@cratis/scene.engine 4.3.0 → 4.4.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.
Files changed (141) hide show
  1. package/dist/cjs/editing/collectIconUsages.js +86 -0
  2. package/dist/cjs/editing/collectIconUsages.js.map +1 -0
  3. package/dist/cjs/editing/diagnoseIcons.js +67 -0
  4. package/dist/cjs/editing/diagnoseIcons.js.map +1 -0
  5. package/dist/cjs/editing/iconDiagnostics.js +103 -0
  6. package/dist/cjs/editing/iconDiagnostics.js.map +1 -0
  7. package/dist/cjs/editing/inspect.js +28 -1
  8. package/dist/cjs/editing/inspect.js.map +1 -1
  9. package/dist/cjs/editing/instanceEdits.js +15 -3
  10. package/dist/cjs/editing/instanceEdits.js.map +1 -1
  11. package/dist/cjs/editing/propertyEdits.js +7 -0
  12. package/dist/cjs/editing/propertyEdits.js.map +1 -1
  13. package/dist/cjs/icons/EffectiveIconCatalog.js +212 -0
  14. package/dist/cjs/icons/EffectiveIconCatalog.js.map +1 -0
  15. package/dist/cjs/icons/EffectiveIconEntry.js +22 -0
  16. package/dist/cjs/icons/EffectiveIconEntry.js.map +1 -0
  17. package/dist/cjs/icons/analyzeIconImpact.js +48 -0
  18. package/dist/cjs/icons/analyzeIconImpact.js.map +1 -0
  19. package/dist/cjs/icons/matchesIconQuery.js +22 -0
  20. package/dist/cjs/icons/matchesIconQuery.js.map +1 -0
  21. package/dist/cjs/icons/resolveIconLibraries.js +45 -0
  22. package/dist/cjs/icons/resolveIconLibraries.js.map +1 -0
  23. package/dist/cjs/index.js +16 -0
  24. package/dist/cjs/index.js.map +1 -1
  25. package/dist/esm/editing/EditingContext.d.ts +2 -0
  26. package/dist/esm/editing/EditingContext.d.ts.map +1 -1
  27. package/dist/esm/editing/collectIconUsages.d.ts +5 -0
  28. package/dist/esm/editing/collectIconUsages.d.ts.map +1 -0
  29. package/dist/esm/editing/collectIconUsages.js +84 -0
  30. package/dist/esm/editing/collectIconUsages.js.map +1 -0
  31. package/dist/esm/editing/diagnoseIcons.d.ts +4 -0
  32. package/dist/esm/editing/diagnoseIcons.d.ts.map +1 -0
  33. package/dist/esm/editing/diagnoseIcons.js +65 -0
  34. package/dist/esm/editing/diagnoseIcons.js.map +1 -0
  35. package/dist/esm/editing/iconDiagnostics.d.ts +11 -0
  36. package/dist/esm/editing/iconDiagnostics.d.ts.map +1 -0
  37. package/dist/esm/editing/iconDiagnostics.js +99 -0
  38. package/dist/esm/editing/iconDiagnostics.js.map +1 -0
  39. package/dist/esm/editing/index.d.ts +3 -0
  40. package/dist/esm/editing/index.d.ts.map +1 -1
  41. package/dist/esm/editing/index.js +3 -0
  42. package/dist/esm/editing/index.js.map +1 -1
  43. package/dist/esm/editing/inspect.d.ts.map +1 -1
  44. package/dist/esm/editing/inspect.js +29 -2
  45. package/dist/esm/editing/inspect.js.map +1 -1
  46. package/dist/esm/editing/instanceEdits.d.ts.map +1 -1
  47. package/dist/esm/editing/instanceEdits.js +17 -5
  48. package/dist/esm/editing/instanceEdits.js.map +1 -1
  49. package/dist/esm/editing/propertyEdits.d.ts.map +1 -1
  50. package/dist/esm/editing/propertyEdits.js +9 -2
  51. package/dist/esm/editing/propertyEdits.js.map +1 -1
  52. package/dist/esm/icons/EffectiveIconCatalog.d.ts +25 -0
  53. package/dist/esm/icons/EffectiveIconCatalog.d.ts.map +1 -0
  54. package/dist/esm/icons/EffectiveIconCatalog.js +210 -0
  55. package/dist/esm/icons/EffectiveIconCatalog.js.map +1 -0
  56. package/dist/esm/icons/EffectiveIconEntry.d.ts +9 -0
  57. package/dist/esm/icons/EffectiveIconEntry.d.ts.map +1 -0
  58. package/dist/esm/icons/EffectiveIconEntry.js +20 -0
  59. package/dist/esm/icons/EffectiveIconEntry.js.map +1 -0
  60. package/dist/esm/icons/IconCatalogSource.d.ts +6 -0
  61. package/dist/esm/icons/IconCatalogSource.d.ts.map +1 -0
  62. package/dist/esm/icons/IconCatalogSource.js +2 -0
  63. package/dist/esm/icons/IconCatalogSource.js.map +1 -0
  64. package/dist/esm/icons/IconDiagnostic.d.ts +9 -0
  65. package/dist/esm/icons/IconDiagnostic.d.ts.map +1 -0
  66. package/dist/esm/icons/IconDiagnostic.js +2 -0
  67. package/dist/esm/icons/IconDiagnostic.js.map +1 -0
  68. package/dist/esm/icons/IconImpactReport.d.ts +18 -0
  69. package/dist/esm/icons/IconImpactReport.d.ts.map +1 -0
  70. package/dist/esm/icons/IconImpactReport.js +2 -0
  71. package/dist/esm/icons/IconImpactReport.js.map +1 -0
  72. package/dist/esm/icons/IconLibraryResolution.d.ts +7 -0
  73. package/dist/esm/icons/IconLibraryResolution.d.ts.map +1 -0
  74. package/dist/esm/icons/IconLibraryResolution.js +2 -0
  75. package/dist/esm/icons/IconLibraryResolution.js.map +1 -0
  76. package/dist/esm/icons/IconQuery.d.ts +7 -0
  77. package/dist/esm/icons/IconQuery.d.ts.map +1 -0
  78. package/dist/esm/icons/IconQuery.js +2 -0
  79. package/dist/esm/icons/IconQuery.js.map +1 -0
  80. package/dist/esm/icons/IconResolution.d.ts +14 -0
  81. package/dist/esm/icons/IconResolution.d.ts.map +1 -0
  82. package/dist/esm/icons/IconResolution.js +2 -0
  83. package/dist/esm/icons/IconResolution.js.map +1 -0
  84. package/dist/esm/icons/IconSearchResult.d.ts +7 -0
  85. package/dist/esm/icons/IconSearchResult.d.ts.map +1 -0
  86. package/dist/esm/icons/IconSearchResult.js +2 -0
  87. package/dist/esm/icons/IconSearchResult.js.map +1 -0
  88. package/dist/esm/icons/IconUsage.d.ts +6 -0
  89. package/dist/esm/icons/IconUsage.d.ts.map +1 -0
  90. package/dist/esm/icons/IconUsage.js +2 -0
  91. package/dist/esm/icons/IconUsage.js.map +1 -0
  92. package/dist/esm/icons/ResolvedIconLibrary.d.ts +8 -0
  93. package/dist/esm/icons/ResolvedIconLibrary.d.ts.map +1 -0
  94. package/dist/esm/icons/ResolvedIconLibrary.js +2 -0
  95. package/dist/esm/icons/ResolvedIconLibrary.js.map +1 -0
  96. package/dist/esm/icons/analyzeIconImpact.d.ts +5 -0
  97. package/dist/esm/icons/analyzeIconImpact.d.ts.map +1 -0
  98. package/dist/esm/icons/analyzeIconImpact.js +46 -0
  99. package/dist/esm/icons/analyzeIconImpact.js.map +1 -0
  100. package/dist/esm/icons/index.d.ts +14 -0
  101. package/dist/esm/icons/index.d.ts.map +1 -0
  102. package/dist/esm/icons/index.js +14 -0
  103. package/dist/esm/icons/index.js.map +1 -0
  104. package/dist/esm/icons/matchesIconQuery.d.ts +4 -0
  105. package/dist/esm/icons/matchesIconQuery.d.ts.map +1 -0
  106. package/dist/esm/icons/matchesIconQuery.js +20 -0
  107. package/dist/esm/icons/matchesIconQuery.js.map +1 -0
  108. package/dist/esm/icons/resolveIconLibraries.d.ts +4 -0
  109. package/dist/esm/icons/resolveIconLibraries.d.ts.map +1 -0
  110. package/dist/esm/icons/resolveIconLibraries.js +43 -0
  111. package/dist/esm/icons/resolveIconLibraries.js.map +1 -0
  112. package/dist/esm/index.d.ts +1 -0
  113. package/dist/esm/index.d.ts.map +1 -1
  114. package/dist/esm/index.js +7 -0
  115. package/dist/esm/index.js.map +1 -1
  116. package/dist/esm/tsconfig.tsbuildinfo +1 -1
  117. package/editing/EditingContext.ts +11 -0
  118. package/editing/collectIconUsages.ts +78 -0
  119. package/editing/diagnoseIcons.ts +60 -0
  120. package/editing/iconDiagnostics.ts +90 -0
  121. package/editing/index.ts +3 -0
  122. package/editing/inspect.ts +25 -2
  123. package/editing/instanceEdits.ts +13 -5
  124. package/editing/propertyEdits.ts +10 -2
  125. package/icons/EffectiveIconCatalog.ts +199 -0
  126. package/icons/EffectiveIconEntry.ts +36 -0
  127. package/icons/IconCatalogSource.ts +23 -0
  128. package/icons/IconDiagnostic.ts +45 -0
  129. package/icons/IconImpactReport.ts +63 -0
  130. package/icons/IconLibraryResolution.ts +22 -0
  131. package/icons/IconQuery.ts +27 -0
  132. package/icons/IconResolution.ts +25 -0
  133. package/icons/IconSearchResult.ts +21 -0
  134. package/icons/IconUsage.ts +21 -0
  135. package/icons/ResolvedIconLibrary.ts +32 -0
  136. package/icons/analyzeIconImpact.ts +41 -0
  137. package/icons/index.ts +16 -0
  138. package/icons/matchesIconQuery.ts +19 -0
  139. package/icons/resolveIconLibraries.ts +47 -0
  140. package/index.ts +1 -0
  141. package/package.json +3 -3
