@cratis/scene.engine 4.26.0 → 4.27.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/editing/resolveEffectiveConfiguration.js +8 -0
- package/dist/cjs/editing/resolveEffectiveConfiguration.js.map +1 -1
- package/dist/cjs/index.js +23 -0
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/navigation/NavigationDiagnosticCode.js +5 -0
- package/dist/cjs/navigation/NavigationDiagnosticCode.js.map +1 -1
- package/dist/cjs/navigation/NavigationEditKind.js +16 -0
- package/dist/cjs/navigation/NavigationEditKind.js.map +1 -0
- package/dist/cjs/navigation/NavigationItemOrigin.js +14 -0
- package/dist/cjs/navigation/NavigationItemOrigin.js.map +1 -0
- package/dist/cjs/navigation/NavigationSourcesKind.js +16 -0
- package/dist/cjs/navigation/NavigationSourcesKind.js.map +1 -0
- package/dist/cjs/navigation/diagnoseNavigation.js +8 -1
- package/dist/cjs/navigation/diagnoseNavigation.js.map +1 -1
- package/dist/cjs/navigation/diagnoseNavigationRegions.js +99 -0
- package/dist/cjs/navigation/diagnoseNavigationRegions.js.map +1 -0
- package/dist/cjs/navigation/effectiveNavigation.js +133 -0
- package/dist/cjs/navigation/effectiveNavigation.js.map +1 -0
- package/dist/cjs/navigation/navigationEdits.js +230 -0
- package/dist/cjs/navigation/navigationEdits.js.map +1 -0
- package/dist/cjs/navigation/navigationRegions.js +42 -0
- package/dist/cjs/navigation/navigationRegions.js.map +1 -0
- package/dist/cjs/validateNavigationDestinations.js +2 -0
- package/dist/cjs/validateNavigationDestinations.js.map +1 -1
- package/dist/esm/editing/resolveEffectiveConfiguration.d.ts.map +1 -1
- package/dist/esm/editing/resolveEffectiveConfiguration.js +8 -0
- package/dist/esm/editing/resolveEffectiveConfiguration.js.map +1 -1
- package/dist/esm/index.js +7 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/navigation/EffectiveNavItem.d.ts +14 -0
- package/dist/esm/navigation/EffectiveNavItem.d.ts.map +1 -0
- package/dist/esm/navigation/EffectiveNavItem.js +2 -0
- package/dist/esm/navigation/EffectiveNavItem.js.map +1 -0
- package/dist/esm/navigation/EffectiveNavigationRegion.d.ts +11 -0
- package/dist/esm/navigation/EffectiveNavigationRegion.d.ts.map +1 -0
- package/dist/esm/navigation/EffectiveNavigationRegion.js +2 -0
- package/dist/esm/navigation/EffectiveNavigationRegion.js.map +1 -0
- package/dist/esm/navigation/NavigationDiagnosticCode.d.ts +6 -1
- package/dist/esm/navigation/NavigationDiagnosticCode.d.ts.map +1 -1
- package/dist/esm/navigation/NavigationDiagnosticCode.js +5 -0
- package/dist/esm/navigation/NavigationDiagnosticCode.js.map +1 -1
- package/dist/esm/navigation/NavigationEdit.d.ts +13 -0
- package/dist/esm/navigation/NavigationEdit.d.ts.map +1 -0
- package/dist/esm/navigation/NavigationEdit.js +2 -0
- package/dist/esm/navigation/NavigationEdit.js.map +1 -0
- package/dist/esm/navigation/NavigationEditKind.d.ts +7 -0
- package/dist/esm/navigation/NavigationEditKind.d.ts.map +1 -0
- package/dist/esm/navigation/NavigationEditKind.js +14 -0
- package/dist/esm/navigation/NavigationEditKind.js.map +1 -0
- package/dist/esm/navigation/NavigationEditOutcome.d.ts +7 -0
- package/dist/esm/navigation/NavigationEditOutcome.d.ts.map +1 -0
- package/dist/esm/navigation/NavigationEditOutcome.js +2 -0
- package/dist/esm/navigation/NavigationEditOutcome.js.map +1 -0
- package/dist/esm/navigation/NavigationEditPlan.d.ts +6 -0
- package/dist/esm/navigation/NavigationEditPlan.d.ts.map +1 -0
- package/dist/esm/navigation/NavigationEditPlan.js +2 -0
- package/dist/esm/navigation/NavigationEditPlan.js.map +1 -0
- package/dist/esm/navigation/NavigationGraph.d.ts +4 -1
- package/dist/esm/navigation/NavigationGraph.d.ts.map +1 -1
- package/dist/esm/navigation/NavigationItemOrigin.d.ts +5 -0
- package/dist/esm/navigation/NavigationItemOrigin.d.ts.map +1 -0
- package/dist/esm/navigation/NavigationItemOrigin.js +12 -0
- package/dist/esm/navigation/NavigationItemOrigin.js.map +1 -0
- package/dist/esm/navigation/NavigationSources.d.ts +6 -0
- package/dist/esm/navigation/NavigationSources.d.ts.map +1 -0
- package/dist/esm/navigation/NavigationSources.js +2 -0
- package/dist/esm/navigation/NavigationSources.js.map +1 -0
- package/dist/esm/navigation/NavigationSourcesKind.d.ts +7 -0
- package/dist/esm/navigation/NavigationSourcesKind.d.ts.map +1 -0
- package/dist/esm/navigation/NavigationSourcesKind.js +14 -0
- package/dist/esm/navigation/NavigationSourcesKind.js.map +1 -0
- package/dist/esm/navigation/ResolvedNavigationTarget.d.ts +6 -0
- package/dist/esm/navigation/ResolvedNavigationTarget.d.ts.map +1 -0
- package/dist/esm/navigation/ResolvedNavigationTarget.js +2 -0
- package/dist/esm/navigation/ResolvedNavigationTarget.js.map +1 -0
- package/dist/esm/navigation/diagnoseNavigation.d.ts.map +1 -1
- package/dist/esm/navigation/diagnoseNavigation.js +8 -1
- package/dist/esm/navigation/diagnoseNavigation.js.map +1 -1
- package/dist/esm/navigation/diagnoseNavigationRegions.d.ts +8 -0
- package/dist/esm/navigation/diagnoseNavigationRegions.d.ts.map +1 -0
- package/dist/esm/navigation/diagnoseNavigationRegions.js +97 -0
- package/dist/esm/navigation/diagnoseNavigationRegions.js.map +1 -0
- package/dist/esm/navigation/effectiveNavigation.d.ts +5 -0
- package/dist/esm/navigation/effectiveNavigation.d.ts.map +1 -0
- package/dist/esm/navigation/effectiveNavigation.js +131 -0
- package/dist/esm/navigation/effectiveNavigation.js.map +1 -0
- package/dist/esm/navigation/index.d.ts +14 -0
- package/dist/esm/navigation/index.d.ts.map +1 -1
- package/dist/esm/navigation/index.js +14 -0
- package/dist/esm/navigation/index.js.map +1 -1
- package/dist/esm/navigation/navigationEdits.d.ts +11 -0
- package/dist/esm/navigation/navigationEdits.d.ts.map +1 -0
- package/dist/esm/navigation/navigationEdits.js +225 -0
- package/dist/esm/navigation/navigationEdits.js.map +1 -0
- package/dist/esm/navigation/navigationRegions.d.ts +9 -0
- package/dist/esm/navigation/navigationRegions.d.ts.map +1 -0
- package/dist/esm/navigation/navigationRegions.js +34 -0
- package/dist/esm/navigation/navigationRegions.js.map +1 -0
- package/dist/esm/tsconfig.tsbuildinfo +1 -1
- package/dist/esm/validateNavigationDestinations.js +2 -0
- package/dist/esm/validateNavigationDestinations.js.map +1 -1
- package/editing/resolveEffectiveConfiguration.ts +13 -0
- package/navigation/EffectiveNavItem.ts +37 -0
- package/navigation/EffectiveNavigationRegion.ts +26 -0
- package/navigation/NavigationDiagnosticCode.ts +15 -0
- package/navigation/NavigationEdit.ts +36 -0
- package/navigation/NavigationEditKind.ts +19 -0
- package/navigation/NavigationEditOutcome.ts +18 -0
- package/navigation/NavigationEditPlan.ts +15 -0
- package/navigation/NavigationGraph.ts +10 -1
- package/navigation/NavigationItemOrigin.ts +13 -0
- package/navigation/NavigationSources.ts +15 -0
- package/navigation/NavigationSourcesKind.ts +19 -0
- package/navigation/ResolvedNavigationTarget.ts +19 -0
- package/navigation/diagnoseNavigation.ts +7 -1
- package/navigation/diagnoseNavigationRegions.ts +122 -0
- package/navigation/effectiveNavigation.ts +105 -0
- package/navigation/index.ts +14 -0
- package/navigation/navigationEdits.ts +176 -0
- package/navigation/navigationRegions.ts +39 -0
- package/package.json +3 -3
|
@@ -54,6 +54,14 @@ function collectionValue(grant, matching, instance, items, diagnostics$1) {
|
|
|
54
54
|
diagnostics$1.push(diagnostics.errorDiagnostic(scene_model.DiagnosticCode.ContributionTypeMismatch, `The saved value of '${grant.path}' set by '${instance}' is ignored: a collection takes items.`, context));
|
|
55
55
|
continue;
|
|
56
56
|
}
|
|
57
|
+
if (contribution.replaceOwnerItems === true) {
|
|
58
|
+
if (!grant.operations.includes(scene_model.CollectionOperation.Replace)) {
|
|
59
|
+
diagnostics$1.push(diagnostics.errorDiagnostic(scene_model.DiagnosticCode.ContributionOperationNotPermitted, `'${instance}' replaces the items it inherits in '${grant.path}', but replacing items is not exposed. It is ignored and kept.`, context));
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
items.splice(0, items.length);
|
|
63
|
+
contributed = true;
|
|
64
|
+
}
|
|
57
65
|
if (contribution.items.length > 0 && !grant.operations.includes(scene_model.CollectionOperation.Add)) {
|
|
58
66
|
diagnostics$1.push(diagnostics.errorDiagnostic(scene_model.DiagnosticCode.ContributionOperationNotPermitted, `'${instance}' has items in '${grant.path}', but adding items is not exposed. They are ignored and kept.`, context));
|
|
59
67
|
continue;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolveEffectiveConfiguration.js","sources":["../../../editing/resolveEffectiveConfiguration.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport {\n CollectionOperation, DiagnosticCode, EffectiveCollectionItem, EffectiveComponentConfiguration,\n EffectiveConfiguration, EffectivePropertyValue, InstanceContribution, PropertyValueType, SceneDiagnostic, ValueSource,\n} from '@cratis/scene.model';\nimport { DescriptorCatalog, findComponentDescriptor } from './DescriptorCatalog';\nimport { errorDiagnostic } from './diagnostics';\nimport { computeExposureGrants, ExposureGrant, grantKey } from './exposureGrants';\nimport { cloneData, getValueAtPath, setValueAtPath } from './pathAccess';\nimport { TemplateChain } from './TemplateChain';\nimport { validateItemValues, validateValue } from './validateValue';\n\n/**\n * Splits a flat collection item as it is stored on an element - `{ id, label, ... }` - into its id and fields.\n */\nfunction toEffectiveItem(item: unknown, index: number): EffectiveCollectionItem {\n const { id, ...values } = (item !== null && typeof item === 'object' ? item : {}) as Record<string, unknown>;\n return { id: typeof id === 'string' && id.length > 0 ? id : `owner-${index}`, values, origin: 'owner', fixed: true };\n}\n\nfunction toFlatItem(item: EffectiveCollectionItem): Record<string, unknown> {\n return { id: item.id, ...item.values };\n}\n\nfunction scalarValue(grant: ExposureGrant, matching: InstanceContribution[], instance: string, current: EffectivePropertyValue, diagnostics: SceneDiagnostic[]): void {\n for (const contribution of matching) {\n const problem = contribution.value === undefined ? 'a value is required' : validateValue(grant.descriptor, contribution.value);\n if (problem) {\n diagnostics.push(errorDiagnostic(\n DiagnosticCode.ContributionTypeMismatch,\n `The saved value of '${grant.path}' set by '${instance}' is ignored: ${problem}. It is kept, and applies again when it fits.`,\n { instance, component: grant.component, path: grant.path }));\n continue;\n }\n\n current.value = contribution.value;\n current.source = ValueSource.Instance;\n current.contributedBy = instance;\n }\n}\n\nfunction collectionValue(grant: ExposureGrant, matching: InstanceContribution[], instance: string, items: EffectiveCollectionItem[], diagnostics: SceneDiagnostic[]): boolean {\n let contributed = false;\n\n for (const contribution of matching) {\n const context = { instance, component: grant.component, path: grant.path };\n if (contribution.items === undefined) {\n diagnostics.push(errorDiagnostic(DiagnosticCode.ContributionTypeMismatch, `The saved value of '${grant.path}' set by '${instance}' is ignored: a collection takes items.`, context));\n continue;\n }\n\n if (contribution.items.length > 0 && !grant.operations.includes(CollectionOperation.Add)) {\n diagnostics.push(errorDiagnostic(\n DiagnosticCode.ContributionOperationNotPermitted,\n `'${instance}' has items in '${grant.path}', but adding items is not exposed. They are ignored and kept.`,\n context));\n continue;\n }\n\n for (const item of contribution.items) {\n const itemContext = { ...context, itemId: item.id };\n if (items.some(existing => existing.id === item.id)) {\n diagnostics.push(errorDiagnostic(DiagnosticCode.DuplicateCollectionItem, `The item id '${item.id}' in '${grant.path}' is already used.`, itemContext));\n continue;\n }\n\n const values: Record<string, unknown> = {};\n for (const [field, value] of Object.entries(item.values)) {\n if (grant.editableFields !== undefined && !grant.editableFields.includes(field)) {\n diagnostics.push(errorDiagnostic(DiagnosticCode.ContributionOperationNotPermitted, `The field '${field}' of '${grant.path}' is not exposed for editing.`, itemContext));\n continue;\n }\n\n const problem = validateItemValues(grant.descriptor.item, { [field]: value }).find(candidate => candidate.field === field);\n if (problem) {\n diagnostics.push(errorDiagnostic(\n problem.problem.startsWith('is not a field') ? DiagnosticCode.UnknownCollectionField : DiagnosticCode.ContributionTypeMismatch,\n `The field '${field}' of an item in '${grant.path}' is ignored: ${problem.problem}.`,\n itemContext));\n continue;\n }\n\n values[field] = value;\n }\n\n items.push({ id: item.id, values, origin: instance, fixed: false });\n contributed = true;\n }\n }\n\n return contributed;\n}\n\n/**\n * Resolves what every configurable component in a template chain is worth: the owner's own values, with each\n * instance's contributions applied in nesting order.\n *\n * This is the one merge. The editor shows its result and the runtime renders from it, so what an author sees is\n * what Play renders. Order is fixed: the owner's value first, then each level from the outermost inwards, so a\n * later level wins a scalar and appends to a collection after the earlier ones.\n *\n * Nothing in the persisted data is changed. A contribution that cannot apply - the exposure was withdrawn, the\n * property's type changed, the component is gone - is reported in `diagnostics` and left out of the result, and\n * stays in `instanceContributions`, so restoring the exposure brings its value back.\n *\n * @param templateChain The nesting, from {@link resolveTemplateChain} or built by hand.\n * @param instanceContributions What each instance has set.\n * @param catalog The descriptors saying what each component supports.\n */\nexport function resolveEffectiveConfiguration(\n templateChain: TemplateChain,\n instanceContributions: InstanceContribution[],\n catalog: DescriptorCatalog,\n): EffectiveConfiguration {\n const grants = computeExposureGrants(templateChain, catalog);\n const diagnostics: SceneDiagnostic[] = [...templateChain.diagnostics, ...grants.diagnostics];\n const handled = new Set<InstanceContribution>();\n const components = new Map<string, EffectiveComponentConfiguration>();\n\n for (const grant of grants.exposed) {\n const owner = templateChain.levels[grant.ownerLevel];\n const element = owner.elements.find(candidate => candidate.id === grant.component)!;\n\n let configuration = components.get(grant.component);\n if (!configuration) {\n configuration = { component: grant.component, owner: owner.owner, properties: cloneData(element.properties), values: [] };\n components.set(grant.component, configuration);\n }\n\n const stored = getValueAtPath(element.properties, grant.path);\n const base = stored === undefined ? cloneData(grant.descriptor.default) : cloneData(stored);\n const isCollection = grant.descriptor.valueType === PropertyValueType.Collection;\n const baseItems = isCollection && Array.isArray(base) ? base.map(toEffectiveItem) : [];\n const items = [...baseItems];\n\n const current: EffectivePropertyValue = {\n path: grant.path,\n value: base,\n source: stored === undefined ? ValueSource.Default : ValueSource.Local,\n inheritedValue: base,\n };\n let contributed = false;\n\n for (let index = grant.ownerLevel + 1; index < templateChain.levels.length; index++) {\n const instance = templateChain.levels[index].instance;\n if (!grants.byInstance.get(instance)?.has(grantKey(grant.component, grant.path))) continue;\n\n const effectiveGrant = grants.byInstance.get(instance)!.get(grantKey(grant.component, grant.path))!;\n const matching = instanceContributions.filter(contribution =>\n contribution.instance === instance && contribution.component === grant.component && contribution.path === grant.path);\n for (const contribution of matching) handled.add(contribution);\n\n if (isCollection) {\n if (collectionValue(effectiveGrant, matching, instance, items, diagnostics)) {\n contributed = true;\n current.contributedBy = instance;\n }\n } else {\n scalarValue(effectiveGrant, matching, instance, current, diagnostics);\n }\n }\n\n const maximumItems = grant.descriptor.constraints?.maximumItems;\n if (isCollection && maximumItems !== undefined && items.length > maximumItems) {\n // Saved items that no longer fit - the owner lowered the limit after they were added - are left out of\n // the result in order and kept in the saved data, like any other saved value that no longer fits.\n const dropped = items.splice(maximumItems);\n diagnostics.push(errorDiagnostic(\n DiagnosticCode.ContributionTypeMismatch,\n `'${grant.path}' on '${grant.component}' allows at most ${maximumItems} items; ${dropped.map(item => `'${item.id}'`).join(', ')} ${dropped.length === 1 ? 'is' : 'are'} ignored and kept.`,\n { instance: current.contributedBy ?? owner.instance, component: grant.component, path: grant.path }));\n }\n\n if (isCollection) {\n current.items = items;\n current.inheritedValue = baseItems.map(toFlatItem);\n current.value = items.map(toFlatItem);\n if (contributed) current.source = ValueSource.Instance;\n }\n\n if (current.value !== undefined) setValueAtPath(configuration.properties, grant.path, current.value);\n configuration.values.push(current);\n }\n\n const levelOf = new Map(templateChain.levels.map((chainLevel, index) => [chainLevel.instance, index]));\n for (const contribution of instanceContributions) {\n const contributorLevel = levelOf.get(contribution.instance);\n if (contributorLevel === undefined || handled.has(contribution)) continue;\n\n const context = { instance: contribution.instance, component: contribution.component, path: contribution.path };\n const owner = templateChain.levels.slice(0, contributorLevel).find(chainLevel => chainLevel.elements.some(element => element.id === contribution.component));\n if (!owner) {\n diagnostics.push(errorDiagnostic(\n DiagnosticCode.ContributionTargetMissing,\n `'${contribution.instance}' has saved values for '${contribution.component}', which is not in any layout or template above it. They are kept.`,\n context));\n } else if (!findComponentDescriptor(catalog, owner.elements.find(element => element.id === contribution.component)!.componentName)) {\n diagnostics.push(errorDiagnostic(\n DiagnosticCode.MissingComponentDescriptor,\n `'${contribution.instance}' has saved values for '${contribution.component}', but nothing describes that component any more. They are kept.`,\n context));\n } else {\n diagnostics.push(errorDiagnostic(\n DiagnosticCode.ContributionNotExposed,\n `'${contribution.instance}' has a saved value for '${contribution.path}' on '${contribution.component}', which is not exposed to it. It is ignored and kept.`,\n context));\n }\n }\n\n return { components: [...components.values()], diagnostics };\n}\n"],"names":["toEffectiveItem","item","index","id","values","length","origin","fixed","toFlatItem","scalarValue","grant","matching","instance","current","diagnostics","contribution","problem","value","undefined","validateValue","descriptor","push","errorDiagnostic","DiagnosticCode","ContributionTypeMismatch","path","component","source","ValueSource","Instance","contributedBy","collectionValue","items","contributed","context","operations","includes","CollectionOperation","Add","ContributionOperationNotPermitted","itemContext","itemId","some","existing","DuplicateCollectionItem","field","Object","entries","editableFields","validateItemValues","find","candidate","startsWith","UnknownCollectionField","resolveEffectiveConfiguration","templateChain","instanceContributions","catalog","grants","computeExposureGrants","handled","Set","components","Map","exposed","owner","levels","ownerLevel","element","elements","configuration","get","properties","cloneData","set","stored","getValueAtPath","base","default","isCollection","valueType","PropertyValueType","Collection","baseItems","Array","isArray","map","Default","Local","inheritedValue","byInstance","has","grantKey","effectiveGrant","filter","add","maximumItems","constraints","dropped","splice","join","setValueAtPath","levelOf","chainLevel","contributorLevel","slice","ContributionTargetMissing","findComponentDescriptor","componentName","MissingComponentDescriptor","ContributionNotExposed"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"resolveEffectiveConfiguration.js","sources":["../../../editing/resolveEffectiveConfiguration.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport {\n CollectionOperation, DiagnosticCode, EffectiveCollectionItem, EffectiveComponentConfiguration,\n EffectiveConfiguration, EffectivePropertyValue, InstanceContribution, PropertyValueType, SceneDiagnostic, ValueSource,\n} from '@cratis/scene.model';\nimport { DescriptorCatalog, findComponentDescriptor } from './DescriptorCatalog';\nimport { errorDiagnostic } from './diagnostics';\nimport { computeExposureGrants, ExposureGrant, grantKey } from './exposureGrants';\nimport { cloneData, getValueAtPath, setValueAtPath } from './pathAccess';\nimport { TemplateChain } from './TemplateChain';\nimport { validateItemValues, validateValue } from './validateValue';\n\n/**\n * Splits a flat collection item as it is stored on an element - `{ id, label, ... }` - into its id and fields.\n */\nfunction toEffectiveItem(item: unknown, index: number): EffectiveCollectionItem {\n const { id, ...values } = (item !== null && typeof item === 'object' ? item : {}) as Record<string, unknown>;\n return { id: typeof id === 'string' && id.length > 0 ? id : `owner-${index}`, values, origin: 'owner', fixed: true };\n}\n\nfunction toFlatItem(item: EffectiveCollectionItem): Record<string, unknown> {\n return { id: item.id, ...item.values };\n}\n\nfunction scalarValue(grant: ExposureGrant, matching: InstanceContribution[], instance: string, current: EffectivePropertyValue, diagnostics: SceneDiagnostic[]): void {\n for (const contribution of matching) {\n const problem = contribution.value === undefined ? 'a value is required' : validateValue(grant.descriptor, contribution.value);\n if (problem) {\n diagnostics.push(errorDiagnostic(\n DiagnosticCode.ContributionTypeMismatch,\n `The saved value of '${grant.path}' set by '${instance}' is ignored: ${problem}. It is kept, and applies again when it fits.`,\n { instance, component: grant.component, path: grant.path }));\n continue;\n }\n\n current.value = contribution.value;\n current.source = ValueSource.Instance;\n current.contributedBy = instance;\n }\n}\n\nfunction collectionValue(grant: ExposureGrant, matching: InstanceContribution[], instance: string, items: EffectiveCollectionItem[], diagnostics: SceneDiagnostic[]): boolean {\n let contributed = false;\n\n for (const contribution of matching) {\n const context = { instance, component: grant.component, path: grant.path };\n if (contribution.items === undefined) {\n diagnostics.push(errorDiagnostic(DiagnosticCode.ContributionTypeMismatch, `The saved value of '${grant.path}' set by '${instance}' is ignored: a collection takes items.`, context));\n continue;\n }\n\n if (contribution.replaceOwnerItems === true) {\n if (!grant.operations.includes(CollectionOperation.Replace)) {\n diagnostics.push(errorDiagnostic(\n DiagnosticCode.ContributionOperationNotPermitted,\n `'${instance}' replaces the items it inherits in '${grant.path}', but replacing items is not exposed. It is ignored and kept.`,\n context));\n continue;\n }\n\n items.splice(0, items.length);\n contributed = true;\n }\n\n if (contribution.items.length > 0 && !grant.operations.includes(CollectionOperation.Add)) {\n diagnostics.push(errorDiagnostic(\n DiagnosticCode.ContributionOperationNotPermitted,\n `'${instance}' has items in '${grant.path}', but adding items is not exposed. They are ignored and kept.`,\n context));\n continue;\n }\n\n for (const item of contribution.items) {\n const itemContext = { ...context, itemId: item.id };\n if (items.some(existing => existing.id === item.id)) {\n diagnostics.push(errorDiagnostic(DiagnosticCode.DuplicateCollectionItem, `The item id '${item.id}' in '${grant.path}' is already used.`, itemContext));\n continue;\n }\n\n const values: Record<string, unknown> = {};\n for (const [field, value] of Object.entries(item.values)) {\n if (grant.editableFields !== undefined && !grant.editableFields.includes(field)) {\n diagnostics.push(errorDiagnostic(DiagnosticCode.ContributionOperationNotPermitted, `The field '${field}' of '${grant.path}' is not exposed for editing.`, itemContext));\n continue;\n }\n\n const problem = validateItemValues(grant.descriptor.item, { [field]: value }).find(candidate => candidate.field === field);\n if (problem) {\n diagnostics.push(errorDiagnostic(\n problem.problem.startsWith('is not a field') ? DiagnosticCode.UnknownCollectionField : DiagnosticCode.ContributionTypeMismatch,\n `The field '${field}' of an item in '${grant.path}' is ignored: ${problem.problem}.`,\n itemContext));\n continue;\n }\n\n values[field] = value;\n }\n\n items.push({ id: item.id, values, origin: instance, fixed: false });\n contributed = true;\n }\n }\n\n return contributed;\n}\n\n/**\n * Resolves what every configurable component in a template chain is worth: the owner's own values, with each\n * instance's contributions applied in nesting order.\n *\n * This is the one merge. The editor shows its result and the runtime renders from it, so what an author sees is\n * what Play renders. Order is fixed: the owner's value first, then each level from the outermost inwards, so a\n * later level wins a scalar and appends to a collection after the earlier ones.\n *\n * Nothing in the persisted data is changed. A contribution that cannot apply - the exposure was withdrawn, the\n * property's type changed, the component is gone - is reported in `diagnostics` and left out of the result, and\n * stays in `instanceContributions`, so restoring the exposure brings its value back.\n *\n * @param templateChain The nesting, from {@link resolveTemplateChain} or built by hand.\n * @param instanceContributions What each instance has set.\n * @param catalog The descriptors saying what each component supports.\n */\nexport function resolveEffectiveConfiguration(\n templateChain: TemplateChain,\n instanceContributions: InstanceContribution[],\n catalog: DescriptorCatalog,\n): EffectiveConfiguration {\n const grants = computeExposureGrants(templateChain, catalog);\n const diagnostics: SceneDiagnostic[] = [...templateChain.diagnostics, ...grants.diagnostics];\n const handled = new Set<InstanceContribution>();\n const components = new Map<string, EffectiveComponentConfiguration>();\n\n for (const grant of grants.exposed) {\n const owner = templateChain.levels[grant.ownerLevel];\n const element = owner.elements.find(candidate => candidate.id === grant.component)!;\n\n let configuration = components.get(grant.component);\n if (!configuration) {\n configuration = { component: grant.component, owner: owner.owner, properties: cloneData(element.properties), values: [] };\n components.set(grant.component, configuration);\n }\n\n const stored = getValueAtPath(element.properties, grant.path);\n const base = stored === undefined ? cloneData(grant.descriptor.default) : cloneData(stored);\n const isCollection = grant.descriptor.valueType === PropertyValueType.Collection;\n const baseItems = isCollection && Array.isArray(base) ? base.map(toEffectiveItem) : [];\n const items = [...baseItems];\n\n const current: EffectivePropertyValue = {\n path: grant.path,\n value: base,\n source: stored === undefined ? ValueSource.Default : ValueSource.Local,\n inheritedValue: base,\n };\n let contributed = false;\n\n for (let index = grant.ownerLevel + 1; index < templateChain.levels.length; index++) {\n const instance = templateChain.levels[index].instance;\n if (!grants.byInstance.get(instance)?.has(grantKey(grant.component, grant.path))) continue;\n\n const effectiveGrant = grants.byInstance.get(instance)!.get(grantKey(grant.component, grant.path))!;\n const matching = instanceContributions.filter(contribution =>\n contribution.instance === instance && contribution.component === grant.component && contribution.path === grant.path);\n for (const contribution of matching) handled.add(contribution);\n\n if (isCollection) {\n if (collectionValue(effectiveGrant, matching, instance, items, diagnostics)) {\n contributed = true;\n current.contributedBy = instance;\n }\n } else {\n scalarValue(effectiveGrant, matching, instance, current, diagnostics);\n }\n }\n\n const maximumItems = grant.descriptor.constraints?.maximumItems;\n if (isCollection && maximumItems !== undefined && items.length > maximumItems) {\n // Saved items that no longer fit - the owner lowered the limit after they were added - are left out of\n // the result in order and kept in the saved data, like any other saved value that no longer fits.\n const dropped = items.splice(maximumItems);\n diagnostics.push(errorDiagnostic(\n DiagnosticCode.ContributionTypeMismatch,\n `'${grant.path}' on '${grant.component}' allows at most ${maximumItems} items; ${dropped.map(item => `'${item.id}'`).join(', ')} ${dropped.length === 1 ? 'is' : 'are'} ignored and kept.`,\n { instance: current.contributedBy ?? owner.instance, component: grant.component, path: grant.path }));\n }\n\n if (isCollection) {\n current.items = items;\n current.inheritedValue = baseItems.map(toFlatItem);\n current.value = items.map(toFlatItem);\n if (contributed) current.source = ValueSource.Instance;\n }\n\n if (current.value !== undefined) setValueAtPath(configuration.properties, grant.path, current.value);\n configuration.values.push(current);\n }\n\n const levelOf = new Map(templateChain.levels.map((chainLevel, index) => [chainLevel.instance, index]));\n for (const contribution of instanceContributions) {\n const contributorLevel = levelOf.get(contribution.instance);\n if (contributorLevel === undefined || handled.has(contribution)) continue;\n\n const context = { instance: contribution.instance, component: contribution.component, path: contribution.path };\n const owner = templateChain.levels.slice(0, contributorLevel).find(chainLevel => chainLevel.elements.some(element => element.id === contribution.component));\n if (!owner) {\n diagnostics.push(errorDiagnostic(\n DiagnosticCode.ContributionTargetMissing,\n `'${contribution.instance}' has saved values for '${contribution.component}', which is not in any layout or template above it. They are kept.`,\n context));\n } else if (!findComponentDescriptor(catalog, owner.elements.find(element => element.id === contribution.component)!.componentName)) {\n diagnostics.push(errorDiagnostic(\n DiagnosticCode.MissingComponentDescriptor,\n `'${contribution.instance}' has saved values for '${contribution.component}', but nothing describes that component any more. They are kept.`,\n context));\n } else {\n diagnostics.push(errorDiagnostic(\n DiagnosticCode.ContributionNotExposed,\n `'${contribution.instance}' has a saved value for '${contribution.path}' on '${contribution.component}', which is not exposed to it. It is ignored and kept.`,\n context));\n }\n }\n\n return { components: [...components.values()], diagnostics };\n}\n"],"names":["toEffectiveItem","item","index","id","values","length","origin","fixed","toFlatItem","scalarValue","grant","matching","instance","current","diagnostics","contribution","problem","value","undefined","validateValue","descriptor","push","errorDiagnostic","DiagnosticCode","ContributionTypeMismatch","path","component","source","ValueSource","Instance","contributedBy","collectionValue","items","contributed","context","replaceOwnerItems","operations","includes","CollectionOperation","Replace","ContributionOperationNotPermitted","splice","Add","itemContext","itemId","some","existing","DuplicateCollectionItem","field","Object","entries","editableFields","validateItemValues","find","candidate","startsWith","UnknownCollectionField","resolveEffectiveConfiguration","templateChain","instanceContributions","catalog","grants","computeExposureGrants","handled","Set","components","Map","exposed","owner","levels","ownerLevel","element","elements","configuration","get","properties","cloneData","set","stored","getValueAtPath","base","default","isCollection","valueType","PropertyValueType","Collection","baseItems","Array","isArray","map","Default","Local","inheritedValue","byInstance","has","grantKey","effectiveGrant","filter","add","maximumItems","constraints","dropped","join","setValueAtPath","levelOf","chainLevel","contributorLevel","slice","ContributionTargetMissing","findComponentDescriptor","componentName","MissingComponentDescriptor","ContributionNotExposed"],"mappings":"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"}
|
package/dist/cjs/index.js
CHANGED
|
@@ -60,6 +60,13 @@ var NavigationDiagnosticCode = require('./navigation/NavigationDiagnosticCode.js
|
|
|
60
60
|
var diagnoseNavigation = require('./navigation/diagnoseNavigation.js');
|
|
61
61
|
var navigationEntriesFrom = require('./navigation/navigationEntriesFrom.js');
|
|
62
62
|
var navigationRoute = require('./navigation/navigationRoute.js');
|
|
63
|
+
var navigationRegions = require('./navigation/navigationRegions.js');
|
|
64
|
+
var NavigationItemOrigin = require('./navigation/NavigationItemOrigin.js');
|
|
65
|
+
var NavigationSourcesKind = require('./navigation/NavigationSourcesKind.js');
|
|
66
|
+
var effectiveNavigation = require('./navigation/effectiveNavigation.js');
|
|
67
|
+
var diagnoseNavigationRegions = require('./navigation/diagnoseNavigationRegions.js');
|
|
68
|
+
var NavigationEditKind = require('./navigation/NavigationEditKind.js');
|
|
69
|
+
var navigationEdits = require('./navigation/navigationEdits.js');
|
|
63
70
|
var validateNavigationDestinations = require('./validateNavigationDestinations.js');
|
|
64
71
|
var diagnostics = require('./editing/diagnostics.js');
|
|
65
72
|
var nodeIds = require('./editing/nodeIds.js');
|
|
@@ -200,6 +207,22 @@ exports.diagnoseNavigation = diagnoseNavigation.diagnoseNavigation;
|
|
|
200
207
|
exports.navigationEntriesFrom = navigationEntriesFrom.navigationEntriesFrom;
|
|
201
208
|
exports.authoredRouteKey = navigationRoute.authoredRouteKey;
|
|
202
209
|
exports.navigationTarget = navigationRoute.navigationTarget;
|
|
210
|
+
exports.applicationItems = navigationRegions.applicationItems;
|
|
211
|
+
exports.collectItemIds = navigationRegions.collectItemIds;
|
|
212
|
+
exports.findModuleNavigation = navigationRegions.findModuleNavigation;
|
|
213
|
+
exports.findNavigationRegion = navigationRegions.findNavigationRegion;
|
|
214
|
+
exports.modeOfModuleRegion = navigationRegions.modeOfModuleRegion;
|
|
215
|
+
exports.navigationRegionOrder = navigationRegions.navigationRegionOrder;
|
|
216
|
+
exports.primarySlot = navigationRegions.primarySlot;
|
|
217
|
+
exports.NavigationItemOrigin = NavigationItemOrigin.NavigationItemOrigin;
|
|
218
|
+
exports.NavigationSourcesKind = NavigationSourcesKind.NavigationSourcesKind;
|
|
219
|
+
exports.effectiveNavigation = effectiveNavigation.effectiveNavigation;
|
|
220
|
+
exports.diagnoseNavigationRegions = diagnoseNavigationRegions.diagnoseNavigationRegions;
|
|
221
|
+
exports.NavigationEditKind = NavigationEditKind.NavigationEditKind;
|
|
222
|
+
exports.addNavItem = navigationEdits.addNavItem;
|
|
223
|
+
exports.applyNavigationEdits = navigationEdits.applyNavigationEdits;
|
|
224
|
+
exports.setApplicationLogo = navigationEdits.setApplicationLogo;
|
|
225
|
+
exports.switchRegionMode = navigationEdits.switchRegionMode;
|
|
203
226
|
exports.validateNavigationDestinations = validateNavigationDestinations.validateNavigationDestinations;
|
|
204
227
|
exports.errorDiagnostic = diagnostics.errorDiagnostic;
|
|
205
228
|
exports.hasErrors = diagnostics.hasErrors;
|
package/dist/cjs/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -12,6 +12,11 @@
|
|
|
12
12
|
/** A destination names an outlet that cannot host what it opens. */ NavigationDiagnosticCode["IncompatibleOutlet"] = "incompatibleOutlet";
|
|
13
13
|
/** Screens are placed in outlets owned by each other, so composition never terminates. */ NavigationDiagnosticCode["NavigationCycle"] = "navigationCycle";
|
|
14
14
|
/** A destination opens a screen or dialog that does not exist, or names nothing to open. */ NavigationDiagnosticCode["UnavailableTarget"] = "unavailableTarget";
|
|
15
|
+
/** A navigation item has no target, or targets a module or feature the application does not have. */ NavigationDiagnosticCode["NavTargetMissing"] = "navTargetMissing";
|
|
16
|
+
/** A navigation item renders into a slot the layout does not declare. */ NavigationDiagnosticCode["NavSlotUnknown"] = "navSlotUnknown";
|
|
17
|
+
/** Two navigation items of one region share an id. */ NavigationDiagnosticCode["NavDuplicateId"] = "navDuplicateId";
|
|
18
|
+
/** A navigation item targets a module that has no feature to go to. */ NavigationDiagnosticCode["NavModuleWithoutFeatures"] = "navModuleWithoutFeatures";
|
|
19
|
+
/** A module's own navigation item targets a different module. */ NavigationDiagnosticCode["NavTargetOutOfScope"] = "navTargetOutOfScope";
|
|
15
20
|
return NavigationDiagnosticCode;
|
|
16
21
|
}({});
|
|
17
22
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NavigationDiagnosticCode.js","sources":["../../../navigation/NavigationDiagnosticCode.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\n/**\n * What is wrong with a navigation destination. The values are shared with the C# engine so both report\n * the same code for the same model.\n */\nexport enum NavigationDiagnosticCode {\n /** Two destinations that go to different targets share one URL. */\n DuplicateRoute = 'duplicateRoute',\n\n /** Two surfaces declare an outlet with the same name, so a destination cannot tell them apart. */\n DuplicateOutlet = 'duplicateOutlet',\n\n /** A destination names an outlet that no layout or screen template declares. */\n MissingOutlet = 'missingOutlet',\n\n /** A destination names an outlet that cannot host what it opens. */\n IncompatibleOutlet = 'incompatibleOutlet',\n\n /** Screens are placed in outlets owned by each other, so composition never terminates. */\n NavigationCycle = 'navigationCycle',\n\n /** A destination opens a screen or dialog that does not exist, or names nothing to open. */\n UnavailableTarget = 'unavailableTarget',\n}\n"],"names":["NavigationDiagnosticCode"],"mappings":";;AAAA;AACA;AAEA;;;IAIO,IAAKA,wBAAAA,iBAAAA,SAAAA,wBAAAA,EAAAA;wEACyD,wBAAA,CAAA,gBAAA,CAAA,GAAA,gBAAA;uGAG+B,wBAAA,CAAA,iBAAA,CAAA,GAAA,iBAAA;qFAGlB,wBAAA,CAAA,eAAA,CAAA,GAAA,eAAA;yEAGZ,wBAAA,CAAA,oBAAA,CAAA,GAAA,oBAAA;+FAGsB,wBAAA,CAAA,iBAAA,CAAA,GAAA,iBAAA;iGAGE,wBAAA,CAAA,mBAAA,CAAA,GAAA,mBAAA;
|
|
1
|
+
{"version":3,"file":"NavigationDiagnosticCode.js","sources":["../../../navigation/NavigationDiagnosticCode.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\n/**\n * What is wrong with a navigation destination. The values are shared with the C# engine so both report\n * the same code for the same model.\n */\nexport enum NavigationDiagnosticCode {\n /** Two destinations that go to different targets share one URL. */\n DuplicateRoute = 'duplicateRoute',\n\n /** Two surfaces declare an outlet with the same name, so a destination cannot tell them apart. */\n DuplicateOutlet = 'duplicateOutlet',\n\n /** A destination names an outlet that no layout or screen template declares. */\n MissingOutlet = 'missingOutlet',\n\n /** A destination names an outlet that cannot host what it opens. */\n IncompatibleOutlet = 'incompatibleOutlet',\n\n /** Screens are placed in outlets owned by each other, so composition never terminates. */\n NavigationCycle = 'navigationCycle',\n\n /** A destination opens a screen or dialog that does not exist, or names nothing to open. */\n UnavailableTarget = 'unavailableTarget',\n\n /** A navigation item has no target, or targets a module or feature the application does not have. */\n NavTargetMissing = 'navTargetMissing',\n\n /** A navigation item renders into a slot the layout does not declare. */\n NavSlotUnknown = 'navSlotUnknown',\n\n /** Two navigation items of one region share an id. */\n NavDuplicateId = 'navDuplicateId',\n\n /** A navigation item targets a module that has no feature to go to. */\n NavModuleWithoutFeatures = 'navModuleWithoutFeatures',\n\n /** A module's own navigation item targets a different module. */\n NavTargetOutOfScope = 'navTargetOutOfScope',\n}\n"],"names":["NavigationDiagnosticCode"],"mappings":";;AAAA;AACA;AAEA;;;IAIO,IAAKA,wBAAAA,iBAAAA,SAAAA,wBAAAA,EAAAA;wEACyD,wBAAA,CAAA,gBAAA,CAAA,GAAA,gBAAA;uGAG+B,wBAAA,CAAA,iBAAA,CAAA,GAAA,iBAAA;qFAGlB,wBAAA,CAAA,eAAA,CAAA,GAAA,eAAA;yEAGZ,wBAAA,CAAA,oBAAA,CAAA,GAAA,oBAAA;+FAGsB,wBAAA,CAAA,iBAAA,CAAA,GAAA,iBAAA;iGAGE,wBAAA,CAAA,mBAAA,CAAA,GAAA,mBAAA;0GAGS,wBAAA,CAAA,kBAAA,CAAA,GAAA,kBAAA;8EAG5B,wBAAA,CAAA,gBAAA,CAAA,GAAA,gBAAA;2DAGnB,wBAAA,CAAA,gBAAA,CAAA,GAAA,gBAAA;4EAGiB,wBAAA,CAAA,0BAAA,CAAA,GAAA,0BAAA;sEAGN,wBAAA,CAAA,qBAAA,CAAA,GAAA,qBAAA;AA/BvDA,IAAAA,OAAAA,wBAAAA;AAiCX,CAAA,CAAA,EAAA;;"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// Copyright (c) Cratis. All rights reserved.
|
|
4
|
+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
5
|
+
/**
|
|
6
|
+
* What a navigation edit does. The values are shared with the C# engine.
|
|
7
|
+
*/ var NavigationEditKind = /*#__PURE__*/ function(NavigationEditKind) {
|
|
8
|
+
/** Sets how a module's region relates to the application's. */ NavigationEditKind["SetRegionMode"] = "setRegionMode";
|
|
9
|
+
/** Replaces the items a level holds in a region. */ NavigationEditKind["SetRegionItems"] = "setRegionItems";
|
|
10
|
+
/** Adds an item, or a sub-item, after the ones already there. */ NavigationEditKind["AddItem"] = "addItem";
|
|
11
|
+
/** Sets the application logo. */ NavigationEditKind["SetLogo"] = "setLogo";
|
|
12
|
+
return NavigationEditKind;
|
|
13
|
+
}({});
|
|
14
|
+
|
|
15
|
+
exports.NavigationEditKind = NavigationEditKind;
|
|
16
|
+
//# sourceMappingURL=NavigationEditKind.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NavigationEditKind.js","sources":["../../../navigation/NavigationEditKind.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\n/**\n * What a navigation edit does. The values are shared with the C# engine.\n */\nexport enum NavigationEditKind {\n /** Sets how a module's region relates to the application's. */\n SetRegionMode = 'setRegionMode',\n\n /** Replaces the items a level holds in a region. */\n SetRegionItems = 'setRegionItems',\n\n /** Adds an item, or a sub-item, after the ones already there. */\n AddItem = 'addItem',\n\n /** Sets the application logo. */\n SetLogo = 'setLogo',\n}\n"],"names":["NavigationEditKind"],"mappings":";;AAAA;AACA;AAEA;;IAGO,IAAKA,kBAAAA,iBAAAA,SAAAA,kBAAAA,EAAAA;oEACqD,kBAAA,CAAA,eAAA,CAAA,GAAA,eAAA;yDAGX,kBAAA,CAAA,gBAAA,CAAA,GAAA,gBAAA;sEAGa,kBAAA,CAAA,SAAA,CAAA,GAAA,SAAA;sCAGhC,kBAAA,CAAA,SAAA,CAAA,GAAA,SAAA;AAVvBA,IAAAA,OAAAA,kBAAAA;AAYX,CAAA,CAAA,EAAA;;"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// Copyright (c) Cratis. All rights reserved.
|
|
4
|
+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
5
|
+
/**
|
|
6
|
+
* Which level defined a navigation item.
|
|
7
|
+
*/ var NavigationItemOrigin = /*#__PURE__*/ function(NavigationItemOrigin) {
|
|
8
|
+
/** The application defined the item. */ NavigationItemOrigin["Application"] = "application";
|
|
9
|
+
/** A module defined the item. */ NavigationItemOrigin["Module"] = "module";
|
|
10
|
+
return NavigationItemOrigin;
|
|
11
|
+
}({});
|
|
12
|
+
|
|
13
|
+
exports.NavigationItemOrigin = NavigationItemOrigin;
|
|
14
|
+
//# sourceMappingURL=NavigationItemOrigin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NavigationItemOrigin.js","sources":["../../../navigation/NavigationItemOrigin.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\n/**\n * Which level defined a navigation item.\n */\nexport enum NavigationItemOrigin {\n /** The application defined the item. */\n Application = 'application',\n\n /** A module defined the item. */\n Module = 'module',\n}\n"],"names":["NavigationItemOrigin"],"mappings":";;AAAA;AACA;AAEA;;IAGO,IAAKA,oBAAAA,iBAAAA,SAAAA,oBAAAA,EAAAA;6CAC8B,oBAAA,CAAA,aAAA,CAAA,GAAA,aAAA;sCAGP,oBAAA,CAAA,QAAA,CAAA,GAAA,QAAA;AAJvBA,IAAAA,OAAAA,oBAAAA;AAMX,CAAA,CAAA,EAAA;;"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// Copyright (c) Cratis. All rights reserved.
|
|
4
|
+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
5
|
+
/**
|
|
6
|
+
* How a region's effective items relate to the application's. The values are shared with the C# engine.
|
|
7
|
+
*/ var NavigationSourcesKind = /*#__PURE__*/ function(NavigationSourcesKind) {
|
|
8
|
+
/** The application level: every region is defined here. */ NavigationSourcesKind["DefinedHere"] = "definedHere";
|
|
9
|
+
/** A module region that shows the application's items. */ NavigationSourcesKind["Inherited"] = "inherited";
|
|
10
|
+
/** A module region that shows the application's items and its own. */ NavigationSourcesKind["Extended"] = "extended";
|
|
11
|
+
/** A module region that shows its own items only. */ NavigationSourcesKind["Overridden"] = "overridden";
|
|
12
|
+
return NavigationSourcesKind;
|
|
13
|
+
}({});
|
|
14
|
+
|
|
15
|
+
exports.NavigationSourcesKind = NavigationSourcesKind;
|
|
16
|
+
//# sourceMappingURL=NavigationSourcesKind.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NavigationSourcesKind.js","sources":["../../../navigation/NavigationSourcesKind.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\n/**\n * How a region's effective items relate to the application's. The values are shared with the C# engine.\n */\nexport enum NavigationSourcesKind {\n /** The application level: every region is defined here. */\n DefinedHere = 'definedHere',\n\n /** A module region that shows the application's items. */\n Inherited = 'inherited',\n\n /** A module region that shows the application's items and its own. */\n Extended = 'extended',\n\n /** A module region that shows its own items only. */\n Overridden = 'overridden',\n}\n"],"names":["NavigationSourcesKind"],"mappings":";;AAAA;AACA;AAEA;;IAGO,IAAKA,qBAAAA,iBAAAA,SAAAA,qBAAAA,EAAAA;gEACiD,qBAAA,CAAA,aAAA,CAAA,GAAA,aAAA;+DAGD,qBAAA,CAAA,WAAA,CAAA,GAAA,WAAA;2EAGY,qBAAA,CAAA,UAAA,CAAA,GAAA,UAAA;0DAGjB,qBAAA,CAAA,YAAA,CAAA,GAAA,YAAA;AAV3CA,IAAAA,OAAAA,qBAAAA;AAYX,CAAA,CAAA,EAAA;;"}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
var scene_model = require('@cratis/scene.model');
|
|
4
4
|
var collectOutlets = require('./collectOutlets.js');
|
|
5
|
+
var diagnoseNavigationRegions = require('./diagnoseNavigationRegions.js');
|
|
5
6
|
var findHostingCycles = require('./findHostingCycles.js');
|
|
6
7
|
var NavigationDiagnosticCode = require('./NavigationDiagnosticCode.js');
|
|
7
8
|
var navigationRoute = require('./navigationRoute.js');
|
|
@@ -14,7 +15,8 @@ var navigationRoute = require('./navigationRoute.js');
|
|
|
14
15
|
*
|
|
15
16
|
* Routes are compared by `routeKey` - by default the authored route override, since the engine constructs no
|
|
16
17
|
* URLs. Nothing is rewritten. The C# engine (`NavigationDiagnostics.Diagnose`) reports the same codes and
|
|
17
|
-
* messages in the same order for the same model; both are asserted against `navigation-diagnostic-fixtures.json`.
|
|
18
|
+
* messages in the same order for the same model; both are asserted against `navigation-diagnostic-fixtures.json`. When the graph carries
|
|
19
|
+
an application `structure` and `navigation` regions, the regions are checked too ({@link diagnoseNavigationRegions}).
|
|
18
20
|
*/ function diagnoseNavigation(graph, routeKey = navigationRoute.authoredRouteKey) {
|
|
19
21
|
const diagnostics = [];
|
|
20
22
|
const outlets = collectOutlets.collectOutlets(graph, diagnostics);
|
|
@@ -71,6 +73,11 @@ var navigationRoute = require('./navigationRoute.js');
|
|
|
71
73
|
].join(' -> ')}: each screen is placed in an outlet owned by the next, so composition never terminates.`
|
|
72
74
|
});
|
|
73
75
|
}
|
|
76
|
+
if (graph.structure && graph.navigation) {
|
|
77
|
+
diagnostics.push(...diagnoseNavigationRegions.diagnoseNavigationRegions(graph.structure, graph.navigation, {
|
|
78
|
+
slots: graph.slots
|
|
79
|
+
}));
|
|
80
|
+
}
|
|
74
81
|
return diagnostics;
|
|
75
82
|
}
|
|
76
83
|
function diagnoseTarget(graph, screens, destination, kind, entry, report) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"diagnoseNavigation.js","sources":["../../../navigation/diagnoseNavigation.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { DestinationKind, DestinationReference, Screen } from '@cratis/scene.model';\nimport { collectOutlets } from './collectOutlets';\nimport { findHostingCycles } from './findHostingCycles';\nimport { NavigationDiagnostic } from './NavigationDiagnostic';\nimport { NavigationDiagnosticCode } from './NavigationDiagnosticCode';\nimport { NavigationGraph } from './NavigationGraph';\nimport { NavigationRouteKey, authoredRouteKey, navigationTarget } from './navigationRoute';\nimport { OutletOwner } from './OutletOwner';\n\n/**\n * Diagnoses how destinations, outlets, routes and targets fit together: duplicate routes, duplicate,\n * missing or incompatible outlets, hosting cycles and unavailable targets.\n *\n * Routes are compared by `routeKey` - by default the authored route override, since the engine constructs no\n * URLs. Nothing is rewritten. The C# engine (`NavigationDiagnostics.Diagnose`) reports the same codes and\n * messages in the same order for the same model; both are asserted against `navigation-diagnostic-fixtures.json`.\n */\nexport function diagnoseNavigation(graph: NavigationGraph, routeKey: NavigationRouteKey = authoredRouteKey): NavigationDiagnostic[] {\n const diagnostics: NavigationDiagnostic[] = [];\n const outlets = collectOutlets(graph, diagnostics);\n const screens = graph.screens ? new Map(graph.screens.map(screen => [screen.name, screen])) : undefined;\n const routes = new Map<string, { entry: string; target: string }>();\n const hostedIn = new Map<string, string[]>();\n\n graph.entries.forEach((navigationEntry, index) => {\n const entry = navigationEntry.id ?? `#${index + 1}`;\n const destination = navigationEntry.destination;\n const kind = destination.kind ?? (destination.dialog ? DestinationKind.Dialog : DestinationKind.Outlet);\n const report = (code: NavigationDiagnosticCode, message: string) => diagnostics.push({ code, message, entry });\n\n if (!destination.screen && !destination.module && !destination.route && !destination.dialog) {\n report(NavigationDiagnosticCode.UnavailableTarget, `Destination '${entry}' names no screen, stable identity, route or dialog.`);\n return;\n }\n\n diagnoseTarget(graph, screens, destination, kind, entry, report);\n const owner = diagnoseOutlet(graph, outlets, screens, destination, kind, entry, report);\n if (owner?.ownerKind === 'ScreenTemplate' && destination.screen && screens?.has(destination.screen)) {\n const hosts = graph.screens!.filter(screen => screen.screenTemplate === owner.owner).map(screen => screen.name);\n hostedIn.set(destination.screen, [...new Set([...(hostedIn.get(destination.screen) ?? []), ...hosts])]);\n }\n\n const route = kind === DestinationKind.External ? undefined : routeKey(destination);\n if (route) {\n const target = navigationTarget(destination, kind);\n const existing = routes.get(route);\n if (!existing) {\n routes.set(route, { entry, target });\n } else if (existing.target !== target) {\n report(NavigationDiagnosticCode.DuplicateRoute, `Route '${destination.route ?? route}' is used by destinations '${existing.entry}' and '${entry}', which open different targets.`);\n }\n }\n });\n\n for (const cycle of findHostingCycles(graph.screens?.map(screen => screen.name) ?? [], hostedIn)) {\n diagnostics.push({\n code: NavigationDiagnosticCode.NavigationCycle,\n message: `Navigation cycle ${[...cycle, cycle[0]].join(' -> ')}: each screen is placed in an outlet owned by the next, so composition never terminates.`,\n });\n }\n\n return diagnostics;\n}\n\ntype Report = (code: NavigationDiagnosticCode, message: string) => void;\n\nfunction diagnoseTarget(\n graph: NavigationGraph,\n screens: Map<string, Screen> | undefined,\n destination: DestinationReference,\n kind: DestinationKind,\n entry: string,\n report: Report,\n) {\n if (kind === DestinationKind.Dialog) {\n if (!destination.dialog) {\n report(NavigationDiagnosticCode.UnavailableTarget, `Dialog destination '${entry}' names no dialog.`);\n } else if (graph.dialogTemplates && !graph.dialogTemplates.some(template => template.name === destination.dialog)) {\n report(NavigationDiagnosticCode.UnavailableTarget, `Destination '${entry}' opens dialog '${destination.dialog}', which no dialog template provides.`);\n }\n return;\n }\n\n if (kind === DestinationKind.Outlet && destination.screen && screens && !screens.has(destination.screen)) {\n report(NavigationDiagnosticCode.UnavailableTarget, `Destination '${entry}' opens screen '${destination.screen}', which does not exist.`);\n }\n}\n\nfunction diagnoseOutlet(\n graph: NavigationGraph,\n outlets: Map<string, OutletOwner>,\n screens: Map<string, Screen> | undefined,\n destination: DestinationReference,\n kind: DestinationKind,\n entry: string,\n report: Report,\n): OutletOwner | undefined {\n if (!destination.outlet) return undefined;\n\n if (kind !== DestinationKind.Outlet) {\n const opens = kind === DestinationKind.Dialog ? 'a dialog' : 'an external target';\n report(NavigationDiagnosticCode.IncompatibleOutlet, `Destination '${entry}' opens ${opens} but names outlet '${destination.outlet}'; only outlet destinations render in outlets.`);\n return undefined;\n }\n\n const owner = outlets.get(destination.outlet);\n if (!owner) {\n report(NavigationDiagnosticCode.MissingOutlet, `Destination '${entry}' targets missing outlet '${destination.outlet}'.`);\n return undefined;\n }\n\n const screen = destination.screen ? screens?.get(destination.screen) : undefined;\n if (!screen) return owner;\n\n if (owner.ownerKind === 'Layout' && screen.layout !== owner.owner) {\n report(\n NavigationDiagnosticCode.IncompatibleOutlet,\n `Outlet '${owner.outlet.name}' belongs to layout '${owner.owner}', but destination '${entry}' places '${screen.name}', which renders in layout '${screen.layout}'.`,\n );\n }\n\n if (owner.outlet.accepts) {\n const type = graph.screenTemplates?.find(template => template.name === screen.screenTemplate)?.metadata?.type;\n if (!type || !owner.outlet.accepts.includes(type)) {\n report(\n NavigationDiagnosticCode.IncompatibleOutlet,\n `Outlet '${owner.outlet.name}' accepts ${owner.outlet.accepts.join(', ')} screens, but destination '${entry}' places '${screen.name}' of type '${type ?? 'untyped'}'.`,\n );\n }\n }\n\n return owner;\n}\n"],"names":["diagnoseNavigation","graph","routeKey","authoredRouteKey","diagnostics","outlets","collectOutlets","screens","Map","map","screen","name","undefined","routes","hostedIn","entries","forEach","navigationEntry","index","entry","id","destination","kind","dialog","DestinationKind","Dialog","Outlet","report","code","message","push","module","route","NavigationDiagnosticCode","UnavailableTarget","diagnoseTarget","owner","diagnoseOutlet","ownerKind","has","hosts","filter","screenTemplate","set","Set","get","External","target","navigationTarget","existing","DuplicateRoute","cycle","findHostingCycles","NavigationCycle","join","dialogTemplates","some","template","outlet","opens","IncompatibleOutlet","MissingOutlet","layout","accepts","type","screenTemplates","find","metadata","includes"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"diagnoseNavigation.js","sources":["../../../navigation/diagnoseNavigation.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { DestinationKind, DestinationReference, Screen } from '@cratis/scene.model';\nimport { collectOutlets } from './collectOutlets';\nimport { diagnoseNavigationRegions } from './diagnoseNavigationRegions';\nimport { findHostingCycles } from './findHostingCycles';\nimport { NavigationDiagnostic } from './NavigationDiagnostic';\nimport { NavigationDiagnosticCode } from './NavigationDiagnosticCode';\nimport { NavigationGraph } from './NavigationGraph';\nimport { NavigationRouteKey, authoredRouteKey, navigationTarget } from './navigationRoute';\nimport { OutletOwner } from './OutletOwner';\n\n/**\n * Diagnoses how destinations, outlets, routes and targets fit together: duplicate routes, duplicate,\n * missing or incompatible outlets, hosting cycles and unavailable targets.\n *\n * Routes are compared by `routeKey` - by default the authored route override, since the engine constructs no\n * URLs. Nothing is rewritten. The C# engine (`NavigationDiagnostics.Diagnose`) reports the same codes and\n * messages in the same order for the same model; both are asserted against `navigation-diagnostic-fixtures.json`. When the graph carries\nan application `structure` and `navigation` regions, the regions are checked too ({@link diagnoseNavigationRegions}).\n */\nexport function diagnoseNavigation(graph: NavigationGraph, routeKey: NavigationRouteKey = authoredRouteKey): NavigationDiagnostic[] {\n const diagnostics: NavigationDiagnostic[] = [];\n const outlets = collectOutlets(graph, diagnostics);\n const screens = graph.screens ? new Map(graph.screens.map(screen => [screen.name, screen])) : undefined;\n const routes = new Map<string, { entry: string; target: string }>();\n const hostedIn = new Map<string, string[]>();\n\n graph.entries.forEach((navigationEntry, index) => {\n const entry = navigationEntry.id ?? `#${index + 1}`;\n const destination = navigationEntry.destination;\n const kind = destination.kind ?? (destination.dialog ? DestinationKind.Dialog : DestinationKind.Outlet);\n const report = (code: NavigationDiagnosticCode, message: string) => diagnostics.push({ code, message, entry });\n\n if (!destination.screen && !destination.module && !destination.route && !destination.dialog) {\n report(NavigationDiagnosticCode.UnavailableTarget, `Destination '${entry}' names no screen, stable identity, route or dialog.`);\n return;\n }\n\n diagnoseTarget(graph, screens, destination, kind, entry, report);\n const owner = diagnoseOutlet(graph, outlets, screens, destination, kind, entry, report);\n if (owner?.ownerKind === 'ScreenTemplate' && destination.screen && screens?.has(destination.screen)) {\n const hosts = graph.screens!.filter(screen => screen.screenTemplate === owner.owner).map(screen => screen.name);\n hostedIn.set(destination.screen, [...new Set([...(hostedIn.get(destination.screen) ?? []), ...hosts])]);\n }\n\n const route = kind === DestinationKind.External ? undefined : routeKey(destination);\n if (route) {\n const target = navigationTarget(destination, kind);\n const existing = routes.get(route);\n if (!existing) {\n routes.set(route, { entry, target });\n } else if (existing.target !== target) {\n report(NavigationDiagnosticCode.DuplicateRoute, `Route '${destination.route ?? route}' is used by destinations '${existing.entry}' and '${entry}', which open different targets.`);\n }\n }\n });\n\n for (const cycle of findHostingCycles(graph.screens?.map(screen => screen.name) ?? [], hostedIn)) {\n diagnostics.push({\n code: NavigationDiagnosticCode.NavigationCycle,\n message: `Navigation cycle ${[...cycle, cycle[0]].join(' -> ')}: each screen is placed in an outlet owned by the next, so composition never terminates.`,\n });\n }\n\n if (graph.structure && graph.navigation) {\n diagnostics.push(...diagnoseNavigationRegions(graph.structure, graph.navigation, { slots: graph.slots }));\n }\n\n return diagnostics;\n}\n\ntype Report = (code: NavigationDiagnosticCode, message: string) => void;\n\nfunction diagnoseTarget(\n graph: NavigationGraph,\n screens: Map<string, Screen> | undefined,\n destination: DestinationReference,\n kind: DestinationKind,\n entry: string,\n report: Report,\n) {\n if (kind === DestinationKind.Dialog) {\n if (!destination.dialog) {\n report(NavigationDiagnosticCode.UnavailableTarget, `Dialog destination '${entry}' names no dialog.`);\n } else if (graph.dialogTemplates && !graph.dialogTemplates.some(template => template.name === destination.dialog)) {\n report(NavigationDiagnosticCode.UnavailableTarget, `Destination '${entry}' opens dialog '${destination.dialog}', which no dialog template provides.`);\n }\n return;\n }\n\n if (kind === DestinationKind.Outlet && destination.screen && screens && !screens.has(destination.screen)) {\n report(NavigationDiagnosticCode.UnavailableTarget, `Destination '${entry}' opens screen '${destination.screen}', which does not exist.`);\n }\n}\n\nfunction diagnoseOutlet(\n graph: NavigationGraph,\n outlets: Map<string, OutletOwner>,\n screens: Map<string, Screen> | undefined,\n destination: DestinationReference,\n kind: DestinationKind,\n entry: string,\n report: Report,\n): OutletOwner | undefined {\n if (!destination.outlet) return undefined;\n\n if (kind !== DestinationKind.Outlet) {\n const opens = kind === DestinationKind.Dialog ? 'a dialog' : 'an external target';\n report(NavigationDiagnosticCode.IncompatibleOutlet, `Destination '${entry}' opens ${opens} but names outlet '${destination.outlet}'; only outlet destinations render in outlets.`);\n return undefined;\n }\n\n const owner = outlets.get(destination.outlet);\n if (!owner) {\n report(NavigationDiagnosticCode.MissingOutlet, `Destination '${entry}' targets missing outlet '${destination.outlet}'.`);\n return undefined;\n }\n\n const screen = destination.screen ? screens?.get(destination.screen) : undefined;\n if (!screen) return owner;\n\n if (owner.ownerKind === 'Layout' && screen.layout !== owner.owner) {\n report(\n NavigationDiagnosticCode.IncompatibleOutlet,\n `Outlet '${owner.outlet.name}' belongs to layout '${owner.owner}', but destination '${entry}' places '${screen.name}', which renders in layout '${screen.layout}'.`,\n );\n }\n\n if (owner.outlet.accepts) {\n const type = graph.screenTemplates?.find(template => template.name === screen.screenTemplate)?.metadata?.type;\n if (!type || !owner.outlet.accepts.includes(type)) {\n report(\n NavigationDiagnosticCode.IncompatibleOutlet,\n `Outlet '${owner.outlet.name}' accepts ${owner.outlet.accepts.join(', ')} screens, but destination '${entry}' places '${screen.name}' of type '${type ?? 'untyped'}'.`,\n );\n }\n }\n\n return owner;\n}\n"],"names":["diagnoseNavigation","graph","routeKey","authoredRouteKey","diagnostics","outlets","collectOutlets","screens","Map","map","screen","name","undefined","routes","hostedIn","entries","forEach","navigationEntry","index","entry","id","destination","kind","dialog","DestinationKind","Dialog","Outlet","report","code","message","push","module","route","NavigationDiagnosticCode","UnavailableTarget","diagnoseTarget","owner","diagnoseOutlet","ownerKind","has","hosts","filter","screenTemplate","set","Set","get","External","target","navigationTarget","existing","DuplicateRoute","cycle","findHostingCycles","NavigationCycle","join","structure","navigation","diagnoseNavigationRegions","slots","dialogTemplates","some","template","outlet","opens","IncompatibleOutlet","MissingOutlet","layout","accepts","type","screenTemplates","find","metadata","includes"],"mappings":"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"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var scene_model = require('@cratis/scene.model');
|
|
4
|
+
var ApplicationStructureIndex = require('../structure/ApplicationStructureIndex.js');
|
|
5
|
+
var NavigationDiagnosticCode = require('./NavigationDiagnosticCode.js');
|
|
6
|
+
var navigationRegions = require('./navigationRegions.js');
|
|
7
|
+
|
|
8
|
+
// Copyright (c) Cratis. All rights reserved.
|
|
9
|
+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
10
|
+
/**
|
|
11
|
+
* Diagnoses the navigation regions of an application against its structure: duplicate item ids, targets that are
|
|
12
|
+
* missing, out of scope or lead nowhere, and slots the layout does not declare. The application is checked first,
|
|
13
|
+
* then each module in the order they are declared; within a level the topbar comes before the sidebar and items are
|
|
14
|
+
* visited depth first.
|
|
15
|
+
*
|
|
16
|
+
* The C# engine (`NavigationRegionDiagnostics`) reports the same codes and messages in the same order; both are
|
|
17
|
+
* asserted against `navigation-inheritance-fixtures.json`, `navigation-targets-fixtures.json` and
|
|
18
|
+
* `navigation-diagnostic-fixtures.json`.
|
|
19
|
+
*
|
|
20
|
+
* @param structure The modules, features and slices of the application.
|
|
21
|
+
* @param navigation The application and module regions.
|
|
22
|
+
* @param options The slots items may render into.
|
|
23
|
+
*/ function diagnoseNavigationRegions(structure, navigation, options = {}) {
|
|
24
|
+
const index = structure instanceof ApplicationStructureIndex.ApplicationStructureIndex ? structure : new ApplicationStructureIndex.ApplicationStructureIndex(structure);
|
|
25
|
+
const slots = options.slots ?? [
|
|
26
|
+
navigationRegions.primarySlot
|
|
27
|
+
];
|
|
28
|
+
const diagnostics = [];
|
|
29
|
+
for (const region of navigationRegions.navigationRegionOrder){
|
|
30
|
+
const defined = navigationRegions.findNavigationRegion(navigation.application.regions, region);
|
|
31
|
+
if (defined) checkRegion(index, slots, diagnostics, undefined, defined, []);
|
|
32
|
+
}
|
|
33
|
+
for (const moduleNavigation of navigation.modules){
|
|
34
|
+
for (const region of navigationRegions.navigationRegionOrder){
|
|
35
|
+
const defined = navigationRegions.findNavigationRegion(moduleNavigation.regions, region);
|
|
36
|
+
if (!defined) continue;
|
|
37
|
+
const inherited = defined.mode === scene_model.NavigationRegionMode.Extend ? navigationRegions.collectItemIds(navigationRegions.applicationItems(navigation.application, region), region) : [];
|
|
38
|
+
checkRegion(index, slots, diagnostics, moduleNavigation.module, defined, inherited);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return diagnostics;
|
|
42
|
+
}
|
|
43
|
+
function checkRegion(index, slots, diagnostics, owner, defined, applicationIds) {
|
|
44
|
+
const scope = owner === undefined ? 'the application' : `module '${owner}'`;
|
|
45
|
+
const seen = new Set();
|
|
46
|
+
const visit = (items)=>{
|
|
47
|
+
for (const item of items){
|
|
48
|
+
const entry = `${owner ?? 'application'}:${defined.region}:${item.id}`;
|
|
49
|
+
const report = (code, message)=>{
|
|
50
|
+
diagnostics.push({
|
|
51
|
+
code,
|
|
52
|
+
message,
|
|
53
|
+
entry
|
|
54
|
+
});
|
|
55
|
+
};
|
|
56
|
+
if (seen.has(item.id)) {
|
|
57
|
+
report(NavigationDiagnosticCode.NavigationDiagnosticCode.NavDuplicateId, `Navigation item '${item.id}' is used more than once in ${scope} ${defined.region}.`);
|
|
58
|
+
} else if (applicationIds.includes(item.id)) {
|
|
59
|
+
report(NavigationDiagnosticCode.NavigationDiagnosticCode.NavDuplicateId, `Navigation item '${item.id}' in ${scope} ${defined.region} is also used by an application item, and the region extends the application.`);
|
|
60
|
+
}
|
|
61
|
+
seen.add(item.id);
|
|
62
|
+
checkTarget(index, owner, item, report);
|
|
63
|
+
const slot = item.slot ?? navigationRegions.primarySlot;
|
|
64
|
+
if (!slots.includes(slot)) {
|
|
65
|
+
report(NavigationDiagnosticCode.NavigationDiagnosticCode.NavSlotUnknown, `Navigation item '${item.id}' renders into slot '${slot}', which the layout does not declare.`);
|
|
66
|
+
}
|
|
67
|
+
if (defined.region === scene_model.NavigationRegionKind.Sidebar && item.children) visit(item.children);
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
visit(defined.items);
|
|
71
|
+
}
|
|
72
|
+
function checkTarget(index, owner, item, report) {
|
|
73
|
+
const module = item.target?.module;
|
|
74
|
+
const hasChildren = (item.children?.length ?? 0) > 0;
|
|
75
|
+
if (!module) {
|
|
76
|
+
// A sidebar item that only groups sub-items needs no target of its own.
|
|
77
|
+
if (!hasChildren) report(NavigationDiagnosticCode.NavigationDiagnosticCode.NavTargetMissing, `Navigation item '${item.id}' has no target.`);
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
if (!index.findModule(module)) {
|
|
81
|
+
report(NavigationDiagnosticCode.NavigationDiagnosticCode.NavTargetMissing, `Navigation item '${item.id}' targets module '${module}', which does not exist.`);
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
if (owner !== undefined && module !== owner) {
|
|
85
|
+
report(NavigationDiagnosticCode.NavigationDiagnosticCode.NavTargetOutOfScope, `Navigation item '${item.id}' of module '${owner}' targets module '${module}'; a module's own items may only target that module.`);
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
const feature = item.target?.feature;
|
|
89
|
+
if (feature) {
|
|
90
|
+
if (!index.findFeature(`${module}.${feature}`)) {
|
|
91
|
+
report(NavigationDiagnosticCode.NavigationDiagnosticCode.NavTargetMissing, `Navigation item '${item.id}' targets feature '${module}.${feature}', which does not exist.`);
|
|
92
|
+
}
|
|
93
|
+
} else if (!index.firstFeature(module)) {
|
|
94
|
+
report(NavigationDiagnosticCode.NavigationDiagnosticCode.NavModuleWithoutFeatures, `Navigation item '${item.id}' targets module '${module}', which has no features to go to.`);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
exports.diagnoseNavigationRegions = diagnoseNavigationRegions;
|
|
99
|
+
//# sourceMappingURL=diagnoseNavigationRegions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diagnoseNavigationRegions.js","sources":["../../../navigation/diagnoseNavigationRegions.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { ApplicationStructure, NavigationModel, NavigationRegion, NavigationRegionKind, NavigationRegionMode, NavItem } from '@cratis/scene.model';\nimport { ApplicationStructureIndex } from '../structure';\nimport { NavigationDiagnostic } from './NavigationDiagnostic';\nimport { NavigationDiagnosticCode } from './NavigationDiagnosticCode';\nimport { applicationItems, collectItemIds, findNavigationRegion, navigationRegionOrder, primarySlot } from './navigationRegions';\n\n/** What the region diagnostics are checked against. */\nexport interface NavigationRegionDiagnosticOptions {\n /** The rendering slots items may render into; `content` only when absent. */\n slots?: string[];\n}\n\n/**\n * Diagnoses the navigation regions of an application against its structure: duplicate item ids, targets that are\n * missing, out of scope or lead nowhere, and slots the layout does not declare. The application is checked first,\n * then each module in the order they are declared; within a level the topbar comes before the sidebar and items are\n * visited depth first.\n *\n * The C# engine (`NavigationRegionDiagnostics`) reports the same codes and messages in the same order; both are\n * asserted against `navigation-inheritance-fixtures.json`, `navigation-targets-fixtures.json` and\n * `navigation-diagnostic-fixtures.json`.\n *\n * @param structure The modules, features and slices of the application.\n * @param navigation The application and module regions.\n * @param options The slots items may render into.\n */\nexport function diagnoseNavigationRegions(\n structure: ApplicationStructure | ApplicationStructureIndex,\n navigation: NavigationModel,\n options: NavigationRegionDiagnosticOptions = {},\n): NavigationDiagnostic[] {\n const index = structure instanceof ApplicationStructureIndex ? structure : new ApplicationStructureIndex(structure);\n const slots = options.slots ?? [primarySlot];\n const diagnostics: NavigationDiagnostic[] = [];\n\n for (const region of navigationRegionOrder) {\n const defined = findNavigationRegion(navigation.application.regions, region);\n if (defined) checkRegion(index, slots, diagnostics, undefined, defined, []);\n }\n\n for (const moduleNavigation of navigation.modules) {\n for (const region of navigationRegionOrder) {\n const defined = findNavigationRegion(moduleNavigation.regions, region);\n if (!defined) continue;\n\n const inherited = defined.mode === NavigationRegionMode.Extend ? collectItemIds(applicationItems(navigation.application, region), region) : [];\n checkRegion(index, slots, diagnostics, moduleNavigation.module, defined, inherited);\n }\n }\n\n return diagnostics;\n}\n\nfunction checkRegion(\n index: ApplicationStructureIndex,\n slots: string[],\n diagnostics: NavigationDiagnostic[],\n owner: string | undefined,\n defined: NavigationRegion,\n applicationIds: string[],\n): void {\n const scope = owner === undefined ? 'the application' : `module '${owner}'`;\n const seen = new Set<string>();\n\n const visit = (items: NavItem[]): void => {\n for (const item of items) {\n const entry = `${owner ?? 'application'}:${defined.region}:${item.id}`;\n const report = (code: NavigationDiagnosticCode, message: string): void => { diagnostics.push({ code, message, entry }); };\n\n if (seen.has(item.id)) {\n report(NavigationDiagnosticCode.NavDuplicateId, `Navigation item '${item.id}' is used more than once in ${scope} ${defined.region}.`);\n } else if (applicationIds.includes(item.id)) {\n report(NavigationDiagnosticCode.NavDuplicateId, `Navigation item '${item.id}' in ${scope} ${defined.region} is also used by an application item, and the region extends the application.`);\n }\n seen.add(item.id);\n\n checkTarget(index, owner, item, report);\n\n const slot = item.slot ?? primarySlot;\n if (!slots.includes(slot)) {\n report(NavigationDiagnosticCode.NavSlotUnknown, `Navigation item '${item.id}' renders into slot '${slot}', which the layout does not declare.`);\n }\n\n if (defined.region === NavigationRegionKind.Sidebar && item.children) visit(item.children);\n }\n };\n\n visit(defined.items);\n}\n\nfunction checkTarget(index: ApplicationStructureIndex, owner: string | undefined, item: NavItem, report: (code: NavigationDiagnosticCode, message: string) => void): void {\n const module = item.target?.module;\n const hasChildren = (item.children?.length ?? 0) > 0;\n\n if (!module) {\n // A sidebar item that only groups sub-items needs no target of its own.\n if (!hasChildren) report(NavigationDiagnosticCode.NavTargetMissing, `Navigation item '${item.id}' has no target.`);\n return;\n }\n\n if (!index.findModule(module)) {\n report(NavigationDiagnosticCode.NavTargetMissing, `Navigation item '${item.id}' targets module '${module}', which does not exist.`);\n return;\n }\n\n if (owner !== undefined && module !== owner) {\n report(NavigationDiagnosticCode.NavTargetOutOfScope, `Navigation item '${item.id}' of module '${owner}' targets module '${module}'; a module's own items may only target that module.`);\n return;\n }\n\n const feature = item.target?.feature;\n if (feature) {\n if (!index.findFeature(`${module}.${feature}`)) {\n report(NavigationDiagnosticCode.NavTargetMissing, `Navigation item '${item.id}' targets feature '${module}.${feature}', which does not exist.`);\n }\n } else if (!index.firstFeature(module)) {\n report(NavigationDiagnosticCode.NavModuleWithoutFeatures, `Navigation item '${item.id}' targets module '${module}', which has no features to go to.`);\n }\n}\n"],"names":["diagnoseNavigationRegions","structure","navigation","options","index","ApplicationStructureIndex","slots","primarySlot","diagnostics","region","navigationRegionOrder","defined","findNavigationRegion","application","regions","checkRegion","undefined","moduleNavigation","modules","inherited","mode","NavigationRegionMode","Extend","collectItemIds","applicationItems","module","owner","applicationIds","scope","seen","Set","visit","items","item","entry","id","report","code","message","push","has","NavigationDiagnosticCode","NavDuplicateId","includes","add","checkTarget","slot","NavSlotUnknown","NavigationRegionKind","Sidebar","children","target","hasChildren","length","NavTargetMissing","findModule","NavTargetOutOfScope","feature","findFeature","firstFeature","NavModuleWithoutFeatures"],"mappings":"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"}
|