@cratis/scene.engine 4.2.1 → 4.3.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 (205) hide show
  1. package/dist/cjs/editing/DescriptorCatalog.js +42 -0
  2. package/dist/cjs/editing/DescriptorCatalog.js.map +1 -0
  3. package/dist/cjs/editing/EditSession.js +44 -0
  4. package/dist/cjs/editing/EditSession.js.map +1 -0
  5. package/dist/cjs/editing/applyEdit.js +83 -0
  6. package/dist/cjs/editing/applyEdit.js.map +1 -0
  7. package/dist/cjs/editing/applyEffectiveConfiguration.js +62 -0
  8. package/dist/cjs/editing/applyEffectiveConfiguration.js.map +1 -0
  9. package/dist/cjs/editing/collectComponents.js +34 -0
  10. package/dist/cjs/editing/collectComponents.js.map +1 -0
  11. package/dist/cjs/editing/describeNode.js +63 -0
  12. package/dist/cjs/editing/describeNode.js.map +1 -0
  13. package/dist/cjs/editing/diagnostics.js +36 -0
  14. package/dist/cjs/editing/diagnostics.js.map +1 -0
  15. package/dist/cjs/editing/documentPaths.js +45 -0
  16. package/dist/cjs/editing/documentPaths.js.map +1 -0
  17. package/dist/cjs/editing/exposureEdits.js +106 -0
  18. package/dist/cjs/editing/exposureEdits.js.map +1 -0
  19. package/dist/cjs/editing/exposureGrants.js +115 -0
  20. package/dist/cjs/editing/exposureGrants.js.map +1 -0
  21. package/dist/cjs/editing/indexDocument.js +400 -0
  22. package/dist/cjs/editing/indexDocument.js.map +1 -0
  23. package/dist/cjs/editing/inspect.js +127 -0
  24. package/dist/cjs/editing/inspect.js.map +1 -0
  25. package/dist/cjs/editing/instanceEdits.js +255 -0
  26. package/dist/cjs/editing/instanceEdits.js.map +1 -0
  27. package/dist/cjs/editing/layoutTypeDescriptors.js +425 -0
  28. package/dist/cjs/editing/layoutTypeDescriptors.js.map +1 -0
  29. package/dist/cjs/editing/layoutTypeEdits.js +141 -0
  30. package/dist/cjs/editing/layoutTypeEdits.js.map +1 -0
  31. package/dist/cjs/editing/nodeIds.js +115 -0
  32. package/dist/cjs/editing/nodeIds.js.map +1 -0
  33. package/dist/cjs/editing/pathAccess.js +53 -0
  34. package/dist/cjs/editing/pathAccess.js.map +1 -0
  35. package/dist/cjs/editing/propertyEdits.js +118 -0
  36. package/dist/cjs/editing/propertyEdits.js.map +1 -0
  37. package/dist/cjs/editing/resolveEffectiveConfiguration.js +200 -0
  38. package/dist/cjs/editing/resolveEffectiveConfiguration.js.map +1 -0
  39. package/dist/cjs/editing/resolveTemplateChain.js +100 -0
  40. package/dist/cjs/editing/resolveTemplateChain.js.map +1 -0
  41. package/dist/cjs/editing/structureEdits.js +231 -0
  42. package/dist/cjs/editing/structureEdits.js.map +1 -0
  43. package/dist/cjs/editing/validateBinding.js +111 -0
  44. package/dist/cjs/editing/validateBinding.js.map +1 -0
  45. package/dist/cjs/editing/validateValue.js +114 -0
  46. package/dist/cjs/editing/validateValue.js.map +1 -0
  47. package/dist/cjs/index.js +51 -0
  48. package/dist/cjs/index.js.map +1 -1
  49. package/dist/esm/editing/DescriptorCatalog.d.ts +9 -0
  50. package/dist/esm/editing/DescriptorCatalog.d.ts.map +1 -0
  51. package/dist/esm/editing/DescriptorCatalog.js +38 -0
  52. package/dist/esm/editing/DescriptorCatalog.js.map +1 -0
  53. package/dist/esm/editing/DocumentIndex.d.ts +31 -0
  54. package/dist/esm/editing/DocumentIndex.d.ts.map +1 -0
  55. package/dist/esm/editing/DocumentIndex.js +2 -0
  56. package/dist/esm/editing/DocumentIndex.js.map +1 -0
  57. package/dist/esm/editing/EditOutcome.d.ts +7 -0
  58. package/dist/esm/editing/EditOutcome.d.ts.map +1 -0
  59. package/dist/esm/editing/EditOutcome.js +2 -0
  60. package/dist/esm/editing/EditOutcome.js.map +1 -0
  61. package/dist/esm/editing/EditSession.d.ts +20 -0
  62. package/dist/esm/editing/EditSession.d.ts.map +1 -0
  63. package/dist/esm/editing/EditSession.js +42 -0
  64. package/dist/esm/editing/EditSession.js.map +1 -0
  65. package/dist/esm/editing/EditingContext.d.ts +8 -0
  66. package/dist/esm/editing/EditingContext.d.ts.map +1 -0
  67. package/dist/esm/editing/EditingContext.js +2 -0
  68. package/dist/esm/editing/EditingContext.js.map +1 -0
  69. package/dist/esm/editing/TemplateChain.d.ts +13 -0
  70. package/dist/esm/editing/TemplateChain.d.ts.map +1 -0
  71. package/dist/esm/editing/TemplateChain.js +2 -0
  72. package/dist/esm/editing/TemplateChain.js.map +1 -0
  73. package/dist/esm/editing/applyEdit.d.ts +5 -0
  74. package/dist/esm/editing/applyEdit.d.ts.map +1 -0
  75. package/dist/esm/editing/applyEdit.js +81 -0
  76. package/dist/esm/editing/applyEdit.js.map +1 -0
  77. package/dist/esm/editing/applyEffectiveConfiguration.d.ts +3 -0
  78. package/dist/esm/editing/applyEffectiveConfiguration.d.ts.map +1 -0
  79. package/dist/esm/editing/applyEffectiveConfiguration.js +60 -0
  80. package/dist/esm/editing/applyEffectiveConfiguration.js.map +1 -0
  81. package/dist/esm/editing/collectComponents.d.ts +3 -0
  82. package/dist/esm/editing/collectComponents.d.ts.map +1 -0
  83. package/dist/esm/editing/collectComponents.js +32 -0
  84. package/dist/esm/editing/collectComponents.js.map +1 -0
  85. package/dist/esm/editing/describeNode.d.ts +11 -0
  86. package/dist/esm/editing/describeNode.d.ts.map +1 -0
  87. package/dist/esm/editing/describeNode.js +60 -0
  88. package/dist/esm/editing/describeNode.js.map +1 -0
  89. package/dist/esm/editing/diagnostics.d.ts +6 -0
  90. package/dist/esm/editing/diagnostics.d.ts.map +1 -0
  91. package/dist/esm/editing/diagnostics.js +32 -0
  92. package/dist/esm/editing/diagnostics.js.map +1 -0
  93. package/dist/esm/editing/documentPaths.d.ts +8 -0
  94. package/dist/esm/editing/documentPaths.d.ts.map +1 -0
  95. package/dist/esm/editing/documentPaths.js +41 -0
  96. package/dist/esm/editing/documentPaths.js.map +1 -0
  97. package/dist/esm/editing/exposureEdits.d.ts +5 -0
  98. package/dist/esm/editing/exposureEdits.d.ts.map +1 -0
  99. package/dist/esm/editing/exposureEdits.js +103 -0
  100. package/dist/esm/editing/exposureEdits.js.map +1 -0
  101. package/dist/esm/editing/exposureGrants.d.ts +21 -0
  102. package/dist/esm/editing/exposureGrants.d.ts.map +1 -0
  103. package/dist/esm/editing/exposureGrants.js +112 -0
  104. package/dist/esm/editing/exposureGrants.js.map +1 -0
  105. package/dist/esm/editing/given/a_layout_document.d.ts +14 -0
  106. package/dist/esm/editing/given/a_layout_document.d.ts.map +1 -0
  107. package/dist/esm/editing/given/a_layout_document.js +67 -0
  108. package/dist/esm/editing/given/a_layout_document.js.map +1 -0
  109. package/dist/esm/editing/given/a_scene_document.d.ts +20 -0
  110. package/dist/esm/editing/given/a_scene_document.d.ts.map +1 -0
  111. package/dist/esm/editing/given/a_scene_document.js +110 -0
  112. package/dist/esm/editing/given/a_scene_document.js.map +1 -0
  113. package/dist/esm/editing/index.d.ts +19 -0
  114. package/dist/esm/editing/index.d.ts.map +1 -0
  115. package/dist/esm/editing/index.js +19 -0
  116. package/dist/esm/editing/index.js.map +1 -0
  117. package/dist/esm/editing/indexDocument.d.ts +6 -0
  118. package/dist/esm/editing/indexDocument.d.ts.map +1 -0
  119. package/dist/esm/editing/indexDocument.js +396 -0
  120. package/dist/esm/editing/indexDocument.js.map +1 -0
  121. package/dist/esm/editing/inspect.d.ts +8 -0
  122. package/dist/esm/editing/inspect.d.ts.map +1 -0
  123. package/dist/esm/editing/inspect.js +124 -0
  124. package/dist/esm/editing/inspect.js.map +1 -0
  125. package/dist/esm/editing/instanceEdits.d.ts +9 -0
  126. package/dist/esm/editing/instanceEdits.d.ts.map +1 -0
  127. package/dist/esm/editing/instanceEdits.js +248 -0
  128. package/dist/esm/editing/instanceEdits.js.map +1 -0
  129. package/dist/esm/editing/layoutTypeDescriptors.d.ts +5 -0
  130. package/dist/esm/editing/layoutTypeDescriptors.d.ts.map +1 -0
  131. package/dist/esm/editing/layoutTypeDescriptors.js +421 -0
  132. package/dist/esm/editing/layoutTypeDescriptors.js.map +1 -0
  133. package/dist/esm/editing/layoutTypeEdits.d.ts +4 -0
  134. package/dist/esm/editing/layoutTypeEdits.d.ts.map +1 -0
  135. package/dist/esm/editing/layoutTypeEdits.js +139 -0
  136. package/dist/esm/editing/layoutTypeEdits.js.map +1 -0
  137. package/dist/esm/editing/nodeIds.d.ts +14 -0
  138. package/dist/esm/editing/nodeIds.d.ts.map +1 -0
  139. package/dist/esm/editing/nodeIds.js +102 -0
  140. package/dist/esm/editing/nodeIds.js.map +1 -0
  141. package/dist/esm/editing/pathAccess.d.ts +7 -0
  142. package/dist/esm/editing/pathAccess.d.ts.map +1 -0
  143. package/dist/esm/editing/pathAccess.js +48 -0
  144. package/dist/esm/editing/pathAccess.js.map +1 -0
  145. package/dist/esm/editing/propertyEdits.d.ts +15 -0
  146. package/dist/esm/editing/propertyEdits.d.ts.map +1 -0
  147. package/dist/esm/editing/propertyEdits.js +113 -0
  148. package/dist/esm/editing/propertyEdits.js.map +1 -0
  149. package/dist/esm/editing/resolveEffectiveConfiguration.d.ts +5 -0
  150. package/dist/esm/editing/resolveEffectiveConfiguration.d.ts.map +1 -0
  151. package/dist/esm/editing/resolveEffectiveConfiguration.js +198 -0
  152. package/dist/esm/editing/resolveEffectiveConfiguration.js.map +1 -0
  153. package/dist/esm/editing/resolveTemplateChain.d.ts +4 -0
  154. package/dist/esm/editing/resolveTemplateChain.d.ts.map +1 -0
  155. package/dist/esm/editing/resolveTemplateChain.js +98 -0
  156. package/dist/esm/editing/resolveTemplateChain.js.map +1 -0
  157. package/dist/esm/editing/structureEdits.d.ts +6 -0
  158. package/dist/esm/editing/structureEdits.d.ts.map +1 -0
  159. package/dist/esm/editing/structureEdits.js +227 -0
  160. package/dist/esm/editing/structureEdits.js.map +1 -0
  161. package/dist/esm/editing/validateBinding.d.ts +7 -0
  162. package/dist/esm/editing/validateBinding.d.ts.map +1 -0
  163. package/dist/esm/editing/validateBinding.js +108 -0
  164. package/dist/esm/editing/validateBinding.js.map +1 -0
  165. package/dist/esm/editing/validateValue.d.ts +8 -0
  166. package/dist/esm/editing/validateValue.d.ts.map +1 -0
  167. package/dist/esm/editing/validateValue.js +111 -0
  168. package/dist/esm/editing/validateValue.js.map +1 -0
  169. package/dist/esm/index.d.ts +1 -0
  170. package/dist/esm/index.d.ts.map +1 -1
  171. package/dist/esm/index.js +14 -0
  172. package/dist/esm/index.js.map +1 -1
  173. package/dist/esm/tsconfig.tsbuildinfo +1 -1
  174. package/editing/DescriptorCatalog.ts +51 -0
  175. package/editing/DocumentIndex.ts +73 -0
  176. package/editing/EditOutcome.ts +21 -0
  177. package/editing/EditSession.ts +50 -0
  178. package/editing/EditingContext.ts +23 -0
  179. package/editing/TemplateChain.ts +36 -0
  180. package/editing/applyEdit.ts +69 -0
  181. package/editing/applyEffectiveConfiguration.ts +53 -0
  182. package/editing/collectComponents.ts +36 -0
  183. package/editing/describeNode.ts +61 -0
  184. package/editing/diagnostics.ts +30 -0
  185. package/editing/documentPaths.ts +40 -0
  186. package/editing/exposureEdits.ts +119 -0
  187. package/editing/exposureGrants.ts +159 -0
  188. package/editing/given/a_layout_document.ts +88 -0
  189. package/editing/given/a_scene_document.ts +135 -0
  190. package/editing/index.ts +21 -0
  191. package/editing/indexDocument.ts +237 -0
  192. package/editing/inspect.ts +142 -0
  193. package/editing/instanceEdits.ts +243 -0
  194. package/editing/layoutTypeDescriptors.ts +191 -0
  195. package/editing/layoutTypeEdits.ts +135 -0
  196. package/editing/nodeIds.ts +111 -0
  197. package/editing/pathAccess.ts +81 -0
  198. package/editing/propertyEdits.ts +119 -0
  199. package/editing/resolveEffectiveConfiguration.ts +202 -0
  200. package/editing/resolveTemplateChain.ts +109 -0
  201. package/editing/structureEdits.ts +234 -0
  202. package/editing/validateBinding.ts +103 -0
  203. package/editing/validateValue.ts +130 -0
  204. package/index.ts +1 -0
  205. package/package.json +3 -3
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exposureEdits.js","sources":["../../../editing/exposureEdits.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, ExposedProperty, ExposePropertyEdit, PropertyValueType, SceneDiagnostic,\n SceneDocument, UnexposePropertyEdit,\n} from '@cratis/scene.model';\nimport { findComponentDescriptor } from './DescriptorCatalog';\nimport { errorDiagnostic } from './diagnostics';\nimport { EditSession } from './EditSession';\nimport { grantKey } from './exposureGrants';\nimport { cloneData } from './pathAccess';\n\nfunction ownsDeclaration(session: EditSession, owner: string, diagnostics: SceneDiagnostic[]): boolean {\n const level = session.chain.levels.at(-1);\n if (!level || level.owner !== owner) {\n diagnostics.push(errorDiagnostic(DiagnosticCode.NodeNotEditable, `Exposure is declared by the layout or template that owns the component. '${owner}' is not what is being edited.`));\n return false;\n }\n\n return true;\n}\n\nfunction validateExposure(session: EditSession, property: ExposedProperty, diagnostics: SceneDiagnostic[]): boolean {\n const context = { component: property.component, path: property.path };\n const level = session.chain.levels.at(-1)!;\n const reExposed = property.reExposes !== undefined;\n\n if (!reExposed && !level.elements.some(candidate => candidate.id === property.component)) {\n diagnostics.push(errorDiagnostic(DiagnosticCode.ExposureTargetMissing, `'${level.owner}' has no component '${property.component}'.`, context));\n return false;\n }\n\n const grant = reExposed ? session.scopeGrants.get(grantKey(property.component, property.path)) : undefined;\n if (reExposed && (!grant || grant.owner !== property.reExposes)) {\n diagnostics.push(errorDiagnostic(DiagnosticCode.ReExposureBroken, `'${property.reExposes}' does not expose '${property.path}' on '${property.component}' to '${level.owner}', so it cannot be passed on.`, context));\n return false;\n }\n\n const element = level.elements.find(candidate => candidate.id === property.component);\n const descriptor = grant\n ? grant.descriptor\n : findComponentDescriptor(session.context.catalog, element!.componentName)?.properties.find(candidate => candidate.path === property.path);\n if (!descriptor) {\n diagnostics.push(errorDiagnostic(DiagnosticCode.ExposureTargetMissing, `There is no editable property '${property.path}' on '${property.component}'.`, context));\n return false;\n }\n\n const operations = property.operations ?? [];\n if (descriptor.valueType !== PropertyValueType.Collection) {\n if (operations.length > 0 || property.editableFields !== undefined) {\n diagnostics.push(errorDiagnostic(DiagnosticCode.InvalidEdit, `'${descriptor.label}' is not a collection, so operations and editable fields do not apply.`, context));\n return false;\n }\n\n return true;\n }\n\n const known = Object.values(CollectionOperation) as string[];\n const unknown = operations.find(operation => !known.includes(operation));\n if (unknown !== undefined) {\n diagnostics.push(errorDiagnostic(DiagnosticCode.InvalidEdit, `'${unknown}' is not a collection operation.`, context));\n return false;\n }\n\n const fields = descriptor.item?.properties.map(candidate => candidate.path) ?? [];\n const unknownField = property.editableFields?.find(field => !fields.includes(field));\n if (unknownField !== undefined) {\n diagnostics.push(errorDiagnostic(DiagnosticCode.UnknownCollectionField, `Items of '${descriptor.label}' have no field '${unknownField}'.`, context));\n return false;\n }\n\n if (grant && (operations.some(operation => !grant.operations.includes(operation))\n || (grant.editableFields !== undefined && (property.editableFields ?? fields).some(field => !grant.editableFields!.includes(field))))) {\n diagnostics.push(errorDiagnostic(DiagnosticCode.ExposureWidensOwner, `'${property.reExposes}' exposed less of '${descriptor.label}' than this re-exposes.`, context));\n return false;\n }\n\n return true;\n}\n\n/**\n * Applies an exposure declaration to a copy of the document.\n *\n * Exposure only narrows: the property has to be one the component's descriptor supports, a collection's\n * operations and fields have to exist, and a re-exposure cannot grant more than the owner it passes on.\n */\nexport function applyExposeProperty(session: EditSession, edit: ExposePropertyEdit, clone: SceneDocument, diagnostics: SceneDiagnostic[]): void {\n if (!ownsDeclaration(session, edit.owner, diagnostics) || !validateExposure(session, edit.property, diagnostics)) return;\n\n let declaration = clone.exposures.find(candidate => candidate.owner === edit.owner);\n if (!declaration) {\n declaration = { owner: edit.owner, properties: [] };\n clone.exposures.push(declaration);\n }\n\n const same = (candidate: ExposedProperty) => candidate.component === edit.property.component\n && candidate.path === edit.property.path && candidate.reExposes === edit.property.reExposes;\n const position = declaration.properties.findIndex(same);\n if (position >= 0) declaration.properties[position] = cloneData(edit.property);\n else declaration.properties.push(cloneData(edit.property));\n}\n\n/**\n * Applies an exposure withdrawal to a copy of the document. Values already saved against it are not touched.\n */\nexport function applyUnexposeProperty(session: EditSession, edit: UnexposePropertyEdit, clone: SceneDocument, diagnostics: SceneDiagnostic[]): void {\n if (!ownsDeclaration(session, edit.owner, diagnostics)) return;\n\n const declaration = clone.exposures.find(candidate => candidate.owner === edit.owner);\n const remaining = declaration?.properties.filter(candidate => !(candidate.component === edit.component && candidate.path === edit.path));\n if (!declaration || remaining!.length === declaration.properties.length) {\n diagnostics.push(errorDiagnostic(DiagnosticCode.ExposureTargetMissing, `'${edit.owner}' does not expose '${edit.path}' on '${edit.component}'.`, { component: edit.component, path: edit.path }));\n return;\n }\n\n if (remaining!.length === 0) clone.exposures.splice(clone.exposures.indexOf(declaration), 1);\n else declaration.properties = remaining!;\n}\n"],"names":["ownsDeclaration","session","owner","diagnostics","level","chain","levels","at","push","errorDiagnostic","DiagnosticCode","NodeNotEditable","validateExposure","property","context","component","path","reExposed","reExposes","undefined","elements","some","candidate","id","ExposureTargetMissing","grant","scopeGrants","get","grantKey","ReExposureBroken","element","find","descriptor","findComponentDescriptor","catalog","componentName","properties","operations","valueType","PropertyValueType","Collection","length","editableFields","InvalidEdit","label","known","Object","values","CollectionOperation","unknown","operation","includes","fields","item","map","unknownField","field","UnknownCollectionField","ExposureWidensOwner","applyExposeProperty","edit","clone","declaration","exposures","same","position","findIndex","cloneData","applyUnexposeProperty","remaining","filter","splice","indexOf"],"mappings":"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"}
@@ -0,0 +1,115 @@
1
+ 'use strict';
2
+
3
+ var scene_model = require('@cratis/scene.model');
4
+ var DescriptorCatalog = require('./DescriptorCatalog.js');
5
+ var diagnostics = require('./diagnostics.js');
6
+
7
+ // Copyright (c) Cratis. All rights reserved.
8
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
9
+ /**
10
+ * The key a grant is stored under.
11
+ */ function grantKey(component, path) {
12
+ return `${component}\u0000${path}`;
13
+ }
14
+ function narrow(grant, reExposure) {
15
+ const requested = reExposure.operations ?? [];
16
+ const operations = requested.filter((operation)=>grant.operations.includes(operation));
17
+ const fields = grant.editableFields === undefined ? reExposure.editableFields : reExposure.editableFields === undefined ? grant.editableFields : reExposure.editableFields.filter((field)=>grant.editableFields.includes(field));
18
+ const widened = operations.length < requested.length || grant.editableFields !== undefined && reExposure.editableFields !== undefined && reExposure.editableFields.some((field)=>!grant.editableFields.includes(field));
19
+ return {
20
+ grant: {
21
+ ...grant,
22
+ operations,
23
+ editableFields: fields,
24
+ label: reExposure.label ?? grant.label
25
+ },
26
+ widened
27
+ };
28
+ }
29
+ /**
30
+ * Works out, for every instance in a chain, which properties it may configure.
31
+ *
32
+ * An owner's exposure reaches the instance directly inside it. It reaches further only through explicit
33
+ * re-exposure by every level in between, and each re-exposure can only narrow what it passes on - a nested
34
+ * template that lists more operations or fields than its owner granted gets the owner's, not its own.
35
+ *
36
+ * @param chain The chain to analyze.
37
+ * @param catalog The descriptors that say what each component supports.
38
+ */ function computeExposureGrants(chain, catalog) {
39
+ const result = {
40
+ exposed: [],
41
+ byInstance: new Map(),
42
+ diagnostics: []
43
+ };
44
+ for (const chainLevel of chain.levels)result.byInstance.set(chainLevel.instance, new Map());
45
+ const consumed = new Set();
46
+ chain.levels.forEach((owner, ownerLevel)=>{
47
+ for (const exposure of owner.exposures.filter((candidate)=>candidate.reExposes === undefined)){
48
+ const element = owner.elements.find((candidate)=>candidate.id === exposure.component);
49
+ if (!element) {
50
+ result.diagnostics.push(diagnostics.errorDiagnostic(scene_model.DiagnosticCode.ExposureTargetMissing, `'${owner.owner}' exposes '${exposure.path}' on '${exposure.component}', but it has no such component.`, {
51
+ component: exposure.component,
52
+ path: exposure.path
53
+ }));
54
+ continue;
55
+ }
56
+ const descriptor = DescriptorCatalog.findComponentDescriptor(catalog, element.componentName);
57
+ if (!descriptor) {
58
+ result.diagnostics.push(diagnostics.errorDiagnostic(scene_model.DiagnosticCode.MissingComponentDescriptor, `'${owner.owner}' exposes '${exposure.path}' on '${exposure.component}', but nothing describes the component '${element.componentName}'.`, {
59
+ component: exposure.component,
60
+ path: exposure.path
61
+ }));
62
+ continue;
63
+ }
64
+ const property = descriptor.properties.find((candidate)=>candidate.path === exposure.path);
65
+ if (!property) {
66
+ result.diagnostics.push(diagnostics.errorDiagnostic(scene_model.DiagnosticCode.ExposureTargetMissing, `'${owner.owner}' exposes '${exposure.path}' on '${exposure.component}', but '${element.componentName}' no longer has that property.`, {
67
+ component: exposure.component,
68
+ path: exposure.path
69
+ }));
70
+ continue;
71
+ }
72
+ const isCollection = property.valueType === scene_model.PropertyValueType.Collection;
73
+ let current = {
74
+ component: exposure.component,
75
+ path: exposure.path,
76
+ descriptor: property,
77
+ owner: owner.owner,
78
+ ownerLevel,
79
+ operations: isCollection ? [
80
+ ...new Set(exposure.operations ?? [])
81
+ ] : [],
82
+ editableFields: isCollection ? exposure.editableFields : undefined,
83
+ label: exposure.label
84
+ };
85
+ result.exposed.push(current);
86
+ for(let contributor = ownerLevel + 1; contributor < chain.levels.length; contributor++){
87
+ result.byInstance.get(chain.levels[contributor].instance).set(grantKey(exposure.component, exposure.path), current);
88
+ const reExposure = chain.levels[contributor].exposures.find((candidate)=>candidate.reExposes === owner.owner && candidate.component === exposure.component && candidate.path === exposure.path);
89
+ if (!reExposure) break;
90
+ consumed.add(reExposure);
91
+ const narrowed = narrow(current, reExposure);
92
+ if (narrowed.widened) {
93
+ result.diagnostics.push(diagnostics.errorDiagnostic(scene_model.DiagnosticCode.ExposureWidensOwner, `'${chain.levels[contributor].owner}' re-exposes more of '${exposure.path}' than '${owner.owner}' exposed; only what the owner granted is passed on.`, {
94
+ component: exposure.component,
95
+ path: exposure.path
96
+ }));
97
+ }
98
+ current = narrowed.grant;
99
+ }
100
+ }
101
+ });
102
+ for (const chainLevel of chain.levels){
103
+ for (const reExposure of chainLevel.exposures.filter((candidate)=>candidate.reExposes !== undefined && !consumed.has(candidate))){
104
+ result.diagnostics.push(diagnostics.errorDiagnostic(scene_model.DiagnosticCode.ReExposureBroken, `'${chainLevel.owner}' re-exposes '${reExposure.path}' on '${reExposure.component}' from '${reExposure.reExposes}', which does not expose it to this chain.`, {
105
+ component: reExposure.component,
106
+ path: reExposure.path
107
+ }));
108
+ }
109
+ }
110
+ return result;
111
+ }
112
+
113
+ exports.computeExposureGrants = computeExposureGrants;
114
+ exports.grantKey = grantKey;
115
+ //# sourceMappingURL=exposureGrants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exposureGrants.js","sources":["../../../editing/exposureGrants.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, ExposedProperty, PropertyDescriptor, PropertyValueType, SceneDiagnostic,\n} from '@cratis/scene.model';\nimport { DescriptorCatalog, findComponentDescriptor } from './DescriptorCatalog';\nimport { errorDiagnostic } from './diagnostics';\nimport { TemplateChain } from './TemplateChain';\n\n/**\n * What one instance may configure on one property: the owner's exposure, narrowed by every re-exposure between the\n * owner and that instance.\n */\nexport interface ExposureGrant {\n /** The id of the element that owns the property. */\n component: string;\n\n path: string;\n descriptor: PropertyDescriptor;\n\n /** The name of the layout or template that owns the element. */\n owner: string;\n\n /** The index of the owner in the chain. */\n ownerLevel: number;\n\n /** For a collection: what may be done to it. Empty for any other property. */\n operations: CollectionOperation[];\n\n /** For a collection: the item fields that may be changed; absent means all of them. */\n editableFields?: string[];\n\n label?: string;\n}\n\n/**\n * The outcome of working out who may configure what.\n */\nexport interface ExposureGrants {\n /** Every valid exposure, one per owner-declared property, at the level of its owner. */\n exposed: ExposureGrant[];\n\n /** For each contributing instance id, what it may configure, keyed by {@link grantKey}. */\n byInstance: Map<string, Map<string, ExposureGrant>>;\n\n diagnostics: SceneDiagnostic[];\n}\n\n/**\n * The key a grant is stored under.\n */\nexport function grantKey(component: string, path: string): string {\n return `${component}\\u0000${path}`;\n}\n\nfunction narrow(grant: ExposureGrant, reExposure: ExposedProperty): { grant: ExposureGrant; widened: boolean } {\n const requested = reExposure.operations ?? [];\n const operations = requested.filter(operation => grant.operations.includes(operation));\n const fields = grant.editableFields === undefined\n ? reExposure.editableFields\n : (reExposure.editableFields === undefined ? grant.editableFields : reExposure.editableFields.filter(field => grant.editableFields!.includes(field)));\n\n const widened = operations.length < requested.length\n || (grant.editableFields !== undefined && reExposure.editableFields !== undefined && reExposure.editableFields.some(field => !grant.editableFields!.includes(field)));\n\n return { grant: { ...grant, operations, editableFields: fields, label: reExposure.label ?? grant.label }, widened };\n}\n\n/**\n * Works out, for every instance in a chain, which properties it may configure.\n *\n * An owner's exposure reaches the instance directly inside it. It reaches further only through explicit\n * re-exposure by every level in between, and each re-exposure can only narrow what it passes on - a nested\n * template that lists more operations or fields than its owner granted gets the owner's, not its own.\n *\n * @param chain The chain to analyze.\n * @param catalog The descriptors that say what each component supports.\n */\nexport function computeExposureGrants(chain: TemplateChain, catalog: DescriptorCatalog): ExposureGrants {\n const result: ExposureGrants = { exposed: [], byInstance: new Map(), diagnostics: [] };\n for (const chainLevel of chain.levels) result.byInstance.set(chainLevel.instance, new Map());\n\n const consumed = new Set<ExposedProperty>();\n\n chain.levels.forEach((owner, ownerLevel) => {\n for (const exposure of owner.exposures.filter(candidate => candidate.reExposes === undefined)) {\n const element = owner.elements.find(candidate => candidate.id === exposure.component);\n if (!element) {\n result.diagnostics.push(errorDiagnostic(\n DiagnosticCode.ExposureTargetMissing,\n `'${owner.owner}' exposes '${exposure.path}' on '${exposure.component}', but it has no such component.`,\n { component: exposure.component, path: exposure.path }));\n continue;\n }\n\n const descriptor = findComponentDescriptor(catalog, element.componentName);\n if (!descriptor) {\n result.diagnostics.push(errorDiagnostic(\n DiagnosticCode.MissingComponentDescriptor,\n `'${owner.owner}' exposes '${exposure.path}' on '${exposure.component}', but nothing describes the component '${element.componentName}'.`,\n { component: exposure.component, path: exposure.path }));\n continue;\n }\n\n const property = descriptor.properties.find(candidate => candidate.path === exposure.path);\n if (!property) {\n result.diagnostics.push(errorDiagnostic(\n DiagnosticCode.ExposureTargetMissing,\n `'${owner.owner}' exposes '${exposure.path}' on '${exposure.component}', but '${element.componentName}' no longer has that property.`,\n { component: exposure.component, path: exposure.path }));\n continue;\n }\n\n const isCollection = property.valueType === PropertyValueType.Collection;\n let current: ExposureGrant = {\n component: exposure.component,\n path: exposure.path,\n descriptor: property,\n owner: owner.owner,\n ownerLevel,\n operations: isCollection ? [...new Set(exposure.operations ?? [])] : [],\n editableFields: isCollection ? exposure.editableFields : undefined,\n label: exposure.label,\n };\n result.exposed.push(current);\n\n for (let contributor = ownerLevel + 1; contributor < chain.levels.length; contributor++) {\n result.byInstance.get(chain.levels[contributor].instance)!.set(grantKey(exposure.component, exposure.path), current);\n\n const reExposure = chain.levels[contributor].exposures.find(candidate =>\n candidate.reExposes === owner.owner && candidate.component === exposure.component && candidate.path === exposure.path);\n if (!reExposure) break;\n\n consumed.add(reExposure);\n const narrowed = narrow(current, reExposure);\n if (narrowed.widened) {\n result.diagnostics.push(errorDiagnostic(\n DiagnosticCode.ExposureWidensOwner,\n `'${chain.levels[contributor].owner}' re-exposes more of '${exposure.path}' than '${owner.owner}' exposed; only what the owner granted is passed on.`,\n { component: exposure.component, path: exposure.path }));\n }\n\n current = narrowed.grant;\n }\n }\n });\n\n for (const chainLevel of chain.levels) {\n for (const reExposure of chainLevel.exposures.filter(candidate => candidate.reExposes !== undefined && !consumed.has(candidate))) {\n result.diagnostics.push(errorDiagnostic(\n DiagnosticCode.ReExposureBroken,\n `'${chainLevel.owner}' re-exposes '${reExposure.path}' on '${reExposure.component}' from '${reExposure.reExposes}', which does not expose it to this chain.`,\n { component: reExposure.component, path: reExposure.path }));\n }\n }\n\n return result;\n}\n"],"names":["grantKey","component","path","narrow","grant","reExposure","requested","operations","filter","operation","includes","fields","editableFields","undefined","field","widened","length","some","label","computeExposureGrants","chain","catalog","result","exposed","byInstance","Map","diagnostics","chainLevel","levels","set","instance","consumed","Set","forEach","owner","ownerLevel","exposure","exposures","candidate","reExposes","element","elements","find","id","push","errorDiagnostic","DiagnosticCode","ExposureTargetMissing","descriptor","findComponentDescriptor","componentName","MissingComponentDescriptor","property","properties","isCollection","valueType","PropertyValueType","Collection","current","contributor","get","add","narrowed","ExposureWidensOwner","has","ReExposureBroken"],"mappings":";;;;;;AAAA;AACA;AAgDA;;AAEC,IACM,SAASA,QAAAA,CAASC,SAAiB,EAAEC,IAAY,EAAA;AACpD,IAAA,OAAO,CAAA,EAAGD,SAAAA,CAAU,MAAM,EAAEC,IAAAA,CAAAA,CAAM;AACtC;AAEA,SAASC,MAAAA,CAAOC,KAAoB,EAAEC,UAA2B,EAAA;AAC7D,IAAA,MAAMC,SAAAA,GAAYD,UAAAA,CAAWE,UAAU,IAAI,EAAE;IAC7C,MAAMA,UAAAA,GAAaD,SAAAA,CAAUE,MAAM,CAACC,CAAAA,YAAaL,KAAAA,CAAMG,UAAU,CAACG,QAAQ,CAACD,SAAAA,CAAAA,CAAAA;IAC3E,MAAME,MAAAA,GAASP,KAAAA,CAAMQ,cAAc,KAAKC,SAAAA,GAClCR,UAAAA,CAAWO,cAAc,GACxBP,UAAAA,CAAWO,cAAc,KAAKC,SAAAA,GAAYT,KAAAA,CAAMQ,cAAc,GAAGP,UAAAA,CAAWO,cAAc,CAACJ,MAAM,CAACM,CAAAA,KAAAA,GAASV,KAAAA,CAAMQ,cAAc,CAAEF,QAAQ,CAACI,KAAAA,CAAAA,CAAAA;IAEjJ,MAAMC,OAAAA,GAAUR,UAAAA,CAAWS,MAAM,GAAGV,SAAAA,CAAUU,MAAM,IAC5CZ,KAAAA,CAAMQ,cAAc,KAAKC,SAAAA,IAAaR,UAAAA,CAAWO,cAAc,KAAKC,SAAAA,IAAaR,UAAAA,CAAWO,cAAc,CAACK,IAAI,CAACH,CAAAA,KAAAA,GAAS,CAACV,KAAAA,CAAMQ,cAAc,CAAEF,QAAQ,CAACI,KAAAA,CAAAA,CAAAA;IAEjK,OAAO;QAAEV,KAAAA,EAAO;AAAE,YAAA,GAAGA,KAAK;AAAEG,YAAAA,UAAAA;YAAYK,cAAAA,EAAgBD,MAAAA;AAAQO,YAAAA,KAAAA,EAAOb,UAAAA,CAAWa,KAAK,IAAId,KAAAA,CAAMc;AAAM,SAAA;AAAGH,QAAAA;AAAQ,KAAA;AACtH;AAEA;;;;;;;;;AASC,IACM,SAASI,qBAAAA,CAAsBC,KAAoB,EAAEC,OAA0B,EAAA;AAClF,IAAA,MAAMC,MAAAA,GAAyB;AAAEC,QAAAA,OAAAA,EAAS,EAAE;AAAEC,QAAAA,UAAAA,EAAY,IAAIC,GAAAA,EAAAA;AAAOC,QAAAA,WAAAA,EAAa;AAAG,KAAA;AACrF,IAAA,KAAK,MAAMC,UAAAA,IAAcP,KAAAA,CAAMQ,MAAM,CAAEN,MAAAA,CAAOE,UAAU,CAACK,GAAG,CAACF,UAAAA,CAAWG,QAAQ,EAAE,IAAIL,GAAAA,EAAAA,CAAAA;AAEtF,IAAA,MAAMM,WAAW,IAAIC,GAAAA,EAAAA;AAErBZ,IAAAA,KAAAA,CAAMQ,MAAM,CAACK,OAAO,CAAC,CAACC,KAAAA,EAAOC,UAAAA,GAAAA;AACzB,QAAA,KAAK,MAAMC,QAAAA,IAAYF,KAAAA,CAAMG,SAAS,CAAC7B,MAAM,CAAC8B,CAAAA,SAAAA,GAAaA,SAAAA,CAAUC,SAAS,KAAK1B,SAAAA,CAAAA,CAAY;AAC3F,YAAA,MAAM2B,OAAAA,GAAUN,KAAAA,CAAMO,QAAQ,CAACC,IAAI,CAACJ,CAAAA,SAAAA,GAAaA,SAAAA,CAAUK,EAAE,KAAKP,QAAAA,CAASnC,SAAS,CAAA;AACpF,YAAA,IAAI,CAACuC,OAAAA,EAAS;gBACVlB,MAAAA,CAAOI,WAAW,CAACkB,IAAI,CAACC,2BAAAA,CACpBC,0BAAAA,CAAeC,qBAAqB,EACpC,CAAC,CAAC,EAAEb,KAAAA,CAAMA,KAAK,CAAC,WAAW,EAAEE,QAAAA,CAASlC,IAAI,CAAC,MAAM,EAAEkC,QAAAA,CAASnC,SAAS,CAAC,gCAAgC,CAAC,EACvG;AAAEA,oBAAAA,SAAAA,EAAWmC,SAASnC,SAAS;AAAEC,oBAAAA,IAAAA,EAAMkC,SAASlC;AAAK,iBAAA,CAAA,CAAA;AACzD,gBAAA;AACJ,YAAA;AAEA,YAAA,MAAM8C,UAAAA,GAAaC,yCAAAA,CAAwB5B,OAAAA,EAASmB,OAAAA,CAAQU,aAAa,CAAA;AACzE,YAAA,IAAI,CAACF,UAAAA,EAAY;AACb1B,gBAAAA,MAAAA,CAAOI,WAAW,CAACkB,IAAI,CAACC,2BAAAA,CACpBC,0BAAAA,CAAeK,0BAA0B,EACzC,CAAC,CAAC,EAAEjB,KAAAA,CAAMA,KAAK,CAAC,WAAW,EAAEE,QAAAA,CAASlC,IAAI,CAAC,MAAM,EAAEkC,SAASnC,SAAS,CAAC,wCAAwC,EAAEuC,OAAAA,CAAQU,aAAa,CAAC,EAAE,CAAC,EACzI;AAAEjD,oBAAAA,SAAAA,EAAWmC,SAASnC,SAAS;AAAEC,oBAAAA,IAAAA,EAAMkC,SAASlC;AAAK,iBAAA,CAAA,CAAA;AACzD,gBAAA;AACJ,YAAA;AAEA,YAAA,MAAMkD,QAAAA,GAAWJ,UAAAA,CAAWK,UAAU,CAACX,IAAI,CAACJ,CAAAA,SAAAA,GAAaA,SAAAA,CAAUpC,IAAI,KAAKkC,QAAAA,CAASlC,IAAI,CAAA;AACzF,YAAA,IAAI,CAACkD,QAAAA,EAAU;AACX9B,gBAAAA,MAAAA,CAAOI,WAAW,CAACkB,IAAI,CAACC,2BAAAA,CACpBC,0BAAAA,CAAeC,qBAAqB,EACpC,CAAC,CAAC,EAAEb,KAAAA,CAAMA,KAAK,CAAC,WAAW,EAAEE,QAAAA,CAASlC,IAAI,CAAC,MAAM,EAAEkC,SAASnC,SAAS,CAAC,QAAQ,EAAEuC,OAAAA,CAAQU,aAAa,CAAC,8BAA8B,CAAC,EACrI;AAAEjD,oBAAAA,SAAAA,EAAWmC,SAASnC,SAAS;AAAEC,oBAAAA,IAAAA,EAAMkC,SAASlC;AAAK,iBAAA,CAAA,CAAA;AACzD,gBAAA;AACJ,YAAA;AAEA,YAAA,MAAMoD,YAAAA,GAAeF,QAAAA,CAASG,SAAS,KAAKC,8BAAkBC,UAAU;AACxE,YAAA,IAAIC,OAAAA,GAAyB;AACzBzD,gBAAAA,SAAAA,EAAWmC,SAASnC,SAAS;AAC7BC,gBAAAA,IAAAA,EAAMkC,SAASlC,IAAI;gBACnB8C,UAAAA,EAAYI,QAAAA;AACZlB,gBAAAA,KAAAA,EAAOA,MAAMA,KAAK;AAClBC,gBAAAA,UAAAA;AACA5B,gBAAAA,UAAAA,EAAY+C,YAAAA,GAAe;AAAI,oBAAA,GAAA,IAAItB,GAAAA,CAAII,QAAAA,CAAS7B,UAAU,IAAI,EAAE;AAAE,iBAAA,GAAG,EAAE;gBACvEK,cAAAA,EAAgB0C,YAAAA,GAAelB,QAAAA,CAASxB,cAAc,GAAGC,SAAAA;AACzDK,gBAAAA,KAAAA,EAAOkB,SAASlB;AACpB,aAAA;YACAI,MAAAA,CAAOC,OAAO,CAACqB,IAAI,CAACc,OAAAA,CAAAA;YAEpB,IAAK,IAAIC,WAAAA,GAAcxB,UAAAA,GAAa,CAAA,EAAGwB,WAAAA,GAAcvC,MAAMQ,MAAM,CAACZ,MAAM,EAAE2C,WAAAA,EAAAA,CAAe;AACrFrC,gBAAAA,MAAAA,CAAOE,UAAU,CAACoC,GAAG,CAACxC,KAAAA,CAAMQ,MAAM,CAAC+B,WAAAA,CAAY,CAAC7B,QAAQ,CAAA,CAAGD,GAAG,CAAC7B,QAAAA,CAASoC,QAAAA,CAASnC,SAAS,EAAEmC,QAAAA,CAASlC,IAAI,CAAA,EAAGwD,OAAAA,CAAAA;AAE5G,gBAAA,MAAMrD,UAAAA,GAAae,KAAAA,CAAMQ,MAAM,CAAC+B,WAAAA,CAAY,CAACtB,SAAS,CAACK,IAAI,CAACJ,CAAAA,SAAAA,GACxDA,SAAAA,CAAUC,SAAS,KAAKL,KAAAA,CAAMA,KAAK,IAAII,SAAAA,CAAUrC,SAAS,KAAKmC,QAAAA,CAASnC,SAAS,IAAIqC,SAAAA,CAAUpC,IAAI,KAAKkC,QAAAA,CAASlC,IAAI,CAAA;AACzH,gBAAA,IAAI,CAACG,UAAAA,EAAY;AAEjB0B,gBAAAA,QAAAA,CAAS8B,GAAG,CAACxD,UAAAA,CAAAA;gBACb,MAAMyD,QAAAA,GAAW3D,OAAOuD,OAAAA,EAASrD,UAAAA,CAAAA;gBACjC,IAAIyD,QAAAA,CAAS/C,OAAO,EAAE;AAClBO,oBAAAA,MAAAA,CAAOI,WAAW,CAACkB,IAAI,CAACC,2BAAAA,CACpBC,0BAAAA,CAAeiB,mBAAmB,EAClC,CAAC,CAAC,EAAE3C,KAAAA,CAAMQ,MAAM,CAAC+B,WAAAA,CAAY,CAACzB,KAAK,CAAC,sBAAsB,EAAEE,QAAAA,CAASlC,IAAI,CAAC,QAAQ,EAAEgC,KAAAA,CAAMA,KAAK,CAAC,oDAAoD,CAAC,EACrJ;AAAEjC,wBAAAA,SAAAA,EAAWmC,SAASnC,SAAS;AAAEC,wBAAAA,IAAAA,EAAMkC,SAASlC;AAAK,qBAAA,CAAA,CAAA;AAC7D,gBAAA;AAEAwD,gBAAAA,OAAAA,GAAUI,SAAS1D,KAAK;AAC5B,YAAA;AACJ,QAAA;AACJ,IAAA,CAAA,CAAA;AAEA,IAAA,KAAK,MAAMuB,UAAAA,IAAcP,KAAAA,CAAMQ,MAAM,CAAE;AACnC,QAAA,KAAK,MAAMvB,UAAAA,IAAcsB,UAAAA,CAAWU,SAAS,CAAC7B,MAAM,CAAC8B,CAAAA,SAAAA,GAAaA,SAAAA,CAAUC,SAAS,KAAK1B,SAAAA,IAAa,CAACkB,QAAAA,CAASiC,GAAG,CAAC1B,SAAAA,CAAAA,CAAAA,CAAa;AAC9HhB,YAAAA,MAAAA,CAAOI,WAAW,CAACkB,IAAI,CAACC,2BAAAA,CACpBC,0BAAAA,CAAemB,gBAAgB,EAC/B,CAAC,CAAC,EAAEtC,UAAAA,CAAWO,KAAK,CAAC,cAAc,EAAE7B,UAAAA,CAAWH,IAAI,CAAC,MAAM,EAAEG,WAAWJ,SAAS,CAAC,QAAQ,EAAEI,UAAAA,CAAWkC,SAAS,CAAC,0CAA0C,CAAC,EAC5J;AAAEtC,gBAAAA,SAAAA,EAAWI,WAAWJ,SAAS;AAAEC,gBAAAA,IAAAA,EAAMG,WAAWH;AAAK,aAAA,CAAA,CAAA;AACjE,QAAA;AACJ,IAAA;IAEA,OAAOoB,MAAAA;AACX;;;"}
@@ -0,0 +1,400 @@
1
+ 'use strict';
2
+
3
+ var scene_model = require('@cratis/scene.model');
4
+ var elementKind = require('../elementKind.js');
5
+ var flowNodeKind = require('../flowNodeKind.js');
6
+ var panelKind = require('../panelKind.js');
7
+ var diagnostics = require('./diagnostics.js');
8
+ var nodeIds = require('./nodeIds.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
+ /**
13
+ * The layout type a panel element is, by its shape.
14
+ */ function panelLayoutType(element) {
15
+ if (!elementKind.isPanel(element)) return undefined;
16
+ if (panelKind.isGrid(element)) return scene_model.LayoutType.GridPanel;
17
+ if (panelKind.isCanvas(element)) return scene_model.LayoutType.Canvas;
18
+ if (panelKind.isDockPanel(element)) return scene_model.LayoutType.DockPanel;
19
+ if (panelKind.isStackPanel(element)) return scene_model.LayoutType.StackPanel;
20
+ if (panelKind.isWrapPanel(element)) return scene_model.LayoutType.WrapPanel;
21
+ return undefined;
22
+ }
23
+ /**
24
+ * The layout type a flow node is.
25
+ */ function flowLayoutType(node) {
26
+ if (flowNodeKind.isFlowContainer(node)) {
27
+ switch(node.kind){
28
+ case scene_model.FlowContainerKind.Row:
29
+ return scene_model.LayoutType.FlowRow;
30
+ case scene_model.FlowContainerKind.Column:
31
+ return scene_model.LayoutType.FlowColumn;
32
+ default:
33
+ return scene_model.LayoutType.FlowGrid;
34
+ }
35
+ }
36
+ return flowNodeKind.isFlowSlotLeaf(node) ? scene_model.LayoutType.FlowSlotLeaf : scene_model.LayoutType.FlowLeaf;
37
+ }
38
+ class Indexer {
39
+ document;
40
+ index = {
41
+ nodes: new Map(),
42
+ diagnostics: []
43
+ };
44
+ constructor(document){
45
+ this.document = document;
46
+ }
47
+ run() {
48
+ this.document.layouts.forEach((layout, position)=>this.owner(layout, [
49
+ 'layouts',
50
+ position
51
+ ], {
52
+ owner: layout.name,
53
+ ownerKind: scene_model.SceneNodeKind.Layout,
54
+ ownerId: nodeIds.layoutNodeId(layout.name)
55
+ }, undefined));
56
+ this.document.screenTemplates.forEach((template, position)=>this.owner(template, [
57
+ 'screenTemplates',
58
+ position
59
+ ], {
60
+ owner: template.name,
61
+ ownerKind: scene_model.SceneNodeKind.ScreenTemplate,
62
+ ownerId: nodeIds.screenTemplateNodeId(template.name)
63
+ }, 'content'));
64
+ this.document.dialogTemplates.forEach((dialog, position)=>this.owner(dialog, [
65
+ 'dialogTemplates',
66
+ position
67
+ ], {
68
+ owner: dialog.name,
69
+ ownerKind: scene_model.SceneNodeKind.DialogTemplate,
70
+ ownerId: nodeIds.dialogTemplateNodeId(dialog.name)
71
+ }, 'content'));
72
+ this.document.screens.forEach((screen, position)=>this.owner(screen, [
73
+ 'screens',
74
+ position
75
+ ], {
76
+ owner: screen.name,
77
+ ownerKind: scene_model.SceneNodeKind.Screen,
78
+ ownerId: nodeIds.screenNodeId(screen.name)
79
+ }, 'slotContent'));
80
+ return this.index;
81
+ }
82
+ add(record) {
83
+ if (this.index.nodes.has(record.id)) return false;
84
+ this.index.nodes.set(record.id, record);
85
+ return true;
86
+ }
87
+ owner(owner, path, context, contentKey) {
88
+ this.add({
89
+ id: context.ownerId,
90
+ kind: context.ownerKind,
91
+ typeId: context.ownerKind,
92
+ label: owner.name,
93
+ path,
94
+ value: owner,
95
+ owner: context.owner,
96
+ ownerKind: context.ownerKind
97
+ });
98
+ const content = contentKey === undefined ? undefined : owner[contentKey];
99
+ const ownsSlots = 'slots' in owner;
100
+ const declared = ownsSlots ? owner.slots : this.slotsAvailableTo(owner);
101
+ const slotNames = new Set([
102
+ ...declared.map((slot)=>slot.name),
103
+ ...Object.keys(content ?? {})
104
+ ]);
105
+ for (const name of slotNames){
106
+ const slotId = nodeIds.slotNodeId(context.ownerId, name);
107
+ const declaration = ownsSlots ? declared.findIndex((slot)=>slot.name === name) : -1;
108
+ const contentPath = contentKey === undefined ? undefined : [
109
+ ...path,
110
+ contentKey,
111
+ name
112
+ ];
113
+ this.add({
114
+ id: slotId,
115
+ kind: scene_model.SceneNodeKind.Slot,
116
+ typeId: 'slot',
117
+ label: name,
118
+ path: declaration >= 0 ? [
119
+ ...path,
120
+ 'slots',
121
+ declaration
122
+ ] : contentPath,
123
+ value: declaration >= 0 ? declared[declaration] : content?.[name],
124
+ parentId: context.ownerId,
125
+ owner: context.owner,
126
+ ownerKind: context.ownerKind,
127
+ slotName: name,
128
+ contentPath
129
+ });
130
+ if (declaration >= 0 && declared[declaration].arrangement) {
131
+ this.arrangement(declared[declaration].arrangement, [
132
+ ...path,
133
+ 'slots',
134
+ declaration,
135
+ 'arrangement'
136
+ ], slotId, context);
137
+ }
138
+ (content?.[name] ?? []).forEach((element, position)=>this.element(element, [
139
+ ...contentPath,
140
+ position
141
+ ], context, {
142
+ parentId: slotId,
143
+ list: {
144
+ path: contentPath,
145
+ index: position
146
+ }
147
+ }));
148
+ }
149
+ if ('arrangement' in owner && owner.arrangement) {
150
+ this.arrangement(owner.arrangement, [
151
+ ...path,
152
+ 'arrangement'
153
+ ], nodeIds.ownerArrangementId(context.ownerId), context, context.ownerId);
154
+ }
155
+ if ('contributions' in owner) {
156
+ owner.contributions.forEach((contribution, position)=>this.element(contribution.content, [
157
+ ...path,
158
+ 'contributions',
159
+ position,
160
+ 'content'
161
+ ], context, {
162
+ parentId: context.ownerId
163
+ }));
164
+ }
165
+ }
166
+ slotsAvailableTo(screen) {
167
+ const template = screen.screenTemplate === undefined ? undefined : this.document.screenTemplates.find((candidate)=>candidate.name === screen.screenTemplate);
168
+ if (template) return template.slots;
169
+ return this.document.layouts.find((candidate)=>candidate.name === screen.layout)?.slots ?? [];
170
+ }
171
+ element(element, path, context, placement) {
172
+ const id = nodeIds.elementNodeId(element.id);
173
+ const panelType = panelLayoutType(element);
174
+ const typeId = elementKind.isExternalComponent(element) ? element.componentName : panelType ?? (elementKind.isContentControl(element) ? 'contentControl' : elementKind.isItemsControl(element) ? 'itemsControl' : 'element');
175
+ const properties = element.properties;
176
+ const label = typeof properties?.label === 'string' && properties.label || elementKind.isPanel(element) && element.name || elementKind.isExternalComponent(element) && element.name || typeId;
177
+ if (!this.add({
178
+ id,
179
+ kind: scene_model.SceneNodeKind.Element,
180
+ typeId,
181
+ label,
182
+ path,
183
+ value: element,
184
+ owner: context.owner,
185
+ ownerKind: context.ownerKind,
186
+ ...placement
187
+ })) {
188
+ this.index.diagnostics.push(diagnostics.errorDiagnostic(scene_model.DiagnosticCode.DuplicateElementId, `The element id '${element.id}' is used more than once.`, {
189
+ nodeId: id
190
+ }));
191
+ return false;
192
+ }
193
+ if (elementKind.isExternalComponent(element)) {
194
+ for (const [name, children] of Object.entries(element.slots)){
195
+ children.forEach((child, position)=>this.element(child, [
196
+ ...path,
197
+ 'slots',
198
+ name,
199
+ position
200
+ ], context, {
201
+ parentId: id,
202
+ list: {
203
+ path: [
204
+ ...path,
205
+ 'slots',
206
+ name
207
+ ],
208
+ index: position
209
+ },
210
+ mirror: placement.mirror
211
+ }));
212
+ }
213
+ } else if (elementKind.isContentControl(element)) {
214
+ this.element(element.content, [
215
+ ...path,
216
+ 'content'
217
+ ], context, {
218
+ parentId: id,
219
+ mirror: placement.mirror
220
+ });
221
+ } else if (elementKind.isItemsControl(element)) {
222
+ this.element(element.itemTemplate, [
223
+ ...path,
224
+ 'itemTemplate'
225
+ ], context, {
226
+ parentId: id,
227
+ mirror: placement.mirror
228
+ });
229
+ } else if (elementKind.isPanel(element)) {
230
+ element.children.forEach((child, position)=>this.element(child, [
231
+ ...path,
232
+ 'children',
233
+ position
234
+ ], context, {
235
+ parentId: id,
236
+ list: {
237
+ path: [
238
+ ...path,
239
+ 'children'
240
+ ],
241
+ index: position
242
+ },
243
+ mirror: placement.mirror
244
+ }));
245
+ }
246
+ return true;
247
+ }
248
+ arrangement(arrangement, path, holderId, context, parentId = holderId) {
249
+ if (arrangement.root !== undefined) {
250
+ const flow = arrangement;
251
+ this.flowNode(flow.root, [
252
+ ...path,
253
+ 'root'
254
+ ], holderId, 'root', [], context, {
255
+ parentId
256
+ });
257
+ flow.overrides?.forEach((override, position)=>this.flowNode(override.root, [
258
+ ...path,
259
+ 'overrides',
260
+ position,
261
+ 'root'
262
+ ], holderId, `override${position}`, [], context, {
263
+ parentId
264
+ }));
265
+ return;
266
+ }
267
+ const variants = arrangement.variants;
268
+ if (!Array.isArray(variants)) return;
269
+ const freeformId = nodeIds.freeformNodeId(holderId);
270
+ this.add({
271
+ id: freeformId,
272
+ kind: scene_model.SceneNodeKind.Freeform,
273
+ typeId: scene_model.LayoutType.Freeform,
274
+ label: 'Freeform',
275
+ path,
276
+ value: arrangement,
277
+ parentId,
278
+ owner: context.owner,
279
+ ownerKind: context.ownerKind
280
+ });
281
+ const firstCopy = new Map();
282
+ variants.forEach((variant, variantIndex)=>{
283
+ variant.placements.forEach((placement, placementIndex)=>{
284
+ const placementPath = [
285
+ ...path,
286
+ 'variants',
287
+ variantIndex,
288
+ 'placements',
289
+ placementIndex
290
+ ];
291
+ const key = placement.element?.id ?? placement.slotName ?? String(placementIndex);
292
+ const placementId = nodeIds.placementNodeId(holderId, variantIndex, key);
293
+ this.add({
294
+ id: placementId,
295
+ kind: scene_model.SceneNodeKind.Placement,
296
+ typeId: 'placement',
297
+ label: key,
298
+ path: placementPath,
299
+ value: placement,
300
+ parentId: freeformId,
301
+ owner: context.owner,
302
+ ownerKind: context.ownerKind,
303
+ list: {
304
+ path: [
305
+ ...path,
306
+ 'variants',
307
+ variantIndex,
308
+ 'placements'
309
+ ],
310
+ index: placementIndex
311
+ }
312
+ });
313
+ if (!placement.element) return;
314
+ const elementPath = [
315
+ ...placementPath,
316
+ 'element'
317
+ ];
318
+ const known = this.index.nodes.get(nodeIds.elementNodeId(placement.element.id));
319
+ const original = firstCopy.get(placement.element.id);
320
+ if (known && original) {
321
+ known.placementIds.push(placementId);
322
+ known.mirror.others.push(elementPath);
323
+ return;
324
+ }
325
+ firstCopy.set(placement.element.id, elementPath);
326
+ const mirror = {
327
+ prefix: elementPath,
328
+ others: []
329
+ };
330
+ if (this.element(placement.element, elementPath, context, {
331
+ parentId: placementId,
332
+ mirror
333
+ })) {
334
+ this.index.nodes.get(nodeIds.elementNodeId(placement.element.id)).placementIds = [
335
+ placementId
336
+ ];
337
+ }
338
+ });
339
+ });
340
+ // Descendants of a freeform element carry the same mirror object, so a copy found later is seen by all of them.
341
+ }
342
+ flowNode(node, path, holderId, variant, indexPath, context, placement) {
343
+ const id = nodeIds.flowNodeId(holderId, variant, indexPath);
344
+ const type = flowLayoutType(node);
345
+ this.add({
346
+ id,
347
+ kind: scene_model.SceneNodeKind.FlowNode,
348
+ typeId: type,
349
+ label: type,
350
+ path,
351
+ value: node,
352
+ owner: context.owner,
353
+ ownerKind: context.ownerKind,
354
+ ...placement
355
+ });
356
+ if (flowNodeKind.isFlowContainer(node)) {
357
+ node.children.forEach((child, position)=>this.flowNode(child, [
358
+ ...path,
359
+ 'children',
360
+ position
361
+ ], holderId, variant, [
362
+ ...indexPath,
363
+ position
364
+ ], context, {
365
+ parentId: id,
366
+ list: {
367
+ path: [
368
+ ...path,
369
+ 'children'
370
+ ],
371
+ index: position
372
+ }
373
+ }));
374
+ } else if (flowNodeKind.isFlowLeaf(node)) {
375
+ this.element(node.content, [
376
+ ...path,
377
+ 'content'
378
+ ], context, {
379
+ parentId: id,
380
+ leafId: id
381
+ });
382
+ }
383
+ }
384
+ }
385
+ /**
386
+ * Indexes every addressable node of a document: layouts, templates, dialog templates, screens, their slots, the
387
+ * elements in them, and the flow and freeform arrangements that position them.
388
+ *
389
+ * The index is what inspection and editing look nodes up in. Duplicate element ids are reported, and the second
390
+ * occurrence is left out of the index.
391
+ *
392
+ * @param document The document to index.
393
+ */ function indexDocument(document) {
394
+ return new Indexer(document).run();
395
+ }
396
+
397
+ exports.flowLayoutType = flowLayoutType;
398
+ exports.indexDocument = indexDocument;
399
+ exports.panelLayoutType = panelLayoutType;
400
+ //# sourceMappingURL=indexDocument.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"indexDocument.js","sources":["../../../editing/indexDocument.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, DialogTemplate, ExternalComponent, FlowArrangement, FlowContainer, FlowLeaf, FlowNode,\n FreeformArrangement, FreeformSlotArrangement, Layout, LayoutType, SceneDocument, SceneElement, SceneNodeKind, Screen,\n ScreenTemplate, Slot, FlowContainerKind,\n} from '@cratis/scene.model';\nimport { isContentControl, isExternalComponent, isItemsControl, isPanel } from '../elementKind';\nimport { isFlowContainer, isFlowLeaf, isFlowSlotLeaf } from '../flowNodeKind';\nimport { isCanvas, isDockPanel, isGrid, isStackPanel, isWrapPanel } from '../panelKind';\nimport { errorDiagnostic } from './diagnostics';\nimport { DocumentIndex, DocumentPath, ListLocation, NodeRecord } from './DocumentIndex';\nimport {\n dialogTemplateNodeId, elementNodeId, flowNodeId, freeformNodeId, layoutNodeId, ownerArrangementId, placementNodeId,\n screenNodeId, screenTemplateNodeId, slotNodeId,\n} from './nodeIds';\n\ntype Owner = Layout | ScreenTemplate | DialogTemplate | Screen;\n\ninterface OwnerContext {\n owner: string;\n ownerKind: SceneNodeKind;\n ownerId: string;\n}\n\ninterface Placement {\n parentId?: string;\n list?: ListLocation;\n leafId?: string;\n mirror?: NodeRecord['mirror'];\n}\n\n/**\n * The layout type a panel element is, by its shape.\n */\nexport function panelLayoutType(element: SceneElement): LayoutType | undefined {\n if (!isPanel(element)) return undefined;\n if (isGrid(element)) return LayoutType.GridPanel;\n if (isCanvas(element)) return LayoutType.Canvas;\n if (isDockPanel(element)) return LayoutType.DockPanel;\n if (isStackPanel(element)) return LayoutType.StackPanel;\n if (isWrapPanel(element)) return LayoutType.WrapPanel;\n return undefined;\n}\n\n/**\n * The layout type a flow node is.\n */\nexport function flowLayoutType(node: FlowNode): LayoutType {\n if (isFlowContainer(node)) {\n switch (node.kind) {\n case FlowContainerKind.Row: return LayoutType.FlowRow;\n case FlowContainerKind.Column: return LayoutType.FlowColumn;\n default: return LayoutType.FlowGrid;\n }\n }\n\n return isFlowSlotLeaf(node) ? LayoutType.FlowSlotLeaf : LayoutType.FlowLeaf;\n}\n\nclass Indexer {\n readonly index: DocumentIndex = { nodes: new Map(), diagnostics: [] };\n\n constructor(private readonly document: SceneDocument) {}\n\n run(): DocumentIndex {\n this.document.layouts.forEach((layout, position) =>\n this.owner(layout, ['layouts', position], { owner: layout.name, ownerKind: SceneNodeKind.Layout, ownerId: layoutNodeId(layout.name) }, undefined));\n this.document.screenTemplates.forEach((template, position) =>\n this.owner(template, ['screenTemplates', position], { owner: template.name, ownerKind: SceneNodeKind.ScreenTemplate, ownerId: screenTemplateNodeId(template.name) }, 'content'));\n this.document.dialogTemplates.forEach((dialog, position) =>\n this.owner(dialog, ['dialogTemplates', position], { owner: dialog.name, ownerKind: SceneNodeKind.DialogTemplate, ownerId: dialogTemplateNodeId(dialog.name) }, 'content'));\n this.document.screens.forEach((screen, position) =>\n this.owner(screen, ['screens', position], { owner: screen.name, ownerKind: SceneNodeKind.Screen, ownerId: screenNodeId(screen.name) }, 'slotContent'));\n return this.index;\n }\n\n private add(record: NodeRecord): boolean {\n if (this.index.nodes.has(record.id)) return false;\n this.index.nodes.set(record.id, record);\n return true;\n }\n\n private owner(owner: Owner, path: DocumentPath, context: OwnerContext, contentKey: 'content' | 'slotContent' | undefined): void {\n this.add({ id: context.ownerId, kind: context.ownerKind, typeId: context.ownerKind, label: owner.name, path, value: owner, owner: context.owner, ownerKind: context.ownerKind });\n\n const content = contentKey === undefined ? undefined : (owner as unknown as Record<string, Record<string, SceneElement[]> | undefined>)[contentKey];\n const ownsSlots = 'slots' in owner;\n const declared: Slot[] = ownsSlots ? owner.slots : this.slotsAvailableTo(owner as Screen);\n const slotNames = new Set<string>([...declared.map(slot => slot.name), ...Object.keys(content ?? {})]);\n\n for (const name of slotNames) {\n const slotId = slotNodeId(context.ownerId, name);\n const declaration = ownsSlots ? declared.findIndex(slot => slot.name === name) : -1;\n const contentPath: DocumentPath | undefined = contentKey === undefined ? undefined : [...path, contentKey, name];\n this.add({\n id: slotId, kind: SceneNodeKind.Slot, typeId: 'slot', label: name, path: declaration >= 0 ? [...path, 'slots', declaration] : contentPath!,\n value: declaration >= 0 ? declared[declaration] : content?.[name], parentId: context.ownerId, owner: context.owner,\n ownerKind: context.ownerKind, slotName: name, contentPath,\n });\n\n if (declaration >= 0 && declared[declaration].arrangement) {\n this.arrangement(declared[declaration].arrangement!, [...path, 'slots', declaration, 'arrangement'], slotId, context);\n }\n\n (content?.[name] ?? []).forEach((element, position) =>\n this.element(element, [...contentPath!, position], context, { parentId: slotId, list: { path: contentPath!, index: position } }));\n }\n\n if ('arrangement' in owner && owner.arrangement) {\n this.arrangement(owner.arrangement, [...path, 'arrangement'], ownerArrangementId(context.ownerId), context, context.ownerId);\n }\n\n if ('contributions' in owner) {\n owner.contributions.forEach((contribution, position) =>\n this.element(contribution.content, [...path, 'contributions', position, 'content'], context, { parentId: context.ownerId }));\n }\n }\n\n private slotsAvailableTo(screen: Screen): Slot[] {\n const template = screen.screenTemplate === undefined ? undefined : this.document.screenTemplates.find(candidate => candidate.name === screen.screenTemplate);\n if (template) return template.slots;\n return this.document.layouts.find(candidate => candidate.name === screen.layout)?.slots ?? [];\n }\n\n private element(element: SceneElement, path: DocumentPath, context: OwnerContext, placement: Placement): boolean {\n const id = elementNodeId(element.id);\n const panelType = panelLayoutType(element);\n const typeId = isExternalComponent(element) ? element.componentName\n : (panelType ?? (isContentControl(element) ? 'contentControl' : (isItemsControl(element) ? 'itemsControl' : 'element')));\n const properties = (element as ExternalComponent).properties;\n const label = (typeof properties?.label === 'string' && properties.label)\n || (isPanel(element) && (element as { name?: string }).name)\n || (isExternalComponent(element) && element.name)\n || typeId;\n\n if (!this.add({\n id, kind: SceneNodeKind.Element, typeId, label, path, value: element, owner: context.owner, ownerKind: context.ownerKind, ...placement,\n })) {\n this.index.diagnostics.push(errorDiagnostic(DiagnosticCode.DuplicateElementId, `The element id '${element.id}' is used more than once.`, { nodeId: id }));\n return false;\n }\n\n if (isExternalComponent(element)) {\n for (const [name, children] of Object.entries(element.slots)) {\n children.forEach((child, position) =>\n this.element(child, [...path, 'slots', name, position], context, { parentId: id, list: { path: [...path, 'slots', name], index: position }, mirror: placement.mirror }));\n }\n } else if (isContentControl(element)) {\n this.element(element.content, [...path, 'content'], context, { parentId: id, mirror: placement.mirror });\n } else if (isItemsControl(element)) {\n this.element(element.itemTemplate, [...path, 'itemTemplate'], context, { parentId: id, mirror: placement.mirror });\n } else if (isPanel(element)) {\n element.children.forEach((child, position) =>\n this.element(child, [...path, 'children', position], context, { parentId: id, list: { path: [...path, 'children'], index: position }, mirror: placement.mirror }));\n }\n\n return true;\n }\n\n private arrangement(arrangement: unknown, path: DocumentPath, holderId: string, context: OwnerContext, parentId = holderId): void {\n if ((arrangement as FlowArrangement).root !== undefined) {\n const flow = arrangement as FlowArrangement;\n this.flowNode(flow.root, [...path, 'root'], holderId, 'root', [], context, { parentId });\n flow.overrides?.forEach((override, position) =>\n this.flowNode(override.root, [...path, 'overrides', position, 'root'], holderId, `override${position}`, [], context, { parentId }));\n return;\n }\n\n const variants = (arrangement as FreeformArrangement | FreeformSlotArrangement).variants;\n if (!Array.isArray(variants)) return;\n\n const freeformId = freeformNodeId(holderId);\n this.add({ id: freeformId, kind: SceneNodeKind.Freeform, typeId: LayoutType.Freeform, label: 'Freeform', path, value: arrangement, parentId, owner: context.owner, ownerKind: context.ownerKind });\n\n const firstCopy = new Map<string, DocumentPath>();\n variants.forEach((variant, variantIndex) => {\n (variant.placements as { element?: SceneElement; slotName?: string }[]).forEach((placement, placementIndex) => {\n const placementPath = [...path, 'variants', variantIndex, 'placements', placementIndex];\n const key = placement.element?.id ?? placement.slotName ?? String(placementIndex);\n const placementId = placementNodeId(holderId, variantIndex, key);\n this.add({\n id: placementId, kind: SceneNodeKind.Placement, typeId: 'placement', label: key, path: placementPath, value: placement,\n parentId: freeformId, owner: context.owner, ownerKind: context.ownerKind,\n list: { path: [...path, 'variants', variantIndex, 'placements'], index: placementIndex },\n });\n\n if (!placement.element) return;\n const elementPath = [...placementPath, 'element'];\n const known = this.index.nodes.get(elementNodeId(placement.element.id));\n const original = firstCopy.get(placement.element.id);\n if (known && original) {\n known.placementIds!.push(placementId);\n known.mirror!.others.push(elementPath);\n return;\n }\n\n firstCopy.set(placement.element.id, elementPath);\n const mirror = { prefix: elementPath, others: [] as DocumentPath[] };\n if (this.element(placement.element, elementPath, context, { parentId: placementId, mirror })) {\n this.index.nodes.get(elementNodeId(placement.element.id))!.placementIds = [placementId];\n }\n });\n });\n\n // Descendants of a freeform element carry the same mirror object, so a copy found later is seen by all of them.\n }\n\n private flowNode(node: FlowNode, path: DocumentPath, holderId: string, variant: string, indexPath: number[], context: OwnerContext, placement: Placement): void {\n const id = flowNodeId(holderId, variant, indexPath);\n const type = flowLayoutType(node);\n this.add({ id, kind: SceneNodeKind.FlowNode, typeId: type, label: type, path, value: node, owner: context.owner, ownerKind: context.ownerKind, ...placement });\n\n if (isFlowContainer(node)) {\n (node as FlowContainer).children.forEach((child, position) =>\n this.flowNode(child, [...path, 'children', position], holderId, variant, [...indexPath, position], context,\n { parentId: id, list: { path: [...path, 'children'], index: position } }));\n } else if (isFlowLeaf(node)) {\n this.element((node as FlowLeaf).content, [...path, 'content'], context, { parentId: id, leafId: id });\n }\n\n }\n}\n\n/**\n * Indexes every addressable node of a document: layouts, templates, dialog templates, screens, their slots, the\n * elements in them, and the flow and freeform arrangements that position them.\n *\n * The index is what inspection and editing look nodes up in. Duplicate element ids are reported, and the second\n * occurrence is left out of the index.\n *\n * @param document The document to index.\n */\nexport function indexDocument(document: SceneDocument): DocumentIndex {\n return new Indexer(document).run();\n}\n"],"names":["panelLayoutType","element","isPanel","undefined","isGrid","LayoutType","GridPanel","isCanvas","Canvas","isDockPanel","DockPanel","isStackPanel","StackPanel","isWrapPanel","WrapPanel","flowLayoutType","node","isFlowContainer","kind","FlowContainerKind","Row","FlowRow","Column","FlowColumn","FlowGrid","isFlowSlotLeaf","FlowSlotLeaf","FlowLeaf","Indexer","index","nodes","Map","diagnostics","document","run","layouts","forEach","layout","position","owner","name","ownerKind","SceneNodeKind","Layout","ownerId","layoutNodeId","screenTemplates","template","ScreenTemplate","screenTemplateNodeId","dialogTemplates","dialog","DialogTemplate","dialogTemplateNodeId","screens","screen","Screen","screenNodeId","add","record","has","id","set","path","context","contentKey","typeId","label","value","content","ownsSlots","declared","slots","slotsAvailableTo","slotNames","Set","map","slot","Object","keys","slotId","slotNodeId","declaration","findIndex","contentPath","Slot","parentId","slotName","arrangement","list","ownerArrangementId","contributions","contribution","screenTemplate","find","candidate","placement","elementNodeId","panelType","isExternalComponent","componentName","isContentControl","isItemsControl","properties","Element","push","errorDiagnostic","DiagnosticCode","DuplicateElementId","nodeId","children","entries","child","mirror","itemTemplate","holderId","root","flow","flowNode","overrides","override","variants","Array","isArray","freeformId","freeformNodeId","Freeform","firstCopy","variant","variantIndex","placements","placementIndex","placementPath","key","String","placementId","placementNodeId","Placement","elementPath","known","get","original","placementIds","others","prefix","indexPath","flowNodeId","type","FlowNode","isFlowLeaf","leafId","indexDocument"],"mappings":"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"}