diff --git a/CHANGELOG.md b/CHANGELOG.md index 5fb3c746f2..6d8cbccbae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ did not actually use any noncompliant cookie names or values, so there was no vu * It's possible now to target the HMR build when registering via `template.append` and `template.prepend`. Use `when: 'hmr:public'` or `when: 'hmr:apos'` that will be evaluated against the current asset `options.hmr` configuration. * Adds asset module option `options.modulePreloadPolyfill` (default `true`) to allow disabling the polyfill preload for e.g. external front-ends. * Adds `bundleMarkup` to the data sent to the external front-end, containing all markup for injecting Apostrophe UI in the front-end. +* Warns users when two page types have the same field name, but a different field type. This may cause errors or other problems when an editor switches page types. ### Changes diff --git a/modules/@apostrophecms/page/index.js b/modules/@apostrophecms/page/index.js index 34562f9ff2..ddb477da4a 100644 --- a/modules/@apostrophecms/page/index.js +++ b/modules/@apostrophecms/page/index.js @@ -920,6 +920,37 @@ module.exports = { } } }, + detectSchemaConflicts() { + for (const left of self.typeChoices) { + for (const right of self.typeChoices) { + const diff = compareSchema(left, right); + if (diff.size) { + self.apos.util.warnDev(`The page type "${left.name}" has a conflict with "${right.name}" (${formatDiff(diff)}). This may cause errors or other problems when an editor switches page types.`); + } + } + } + function compareSchema(left, right) { + const conflicts = new Map(); + if (left.name === right.name) { + return conflicts; + } + + const leftSchema = self.apos.modules[left.name].schema; + const rightSchema = self.apos.modules[right.name].schema; + for (const leftField of leftSchema) { + const rightField = rightSchema.find(field => field.name === leftField.name); + if (rightField && leftField.type !== rightField.type) { + conflicts.set(leftField.name, [ leftField.type, rightField.type ]); + } + } + + return conflicts; + } + function formatDiff(diff) { + return Array.from(diff.entries()) + .map(([ entry, [ left, right ] ]) => `${entry}:${left} vs ${entry}:${right}`); + } + }, async manageOrphans() { const managed = self.apos.doc.getManaged();