@cratis/scene.engine 4.2.0 → 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 (310) 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 +5 -4
  206. package/dist/esm/for_aggregateContributions/when_aggregating_by_contribution_point.d.ts +0 -2
  207. package/dist/esm/for_aggregateContributions/when_aggregating_by_contribution_point.d.ts.map +0 -1
  208. package/dist/esm/for_aggregateContributions/when_aggregating_by_contribution_point.js +0 -23
  209. package/dist/esm/for_aggregateContributions/when_aggregating_by_contribution_point.js.map +0 -1
  210. package/dist/esm/for_buildStarterProfile/when_checking_against_the_shared_fixture_corpus.d.ts +0 -2
  211. package/dist/esm/for_buildStarterProfile/when_checking_against_the_shared_fixture_corpus.d.ts.map +0 -1
  212. package/dist/esm/for_buildStarterProfile/when_checking_against_the_shared_fixture_corpus.js +0 -16
  213. package/dist/esm/for_buildStarterProfile/when_checking_against_the_shared_fixture_corpus.js.map +0 -1
  214. package/dist/esm/for_computeSizeClass/when_computing_the_size_class.d.ts +0 -2
  215. package/dist/esm/for_computeSizeClass/when_computing_the_size_class.d.ts.map +0 -1
  216. package/dist/esm/for_computeSizeClass/when_computing_the_size_class.js +0 -17
  217. package/dist/esm/for_computeSizeClass/when_computing_the_size_class.js.map +0 -1
  218. package/dist/esm/for_evaluateFlowArrangement/when_evaluating_against_the_shared_fixture_corpus.d.ts +0 -2
  219. package/dist/esm/for_evaluateFlowArrangement/when_evaluating_against_the_shared_fixture_corpus.d.ts.map +0 -1
  220. package/dist/esm/for_evaluateFlowArrangement/when_evaluating_against_the_shared_fixture_corpus.js +0 -43
  221. package/dist/esm/for_evaluateFlowArrangement/when_evaluating_against_the_shared_fixture_corpus.js.map +0 -1
  222. package/dist/esm/for_evaluateFreeformArrangement/when_evaluating_against_the_shared_fixture_corpus.d.ts +0 -2
  223. package/dist/esm/for_evaluateFreeformArrangement/when_evaluating_against_the_shared_fixture_corpus.d.ts.map +0 -1
  224. package/dist/esm/for_evaluateFreeformArrangement/when_evaluating_against_the_shared_fixture_corpus.js +0 -46
  225. package/dist/esm/for_evaluateFreeformArrangement/when_evaluating_against_the_shared_fixture_corpus.js.map +0 -1
  226. package/dist/esm/for_evaluateFreeformSlotArrangement/when_evaluating_against_the_shared_fixture_corpus.d.ts +0 -2
  227. package/dist/esm/for_evaluateFreeformSlotArrangement/when_evaluating_against_the_shared_fixture_corpus.d.ts.map +0 -1
  228. package/dist/esm/for_evaluateFreeformSlotArrangement/when_evaluating_against_the_shared_fixture_corpus.js +0 -25
  229. package/dist/esm/for_evaluateFreeformSlotArrangement/when_evaluating_against_the_shared_fixture_corpus.js.map +0 -1
  230. package/dist/esm/for_incompatibleStarterThemes/when_checking_against_the_shared_fixture_corpus.d.ts +0 -2
  231. package/dist/esm/for_incompatibleStarterThemes/when_checking_against_the_shared_fixture_corpus.d.ts.map +0 -1
  232. package/dist/esm/for_incompatibleStarterThemes/when_checking_against_the_shared_fixture_corpus.js +0 -17
  233. package/dist/esm/for_incompatibleStarterThemes/when_checking_against_the_shared_fixture_corpus.js.map +0 -1
  234. package/dist/esm/for_packageCatalog/when_querying_against_the_shared_fixture_corpus.d.ts +0 -2
  235. package/dist/esm/for_packageCatalog/when_querying_against_the_shared_fixture_corpus.d.ts.map +0 -1
  236. package/dist/esm/for_packageCatalog/when_querying_against_the_shared_fixture_corpus.js +0 -22
  237. package/dist/esm/for_packageCatalog/when_querying_against_the_shared_fixture_corpus.js.map +0 -1
  238. package/dist/esm/for_packageDependencies/fixtures.d.ts +0 -38
  239. package/dist/esm/for_packageDependencies/fixtures.d.ts.map +0 -1
  240. package/dist/esm/for_packageDependencies/fixtures.js +0 -5
  241. package/dist/esm/for_packageDependencies/fixtures.js.map +0 -1
  242. package/dist/esm/for_packageDependencies/when_resolving_against_the_shared_fixture_corpus.d.ts +0 -2
  243. package/dist/esm/for_packageDependencies/when_resolving_against_the_shared_fixture_corpus.d.ts.map +0 -1
  244. package/dist/esm/for_packageDependencies/when_resolving_against_the_shared_fixture_corpus.js +0 -29
  245. package/dist/esm/for_packageDependencies/when_resolving_against_the_shared_fixture_corpus.js.map +0 -1
  246. package/dist/esm/for_packageVersionRange/when_checking_against_the_shared_fixture_corpus.d.ts +0 -2
  247. package/dist/esm/for_packageVersionRange/when_checking_against_the_shared_fixture_corpus.d.ts.map +0 -1
  248. package/dist/esm/for_packageVersionRange/when_checking_against_the_shared_fixture_corpus.js +0 -10
  249. package/dist/esm/for_packageVersionRange/when_checking_against_the_shared_fixture_corpus.js.map +0 -1
  250. package/dist/esm/for_panelKind/when_telling_the_panels_apart.d.ts +0 -2
  251. package/dist/esm/for_panelKind/when_telling_the_panels_apart.d.ts.map +0 -1
  252. package/dist/esm/for_panelKind/when_telling_the_panels_apart.js +0 -38
  253. package/dist/esm/for_panelKind/when_telling_the_panels_apart.js.map +0 -1
  254. package/dist/esm/for_renderElement/when_rendering_a_mixed_tree.d.ts +0 -2
  255. package/dist/esm/for_renderElement/when_rendering_a_mixed_tree.d.ts.map +0 -1
  256. package/dist/esm/for_renderElement/when_rendering_a_mixed_tree.js +0 -46
  257. package/dist/esm/for_renderElement/when_rendering_a_mixed_tree.js.map +0 -1
  258. package/dist/esm/for_resolveBehaviors/when_resolving_additive_attachments.d.ts +0 -2
  259. package/dist/esm/for_resolveBehaviors/when_resolving_additive_attachments.d.ts.map +0 -1
  260. package/dist/esm/for_resolveBehaviors/when_resolving_additive_attachments.js +0 -68
  261. package/dist/esm/for_resolveBehaviors/when_resolving_additive_attachments.js.map +0 -1
  262. package/dist/esm/for_resolveComponentName/when_resolving_against_the_shared_fixture_corpus.d.ts +0 -2
  263. package/dist/esm/for_resolveComponentName/when_resolving_against_the_shared_fixture_corpus.d.ts.map +0 -1
  264. package/dist/esm/for_resolveComponentName/when_resolving_against_the_shared_fixture_corpus.js +0 -20
  265. package/dist/esm/for_resolveComponentName/when_resolving_against_the_shared_fixture_corpus.js.map +0 -1
  266. package/dist/esm/for_resolveScreenTemplates/when_resolving_against_the_shared_fixture_corpus.d.ts +0 -2
  267. package/dist/esm/for_resolveScreenTemplates/when_resolving_against_the_shared_fixture_corpus.d.ts.map +0 -1
  268. package/dist/esm/for_resolveScreenTemplates/when_resolving_against_the_shared_fixture_corpus.js +0 -30
  269. package/dist/esm/for_resolveScreenTemplates/when_resolving_against_the_shared_fixture_corpus.js.map +0 -1
  270. package/dist/esm/for_resolveStrings/when_resolving_a_strings_reference.d.ts +0 -2
  271. package/dist/esm/for_resolveStrings/when_resolving_a_strings_reference.d.ts.map +0 -1
  272. package/dist/esm/for_resolveStrings/when_resolving_a_strings_reference.js +0 -69
  273. package/dist/esm/for_resolveStrings/when_resolving_a_strings_reference.js.map +0 -1
  274. package/dist/esm/for_runActions/given/a_recording_dispatcher.d.ts +0 -21
  275. package/dist/esm/for_runActions/given/a_recording_dispatcher.d.ts.map +0 -1
  276. package/dist/esm/for_runActions/given/a_recording_dispatcher.js +0 -45
  277. package/dist/esm/for_runActions/given/a_recording_dispatcher.js.map +0 -1
  278. package/dist/esm/for_runActions/when_running_a_sequence_of_actions.d.ts +0 -2
  279. package/dist/esm/for_runActions/when_running_a_sequence_of_actions.d.ts.map +0 -1
  280. package/dist/esm/for_runActions/when_running_a_sequence_of_actions.js +0 -126
  281. package/dist/esm/for_runActions/when_running_a_sequence_of_actions.js.map +0 -1
  282. package/dist/esm/for_runActions/when_running_against_the_shared_fixture_corpus.d.ts +0 -2
  283. package/dist/esm/for_runActions/when_running_against_the_shared_fixture_corpus.d.ts.map +0 -1
  284. package/dist/esm/for_runActions/when_running_against_the_shared_fixture_corpus.js +0 -61
  285. package/dist/esm/for_runActions/when_running_against_the_shared_fixture_corpus.js.map +0 -1
  286. package/dist/esm/for_themeCompatibility/when_checking_against_the_shared_fixture_corpus.d.ts +0 -2
  287. package/dist/esm/for_themeCompatibility/when_checking_against_the_shared_fixture_corpus.d.ts.map +0 -1
  288. package/dist/esm/for_themeCompatibility/when_checking_against_the_shared_fixture_corpus.js +0 -18
  289. package/dist/esm/for_themeCompatibility/when_checking_against_the_shared_fixture_corpus.js.map +0 -1
  290. package/for_aggregateContributions/when_aggregating_by_contribution_point.ts +0 -31
  291. package/for_buildStarterProfile/when_checking_against_the_shared_fixture_corpus.ts +0 -32
  292. package/for_computeSizeClass/when_computing_the_size_class.ts +0 -23
  293. package/for_evaluateFlowArrangement/when_evaluating_against_the_shared_fixture_corpus.ts +0 -67
  294. package/for_evaluateFreeformArrangement/when_evaluating_against_the_shared_fixture_corpus.ts +0 -68
  295. package/for_evaluateFreeformSlotArrangement/when_evaluating_against_the_shared_fixture_corpus.ts +0 -47
  296. package/for_incompatibleStarterThemes/when_checking_against_the_shared_fixture_corpus.ts +0 -34
  297. package/for_packageCatalog/when_querying_against_the_shared_fixture_corpus.ts +0 -26
  298. package/for_packageDependencies/fixtures.ts +0 -44
  299. package/for_packageDependencies/when_resolving_against_the_shared_fixture_corpus.ts +0 -39
  300. package/for_packageVersionRange/when_checking_against_the_shared_fixture_corpus.ts +0 -13
  301. package/for_panelKind/when_telling_the_panels_apart.ts +0 -47
  302. package/for_renderElement/when_rendering_a_mixed_tree.ts +0 -58
  303. package/for_resolveBehaviors/when_resolving_additive_attachments.ts +0 -100
  304. package/for_resolveComponentName/when_resolving_against_the_shared_fixture_corpus.ts +0 -36
  305. package/for_resolveScreenTemplates/when_resolving_against_the_shared_fixture_corpus.ts +0 -49
  306. package/for_resolveStrings/when_resolving_a_strings_reference.ts +0 -85
  307. package/for_runActions/given/a_recording_dispatcher.ts +0 -72
  308. package/for_runActions/when_running_a_sequence_of_actions.ts +0 -226
  309. package/for_runActions/when_running_against_the_shared_fixture_corpus.ts +0 -124
  310. package/for_themeCompatibility/when_checking_against_the_shared_fixture_corpus.ts +0 -37