@@ -0,0 +1,86 @@
1
+ 'use strict';
2
+
3
+ var scene_model = require('@cratis/scene.model');
4
+ var collectComponents = require('./collectComponents.js');
5
+ var DescriptorCatalog = require('./DescriptorCatalog.js');
6
+ var pathAccess = require('./pathAccess.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
+ function iconFields(property) {
11
+ return (property.item?.properties ?? []).filter((field)=>field.valueType === scene_model.PropertyValueType.Icon).map((field)=>field.path);
12
+ }
13
+ function usagesOf(property, value, items, location) {
14
+ if (property.valueType === scene_model.PropertyValueType.Icon) {
15
+ return value === undefined ? [] : [
16
+ {
17
+ value: value,
18
+ location: `${location}:${property.path}`
19
+ }
20
+ ];
21
+ }
22
+ return property.valueType === scene_model.PropertyValueType.Collection ? (items ?? []).flatMap((item)=>iconFields(property).filter((field)=>item.values[field] !== undefined).map((field)=>({
23
+ value: item.values[field],
24
+ location: `${location}:${property.path}:${item.id}:${field}`
25
+ }))) : [];
26
+ }
27
+ function ownerItems(value) {
28
+ return (Array.isArray(value) ? value : []).filter((item)=>item !== null && typeof item === 'object').map(({ id, ...values })=>({
29
+ id: String(id),
30
+ values
31
+ }));
32
+ }
33
+ /**
34
+ * Finds every icon value stored anywhere in a document - the values components carry themselves, and the values
35
+ * and collection-item icon fields that template instances contributed - as the `IconUsage`s that
36
+ * `analyzeIconImpact` takes, so "what would removing this library break" can be asked of a whole document.
37
+ *
38
+ * Each usage's `location` reads `<owner or instance>:<component>:<path>[:<itemId>:<field>]`, where the first part is
39
+ * the contributing instance id (`screen:Orders`) for a contributed value and the name of the owning layout or
40
+ * template for a value the component carries. Values are read as stored; none are changed.
41
+ *
42
+ * @param document The document to read.
43
+ * @param catalog The descriptors saying which properties are icons.
44
+ */ function collectIconUsages(document, catalog) {
45
+ const usages = [];
46
+ const componentNames = new Map();
47
+ const owners = [
48
+ ...document.layouts.map((layout)=>({
49
+ name: layout.name,
50
+ value: layout
51
+ })),
52
+ ...document.screenTemplates.map((template)=>({
53
+ name: template.name,
54
+ value: template
55
+ })),
56
+ ...document.dialogTemplates.map((template)=>({
57
+ name: template.name,
58
+ value: template
59
+ })),
60
+ ...document.screens.map((screen)=>({
61
+ name: screen.name,
62
+ value: screen
63
+ }))
64
+ ];
65
+ for (const owner of owners){
66
+ for (const component of collectComponents.collectComponents(owner.value)){
67
+ if (!componentNames.has(component.id)) componentNames.set(component.id, component.componentName);
68
+ for (const property of DescriptorCatalog.findComponentDescriptor(catalog, component.componentName)?.properties ?? []){
69
+ const value = pathAccess.getValueAtPath(component.properties, property.path);
70
+ usages.push(...usagesOf(property, value, ownerItems(value), `${owner.name}:${component.id}`));
71
+ }
72
+ }
73
+ }
74
+ for (const contribution of document.instanceContributions){
75
+ const componentName = componentNames.get(contribution.component);
76
+ const property = componentName === undefined ? undefined : DescriptorCatalog.findComponentDescriptor(catalog, componentName)?.properties.find((candidate)=>candidate.path === contribution.path);
77
+ if (property) usages.push(...contributedUsages(property, contribution));
78
+ }
79
+ return usages;
80
+ }
81
+ function contributedUsages(property, contribution) {
82
+ return usagesOf(property, contribution.value, contribution.items, `${contribution.instance}:${contribution.component}`);
83
+ }
84
+
85
+ exports.collectIconUsages = collectIconUsages;
86
+ //# sourceMappingURL=collectIconUsages.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"collectIconUsages.js","sources":["../../../editing/collectIconUsages.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 { InstanceContribution, PropertyDescriptor, PropertyValueType, SceneDocument } from '@cratis/scene.model';\nimport { IconUsage } from '../icons/IconUsage';\nimport { collectComponents } from './collectComponents';\nimport { DescriptorCatalog, findComponentDescriptor } from './DescriptorCatalog';\nimport { getValueAtPath } from './pathAccess';\n\nfunction iconFields(property: PropertyDescriptor): string[] {\n return (property.item?.properties ?? []).filter((field) => field.valueType === PropertyValueType.Icon).map((field) => field.path);\n}\n\nfunction usagesOf(property: PropertyDescriptor, value: unknown, items: { id: string; values: Record<string, unknown> }[] | undefined, location: string): IconUsage[] {\n if (property.valueType === PropertyValueType.Icon) {\n return value === undefined ? [] : [{ value: value as IconUsage['value'], location: `${location}:${property.path}` }];\n }\n\n return property.valueType === PropertyValueType.Collection\n ? (items ?? []).flatMap((item) =>\n iconFields(property)\n .filter((field) => item.values[field] !== undefined)\n .map((field) => ({ value: item.values[field] as IconUsage['value'], location: `${location}:${property.path}:${item.id}:${field}` })))\n : [];\n}\n\nfunction ownerItems(value: unknown): { id: string; values: Record<string, unknown> }[] {\n return (Array.isArray(value) ? value : [])\n .filter((item): item is Record<string, unknown> => item !== null && typeof item === 'object')\n .map(({ id, ...values }) => ({ id: String(id), values }));\n}\n\n/**\n * Finds every icon value stored anywhere in a document - the values components carry themselves, and the values\n * and collection-item icon fields that template instances contributed - as the `IconUsage`s that\n * `analyzeIconImpact` takes, so \"what would removing this library break\" can be asked of a whole document.\n *\n * Each usage's `location` reads `<owner or instance>:<component>:<path>[:<itemId>:<field>]`, where the first part is\n * the contributing instance id (`screen:Orders`) for a contributed value and the name of the owning layout or\n * template for a value the component carries. Values are read as stored; none are changed.\n *\n * @param document The document to read.\n * @param catalog The descriptors saying which properties are icons.\n */\nexport function collectIconUsages(document: SceneDocument, catalog: DescriptorCatalog): IconUsage[] {\n const usages: IconUsage[] = [];\n const componentNames = new Map<string, string>();\n\n const owners: { name: string; value: unknown }[] = [\n ...document.layouts.map((layout) => ({ name: layout.name, value: layout })),\n ...document.screenTemplates.map((template) => ({ name: template.name, value: template })),\n ...document.dialogTemplates.map((template) => ({ name: template.name, value: template })),\n ...document.screens.map((screen) => ({ name: screen.name, value: screen })),\n ];\n\n for (const owner of owners) {\n for (const component of collectComponents(owner.value)) {\n if (!componentNames.has(component.id)) componentNames.set(component.id, component.componentName);\n\n for (const property of findComponentDescriptor(catalog, component.componentName)?.properties ?? []) {\n const value = getValueAtPath(component.properties, property.path);\n usages.push(...usagesOf(property, value, ownerItems(value), `${owner.name}:${component.id}`));\n }\n }\n }\n\n for (const contribution of document.instanceContributions) {\n const componentName = componentNames.get(contribution.component);\n const property = componentName === undefined ? undefined : findComponentDescriptor(catalog, componentName)?.properties.find((candidate) => candidate.path === contribution.path);\n if (property) usages.push(...contributedUsages(property, contribution));\n }\n\n return usages;\n}\n\nfunction contributedUsages(property: PropertyDescriptor, contribution: InstanceContribution): IconUsage[] {\n return usagesOf(property, contribution.value, contribution.items, `${contribution.instance}:${contribution.component}`);\n}\n"],"names":["iconFields","property","item","properties","filter","field","valueType","PropertyValueType","Icon","map","path","usagesOf","value","items","location","undefined","Collection","flatMap","values","id","ownerItems","Array","isArray","String","collectIconUsages","document","catalog","usages","componentNames","Map","owners","layouts","layout","name","screenTemplates","template","dialogTemplates","screens","screen","owner","component","collectComponents","has","set","componentName","findComponentDescriptor","getValueAtPath","push","contribution","instanceContributions","get","find","candidate","contributedUsages","instance"],"mappings":"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"}
@@ -0,0 +1,67 @@
1
+ 'use strict';
2
+
3
+ var scene_model = require('@cratis/scene.model');
4
+ var DescriptorCatalog = require('./DescriptorCatalog.js');
5
+ var iconDiagnostics = require('./iconDiagnostics.js');
6
+ var pathAccess = require('./pathAccess.js');
7
+ var resolveEffectiveConfiguration = require('./resolveEffectiveConfiguration.js');
8
+ var resolveTemplateChain = require('./resolveTemplateChain.js');
9
+
10
+ // Copyright (c) Cratis. All rights reserved.
11
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
12
+ function isIconBearing(property) {
13
+ return property.valueType === scene_model.PropertyValueType.Icon || property.valueType === scene_model.PropertyValueType.Collection && (property.item?.properties ?? []).some((field)=>field.valueType === scene_model.PropertyValueType.Icon);
14
+ }
15
+ /**
16
+ * Reports every icon in what the editing scope renders - the template chain's own values and what each instance
17
+ * contributed - that the profile's icon catalog cannot supply: a library the profile lacks, an icon or variant a
18
+ * library no longer has, a library at an incompatible version.
19
+ *
20
+ * It reports; it never changes anything. The offending values stay in the document, still applied (a renderer
21
+ * shows its fallback), and apply again as soon as the icon is available, so removing a library is reversible.
22
+ * Each diagnostic names the component, property, collection item and - for a contributed value - the instance.
23
+ *
24
+ * Returns nothing when the context carries no `iconCatalog`. Load the catalogs first (`iconCatalog.load()`) for
25
+ * definite answers; an icon from an unloaded library is reported as not verified.
26
+ */ function diagnoseIcons(document, context) {
27
+ const iconCatalog = context.iconCatalog;
28
+ if (!iconCatalog) return [];
29
+ const chain = resolveTemplateChain.resolveTemplateChain(document, context.scope);
30
+ const configuration = resolveEffectiveConfiguration.resolveEffectiveConfiguration(chain, document.instanceContributions, context.catalog);
31
+ const diagnostics = [];
32
+ for (const level of chain.levels){
33
+ for (const element of level.elements){
34
+ const descriptor = DescriptorCatalog.findComponentDescriptor(context.catalog, element.componentName);
35
+ const configured = configuration.components.find((candidate)=>candidate.component === element.id);
36
+ for (const property of (descriptor?.properties ?? []).filter(isIconBearing)){
37
+ const effective = configured?.values.find((candidate)=>candidate.path === property.path);
38
+ const where = {
39
+ component: element.id,
40
+ ...effective?.contributedBy === undefined ? {} : {
41
+ instance: effective.contributedBy
42
+ }
43
+ };
44
+ if (property.valueType === scene_model.PropertyValueType.Icon) {
45
+ const value = effective ? effective.value : pathAccess.getValueAtPath(element.properties, property.path);
46
+ diagnostics.push(...iconDiagnostics.iconProblemsOfProperty(iconCatalog, property, value, scene_model.DiagnosticSeverity.Warning, where));
47
+ } else if (effective?.items) {
48
+ const items = effective.items.map((item)=>({
49
+ id: item.id,
50
+ values: item.values,
51
+ instance: item.origin === 'owner' ? undefined : item.origin
52
+ }));
53
+ diagnostics.push(...iconDiagnostics.iconProblemsOfItems(iconCatalog, property.item, items, scene_model.DiagnosticSeverity.Warning, {
54
+ component: element.id,
55
+ path: property.path
56
+ }));
57
+ } else {
58
+ diagnostics.push(...iconDiagnostics.iconProblemsOfProperty(iconCatalog, property, pathAccess.getValueAtPath(element.properties, property.path), scene_model.DiagnosticSeverity.Warning, where));
59
+ }
60
+ }
61
+ }
62
+ }
63
+ return diagnostics;
64
+ }
65
+
66
+ exports.diagnoseIcons = diagnoseIcons;
67
+ //# sourceMappingURL=diagnoseIcons.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diagnoseIcons.js","sources":["../../../editing/diagnoseIcons.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 { DiagnosticSeverity, PropertyDescriptor, PropertyValueType, SceneDiagnostic, SceneDocument } from '@cratis/scene.model';\nimport { findComponentDescriptor } from './DescriptorCatalog';\nimport { EditingContext } from './EditingContext';\nimport { iconProblemsOfItems, iconProblemsOfProperty } from './iconDiagnostics';\nimport { getValueAtPath } from './pathAccess';\nimport { resolveEffectiveConfiguration } from './resolveEffectiveConfiguration';\nimport { resolveTemplateChain } from './resolveTemplateChain';\n\nfunction isIconBearing(property: PropertyDescriptor): boolean {\n return property.valueType === PropertyValueType.Icon\n || (property.valueType === PropertyValueType.Collection && (property.item?.properties ?? []).some((field) => field.valueType === PropertyValueType.Icon));\n}\n\n/**\n * Reports every icon in what the editing scope renders - the template chain's own values and what each instance\n * contributed - that the profile's icon catalog cannot supply: a library the profile lacks, an icon or variant a\n * library no longer has, a library at an incompatible version.\n *\n * It reports; it never changes anything. The offending values stay in the document, still applied (a renderer\n * shows its fallback), and apply again as soon as the icon is available, so removing a library is reversible.\n * Each diagnostic names the component, property, collection item and - for a contributed value - the instance.\n *\n * Returns nothing when the context carries no `iconCatalog`. Load the catalogs first (`iconCatalog.load()`) for\n * definite answers; an icon from an unloaded library is reported as not verified.\n */\nexport function diagnoseIcons(document: SceneDocument, context: EditingContext): SceneDiagnostic[] {\n const iconCatalog = context.iconCatalog;\n if (!iconCatalog) return [];\n\n const chain = resolveTemplateChain(document, context.scope);\n const configuration = resolveEffectiveConfiguration(chain, document.instanceContributions, context.catalog);\n const diagnostics: SceneDiagnostic[] = [];\n\n for (const level of chain.levels) {\n for (const element of level.elements) {\n const descriptor = findComponentDescriptor(context.catalog, element.componentName);\n const configured = configuration.components.find((candidate) => candidate.component === element.id);\n\n for (const property of (descriptor?.properties ?? []).filter(isIconBearing)) {\n const effective = configured?.values.find((candidate) => candidate.path === property.path);\n const where = { component: element.id, ...(effective?.contributedBy === undefined ? {} : { instance: effective.contributedBy }) };\n\n if (property.valueType === PropertyValueType.Icon) {\n const value = effective ? effective.value : getValueAtPath(element.properties, property.path);\n diagnostics.push(...iconProblemsOfProperty(iconCatalog, property, value, DiagnosticSeverity.Warning, where));\n } else if (effective?.items) {\n const items = effective.items.map((item) => ({ id: item.id, values: item.values, instance: item.origin === 'owner' ? undefined : item.origin }));\n diagnostics.push(...iconProblemsOfItems(iconCatalog, property.item, items, DiagnosticSeverity.Warning, { component: element.id, path: property.path }));\n } else {\n diagnostics.push(...iconProblemsOfProperty(iconCatalog, property, getValueAtPath(element.properties, property.path), DiagnosticSeverity.Warning, where));\n }\n }\n }\n }\n\n return diagnostics;\n}\n"],"names":["isIconBearing","property","valueType","PropertyValueType","Icon","Collection","item","properties","some","field","diagnoseIcons","document","context","iconCatalog","chain","resolveTemplateChain","scope","configuration","resolveEffectiveConfiguration","instanceContributions","catalog","diagnostics","level","levels","element","elements","descriptor","findComponentDescriptor","componentName","configured","components","find","candidate","component","id","filter","effective","values","path","where","contributedBy","undefined","instance","value","getValueAtPath","push","iconProblemsOfProperty","DiagnosticSeverity","Warning","items","map","origin","iconProblemsOfItems"],"mappings":"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"}
@@ -0,0 +1,103 @@
1
+ 'use strict';
2
+
3
+ var scene_model = require('@cratis/scene.model');
4
+
5
+ // Copyright (c) Cratis. All rights reserved.
6
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
7
+ const codes = {
8
+ 'missing-library': scene_model.DiagnosticCode.MissingIconLibrary,
9
+ 'missing-icon': scene_model.DiagnosticCode.MissingIcon,
10
+ 'missing-variant': scene_model.DiagnosticCode.MissingIconVariant,
11
+ 'incompatible-version': scene_model.DiagnosticCode.IncompatibleIconLibrary,
12
+ 'catalog-unavailable': scene_model.DiagnosticCode.IconCatalogUnavailable
13
+ };
14
+ /**
15
+ * Checks one icon value against the effective icon catalog.
16
+ *
17
+ * Nothing is rewritten or dropped: this only reports. A value whose library, icon or variant is missing, or
18
+ * whose library is at an incompatible version, produces a diagnostic of the given severity - an error when
19
+ * the value is being *set* (the edit is refused), a warning when it is already stored (it is kept, and
20
+ * applies again if the icon comes back). A value that cannot be judged yet, because its library's catalog has
21
+ * not been loaded, produces an `IconNotVerified` warning rather than silently passing.
22
+ *
23
+ * @param catalog The effective catalog of the profile being edited.
24
+ * @param value The value; anything that is not an icon reference is left to `validateValue`.
25
+ * @param severity How serious a definite problem is.
26
+ * @param context What the diagnostic is about.
27
+ */ function iconProblem(catalog, value, severity, context) {
28
+ if (!scene_model.isIconReference(value)) return undefined;
29
+ const resolution = catalog.lookup(value);
30
+ if (resolution === undefined) {
31
+ return {
32
+ code: scene_model.DiagnosticCode.IconNotVerified,
33
+ severity: scene_model.DiagnosticSeverity.Warning,
34
+ message: `The catalog of the icon library '${value.library}' is not loaded, so '${value.key}' could not be verified.`,
35
+ ...context
36
+ };
37
+ }
38
+ return resolution.isResolved ? undefined : {
39
+ code: codes[resolution.diagnostic.kind],
40
+ severity,
41
+ message: `${resolution.diagnostic.message}.`,
42
+ ...context
43
+ };
44
+ }
45
+ /**
46
+ * Checks the icon fields of collection items.
47
+ *
48
+ * @param itemDescriptor What the items look like.
49
+ * @param items The items, each with its id and field values.
50
+ */ function iconProblemsOfItems(catalog, itemDescriptor, items, severity, context) {
51
+ const iconFields = (itemDescriptor?.properties ?? []).filter((field)=>field.valueType === scene_model.PropertyValueType.Icon);
52
+ return items.flatMap((item)=>iconFields.flatMap((field)=>{
53
+ const problem = iconProblem(catalog, item.values[field.path], severity, {
54
+ ...context,
55
+ itemId: item.id,
56
+ ...item.instance === undefined ? {} : {
57
+ instance: item.instance
58
+ }
59
+ });
60
+ return problem ? [
61
+ {
62
+ ...problem,
63
+ message: `'${field.label}' of '${item.id}': ${problem.message}`
64
+ }
65
+ ] : [];
66
+ }));
67
+ }
68
+ /**
69
+ * Checks a property's value - an icon, or a collection whose items have icon fields - against the effective icon
70
+ * catalog. Any other kind of property has nothing to check.
71
+ *
72
+ * @param descriptor The property.
73
+ * @param value The value; for a collection, the flat items (`{ id, ...fields }`) as they are stored.
74
+ */ function iconProblemsOfProperty(catalog, descriptor, value, severity, context) {
75
+ if (descriptor.valueType === scene_model.PropertyValueType.Icon) {
76
+ const problem = iconProblem(catalog, value, severity, {
77
+ ...context,
78
+ path: descriptor.path
79
+ });
80
+ return problem ? [
81
+ {
82
+ ...problem,
83
+ message: `'${descriptor.label}': ${problem.message}`
84
+ }
85
+ ] : [];
86
+ }
87
+ if (descriptor.valueType === scene_model.PropertyValueType.Collection && Array.isArray(value)) {
88
+ const items = value.filter((item)=>item !== null && typeof item === 'object').map(({ id, ...values })=>({
89
+ id: String(id),
90
+ values
91
+ }));
92
+ return iconProblemsOfItems(catalog, descriptor.item, items, severity, {
93
+ ...context,
94
+ path: descriptor.path
95
+ });
96
+ }
97
+ return [];
98
+ }
99
+
100
+ exports.iconProblem = iconProblem;
101
+ exports.iconProblemsOfItems = iconProblemsOfItems;
102
+ exports.iconProblemsOfProperty = iconProblemsOfProperty;
103
+ //# sourceMappingURL=iconDiagnostics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"iconDiagnostics.js","sources":["../../../editing/iconDiagnostics.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 { CollectionItemDescriptor, DiagnosticCode, DiagnosticSeverity, PropertyDescriptor, PropertyValueType, SceneDiagnostic, isIconReference } from '@cratis/scene.model';\nimport { EffectiveIconCatalog } from '../icons/EffectiveIconCatalog';\nimport { IconDiagnosticKind } from '../icons/IconDiagnostic';\nimport { DiagnosticContext } from './diagnostics';\n\nconst codes: Record<IconDiagnosticKind, DiagnosticCode> = {\n 'missing-library': DiagnosticCode.MissingIconLibrary,\n 'missing-icon': DiagnosticCode.MissingIcon,\n 'missing-variant': DiagnosticCode.MissingIconVariant,\n 'incompatible-version': DiagnosticCode.IncompatibleIconLibrary,\n 'catalog-unavailable': DiagnosticCode.IconCatalogUnavailable,\n};\n\n/**\n * Checks one icon value against the effective icon catalog.\n *\n * Nothing is rewritten or dropped: this only reports. A value whose library, icon or variant is missing, or\n * whose library is at an incompatible version, produces a diagnostic of the given severity - an error when\n * the value is being *set* (the edit is refused), a warning when it is already stored (it is kept, and\n * applies again if the icon comes back). A value that cannot be judged yet, because its library's catalog has\n * not been loaded, produces an `IconNotVerified` warning rather than silently passing.\n *\n * @param catalog The effective catalog of the profile being edited.\n * @param value The value; anything that is not an icon reference is left to `validateValue`.\n * @param severity How serious a definite problem is.\n * @param context What the diagnostic is about.\n */\nexport function iconProblem(catalog: EffectiveIconCatalog, value: unknown, severity: DiagnosticSeverity, context: DiagnosticContext): SceneDiagnostic | undefined {\n if (!isIconReference(value)) return undefined;\n\n const resolution = catalog.lookup(value);\n if (resolution === undefined) {\n return {\n code: DiagnosticCode.IconNotVerified,\n severity: DiagnosticSeverity.Warning,\n message: `The catalog of the icon library '${value.library}' is not loaded, so '${value.key}' could not be verified.`,\n ...context,\n };\n }\n\n return resolution.isResolved ? undefined : { code: codes[resolution.diagnostic.kind], severity, message: `${resolution.diagnostic.message}.`, ...context };\n}\n\n/**\n * Checks the icon fields of collection items.\n *\n * @param itemDescriptor What the items look like.\n * @param items The items, each with its id and field values.\n */\nexport function iconProblemsOfItems(\n catalog: EffectiveIconCatalog,\n itemDescriptor: CollectionItemDescriptor | undefined,\n items: { id: string; values: Record<string, unknown>; instance?: string }[],\n severity: DiagnosticSeverity,\n context: DiagnosticContext\n): SceneDiagnostic[] {\n const iconFields = (itemDescriptor?.properties ?? []).filter((field) => field.valueType === PropertyValueType.Icon);\n return items.flatMap((item) =>\n iconFields.flatMap((field) => {\n const problem = iconProblem(catalog, item.values[field.path], severity, { ...context, itemId: item.id, ...(item.instance === undefined ? {} : { instance: item.instance }) });\n return problem ? [{ ...problem, message: `'${field.label}' of '${item.id}': ${problem.message}` }] : [];\n })\n );\n}\n\n/**\n * Checks a property's value - an icon, or a collection whose items have icon fields - against the effective icon\n * catalog. Any other kind of property has nothing to check.\n *\n * @param descriptor The property.\n * @param value The value; for a collection, the flat items (`{ id, ...fields }`) as they are stored.\n */\nexport function iconProblemsOfProperty(catalog: EffectiveIconCatalog, descriptor: PropertyDescriptor, value: unknown, severity: DiagnosticSeverity, context: DiagnosticContext): SceneDiagnostic[] {\n if (descriptor.valueType === PropertyValueType.Icon) {\n const problem = iconProblem(catalog, value, severity, { ...context, path: descriptor.path });\n return problem ? [{ ...problem, message: `'${descriptor.label}': ${problem.message}` }] : [];\n }\n\n if (descriptor.valueType === PropertyValueType.Collection && Array.isArray(value)) {\n const items = value\n .filter((item): item is Record<string, unknown> => item !== null && typeof item === 'object')\n .map(({ id, ...values }) => ({ id: String(id), values }));\n return iconProblemsOfItems(catalog, descriptor.item, items, severity, { ...context, path: descriptor.path });\n }\n\n return [];\n}\n"],"names":["codes","DiagnosticCode","MissingIconLibrary","MissingIcon","MissingIconVariant","IncompatibleIconLibrary","IconCatalogUnavailable","iconProblem","catalog","value","severity","context","isIconReference","undefined","resolution","lookup","code","IconNotVerified","DiagnosticSeverity","Warning","message","library","key","isResolved","diagnostic","kind","iconProblemsOfItems","itemDescriptor","items","iconFields","properties","filter","field","valueType","PropertyValueType","Icon","flatMap","item","problem","values","path","itemId","id","instance","label","iconProblemsOfProperty","descriptor","Collection","Array","isArray","map","String"],"mappings":"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"}
@@ -3,6 +3,7 @@
3
3
  var scene_model = require('@cratis/scene.model');
4
4
  var describeNode = require('./describeNode.js');
5
5
  var exposureGrants = require('./exposureGrants.js');
6
+ var iconDiagnostics = require('./iconDiagnostics.js');
6
7
  var indexDocument = require('./indexDocument.js');
7
8
  var resolveEffectiveConfiguration = require('./resolveEffectiveConfiguration.js');
8
9
  var resolveTemplateChain = require('./resolveTemplateChain.js');
@@ -76,6 +77,28 @@ function inspectProperty(descriptor, record, provenance, scopeInstance, grants,
76
77
  }
77
78
  return inspected;
78
79
  }
