@cratis/scene.engine 4.3.0 → 4.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (141) hide show
  1. package/dist/cjs/editing/collectIconUsages.js +86 -0
  2. package/dist/cjs/editing/collectIconUsages.js.map +1 -0
  3. package/dist/cjs/editing/diagnoseIcons.js +67 -0
  4. package/dist/cjs/editing/diagnoseIcons.js.map +1 -0
  5. package/dist/cjs/editing/iconDiagnostics.js +103 -0
  6. package/dist/cjs/editing/iconDiagnostics.js.map +1 -0
  7. package/dist/cjs/editing/inspect.js +28 -1
  8. package/dist/cjs/editing/inspect.js.map +1 -1
  9. package/dist/cjs/editing/instanceEdits.js +15 -3
  10. package/dist/cjs/editing/instanceEdits.js.map +1 -1
  11. package/dist/cjs/editing/propertyEdits.js +7 -0
  12. package/dist/cjs/editing/propertyEdits.js.map +1 -1
  13. package/dist/cjs/icons/EffectiveIconCatalog.js +212 -0
  14. package/dist/cjs/icons/EffectiveIconCatalog.js.map +1 -0
  15. package/dist/cjs/icons/EffectiveIconEntry.js +22 -0
  16. package/dist/cjs/icons/EffectiveIconEntry.js.map +1 -0
  17. package/dist/cjs/icons/analyzeIconImpact.js +48 -0
  18. package/dist/cjs/icons/analyzeIconImpact.js.map +1 -0
  19. package/dist/cjs/icons/matchesIconQuery.js +22 -0
  20. package/dist/cjs/icons/matchesIconQuery.js.map +1 -0
  21. package/dist/cjs/icons/resolveIconLibraries.js +45 -0
  22. package/dist/cjs/icons/resolveIconLibraries.js.map +1 -0
  23. package/dist/cjs/index.js +16 -0
  24. package/dist/cjs/index.js.map +1 -1
  25. package/dist/esm/editing/EditingContext.d.ts +2 -0
  26. package/dist/esm/editing/EditingContext.d.ts.map +1 -1
  27. package/dist/esm/editing/collectIconUsages.d.ts +5 -0
  28. package/dist/esm/editing/collectIconUsages.d.ts.map +1 -0
  29. package/dist/esm/editing/collectIconUsages.js +84 -0
  30. package/dist/esm/editing/collectIconUsages.js.map +1 -0
  31. package/dist/esm/editing/diagnoseIcons.d.ts +4 -0
  32. package/dist/esm/editing/diagnoseIcons.d.ts.map +1 -0
  33. package/dist/esm/editing/diagnoseIcons.js +65 -0
  34. package/dist/esm/editing/diagnoseIcons.js.map +1 -0
  35. package/dist/esm/editing/iconDiagnostics.d.ts +11 -0
  36. package/dist/esm/editing/iconDiagnostics.d.ts.map +1 -0
  37. package/dist/esm/editing/iconDiagnostics.js +99 -0
  38. package/dist/esm/editing/iconDiagnostics.js.map +1 -0
  39. package/dist/esm/editing/index.d.ts +3 -0
  40. package/dist/esm/editing/index.d.ts.map +1 -1
  41. package/dist/esm/editing/index.js +3 -0
  42. package/dist/esm/editing/index.js.map +1 -1
  43. package/dist/esm/editing/inspect.d.ts.map +1 -1
  44. package/dist/esm/editing/inspect.js +29 -2
  45. package/dist/esm/editing/inspect.js.map +1 -1
  46. package/dist/esm/editing/instanceEdits.d.ts.map +1 -1
  47. package/dist/esm/editing/instanceEdits.js +17 -5
  48. package/dist/esm/editing/instanceEdits.js.map +1 -1
  49. package/dist/esm/editing/propertyEdits.d.ts.map +1 -1
  50. package/dist/esm/editing/propertyEdits.js +9 -2
  51. package/dist/esm/editing/propertyEdits.js.map +1 -1
  52. package/dist/esm/icons/EffectiveIconCatalog.d.ts +25 -0
  53. package/dist/esm/icons/EffectiveIconCatalog.d.ts.map +1 -0
  54. package/dist/esm/icons/EffectiveIconCatalog.js +210 -0
  55. package/dist/esm/icons/EffectiveIconCatalog.js.map +1 -0
  56. package/dist/esm/icons/EffectiveIconEntry.d.ts +9 -0
  57. package/dist/esm/icons/EffectiveIconEntry.d.ts.map +1 -0
  58. package/dist/esm/icons/EffectiveIconEntry.js +20 -0
  59. package/dist/esm/icons/EffectiveIconEntry.js.map +1 -0
  60. package/dist/esm/icons/IconCatalogSource.d.ts +6 -0
  61. package/dist/esm/icons/IconCatalogSource.d.ts.map +1 -0
  62. package/dist/esm/icons/IconCatalogSource.js +2 -0
  63. package/dist/esm/icons/IconCatalogSource.js.map +1 -0
  64. package/dist/esm/icons/IconDiagnostic.d.ts +9 -0
  65. package/dist/esm/icons/IconDiagnostic.d.ts.map +1 -0
  66. package/dist/esm/icons/IconDiagnostic.js +2 -0
  67. package/dist/esm/icons/IconDiagnostic.js.map +1 -0
  68. package/dist/esm/icons/IconImpactReport.d.ts +18 -0
  69. package/dist/esm/icons/IconImpactReport.d.ts.map +1 -0
  70. package/dist/esm/icons/IconImpactReport.js +2 -0
  71. package/dist/esm/icons/IconImpactReport.js.map +1 -0
  72. package/dist/esm/icons/IconLibraryResolution.d.ts +7 -0
  73. package/dist/esm/icons/IconLibraryResolution.d.ts.map +1 -0
  74. package/dist/esm/icons/IconLibraryResolution.js +2 -0
  75. package/dist/esm/icons/IconLibraryResolution.js.map +1 -0
  76. package/dist/esm/icons/IconQuery.d.ts +7 -0
  77. package/dist/esm/icons/IconQuery.d.ts.map +1 -0
  78. package/dist/esm/icons/IconQuery.js +2 -0
  79. package/dist/esm/icons/IconQuery.js.map +1 -0
  80. package/dist/esm/icons/IconResolution.d.ts +14 -0
  81. package/dist/esm/icons/IconResolution.d.ts.map +1 -0
  82. package/dist/esm/icons/IconResolution.js +2 -0
  83. package/dist/esm/icons/IconResolution.js.map +1 -0
  84. package/dist/esm/icons/IconSearchResult.d.ts +7 -0
  85. package/dist/esm/icons/IconSearchResult.d.ts.map +1 -0
  86. package/dist/esm/icons/IconSearchResult.js +2 -0
  87. package/dist/esm/icons/IconSearchResult.js.map +1 -0
  88. package/dist/esm/icons/IconUsage.d.ts +6 -0
  89. package/dist/esm/icons/IconUsage.d.ts.map +1 -0
  90. package/dist/esm/icons/IconUsage.js +2 -0
  91. package/dist/esm/icons/IconUsage.js.map +1 -0
  92. package/dist/esm/icons/ResolvedIconLibrary.d.ts +8 -0
  93. package/dist/esm/icons/ResolvedIconLibrary.d.ts.map +1 -0
  94. package/dist/esm/icons/ResolvedIconLibrary.js +2 -0
  95. package/dist/esm/icons/ResolvedIconLibrary.js.map +1 -0
  96. package/dist/esm/icons/analyzeIconImpact.d.ts +5 -0
  97. package/dist/esm/icons/analyzeIconImpact.d.ts.map +1 -0
  98. package/dist/esm/icons/analyzeIconImpact.js +46 -0
  99. package/dist/esm/icons/analyzeIconImpact.js.map +1 -0
  100. package/dist/esm/icons/index.d.ts +14 -0
  101. package/dist/esm/icons/index.d.ts.map +1 -0
  102. package/dist/esm/icons/index.js +14 -0
  103. package/dist/esm/icons/index.js.map +1 -0
  104. package/dist/esm/icons/matchesIconQuery.d.ts +4 -0
  105. package/dist/esm/icons/matchesIconQuery.d.ts.map +1 -0
  106. package/dist/esm/icons/matchesIconQuery.js +20 -0
  107. package/dist/esm/icons/matchesIconQuery.js.map +1 -0
  108. package/dist/esm/icons/resolveIconLibraries.d.ts +4 -0
  109. package/dist/esm/icons/resolveIconLibraries.d.ts.map +1 -0
  110. package/dist/esm/icons/resolveIconLibraries.js +43 -0
  111. package/dist/esm/icons/resolveIconLibraries.js.map +1 -0
  112. package/dist/esm/index.d.ts +1 -0
  113. package/dist/esm/index.d.ts.map +1 -1
  114. package/dist/esm/index.js +7 -0
  115. package/dist/esm/index.js.map +1 -1
  116. package/dist/esm/tsconfig.tsbuildinfo +1 -1
  117. package/editing/EditingContext.ts +11 -0
  118. package/editing/collectIconUsages.ts +78 -0
  119. package/editing/diagnoseIcons.ts +60 -0
  120. package/editing/iconDiagnostics.ts +90 -0
  121. package/editing/index.ts +3 -0
  122. package/editing/inspect.ts +25 -2
  123. package/editing/instanceEdits.ts +13 -5
  124. package/editing/propertyEdits.ts +10 -2
  125. package/icons/EffectiveIconCatalog.ts +199 -0
  126. package/icons/EffectiveIconEntry.ts +36 -0
  127. package/icons/IconCatalogSource.ts +23 -0
  128. package/icons/IconDiagnostic.ts +45 -0
  129. package/icons/IconImpactReport.ts +63 -0
  130. package/icons/IconLibraryResolution.ts +22 -0
  131. package/icons/IconQuery.ts +27 -0
  132. package/icons/IconResolution.ts +25 -0
  133. package/icons/IconSearchResult.ts +21 -0
  134. package/icons/IconUsage.ts +21 -0
  135. package/icons/ResolvedIconLibrary.ts +32 -0
  136. package/icons/analyzeIconImpact.ts +41 -0
  137. package/icons/index.ts +16 -0
  138. package/icons/matchesIconQuery.ts +19 -0
  139. package/icons/resolveIconLibraries.ts +47 -0
  140. package/index.ts +1 -0
  141. package/package.json +3 -3