@@ -0,0 +1,60 @@
1
+ import { isExternalComponent, isContentControl, isItemsControl, isPanel } from '../elementKind.js';
2
+
3
+ // Copyright (c) Cratis. All rights reserved.
4
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
5
+ /**
6
+ * Returns the element tree a renderer should draw once effective configuration is applied: each configurable
7
+ * component carries its resolved properties.
8
+ *
9
+ * Pure, and structure-sharing - an element with nothing to change comes back as the same object, so a renderer
10
+ * that memoizes on identity does not redraw what did not change. There is no design-time flag here or anywhere
11
+ * downstream: a screen being edited and a screen being played go through this same function.
12
+ *
13
+ * @param element The element tree from the template or screen.
14
+ * @param configuration What {@link resolveEffectiveConfiguration} produced for the chain the tree sits in.
15
+ */ function applyEffectiveConfiguration(element, configuration) {
16
+ if (isExternalComponent(element)) {
17
+ const resolved = configuration.components.find((candidate)=>candidate.component === element.id);
18
+ let changed = resolved !== undefined;
19
+ const slots = {};
20
+ for (const [name, children] of Object.entries(element.slots)){
21
+ const mapped = children.map((child)=>applyEffectiveConfiguration(child, configuration));
22
+ if (mapped.some((child, index)=>child !== children[index])) changed = true;
23
+ slots[name] = mapped;
24
+ }
25
+ const updated = {
26
+ ...element,
27
+ properties: resolved?.properties ?? element.properties,
28
+ slots
29
+ };
30
+ return changed ? updated : element;
31
+ }
32
+ if (isContentControl(element)) {
33
+ const content = applyEffectiveConfiguration(element.content, configuration);
34
+ const updated = {
35
+ ...element,
36
+ content
37
+ };
38
+ return content === element.content ? element : updated;
39
+ }
40
+ if (isItemsControl(element)) {
41
+ const itemTemplate = applyEffectiveConfiguration(element.itemTemplate, configuration);
42
+ const updated = {
43
+ ...element,
44
+ itemTemplate
45
+ };
46
+ return itemTemplate === element.itemTemplate ? element : updated;
47
+ }
48
+ if (isPanel(element)) {
49
+ const children = element.children.map((child)=>applyEffectiveConfiguration(child, configuration));
50
+ const updated = {
51
+ ...element,
52
+ children
53
+ };
54
+ return children.some((child, index)=>child !== element.children[index]) ? updated : element;
55
+ }
56
+ return element;
57
+ }
58
+
59
+ export { applyEffectiveConfiguration };
60
+ //# sourceMappingURL=applyEffectiveConfiguration.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"applyEffectiveConfiguration.js","sources":["../../../editing/applyEffectiveConfiguration.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 { ContentControl, EffectiveConfiguration, ExternalComponent, ItemsControl, Panel, SceneElement } from '@cratis/scene.model';\nimport { isContentControl, isExternalComponent, isItemsControl, isPanel } from '../elementKind';\n\n/**\n * Returns the element tree a renderer should draw once effective configuration is applied: each configurable\n * component carries its resolved properties.\n *\n * Pure, and structure-sharing - an element with nothing to change comes back as the same object, so a renderer\n * that memoizes on identity does not redraw what did not change. There is no design-time flag here or anywhere\n * downstream: a screen being edited and a screen being played go through this same function.\n *\n * @param element The element tree from the template or screen.\n * @param configuration What {@link resolveEffectiveConfiguration} produced for the chain the tree sits in.\n */\nexport function applyEffectiveConfiguration(element: SceneElement, configuration: EffectiveConfiguration): SceneElement {\n if (isExternalComponent(element)) {\n const resolved = configuration.components.find(candidate => candidate.component === element.id);\n let changed = resolved !== undefined;\n\n const slots: typeof element.slots = {};\n for (const [name, children] of Object.entries(element.slots)) {\n const mapped = children.map(child => applyEffectiveConfiguration(child, configuration));\n if (mapped.some((child, index) => child !== children[index])) changed = true;\n slots[name] = mapped;\n }\n\n const updated: ExternalComponent = { ...element, properties: resolved?.properties ?? element.properties, slots };\n return changed ? updated : element;\n }\n\n if (isContentControl(element)) {\n const content = applyEffectiveConfiguration(element.content, configuration);\n const updated: ContentControl = { ...element, content };\n return content === element.content ? element : updated;\n }\n\n if (isItemsControl(element)) {\n const itemTemplate = applyEffectiveConfiguration(element.itemTemplate, configuration);\n const updated: ItemsControl = { ...element, itemTemplate };\n return itemTemplate === element.itemTemplate ? element : updated;\n }\n\n if (isPanel(element)) {\n const children = element.children.map(child => applyEffectiveConfiguration(child, configuration));\n const updated: Panel = { ...element, children };\n return children.some((child, index) => child !== element.children[index]) ? updated : element;\n }\n\n return element;\n}\n"],"names":["applyEffectiveConfiguration","element","configuration","isExternalComponent","resolved","components","find","candidate","component","id","changed","undefined","slots","name","children","Object","entries","mapped","map","child","some","index","updated","properties","isContentControl","content","isItemsControl","itemTemplate","isPanel"],"mappings":";;AAAA;AACA;AAKA;;;;;;;;;;AAUC,IACM,SAASA,2BAAAA,CAA4BC,OAAqB,EAAEC,aAAqC,EAAA;AACpG,IAAA,IAAIC,oBAAoBF,OAAAA,CAAAA,EAAU;AAC9B,QAAA,MAAMG,QAAAA,GAAWF,aAAAA,CAAcG,UAAU,CAACC,IAAI,CAACC,CAAAA,SAAAA,GAAaA,SAAAA,CAAUC,SAAS,KAAKP,OAAAA,CAAQQ,EAAE,CAAA;AAC9F,QAAA,IAAIC,UAAUN,QAAAA,KAAaO,SAAAA;AAE3B,QAAA,MAAMC,QAA8B,EAAC;QACrC,KAAK,MAAM,CAACC,IAAAA,EAAMC,QAAAA,CAAS,IAAIC,OAAOC,OAAO,CAACf,OAAAA,CAAQW,KAAK,CAAA,CAAG;AAC1D,YAAA,MAAMK,SAASH,QAAAA,CAASI,GAAG,CAACC,CAAAA,KAAAA,GAASnB,4BAA4BmB,KAAAA,EAAOjB,aAAAA,CAAAA,CAAAA;YACxE,IAAIe,MAAAA,CAAOG,IAAI,CAAC,CAACD,KAAAA,EAAOE,KAAAA,GAAUF,KAAAA,KAAUL,QAAQ,CAACO,KAAAA,CAAM,CAAA,EAAGX,OAAAA,GAAU,IAAA;YACxEE,KAAK,CAACC,KAAK,GAAGI,MAAAA;AAClB,QAAA;AAEA,QAAA,MAAMK,OAAAA,GAA6B;AAAE,YAAA,GAAGrB,OAAO;YAAEsB,UAAAA,EAAYnB,QAAAA,EAAUmB,UAAAA,IAActB,OAAAA,CAAQsB,UAAU;AAAEX,YAAAA;AAAM,SAAA;AAC/G,QAAA,OAAOF,UAAUY,OAAAA,GAAUrB,OAAAA;AAC/B,IAAA;AAEA,IAAA,IAAIuB,iBAAiBvB,OAAAA,CAAAA,EAAU;AAC3B,QAAA,MAAMwB,OAAAA,GAAUzB,2BAAAA,CAA4BC,OAAAA,CAAQwB,OAAO,EAAEvB,aAAAA,CAAAA;AAC7D,QAAA,MAAMoB,OAAAA,GAA0B;AAAE,YAAA,GAAGrB,OAAO;AAAEwB,YAAAA;AAAQ,SAAA;AACtD,QAAA,OAAOA,OAAAA,KAAYxB,OAAAA,CAAQwB,OAAO,GAAGxB,OAAAA,GAAUqB,OAAAA;AACnD,IAAA;AAEA,IAAA,IAAII,eAAezB,OAAAA,CAAAA,EAAU;AACzB,QAAA,MAAM0B,YAAAA,GAAe3B,2BAAAA,CAA4BC,OAAAA,CAAQ0B,YAAY,EAAEzB,aAAAA,CAAAA;AACvE,QAAA,MAAMoB,OAAAA,GAAwB;AAAE,YAAA,GAAGrB,OAAO;AAAE0B,YAAAA;AAAa,SAAA;AACzD,QAAA,OAAOA,YAAAA,KAAiB1B,OAAAA,CAAQ0B,YAAY,GAAG1B,OAAAA,GAAUqB,OAAAA;AAC7D,IAAA;AAEA,IAAA,IAAIM,QAAQ3B,OAAAA,CAAAA,EAAU;QAClB,MAAMa,QAAAA,GAAWb,QAAQa,QAAQ,CAACI,GAAG,CAACC,CAAAA,KAAAA,GAASnB,2BAAAA,CAA4BmB,KAAAA,EAAOjB,aAAAA,CAAAA,CAAAA;AAClF,QAAA,MAAMoB,OAAAA,GAAiB;AAAE,YAAA,GAAGrB,OAAO;AAAEa,YAAAA;AAAS,SAAA;AAC9C,QAAA,OAAOA,QAAAA,CAASM,IAAI,CAAC,CAACD,KAAAA,EAAOE,KAAAA,GAAUF,KAAAA,KAAUlB,OAAAA,CAAQa,QAAQ,CAACO,KAAAA,CAAM,CAAA,GAAIC,OAAAA,GAAUrB,OAAAA;AAC1F,IAAA;IAEA,OAAOA,OAAAA;AACX;;"}
@@ -0,0 +1,3 @@
1
+ import { ExternalComponent } from '@cratis/scene.model';
2
+ export declare function collectComponents(owner: unknown): ExternalComponent[];
3
+ //# sourceMappingURL=collectComponents.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"collectComponents.d.ts","sourceRoot":"","sources":["../../../editing/collectComponents.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAgBxD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,iBAAiB,EAAE,CAgBrE"}
@@ -0,0 +1,32 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+ function isExternalComponentValue(value) {
4
+ const candidate = value;
5
+ return typeof candidate.id === 'string' && typeof candidate.componentName === 'string' && candidate.properties !== null && typeof candidate.properties === 'object';
6
+ }
7
+ /**
8
+ * Finds every external component anywhere inside a layout, template, dialog template or screen, each once by id.
9
+ *
10
+ * It scans the value's structure rather than following a fixed list of properties, so a component is found
11
+ * wherever the model keeps it - slot content, a flow leaf, a freeform placement, a panel's children, another
12
+ * component's slot. A freeform arrangement repeats an element across its size-class variants; the first copy
13
+ * is the one returned.
14
+ */ function collectComponents(owner) {
15
+ const found = new Map();
16
+ const visit = (value)=>{
17
+ if (value === null || typeof value !== 'object') return;
18
+ if (Array.isArray(value)) {
19
+ for (const item of value)visit(item);
20
+ return;
21
+ }
22
+ if (isExternalComponentValue(value) && !found.has(value.id)) found.set(value.id, value);
23
+ for (const child of Object.values(value))visit(child);
24
+ };
25
+ visit(owner);
26
+ return [
27
+ ...found.values()
28
+ ];
29
+ }
30
+
31
+ export { collectComponents };
32
+ //# sourceMappingURL=collectComponents.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"collectComponents.js","sources":["../../../editing/collectComponents.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 { ExternalComponent } from '@cratis/scene.model';\n\nfunction isExternalComponentValue(value: object): value is ExternalComponent {\n const candidate = value as Partial<ExternalComponent>;\n return typeof candidate.id === 'string' && typeof candidate.componentName === 'string'\n && candidate.properties !== null && typeof candidate.properties === 'object';\n}\n\n/**\n * Finds every external component anywhere inside a layout, template, dialog template or screen, each once by id.\n *\n * It scans the value's structure rather than following a fixed list of properties, so a component is found\n * wherever the model keeps it - slot content, a flow leaf, a freeform placement, a panel's children, another\n * component's slot. A freeform arrangement repeats an element across its size-class variants; the first copy\n * is the one returned.\n */\nexport function collectComponents(owner: unknown): ExternalComponent[] {\n const found = new Map<string, ExternalComponent>();\n\n const visit = (value: unknown): void => {\n if (value === null || typeof value !== 'object') return;\n if (Array.isArray(value)) {\n for (const item of value) visit(item);\n return;\n }\n\n if (isExternalComponentValue(value) && !found.has(value.id)) found.set(value.id, value);\n for (const child of Object.values(value)) visit(child);\n };\n\n visit(owner);\n return [...found.values()];\n}\n"],"names":["isExternalComponentValue","value","candidate","id","componentName","properties","collectComponents","owner","found","Map","visit","Array","isArray","item","has","set","child","Object","values"],"mappings":"AAAA;AACA;AAIA,SAASA,yBAAyBC,KAAa,EAAA;AAC3C,IAAA,MAAMC,SAAAA,GAAYD,KAAAA;AAClB,IAAA,OAAO,OAAOC,SAAAA,CAAUC,EAAE,KAAK,QAAA,IAAY,OAAOD,SAAAA,CAAUE,aAAa,KAAK,QAAA,IACvEF,UAAUG,UAAU,KAAK,QAAQ,OAAOH,SAAAA,CAAUG,UAAU,KAAK,QAAA;AAC5E;AAEA;;;;;;;IAQO,SAASC,iBAAAA,CAAkBC,KAAc,EAAA;AAC5C,IAAA,MAAMC,QAAQ,IAAIC,GAAAA,EAAAA;AAElB,IAAA,MAAMC,QAAQ,CAACT,KAAAA,GAAAA;AACX,QAAA,IAAIA,KAAAA,KAAU,IAAA,IAAQ,OAAOA,KAAAA,KAAU,QAAA,EAAU;QACjD,IAAIU,KAAAA,CAAMC,OAAO,CAACX,KAAAA,CAAAA,EAAQ;YACtB,KAAK,MAAMY,IAAAA,IAAQZ,KAAAA,CAAOS,KAAAA,CAAMG,IAAAA,CAAAA;AAChC,YAAA;AACJ,QAAA;AAEA,QAAA,IAAIb,wBAAAA,CAAyBC,KAAAA,CAAAA,IAAU,CAACO,KAAAA,CAAMM,GAAG,CAACb,KAAAA,CAAME,EAAE,CAAA,EAAGK,KAAAA,CAAMO,GAAG,CAACd,KAAAA,CAAME,EAAE,EAAEF,KAAAA,CAAAA;AACjF,QAAA,KAAK,MAAMe,KAAAA,IAASC,MAAAA,CAAOC,MAAM,CAACjB,OAAQS,KAAAA,CAAMM,KAAAA,CAAAA;AACpD,IAAA,CAAA;IAEAN,KAAAA,CAAMH,KAAAA,CAAAA;IACN,OAAO;AAAIC,QAAAA,GAAAA,KAAAA,CAAMU,MAAM;AAAG,KAAA;AAC9B;;"}
@@ -0,0 +1,11 @@
1
+ import { LayoutCapabilities, PropertyDescriptor, SceneDiagnostic } from '@cratis/scene.model';
2
+ import { DescriptorCatalog } from './DescriptorCatalog';
3
+ import { NodeRecord } from './DocumentIndex';
4
+ export interface NodeDescription {
5
+ properties: PropertyDescriptor[];
6
+ capabilities?: LayoutCapabilities;
7
+ diagnostics: SceneDiagnostic[];
8
+ }
9
+ export declare function describeNode(record: NodeRecord, catalog: DescriptorCatalog): NodeDescription;
10
+ export declare function readNodeValue(record: NodeRecord, path: string): unknown;
11
+ //# sourceMappingURL=describeNode.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"describeNode.d.ts","sourceRoot":"","sources":["../../../editing/describeNode.ts"],"names":[],"mappings":"AAGA,OAAO,EACa,kBAAkB,EAAc,kBAAkB,EAAE,eAAe,EACtF,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,iBAAiB,EAAqD,MAAM,qBAAqB,CAAC;AAC3G,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAQ7C,MAAM,WAAW,eAAe;IAC5B,UAAU,EAAE,kBAAkB,EAAE,CAAC;IACjC,YAAY,CAAC,EAAE,kBAAkB,CAAC;IAClC,WAAW,EAAE,eAAe,EAAE,CAAC;CAClC;AAWD,wBAAgB,YAAY,CAAC,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,iBAAiB,GAAG,eAAe,CAqB5F;AAKD,wBAAgB,aAAa,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAIvE"}
@@ -0,0 +1,60 @@
1
+ import { LayoutType, SceneNodeKind, DiagnosticCode } from '@cratis/scene.model';
2
+ import { findLayoutTypeDescriptor, findComponentDescriptor } from './DescriptorCatalog.js';
3
+ import { warningDiagnostic } from './diagnostics.js';
4
+ import { getValueAtPath } from './pathAccess.js';
5
+ import { placementProperties, templateProperties } from './layoutTypeDescriptors.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
+ const layoutTypes = new Set(Object.values(LayoutType));
10
+ /**
11
+ * Works out which descriptors apply to a node.
12
+ *
13
+ * A component takes its descriptor from the catalog by the name it carries; a layout node takes its layout type's;
14
+ * a placement and a template have their own fixed sets. A component nothing describes has no editable
15
+ * properties, and says so rather than failing.
16
+ */ function describeNode(record, catalog) {
17
+ const diagnostics = [];
18
+ if (record.kind === SceneNodeKind.Placement) return {
19
+ properties: placementProperties,
20
+ diagnostics
21
+ };
22
+ if (record.kind === SceneNodeKind.ScreenTemplate || record.kind === SceneNodeKind.DialogTemplate) return {
23
+ properties: templateProperties,
24
+ diagnostics
25
+ };
26
+ if (layoutTypes.has(record.typeId)) {
27
+ const descriptor = findLayoutTypeDescriptor(catalog, record.typeId);
28
+ return {
29
+ properties: descriptor?.properties ?? [],
30
+ capabilities: descriptor?.capabilities,
31
+ diagnostics
32
+ };
33
+ }
34
+ if (record.kind === SceneNodeKind.Element && record.value.componentName !== undefined) {
35
+ const descriptor = findComponentDescriptor(catalog, record.typeId);
36
+ if (!descriptor) {
37
+ diagnostics.push(warningDiagnostic(DiagnosticCode.MissingComponentDescriptor, `Nothing describes the component '${record.typeId}', so none of its properties can be edited.`, {
38
+ nodeId: record.id
39
+ }));
40
+ }
41
+ return {
42
+ properties: descriptor?.properties ?? [],
43
+ diagnostics
44
+ };
45
+ }
46
+ return {
47
+ properties: [],
48
+ diagnostics
49
+ };
50
+ }
51
+ /**
52
+ * Reads a descriptor's value from a node: from the property bag of a component, from the node itself otherwise.
53
+ */ function readNodeValue(record, path) {
54
+ const value = record.value;
55
+ const isComponent = record.kind === SceneNodeKind.Element && value.componentName !== undefined;
56
+ return getValueAtPath(isComponent ? value.properties : value, path);
57
+ }
58
+
59
+ export { describeNode, readNodeValue };
60
+ //# sourceMappingURL=describeNode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"describeNode.js","sources":["../../../editing/describeNode.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, LayoutCapabilities, LayoutType, PropertyDescriptor, SceneDiagnostic, SceneNodeKind,\n} from '@cratis/scene.model';\nimport { DescriptorCatalog, findComponentDescriptor, findLayoutTypeDescriptor } from './DescriptorCatalog';\nimport { NodeRecord } from './DocumentIndex';\nimport { warningDiagnostic } from './diagnostics';\nimport { getValueAtPath } from './pathAccess';\nimport { placementProperties, templateProperties } from './layoutTypeDescriptors';\n\n/**\n * What describes a node: its editable properties, and for a layout node what the type can do.\n */\nexport interface NodeDescription {\n properties: PropertyDescriptor[];\n capabilities?: LayoutCapabilities;\n diagnostics: SceneDiagnostic[];\n}\n\nconst layoutTypes = new Set<string>(Object.values(LayoutType));\n\n/**\n * Works out which descriptors apply to a node.\n *\n * A component takes its descriptor from the catalog by the name it carries; a layout node takes its layout type's;\n * a placement and a template have their own fixed sets. A component nothing describes has no editable\n * properties, and says so rather than failing.\n */\nexport function describeNode(record: NodeRecord, catalog: DescriptorCatalog): NodeDescription {\n const diagnostics: SceneDiagnostic[] = [];\n\n if (record.kind === SceneNodeKind.Placement) return { properties: placementProperties, diagnostics };\n if (record.kind === SceneNodeKind.ScreenTemplate || record.kind === SceneNodeKind.DialogTemplate) return { properties: templateProperties, diagnostics };\n\n if (layoutTypes.has(record.typeId)) {\n const descriptor = findLayoutTypeDescriptor(catalog, record.typeId);\n return { properties: descriptor?.properties ?? [], capabilities: descriptor?.capabilities, diagnostics };\n }\n\n if (record.kind === SceneNodeKind.Element && (record.value as { componentName?: unknown }).componentName !== undefined) {\n const descriptor = findComponentDescriptor(catalog, record.typeId);\n if (!descriptor) {\n diagnostics.push(warningDiagnostic(DiagnosticCode.MissingComponentDescriptor, `Nothing describes the component '${record.typeId}', so none of its properties can be edited.`, { nodeId: record.id }));\n }\n\n return { properties: descriptor?.properties ?? [], diagnostics };\n }\n\n return { properties: [], diagnostics };\n}\n\n/**\n * Reads a descriptor's value from a node: from the property bag of a component, from the node itself otherwise.\n */\nexport function readNodeValue(record: NodeRecord, path: string): unknown {\n const value = record.value as Record<string, unknown>;\n const isComponent = record.kind === SceneNodeKind.Element && value.componentName !== undefined;\n return getValueAtPath(isComponent ? (value.properties as Record<string, unknown>) : value, path);\n}\n"],"names":["layoutTypes","Set","Object","values","LayoutType","describeNode","record","catalog","diagnostics","kind","SceneNodeKind","Placement","properties","placementProperties","ScreenTemplate","DialogTemplate","templateProperties","has","typeId","descriptor","findLayoutTypeDescriptor","capabilities","Element","value","componentName","undefined","findComponentDescriptor","push","warningDiagnostic","DiagnosticCode","MissingComponentDescriptor","nodeId","id","readNodeValue","path","isComponent","getValueAtPath"],"mappings":";;;;;;AAAA;AACA;AAoBA,MAAMA,WAAAA,GAAc,IAAIC,GAAAA,CAAYC,MAAAA,CAAOC,MAAM,CAACC,UAAAA,CAAAA,CAAAA;AAElD;;;;;;AAMC,IACM,SAASC,YAAAA,CAAaC,MAAkB,EAAEC,OAA0B,EAAA;AACvE,IAAA,MAAMC,cAAiC,EAAE;AAEzC,IAAA,IAAIF,OAAOG,IAAI,KAAKC,aAAAA,CAAcC,SAAS,EAAE,OAAO;QAAEC,UAAAA,EAAYC,mBAAAA;AAAqBL,QAAAA;AAAY,KAAA;AACnG,IAAA,IAAIF,MAAAA,CAAOG,IAAI,KAAKC,aAAAA,CAAcI,cAAc,IAAIR,MAAAA,CAAOG,IAAI,KAAKC,aAAAA,CAAcK,cAAc,EAAE,OAAO;QAAEH,UAAAA,EAAYI,kBAAAA;AAAoBR,QAAAA;AAAY,KAAA;AAEvJ,IAAA,IAAIR,WAAAA,CAAYiB,GAAG,CAACX,MAAAA,CAAOY,MAAM,CAAA,EAAG;AAChC,QAAA,MAAMC,UAAAA,GAAaC,wBAAAA,CAAyBb,OAAAA,EAASD,MAAAA,CAAOY,MAAM,CAAA;QAClE,OAAO;YAAEN,UAAAA,EAAYO,UAAAA,EAAYP,cAAc,EAAE;AAAES,YAAAA,YAAAA,EAAcF,UAAAA,EAAYE,YAAAA;AAAcb,YAAAA;AAAY,SAAA;AAC3G,IAAA;AAEA,IAAA,IAAIF,MAAAA,CAAOG,IAAI,KAAKC,aAAAA,CAAcY,OAAO,IAAI,MAAChB,CAAOiB,KAAK,CAAiCC,aAAa,KAAKC,SAAAA,EAAW;AACpH,QAAA,MAAMN,UAAAA,GAAaO,uBAAAA,CAAwBnB,OAAAA,EAASD,MAAAA,CAAOY,MAAM,CAAA;AACjE,QAAA,IAAI,CAACC,UAAAA,EAAY;AACbX,YAAAA,WAAAA,CAAYmB,IAAI,CAACC,iBAAAA,CAAkBC,cAAAA,CAAeC,0BAA0B,EAAE,CAAC,iCAAiC,EAAExB,MAAAA,CAAOY,MAAM,CAAC,2CAA2C,CAAC,EAAE;AAAEa,gBAAAA,MAAAA,EAAQzB,OAAO0B;AAAG,aAAA,CAAA,CAAA;AACtM,QAAA;QAEA,OAAO;YAAEpB,UAAAA,EAAYO,UAAAA,EAAYP,cAAc,EAAE;AAAEJ,YAAAA;AAAY,SAAA;AACnE,IAAA;IAEA,OAAO;AAAEI,QAAAA,UAAAA,EAAY,EAAE;AAAEJ,QAAAA;AAAY,KAAA;AACzC;AAEA;;AAEC,IACM,SAASyB,aAAAA,CAAc3B,MAAkB,EAAE4B,IAAY,EAAA;IAC1D,MAAMX,KAAAA,GAAQjB,OAAOiB,KAAK;IAC1B,MAAMY,WAAAA,GAAc7B,OAAOG,IAAI,KAAKC,cAAcY,OAAO,IAAIC,KAAAA,CAAMC,aAAa,KAAKC,SAAAA;AACrF,IAAA,OAAOW,cAAAA,CAAeD,WAAAA,GAAeZ,KAAAA,CAAMX,UAAU,GAA+BW,KAAAA,EAAOW,IAAAA,CAAAA;AAC/F;;"}
@@ -0,0 +1,6 @@
1
+ import { DiagnosticCode, SceneDiagnostic } from '@cratis/scene.model';
2
+ export type DiagnosticContext = Partial<Omit<SceneDiagnostic, 'code' | 'severity' | 'message'>>;
3
+ export declare function errorDiagnostic(code: DiagnosticCode, message: string, context?: DiagnosticContext): SceneDiagnostic;
4
+ export declare function warningDiagnostic(code: DiagnosticCode, message: string, context?: DiagnosticContext): SceneDiagnostic;
5
+ export declare function hasErrors(diagnostics: SceneDiagnostic[]): boolean;
6
+ //# sourceMappingURL=diagnostics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diagnostics.d.ts","sourceRoot":"","sources":["../../../editing/diagnostics.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,cAAc,EAAsB,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAK1F,MAAM,MAAM,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,eAAe,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAAC,CAAC,CAAC;AAKhG,wBAAgB,eAAe,CAAC,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,iBAAsB,GAAG,eAAe,CAEvH;AAKD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,iBAAsB,GAAG,eAAe,CAEzH;AAKD,wBAAgB,SAAS,CAAC,WAAW,EAAE,eAAe,EAAE,GAAG,OAAO,CAEjE"}
@@ -0,0 +1,32 @@
1
+ import { DiagnosticSeverity } from '@cratis/scene.model';
2
+
3
+ // Copyright (c) Cratis. All rights reserved.
4
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
5
+ /**
6
+ * Builds an error diagnostic: the edit or resolution step that produced it did not happen.
7
+ */ function errorDiagnostic(code, message, context = {}) {
8
+ return {
9
+ code,
10
+ severity: DiagnosticSeverity.Error,
11
+ message,
12
+ ...context
13
+ };
14
+ }
15
+ /**
16
+ * Builds a warning diagnostic: the work went ahead, and the author should know something about it.
17
+ */ function warningDiagnostic(code, message, context = {}) {
18
+ return {
19
+ code,
20
+ severity: DiagnosticSeverity.Warning,
21
+ message,
22
+ ...context
23
+ };
24
+ }
25
+ /**
26
+ * Whether any diagnostic is an error.
27
+ */ function hasErrors(diagnostics) {
28
+ return diagnostics.some((diagnostic)=>diagnostic.severity === DiagnosticSeverity.Error);
29
+ }
30
+
31
+ export { errorDiagnostic, hasErrors, warningDiagnostic };
32
+ //# sourceMappingURL=diagnostics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diagnostics.js","sources":["../../../editing/diagnostics.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 { DiagnosticCode, DiagnosticSeverity, SceneDiagnostic } from '@cratis/scene.model';\n\n/**\n * The context a diagnostic can carry besides its code and message.\n */\nexport type DiagnosticContext = Partial<Omit<SceneDiagnostic, 'code' | 'severity' | 'message'>>;\n\n/**\n * Builds an error diagnostic: the edit or resolution step that produced it did not happen.\n */\nexport function errorDiagnostic(code: DiagnosticCode, message: string, context: DiagnosticContext = {}): SceneDiagnostic {\n return { code, severity: DiagnosticSeverity.Error, message, ...context };\n}\n\n/**\n * Builds a warning diagnostic: the work went ahead, and the author should know something about it.\n */\nexport function warningDiagnostic(code: DiagnosticCode, message: string, context: DiagnosticContext = {}): SceneDiagnostic {\n return { code, severity: DiagnosticSeverity.Warning, message, ...context };\n}\n\n/**\n * Whether any diagnostic is an error.\n */\nexport function hasErrors(diagnostics: SceneDiagnostic[]): boolean {\n return diagnostics.some(diagnostic => diagnostic.severity === DiagnosticSeverity.Error);\n}\n"],"names":["errorDiagnostic","code","message","context","severity","DiagnosticSeverity","Error","warningDiagnostic","Warning","hasErrors","diagnostics","some","diagnostic"],"mappings":";;AAAA;AACA;AASA;;IAGO,SAASA,eAAAA,CAAgBC,IAAoB,EAAEC,OAAe,EAAEC,OAAAA,GAA6B,EAAE,EAAA;IAClG,OAAO;AAAEF,QAAAA,IAAAA;AAAMG,QAAAA,QAAAA,EAAUC,mBAAmBC,KAAK;AAAEJ,QAAAA,OAAAA;AAAS,QAAA,GAAGC;AAAQ,KAAA;AAC3E;AAEA;;IAGO,SAASI,iBAAAA,CAAkBN,IAAoB,EAAEC,OAAe,EAAEC,OAAAA,GAA6B,EAAE,EAAA;IACpG,OAAO;AAAEF,QAAAA,IAAAA;AAAMG,QAAAA,QAAAA,EAAUC,mBAAmBG,OAAO;AAAEN,QAAAA,OAAAA;AAAS,QAAA,GAAGC;AAAQ,KAAA;AAC7E;AAEA;;IAGO,SAASM,SAAAA,CAAUC,WAA8B,EAAA;IACpD,OAAOA,WAAAA,CAAYC,IAAI,CAACC,CAAAA,aAAcA,UAAAA,CAAWR,QAAQ,KAAKC,kBAAAA,CAAmBC,KAAK,CAAA;AAC1F;;"}
@@ -0,0 +1,8 @@
1
+ import { DocumentPath } from './DocumentIndex';
2
+ export declare function getAtPath(root: unknown, path: DocumentPath): unknown;
3
+ export declare function ensureArrayAt(root: unknown, path: DocumentPath): unknown[];
4
+ export declare function mirroredPaths(mirror: {
5
+ prefix: DocumentPath;
6
+ others: DocumentPath[];
7
+ } | undefined, path: DocumentPath): DocumentPath[];
8
+ //# sourceMappingURL=documentPaths.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"documentPaths.d.ts","sourceRoot":"","sources":["../../../editing/documentPaths.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAK/C,wBAAgB,SAAS,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,YAAY,GAAG,OAAO,CAQpE;AAMD,wBAAgB,aAAa,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,YAAY,GAAG,OAAO,EAAE,CAQ1E;AAMD,wBAAgB,aAAa,CAAC,MAAM,EAAE;IAAE,MAAM,EAAE,YAAY,CAAC;IAAC,MAAM,EAAE,YAAY,EAAE,CAAA;CAAE,GAAG,SAAS,EAAE,IAAI,EAAE,YAAY,GAAG,YAAY,EAAE,CAGtI"}
@@ -0,0 +1,41 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+ /**
4
+ * Reads the value at a document path.
5
+ */ function getAtPath(root, path) {
6
+ let current = root;
7
+ for (const key of path){
8
+ if (current === null || typeof current !== 'object') return undefined;
9
+ current = current[key];
10
+ }
11
+ return current;
12
+ }
13
+ /**
14
+ * Reads the array at a path, creating it - and any objects on the way - when it is not there yet. Mutates `root`,
15
+ * which callers hold a copy of.
16
+ */ function ensureArrayAt(root, path) {
17
+ let current = root;
18
+ path.forEach((key, position)=>{
19
+ if (current[key] === undefined) current[key] = position === path.length - 1 ? [] : {};
20
+ current = current[key];
21
+ });
22
+ return current;
23
+ }
24
+ /**
25
+ * The paths a change to `path` must be made at: the path itself and, for a node inside a freeform element, the same
26
+ * place in every other size-class variant's copy.
27
+ */ function mirroredPaths(mirror, path) {
28
+ if (!mirror || mirror.prefix.some((key, position)=>path[position] !== key)) return [
29
+ path
30
+ ];
31
+ return [
32
+ path,
33
+ ...mirror.others.map((other)=>[
34
+ ...other,
35
+ ...path.slice(mirror.prefix.length)
36
+ ])
37
+ ];
38
+ }
39
+
40
+ export { ensureArrayAt, getAtPath, mirroredPaths };
41
+ //# sourceMappingURL=documentPaths.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"documentPaths.js","sources":["../../../editing/documentPaths.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 { DocumentPath } from './DocumentIndex';\n\n/**\n * Reads the value at a document path.\n */\nexport function getAtPath(root: unknown, path: DocumentPath): unknown {\n let current = root;\n for (const key of path) {\n if (current === null || typeof current !== 'object') return undefined;\n current = (current as Record<string | number, unknown>)[key];\n }\n\n return current;\n}\n\n/**\n * Reads the array at a path, creating it - and any objects on the way - when it is not there yet. Mutates `root`,\n * which callers hold a copy of.\n */\nexport function ensureArrayAt(root: unknown, path: DocumentPath): unknown[] {\n let current = root as Record<string | number, unknown>;\n path.forEach((key, position) => {\n if (current[key] === undefined) current[key] = position === path.length - 1 ? [] : {};\n current = current[key] as Record<string | number, unknown>;\n });\n\n return current as unknown as unknown[];\n}\n\n/**\n * The paths a change to `path` must be made at: the path itself and, for a node inside a freeform element, the same\n * place in every other size-class variant's copy.\n */\nexport function mirroredPaths(mirror: { prefix: DocumentPath; others: DocumentPath[] } | undefined, path: DocumentPath): DocumentPath[] {\n if (!mirror || mirror.prefix.some((key, position) => path[position] !== key)) return [path];\n return [path, ...mirror.others.map(other => [...other, ...path.slice(mirror.prefix.length)])];\n}\n"],"names":["getAtPath","root","path","current","key","undefined","ensureArrayAt","forEach","position","length","mirroredPaths","mirror","prefix","some","others","map","other","slice"],"mappings":"AAAA;AACA;AAIA;;AAEC,IACM,SAASA,SAAAA,CAAUC,IAAa,EAAEC,IAAkB,EAAA;AACvD,IAAA,IAAIC,OAAAA,GAAUF,IAAAA;IACd,KAAK,MAAMG,OAAOF,IAAAA,CAAM;AACpB,QAAA,IAAIC,OAAAA,KAAY,IAAA,IAAQ,OAAOA,OAAAA,KAAY,UAAU,OAAOE,SAAAA;QAC5DF,OAAAA,GAAWA,OAA4C,CAACC,GAAAA,CAAI;AAChE,IAAA;IAEA,OAAOD,OAAAA;AACX;AAEA;;;AAGC,IACM,SAASG,aAAAA,CAAcL,IAAa,EAAEC,IAAkB,EAAA;AAC3D,IAAA,IAAIC,OAAAA,GAAUF,IAAAA;IACdC,IAAAA,CAAKK,OAAO,CAAC,CAACH,GAAAA,EAAKI,QAAAA,GAAAA;AACf,QAAA,IAAIL,OAAO,CAACC,GAAAA,CAAI,KAAKC,SAAAA,EAAWF,OAAO,CAACC,GAAAA,CAAI,GAAGI,QAAAA,KAAaN,KAAKO,MAAM,GAAG,CAAA,GAAI,EAAE,GAAG,EAAC;QACpFN,OAAAA,GAAUA,OAAO,CAACC,GAAAA,CAAI;AAC1B,IAAA,CAAA,CAAA;IAEA,OAAOD,OAAAA;AACX;AAEA;;;AAGC,IACM,SAASO,aAAAA,CAAcC,MAAoE,EAAET,IAAkB,EAAA;AAClH,IAAA,IAAI,CAACS,MAAAA,IAAUA,MAAAA,CAAOC,MAAM,CAACC,IAAI,CAAC,CAACT,GAAAA,EAAKI,WAAaN,IAAI,CAACM,QAAAA,CAAS,KAAKJ,MAAM,OAAO;AAACF,QAAAA;AAAK,KAAA;IAC3F,OAAO;AAACA,QAAAA,IAAAA;AAASS,QAAAA,GAAAA,MAAAA,CAAOG,MAAM,CAACC,GAAG,CAACC,CAAAA,KAAAA,GAAS;AAAIA,gBAAAA,GAAAA,KAAAA;AAAUd,gBAAAA,GAAAA,IAAAA,CAAKe,KAAK,CAACN,MAAAA,CAAOC,MAAM,CAACH,MAAM;AAAE,aAAA;AAAE,KAAA;AACjG;;"}
@@ -0,0 +1,5 @@
1
+ import { ExposePropertyEdit, SceneDiagnostic, SceneDocument, UnexposePropertyEdit } from '@cratis/scene.model';
2
+ import { EditSession } from './EditSession';
3
+ export declare function applyExposeProperty(session: EditSession, edit: ExposePropertyEdit, clone: SceneDocument, diagnostics: SceneDiagnostic[]): void;
4
+ export declare function applyUnexposeProperty(session: EditSession, edit: UnexposePropertyEdit, clone: SceneDocument, diagnostics: SceneDiagnostic[]): void;
5
+ //# sourceMappingURL=exposureEdits.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exposureEdits.d.ts","sourceRoot":"","sources":["../../../editing/exposureEdits.ts"],"names":[],"mappings":"AAGA,OAAO,EACmD,kBAAkB,EAAqB,eAAe,EAC5G,aAAa,EAAE,oBAAoB,EACtC,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AA8E5C,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,kBAAkB,EAAE,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,eAAe,EAAE,GAAG,IAAI,CAc9I;AAKD,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,oBAAoB,EAAE,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,eAAe,EAAE,GAAG,IAAI,CAYlJ"}
@@ -0,0 +1,103 @@
1
+ import { DiagnosticCode, PropertyValueType, CollectionOperation } from '@cratis/scene.model';
2
+ import { findComponentDescriptor } from './DescriptorCatalog.js';
3
+ import { errorDiagnostic } from './diagnostics.js';
4
+ import { grantKey } from './exposureGrants.js';
5
+ import { cloneData } from './pathAccess.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
+ function ownsDeclaration(session, owner, diagnostics) {
10
+ const level = session.chain.levels.at(-1);
11
+ if (!level || level.owner !== owner) {
12
+ diagnostics.push(errorDiagnostic(DiagnosticCode.NodeNotEditable, `Exposure is declared by the layout or template that owns the component. '${owner}' is not what is being edited.`));
13
+ return false;
14
+ }
15
+ return true;
16
+ }
17
+ function validateExposure(session, property, diagnostics) {
18
+ const context = {
19
+ component: property.component,
20
+ path: property.path
21
+ };
22
+ const level = session.chain.levels.at(-1);
23
+ const reExposed = property.reExposes !== undefined;
24
+ if (!reExposed && !level.elements.some((candidate)=>candidate.id === property.component)) {
25
+ diagnostics.push(errorDiagnostic(DiagnosticCode.ExposureTargetMissing, `'${level.owner}' has no component '${property.component}'.`, context));
26
+ return false;
27
+ }
28
+ const grant = reExposed ? session.scopeGrants.get(grantKey(property.component, property.path)) : undefined;
29
+ if (reExposed && (!grant || grant.owner !== property.reExposes)) {
30
+ 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));
31
+ return false;
32
+ }
33
+ const element = level.elements.find((candidate)=>candidate.id === property.component);
34
+ const descriptor = grant ? grant.descriptor : findComponentDescriptor(session.context.catalog, element.componentName)?.properties.find((candidate)=>candidate.path === property.path);
35
+ if (!descriptor) {
36
+ diagnostics.push(errorDiagnostic(DiagnosticCode.ExposureTargetMissing, `There is no editable property '${property.path}' on '${property.component}'.`, context));
37
+ return false;
38
+ }
39
+ const operations = property.operations ?? [];
40
+ if (descriptor.valueType !== PropertyValueType.Collection) {
41
+ if (operations.length > 0 || property.editableFields !== undefined) {
42
+ diagnostics.push(errorDiagnostic(DiagnosticCode.InvalidEdit, `'${descriptor.label}' is not a collection, so operations and editable fields do not apply.`, context));
43
+ return false;
44
+ }
45
+ return true;
46
+ }
47
+ const known = Object.values(CollectionOperation);
48
+ const unknown = operations.find((operation)=>!known.includes(operation));
49
+ if (unknown !== undefined) {
50
+ diagnostics.push(errorDiagnostic(DiagnosticCode.InvalidEdit, `'${unknown}' is not a collection operation.`, context));
51
+ return false;
52
+ }
53
+ const fields = descriptor.item?.properties.map((candidate)=>candidate.path) ?? [];
54
+ const unknownField = property.editableFields?.find((field)=>!fields.includes(field));
55
+ if (unknownField !== undefined) {
56
+ diagnostics.push(errorDiagnostic(DiagnosticCode.UnknownCollectionField, `Items of '${descriptor.label}' have no field '${unknownField}'.`, context));
57
+ return false;
58
+ }
59
+ if (grant && (operations.some((operation)=>!grant.operations.includes(operation)) || grant.editableFields !== undefined && (property.editableFields ?? fields).some((field)=>!grant.editableFields.includes(field)))) {
60
+ diagnostics.push(errorDiagnostic(DiagnosticCode.ExposureWidensOwner, `'${property.reExposes}' exposed less of '${descriptor.label}' than this re-exposes.`, context));
61
+ return false;
62
+ }
63
+ return true;
64
+ }
65
+ /**
66
+ * Applies an exposure declaration to a copy of the document.
67
+ *
68
+ * Exposure only narrows: the property has to be one the component's descriptor supports, a collection's
69
+ * operations and fields have to exist, and a re-exposure cannot grant more than the owner it passes on.
70
+ */ function applyExposeProperty(session, edit, clone, diagnostics) {
71
+ if (!ownsDeclaration(session, edit.owner, diagnostics) || !validateExposure(session, edit.property, diagnostics)) return;
72
+ let declaration = clone.exposures.find((candidate)=>candidate.owner === edit.owner);
73
+ if (!declaration) {
74
+ declaration = {
75
+ owner: edit.owner,
76
+ properties: []
77
+ };
78
+ clone.exposures.push(declaration);
79
+ }
80
+ const same = (candidate)=>candidate.component === edit.property.component && candidate.path === edit.property.path && candidate.reExposes === edit.property.reExposes;
81
+ const position = declaration.properties.findIndex(same);
82
+ if (position >= 0) declaration.properties[position] = cloneData(edit.property);
83
+ else declaration.properties.push(cloneData(edit.property));
84
+ }
85
+ /**
86
+ * Applies an exposure withdrawal to a copy of the document. Values already saved against it are not touched.
87
+ */ function applyUnexposeProperty(session, edit, clone, diagnostics) {
88
+ if (!ownsDeclaration(session, edit.owner, diagnostics)) return;
89
+ const declaration = clone.exposures.find((candidate)=>candidate.owner === edit.owner);
90
+ const remaining = declaration?.properties.filter((candidate)=>!(candidate.component === edit.component && candidate.path === edit.path));
91
+ if (!declaration || remaining.length === declaration.properties.length) {
92
+ diagnostics.push(errorDiagnostic(DiagnosticCode.ExposureTargetMissing, `'${edit.owner}' does not expose '${edit.path}' on '${edit.component}'.`, {
93
+ component: edit.component,
94
+ path: edit.path
95
+ }));
96
+ return;
97
+ }
98
+ if (remaining.length === 0) clone.exposures.splice(clone.exposures.indexOf(declaration), 1);
99
+ else declaration.properties = remaining;
100
+ }
101
+
102
+ export { applyExposeProperty, applyUnexposeProperty };
103
+ //# sourceMappingURL=exposureEdits.js.map
@@ -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,21 @@
1
+ import { CollectionOperation, PropertyDescriptor, SceneDiagnostic } from '@cratis/scene.model';
2
+ import { DescriptorCatalog } from './DescriptorCatalog';
3
+ import { TemplateChain } from './TemplateChain';
4
+ export interface ExposureGrant {
5
+ component: string;
6
+ path: string;
7
+ descriptor: PropertyDescriptor;
8
+ owner: string;
9
+ ownerLevel: number;
10
+ operations: CollectionOperation[];
11
+ editableFields?: string[];
12
+ label?: string;
13
+ }
14
+ export interface ExposureGrants {
15
+ exposed: ExposureGrant[];
16
+ byInstance: Map<string, Map<string, ExposureGrant>>;
17
+ diagnostics: SceneDiagnostic[];
18
+ }
19
+ export declare function grantKey(component: string, path: string): string;
20
+ export declare function computeExposureGrants(chain: TemplateChain, catalog: DescriptorCatalog): ExposureGrants;
21
+ //# sourceMappingURL=exposureGrants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exposureGrants.d.ts","sourceRoot":"","sources":["../../../editing/exposureGrants.ts"],"names":[],"mappings":"AAGA,OAAO,EACH,mBAAmB,EAAmC,kBAAkB,EAAqB,eAAe,EAC/G,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,iBAAiB,EAA2B,MAAM,qBAAqB,CAAC;AAEjF,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAMhD,MAAM,WAAW,aAAa;IAE1B,SAAS,EAAE,MAAM,CAAC;IAElB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,kBAAkB,CAAC;IAG/B,KAAK,EAAE,MAAM,CAAC;IAGd,UAAU,EAAE,MAAM,CAAC;IAGnB,UAAU,EAAE,mBAAmB,EAAE,CAAC;IAGlC,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAE1B,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AAKD,MAAM,WAAW,cAAc;IAE3B,OAAO,EAAE,aAAa,EAAE,CAAC;IAGzB,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC;IAEpD,WAAW,EAAE,eAAe,EAAE,CAAC;CAClC;AAKD,wBAAgB,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAEhE;AAyBD,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,aAAa,EAAE,OAAO,EAAE,iBAAiB,GAAG,cAAc,CA+EtG"}
@@ -0,0 +1,112 @@
1
+ import { DiagnosticCode, PropertyValueType } from '@cratis/scene.model';
2
+ import { findComponentDescriptor } from './DescriptorCatalog.js';
3
+ import { errorDiagnostic } from './diagnostics.js';
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
+ /**
8
+ * The key a grant is stored under.
9
+ */ function grantKey(component, path) {
10
+ return `${component}\u0000${path}`;
11
+ }
12
+ function narrow(grant, reExposure) {
13
+ const requested = reExposure.operations ?? [];
14
+ const operations = requested.filter((operation)=>grant.operations.includes(operation));
15
+ const fields = grant.editableFields === undefined ? reExposure.editableFields : reExposure.editableFields === undefined ? grant.editableFields : reExposure.editableFields.filter((field)=>grant.editableFields.includes(field));
16
+ const widened = operations.length < requested.length || grant.editableFields !== undefined && reExposure.editableFields !== undefined && reExposure.editableFields.some((field)=>!grant.editableFields.includes(field));
17
+ return {
18
+ grant: {
19
+ ...grant,
20
+ operations,
21
+ editableFields: fields,
22
+ label: reExposure.label ?? grant.label
23
+ },
24
+ widened
25
+ };
26
+ }
27
+ /**
28
+ * Works out, for every instance in a chain, which properties it may configure.
29
+ *
30
+ * An owner's exposure reaches the instance directly inside it. It reaches further only through explicit
31
+ * re-exposure by every level in between, and each re-exposure can only narrow what it passes on - a nested
32
+ * template that lists more operations or fields than its owner granted gets the owner's, not its own.
33
+ *
34
+ * @param chain The chain to analyze.
35
+ * @param catalog The descriptors that say what each component supports.
36
+ */ function computeExposureGrants(chain, catalog) {
37
+ const result = {
38
+ exposed: [],
39
+ byInstance: new Map(),
40
+ diagnostics: []
41
+ };
42
+ for (const chainLevel of chain.levels)result.byInstance.set(chainLevel.instance, new Map());
43
+ const consumed = new Set();
44
+ chain.levels.forEach((owner, ownerLevel)=>{
45
+ for (const exposure of owner.exposures.filter((candidate)=>candidate.reExposes === undefined)){
46
+ const element = owner.elements.find((candidate)=>candidate.id === exposure.component);
47
+ if (!element) {
48
+ result.diagnostics.push(errorDiagnostic(DiagnosticCode.ExposureTargetMissing, `'${owner.owner}' exposes '${exposure.path}' on '${exposure.component}', but it has no such component.`, {
49
+ component: exposure.component,
50
+ path: exposure.path
51
+ }));
52
+ continue;
53
+ }
54
+ const descriptor = findComponentDescriptor(catalog, element.componentName);
55
+ if (!descriptor) {
56
+ result.diagnostics.push(errorDiagnostic(DiagnosticCode.MissingComponentDescriptor, `'${owner.owner}' exposes '${exposure.path}' on '${exposure.component}', but nothing describes the component '${element.componentName}'.`, {
57
+ component: exposure.component,
58
+ path: exposure.path
59
+ }));
60
+ continue;
61
+ }
62
+ const property = descriptor.properties.find((candidate)=>candidate.path === exposure.path);
63
+ if (!property) {
64
+ result.diagnostics.push(errorDiagnostic(DiagnosticCode.ExposureTargetMissing, `'${owner.owner}' exposes '${exposure.path}' on '${exposure.component}', but '${element.componentName}' no longer has that property.`, {
65
+ component: exposure.component,
66
+ path: exposure.path
67
+ }));
68
+ continue;
69
+ }
70
+ const isCollection = property.valueType === PropertyValueType.Collection;
71
+ let current = {
72
+ component: exposure.component,
73
+ path: exposure.path,
74
+ descriptor: property,
75
+ owner: owner.owner,
76
+ ownerLevel,
77
+ operations: isCollection ? [
78
+ ...new Set(exposure.operations ?? [])
79
+ ] : [],
80
+ editableFields: isCollection ? exposure.editableFields : undefined,
81
+ label: exposure.label
82
+ };
83
+ result.exposed.push(current);
84
+ for(let contributor = ownerLevel + 1; contributor < chain.levels.length; contributor++){
85
+ result.byInstance.get(chain.levels[contributor].instance).set(grantKey(exposure.component, exposure.path), current);
86
+ const reExposure = chain.levels[contributor].exposures.find((candidate)=>candidate.reExposes === owner.owner && candidate.component === exposure.component && candidate.path === exposure.path);
87
+ if (!reExposure) break;
88
+ consumed.add(reExposure);
89
+ const narrowed = narrow(current, reExposure);
90
+ if (narrowed.widened) {
91
+ result.diagnostics.push(errorDiagnostic(DiagnosticCode.ExposureWidensOwner, `'${chain.levels[contributor].owner}' re-exposes more of '${exposure.path}' than '${owner.owner}' exposed; only what the owner granted is passed on.`, {
92
+ component: exposure.component,
93
+ path: exposure.path
94
+ }));
95
+ }
96
+ current = narrowed.grant;
97
+ }
98
+ }
99
+ });
100
+ for (const chainLevel of chain.levels){
101
+ for (const reExposure of chainLevel.exposures.filter((candidate)=>candidate.reExposes !== undefined && !consumed.has(candidate))){
102
+ result.diagnostics.push(errorDiagnostic(DiagnosticCode.ReExposureBroken, `'${chainLevel.owner}' re-exposes '${reExposure.path}' on '${reExposure.component}' from '${reExposure.reExposes}', which does not expose it to this chain.`, {
103
+ component: reExposure.component,
104
+ path: reExposure.path
105
+ }));
106
+ }
107
+ }
108
+ return result;
109
+ }
110
+
111
+ export { computeExposureGrants, grantKey };
112
+ //# sourceMappingURL=exposureGrants.js.map