80
+ /**
81
+ * Reports icons the profile cannot supply - on the node itself and in configuration contributed to it. The values
82
+ * stay where they are; these are warnings.
83
+ */ function iconDiagnosticsOf(properties, iconCatalog, nodeId) {
84
+ return properties.flatMap((property)=>{
85
+ const descriptor = property.descriptor;
86
+ if (descriptor.valueType !== scene_model.PropertyValueType.Collection) {
87
+ return iconDiagnostics.iconProblemsOfProperty(iconCatalog, descriptor, property.effectiveValue, scene_model.DiagnosticSeverity.Warning, {
88
+ nodeId
89
+ });
90
+ }
91
+ const items = (property.items ?? []).map((item)=>({
92
+ id: item.id,
93
+ values: item.values,
94
+ instance: item.origin === 'owner' ? undefined : item.origin
95
+ }));
96
+ return iconDiagnostics.iconProblemsOfItems(iconCatalog, descriptor.item, items, scene_model.DiagnosticSeverity.Warning, {
97
+ nodeId,
98
+ path: descriptor.path
99
+ });
100
+ });
101
+ }
79
102
  /**
80
103
  * Describes one node for an editor: what it is, where it comes from, what can be edited on it - with current and
81
104
  * effective values and effective editability - and what can be done with it.
@@ -108,6 +131,10 @@ function inspectProperty(descriptor, record, provenance, scopeInstance, grants,
108
131
  if (chain.levels.length === 0) {
109
132
  diagnostics.push(...chain.diagnostics.filter((diagnostic)=>diagnostic.code === scene_model.DiagnosticCode.UnknownScope));
110
133
  }
134
+ const properties = description.properties.map((descriptor)=>inspectProperty(descriptor, record, provenance, scopeInstance, scopeGrants, configuredValues));
135
+ if (context.iconCatalog) {
136
+ diagnostics.push(...iconDiagnosticsOf(properties, context.iconCatalog, nodeId));
137
+ }
111
138
  return {
112
139
  nodeId,
113
140
  kind: record.kind,
@@ -115,7 +142,7 @@ function inspectProperty(descriptor, record, provenance, scopeInstance, grants,
115
142
  label: record.label,
116
143
  parentId: record.parentId,
117
144
  provenance,
118
- properties: description.properties.map((descriptor)=>inspectProperty(descriptor, record, provenance, scopeInstance, scopeGrants, configuredValues)),
145
+ properties,
119
146
  capabilities: description.capabilities,
120
147
  removable: isRemovable(record, provenance),
121
148
  diagnostics
@@ -1 +1 @@
1
- {"version":3,"file":"inspect.js","sources":["../../../editing/inspect.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 DiagnosticCode, EditTarget, InspectedCollectionItem, InspectedProperty, NodeInspection,\n NodeProvenance, ProvenanceKind, PropertyDescriptor, PropertyValueType, SceneDiagnostic, SceneDocument, SceneNodeKind, ValueSource,\n} from '@cratis/scene.model';\nimport { describeNode, readNodeValue } from './describeNode';\nimport { EditingContext } from './EditingContext';\nimport { computeExposureGrants, ExposureGrant, grantKey } from './exposureGrants';\nimport { indexDocument } from './indexDocument';\nimport { NodeRecord } from './DocumentIndex';\nimport { resolveEffectiveConfiguration } from './resolveEffectiveConfiguration';\nimport { resolveTemplateChain } from './resolveTemplateChain';\nimport { TemplateChain } from './TemplateChain';\n\n/**\n * Works out whether a node is the editing scope's own, and when it is not, where it comes from and whether any of\n * it is configurable here.\n *\n * @param record The node.\n * @param chain The chain the scope sits in.\n * @param scopeGrants What the scope's own instance may configure.\n */\nexport function provenanceOf(record: NodeRecord, chain: TemplateChain, scopeGrants: Map<string, ExposureGrant> | undefined): NodeProvenance {\n const scopeLevel = chain.levels.at(-1);\n if (scopeLevel && record.owner === scopeLevel.owner && record.ownerKind === scopeLevel.kind) return { kind: ProvenanceKind.Local };\n\n const configurable = record.kind === SceneNodeKind.Element\n && [...(scopeGrants?.values() ?? [])].some(grant => grant.component === (record.value as { id: string }).id);\n return { kind: configurable ? ProvenanceKind.ConfigurableInherited : ProvenanceKind.Inherited, source: record.owner };\n}\n\nfunction isRemovable(record: NodeRecord, provenance: NodeProvenance): boolean {\n return provenance.kind === ProvenanceKind.Local\n && (record.list !== undefined || record.leafId !== undefined || record.placementIds !== undefined);\n}\n\nfunction toInspectedItems(raw: unknown, local: boolean): InspectedCollectionItem[] {\n return (Array.isArray(raw) ? raw : []).map((item: Record<string, unknown>, position) => {\n const { id, ...values } = item;\n return { id: typeof id === 'string' ? id : `owner-${position}`, values, origin: 'owner', editable: local };\n });\n}\n\nfunction inspectProperty(\n descriptor: PropertyDescriptor,\n record: NodeRecord,\n provenance: NodeProvenance,\n scopeInstance: string | undefined,\n grants: Map<string, ExposureGrant> | undefined,\n configuredValues: { path: string; value: unknown; source: string; items?: { id: string; values: Record<string, unknown>; origin: string }[] }[] | undefined,\n): InspectedProperty {\n const currentValue = readNodeValue(record, descriptor.path);\n const configured = configuredValues?.find(candidate => candidate.path === descriptor.path);\n const local = provenance.kind === ProvenanceKind.Local;\n const isCollection = descriptor.valueType === PropertyValueType.Collection;\n\n const inspected: InspectedProperty = {\n descriptor,\n currentValue,\n effectiveValue: configured ? configured.value : (currentValue ?? descriptor.default),\n source: (configured?.source ?? (currentValue === undefined ? ValueSource.Default : ValueSource.Local)) as ValueSource,\n editable: false,\n };\n\n const grant = !local && record.kind === SceneNodeKind.Element\n ? grants?.get(grantKey((record.value as { id: string }).id, descriptor.path))\n : undefined;\n\n if (local) {\n inspected.editable = descriptor.readOnly !== true;\n if (inspected.editable) inspected.editTarget = EditTarget.Node;\n else inspected.reason = 'This property is read-only.';\n } else if (grant) {\n inspected.editable = true;\n inspected.editTarget = EditTarget.Instance;\n if (isCollection) inspected.operations = grant.operations;\n } else {\n inspected.reason = `Inherited from '${provenance.source}', which does not expose it.`;\n }\n\n if (isCollection) {\n const items = configured?.items\n ? configured.items.map(item => ({ ...item, editable: local || (item.origin === scopeInstance && grant !== undefined && grant.operations.length > 0) }))\n : toInspectedItems(currentValue, local);\n inspected.items = items;\n }\n\n return inspected;\n}\n\n/**\n * Describes one node for an editor: what it is, where it comes from, what can be edited on it - with current and\n * effective values and effective editability - and what can be done with it.\n *\n * A property of a node the scope owns is edited on the node. A property of an inherited node is editable only\n * when its owner exposed it, and then the edit goes to an instance contribution, never into the inherited node.\n * Nothing is mutated.\n *\n * @param document The document to read.\n * @param nodeId The node to describe; see the node id functions.\n * @param context The catalog and the editing scope.\n * @returns The inspection, or `undefined` when the document has no such node.\n */\nexport function inspect(document: SceneDocument, nodeId: string, context: EditingContext): NodeInspection | undefined {\n const index = indexDocument(document);\n const record = index.nodes.get(nodeId);\n if (!record) return undefined;\n\n const chain = resolveTemplateChain(document, context.scope);\n const grants = computeExposureGrants(chain, context.catalog);\n const scopeInstance = chain.levels.at(-1)?.instance;\n const scopeGrants = scopeInstance === undefined ? undefined : grants.byInstance.get(scopeInstance);\n const configuration = resolveEffectiveConfiguration(chain, document.instanceContributions, context.catalog);\n\n const provenance = provenanceOf(record, chain, scopeGrants);\n const description = describeNode(record, context.catalog);\n const componentId = record.kind === SceneNodeKind.Element ? (record.value as { id: string }).id : undefined;\n const configuredValues = configuration.components.find(candidate => candidate.component === componentId)?.values;\n\n const diagnostics: SceneDiagnostic[] = [\n ...description.diagnostics,\n ...configuration.diagnostics.filter(diagnostic => diagnostic.component !== undefined && diagnostic.component === componentId),\n ];\n if (chain.levels.length === 0) {\n diagnostics.push(...chain.diagnostics.filter(diagnostic => diagnostic.code === DiagnosticCode.UnknownScope));\n }\n\n return {\n nodeId,\n kind: record.kind,\n typeId: record.typeId,\n label: record.label,\n parentId: record.parentId,\n provenance,\n properties: description.properties.map(descriptor => inspectProperty(descriptor, record, provenance, scopeInstance, scopeGrants, configuredValues)),\n capabilities: description.capabilities,\n removable: isRemovable(record, provenance),\n diagnostics,\n };\n}\n"],"names":["provenanceOf","record","chain","scopeGrants","scopeLevel","levels","at","owner","ownerKind","kind","ProvenanceKind","Local","configurable","SceneNodeKind","Element","values","some","grant","component","value","id","ConfigurableInherited","Inherited","source","isRemovable","provenance","list","undefined","leafId","placementIds","toInspectedItems","raw","local","Array","isArray","map","item","position","origin","editable","inspectProperty","descriptor","scopeInstance","grants","configuredValues","currentValue","readNodeValue","path","configured","find","candidate","isCollection","valueType","PropertyValueType","Collection","inspected","effectiveValue","default","ValueSource","Default","get","grantKey","readOnly","editTarget","EditTarget","Node","reason","Instance","operations","items","length","inspect","document","nodeId","context","index","indexDocument","nodes","resolveTemplateChain","scope","computeExposureGrants","catalog","instance","byInstance","configuration","resolveEffectiveConfiguration","instanceContributions","description","describeNode","componentId","components","diagnostics","filter","diagnostic","push","code","DiagnosticCode","UnknownScope","typeId","label","parentId","properties","capabilities","removable"],"mappings":"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"}
1
+ {"version":3,"file":"inspect.js","sources":["../../../editing/inspect.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 DiagnosticCode, DiagnosticSeverity, EditTarget, InspectedCollectionItem, InspectedProperty, NodeInspection,\n NodeProvenance, ProvenanceKind, PropertyDescriptor, PropertyValueType, SceneDiagnostic, SceneDocument, SceneNodeKind, ValueSource,\n} from '@cratis/scene.model';\nimport { describeNode, readNodeValue } from './describeNode';\nimport { EffectiveIconCatalog } from '../icons/EffectiveIconCatalog';\nimport { EditingContext } from './EditingContext';\nimport { computeExposureGrants, ExposureGrant, grantKey } from './exposureGrants';\nimport { iconProblemsOfItems, iconProblemsOfProperty } from './iconDiagnostics';\nimport { indexDocument } from './indexDocument';\nimport { NodeRecord } from './DocumentIndex';\nimport { resolveEffectiveConfiguration } from './resolveEffectiveConfiguration';\nimport { resolveTemplateChain } from './resolveTemplateChain';\nimport { TemplateChain } from './TemplateChain';\n\n/**\n * Works out whether a node is the editing scope's own, and when it is not, where it comes from and whether any of\n * it is configurable here.\n *\n * @param record The node.\n * @param chain The chain the scope sits in.\n * @param scopeGrants What the scope's own instance may configure.\n */\nexport function provenanceOf(record: NodeRecord, chain: TemplateChain, scopeGrants: Map<string, ExposureGrant> | undefined): NodeProvenance {\n const scopeLevel = chain.levels.at(-1);\n if (scopeLevel && record.owner === scopeLevel.owner && record.ownerKind === scopeLevel.kind) return { kind: ProvenanceKind.Local };\n\n const configurable = record.kind === SceneNodeKind.Element\n && [...(scopeGrants?.values() ?? [])].some(grant => grant.component === (record.value as { id: string }).id);\n return { kind: configurable ? ProvenanceKind.ConfigurableInherited : ProvenanceKind.Inherited, source: record.owner };\n}\n\nfunction isRemovable(record: NodeRecord, provenance: NodeProvenance): boolean {\n return provenance.kind === ProvenanceKind.Local\n && (record.list !== undefined || record.leafId !== undefined || record.placementIds !== undefined);\n}\n\nfunction toInspectedItems(raw: unknown, local: boolean): InspectedCollectionItem[] {\n return (Array.isArray(raw) ? raw : []).map((item: Record<string, unknown>, position) => {\n const { id, ...values } = item;\n return { id: typeof id === 'string' ? id : `owner-${position}`, values, origin: 'owner', editable: local };\n });\n}\n\nfunction inspectProperty(\n descriptor: PropertyDescriptor,\n record: NodeRecord,\n provenance: NodeProvenance,\n scopeInstance: string | undefined,\n grants: Map<string, ExposureGrant> | undefined,\n configuredValues: { path: string; value: unknown; source: string; items?: { id: string; values: Record<string, unknown>; origin: string }[] }[] | undefined,\n): InspectedProperty {\n const currentValue = readNodeValue(record, descriptor.path);\n const configured = configuredValues?.find(candidate => candidate.path === descriptor.path);\n const local = provenance.kind === ProvenanceKind.Local;\n const isCollection = descriptor.valueType === PropertyValueType.Collection;\n\n const inspected: InspectedProperty = {\n descriptor,\n currentValue,\n effectiveValue: configured ? configured.value : (currentValue ?? descriptor.default),\n source: (configured?.source ?? (currentValue === undefined ? ValueSource.Default : ValueSource.Local)) as ValueSource,\n editable: false,\n };\n\n const grant = !local && record.kind === SceneNodeKind.Element\n ? grants?.get(grantKey((record.value as { id: string }).id, descriptor.path))\n : undefined;\n\n if (local) {\n inspected.editable = descriptor.readOnly !== true;\n if (inspected.editable) inspected.editTarget = EditTarget.Node;\n else inspected.reason = 'This property is read-only.';\n } else if (grant) {\n inspected.editable = true;\n inspected.editTarget = EditTarget.Instance;\n if (isCollection) inspected.operations = grant.operations;\n } else {\n inspected.reason = `Inherited from '${provenance.source}', which does not expose it.`;\n }\n\n if (isCollection) {\n const items = configured?.items\n ? configured.items.map(item => ({ ...item, editable: local || (item.origin === scopeInstance && grant !== undefined && grant.operations.length > 0) }))\n : toInspectedItems(currentValue, local);\n inspected.items = items;\n }\n\n return inspected;\n}\n\n/**\n * Reports icons the profile cannot supply - on the node itself and in configuration contributed to it. The values\n * stay where they are; these are warnings.\n */\nfunction iconDiagnosticsOf(properties: InspectedProperty[], iconCatalog: EffectiveIconCatalog, nodeId: string): SceneDiagnostic[] {\n return properties.flatMap(property => {\n const descriptor = property.descriptor;\n if (descriptor.valueType !== PropertyValueType.Collection) {\n return iconProblemsOfProperty(iconCatalog, descriptor, property.effectiveValue, DiagnosticSeverity.Warning, { nodeId });\n }\n\n const items = (property.items ?? []).map(item => ({ id: item.id, values: item.values, instance: item.origin === 'owner' ? undefined : item.origin }));\n return iconProblemsOfItems(iconCatalog, descriptor.item, items, DiagnosticSeverity.Warning, { nodeId, path: descriptor.path });\n });\n}\n\n/**\n * Describes one node for an editor: what it is, where it comes from, what can be edited on it - with current and\n * effective values and effective editability - and what can be done with it.\n *\n * A property of a node the scope owns is edited on the node. A property of an inherited node is editable only\n * when its owner exposed it, and then the edit goes to an instance contribution, never into the inherited node.\n * Nothing is mutated.\n *\n * @param document The document to read.\n * @param nodeId The node to describe; see the node id functions.\n * @param context The catalog and the editing scope.\n * @returns The inspection, or `undefined` when the document has no such node.\n */\nexport function inspect(document: SceneDocument, nodeId: string, context: EditingContext): NodeInspection | undefined {\n const index = indexDocument(document);\n const record = index.nodes.get(nodeId);\n if (!record) return undefined;\n\n const chain = resolveTemplateChain(document, context.scope);\n const grants = computeExposureGrants(chain, context.catalog);\n const scopeInstance = chain.levels.at(-1)?.instance;\n const scopeGrants = scopeInstance === undefined ? undefined : grants.byInstance.get(scopeInstance);\n const configuration = resolveEffectiveConfiguration(chain, document.instanceContributions, context.catalog);\n\n const provenance = provenanceOf(record, chain, scopeGrants);\n const description = describeNode(record, context.catalog);\n const componentId = record.kind === SceneNodeKind.Element ? (record.value as { id: string }).id : undefined;\n const configuredValues = configuration.components.find(candidate => candidate.component === componentId)?.values;\n\n const diagnostics: SceneDiagnostic[] = [\n ...description.diagnostics,\n ...configuration.diagnostics.filter(diagnostic => diagnostic.component !== undefined && diagnostic.component === componentId),\n ];\n if (chain.levels.length === 0) {\n diagnostics.push(...chain.diagnostics.filter(diagnostic => diagnostic.code === DiagnosticCode.UnknownScope));\n }\n\n const properties = description.properties.map(descriptor => inspectProperty(descriptor, record, provenance, scopeInstance, scopeGrants, configuredValues));\n if (context.iconCatalog) {\n diagnostics.push(...iconDiagnosticsOf(properties, context.iconCatalog, nodeId));\n }\n\n return {\n nodeId,\n kind: record.kind,\n typeId: record.typeId,\n label: record.label,\n parentId: record.parentId,\n provenance,\n properties,\n capabilities: description.capabilities,\n removable: isRemovable(record, provenance),\n diagnostics,\n };\n}\n"],"names":["provenanceOf","record","chain","scopeGrants","scopeLevel","levels","at","owner","ownerKind","kind","ProvenanceKind","Local","configurable","SceneNodeKind","Element","values","some","grant","component","value","id","ConfigurableInherited","Inherited","source","isRemovable","provenance","list","undefined","leafId","placementIds","toInspectedItems","raw","local","Array","isArray","map","item","position","origin","editable","inspectProperty","descriptor","scopeInstance","grants","configuredValues","currentValue","readNodeValue","path","configured","find","candidate","isCollection","valueType","PropertyValueType","Collection","inspected","effectiveValue","default","ValueSource","Default","get","grantKey","readOnly","editTarget","EditTarget","Node","reason","Instance","operations","items","length","iconDiagnosticsOf","properties","iconCatalog","nodeId","flatMap","property","iconProblemsOfProperty","DiagnosticSeverity","Warning","instance","iconProblemsOfItems","inspect","document","context","index","indexDocument","nodes","resolveTemplateChain","scope","computeExposureGrants","catalog","byInstance","configuration","resolveEffectiveConfiguration","instanceContributions","description","describeNode","componentId","components","diagnostics","filter","diagnostic","push","code","DiagnosticCode","UnknownScope","typeId","label","parentId","capabilities","removable"],"mappings":";;;;;;;;;;AAAA;AACA;AAiBA;;;;;;;AAOC,IACM,SAASA,YAAAA,CAAaC,MAAkB,EAAEC,KAAoB,EAAEC,WAAmD,EAAA;AACtH,IAAA,MAAMC,aAAaF,KAAAA,CAAMG,MAAM,CAACC,EAAE,CAAC,EAAC,CAAA;AACpC,IAAA,IAAIF,UAAAA,IAAcH,MAAAA,CAAOM,KAAK,KAAKH,UAAAA,CAAWG,KAAK,IAAIN,MAAAA,CAAOO,SAAS,KAAKJ,UAAAA,CAAWK,IAAI,EAAE,OAAO;AAAEA,QAAAA,IAAAA,EAAMC,2BAAeC;AAAM,KAAA;AAEjI,IAAA,MAAMC,eAAeX,MAAAA,CAAOQ,IAAI,KAAKI,yBAAAA,CAAcC,OAAO,IACnD;AAAKX,QAAAA,GAAAA,WAAAA,EAAaY,YAAY;KAAI,CAACC,IAAI,CAACC,CAAAA,KAAAA,GAASA,KAAAA,CAAMC,SAAS,KAAK,MAACjB,CAAOkB,KAAK,CAAoBC,EAAE,CAAA;IAC/G,OAAO;AAAEX,QAAAA,IAAAA,EAAMG,YAAAA,GAAeF,0BAAAA,CAAeW,qBAAqB,GAAGX,2BAAeY,SAAS;AAAEC,QAAAA,MAAAA,EAAQtB,OAAOM;AAAM,KAAA;AACxH;AAEA,SAASiB,WAAAA,CAAYvB,MAAkB,EAAEwB,UAA0B,EAAA;AAC/D,IAAA,OAAOA,WAAWhB,IAAI,KAAKC,2BAAeC,KAAK,KACvCV,MAAAA,CAAOyB,IAAI,KAAKC,SAAAA,IAAa1B,OAAO2B,MAAM,KAAKD,aAAa1B,MAAAA,CAAO4B,YAAY,KAAKF,SAAQ,CAAA;AACxG;AAEA,SAASG,gBAAAA,CAAiBC,GAAY,EAAEC,KAAc,EAAA;AAClD,IAAA,OAAO,CAACC,KAAAA,CAAMC,OAAO,CAACH,GAAAA,CAAAA,GAAOA,GAAAA,GAAM,EAAE,EAAEI,GAAG,CAAC,CAACC,IAAAA,EAA+BC,QAAAA,GAAAA;AACvE,QAAA,MAAM,EAAEjB,EAAE,EAAE,GAAGL,QAAQ,GAAGqB,IAAAA;QAC1B,OAAO;AAAEhB,YAAAA,EAAAA,EAAI,OAAOA,EAAAA,KAAO,QAAA,GAAWA,KAAK,CAAC,MAAM,EAAEiB,QAAAA,CAAAA,CAAU;AAAEtB,YAAAA,MAAAA;YAAQuB,MAAAA,EAAQ,OAAA;YAASC,QAAAA,EAAUP;AAAM,SAAA;AAC7G,IAAA,CAAA,CAAA;AACJ;AAEA,SAASQ,eAAAA,CACLC,UAA8B,EAC9BxC,MAAkB,EAClBwB,UAA0B,EAC1BiB,aAAiC,EACjCC,MAA8C,EAC9CC,gBAA2J,EAAA;AAE3J,IAAA,MAAMC,YAAAA,GAAeC,0BAAAA,CAAc7C,MAAAA,EAAQwC,UAAAA,CAAWM,IAAI,CAAA;IAC1D,MAAMC,UAAAA,GAAaJ,kBAAkBK,IAAAA,CAAKC,CAAAA,YAAaA,SAAAA,CAAUH,IAAI,KAAKN,UAAAA,CAAWM,IAAI,CAAA;AACzF,IAAA,MAAMf,KAAAA,GAAQP,UAAAA,CAAWhB,IAAI,KAAKC,2BAAeC,KAAK;AACtD,IAAA,MAAMwC,YAAAA,GAAeV,UAAAA,CAAWW,SAAS,KAAKC,8BAAkBC,UAAU;AAE1E,IAAA,MAAMC,SAAAA,GAA+B;AACjCd,QAAAA,UAAAA;AACAI,QAAAA,YAAAA;AACAW,QAAAA,cAAAA,EAAgBR,aAAaA,UAAAA,CAAW7B,KAAK,GAAI0B,YAAAA,IAAgBJ,WAAWgB,OAAO;QACnFlC,MAAAA,EAASyB,UAAAA,EAAYzB,MAAAA,KAAWsB,YAAAA,KAAiBlB,SAAAA,GAAY+B,wBAAYC,OAAO,GAAGD,uBAAAA,CAAY/C,KAAK,CAAD;QACnG4B,QAAAA,EAAU;AACd,KAAA;IAEA,MAAMtB,KAAAA,GAAQ,CAACe,KAAAA,IAAS/B,MAAAA,CAAOQ,IAAI,KAAKI,yBAAAA,CAAcC,OAAO,GACvD6B,MAAAA,EAAQiB,IAAIC,uBAAAA,CAAU5D,OAAOkB,KAAK,CAAoBC,EAAE,EAAEqB,UAAAA,CAAWM,IAAI,CAAA,CAAA,GACzEpB,SAAAA;AAEN,IAAA,IAAIK,KAAAA,EAAO;AACPuB,QAAAA,SAAAA,CAAUhB,QAAQ,GAAGE,UAAAA,CAAWqB,QAAQ,KAAK,IAAA;AAC7C,QAAA,IAAIP,UAAUhB,QAAQ,EAAEgB,UAAUQ,UAAU,GAAGC,uBAAWC,IAAI;AACzDV,aAAAA,SAAAA,CAAUW,MAAM,GAAG,6BAAA;AAC5B,IAAA,CAAA,MAAO,IAAIjD,KAAAA,EAAO;AACdsC,QAAAA,SAAAA,CAAUhB,QAAQ,GAAG,IAAA;QACrBgB,SAAAA,CAAUQ,UAAU,GAAGC,sBAAAA,CAAWG,QAAQ;AAC1C,QAAA,IAAIhB,YAAAA,EAAcI,SAAAA,CAAUa,UAAU,GAAGnD,MAAMmD,UAAU;IAC7D,CAAA,MAAO;QACHb,SAAAA,CAAUW,MAAM,GAAG,CAAC,gBAAgB,EAAEzC,UAAAA,CAAWF,MAAM,CAAC,4BAA4B,CAAC;AACzF,IAAA;AAEA,IAAA,IAAI4B,YAAAA,EAAc;QACd,MAAMkB,KAAAA,GAAQrB,UAAAA,EAAYqB,KAAAA,GACpBrB,UAAAA,CAAWqB,KAAK,CAAClC,GAAG,CAACC,CAAAA,IAAAA,IAAS;AAAE,gBAAA,GAAGA,IAAI;gBAAEG,QAAAA,EAAUP,KAAAA,IAAUI,IAAAA,CAAKE,MAAM,KAAKI,aAAAA,IAAiBzB,KAAAA,KAAUU,SAAAA,IAAaV,KAAAA,CAAMmD,UAAU,CAACE,MAAM,GAAG;aAAG,CAAA,CAAA,GAClJxC,iBAAiBe,YAAAA,EAAcb,KAAAA,CAAAA;AACrCuB,QAAAA,SAAAA,CAAUc,KAAK,GAAGA,KAAAA;AACtB,IAAA;IAEA,OAAOd,SAAAA;AACX;AAEA;;;AAGC,IACD,SAASgB,iBAAAA,CAAkBC,UAA+B,EAAEC,WAAiC,EAAEC,MAAc,EAAA;IACzG,OAAOF,UAAAA,CAAWG,OAAO,CAACC,CAAAA,QAAAA,GAAAA;QACtB,MAAMnC,UAAAA,GAAamC,SAASnC,UAAU;AACtC,QAAA,IAAIA,UAAAA,CAAWW,SAAS,KAAKC,6BAAAA,CAAkBC,UAAU,EAAE;YACvD,OAAOuB,sCAAAA,CAAuBJ,aAAahC,UAAAA,EAAYmC,QAAAA,CAASpB,cAAc,EAAEsB,8BAAAA,CAAmBC,OAAO,EAAE;AAAEL,gBAAAA;AAAO,aAAA,CAAA;AACzH,QAAA;AAEA,QAAA,MAAML,KAAAA,GAASO,CAAAA,QAAAA,CAASP,KAAK,IAAI,EAAC,EAAGlC,GAAG,CAACC,CAAAA,QAAS;AAAEhB,gBAAAA,EAAAA,EAAIgB,KAAKhB,EAAE;AAAEL,gBAAAA,MAAAA,EAAQqB,KAAKrB,MAAM;AAAEiE,gBAAAA,QAAAA,EAAU5C,KAAKE,MAAM,KAAK,OAAA,GAAUX,SAAAA,GAAYS,KAAKE;aAAO,CAAA,CAAA;QAClJ,OAAO2C,mCAAAA,CAAoBR,aAAahC,UAAAA,CAAWL,IAAI,EAAEiC,KAAAA,EAAOS,8BAAAA,CAAmBC,OAAO,EAAE;AAAEL,YAAAA,MAAAA;AAAQ3B,YAAAA,IAAAA,EAAMN,WAAWM;AAAK,SAAA,CAAA;AAChI,IAAA,CAAA,CAAA;AACJ;AAEA;;;;;;;;;;;;AAYC,IACM,SAASmC,OAAAA,CAAQC,QAAuB,EAAET,MAAc,EAAEU,OAAuB,EAAA;AACpF,IAAA,MAAMC,QAAQC,2BAAAA,CAAcH,QAAAA,CAAAA;AAC5B,IAAA,MAAMlF,MAAAA,GAASoF,KAAAA,CAAME,KAAK,CAAC3B,GAAG,CAACc,MAAAA,CAAAA;IAC/B,IAAI,CAACzE,QAAQ,OAAO0B,SAAAA;AAEpB,IAAA,MAAMzB,KAAAA,GAAQsF,yCAAAA,CAAqBL,QAAAA,EAAUC,OAAAA,CAAQK,KAAK,CAAA;AAC1D,IAAA,MAAM9C,MAAAA,GAAS+C,oCAAAA,CAAsBxF,KAAAA,EAAOkF,OAAAA,CAAQO,OAAO,CAAA;AAC3D,IAAA,MAAMjD,gBAAgBxC,KAAAA,CAAMG,MAAM,CAACC,EAAE,CAAC,EAAC,CAAA,EAAI0E,QAAAA;IAC3C,MAAM7E,WAAAA,GAAcuC,kBAAkBf,SAAAA,GAAYA,SAAAA,GAAYgB,OAAOiD,UAAU,CAAChC,GAAG,CAAClB,aAAAA,CAAAA;AACpF,IAAA,MAAMmD,gBAAgBC,2DAAAA,CAA8B5F,KAAAA,EAAOiF,SAASY,qBAAqB,EAAEX,QAAQO,OAAO,CAAA;IAE1G,MAAMlE,UAAAA,GAAazB,YAAAA,CAAaC,MAAAA,EAAQC,KAAAA,EAAOC,WAAAA,CAAAA;AAC/C,IAAA,MAAM6F,WAAAA,GAAcC,yBAAAA,CAAahG,MAAAA,EAAQmF,OAAAA,CAAQO,OAAO,CAAA;AACxD,IAAA,MAAMO,WAAAA,GAAcjG,MAAAA,CAAOQ,IAAI,KAAKI,yBAAAA,CAAcC,OAAO,GAAIb,MAAAA,CAAOkB,KAAK,CAAoBC,EAAE,GAAGO,SAAAA;IAClG,MAAMiB,gBAAAA,GAAmBiD,aAAAA,CAAcM,UAAU,CAAClD,IAAI,CAACC,CAAAA,SAAAA,GAAaA,SAAAA,CAAUhC,SAAS,KAAKgF,WAAAA,CAAAA,EAAcnF,MAAAA;AAE1G,IAAA,MAAMqF,WAAAA,GAAiC;AAChCJ,QAAAA,GAAAA,WAAAA,CAAYI,WAAW;AACvBP,QAAAA,GAAAA,aAAAA,CAAcO,WAAW,CAACC,MAAM,CAACC,CAAAA,UAAAA,GAAcA,UAAAA,CAAWpF,SAAS,KAAKS,SAAAA,IAAa2E,UAAAA,CAAWpF,SAAS,KAAKgF,WAAAA;AACpH,KAAA;AACD,IAAA,IAAIhG,KAAAA,CAAMG,MAAM,CAACiE,MAAM,KAAK,CAAA,EAAG;AAC3B8B,QAAAA,WAAAA,CAAYG,IAAI,CAAA,GAAIrG,KAAAA,CAAMkG,WAAW,CAACC,MAAM,CAACC,CAAAA,UAAAA,GAAcA,UAAAA,CAAWE,IAAI,KAAKC,2BAAeC,YAAY,CAAA,CAAA;AAC9G,IAAA;AAEA,IAAA,MAAMlC,UAAAA,GAAawB,WAAAA,CAAYxB,UAAU,CAACrC,GAAG,CAACM,CAAAA,UAAAA,GAAcD,eAAAA,CAAgBC,UAAAA,EAAYxC,MAAAA,EAAQwB,UAAAA,EAAYiB,eAAevC,WAAAA,EAAayC,gBAAAA,CAAAA,CAAAA;IACxI,IAAIwC,OAAAA,CAAQX,WAAW,EAAE;AACrB2B,QAAAA,WAAAA,CAAYG,IAAI,CAAA,GAAIhC,iBAAAA,CAAkBC,UAAAA,EAAYY,OAAAA,CAAQX,WAAW,EAAEC,MAAAA,CAAAA,CAAAA;AAC3E,IAAA;IAEA,OAAO;AACHA,QAAAA,MAAAA;AACAjE,QAAAA,IAAAA,EAAMR,OAAOQ,IAAI;AACjBkG,QAAAA,MAAAA,EAAQ1G,OAAO0G,MAAM;AACrBC,QAAAA,KAAAA,EAAO3G,OAAO2G,KAAK;AACnBC,QAAAA,QAAAA,EAAU5G,OAAO4G,QAAQ;AACzBpF,QAAAA,UAAAA;AACA+C,QAAAA,UAAAA;AACAsC,QAAAA,YAAAA,EAAcd,YAAYc,YAAY;AACtCC,QAAAA,SAAAA,EAAWvF,YAAYvB,MAAAA,EAAQwB,UAAAA,CAAAA;AAC/B2E,QAAAA;AACJ,KAAA;AACJ;;;"}
@@ -2,6 +2,7 @@
2
2
 