@@ -1 +1 @@
1
- {"version":3,"file":"inspect.js","sources":["../../../editing/inspect.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport {\n DiagnosticCode, EditTarget, InspectedCollectionItem, InspectedProperty, NodeInspection,\n NodeProvenance, ProvenanceKind, PropertyDescriptor, PropertyValueType, SceneDiagnostic, SceneDocument, SceneNodeKind, ValueSource,\n} from '@cratis/scene.model';\nimport { describeNode, readNodeValue } from './describeNode';\nimport { EditingContext } from './EditingContext';\nimport { computeExposureGrants, ExposureGrant, grantKey } from './exposureGrants';\nimport { indexDocument } from './indexDocument';\nimport { NodeRecord } from './DocumentIndex';\nimport { resolveEffectiveConfiguration } from './resolveEffectiveConfiguration';\nimport { resolveTemplateChain } from './resolveTemplateChain';\nimport { TemplateChain } from './TemplateChain';\n\n/**\n * Works out whether a node is the editing scope's own, and when it is not, where it comes from and whether any of\n * it is configurable here.\n *\n * @param record The node.\n * @param chain The chain the scope sits in.\n * @param scopeGrants What the scope's own instance may configure.\n */\nexport function provenanceOf(record: NodeRecord, chain: TemplateChain, scopeGrants: Map<string, ExposureGrant> | undefined): NodeProvenance {\n const scopeLevel = chain.levels.at(-1);\n if (scopeLevel && record.owner === scopeLevel.owner && record.ownerKind === scopeLevel.kind) return { kind: ProvenanceKind.Local };\n\n const configurable = record.kind === SceneNodeKind.Element\n && [...(scopeGrants?.values() ?? [])].some(grant => grant.component === (record.value as { id: string }).id);\n return { kind: configurable ? ProvenanceKind.ConfigurableInherited : ProvenanceKind.Inherited, source: record.owner };\n}\n\nfunction isRemovable(record: NodeRecord, provenance: NodeProvenance): boolean {\n return provenance.kind === ProvenanceKind.Local\n && (record.list !== undefined || record.leafId !== undefined || record.placementIds !== undefined);\n}\n\nfunction toInspectedItems(raw: unknown, local: boolean): InspectedCollectionItem[] {\n return (Array.isArray(raw) ? raw : []).map((item: Record<string, unknown>, position) => {\n const { id, ...values } = item;\n return { id: typeof id === 'string' ? id : `owner-${position}`, values, origin: 'owner', editable: local };\n });\n}\n\nfunction inspectProperty(\n descriptor: PropertyDescriptor,\n record: NodeRecord,\n provenance: NodeProvenance,\n scopeInstance: string | undefined,\n grants: Map<string, ExposureGrant> | undefined,\n configuredValues: { path: string; value: unknown; source: string; items?: { id: string; values: Record<string, unknown>; origin: string }[] }[] | undefined,\n): InspectedProperty {\n const currentValue = readNodeValue(record, descriptor.path);\n const configured = configuredValues?.find(candidate => candidate.path === descriptor.path);\n const local = provenance.kind === ProvenanceKind.Local;\n const isCollection = descriptor.valueType === PropertyValueType.Collection;\n\n const inspected: InspectedProperty = {\n descriptor,\n currentValue,\n effectiveValue: configured ? configured.value : (currentValue ?? descriptor.default),\n source: (configured?.source ?? (currentValue === undefined ? ValueSource.Default : ValueSource.Local)) as ValueSource,\n editable: false,\n };\n\n const grant = !local && record.kind === SceneNodeKind.Element\n ? grants?.get(grantKey((record.value as { id: string }).id, descriptor.path))\n : undefined;\n\n if (local) {\n inspected.editable = descriptor.readOnly !== true;\n if (inspected.editable) inspected.editTarget = EditTarget.Node;\n else inspected.reason = 'This property is read-only.';\n } else if (grant) {\n inspected.editable = true;\n inspected.editTarget = EditTarget.Instance;\n if (isCollection) inspected.operations = grant.operations;\n } else {\n inspected.reason = `Inherited from '${provenance.source}', which does not expose it.`;\n }\n\n if (isCollection) {\n const items = configured?.items\n ? configured.items.map(item => ({ ...item, editable: local || (item.origin === scopeInstance && grant !== undefined && grant.operations.length > 0) }))\n : toInspectedItems(currentValue, local);\n inspected.items = items;\n }\n\n return inspected;\n}\n\n/**\n * Describes one node for an editor: what it is, where it comes from, what can be edited on it - with current and\n * effective values and effective editability - and what can be done with it.\n *\n * A property of a node the scope owns is edited on the node. A property of an inherited node is editable only\n * when its owner exposed it, and then the edit goes to an instance contribution, never into the inherited node.\n * Nothing is mutated.\n *\n * @param document The document to read.\n * @param nodeId The node to describe; see the node id functions.\n * @param context The catalog and the editing scope.\n * @returns The inspection, or `undefined` when the document has no such node.\n */\nexport function inspect(document: SceneDocument, nodeId: string, context: EditingContext): NodeInspection | undefined {\n const index = indexDocument(document);\n const record = index.nodes.get(nodeId);\n if (!record) return undefined;\n\n const chain = resolveTemplateChain(document, context.scope);\n const grants = computeExposureGrants(chain, context.catalog);\n const scopeInstance = chain.levels.at(-1)?.instance;\n const scopeGrants = scopeInstance === undefined ? undefined : grants.byInstance.get(scopeInstance);\n const configuration = resolveEffectiveConfiguration(chain, document.instanceContributions, context.catalog);\n\n const provenance = provenanceOf(record, chain, scopeGrants);\n const description = describeNode(record, context.catalog);\n const componentId = record.kind === SceneNodeKind.Element ? (record.value as { id: string }).id : undefined;\n const configuredValues = configuration.components.find(candidate => candidate.component === componentId)?.values;\n\n const diagnostics: SceneDiagnostic[] = [\n ...description.diagnostics,\n ...configuration.diagnostics.filter(diagnostic => diagnostic.component !== undefined && diagnostic.component === componentId),\n ];\n if (chain.levels.length === 0) {\n diagnostics.push(...chain.diagnostics.filter(diagnostic => diagnostic.code === DiagnosticCode.UnknownScope));\n }\n\n return {\n nodeId,\n kind: record.kind,\n typeId: record.typeId,\n label: record.label,\n parentId: record.parentId,\n provenance,\n properties: description.properties.map(descriptor => inspectProperty(descriptor, record, provenance, scopeInstance, scopeGrants, configuredValues)),\n capabilities: description.capabilities,\n removable: isRemovable(record, provenance),\n diagnostics,\n };\n}\n"],"names":["provenanceOf","record","chain","scopeGrants","scopeLevel","levels","at","owner","ownerKind","kind","ProvenanceKind","Local","configurable","SceneNodeKind","Element","values","some","grant","component","value","id","ConfigurableInherited","Inherited","source","isRemovable","provenance","list","undefined","leafId","placementIds","toInspectedItems","raw","local","Array","isArray","map","item","position","origin","editable","inspectProperty","descriptor","scopeInstance","grants","configuredValues","currentValue","readNodeValue","path","configured","find","candidate","isCollection","valueType","PropertyValueType","Collection","inspected","effectiveValue","default","ValueSource","Default","get","grantKey","readOnly","editTarget","EditTarget","Node","reason","Instance","operations","items","length","inspect","document","nodeId","context","index","indexDocument","nodes","resolveTemplateChain","scope","computeExposureGrants","catalog","instance","byInstance","configuration","resolveEffectiveConfiguration","instanceContributions","description","describeNode","componentId","components","diagnostics","filter","diagnostic","push","code","DiagnosticCode","UnknownScope","typeId","label","parentId","properties","capabilities","removable"],"mappings":"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"}
1
+ {"version":3,"file":"inspect.js","sources":["../../../editing/inspect.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport {\n DiagnosticCode, DiagnosticSeverity, EditTarget, InspectedCollectionItem, InspectedProperty, NodeInspection,\n NodeProvenance, ProvenanceKind, PropertyDescriptor, PropertyValueType, SceneDiagnostic, SceneDocument, SceneNodeKind, ValueSource,\n} from '@cratis/scene.model';\nimport { describeNode, readNodeValue } from './describeNode';\nimport { EffectiveIconCatalog } from '../icons/EffectiveIconCatalog';\nimport { EditingContext } from './EditingContext';\nimport { computeExposureGrants, ExposureGrant, grantKey } from './exposureGrants';\nimport { iconProblemsOfItems, iconProblemsOfProperty } from './iconDiagnostics';\nimport { indexDocument } from './indexDocument';\nimport { NodeRecord } from './DocumentIndex';\nimport { resolveEffectiveConfiguration } from './resolveEffectiveConfiguration';\nimport { resolveTemplateChain } from './resolveTemplateChain';\nimport { TemplateChain } from './TemplateChain';\n\n/**\n * Works out whether a node is the editing scope's own, and when it is not, where it comes from and whether any of\n * it is configurable here.\n *\n * @param record The node.\n * @param chain The chain the scope sits in.\n * @param scopeGrants What the scope's own instance may configure.\n */\nexport function provenanceOf(record: NodeRecord, chain: TemplateChain, scopeGrants: Map<string, ExposureGrant> | undefined): NodeProvenance {\n const scopeLevel = chain.levels.at(-1);\n if (scopeLevel && record.owner === scopeLevel.owner && record.ownerKind === scopeLevel.kind) return { kind: ProvenanceKind.Local };\n\n const configurable = record.kind === SceneNodeKind.Element\n && [...(scopeGrants?.values() ?? [])].some(grant => grant.component === (record.value as { id: string }).id);\n return { kind: configurable ? ProvenanceKind.ConfigurableInherited : ProvenanceKind.Inherited, source: record.owner };\n}\n\nfunction isRemovable(record: NodeRecord, provenance: NodeProvenance): boolean {\n return provenance.kind === ProvenanceKind.Local\n && (record.list !== undefined || record.leafId !== undefined || record.placementIds !== undefined);\n}\n\nfunction toInspectedItems(raw: unknown, local: boolean): InspectedCollectionItem[] {\n return (Array.isArray(raw) ? raw : []).map((item: Record<string, unknown>, position) => {\n const { id, ...values } = item;\n return { id: typeof id === 'string' ? id : `owner-${position}`, values, origin: 'owner', editable: local };\n });\n}\n\nfunction inspectProperty(\n descriptor: PropertyDescriptor,\n record: NodeRecord,\n provenance: NodeProvenance,\n scopeInstance: string | undefined,\n grants: Map<string, ExposureGrant> | undefined,\n configuredValues: { path: string; value: unknown; source: string; items?: { id: string; values: Record<string, unknown>; origin: string }[] }[] | undefined,\n): InspectedProperty {\n const currentValue = readNodeValue(record, descriptor.path);\n const configured = configuredValues?.find(candidate => candidate.path === descriptor.path);\n const local = provenance.kind === ProvenanceKind.Local;\n const isCollection = descriptor.valueType === PropertyValueType.Collection;\n\n const inspected: InspectedProperty = {\n descriptor,\n currentValue,\n effectiveValue: configured ? configured.value : (currentValue ?? descriptor.default),\n source: (configured?.source ?? (currentValue === undefined ? ValueSource.Default : ValueSource.Local)) as ValueSource,\n editable: false,\n };\n\n const grant = !local && record.kind === SceneNodeKind.Element\n ? grants?.get(grantKey((record.value as { id: string }).id, descriptor.path))\n : undefined;\n\n if (local) {\n inspected.editable = descriptor.readOnly !== true;\n if (inspected.editable) inspected.editTarget = EditTarget.Node;\n else inspected.reason = 'This property is read-only.';\n } else if (grant) {\n inspected.editable = true;\n inspected.editTarget = EditTarget.Instance;\n if (isCollection) inspected.operations = grant.operations;\n } else {\n inspected.reason = `Inherited from '${provenance.source}', which does not expose it.`;\n }\n\n if (isCollection) {\n const items = configured?.items\n ? configured.items.map(item => ({ ...item, editable: local || (item.origin === scopeInstance && grant !== undefined && grant.operations.length > 0) }))\n : toInspectedItems(currentValue, local);\n inspected.items = items;\n }\n\n return inspected;\n}\n\n/**\n * Reports icons the profile cannot supply - on the node itself and in configuration contributed to it. The values\n * stay where they are; these are warnings.\n */\nfunction iconDiagnosticsOf(properties: InspectedProperty[], iconCatalog: EffectiveIconCatalog, nodeId: string): SceneDiagnostic[] {\n return properties.flatMap(property => {\n const descriptor = property.descriptor;\n if (descriptor.valueType !== PropertyValueType.Collection) {\n return iconProblemsOfProperty(iconCatalog, descriptor, property.effectiveValue, DiagnosticSeverity.Warning, { nodeId });\n }\n\n const items = (property.items ?? []).map(item => ({ id: item.id, values: item.values, instance: item.origin === 'owner' ? undefined : item.origin }));\n return iconProblemsOfItems(iconCatalog, descriptor.item, items, DiagnosticSeverity.Warning, { nodeId, path: descriptor.path });\n });\n}\n\n/**\n * Describes one node for an editor: what it is, where it comes from, what can be edited on it - with current and\n * effective values and effective editability - and what can be done with it.\n *\n * A property of a node the scope owns is edited on the node. A property of an inherited node is editable only\n * when its owner exposed it, and then the edit goes to an instance contribution, never into the inherited node.\n * Nothing is mutated.\n *\n * @param document The document to read.\n * @param nodeId The node to describe; see the node id functions.\n * @param context The catalog and the editing scope.\n * @returns The inspection, or `undefined` when the document has no such node.\n */\nexport function inspect(document: SceneDocument, nodeId: string, context: EditingContext): NodeInspection | undefined {\n const index = indexDocument(document);\n const record = index.nodes.get(nodeId);\n if (!record) return undefined;\n\n const chain = resolveTemplateChain(document, context.scope);\n const grants = computeExposureGrants(chain, context.catalog);\n const scopeInstance = chain.levels.at(-1)?.instance;\n const scopeGrants = scopeInstance === undefined ? undefined : grants.byInstance.get(scopeInstance);\n const configuration = resolveEffectiveConfiguration(chain, document.instanceContributions, context.catalog);\n\n const provenance = provenanceOf(record, chain, scopeGrants);\n const description = describeNode(record, context.catalog);\n const componentId = record.kind === SceneNodeKind.Element ? (record.value as { id: string }).id : undefined;\n const configuredValues = configuration.components.find(candidate => candidate.component === componentId)?.values;\n\n const diagnostics: SceneDiagnostic[] = [\n ...description.diagnostics,\n ...configuration.diagnostics.filter(diagnostic => diagnostic.component !== undefined && diagnostic.component === componentId),\n ];\n if (chain.levels.length === 0) {\n diagnostics.push(...chain.diagnostics.filter(diagnostic => diagnostic.code === DiagnosticCode.UnknownScope));\n }\n\n const properties = description.properties.map(descriptor => inspectProperty(descriptor, record, provenance, scopeInstance, scopeGrants, configuredValues));\n if (context.iconCatalog) {\n diagnostics.push(...iconDiagnosticsOf(properties, context.iconCatalog, nodeId));\n }\n\n return {\n nodeId,\n kind: record.kind,\n typeId: record.typeId,\n label: record.label,\n parentId: record.parentId,\n provenance,\n properties,\n capabilities: description.capabilities,\n removable: isRemovable(record, provenance),\n diagnostics,\n };\n}\n"],"names":["provenanceOf","record","chain","scopeGrants","scopeLevel","levels","at","owner","ownerKind","kind","ProvenanceKind","Local","configurable","SceneNodeKind","Element","values","some","grant","component","value","id","ConfigurableInherited","Inherited","source","isRemovable","provenance","list","undefined","leafId","placementIds","toInspectedItems","raw","local","Array","isArray","map","item","position","origin","editable","inspectProperty","descriptor","scopeInstance","grants","configuredValues","currentValue","readNodeValue","path","configured","find","candidate","isCollection","valueType","PropertyValueType","Collection","inspected","effectiveValue","default","ValueSource","Default","get","grantKey","readOnly","editTarget","EditTarget","Node","reason","Instance","operations","items","length","iconDiagnosticsOf","properties","iconCatalog","nodeId","flatMap","property","iconProblemsOfProperty","DiagnosticSeverity","Warning","instance","iconProblemsOfItems","inspect","document","context","index","indexDocument","nodes","resolveTemplateChain","scope","computeExposureGrants","catalog","byInstance","configuration","resolveEffectiveConfiguration","instanceContributions","description","describeNode","componentId","components","diagnostics","filter","diagnostic","push","code","DiagnosticCode","UnknownScope","typeId","label","parentId","capabilities","removable"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"instanceEdits.d.ts","sourceRoot":"","sources":["../../../editing/instanceEdits.ts"],"names":[],"mappings":"AAGA,OAAO,EACH,qBAAqB,EAAwD,sBAAsB,EAChF,wBAAwB,EAAE,yBAAyB,EAAE,sBAAsB,EAAE,eAAe,EAC/G,aAAa,EAAE,oBAAoB,EACtC,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAsG5C,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,oBAAoB,EAAE,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,eAAe,EAAE,GAAG,IAAI,CAclJ;AAKD,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,sBAAsB,EAAE,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,eAAe,EAAE,GAAG,IAAI,CAMtJ;AAKD,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,qBAAqB,EAAE,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,eAAe,EAAE,GAAG,IAAI,CAmCpJ;AAkBD,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,wBAAwB,EAAE,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,eAAe,EAAE,GAAG,IAAI,CAS1J;AAKD,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,yBAAyB,EAAE,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,eAAe,EAAE,GAAG,IAAI,CAiB5J;AAKD,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,sBAAsB,EAAE,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,eAAe,EAAE,GAAG,IAAI,CAYtJ"}
1
+ {"version":3,"file":"instanceEdits.d.ts","sourceRoot":"","sources":["../../../editing/instanceEdits.ts"],"names":[],"mappings":"AAGA,OAAO,EACH,qBAAqB,EAA4E,sBAAsB,EACpG,wBAAwB,EAAE,yBAAyB,EAAE,sBAAsB,EAAE,eAAe,EAC/G,aAAa,EAAE,oBAAoB,EACtC,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AA6G5C,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,oBAAoB,EAAE,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,eAAe,EAAE,GAAG,IAAI,CAclJ;AAKD,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,sBAAsB,EAAE,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,eAAe,EAAE,GAAG,IAAI,CAMtJ;AAKD,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,qBAAqB,EAAE,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,eAAe,EAAE,GAAG,IAAI,CAmCpJ;AAkBD,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,wBAAwB,EAAE,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,eAAe,EAAE,GAAG,IAAI,CAS1J;AAKD,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,yBAAyB,EAAE,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,eAAe,EAAE,GAAG,IAAI,CAiB5J;AAKD,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,sBAAsB,EAAE,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,eAAe,EAAE,GAAG,IAAI,CAYtJ"}
@@ -1,5 +1,6 @@
1
- import { CollectionOperation, DiagnosticCode, PropertyValueType } from '@cratis/scene.model';
2
- import { errorDiagnostic } from './diagnostics.js';
1
+ import { CollectionOperation, DiagnosticCode, PropertyValueType, DiagnosticSeverity } from '@cratis/scene.model';
2
+ import { errorDiagnostic, hasErrors } from './diagnostics.js';
3
+ import { iconProblemsOfItems } from './iconDiagnostics.js';
3
4
  import { grantKey } from './exposureGrants.js';
4
5
  import { cloneData } from './pathAccess.js';
5
6
  import { checkValue } from './propertyEdits.js';
@@ -57,7 +58,7 @@ function permitted(grant, operation, instance, diagnostics) {
57
58
  }
58
59
  return true;
59
60
  }
60
- function checkFields(grant, values, itemId, instance, diagnostics, requireAll) {
61
+ function checkFields(session, grant, values, itemId, instance, diagnostics, requireAll) {
61
62
  const context = {
62
63
  instance,
63
64
  component: grant.component,
@@ -78,6 +79,17 @@ function checkFields(grant, values, itemId, instance, diagnostics, requireAll) {
78
79
  diagnostics.push(errorDiagnostic(problem.problem.startsWith('is not a field') ? DiagnosticCode.UnknownCollectionField : DiagnosticCode.InvalidValue, `'${problem.field}' ${problem.problem}.`, context));
79
80
  valid = false;
80
81
  }
82
+ const icons = session.context.iconCatalog;
83
+ if (icons && valid) {
84
+ const iconProblems = iconProblemsOfItems(icons, itemDescriptor, [
85
+ {
86
+ id: itemId,
87
+ values
88
+ }
89
+ ], DiagnosticSeverity.Error, context);
90
+ diagnostics.push(...iconProblems);
91
+ valid = !hasErrors(iconProblems);
92
+ }
81
93
  return valid;
82
94
  }
83
95
  function ownItems(clone, instance, grant) {
@@ -164,7 +176,7 @@ function save(clone, instance, grant, existing, items) {
164
176
  diagnostics.push(errorDiagnostic(DiagnosticCode.InvalidValue, `'${grant.descriptor.label}' allows at most ${maximum} items.`, context));
165
177
  return;
166
178
  }
167
- if (!checkFields(grant, edit.item.values, edit.item.id, instance, diagnostics, true)) return;
179
+ if (!checkFields(session, grant, edit.item.values, edit.item.id, instance, diagnostics, true)) return;
168
180
  const { contribution, items } = ownItems(clone, instance, grant);
169
181
  if (edit.index !== undefined && (!Number.isInteger(edit.index) || edit.index < 0 || edit.index > items.length)) {
170
182
  diagnostics.push(errorDiagnostic(DiagnosticCode.IndexOutOfRange, `There is no position ${edit.index} among ${items.length} items.`, context));
@@ -231,7 +243,7 @@ function findOwnItem(items, itemId, instance, grant, session, diagnostics) {
231
243
  const { contribution, items } = ownItems(clone, resolved.instance, resolved.grant);
232
244
  const position = findOwnItem(items, edit.itemId, resolved.instance, resolved.grant, session, diagnostics);
233
245
  if (position < 0) return;
234
- if (!checkFields(resolved.grant, {
246
+ if (!checkFields(session, resolved.grant, {
235
247
  [edit.field]: edit.value
236
248
  }, edit.itemId, resolved.instance, diagnostics, false)) return;
237
249
  const next = items.map((item, index)=>index === position ? {
@@ -1 +1 @@
1
- {"version":3,"file":"instanceEdits.js","sources":["../../../editing/instanceEdits.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 AddCollectionItemEdit, CollectionOperation, ContributedItem, DiagnosticCode, EditCollectionItemEdit, InstanceContribution,\n PropertyValueType, RemoveCollectionItemEdit, ReorderCollectionItemEdit, ResetInstanceValueEdit, SceneDiagnostic,\n SceneDocument, SetInstanceValueEdit,\n} from '@cratis/scene.model';\nimport { errorDiagnostic } from './diagnostics';\nimport { EditSession } from './EditSession';\nimport { ExposureGrant, grantKey } from './exposureGrants';\nimport { cloneData } from './pathAccess';\nimport { checkValue } from './propertyEdits';\nimport { validateItemValues } from './validateValue';\n\ninterface InstanceEditTarget {\n instance: string;\n component: string;\n path: string;\n}\n\nfunction resolveGrant(session: EditSession, edit: InstanceEditTarget & { instance?: string }, diagnostics: SceneDiagnostic[]): { instance: string; grant: ExposureGrant } | undefined {\n const context = { instance: edit.instance, component: edit.component, path: edit.path };\n const instance = session.scopeInstance;\n if (instance === undefined) {\n diagnostics.push(errorDiagnostic(DiagnosticCode.UnknownScope, `There is no ${session.context.scope.kind} named '${session.context.scope.name}'.`, context));\n return undefined;\n }\n\n if (edit.instance !== undefined && edit.instance !== instance) {\n diagnostics.push(errorDiagnostic(DiagnosticCode.UnknownInstance, `Edits are made as '${instance}', not as '${edit.instance}'.`, context));\n return undefined;\n }\n\n const grant = session.scopeGrants.get(grantKey(edit.component, edit.path));\n if (!grant) {\n diagnostics.push(errorDiagnostic(\n DiagnosticCode.ContributionNotExposed,\n `'${edit.path}' on '${edit.component}' is not exposed to '${instance}'. An owner exposes it, and each template between re-exposes it.`,\n { ...context, instance }));\n return undefined;\n }\n\n return { instance, grant };\n}\n\nfunction findContribution(clone: SceneDocument, instance: string, component: string, path: string): InstanceContribution | undefined {\n return clone.instanceContributions.find(contribution =>\n contribution.instance === instance && contribution.component === component && contribution.path === path);\n}\n\nfunction permitted(grant: ExposureGrant, operation: CollectionOperation, instance: string, diagnostics: SceneDiagnostic[]): boolean {\n if (grant.descriptor.valueType !== PropertyValueType.Collection) {\n diagnostics.push(errorDiagnostic(DiagnosticCode.InvalidEdit, `'${grant.descriptor.label}' is not a collection.`, { instance, component: grant.component, path: grant.path }));\n return false;\n }\n\n if (!grant.operations.includes(operation)) {\n diagnostics.push(errorDiagnostic(\n DiagnosticCode.ContributionOperationNotPermitted,\n `'${grant.descriptor.label}' does not allow '${operation}' from '${instance}'.`,\n { instance, component: grant.component, path: grant.path }));\n return false;\n }\n\n return true;\n}\n\nfunction checkFields(grant: ExposureGrant, values: Record<string, unknown>, itemId: string, instance: string, diagnostics: SceneDiagnostic[], requireAll: boolean): boolean {\n const context = { instance, component: grant.component, path: grant.path, itemId };\n let valid = true;\n\n for (const field of Object.keys(values)) {\n const known = grant.descriptor.item?.properties.some(candidate => candidate.path === field) ?? false;\n if (known && grant.editableFields !== undefined && !grant.editableFields.includes(field)) {\n diagnostics.push(errorDiagnostic(DiagnosticCode.ContributionOperationNotPermitted, `The field '${field}' of '${grant.descriptor.label}' is not exposed for editing.`, context));\n valid = false;\n }\n }\n\n const itemDescriptor = grant.descriptor.item;\n const problems = validateItemValues(itemDescriptor, values).filter(problem => requireAll || problem.problem !== 'a value is required');\n for (const problem of problems) {\n diagnostics.push(errorDiagnostic(\n problem.problem.startsWith('is not a field') ? DiagnosticCode.UnknownCollectionField : DiagnosticCode.InvalidValue,\n `'${problem.field}' ${problem.problem}.`,\n context));\n valid = false;\n }\n\n return valid;\n}\n\nfunction ownItems(clone: SceneDocument, instance: string, grant: ExposureGrant): { contribution: InstanceContribution | undefined; items: ContributedItem[] } {\n const contribution = findContribution(clone, instance, grant.component, grant.path);\n return { contribution, items: contribution?.items ?? [] };\n}\n\nfunction save(clone: SceneDocument, instance: string, grant: ExposureGrant, existing: InstanceContribution | undefined, items: ContributedItem[]): void {\n if (items.length === 0) {\n if (existing) clone.instanceContributions.splice(clone.instanceContributions.indexOf(existing), 1);\n return;\n }\n\n if (existing) existing.items = items;\n else clone.instanceContributions.push({ instance, component: grant.component, path: grant.path, items });\n}\n\n/**\n * Applies a scalar value set from the editing scope's instance to a copy of the document.\n */\nexport function applySetInstanceValue(session: EditSession, edit: SetInstanceValueEdit, clone: SceneDocument, diagnostics: SceneDiagnostic[]): void {\n const resolved = resolveGrant(session, { ...edit, instance: edit.instance } as InstanceEditTarget, diagnostics);\n if (!resolved) return;\n\n if (resolved.grant.descriptor.valueType === PropertyValueType.Collection) {\n diagnostics.push(errorDiagnostic(DiagnosticCode.InvalidEdit, `'${resolved.grant.descriptor.label}' is a collection; add, remove, reorder and edit its items instead.`, { instance: resolved.instance, component: edit.component, path: edit.path }));\n return;\n }\n\n if (!checkValue(session, resolved.grant.descriptor, edit.value, { component: edit.component, instance: resolved.instance }, diagnostics)) return;\n\n const existing = findContribution(clone, resolved.instance, edit.component, edit.path);\n if (existing) existing.value = cloneData(edit.value);\n else clone.instanceContributions.push({ instance: resolved.instance, component: edit.component, path: edit.path, value: cloneData(edit.value) });\n}\n\n/**\n * Applies a reset to a copy of the document: the instance's contribution is removed, so the inherited value applies.\n */\nexport function applyResetInstanceValue(session: EditSession, edit: ResetInstanceValueEdit, clone: SceneDocument, diagnostics: SceneDiagnostic[]): void {\n const resolved = resolveGrant(session, edit as InstanceEditTarget, diagnostics);\n if (!resolved) return;\n\n const existing = findContribution(clone, resolved.instance, edit.component, edit.path);\n if (existing) clone.instanceContributions.splice(clone.instanceContributions.indexOf(existing), 1);\n}\n\n/**\n * Applies an item addition to a copy of the document.\n */\nexport function applyAddCollectionItem(session: EditSession, edit: AddCollectionItemEdit, clone: SceneDocument, diagnostics: SceneDiagnostic[]): void {\n const resolved = resolveGrant(session, edit as InstanceEditTarget, diagnostics);\n if (!resolved || !permitted(resolved.grant, CollectionOperation.Add, resolved.instance, diagnostics)) return;\n\n const { grant, instance } = resolved;\n const context = { instance, component: edit.component, path: edit.path, itemId: edit.item.id };\n if (typeof edit.item.id !== 'string' || edit.item.id.length === 0) {\n diagnostics.push(errorDiagnostic(DiagnosticCode.InvalidValue, 'An item needs an id.', context));\n return;\n }\n\n const effective = session.configuration.components.find(candidate => candidate.component === edit.component)?.values.find(value => value.path === edit.path);\n const existingItems = effective?.items ?? [];\n if (existingItems.some(item => item.id === edit.item.id)) {\n diagnostics.push(errorDiagnostic(DiagnosticCode.DuplicateCollectionItem, `The item id '${edit.item.id}' is already used.`, context));\n return;\n }\n\n const maximum = grant.descriptor.constraints?.maximumItems;\n if (maximum !== undefined && existingItems.length >= maximum) {\n diagnostics.push(errorDiagnostic(DiagnosticCode.InvalidValue, `'${grant.descriptor.label}' allows at most ${maximum} items.`, context));\n return;\n }\n\n if (!checkFields(grant, edit.item.values, edit.item.id, instance, diagnostics, true)) return;\n\n const { contribution, items } = ownItems(clone, instance, grant);\n if (edit.index !== undefined && (!Number.isInteger(edit.index) || edit.index < 0 || edit.index > items.length)) {\n diagnostics.push(errorDiagnostic(DiagnosticCode.IndexOutOfRange, `There is no position ${edit.index} among ${items.length} items.`, context));\n return;\n }\n\n const next = [...items];\n next.splice(edit.index ?? next.length, 0, cloneData(edit.item));\n save(clone, instance, grant, contribution, next);\n}\n\nfunction findOwnItem(items: ContributedItem[], itemId: string, instance: string, grant: ExposureGrant, session: EditSession, diagnostics: SceneDiagnostic[]): number {\n const position = items.findIndex(item => item.id === itemId);\n if (position >= 0) return position;\n\n const effective = session.configuration.components.find(candidate => candidate.component === grant.component)?.values.find(value => value.path === grant.path);\n const fixed = effective?.items?.find(item => item.id === itemId);\n diagnostics.push(errorDiagnostic(\n fixed ? DiagnosticCode.ContributionOperationNotPermitted : DiagnosticCode.CollectionItemNotFound,\n fixed ? `The item '${itemId}' belongs to '${fixed.origin}' and cannot be changed from '${instance}'.` : `'${instance}' has no item '${itemId}' in '${grant.descriptor.label}'.`,\n { instance, component: grant.component, path: grant.path, itemId }));\n return -1;\n}\n\n/**\n * Applies an item removal to a copy of the document.\n */\nexport function applyRemoveCollectionItem(session: EditSession, edit: RemoveCollectionItemEdit, clone: SceneDocument, diagnostics: SceneDiagnostic[]): void {\n const resolved = resolveGrant(session, edit as InstanceEditTarget, diagnostics);\n if (!resolved || !permitted(resolved.grant, CollectionOperation.Remove, resolved.instance, diagnostics)) return;\n\n const { contribution, items } = ownItems(clone, resolved.instance, resolved.grant);\n const position = findOwnItem(items, edit.itemId, resolved.instance, resolved.grant, session, diagnostics);\n if (position < 0) return;\n\n save(clone, resolved.instance, resolved.grant, contribution, items.filter((_, index) => index !== position));\n}\n\n/**\n * Applies an item reorder to a copy of the document.\n */\nexport function applyReorderCollectionItem(session: EditSession, edit: ReorderCollectionItemEdit, clone: SceneDocument, diagnostics: SceneDiagnostic[]): void {\n const resolved = resolveGrant(session, edit as InstanceEditTarget, diagnostics);\n if (!resolved || !permitted(resolved.grant, CollectionOperation.Reorder, resolved.instance, diagnostics)) return;\n\n const { contribution, items } = ownItems(clone, resolved.instance, resolved.grant);\n const position = findOwnItem(items, edit.itemId, resolved.instance, resolved.grant, session, diagnostics);\n if (position < 0) return;\n\n if (!Number.isInteger(edit.index) || edit.index < 0 || edit.index >= items.length) {\n diagnostics.push(errorDiagnostic(DiagnosticCode.IndexOutOfRange, `There is no position ${edit.index} among ${items.length} items.`, { instance: resolved.instance, component: edit.component, path: edit.path, itemId: edit.itemId }));\n return;\n }\n\n const next = [...items];\n const [moved] = next.splice(position, 1);\n next.splice(edit.index, 0, moved);\n save(clone, resolved.instance, resolved.grant, contribution, next);\n}\n\n/**\n * Applies an item field change to a copy of the document.\n */\nexport function applyEditCollectionItem(session: EditSession, edit: EditCollectionItemEdit, clone: SceneDocument, diagnostics: SceneDiagnostic[]): void {\n const resolved = resolveGrant(session, edit as InstanceEditTarget, diagnostics);\n if (!resolved || !permitted(resolved.grant, CollectionOperation.EditFields, resolved.instance, diagnostics)) return;\n\n const { contribution, items } = ownItems(clone, resolved.instance, resolved.grant);\n const position = findOwnItem(items, edit.itemId, resolved.instance, resolved.grant, session, diagnostics);\n if (position < 0) return;\n\n if (!checkFields(resolved.grant, { [edit.field]: edit.value }, edit.itemId, resolved.instance, diagnostics, false)) return;\n\n const next = items.map((item, index) => index === position ? { ...item, values: { ...item.values, [edit.field]: cloneData(edit.value) } } : item);\n save(clone, resolved.instance, resolved.grant, contribution, next);\n}\n"],"names":["resolveGrant","session","edit","diagnostics","context","instance","component","path","scopeInstance","undefined","push","errorDiagnostic","DiagnosticCode","UnknownScope","scope","kind","name","UnknownInstance","grant","scopeGrants","get","grantKey","ContributionNotExposed","findContribution","clone","instanceContributions","find","contribution","permitted","operation","descriptor","valueType","PropertyValueType","Collection","InvalidEdit","label","operations","includes","ContributionOperationNotPermitted","checkFields","values","itemId","requireAll","valid","field","Object","keys","known","item","properties","some","candidate","editableFields","itemDescriptor","problems","validateItemValues","filter","problem","startsWith","UnknownCollectionField","InvalidValue","ownItems","items","save","existing","length","splice","indexOf","applySetInstanceValue","resolved","checkValue","value","cloneData","applyResetInstanceValue","applyAddCollectionItem","CollectionOperation","Add","id","effective","configuration","components","existingItems","DuplicateCollectionItem","maximum","constraints","maximumItems","index","Number","isInteger","IndexOutOfRange","next","findOwnItem","position","findIndex","fixed","CollectionItemNotFound","origin","applyRemoveCollectionItem","Remove","_","applyReorderCollectionItem","Reorder","moved","applyEditCollectionItem","EditFields","map"],"mappings":"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"}
1
+ {"version":3,"file":"instanceEdits.js","sources":["../../../editing/instanceEdits.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 AddCollectionItemEdit, CollectionOperation, ContributedItem, DiagnosticCode, DiagnosticSeverity, EditCollectionItemEdit, InstanceContribution,\n PropertyValueType, RemoveCollectionItemEdit, ReorderCollectionItemEdit, ResetInstanceValueEdit, SceneDiagnostic,\n SceneDocument, SetInstanceValueEdit,\n} from '@cratis/scene.model';\nimport { errorDiagnostic, hasErrors } from './diagnostics';\nimport { iconProblemsOfItems } from './iconDiagnostics';\nimport { EditSession } from './EditSession';\nimport { ExposureGrant, grantKey } from './exposureGrants';\nimport { cloneData } from './pathAccess';\nimport { checkValue } from './propertyEdits';\nimport { validateItemValues } from './validateValue';\n\ninterface InstanceEditTarget {\n instance: string;\n component: string;\n path: string;\n}\n\nfunction resolveGrant(session: EditSession, edit: InstanceEditTarget & { instance?: string }, diagnostics: SceneDiagnostic[]): { instance: string; grant: ExposureGrant } | undefined {\n const context = { instance: edit.instance, component: edit.component, path: edit.path };\n const instance = session.scopeInstance;\n if (instance === undefined) {\n diagnostics.push(errorDiagnostic(DiagnosticCode.UnknownScope, `There is no ${session.context.scope.kind} named '${session.context.scope.name}'.`, context));\n return undefined;\n }\n\n if (edit.instance !== undefined && edit.instance !== instance) {\n diagnostics.push(errorDiagnostic(DiagnosticCode.UnknownInstance, `Edits are made as '${instance}', not as '${edit.instance}'.`, context));\n return undefined;\n }\n\n const grant = session.scopeGrants.get(grantKey(edit.component, edit.path));\n if (!grant) {\n diagnostics.push(errorDiagnostic(\n DiagnosticCode.ContributionNotExposed,\n `'${edit.path}' on '${edit.component}' is not exposed to '${instance}'. An owner exposes it, and each template between re-exposes it.`,\n { ...context, instance }));\n return undefined;\n }\n\n return { instance, grant };\n}\n\nfunction findContribution(clone: SceneDocument, instance: string, component: string, path: string): InstanceContribution | undefined {\n return clone.instanceContributions.find(contribution =>\n contribution.instance === instance && contribution.component === component && contribution.path === path);\n}\n\nfunction permitted(grant: ExposureGrant, operation: CollectionOperation, instance: string, diagnostics: SceneDiagnostic[]): boolean {\n if (grant.descriptor.valueType !== PropertyValueType.Collection) {\n diagnostics.push(errorDiagnostic(DiagnosticCode.InvalidEdit, `'${grant.descriptor.label}' is not a collection.`, { instance, component: grant.component, path: grant.path }));\n return false;\n }\n\n if (!grant.operations.includes(operation)) {\n diagnostics.push(errorDiagnostic(\n DiagnosticCode.ContributionOperationNotPermitted,\n `'${grant.descriptor.label}' does not allow '${operation}' from '${instance}'.`,\n { instance, component: grant.component, path: grant.path }));\n return false;\n }\n\n return true;\n}\n\nfunction checkFields(session: EditSession, grant: ExposureGrant, values: Record<string, unknown>, itemId: string, instance: string, diagnostics: SceneDiagnostic[], requireAll: boolean): boolean {\n const context = { instance, component: grant.component, path: grant.path, itemId };\n let valid = true;\n\n for (const field of Object.keys(values)) {\n const known = grant.descriptor.item?.properties.some(candidate => candidate.path === field) ?? false;\n if (known && grant.editableFields !== undefined && !grant.editableFields.includes(field)) {\n diagnostics.push(errorDiagnostic(DiagnosticCode.ContributionOperationNotPermitted, `The field '${field}' of '${grant.descriptor.label}' is not exposed for editing.`, context));\n valid = false;\n }\n }\n\n const itemDescriptor = grant.descriptor.item;\n const problems = validateItemValues(itemDescriptor, values).filter(problem => requireAll || problem.problem !== 'a value is required');\n for (const problem of problems) {\n diagnostics.push(errorDiagnostic(\n problem.problem.startsWith('is not a field') ? DiagnosticCode.UnknownCollectionField : DiagnosticCode.InvalidValue,\n `'${problem.field}' ${problem.problem}.`,\n context));\n valid = false;\n }\n\n const icons = session.context.iconCatalog;\n if (icons && valid) {\n const iconProblems = iconProblemsOfItems(icons, itemDescriptor, [{ id: itemId, values }], DiagnosticSeverity.Error, context);\n diagnostics.push(...iconProblems);\n valid = !hasErrors(iconProblems);\n }\n\n return valid;\n}\n\nfunction ownItems(clone: SceneDocument, instance: string, grant: ExposureGrant): { contribution: InstanceContribution | undefined; items: ContributedItem[] } {\n const contribution = findContribution(clone, instance, grant.component, grant.path);\n return { contribution, items: contribution?.items ?? [] };\n}\n\nfunction save(clone: SceneDocument, instance: string, grant: ExposureGrant, existing: InstanceContribution | undefined, items: ContributedItem[]): void {\n if (items.length === 0) {\n if (existing) clone.instanceContributions.splice(clone.instanceContributions.indexOf(existing), 1);\n return;\n }\n\n if (existing) existing.items = items;\n else clone.instanceContributions.push({ instance, component: grant.component, path: grant.path, items });\n}\n\n/**\n * Applies a scalar value set from the editing scope's instance to a copy of the document.\n */\nexport function applySetInstanceValue(session: EditSession, edit: SetInstanceValueEdit, clone: SceneDocument, diagnostics: SceneDiagnostic[]): void {\n const resolved = resolveGrant(session, { ...edit, instance: edit.instance } as InstanceEditTarget, diagnostics);\n if (!resolved) return;\n\n if (resolved.grant.descriptor.valueType === PropertyValueType.Collection) {\n diagnostics.push(errorDiagnostic(DiagnosticCode.InvalidEdit, `'${resolved.grant.descriptor.label}' is a collection; add, remove, reorder and edit its items instead.`, { instance: resolved.instance, component: edit.component, path: edit.path }));\n return;\n }\n\n if (!checkValue(session, resolved.grant.descriptor, edit.value, { component: edit.component, instance: resolved.instance }, diagnostics)) return;\n\n const existing = findContribution(clone, resolved.instance, edit.component, edit.path);\n if (existing) existing.value = cloneData(edit.value);\n else clone.instanceContributions.push({ instance: resolved.instance, component: edit.component, path: edit.path, value: cloneData(edit.value) });\n}\n\n/**\n * Applies a reset to a copy of the document: the instance's contribution is removed, so the inherited value applies.\n */\nexport function applyResetInstanceValue(session: EditSession, edit: ResetInstanceValueEdit, clone: SceneDocument, diagnostics: SceneDiagnostic[]): void {\n const resolved = resolveGrant(session, edit as InstanceEditTarget, diagnostics);\n if (!resolved) return;\n\n const existing = findContribution(clone, resolved.instance, edit.component, edit.path);\n if (existing) clone.instanceContributions.splice(clone.instanceContributions.indexOf(existing), 1);\n}\n\n/**\n * Applies an item addition to a copy of the document.\n */\nexport function applyAddCollectionItem(session: EditSession, edit: AddCollectionItemEdit, clone: SceneDocument, diagnostics: SceneDiagnostic[]): void {\n const resolved = resolveGrant(session, edit as InstanceEditTarget, diagnostics);\n if (!resolved || !permitted(resolved.grant, CollectionOperation.Add, resolved.instance, diagnostics)) return;\n\n const { grant, instance } = resolved;\n const context = { instance, component: edit.component, path: edit.path, itemId: edit.item.id };\n if (typeof edit.item.id !== 'string' || edit.item.id.length === 0) {\n diagnostics.push(errorDiagnostic(DiagnosticCode.InvalidValue, 'An item needs an id.', context));\n return;\n }\n\n const effective = session.configuration.components.find(candidate => candidate.component === edit.component)?.values.find(value => value.path === edit.path);\n const existingItems = effective?.items ?? [];\n if (existingItems.some(item => item.id === edit.item.id)) {\n diagnostics.push(errorDiagnostic(DiagnosticCode.DuplicateCollectionItem, `The item id '${edit.item.id}' is already used.`, context));\n return;\n }\n\n const maximum = grant.descriptor.constraints?.maximumItems;\n if (maximum !== undefined && existingItems.length >= maximum) {\n diagnostics.push(errorDiagnostic(DiagnosticCode.InvalidValue, `'${grant.descriptor.label}' allows at most ${maximum} items.`, context));\n return;\n }\n\n if (!checkFields(session, grant, edit.item.values, edit.item.id, instance, diagnostics, true)) return;\n\n const { contribution, items } = ownItems(clone, instance, grant);\n if (edit.index !== undefined && (!Number.isInteger(edit.index) || edit.index < 0 || edit.index > items.length)) {\n diagnostics.push(errorDiagnostic(DiagnosticCode.IndexOutOfRange, `There is no position ${edit.index} among ${items.length} items.`, context));\n return;\n }\n\n const next = [...items];\n next.splice(edit.index ?? next.length, 0, cloneData(edit.item));\n save(clone, instance, grant, contribution, next);\n}\n\nfunction findOwnItem(items: ContributedItem[], itemId: string, instance: string, grant: ExposureGrant, session: EditSession, diagnostics: SceneDiagnostic[]): number {\n const position = items.findIndex(item => item.id === itemId);\n if (position >= 0) return position;\n\n const effective = session.configuration.components.find(candidate => candidate.component === grant.component)?.values.find(value => value.path === grant.path);\n const fixed = effective?.items?.find(item => item.id === itemId);\n diagnostics.push(errorDiagnostic(\n fixed ? DiagnosticCode.ContributionOperationNotPermitted : DiagnosticCode.CollectionItemNotFound,\n fixed ? `The item '${itemId}' belongs to '${fixed.origin}' and cannot be changed from '${instance}'.` : `'${instance}' has no item '${itemId}' in '${grant.descriptor.label}'.`,\n { instance, component: grant.component, path: grant.path, itemId }));\n return -1;\n}\n\n/**\n * Applies an item removal to a copy of the document.\n */\nexport function applyRemoveCollectionItem(session: EditSession, edit: RemoveCollectionItemEdit, clone: SceneDocument, diagnostics: SceneDiagnostic[]): void {\n const resolved = resolveGrant(session, edit as InstanceEditTarget, diagnostics);\n if (!resolved || !permitted(resolved.grant, CollectionOperation.Remove, resolved.instance, diagnostics)) return;\n\n const { contribution, items } = ownItems(clone, resolved.instance, resolved.grant);\n const position = findOwnItem(items, edit.itemId, resolved.instance, resolved.grant, session, diagnostics);\n if (position < 0) return;\n\n save(clone, resolved.instance, resolved.grant, contribution, items.filter((_, index) => index !== position));\n}\n\n/**\n * Applies an item reorder to a copy of the document.\n */\nexport function applyReorderCollectionItem(session: EditSession, edit: ReorderCollectionItemEdit, clone: SceneDocument, diagnostics: SceneDiagnostic[]): void {\n const resolved = resolveGrant(session, edit as InstanceEditTarget, diagnostics);\n if (!resolved || !permitted(resolved.grant, CollectionOperation.Reorder, resolved.instance, diagnostics)) return;\n\n const { contribution, items } = ownItems(clone, resolved.instance, resolved.grant);\n const position = findOwnItem(items, edit.itemId, resolved.instance, resolved.grant, session, diagnostics);\n if (position < 0) return;\n\n if (!Number.isInteger(edit.index) || edit.index < 0 || edit.index >= items.length) {\n diagnostics.push(errorDiagnostic(DiagnosticCode.IndexOutOfRange, `There is no position ${edit.index} among ${items.length} items.`, { instance: resolved.instance, component: edit.component, path: edit.path, itemId: edit.itemId }));\n return;\n }\n\n const next = [...items];\n const [moved] = next.splice(position, 1);\n next.splice(edit.index, 0, moved);\n save(clone, resolved.instance, resolved.grant, contribution, next);\n}\n\n/**\n * Applies an item field change to a copy of the document.\n */\nexport function applyEditCollectionItem(session: EditSession, edit: EditCollectionItemEdit, clone: SceneDocument, diagnostics: SceneDiagnostic[]): void {\n const resolved = resolveGrant(session, edit as InstanceEditTarget, diagnostics);\n if (!resolved || !permitted(resolved.grant, CollectionOperation.EditFields, resolved.instance, diagnostics)) return;\n\n const { contribution, items } = ownItems(clone, resolved.instance, resolved.grant);\n const position = findOwnItem(items, edit.itemId, resolved.instance, resolved.grant, session, diagnostics);\n if (position < 0) return;\n\n if (!checkFields(session, resolved.grant, { [edit.field]: edit.value }, edit.itemId, resolved.instance, diagnostics, false)) return;\n\n const next = items.map((item, index) => index === position ? { ...item, values: { ...item.values, [edit.field]: cloneData(edit.value) } } : item);\n save(clone, resolved.instance, resolved.grant, contribution, next);\n}\n"],"names":["resolveGrant","session","edit","diagnostics","context","instance","component","path","scopeInstance","undefined","push","errorDiagnostic","DiagnosticCode","UnknownScope","scope","kind","name","UnknownInstance","grant","scopeGrants","get","grantKey","ContributionNotExposed","findContribution","clone","instanceContributions","find","contribution","permitted","operation","descriptor","valueType","PropertyValueType","Collection","InvalidEdit","label","operations","includes","ContributionOperationNotPermitted","checkFields","values","itemId","requireAll","valid","field","Object","keys","known","item","properties","some","candidate","editableFields","itemDescriptor","problems","validateItemValues","filter","problem","startsWith","UnknownCollectionField","InvalidValue","icons","iconCatalog","iconProblems","iconProblemsOfItems","id","DiagnosticSeverity","Error","hasErrors","ownItems","items","save","existing","length","splice","indexOf","applySetInstanceValue","resolved","checkValue","value","cloneData","applyResetInstanceValue","applyAddCollectionItem","CollectionOperation","Add","effective","configuration","components","existingItems","DuplicateCollectionItem","maximum","constraints","maximumItems","index","Number","isInteger","IndexOutOfRange","next","findOwnItem","position","findIndex","fixed","CollectionItemNotFound","origin","applyRemoveCollectionItem","Remove","_","applyReorderCollectionItem","Reorder","moved","applyEditCollectionItem","EditFields","map"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"propertyEdits.d.ts","sourceRoot":"","sources":["../../../editing/propertyEdits.ts"],"names":[],"mappings":"AAGA,OAAO,EACa,kBAAkB,EAAmC,iBAAiB,EAAE,eAAe,EAAE,aAAa,EACvG,eAAe,EACjC,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAQ5C,wBAAgB,uBAAuB,CACnC,OAAO,EAAE,WAAW,EACpB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,eAAe,EAAE,GAC/B;IAAE,MAAM,EAAE,UAAU,CAAC;IAAC,UAAU,EAAE,kBAAkB,CAAA;CAAE,GAAG,SAAS,CA+BpE;AAOD,wBAAgB,UAAU,CAAC,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,kBAAkB,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,EAAE,WAAW,EAAE,eAAe,EAAE,GAAG,OAAO,CAgB7M;AAaD,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,eAAe,EAAE,GAAG,IAAI,CASxI;AAKD,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,iBAAiB,EAAE,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,eAAe,EAAE,GAAG,IAAI,CAa5I"}
1
+ {"version":3,"file":"propertyEdits.d.ts","sourceRoot":"","sources":["../../../editing/propertyEdits.ts"],"names":[],"mappings":"AAGA,OAAO,EACiC,kBAAkB,EAAmC,iBAAiB,EAAE,eAAe,EAAE,aAAa,EAC3H,eAAe,EACjC,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAS5C,wBAAgB,uBAAuB,CACnC,OAAO,EAAE,WAAW,EACpB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,eAAe,EAAE,GAC/B;IAAE,MAAM,EAAE,UAAU,CAAC;IAAC,UAAU,EAAE,kBAAkB,CAAA;CAAE,GAAG,SAAS,CA+BpE;AAOD,wBAAgB,UAAU,CAAC,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,kBAAkB,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,EAAE,WAAW,EAAE,eAAe,EAAE,GAAG,OAAO,CAuB7M;AAaD,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,eAAe,EAAE,GAAG,IAAI,CASxI;AAKD,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,iBAAiB,EAAE,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,eAAe,EAAE,GAAG,IAAI,CAa5I"}
@@ -1,7 +1,8 @@
1
- import { DiagnosticCode, PropertyValueType, SceneNodeKind } from '@cratis/scene.model';
1
+ import { DiagnosticCode, PropertyValueType, DiagnosticSeverity, SceneNodeKind } from '@cratis/scene.model';
2
2
  import { describeNode } from './describeNode.js';
3
- import { errorDiagnostic } from './diagnostics.js';
3
+ import { errorDiagnostic, hasErrors } from './diagnostics.js';
4
4
  import { mirroredPaths, getAtPath } from './documentPaths.js';
5
+ import { iconProblemsOfProperty } from './iconDiagnostics.js';
5
6
  import { removeValueAtPath, setValueAtPath, cloneData } from './pathAccess.js';
6
7
  import { validateBinding } from './validateBinding.js';
7
8
  import { validateValue } from './validateValue.js';
@@ -69,6 +70,12 @@ import { validateValue } from './validateValue.js';
69
70
  })));
70
71
  return problems.length === 0;
71
72
  }
73
+ const icons = session.context.iconCatalog;
74
+ if (icons) {
75
+ const problems = iconProblemsOfProperty(icons, descriptor, value, DiagnosticSeverity.Error, context);
76
+ diagnostics.push(...problems);
77
+ return !hasErrors(problems);
78
+ }
72
79
  return true;
73
80
  }
74
81
  function bagFor(root, record, path) {
@@ -1 +1 @@
1
- {"version":3,"file":"propertyEdits.js","sources":["../../../editing/propertyEdits.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, PropertyDescriptor, PropertyValueType, QueryBinding, ResetPropertyEdit, SceneDiagnostic, SceneDocument,\n SceneNodeKind, SetPropertyEdit,\n} from '@cratis/scene.model';\nimport { describeNode } from './describeNode';\nimport { errorDiagnostic } from './diagnostics';\nimport { NodeRecord } from './DocumentIndex';\nimport { getAtPath, mirroredPaths } from './documentPaths';\nimport { EditSession } from './EditSession';\nimport { cloneData, removeValueAtPath, setValueAtPath } from './pathAccess';\nimport { validateBinding } from './validateBinding';\nimport { validateValue } from './validateValue';\n\n/**\n * Finds the node and descriptor an edit of a property addresses, or says why it cannot.\n */\nexport function resolveEditableProperty(\n session: EditSession,\n nodeId: string,\n path: string,\n diagnostics: SceneDiagnostic[],\n): { record: NodeRecord; descriptor: PropertyDescriptor } | undefined {\n const record = session.index.nodes.get(nodeId);\n if (!record) {\n diagnostics.push(errorDiagnostic(DiagnosticCode.UnknownNode, `There is no node '${nodeId}'.`, { nodeId }));\n return undefined;\n }\n\n if (!session.isLocal(record)) {\n diagnostics.push(errorDiagnostic(\n DiagnosticCode.NodeNotEditable,\n `'${nodeId}' is inherited from '${session.sourceOf(record)}'. An exposed property is configured with an instance edit, not by changing the node.`,\n { nodeId, path }));\n return undefined;\n }\n\n const description = describeNode(record, session.context.catalog);\n const descriptor = description.properties.find(candidate => candidate.path === path);\n if (!descriptor) {\n diagnostics.push(errorDiagnostic(\n description.diagnostics.length > 0 ? DiagnosticCode.MissingComponentDescriptor : DiagnosticCode.UnknownProperty,\n description.diagnostics[0]?.message ?? `'${record.typeId}' has no property '${path}'.`,\n { nodeId, path }));\n return undefined;\n }\n\n if (descriptor.readOnly) {\n diagnostics.push(errorDiagnostic(DiagnosticCode.ReadOnlyProperty, `'${descriptor.label}' is read-only.`, { nodeId, path }));\n return undefined;\n }\n\n return { record, descriptor };\n}\n\n/**\n * Checks a value for a property, including a query binding against the host's candidates.\n *\n * @returns Whether the value is acceptable; the reasons are added to `diagnostics`.\n */\nexport function checkValue(session: EditSession, descriptor: PropertyDescriptor, value: unknown, context: { nodeId?: string; component?: string; instance?: string }, diagnostics: SceneDiagnostic[]): boolean {\n const problem = validateValue(descriptor, value);\n if (problem) {\n diagnostics.push(errorDiagnostic(DiagnosticCode.InvalidValue, `'${descriptor.label}': ${problem}.`, { ...context, path: descriptor.path }));\n return false;\n }\n\n const candidates = session.context.queryCandidates;\n if (descriptor.valueType === PropertyValueType.QueryReference && candidates && typeof value === 'object' && value !== null) {\n const binding = value as QueryBinding;\n const problems = validateBinding(descriptor, candidates.find(candidate => candidate.id === binding.queryId), binding);\n diagnostics.push(...problems.map(problemDiagnostic => ({ ...problemDiagnostic, ...context })));\n return problems.length === 0;\n }\n\n return true;\n}\n\nfunction bagFor(root: SceneDocument, record: NodeRecord, path: string[]): Record<string, unknown> | undefined {\n const target = getAtPath(root, path) as Record<string, unknown> | undefined;\n if (!target) return undefined;\n const isComponent = record.kind === SceneNodeKind.Element && target.componentName !== undefined;\n if (!isComponent) return target;\n return (target.properties ??= {}) as Record<string, unknown>;\n}\n\n/**\n * Applies a property set to a copy of the document.\n */\nexport function applySetProperty(session: EditSession, edit: SetPropertyEdit, clone: SceneDocument, diagnostics: SceneDiagnostic[]): void {\n const resolved = resolveEditableProperty(session, edit.nodeId, edit.path, diagnostics);\n if (!resolved) return;\n if (!checkValue(session, resolved.descriptor, edit.value, { nodeId: edit.nodeId }, diagnostics)) return;\n\n for (const path of mirroredPaths(resolved.record.mirror, resolved.record.path)) {\n const bag = bagFor(clone, resolved.record, path as string[]);\n if (bag) setValueAtPath(bag, edit.path, cloneData(edit.value));\n }\n}\n\n/**\n * Applies a property reset to a copy of the document.\n */\nexport function applyResetProperty(session: EditSession, edit: ResetPropertyEdit, clone: SceneDocument, diagnostics: SceneDiagnostic[]): void {\n const resolved = resolveEditableProperty(session, edit.nodeId, edit.path, diagnostics);\n if (!resolved) return;\n\n if (resolved.descriptor.constraints?.required && resolved.descriptor.default === undefined) {\n diagnostics.push(errorDiagnostic(DiagnosticCode.InvalidValue, `'${resolved.descriptor.label}' is required and has no default to go back to.`, { nodeId: edit.nodeId, path: edit.path }));\n return;\n }\n\n for (const path of mirroredPaths(resolved.record.mirror, resolved.record.path)) {\n const bag = bagFor(clone, resolved.record, path as string[]);\n if (bag) removeValueAtPath(bag, edit.path);\n }\n}\n"],"names":["resolveEditableProperty","session","nodeId","path","diagnostics","record","index","nodes","get","push","errorDiagnostic","DiagnosticCode","UnknownNode","undefined","isLocal","NodeNotEditable","sourceOf","description","describeNode","context","catalog","descriptor","properties","find","candidate","length","MissingComponentDescriptor","UnknownProperty","message","typeId","readOnly","ReadOnlyProperty","label","checkValue","value","problem","validateValue","InvalidValue","candidates","queryCandidates","valueType","PropertyValueType","QueryReference","binding","problems","validateBinding","id","queryId","map","problemDiagnostic","bagFor","root","target","getAtPath","isComponent","kind","SceneNodeKind","Element","componentName","applySetProperty","edit","clone","resolved","mirroredPaths","mirror","bag","setValueAtPath","cloneData","applyResetProperty","constraints","required","default","removeValueAtPath"],"mappings":"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"}
1
+ {"version":3,"file":"propertyEdits.js","sources":["../../../editing/propertyEdits.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport {\n DiagnosticCode, DiagnosticSeverity, PropertyDescriptor, PropertyValueType, QueryBinding, ResetPropertyEdit, SceneDiagnostic, SceneDocument,\n SceneNodeKind, SetPropertyEdit,\n} from '@cratis/scene.model';\nimport { describeNode } from './describeNode';\nimport { errorDiagnostic, hasErrors } from './diagnostics';\nimport { NodeRecord } from './DocumentIndex';\nimport { getAtPath, mirroredPaths } from './documentPaths';\nimport { EditSession } from './EditSession';\nimport { iconProblemsOfProperty } from './iconDiagnostics';\nimport { cloneData, removeValueAtPath, setValueAtPath } from './pathAccess';\nimport { validateBinding } from './validateBinding';\nimport { validateValue } from './validateValue';\n\n/**\n * Finds the node and descriptor an edit of a property addresses, or says why it cannot.\n */\nexport function resolveEditableProperty(\n session: EditSession,\n nodeId: string,\n path: string,\n diagnostics: SceneDiagnostic[],\n): { record: NodeRecord; descriptor: PropertyDescriptor } | undefined {\n const record = session.index.nodes.get(nodeId);\n if (!record) {\n diagnostics.push(errorDiagnostic(DiagnosticCode.UnknownNode, `There is no node '${nodeId}'.`, { nodeId }));\n return undefined;\n }\n\n if (!session.isLocal(record)) {\n diagnostics.push(errorDiagnostic(\n DiagnosticCode.NodeNotEditable,\n `'${nodeId}' is inherited from '${session.sourceOf(record)}'. An exposed property is configured with an instance edit, not by changing the node.`,\n { nodeId, path }));\n return undefined;\n }\n\n const description = describeNode(record, session.context.catalog);\n const descriptor = description.properties.find(candidate => candidate.path === path);\n if (!descriptor) {\n diagnostics.push(errorDiagnostic(\n description.diagnostics.length > 0 ? DiagnosticCode.MissingComponentDescriptor : DiagnosticCode.UnknownProperty,\n description.diagnostics[0]?.message ?? `'${record.typeId}' has no property '${path}'.`,\n { nodeId, path }));\n return undefined;\n }\n\n if (descriptor.readOnly) {\n diagnostics.push(errorDiagnostic(DiagnosticCode.ReadOnlyProperty, `'${descriptor.label}' is read-only.`, { nodeId, path }));\n return undefined;\n }\n\n return { record, descriptor };\n}\n\n/**\n * Checks a value for a property, including a query binding against the host's candidates.\n *\n * @returns Whether the value is acceptable; the reasons are added to `diagnostics`.\n */\nexport function checkValue(session: EditSession, descriptor: PropertyDescriptor, value: unknown, context: { nodeId?: string; component?: string; instance?: string }, diagnostics: SceneDiagnostic[]): boolean {\n const problem = validateValue(descriptor, value);\n if (problem) {\n diagnostics.push(errorDiagnostic(DiagnosticCode.InvalidValue, `'${descriptor.label}': ${problem}.`, { ...context, path: descriptor.path }));\n return false;\n }\n\n const candidates = session.context.queryCandidates;\n if (descriptor.valueType === PropertyValueType.QueryReference && candidates && typeof value === 'object' && value !== null) {\n const binding = value as QueryBinding;\n const problems = validateBinding(descriptor, candidates.find(candidate => candidate.id === binding.queryId), binding);\n diagnostics.push(...problems.map(problemDiagnostic => ({ ...problemDiagnostic, ...context })));\n return problems.length === 0;\n }\n\n const icons = session.context.iconCatalog;\n if (icons) {\n const problems = iconProblemsOfProperty(icons, descriptor, value, DiagnosticSeverity.Error, context);\n diagnostics.push(...problems);\n return !hasErrors(problems);\n }\n\n return true;\n}\n\nfunction bagFor(root: SceneDocument, record: NodeRecord, path: string[]): Record<string, unknown> | undefined {\n const target = getAtPath(root, path) as Record<string, unknown> | undefined;\n if (!target) return undefined;\n const isComponent = record.kind === SceneNodeKind.Element && target.componentName !== undefined;\n if (!isComponent) return target;\n return (target.properties ??= {}) as Record<string, unknown>;\n}\n\n/**\n * Applies a property set to a copy of the document.\n */\nexport function applySetProperty(session: EditSession, edit: SetPropertyEdit, clone: SceneDocument, diagnostics: SceneDiagnostic[]): void {\n const resolved = resolveEditableProperty(session, edit.nodeId, edit.path, diagnostics);\n if (!resolved) return;\n if (!checkValue(session, resolved.descriptor, edit.value, { nodeId: edit.nodeId }, diagnostics)) return;\n\n for (const path of mirroredPaths(resolved.record.mirror, resolved.record.path)) {\n const bag = bagFor(clone, resolved.record, path as string[]);\n if (bag) setValueAtPath(bag, edit.path, cloneData(edit.value));\n }\n}\n\n/**\n * Applies a property reset to a copy of the document.\n */\nexport function applyResetProperty(session: EditSession, edit: ResetPropertyEdit, clone: SceneDocument, diagnostics: SceneDiagnostic[]): void {\n const resolved = resolveEditableProperty(session, edit.nodeId, edit.path, diagnostics);\n if (!resolved) return;\n\n if (resolved.descriptor.constraints?.required && resolved.descriptor.default === undefined) {\n diagnostics.push(errorDiagnostic(DiagnosticCode.InvalidValue, `'${resolved.descriptor.label}' is required and has no default to go back to.`, { nodeId: edit.nodeId, path: edit.path }));\n return;\n }\n\n for (const path of mirroredPaths(resolved.record.mirror, resolved.record.path)) {\n const bag = bagFor(clone, resolved.record, path as string[]);\n if (bag) removeValueAtPath(bag, edit.path);\n }\n}\n"],"names":["resolveEditableProperty","session","nodeId","path","diagnostics","record","index","nodes","get","push","errorDiagnostic","DiagnosticCode","UnknownNode","undefined","isLocal","NodeNotEditable","sourceOf","description","describeNode","context","catalog","descriptor","properties","find","candidate","length","MissingComponentDescriptor","UnknownProperty","message","typeId","readOnly","ReadOnlyProperty","label","checkValue","value","problem","validateValue","InvalidValue","candidates","queryCandidates","valueType","PropertyValueType","QueryReference","binding","problems","validateBinding","id","queryId","map","problemDiagnostic","icons","iconCatalog","iconProblemsOfProperty","DiagnosticSeverity","Error","hasErrors","bagFor","root","target","getAtPath","isComponent","kind","SceneNodeKind","Element","componentName","applySetProperty","edit","clone","resolved","mirroredPaths","mirror","bag","setValueAtPath","cloneData","applyResetProperty","constraints","required","default","removeValueAtPath"],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import { IconEntry, IconReference } from '@cratis/scene.model';
2
+ import { EffectiveIconEntry } from './EffectiveIconEntry';
3
+ import { IconCatalogSource } from './IconCatalogSource';
4
+ import { IconDiagnostic } from './IconDiagnostic';
5
+ import { IconLibraryResolution } from './IconLibraryResolution';
6
+ import { IconQuery } from './IconQuery';
7
+ import { IconResolution } from './IconResolution';
8
+ import { IconSearchResult } from './IconSearchResult';
9
+ import { ResolvedIconLibrary } from './ResolvedIconLibrary';
10
+ export declare class EffectiveIconCatalog {
11
+ #private;
12
+ readonly resolution: IconLibraryResolution;
13
+ constructor(resolution: IconLibraryResolution, sources: IconCatalogSource[]);
14
+ get libraries(): ResolvedIconLibrary[];
15
+ get diagnostics(): IconDiagnostic[];
16
+ isLoaded(library: string): boolean;
17
+ entriesOf(library: string): Promise<IconEntry[] | undefined>;
18
+ search(query?: IconQuery): Promise<IconSearchResult>;
19
+ findByName(name: string): Promise<EffectiveIconEntry[]>;
20
+ categories(library?: string): Promise<string[]>;
21
+ resolve(reference: IconReference): Promise<IconResolution>;
22
+ lookup(reference: IconReference): IconResolution | undefined;
23
+ load(library?: string): Promise<IconDiagnostic[]>;
24
+ }
25
+ //# sourceMappingURL=EffectiveIconCatalog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EffectiveIconCatalog.d.ts","sourceRoot":"","sources":["../../../icons/EffectiveIconCatalog.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,SAAS,EAAE,aAAa,EAAuB,MAAM,qBAAqB,CAAC;AACpF,OAAO,EAAE,kBAAkB,EAAqB,MAAM,sBAAsB,CAAC;AAC7E,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAY5D,qBAAa,oBAAoB;;IAUjB,QAAQ,CAAC,UAAU,EAAE,qBAAqB;IAAtD,YAAqB,UAAU,EAAE,qBAAqB,EAAE,OAAO,EAAE,iBAAiB,EAAE,EAEnF;IAKD,IAAI,SAAS,IAAI,mBAAmB,EAAE,CAErC;IAKD,IAAI,WAAW,IAAI,cAAc,EAAE,CAElC;IAKD,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAEjC;IAQK,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,GAAG,SAAS,CAAC,CAiBjE;IAKK,MAAM,CAAC,KAAK,GAAE,SAAc,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAmB7D;IAOK,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAI5D;IAKK,UAAU,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAGpD;IAKK,OAAO,CAAC,SAAS,EAAE,aAAa,GAAG,OAAO,CAAC,cAAc,CAAC,CAQ/D;IAWD,MAAM,CAAC,SAAS,EAAE,aAAa,GAAG,cAAc,GAAG,SAAS,CAsB3D;IAMK,IAAI,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,CAItD;CAkBJ"}
@@ -0,0 +1,210 @@
1
+ import { formatIconReference } from '@cratis/scene.model';
2
+ import { referencesOfEntry } from './EffectiveIconEntry.js';
3
+ import { matchesIconQuery } from './matchesIconQuery.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 icons a profile can actually use: the active libraries from {@link resolveIconLibraries}, with their
9
+ * catalogs loaded on demand.
10
+ *
11
+ * Opening it costs nothing - no catalog is read until a query or a lookup needs that library, and a
12
+ * query narrowed to one library reads only that one. A catalog is loaded once and kept; a load that
13
+ * fails is not kept, so the next call tries again. Everything that goes wrong is reported as an
14
+ * {@link IconDiagnostic}; nothing is ever answered with a different icon than the one asked for.
15
+ */ class EffectiveIconCatalog {
16
+ resolution;
17
+ #sources;
18
+ #loads = new Map();
19
+ #loadedEntries = new Map();
20
+ /**
21
+ * @param resolution The active libraries and the problems found with them.
22
+ * @param sources The catalog source of each library; a library with none is active but reports
23
+ * 'catalog-unavailable' when its icons are needed.
24
+ */ constructor(resolution, sources){
25
+ this.resolution = resolution;
26
+ this.#sources = new Map(sources.map((source)=>[
27
+ source.library,
28
+ source
29
+ ]));
30
+ }
31
+ /**
32
+ * The active libraries, with provenance.
33
+ */ get libraries() {
34
+ return this.resolution.libraries;
35
+ }
36
+ /**
37
+ * Problems with the libraries themselves, known without loading any catalog.
38
+ */ get diagnostics() {
39
+ return this.resolution.diagnostics;
40
+ }
41
+ /**
42
+ * Whether a library's catalog has been read yet.
43
+ */ isLoaded(library) {
44
+ return this.#loadedEntries.has(library);
45
+ }
46
+ /**
47
+ * The entries of one library, loading its catalog if this is the first time it is needed.
48
+ * Resolves to `undefined` when the library is not active.
49
+ *
50
+ * @throws Whatever the library's source throws, or an Error when an active library has no source.
51
+ */ async entriesOf(library) {
52
+ if (!this.libraries.some((resolved)=>resolved.library === library)) return undefined;
53
+ let load = this.#loads.get(library);
54
+ if (!load) {
55
+ const source = this.#sources.get(library);
56
+ if (!source) throw new Error(`The icon library '${library}' is active but has no catalog source`);
57
+ load = source.loadEntries();
58
+ this.#loads.set(library, load);
59
+ load.then((entries)=>this.#loadedEntries.set(library, entries), ()=>this.#loads.delete(library));
60
+ }
61
+ return load;
62
+ }
63
+ /**
64
+ * Searches the catalogs of the libraries the query covers - all of them, or the one it names.
65
+ */ async search(query = {}) {
66
+ const covered = this.libraries.filter((resolved)=>query.library === undefined || resolved.library === query.library);
67
+ const outcomes = await Promise.all(covered.map(async (resolved)=>this.#entriesOrDiagnostic(resolved)));
68
+ const entries = [];
69
+ const diagnostics = [];
70
+ outcomes.forEach((outcome, position)=>{
71
+ const library = covered[position];
72
+ if ('diagnostic' in outcome) {
73
+ diagnostics.push(outcome.diagnostic);
74
+ return;
75
+ }
76
+ for (const entry of outcome.entries.filter((candidate)=>matchesIconQuery(candidate, query))){
77
+ entries.push({
78
+ library,
79
+ entry,
80
+ references: referencesOfEntry(library.library, entry)
81
+ });
82
+ }
83
+ });
84
+ return {
85
+ entries,
86
+ diagnostics
87
+ };
88
+ }
89
+ /**
90
+ * Every active library's icons whose name or key is exactly `name` (ignoring case) - the several
91
+ * candidates a bare legacy icon name could have meant. More than one is a real answer, not a tie to
92
+ * break: it is the author's decision which library the icon comes from.
93
+ */ async findByName(name) {
94
+ const wanted = name.trim().toLowerCase();
95
+ const { entries } = await this.search({});
96
+ return entries.filter(({ entry })=>entry.key.toLowerCase() === wanted || entry.name.toLowerCase() === wanted);
97
+ }
98
+ /**
99
+ * The categories in use, sorted, across all libraries or one.
100
+ */ async categories(library) {
101
+ const { entries } = await this.search({
102
+ library
103
+ });
104
+ return [
105
+ ...new Set(entries.flatMap(({ entry })=>entry.categories))
106
+ ].sort();
107
+ }
108
+ /**
109
+ * Looks a reference up: the icon it names, or exactly why there is none.
110
+ */ async resolve(reference) {
111
+ const library = this.libraries.find((resolved)=>resolved.library === reference.library);
112
+ if (library && !this.isLoaded(library.library) && !this.#incompatibility(library)) {
113
+ const outcome = await this.#entriesOrDiagnostic(library);
114
+ if ('diagnostic' in outcome) return {
115
+ isResolved: false,
116
+ reference,
117
+ diagnostic: {
118
+ ...outcome.diagnostic,
119
+ reference
120
+ }
121
+ };
122
+ }
123
+ return this.lookup(reference);
124
+ }
125
+ /**
126
+ * Looks a reference up without loading anything, for callers that cannot wait - an edit is applied
127
+ * synchronously. Resolves everything that is decidable from what is already known: a library that is not
128
+ * active, one at an incompatible version, and - once the library's catalog has been loaded - a missing
129
+ * icon or variant.
130
+ *
131
+ * @returns The resolution, or `undefined` when the library is active but its catalog has not been loaded,
132
+ * so nothing can be said about the icon yet. Call {@link load} first to make the answer definite.
133
+ */ lookup(reference) {
134
+ const library = this.libraries.find((resolved)=>resolved.library === reference.library);
135
+ if (!library) {
136
+ return this.#unresolved(reference, 'missing-library', `The icon library '${reference.library}' is not active in this profile`);
137
+ }
138
+ const incompatible = this.#incompatibility(library);
139
+ if (incompatible) return {
140
+ isResolved: false,
141
+ reference,
142
+ diagnostic: {
143
+ ...incompatible,
144
+ reference
145
+ }
146
+ };
147
+ const entries = this.#loadedEntries.get(library.library);
148
+ if (!entries) return undefined;
149
+ const entry = entries.find((candidate)=>candidate.key === reference.key);
150
+ if (!entry) {
151
+ return this.#unresolved(reference, 'missing-icon', `The icon library '${library.library}' has no icon '${reference.key}'`);
152
+ }
153
+ if (reference.variant !== undefined && !(entry.variants ?? []).includes(reference.variant)) {
154
+ return this.#unresolved(reference, 'missing-variant', `The icon '${formatIconReference({
155
+ library: library.library,
156
+ key: entry.key
157
+ })}' has no '${reference.variant}' variant`);
158
+ }
159
+ return {
160
+ isResolved: true,
161
+ reference,
162
+ library,
163
+ entry
164
+ };
165
+ }
166
+ /**
167
+ * Loads the catalogs of one library, or of every active library, so that {@link lookup} can answer
168
+ * definitely. Libraries whose catalog cannot be loaded are reported, not thrown.
169
+ */ async load(library) {
170
+ const covered = this.libraries.filter((resolved)=>library === undefined || resolved.library === library);
171
+ const outcomes = await Promise.all(covered.map(async (resolved)=>this.#entriesOrDiagnostic(resolved)));
172
+ return outcomes.flatMap((outcome)=>'diagnostic' in outcome ? [
173
+ outcome.diagnostic
174
+ ] : []);
175
+ }
176
+ #incompatibility(library) {
177
+ return this.diagnostics.find((diagnostic)=>diagnostic.kind === 'incompatible-version' && diagnostic.library === library.library);
178
+ }
179
+ async #entriesOrDiagnostic(library) {
180
+ try {
181
+ return {
182
+ entries: await this.entriesOf(library.library) ?? []
183
+ };
184
+ } catch (error) {
185
+ const reason = error instanceof Error ? error.message : String(error);
186
+ return {
187
+ diagnostic: {
188
+ kind: 'catalog-unavailable',
189
+ library: library.library,
190
+ message: `The catalog of '${library.library}' could not be loaded: ${reason}`
191
+ }
192
+ };
193
+ }
194
+ }
195
+ #unresolved(reference, kind, message) {
196
+ return {
197
+ isResolved: false,
198
+ reference,
199
+ diagnostic: {
200
+ kind,
201
+ library: reference.library,
202
+ message,
203
+ reference
204
+ }
205
+ };
206
+ }
207
+ }
208
+
209
+ export { EffectiveIconCatalog };
210
+ //# sourceMappingURL=EffectiveIconCatalog.js.map