3
3
  var scene_model = require('@cratis/scene.model');
4
4
  var diagnostics = require('./diagnostics.js');
5
+ var iconDiagnostics = require('./iconDiagnostics.js');
5
6
  var exposureGrants = require('./exposureGrants.js');
6
7
  var pathAccess = require('./pathAccess.js');
7
8
  var propertyEdits = require('./propertyEdits.js');
@@ -59,7 +60,7 @@ function permitted(grant, operation, instance, diagnostics$1) {
59
60
  }
60
61
  return true;
61
62
  }
62
- function checkFields(grant, values, itemId, instance, diagnostics$1, requireAll) {
63
+ function checkFields(session, grant, values, itemId, instance, diagnostics$1, requireAll) {
63
64
  const context = {
64
65
  instance,
65
66
  component: grant.component,
@@ -80,6 +81,17 @@ function checkFields(grant, values, itemId, instance, diagnostics$1, requireAll)
80
81
  diagnostics$1.push(diagnostics.errorDiagnostic(problem.problem.startsWith('is not a field') ? scene_model.DiagnosticCode.UnknownCollectionField : scene_model.DiagnosticCode.InvalidValue, `'${problem.field}' ${problem.problem}.`, context));
81
82
  valid = false;
82
83
  }
84
+ const icons = session.context.iconCatalog;
85
+ if (icons && valid) {
86
+ const iconProblems = iconDiagnostics.iconProblemsOfItems(icons, itemDescriptor, [
87
+ {
88
+ id: itemId,
89
+ values
90
+ }
91
+ ], scene_model.DiagnosticSeverity.Error, context);
92
+ diagnostics$1.push(...iconProblems);
93
+ valid = !diagnostics.hasErrors(iconProblems);
94
+ }
83
95
  return valid;
84
96
  }
85
97
  function ownItems(clone, instance, grant) {
@@ -166,7 +178,7 @@ function save(clone, instance, grant, existing, items) {
166
178
  diagnostics$1.push(diagnostics.errorDiagnostic(scene_model.DiagnosticCode.InvalidValue, `'${grant.descriptor.label}' allows at most ${maximum} items.`, context));
167
179
  return;
168
180
  }
169
- if (!checkFields(grant, edit.item.values, edit.item.id, instance, diagnostics$1, true)) return;
181
+ if (!checkFields(session, grant, edit.item.values, edit.item.id, instance, diagnostics$1, true)) return;
170
182
  const { contribution, items } = ownItems(clone, instance, grant);
171
183
  if (edit.index !== undefined && (!Number.isInteger(edit.index) || edit.index < 0 || edit.index > items.length)) {
172
184
  diagnostics$1.push(diagnostics.errorDiagnostic(scene_model.DiagnosticCode.IndexOutOfRange, `There is no position ${edit.index} among ${items.length} items.`, context));
@@ -233,7 +245,7 @@ function findOwnItem(items, itemId, instance, grant, session, diagnostics$1) {
233
245
  const { contribution, items } = ownItems(clone, resolved.instance, resolved.grant);
234
246
  const position = findOwnItem(items, edit.itemId, resolved.instance, resolved.grant, session, diagnostics);
235
247
  if (position < 0) return;
236
- if (!checkFields(resolved.grant, {
248
+ if (!checkFields(session, resolved.grant, {
237
249
  [edit.field]: edit.value
238
250
  }, edit.itemId, resolved.instance, diagnostics, false)) return;
239
251
  const next = items.map((item, index)=>index === position ? {