@_linked/core 2.36.0 → 2.36.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +21 -0
- package/README.md +19 -0
- package/lib/esm/collections/CoreSet.js +2 -0
- package/lib/esm/collections/CoreSet.js.map +1 -1
- package/lib/esm/collections/ShapeSet.js +2 -0
- package/lib/esm/collections/ShapeSet.js.map +1 -1
- package/lib/esm/expressions/Expr.js +3 -2
- package/lib/esm/expressions/Expr.js.map +1 -1
- package/lib/esm/expressions/ExpressionNode.js +10 -7
- package/lib/esm/expressions/ExpressionNode.js.map +1 -1
- package/lib/esm/index.d.ts +1 -1
- package/lib/esm/index.js +1 -1
- package/lib/esm/index.js.map +1 -1
- package/lib/esm/queries/AskBuilder.js +5 -3
- package/lib/esm/queries/AskBuilder.js.map +1 -1
- package/lib/esm/queries/CountBuilder.js +4 -2
- package/lib/esm/queries/CountBuilder.js.map +1 -1
- package/lib/esm/queries/CreateBuilder.js +2 -0
- package/lib/esm/queries/CreateBuilder.js.map +1 -1
- package/lib/esm/queries/DeleteBuilder.js +3 -1
- package/lib/esm/queries/DeleteBuilder.js.map +1 -1
- package/lib/esm/queries/DslJsonExpression.js +7 -6
- package/lib/esm/queries/DslJsonExpression.js.map +1 -1
- package/lib/esm/queries/FieldSet.js +10 -8
- package/lib/esm/queries/FieldSet.js.map +1 -1
- package/lib/esm/queries/IRLower.js +2 -1
- package/lib/esm/queries/IRLower.js.map +1 -1
- package/lib/esm/queries/MutationSerialization.js +2 -1
- package/lib/esm/queries/MutationSerialization.js.map +1 -1
- package/lib/esm/queries/PropertyPath.js +2 -0
- package/lib/esm/queries/PropertyPath.js.map +1 -1
- package/lib/esm/queries/ProxiedPathBuilder.js +2 -1
- package/lib/esm/queries/ProxiedPathBuilder.js.map +1 -1
- package/lib/esm/queries/QueryBuilder.js +5 -4
- package/lib/esm/queries/QueryBuilder.js.map +1 -1
- package/lib/esm/queries/QueryContext.js +17 -6
- package/lib/esm/queries/QueryContext.js.map +1 -1
- package/lib/esm/queries/SelectQuery.js +18 -12
- package/lib/esm/queries/SelectQuery.js.map +1 -1
- package/lib/esm/queries/UpdateBuilder.js +3 -1
- package/lib/esm/queries/UpdateBuilder.js.map +1 -1
- package/lib/esm/queries/lower.js +5 -4
- package/lib/esm/queries/lower.js.map +1 -1
- package/lib/esm/shapes/SHACL.js +6 -3
- package/lib/esm/shapes/SHACL.js.map +1 -1
- package/lib/esm/shapes/Shape.d.ts +3 -1
- package/lib/esm/shapes/Shape.js +20 -2
- package/lib/esm/shapes/Shape.js.map +1 -1
- package/lib/esm/shapes/validation.js +3 -2
- package/lib/esm/shapes/validation.js.map +1 -1
- package/lib/esm/utils/LinkedErrorLogging.d.ts +2 -1
- package/lib/esm/utils/LinkedErrorLogging.js +11 -0
- package/lib/esm/utils/LinkedErrorLogging.js.map +1 -1
- package/lib/esm/utils/LinkedFileStorage.d.ts +6 -4
- package/lib/esm/utils/LinkedFileStorage.js +34 -4
- package/lib/esm/utils/LinkedFileStorage.js.map +1 -1
- package/lib/esm/utils/Package.d.ts +6 -0
- package/lib/esm/utils/Package.js +35 -7
- package/lib/esm/utils/Package.js.map +1 -1
- package/lib/esm/utils/Prefix.d.ts +4 -2
- package/lib/esm/utils/Prefix.js +18 -2
- package/lib/esm/utils/Prefix.js.map +1 -1
- package/lib/esm/utils/ShapeClass.js +11 -6
- package/lib/esm/utils/ShapeClass.js.map +1 -1
- package/lib/esm/utils/cached.js +2 -1
- package/lib/esm/utils/cached.js.map +1 -1
- package/lib/esm/utils/linkedError.d.ts +32 -0
- package/lib/esm/utils/linkedError.js +40 -0
- package/lib/esm/utils/linkedError.js.map +1 -1
- package/lib/esm/utils/unresolvedShape.d.ts +8 -4
- package/lib/esm/utils/unresolvedShape.js +14 -10
- package/lib/esm/utils/unresolvedShape.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validation.js","sourceRoot":"","sources":["../../../src/shapes/validation.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * This Source Code Form is subject to the terms of the Mozilla Public\n * License, v. 2.0. If a copy of the MPL was not distributed with this\n * file, You can obtain one at https://mozilla.org/MPL/2.0/.\n */\n/**\n * SHACL-aligned validation of plain data objects against a node shape.\n *\n * One entry point — {@link validate} — used by the create and update pipelines\n * (via `MutationQueryFactory.describe()`) and directly by callers that want to\n * know how well an object fits a shape without building a mutation.\n *\n * **Shape of the output.** This library has no triple/Turtle layer and this\n * module does not add one: a {@link ValidationReport} is plain JavaScript. It is\n * however 1-1 with the SHACL vocabulary — one key per SHACL property, named\n * after it, holding a value the mutation pipeline accepts (a literal, or a\n * `{id}` node reference for IRI-valued properties). So a report can be\n * materialized by an ordinary create query as soon as shape classes for\n * `sh:ValidationReport` / `sh:ValidationResult` exist, with no transform step:\n *\n * ```ts\n * const report = validate(Slide, data);\n * await ValidationReport.create(report); // once those shape classes exist\n * ```\n *\n * Two deliberate departures, both documented on the types: `results` is plural\n * where SHACL's repeated property is `sh:result`, and `propertyPath` is a\n * non-SHACL locator. Both map cleanly — a shape class chooses its own labels for\n * SHACL paths, and an extension property is legal on a SHACL report.\n *\n * **Coverage.** Cardinality (`sh:minCount` / `sh:maxCount`), node kind (literal\n * vs relation), undeclared properties (as `sh:closed`), `sh:datatype`, the four\n * `sh:min/maxInclusive/Exclusive` bounds, `sh:min/maxLength`, `sh:pattern` and\n * `sh:in`. Each is one entry in {@link CARDINALITY_CONSTRAINTS} or\n * {@link VALUE_CONSTRAINTS}, so adding another is one function and one test.\n *\n * Not covered: `sh:languageIn` / `sh:uniqueLang` (skipped at serialization time\n * too, so there is no metadata to check against) and `sh:hasValue`.\n */\nimport {getShapeRegistryInstanceCount, getQueryShapeClass} from '../utils/ShapeClass.js';\nimport {shacl} from '../ontologies/shacl.js';\nimport {brandLinkedError} from '../utils/linkedError.js';\nimport {xsd} from '../ontologies/xsd.js';\nimport {isNodeReferenceValue, type NodeReferenceValue} from '../utils/NodeReference.js';\nimport {getUniquePropertyShapes} from './nodeShapeData.js';\nimport type {NodeShapeData, PropertyShapeData} from './nodeShapeData.js';\nimport {getNodeShape, getShapeClass, isSubShapeOf} from '../utils/ShapeClass.js';\nimport {isExpressionNode} from '../expressions/ExpressionNode.js';\nimport {asContextRef} from '../queries/QueryContext.js';\nimport {describeUnresolved, unresolvedValueShapeDetails} from '../utils/unresolvedShape.js';\n\n/**\n * Which constraints apply to the data being validated.\n *\n * - `complete` — the object describes a whole node (a create, or a standalone\n * object being checked for fit). Properties absent from the data are genuinely\n * absent, so `sh:minCount` presence is checkable.\n * - `partial` — the object describes a change to an existing node (an update).\n * The store holds whatever the payload does not mention, so presence is\n * unknowable; only the values actually provided are checked.\n */\nexport type ValidationMode = 'complete' | 'partial';\n\n/**\n * A single constraint violation — an `sh:ValidationResult`.\n *\n * Every key is the local name of the SHACL property it carries, and every value\n * is in a form the create pipeline accepts (a literal, or a `{id}` node\n * reference for IRI-valued properties). A shape class declaring these\n * properties therefore materializes a result with no transform step:\n * `ValidationResult.create(result)`. The one non-SHACL key is `propertyPath`;\n * see {@link ValidationReport}.\n */\nexport interface ValidationResult {\n /** `sh:focusNode` — the node the violation is about, when its id is known. */\n focusNode?: NodeReferenceValue;\n /** `sh:resultPath` — the IRI of the property the violation is about. */\n resultPath?: NodeReferenceValue;\n /**\n * `sh:value` — the offending value, present only when it is an RDF term (a\n * literal or a node reference). Cardinality violations are about the property\n * rather than any one value, so they carry none.\n */\n value?: LiteralTerm | NodeReferenceValue;\n /** `sh:sourceShape` — the node or property shape carrying the constraint. */\n sourceShape?: NodeReferenceValue;\n /** `sh:sourceConstraintComponent` — which SHACL constraint failed. */\n sourceConstraintComponent: NodeReferenceValue;\n /** `sh:resultSeverity` — `sh:Violation`, `sh:Warning` or `sh:Info`. */\n resultSeverity: NodeReferenceValue;\n /** `sh:resultMessage` — human-readable explanation. */\n resultMessage: string;\n /**\n * **Not SHACL.** The property's label, dot-joined through nested shapes\n * (`author.fullName`) — the locator a caller needs to point at a field in the\n * object they passed in, which `sh:resultPath` alone cannot give (it names the\n * property, not where the nesting reached it). Materializes like any other\n * property once a shape class declares it; drop it for a pure-SHACL result.\n */\n propertyPath?: string;\n}\n\n/**\n * The outcome of a validation run — an `sh:ValidationReport`.\n *\n * Plain objects, 1-1 with the SHACL vocabulary, so a report can later be\n * materialized through an ordinary create query against shape classes for\n * `sh:ValidationReport` / `sh:ValidationResult` — whether or not this library\n * ever ships those classes. `results` is the sole plural rename (SHACL's\n * property is `sh:result`, repeated); a shape class maps it with\n * `@objectProperty({path: shacl.result, …}) get results()`.\n */\nexport interface ValidationReport {\n /** `sh:conforms` — true when there are no `sh:Violation`-severity results. */\n conforms: boolean;\n /** `sh:result` — every violation found, in deterministic order. */\n results: ValidationResult[];\n}\n\n/** The literal types the mutation pipeline accepts as a value. */\ntype LiteralTerm = string | number | boolean | Date;\n\nexport interface ValidateOptions {\n /** Defaults to `complete`. */\n mode?: ValidationMode;\n /** How deep to descend into nested node descriptions. Defaults to 10. */\n maxDepth?: number;\n}\n\n/** Thrown by {@link assertValid} — carries the full report, not just the first violation. */\nexport class ShapeValidationError extends Error {\n readonly report: ValidationReport;\n constructor(report: ValidationReport) {\n super(report.results.map((r) => r.resultMessage).join('\\n'));\n this.name = 'ShapeValidationError';\n this.report = report;\n }\n}\nbrandLinkedError(ShapeValidationError, '@_linked/core', 'ShapeValidationError');\n\n/**\n * Keys that carry metadata about the node rather than a property value: `id` /\n * `__id` name it, and `shape` names the shape of a nested value when the\n * property shape itself doesn't declare one (see `convertUpdateValue`).\n */\nconst RESERVED_KEYS = new Set(['id', '__id', 'shape']);\n\n/**\n * The message for an undeclared property key. Shared with the normalization path\n * in `MutationQuery`, which needs the same guard to build a field at all.\n */\nexport function undeclaredPropertyMessage(key: string, shape: NodeShapeData): string {\n const shapeName = shape.label || shape.id?.split('/').pop();\n const base =\n `Invalid property key: ${key}. The shape ${shapeName} does not have a registered ` +\n `property with this name. Make sure the get/set method exists, and that it uses a ` +\n `@objectProperty or @literalProperty decorator.`;\n\n // If more than one copy of the shape registry module has evaluated, this message is\n // very probably lying: the property IS declared, on a copy this code cannot see.\n // Saying so here is the whole point — the previous version of this error accused\n // correct application code, and finding the real cause took a day of eliminating\n // innocent suspects. See docs/reports/043-module-identity-in-the-backend.md.\n const copies = getShapeRegistryInstanceCount();\n if (copies > 1) {\n return (\n `${base}\\n\\n` +\n `NOTE: ${copies} copies of the shape registry have loaded in this process. If this ` +\n `property is declared, it almost certainly registered on a different copy than the ` +\n `one validating here, and the declaration is not the problem. This happens when part ` +\n `of the app resolves a framework package to its source and part to its built output.`\n );\n }\n return base;\n}\n\n// ---------------------------------------------------------------------------\n// Constraint components\n// ---------------------------------------------------------------------------\n\n/** What a constraint check needs to know about the property it is checking. */\ninterface PropertyContext {\n shape: NodeShapeData;\n propertyShape: PropertyShapeData;\n /** Dot-joined label path from the root of the validated object. */\n property: string;\n focusNode?: string;\n mode: ValidationMode;\n}\n\n/**\n * A constraint check. Receives the property's values already normalized to an\n * array (a single value becomes a one-element array) and returns any violations.\n */\ntype ConstraintCheck = (values: unknown[], ctx: PropertyContext) => ValidationResult[];\n\n/**\n * `sh:value` must be an RDF term. A literal or a node reference is one; a plain\n * object, array or function is not, so it is left off rather than emitted as\n * something no store could materialize — the message still names it.\n */\nfunction asTerm(value: unknown): LiteralTerm | NodeReferenceValue | undefined {\n if (isScalarValue(value)) return value as LiteralTerm;\n if (isNodeReference(value)) return {id: (value as NodeReferenceValue).id};\n return undefined;\n}\n\n/**\n * A violation about the node itself rather than one of its property shapes —\n * `sh:sourceShape` is the node shape, and there is no `sh:resultPath` (an\n * undeclared key has no property IRI to point at).\n */\nfunction nodeViolation(\n shape: NodeShapeData,\n ctx: {focusNode?: string},\n component: NodeReferenceValue,\n message: string,\n propertyPath?: string,\n value?: unknown,\n): ValidationResult {\n const result: ValidationResult = {\n sourceConstraintComponent: component,\n resultSeverity: shacl.Violation,\n resultMessage: message,\n };\n if (ctx.focusNode) result.focusNode = {id: ctx.focusNode};\n if (propertyPath) result.propertyPath = propertyPath;\n const term = asTerm(value);\n if (term !== undefined) result.value = term;\n if (shape.id) result.sourceShape = {id: shape.id};\n return result;\n}\n\n/**\n * Build a result, omitting absent keys entirely — an `undefined` value is not a\n * property the create pipeline should see.\n */\nfunction violation(\n ctx: PropertyContext,\n component: NodeReferenceValue,\n message: string,\n value?: unknown,\n): ValidationResult {\n const result: ValidationResult = {\n sourceConstraintComponent: component,\n resultSeverity: shacl.Violation,\n resultMessage: message,\n };\n if (ctx.focusNode) result.focusNode = {id: ctx.focusNode};\n const path = ctx.propertyShape.path as NodeReferenceValue | undefined;\n if (path?.id) result.resultPath = {id: path.id};\n if (ctx.property) result.propertyPath = ctx.property;\n const term = asTerm(value);\n if (term !== undefined) result.value = term;\n const sourceShape = ctx.propertyShape.id || ctx.shape.id;\n if (sourceShape) result.sourceShape = {id: sourceShape};\n return result;\n}\n\n/** The label used in messages — the property's own label, not its nested path. */\nfunction labelOf(ps: PropertyShapeData): string {\n return ps.label || ps.id;\n}\n\n/** `sh:maxCount` — no more values than the shape allows. */\nconst maxCountCheck: ConstraintCheck = (values, ctx) => {\n const {maxCount} = ctx.propertyShape;\n if (typeof maxCount !== 'number' || values.length <= maxCount) return [];\n return [\n violation(\n ctx,\n shacl.MaxCountConstraintComponent,\n `Property '${labelOf(ctx.propertyShape)}' allows at most ${maxCount} value(s), but ${values.length} were provided.`,\n ),\n ];\n};\n\n/** `sh:minCount` — at least as many values as the shape requires. */\nconst minCountCheck: ConstraintCheck = (values, ctx) => {\n const {minCount} = ctx.propertyShape;\n if (typeof minCount !== 'number' || minCount <= 0 || values.length >= minCount) return [];\n return [\n violation(\n ctx,\n shacl.MinCountConstraintComponent,\n `Property '${labelOf(ctx.propertyShape)}' requires at least ${minCount} value(s), but ${values.length} were provided.`,\n ),\n ];\n};\n\n/** True when the property clearly accepts only literal values. */\nfunction expectsLiteral(ps: PropertyShapeData): boolean {\n if (ps.nodeKind) return ps.nodeKind.id === shacl.Literal.id;\n return !!ps.datatype && !ps.valueShape && !ps.class;\n}\n\n/**\n * True when the property clearly accepts only nodes (IRIs/blank nodes). `sh:class` counts\n * as much as `sh:node`: a value that is an instance of a class is a node, whether or not\n * the property names a shape for it.\n */\nfunction expectsNode(ps: PropertyShapeData): boolean {\n if (ps.nodeKind) {\n return (\n ps.nodeKind.id === shacl.IRI.id ||\n ps.nodeKind.id === shacl.BlankNode.id ||\n ps.nodeKind.id === shacl.BlankNodeOrIRI.id\n );\n }\n return !!(ps.valueShape || ps.class);\n}\n\nfunction isScalarValue(value: unknown): boolean {\n return (\n typeof value === 'string' ||\n typeof value === 'number' ||\n typeof value === 'boolean' ||\n value instanceof Date\n );\n}\n\n/**\n * `sh:nodeKind` — literal properties reject nodes/objects, relation properties\n * reject bare scalars. Ambiguous kinds (`sh:IRIOrLiteral`, or no `nodeKind` and\n * no `datatype`/`valueShape`/`class` to infer from) are not enforced.\n */\nconst nodeKindCheck: ConstraintCheck = (values, ctx) => {\n const ps = ctx.propertyShape;\n const literalExpected = expectsLiteral(ps);\n const nodeExpected = expectsNode(ps);\n if (!literalExpected && !nodeExpected) return [];\n\n const results: ValidationResult[] = [];\n for (const el of values) {\n if (!isCheckableElement(el)) continue;\n const scalar = isScalarValue(el);\n if (literalExpected && !scalar) {\n results.push(\n violation(\n ctx,\n shacl.NodeKindConstraintComponent,\n `Property '${labelOf(ps)}' is a literal property but was given a ${typeof el === 'object' ? 'node/object' : typeof el} value.`,\n el,\n ),\n );\n } else if (nodeExpected && scalar) {\n results.push(\n violation(\n ctx,\n shacl.NodeKindConstraintComponent,\n `Property '${labelOf(ps)}' is a relation (object) property but was given a literal (${typeof el}). Provide a {id} reference or a nested object.`,\n el,\n ),\n );\n }\n }\n return results;\n};\n\n/**\n * An element worth checking: a concrete value rather than something whose final\n * form is decided elsewhere (an expression, a context ref, an absent value).\n */\nfunction isCheckableElement(el: unknown): boolean {\n return el !== null && el !== undefined && !isExpressionNode(el) && !asContextRef(el);\n}\n\nconst XSD_BASE = xsd.string.id.slice(0, -'string'.length);\n\n/** `xsd:integer` rather than the full IRI, when the datatype is an XSD one. */\nfunction datatypeLabel(datatype: NodeReferenceValue): string {\n return datatype.id.startsWith(XSD_BASE)\n ? `xsd:${datatype.id.slice(XSD_BASE.length)}`\n : datatype.id;\n}\n\n/** How a value reads in a message — its JS kind, which is what went wrong. */\nfunction describeValue(value: unknown): string {\n if (value instanceof Date) return 'a Date';\n if (Array.isArray(value)) return 'an array';\n if (typeof value === 'number') return Number.isInteger(value) ? 'a whole number' : 'a decimal number';\n if (typeof value === 'object') return 'a node/object';\n return `a ${typeof value}`;\n}\n\nconst isFiniteNumber = (v: unknown) => typeof v === 'number' && Number.isFinite(v);\n\n/**\n * What each XSD datatype accepts as a JavaScript value.\n *\n * This matters more than a normal type check: mutation literals are typed from\n * the *JavaScript* type when they reach SPARQL (`irToAlgebra`), not from the\n * declared datatype — a number becomes `xsd:integer`/`xsd:double`, a boolean\n * `xsd:boolean`, a `Date` `xsd:dateTime`, and a string an untyped literal. So a\n * string handed to an `xsd:integer` property does not merely skip a check, it\n * writes the wrong RDF term. Rejecting it is a correctness fix.\n *\n * `xsd:date` and `xsd:dateTime` take a `Date` and nothing else — one representation for a point\n * in time, rather than a JS object and a hand-written lexical string that behave differently.\n * The serializer derives the right lexical form from the declared datatype\n * (`irToAlgebra.dateToTerm`), so an `xsd:date` property gets `\"2020-06-15\"^^xsd:date` from the\n * same `Date` an `xsd:dateTime` property gets a full timestamp from.\n *\n * `xsd:time` is the exception, and takes a STRING. A `Date` cannot express a time of day without\n * inventing a date to carry it: the date half is meaningless, has to be discarded on\n * serialization, and makes two identical clock times on different days compare unequal. JS has\n * no time-only type — `Temporal.PlainTime` is the right answer and is not available yet — so the\n * lexical form is the honest representation. It is pattern-checked here, and `irToAlgebra` types\n * it from the declared datatype so it is written `\"10:30:00\"^^xsd:time` rather than as a plain\n * literal.\n *\n * Datatypes with no obvious JS counterpart (`xsd:duration`, `xsd:gYear`,\n * `xsd:Bytes`) are not checked.\n */\n/**\n * `HH:MM:SS` with optional milliseconds and optional timezone.\n *\n * Ranges are enforced by the pattern rather than parsed: hours 00-23, minutes and seconds 00-59,\n * so \"25:00:00\" is rejected where a looser `\\d{2}` would let it through and write a malformed\n * literal. The optional `Z`/offset is included because it is valid `xsd:time` — rejecting\n * \"14:30:00Z\" would make this stricter than the datatype it validates.\n */\nconst XSD_TIME_PATTERN = /^([01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(\\.\\d{1,3})?(Z|[+-]([01]\\d|2[0-3]):[0-5]\\d)?$/;\n\nconst DATATYPE_RULES: Record<string, {accepts: (v: unknown) => boolean; expected: string}> = {\n [xsd.string.id]: {accepts: (v) => typeof v === 'string', expected: 'a string'},\n [xsd.boolean.id]: {accepts: (v) => typeof v === 'boolean', expected: 'a boolean'},\n [xsd.integer.id]: {accepts: (v) => isFiniteNumber(v) && Number.isInteger(v), expected: 'a whole number'},\n [xsd.long.id]: {accepts: (v) => isFiniteNumber(v) && Number.isInteger(v), expected: 'a whole number'},\n [xsd.decimal.id]: {accepts: isFiniteNumber, expected: 'a number'},\n [xsd.float.id]: {accepts: isFiniteNumber, expected: 'a number'},\n [xsd.double.id]: {accepts: isFiniteNumber, expected: 'a number'},\n [xsd.date.id]: {accepts: (v) => v instanceof Date, expected: 'a Date'},\n [xsd.dateTime.id]: {accepts: (v) => v instanceof Date, expected: 'a Date'},\n [xsd.time.id]: {\n accepts: (v) => typeof v === 'string' && XSD_TIME_PATTERN.test(v),\n expected: 'a time string like \"14:30:00\", \"14:30:00.250\" or \"14:30:00Z\"',\n },\n};\n\n/** `sh:datatype` — the value's JavaScript type must match the declared datatype. */\nconst datatypeCheck: ConstraintCheck = (values, ctx) => {\n const ps = ctx.propertyShape;\n if (!ps.datatype) return [];\n const rule = DATATYPE_RULES[ps.datatype.id];\n if (!rule) return [];\n\n const results: ValidationResult[] = [];\n for (const el of values) {\n // A node reference is a node-kind problem, not a datatype one — one\n // violation per mistake, reported by the check that owns it.\n if (!isCheckableElement(el) || isNodeReference(el) || rule.accepts(el)) continue;\n results.push(\n violation(\n ctx,\n shacl.DatatypeConstraintComponent,\n `Property '${labelOf(ps)}' expects ${datatypeLabel(ps.datatype)} (${rule.expected}), but was given ${describeValue(el)}.`,\n el,\n ),\n );\n }\n return results;\n};\n\n/** The four `sh:min/maxInclusive/Exclusive` range constraints, on numbers. */\nconst rangeCheck: ConstraintCheck = (values, ctx) => {\n const ps = ctx.propertyShape;\n const bounds: {\n limit: unknown;\n component: NodeReferenceValue;\n ok: (v: number, limit: number) => boolean;\n phrase: string;\n }[] = [\n {limit: ps.minInclusive, component: shacl.MinInclusiveConstraintComponent, ok: (v, l) => v >= l, phrase: 'at least'},\n {limit: ps.maxInclusive, component: shacl.MaxInclusiveConstraintComponent, ok: (v, l) => v <= l, phrase: 'at most'},\n {limit: ps.minExclusive, component: shacl.MinExclusiveConstraintComponent, ok: (v, l) => v > l, phrase: 'greater than'},\n {limit: ps.maxExclusive, component: shacl.MaxExclusiveConstraintComponent, ok: (v, l) => v < l, phrase: 'less than'},\n ];\n const active = bounds.filter((b) => typeof b.limit === 'number');\n if (!active.length) return [];\n\n const results: ValidationResult[] = [];\n for (const el of values) {\n // Non-numbers are the datatype check's business.\n if (!isCheckableElement(el) || typeof el !== 'number') continue;\n for (const bound of active) {\n if (bound.ok(el, bound.limit as number)) continue;\n results.push(\n violation(\n ctx,\n bound.component,\n `Property '${labelOf(ps)}' must be ${bound.phrase} ${bound.limit}, but was given ${el}.`,\n el,\n ),\n );\n }\n }\n return results;\n};\n\n/** `sh:minLength` / `sh:maxLength`, on strings. */\nconst lengthCheck: ConstraintCheck = (values, ctx) => {\n const ps = ctx.propertyShape;\n if (typeof ps.minLength !== 'number' && typeof ps.maxLength !== 'number') return [];\n\n const results: ValidationResult[] = [];\n for (const el of values) {\n if (!isCheckableElement(el) || typeof el !== 'string') continue;\n if (typeof ps.minLength === 'number' && el.length < ps.minLength) {\n results.push(\n violation(\n ctx,\n shacl.MinLengthConstraintComponent,\n `Property '${labelOf(ps)}' must be at least ${ps.minLength} character(s), but was given ${el.length}.`,\n el,\n ),\n );\n }\n if (typeof ps.maxLength === 'number' && el.length > ps.maxLength) {\n results.push(\n violation(\n ctx,\n shacl.MaxLengthConstraintComponent,\n `Property '${labelOf(ps)}' must be at most ${ps.maxLength} character(s), but was given ${el.length}.`,\n el,\n ),\n );\n }\n }\n return results;\n};\n\n/** `sh:pattern` — the string form of the value must match the shape's regex. */\nconst patternCheck: ConstraintCheck = (values, ctx) => {\n const ps = ctx.propertyShape;\n if (!ps.pattern) return [];\n // Rebuild without `g`/`y`: those carry `lastIndex` between calls, so a shared\n // shape regex would match every other value.\n const regex = new RegExp(ps.pattern.source, ps.pattern.flags.replace(/[gy]/g, ''));\n\n const results: ValidationResult[] = [];\n for (const el of values) {\n if (!isCheckableElement(el) || typeof el !== 'string') continue;\n if (regex.test(el)) continue;\n results.push(\n violation(\n ctx,\n shacl.PatternConstraintComponent,\n `Property '${labelOf(ps)}' must match ${String(ps.pattern)}, but was given \"${el}\".`,\n el,\n ),\n );\n }\n return results;\n};\n\n/** `sh:in` — the value must be one of the shape's allowed values. */\nconst inCheck: ConstraintCheck = (values, ctx) => {\n const ps = ctx.propertyShape;\n if (!ps.in?.length) return [];\n const allowed = ps.in;\n const matches = (el: unknown) =>\n allowed.some((a) =>\n isNodeReferenceValue(a)\n ? isNodeReference(el) && (el as NodeReferenceValue).id === a.id\n : a === el,\n );\n\n const results: ValidationResult[] = [];\n for (const el of values) {\n if (!isCheckableElement(el) || matches(el)) continue;\n const rendered = allowed\n .map((a) => (isNodeReferenceValue(a) ? a.id : JSON.stringify(a)))\n .join(', ');\n results.push(\n violation(\n ctx,\n shacl.InConstraintComponent,\n `Property '${labelOf(ps)}' must be one of [${rendered}].`,\n el,\n ),\n );\n }\n return results;\n};\n\n/**\n * The registry. Every property-level constraint the library enforces lives here;\n * adding another SHACL component is one more entry plus its test.\n *\n * Split by what each kind of check needs to see. **Cardinality** needs the\n * property's whole value set, so it cannot run against a set modification —\n * `{add: […]}` changes a count that lives in the store. **Value** checks need\n * only the value in hand, so they run everywhere a concrete value appears,\n * including inside `add`.\n *\n * Cardinality runs first when it runs at all: a count problem explains itself\n * better than the per-value violations that would follow it.\n */\nconst CARDINALITY_CONSTRAINTS: ConstraintCheck[] = [maxCountCheck, minCountCheck];\n\nconst VALUE_CONSTRAINTS: ConstraintCheck[] = [\n nodeKindCheck,\n datatypeCheck,\n rangeCheck,\n lengthCheck,\n patternCheck,\n inCheck,\n];\n\nconst PROPERTY_CONSTRAINTS: ConstraintCheck[] = [\n ...CARDINALITY_CONSTRAINTS,\n ...VALUE_CONSTRAINTS,\n];\n\n// ---------------------------------------------------------------------------\n// Value classification\n// ---------------------------------------------------------------------------\n\n/**\n * A `{add, remove}` set modification. The resulting value count depends on the\n * node's current state, so cardinality and kind are unknowable here.\n */\nfunction isSetModification(value: unknown): boolean {\n if (typeof value !== 'object' || value === null) return false;\n const obj = value as Record<string, unknown>;\n const expected = (obj.add ? 1 : 0) + (obj.remove ? 1 : 0);\n return expected > 0 && Object.getOwnPropertyNames(obj).length === expected;\n}\n\n/** An object carrying only an `id` — a reference to an existing node, not a description. */\nfunction isNodeReference(value: unknown): boolean {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'id' in value &&\n Object.keys(value).length === 1\n );\n}\n\n/**\n * A value that stands for something resolved later — an expression, a query\n * context reference, a callback, or nothing at all.\n *\n * Must be ruled out *before* anything reads properties off the value: a resolved\n * context ref is a query proxy that throws on any undecorated key, so probing it\n * for `.add` is not a safe way to ask what it is.\n */\nfunction isDeferredValue(value: unknown): boolean {\n return (\n value === undefined ||\n typeof value === 'function' ||\n isExpressionNode(value) ||\n !!asContextRef(value)\n );\n}\n\n/** Values whose final shape isn't knowable without the store or a lowering pass. */\nfunction isOpaqueValue(value: unknown): boolean {\n return isDeferredValue(value) || isSetModification(value);\n}\n\n/** A nested node description — an object to descend into, rather than a leaf value. */\nfunction isNodeDescription(value: unknown): boolean {\n return (\n typeof value === 'object' &&\n value !== null &&\n !Array.isArray(value) &&\n !(value instanceof Date) &&\n !isNodeReference(value) &&\n !isOpaqueValue(value)\n );\n}\n\n// ---------------------------------------------------------------------------\n// Entry points\n// ---------------------------------------------------------------------------\n\n/**\n * What can be validated against: a shape class (`Person`) or the plain\n * `NodeShapeData` the decorators generate (`Person.shape`, or the same object\n * obtained anywhere else). The two are interchangeable — the class is unwrapped\n * to its `shape` and nothing else about it is read.\n */\nexport type ValidatableShape = NodeShapeData | {shape: NodeShapeData};\n\nfunction resolveShapeData(shape: ValidatableShape): NodeShapeData {\n const resolved = 'propertyShapes' in shape ? shape : (shape as {shape: NodeShapeData}).shape;\n if (!resolved) {\n throw new Error(\n 'validate() requires a node shape or a shape class with a static `shape`. ' +\n 'Did you pass an unregistered class (missing @linkedShape)?',\n );\n }\n return resolved as NodeShapeData;\n}\n\n/**\n * Validate a plain data object against a node shape.\n *\n * Never throws for invalid *data* — a violation is a result, not an exception.\n * (It does throw when the *shape* argument itself is unusable.)\n *\n * ```ts\n * const report = validate(Person, {name: ['a', 'b']});\n * report.conforms; // false\n * report.results[0].sourceConstraintComponent.id; // …shacl#MaxCountConstraintComponent\n * ```\n *\n * **A shape class is optional.** The plain `NodeShapeData` the decorators\n * generate validates identically, so a caller that only ever holds shape\n * objects needs no class reference:\n *\n * ```ts\n * validate(Person, data); // ≡\n * validate(Person.shape, data); // same report\n * ```\n *\n * That holds even though a shape object carries neither its inherited property\n * shapes (a subclass's `propertyShapes` holds only its own) nor its nested\n * shapes (`valueShape` is a bare `{id}`): both are resolved through the shape\n * registry by id. A shape whose id is not registered therefore cannot be fully\n * checked, and says so — see {@link unresolvedValueShapeMessage} and the\n * inherited-properties check in `validateNode` — rather than reporting a node\n * as conforming on the strength of a branch it could not look at.\n */\nexport function validate(\n shape: ValidatableShape,\n data: unknown,\n options: ValidateOptions = {},\n): ValidationReport {\n const {mode = 'complete', maxDepth = 10} = options;\n const results = validateNode(resolveShapeData(shape), data, {\n mode,\n maxDepth,\n depth: 0,\n prefix: '',\n });\n return {\n conforms: !results.some((r) => r.resultSeverity.id === shacl.Violation.id),\n results,\n };\n}\n\n/** {@link validate}, but throws a {@link ShapeValidationError} when the data doesn't conform. */\nexport function assertValid(\n shape: ValidatableShape,\n data: unknown,\n options: ValidateOptions = {},\n): void {\n const report = validate(shape, data, options);\n if (!report.conforms) throw new ShapeValidationError(report);\n}\n\n// ---------------------------------------------------------------------------\n// Walk\n// ---------------------------------------------------------------------------\n\ninterface WalkContext {\n mode: ValidationMode;\n maxDepth: number;\n depth: number;\n /** Dot-joined label path of the node being validated (`''` at the root). */\n prefix: string;\n focusNode?: string;\n}\n\nfunction validateNode(\n shape: NodeShapeData,\n data: unknown,\n ctx: WalkContext,\n): ValidationResult[] {\n if (typeof data !== 'object' || data === null || Array.isArray(data)) {\n return [\n nodeViolation(\n shape,\n ctx,\n shacl.NodeConstraintComponent,\n `Expected an object describing '${shape.label || shape.id}', but got ${data === null ? 'null' : typeof data}.`,\n ctx.prefix,\n data,\n ),\n ];\n }\n\n const obj = data as Record<string, unknown>;\n const propertyShapes = getUniquePropertyShapes(shape);\n const byLabel = new Map(propertyShapes.map((ps) => [ps.label, ps]));\n const focusNode =\n typeof obj.__id === 'string'\n ? obj.__id\n : typeof obj.id === 'string'\n ? obj.id\n : ctx.focusNode;\n const results: ValidationResult[] = [];\n\n // A shape declaring a superclass carries only its *own* property shapes; the\n // inherited ones are resolved through the registry by id. If this shape's id\n // is not registered, that resolution quietly yields half a shape — required\n // inherited properties go unchecked, and any that *are* supplied look\n // undeclared. Report it rather than let a partial shape pass as a clean bill.\n //\n // \"Registered\" means present in EITHER registry. Checking only for a class rejected\n // exactly the shapes the metamodel work exists to support: a data-only child is\n // registered, its parent resolves, and its inherited properties are checked — it simply\n // has no class, which is not a defect.\n if (shape.extends?.id && !getShapeClass(shape.id) && !getNodeShape(shape.id)) {\n results.push(\n nodeViolation(\n shape,\n {focusNode},\n shacl.NodeConstraintComponent,\n `Cannot resolve the properties '${shape.label || shape.id}' inherits from '${shape.extends.id}': shape '${shape.id}' is not registered, so only its own properties could be checked.`,\n ctx.prefix,\n ),\n );\n }\n\n // Presence of required properties — only decidable for a complete description.\n if (ctx.mode === 'complete') {\n for (const ps of propertyShapes) {\n if (typeof ps.minCount !== 'number' || ps.minCount <= 0) continue;\n if (ps.label in obj) continue;\n results.push(\n violation(\n {shape, propertyShape: ps, property: join(ctx.prefix, ps.label), focusNode, mode: ctx.mode},\n shacl.MinCountConstraintComponent,\n `Property '${labelOf(ps)}' requires at least ${ps.minCount} value(s), but none were provided.`,\n ),\n );\n }\n }\n\n // The values actually provided.\n for (const [key, value] of Object.entries(obj)) {\n if (RESERVED_KEYS.has(key)) continue;\n const propertyShape = byLabel.get(key);\n if (!propertyShape) {\n results.push(\n nodeViolation(\n shape,\n {...ctx, focusNode},\n shacl.ClosedConstraintComponent,\n undeclaredPropertyMessage(key, shape),\n join(ctx.prefix, key),\n value,\n ),\n );\n continue;\n }\n results.push(\n ...validateProperty(value, {\n shape,\n propertyShape,\n property: join(ctx.prefix, key),\n focusNode,\n mode: ctx.mode,\n }, ctx),\n );\n }\n\n return results;\n}\n\nfunction validateProperty(\n value: unknown,\n propCtx: PropertyContext,\n walk: WalkContext,\n): ValidationResult[] {\n const ps = propCtx.propertyShape;\n\n // `null` clears the property — the same as providing zero values, so clearing\n // a required one is a cardinality violation (both spellings behave alike).\n if (value === null) {\n if (typeof ps.minCount === 'number' && ps.minCount > 0) {\n return [\n violation(\n propCtx,\n shacl.MinCountConstraintComponent,\n `Property '${labelOf(ps)}' requires at least ${ps.minCount} value(s) and cannot be cleared.`,\n ),\n ];\n }\n return [];\n }\n\n // Ruled out first: reading `.add` off a resolved context proxy would throw.\n if (isDeferredValue(value)) return [];\n\n // A set modification adds to and removes from what the store already holds,\n // so the resulting *count* is unknowable here — but each added value is as\n // checkable as any other, and skipping them let mistyped literals through the\n // one door the rest of this module closes. `remove` takes `{id}` references\n // only, which normalization enforces on its own.\n if (isSetModification(value)) {\n const {add} = value as {add?: unknown};\n if (add === undefined) return [];\n return runChecks(VALUE_CONSTRAINTS, toValues(add), propCtx, walk);\n }\n\n return runChecks(PROPERTY_CONSTRAINTS, toValues(value), propCtx, walk);\n}\n\n/** A property's value(s) as an array — a single value becomes a one-element one. */\nfunction toValues(value: unknown): unknown[] {\n return Array.isArray(value) ? value : [value];\n}\n\n/**\n * Run a set of constraint checks over a property's values, then descend into any\n * nested node descriptions among them (`sh:node`-style recursion). A bare `{id}`\n * is a reference to an existing node and has nothing to validate; an object with\n * an id *and* data is a nested create with a predefined id.\n */\nfunction runChecks(\n checks: ConstraintCheck[],\n values: unknown[],\n propCtx: PropertyContext,\n walk: WalkContext,\n): ValidationResult[] {\n const results: ValidationResult[] = [];\n for (const check of checks) {\n results.push(...check(values, propCtx));\n }\n\n if (walk.depth < walk.maxDepth) {\n for (const el of values) {\n if (!isNodeDescription(el)) continue;\n const nestedShape = resolveValueShape(propCtx.propertyShape, el);\n if (!nestedShape) {\n // The value is a node description we have no shape for, so nothing about\n // it can be checked. Silently skipping would report the whole node as\n // conforming on the strength of a branch never looked at.\n results.push(\n violation(\n propCtx,\n shacl.NodeConstraintComponent,\n unresolvedValueShapeMessage(propCtx.propertyShape, propCtx.shape),\n ),\n );\n continue;\n }\n results.push(\n ...validateNode(nestedShape, el, {\n ...walk,\n depth: walk.depth + 1,\n prefix: propCtx.property,\n focusNode: undefined,\n }),\n );\n }\n }\n\n return results;\n}\n\n/**\n * Why a nested value could not be resolved to a shape — the property named one\n * that is not registered, or named none and the value did not carry one either.\n * Both are actionable, and they are fixed differently.\n */\nfunction unresolvedValueShapeMessage(ps: PropertyShapeData, owner: NodeShapeData): string {\n const label = labelOf(ps);\n return ps.valueShape\n ? `Cannot validate the value of '${label}': its shape '${ps.valueShape.id}' does not resolve ` +\n `(${describeUnresolved(unresolvedValueShapeDetails(ps, owner))}).`\n : `Cannot validate the value of '${label}' of '${owner.id}': the property declares no shape for its values. ` +\n `Add a 'shape' to its @objectProperty decorator, or give the value a 'shape' key.`;\n}\n\n/**\n * The shape a nested value should be validated against: the shape class carried\n * in the value's reserved `shape` key when the property declares no `valueShape`\n * or the key names a subclass of it, otherwise the declared `valueShape`. Mirrors\n * `convertUpdateValue`; returns undefined when neither is available.\n */\nfunction resolveValueShape(\n ps: PropertyShapeData,\n value: unknown,\n): NodeShapeData | undefined {\n const own = (value as {shape?: {shape?: NodeShapeData}}).shape?.shape;\n if (!ps.valueShape) return own;\n const declared = getQueryShapeClass(ps.valueShape)?.shape;\n // A value naming a subclass of the declared shape is validated as that subclass.\n if (own && declared && isSubShapeOf(own, declared)) return own;\n return declared;\n}\n\nfunction join(prefix: string, label: string): string {\n return prefix ? `${prefix}.${label}` : label;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"validation.js","sourceRoot":"","sources":["../../../src/shapes/validation.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,OAAO,EAAC,6BAA6B,EAAE,kBAAkB,EAAC,MAAM,wBAAwB,CAAC;AACzF,OAAO,EAAC,KAAK,EAAC,MAAM,wBAAwB,CAAC;AAC7C,OAAO,EAAC,gBAAgB,EAAC,MAAM,yBAAyB,CAAC;AACzD,OAAO,EAAC,GAAG,EAAC,MAAM,sBAAsB,CAAC;AACzC,OAAO,EAAC,oBAAoB,EAA0B,MAAM,2BAA2B,CAAC;AACxF,OAAO,EAAC,uBAAuB,EAAC,MAAM,oBAAoB,CAAC;AAE3D,OAAO,EAAC,YAAY,EAAE,aAAa,EAAE,YAAY,EAAC,MAAM,wBAAwB,CAAC;AACjF,OAAO,EAAC,gBAAgB,EAAC,MAAM,kCAAkC,CAAC;AAClE,OAAO,EAAC,YAAY,EAAC,MAAM,4BAA4B,CAAC;AACxD,OAAO,EAAC,kBAAkB,EAAE,2BAA2B,EAAC,MAAM,6BAA6B,CAAC;AAgF5F,6FAA6F;AAC7F,MAAM,OAAO,oBAAqB,SAAQ,KAAK;IAE7C,YAAY,MAAwB;QAClC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QAC7D,IAAI,CAAC,IAAI,GAAG,sBAAsB,CAAC;QACnC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;CACF;AACD,gBAAgB,CAAC,oBAAoB,EAAE,eAAe,EAAE,sBAAsB,CAAC,CAAC;AAEhF;;;;GAIG;AACH,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AAEvD;;;GAGG;AACH,MAAM,UAAU,yBAAyB,CAAC,GAAW,EAAE,KAAoB;;IACzE,MAAM,SAAS,GAAG,KAAK,CAAC,KAAK,KAAI,MAAA,KAAK,CAAC,EAAE,0CAAE,KAAK,CAAC,GAAG,EAAE,GAAG,EAAE,CAAA,CAAC;IAC5D,MAAM,IAAI,GACR,yBAAyB,GAAG,eAAe,SAAS,8BAA8B;QAClF,mFAAmF;QACnF,gDAAgD,CAAC;IAEnD,oFAAoF;IACpF,iFAAiF;IACjF,iFAAiF;IACjF,iFAAiF;IACjF,6EAA6E;IAC7E,MAAM,MAAM,GAAG,6BAA6B,EAAE,CAAC;IAC/C,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;QACf,OAAO,CACL,GAAG,IAAI,MAAM;YACb,SAAS,MAAM,qEAAqE;YACpF,oFAAoF;YACpF,sFAAsF;YACtF,qFAAqF,CACtF,CAAC;IACJ,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAsBD;;;;GAIG;AACH,SAAS,MAAM,CAAC,KAAc;IAC5B,IAAI,aAAa,CAAC,KAAK,CAAC;QAAE,OAAO,KAAoB,CAAC;IACtD,IAAI,eAAe,CAAC,KAAK,CAAC;QAAE,OAAO,EAAC,EAAE,EAAG,KAA4B,CAAC,EAAE,EAAC,CAAC;IAC1E,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;GAIG;AACH,SAAS,aAAa,CACpB,KAAoB,EACpB,GAAyB,EACzB,SAA6B,EAC7B,OAAe,EACf,YAAqB,EACrB,KAAe;IAEf,MAAM,MAAM,GAAqB;QAC/B,yBAAyB,EAAE,SAAS;QACpC,cAAc,EAAE,KAAK,CAAC,SAAS;QAC/B,aAAa,EAAE,OAAO;KACvB,CAAC;IACF,IAAI,GAAG,CAAC,SAAS;QAAE,MAAM,CAAC,SAAS,GAAG,EAAC,EAAE,EAAE,GAAG,CAAC,SAAS,EAAC,CAAC;IAC1D,IAAI,YAAY;QAAE,MAAM,CAAC,YAAY,GAAG,YAAY,CAAC;IACrD,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAC3B,IAAI,IAAI,KAAK,SAAS;QAAE,MAAM,CAAC,KAAK,GAAG,IAAI,CAAC;IAC5C,IAAI,KAAK,CAAC,EAAE;QAAE,MAAM,CAAC,WAAW,GAAG,EAAC,EAAE,EAAE,KAAK,CAAC,EAAE,EAAC,CAAC;IAClD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;GAGG;AACH,SAAS,SAAS,CAChB,GAAoB,EACpB,SAA6B,EAC7B,OAAe,EACf,KAAe;IAEf,MAAM,MAAM,GAAqB;QAC/B,yBAAyB,EAAE,SAAS;QACpC,cAAc,EAAE,KAAK,CAAC,SAAS;QAC/B,aAAa,EAAE,OAAO;KACvB,CAAC;IACF,IAAI,GAAG,CAAC,SAAS;QAAE,MAAM,CAAC,SAAS,GAAG,EAAC,EAAE,EAAE,GAAG,CAAC,SAAS,EAAC,CAAC;IAC1D,MAAM,IAAI,GAAG,GAAG,CAAC,aAAa,CAAC,IAAsC,CAAC;IACtE,IAAI,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,EAAE;QAAE,MAAM,CAAC,UAAU,GAAG,EAAC,EAAE,EAAE,IAAI,CAAC,EAAE,EAAC,CAAC;IAChD,IAAI,GAAG,CAAC,QAAQ;QAAE,MAAM,CAAC,YAAY,GAAG,GAAG,CAAC,QAAQ,CAAC;IACrD,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAC3B,IAAI,IAAI,KAAK,SAAS;QAAE,MAAM,CAAC,KAAK,GAAG,IAAI,CAAC;IAC5C,MAAM,WAAW,GAAG,GAAG,CAAC,aAAa,CAAC,EAAE,IAAI,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;IACzD,IAAI,WAAW;QAAE,MAAM,CAAC,WAAW,GAAG,EAAC,EAAE,EAAE,WAAW,EAAC,CAAC;IACxD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,kFAAkF;AAClF,SAAS,OAAO,CAAC,EAAqB;IACpC,OAAO,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC,EAAE,CAAC;AAC3B,CAAC;AAED,4DAA4D;AAC5D,MAAM,aAAa,GAAoB,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE;IACrD,MAAM,EAAC,QAAQ,EAAC,GAAG,GAAG,CAAC,aAAa,CAAC;IACrC,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,MAAM,CAAC,MAAM,IAAI,QAAQ;QAAE,OAAO,EAAE,CAAC;IACzE,OAAO;QACL,SAAS,CACP,GAAG,EACH,KAAK,CAAC,2BAA2B,EACjC,aAAa,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,oBAAoB,QAAQ,kBAAkB,MAAM,CAAC,MAAM,iBAAiB,CACpH;KACF,CAAC;AACJ,CAAC,CAAC;AAEF,qEAAqE;AACrE,MAAM,aAAa,GAAoB,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE;IACrD,MAAM,EAAC,QAAQ,EAAC,GAAG,GAAG,CAAC,aAAa,CAAC;IACrC,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,IAAI,CAAC,IAAI,MAAM,CAAC,MAAM,IAAI,QAAQ;QAAE,OAAO,EAAE,CAAC;IAC1F,OAAO;QACL,SAAS,CACP,GAAG,EACH,KAAK,CAAC,2BAA2B,EACjC,aAAa,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,uBAAuB,QAAQ,kBAAkB,MAAM,CAAC,MAAM,iBAAiB,CACvH;KACF,CAAC;AACJ,CAAC,CAAC;AAEF,kEAAkE;AAClE,SAAS,cAAc,CAAC,EAAqB;IAC3C,IAAI,EAAE,CAAC,QAAQ;QAAE,OAAO,EAAE,CAAC,QAAQ,CAAC,EAAE,KAAK,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC;IAC5D,OAAO,CAAC,CAAC,EAAE,CAAC,QAAQ,IAAI,CAAC,EAAE,CAAC,UAAU,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC;AACtD,CAAC;AAED;;;;GAIG;AACH,SAAS,WAAW,CAAC,EAAqB;IACxC,IAAI,EAAE,CAAC,QAAQ,EAAE,CAAC;QAChB,OAAO,CACL,EAAE,CAAC,QAAQ,CAAC,EAAE,KAAK,KAAK,CAAC,GAAG,CAAC,EAAE;YAC/B,EAAE,CAAC,QAAQ,CAAC,EAAE,KAAK,KAAK,CAAC,SAAS,CAAC,EAAE;YACrC,EAAE,CAAC,QAAQ,CAAC,EAAE,KAAK,KAAK,CAAC,cAAc,CAAC,EAAE,CAC3C,CAAC;IACJ,CAAC;IACD,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC;AACvC,CAAC;AAED,SAAS,aAAa,CAAC,KAAc;IACnC,OAAO,CACL,OAAO,KAAK,KAAK,QAAQ;QACzB,OAAO,KAAK,KAAK,QAAQ;QACzB,OAAO,KAAK,KAAK,SAAS;QAC1B,KAAK,YAAY,IAAI,CACtB,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,aAAa,GAAoB,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE;IACrD,MAAM,EAAE,GAAG,GAAG,CAAC,aAAa,CAAC;IAC7B,MAAM,eAAe,GAAG,cAAc,CAAC,EAAE,CAAC,CAAC;IAC3C,MAAM,YAAY,GAAG,WAAW,CAAC,EAAE,CAAC,CAAC;IACrC,IAAI,CAAC,eAAe,IAAI,CAAC,YAAY;QAAE,OAAO,EAAE,CAAC;IAEjD,MAAM,OAAO,GAAuB,EAAE,CAAC;IACvC,KAAK,MAAM,EAAE,IAAI,MAAM,EAAE,CAAC;QACxB,IAAI,CAAC,kBAAkB,CAAC,EAAE,CAAC;YAAE,SAAS;QACtC,MAAM,MAAM,GAAG,aAAa,CAAC,EAAE,CAAC,CAAC;QACjC,IAAI,eAAe,IAAI,CAAC,MAAM,EAAE,CAAC;YAC/B,OAAO,CAAC,IAAI,CACV,SAAS,CACP,GAAG,EACH,KAAK,CAAC,2BAA2B,EACjC,aAAa,OAAO,CAAC,EAAE,CAAC,2CAA2C,OAAO,EAAE,KAAK,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,OAAO,EAAE,SAAS,EAC9H,EAAE,CACH,CACF,CAAC;QACJ,CAAC;aAAM,IAAI,YAAY,IAAI,MAAM,EAAE,CAAC;YAClC,OAAO,CAAC,IAAI,CACV,SAAS,CACP,GAAG,EACH,KAAK,CAAC,2BAA2B,EACjC,aAAa,OAAO,CAAC,EAAE,CAAC,8DAA8D,OAAO,EAAE,iDAAiD,EAChJ,EAAE,CACH,CACF,CAAC;QACJ,CAAC;IACH,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC,CAAC;AAEF;;;GAGG;AACH,SAAS,kBAAkB,CAAC,EAAW;IACrC,OAAO,EAAE,KAAK,IAAI,IAAI,EAAE,KAAK,SAAS,IAAI,CAAC,gBAAgB,CAAC,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;AACvF,CAAC;AAED,MAAM,QAAQ,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;AAE1D,+EAA+E;AAC/E,SAAS,aAAa,CAAC,QAA4B;IACjD,OAAO,QAAQ,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC;QACrC,CAAC,CAAC,OAAO,QAAQ,CAAC,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE;QAC7C,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC;AAClB,CAAC;AAED,8EAA8E;AAC9E,SAAS,aAAa,CAAC,KAAc;IACnC,IAAI,KAAK,YAAY,IAAI;QAAE,OAAO,QAAQ,CAAC;IAC3C,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,UAAU,CAAC;IAC5C,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,kBAAkB,CAAC;IACtG,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,eAAe,CAAC;IACtD,OAAO,KAAK,OAAO,KAAK,EAAE,CAAC;AAC7B,CAAC;AAED,MAAM,cAAc,GAAG,CAAC,CAAU,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AAEnF;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH;;;;;;;GAOG;AACH,MAAM,gBAAgB,GAAG,+EAA+E,CAAC;AAEzG,MAAM,cAAc,GAAyE;IAC3F,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,EAAC,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAC;IAC9E,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,EAAC,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,SAAS,EAAE,QAAQ,EAAE,WAAW,EAAC;IACjF,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,EAAC,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,gBAAgB,EAAC;IACxG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAC,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,gBAAgB,EAAC;IACrG,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,EAAC,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,UAAU,EAAC;IACjE,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,EAAC,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,UAAU,EAAC;IAC/D,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,EAAC,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,UAAU,EAAC;IAChE,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAC,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,YAAY,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAC;IACtE,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,EAAC,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,YAAY,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAC;IAC1E,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE;QACb,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC;QACjE,QAAQ,EAAE,8DAA8D;KACzE;CACF,CAAC;AAEF,oFAAoF;AACpF,MAAM,aAAa,GAAoB,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE;IACrD,MAAM,EAAE,GAAG,GAAG,CAAC,aAAa,CAAC;IAC7B,IAAI,CAAC,EAAE,CAAC,QAAQ;QAAE,OAAO,EAAE,CAAC;IAC5B,MAAM,IAAI,GAAG,cAAc,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IAC5C,IAAI,CAAC,IAAI;QAAE,OAAO,EAAE,CAAC;IAErB,MAAM,OAAO,GAAuB,EAAE,CAAC;IACvC,KAAK,MAAM,EAAE,IAAI,MAAM,EAAE,CAAC;QACxB,oEAAoE;QACpE,6DAA6D;QAC7D,IAAI,CAAC,kBAAkB,CAAC,EAAE,CAAC,IAAI,eAAe,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;YAAE,SAAS;QACjF,OAAO,CAAC,IAAI,CACV,SAAS,CACP,GAAG,EACH,KAAK,CAAC,2BAA2B,EACjC,aAAa,OAAO,CAAC,EAAE,CAAC,aAAa,aAAa,CAAC,EAAE,CAAC,QAAQ,CAAC,KAAK,IAAI,CAAC,QAAQ,oBAAoB,aAAa,CAAC,EAAE,CAAC,GAAG,EACzH,EAAE,CACH,CACF,CAAC;IACJ,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC,CAAC;AAEF,8EAA8E;AAC9E,MAAM,UAAU,GAAoB,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE;IAClD,MAAM,EAAE,GAAG,GAAG,CAAC,aAAa,CAAC;IAC7B,MAAM,MAAM,GAKN;QACJ,EAAC,KAAK,EAAE,EAAE,CAAC,YAAY,EAAE,SAAS,EAAE,KAAK,CAAC,+BAA+B,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,UAAU,EAAC;QACpH,EAAC,KAAK,EAAE,EAAE,CAAC,YAAY,EAAE,SAAS,EAAE,KAAK,CAAC,+BAA+B,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,SAAS,EAAC;QACnH,EAAC,KAAK,EAAE,EAAE,CAAC,YAAY,EAAE,SAAS,EAAE,KAAK,CAAC,+BAA+B,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,cAAc,EAAC;QACvH,EAAC,KAAK,EAAE,EAAE,CAAC,YAAY,EAAE,SAAS,EAAE,KAAK,CAAC,+BAA+B,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,WAAW,EAAC;KACrH,CAAC;IACF,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC;IACjE,IAAI,CAAC,MAAM,CAAC,MAAM;QAAE,OAAO,EAAE,CAAC;IAE9B,MAAM,OAAO,GAAuB,EAAE,CAAC;IACvC,KAAK,MAAM,EAAE,IAAI,MAAM,EAAE,CAAC;QACxB,iDAAiD;QACjD,IAAI,CAAC,kBAAkB,CAAC,EAAE,CAAC,IAAI,OAAO,EAAE,KAAK,QAAQ;YAAE,SAAS;QAChE,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,IAAI,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,KAAK,CAAC,KAAe,CAAC;gBAAE,SAAS;YAClD,OAAO,CAAC,IAAI,CACV,SAAS,CACP,GAAG,EACH,KAAK,CAAC,SAAS,EACf,aAAa,OAAO,CAAC,EAAE,CAAC,aAAa,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,KAAK,mBAAmB,EAAE,GAAG,EACxF,EAAE,CACH,CACF,CAAC;QACJ,CAAC;IACH,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC,CAAC;AAEF,mDAAmD;AACnD,MAAM,WAAW,GAAoB,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE;IACnD,MAAM,EAAE,GAAG,GAAG,CAAC,aAAa,CAAC;IAC7B,IAAI,OAAO,EAAE,CAAC,SAAS,KAAK,QAAQ,IAAI,OAAO,EAAE,CAAC,SAAS,KAAK,QAAQ;QAAE,OAAO,EAAE,CAAC;IAEpF,MAAM,OAAO,GAAuB,EAAE,CAAC;IACvC,KAAK,MAAM,EAAE,IAAI,MAAM,EAAE,CAAC;QACxB,IAAI,CAAC,kBAAkB,CAAC,EAAE,CAAC,IAAI,OAAO,EAAE,KAAK,QAAQ;YAAE,SAAS;QAChE,IAAI,OAAO,EAAE,CAAC,SAAS,KAAK,QAAQ,IAAI,EAAE,CAAC,MAAM,GAAG,EAAE,CAAC,SAAS,EAAE,CAAC;YACjE,OAAO,CAAC,IAAI,CACV,SAAS,CACP,GAAG,EACH,KAAK,CAAC,4BAA4B,EAClC,aAAa,OAAO,CAAC,EAAE,CAAC,sBAAsB,EAAE,CAAC,SAAS,gCAAgC,EAAE,CAAC,MAAM,GAAG,EACtG,EAAE,CACH,CACF,CAAC;QACJ,CAAC;QACD,IAAI,OAAO,EAAE,CAAC,SAAS,KAAK,QAAQ,IAAI,EAAE,CAAC,MAAM,GAAG,EAAE,CAAC,SAAS,EAAE,CAAC;YACjE,OAAO,CAAC,IAAI,CACV,SAAS,CACP,GAAG,EACH,KAAK,CAAC,4BAA4B,EAClC,aAAa,OAAO,CAAC,EAAE,CAAC,qBAAqB,EAAE,CAAC,SAAS,gCAAgC,EAAE,CAAC,MAAM,GAAG,EACrG,EAAE,CACH,CACF,CAAC;QACJ,CAAC;IACH,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC,CAAC;AAEF,gFAAgF;AAChF,MAAM,YAAY,GAAoB,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE;IACpD,MAAM,EAAE,GAAG,GAAG,CAAC,aAAa,CAAC;IAC7B,IAAI,CAAC,EAAE,CAAC,OAAO;QAAE,OAAO,EAAE,CAAC;IAC3B,8EAA8E;IAC9E,6CAA6C;IAC7C,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;IAEnF,MAAM,OAAO,GAAuB,EAAE,CAAC;IACvC,KAAK,MAAM,EAAE,IAAI,MAAM,EAAE,CAAC;QACxB,IAAI,CAAC,kBAAkB,CAAC,EAAE,CAAC,IAAI,OAAO,EAAE,KAAK,QAAQ;YAAE,SAAS;QAChE,IAAI,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YAAE,SAAS;QAC7B,OAAO,CAAC,IAAI,CACV,SAAS,CACP,GAAG,EACH,KAAK,CAAC,0BAA0B,EAChC,aAAa,OAAO,CAAC,EAAE,CAAC,gBAAgB,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,oBAAoB,EAAE,IAAI,EACpF,EAAE,CACH,CACF,CAAC;IACJ,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC,CAAC;AAEF,qEAAqE;AACrE,MAAM,OAAO,GAAoB,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE;;IAC/C,MAAM,EAAE,GAAG,GAAG,CAAC,aAAa,CAAC;IAC7B,IAAI,CAAC,CAAA,MAAA,EAAE,CAAC,EAAE,0CAAE,MAAM,CAAA;QAAE,OAAO,EAAE,CAAC;IAC9B,MAAM,OAAO,GAAG,EAAE,CAAC,EAAE,CAAC;IACtB,MAAM,OAAO,GAAG,CAAC,EAAW,EAAE,EAAE,CAC9B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CACjB,oBAAoB,CAAC,CAAC,CAAC;QACrB,CAAC,CAAC,eAAe,CAAC,EAAE,CAAC,IAAK,EAAyB,CAAC,EAAE,KAAK,CAAC,CAAC,EAAE;QAC/D,CAAC,CAAC,CAAC,KAAK,EAAE,CACb,CAAC;IAEJ,MAAM,OAAO,GAAuB,EAAE,CAAC;IACvC,KAAK,MAAM,EAAE,IAAI,MAAM,EAAE,CAAC;QACxB,IAAI,CAAC,kBAAkB,CAAC,EAAE,CAAC,IAAI,OAAO,CAAC,EAAE,CAAC;YAAE,SAAS;QACrD,MAAM,QAAQ,GAAG,OAAO;aACrB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;aAChE,IAAI,CAAC,IAAI,CAAC,CAAC;QACd,OAAO,CAAC,IAAI,CACV,SAAS,CACP,GAAG,EACH,KAAK,CAAC,qBAAqB,EAC3B,aAAa,OAAO,CAAC,EAAE,CAAC,qBAAqB,QAAQ,IAAI,EACzD,EAAE,CACH,CACF,CAAC;IACJ,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,MAAM,uBAAuB,GAAsB,CAAC,aAAa,EAAE,aAAa,CAAC,CAAC;AAElF,MAAM,iBAAiB,GAAsB;IAC3C,aAAa;IACb,aAAa;IACb,UAAU;IACV,WAAW;IACX,YAAY;IACZ,OAAO;CACR,CAAC;AAEF,MAAM,oBAAoB,GAAsB;IAC9C,GAAG,uBAAuB;IAC1B,GAAG,iBAAiB;CACrB,CAAC;AAEF,8EAA8E;AAC9E,uBAAuB;AACvB,8EAA8E;AAE9E;;;GAGG;AACH,SAAS,iBAAiB,CAAC,KAAc;IACvC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IAC9D,MAAM,GAAG,GAAG,KAAgC,CAAC;IAC7C,MAAM,QAAQ,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1D,OAAO,QAAQ,GAAG,CAAC,IAAI,MAAM,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC,MAAM,KAAK,QAAQ,CAAC;AAC7E,CAAC;AAED,4FAA4F;AAC5F,SAAS,eAAe,CAAC,KAAc;IACrC,OAAO,CACL,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,KAAK,IAAI;QACd,IAAI,IAAI,KAAK;QACb,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,KAAK,CAAC,CAChC,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,eAAe,CAAC,KAAc;IACrC,OAAO,CACL,KAAK,KAAK,SAAS;QACnB,OAAO,KAAK,KAAK,UAAU;QAC3B,gBAAgB,CAAC,KAAK,CAAC;QACvB,CAAC,CAAC,YAAY,CAAC,KAAK,CAAC,CACtB,CAAC;AACJ,CAAC;AAED,oFAAoF;AACpF,SAAS,aAAa,CAAC,KAAc;IACnC,OAAO,eAAe,CAAC,KAAK,CAAC,IAAI,iBAAiB,CAAC,KAAK,CAAC,CAAC;AAC5D,CAAC;AAED,uFAAuF;AACvF,SAAS,iBAAiB,CAAC,KAAc;IACvC,OAAO,CACL,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,KAAK,IAAI;QACd,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QACrB,CAAC,CAAC,KAAK,YAAY,IAAI,CAAC;QACxB,CAAC,eAAe,CAAC,KAAK,CAAC;QACvB,CAAC,aAAa,CAAC,KAAK,CAAC,CACtB,CAAC;AACJ,CAAC;AAcD,SAAS,gBAAgB,CAAC,KAAuB;IAC/C,MAAM,QAAQ,GAAG,gBAAgB,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAE,KAAgC,CAAC,KAAK,CAAC;IAC7F,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,KAAK,CACb,2EAA2E;YACzE,4DAA4D,CAC/D,CAAC;IACJ,CAAC;IACD,OAAO,QAAyB,CAAC;AACnC,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,MAAM,UAAU,QAAQ,CACtB,KAAuB,EACvB,IAAa,EACb,UAA2B,EAAE;IAE7B,MAAM,EAAC,IAAI,GAAG,UAAU,EAAE,QAAQ,GAAG,EAAE,EAAC,GAAG,OAAO,CAAC;IACnD,MAAM,OAAO,GAAG,YAAY,CAAC,gBAAgB,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE;QAC1D,IAAI;QACJ,QAAQ;QACR,KAAK,EAAE,CAAC;QACR,MAAM,EAAE,EAAE;KACX,CAAC,CAAC;IACH,OAAO;QACL,QAAQ,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,cAAc,CAAC,EAAE,KAAK,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC;QAC1E,OAAO;KACR,CAAC;AACJ,CAAC;AAED,iGAAiG;AACjG,MAAM,UAAU,WAAW,CACzB,KAAuB,EACvB,IAAa,EACb,UAA2B,EAAE;IAE7B,MAAM,MAAM,GAAG,QAAQ,CAAC,KAAK,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;IAC9C,IAAI,CAAC,MAAM,CAAC,QAAQ;QAAE,MAAM,IAAI,oBAAoB,CAAC,MAAM,CAAC,CAAC;AAC/D,CAAC;AAeD,SAAS,YAAY,CACnB,KAAoB,EACpB,IAAa,EACb,GAAgB;;IAEhB,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QACrE,OAAO;YACL,aAAa,CACX,KAAK,EACL,GAAG,EACH,KAAK,CAAC,uBAAuB,EAC7B,kCAAkC,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,EAAE,cAAc,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,IAAI,GAAG,EAC9G,GAAG,CAAC,MAAM,EACV,IAAI,CACL;SACF,CAAC;IACJ,CAAC;IAED,MAAM,GAAG,GAAG,IAA+B,CAAC;IAC5C,MAAM,cAAc,GAAG,uBAAuB,CAAC,KAAK,CAAC,CAAC;IACtD,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;IACpE,MAAM,SAAS,GACb,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ;QAC1B,CAAC,CAAC,GAAG,CAAC,IAAI;QACV,CAAC,CAAC,OAAO,GAAG,CAAC,EAAE,KAAK,QAAQ;YAC1B,CAAC,CAAC,GAAG,CAAC,EAAE;YACR,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC;IACtB,MAAM,OAAO,GAAuB,EAAE,CAAC;IAEvC,6EAA6E;IAC7E,6EAA6E;IAC7E,4EAA4E;IAC5E,sEAAsE;IACtE,8EAA8E;IAC9E,EAAE;IACF,oFAAoF;IACpF,gFAAgF;IAChF,wFAAwF;IACxF,uCAAuC;IACvC,IAAI,CAAA,MAAA,KAAK,CAAC,OAAO,0CAAE,EAAE,KAAI,CAAC,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC;QAC7E,OAAO,CAAC,IAAI,CACV,aAAa,CACX,KAAK,EACL,EAAC,SAAS,EAAC,EACX,KAAK,CAAC,uBAAuB,EAC7B,kCAAkC,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,EAAE,oBAAoB,KAAK,CAAC,OAAO,CAAC,EAAE,aAAa,KAAK,CAAC,EAAE,mEAAmE,EACrL,GAAG,CAAC,MAAM,CACX,CACF,CAAC;IACJ,CAAC;IAED,+EAA+E;IAC/E,IAAI,GAAG,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;QAC5B,KAAK,MAAM,EAAE,IAAI,cAAc,EAAE,CAAC;YAChC,IAAI,OAAO,EAAE,CAAC,QAAQ,KAAK,QAAQ,IAAI,EAAE,CAAC,QAAQ,IAAI,CAAC;gBAAE,SAAS;YAClE,IAAI,EAAE,CAAC,KAAK,IAAI,GAAG;gBAAE,SAAS;YAC9B,OAAO,CAAC,IAAI,CACV,SAAS,CACP,EAAC,KAAK,EAAE,aAAa,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAC,EAC3F,KAAK,CAAC,2BAA2B,EACjC,aAAa,OAAO,CAAC,EAAE,CAAC,uBAAuB,EAAE,CAAC,QAAQ,oCAAoC,CAC/F,CACF,CAAC;QACJ,CAAC;IACH,CAAC;IAED,gCAAgC;IAChC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QAC/C,IAAI,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,SAAS;QACrC,MAAM,aAAa,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACvC,IAAI,CAAC,aAAa,EAAE,CAAC;YACnB,OAAO,CAAC,IAAI,CACV,aAAa,CACX,KAAK,kCACD,GAAG,KAAE,SAAS,KAClB,KAAK,CAAC,yBAAyB,EAC/B,yBAAyB,CAAC,GAAG,EAAE,KAAK,CAAC,EACrC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,EACrB,KAAK,CACN,CACF,CAAC;YACF,SAAS;QACX,CAAC;QACD,OAAO,CAAC,IAAI,CACV,GAAG,gBAAgB,CAAC,KAAK,EAAE;YACzB,KAAK;YACL,aAAa;YACb,QAAQ,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC;YAC/B,SAAS;YACT,IAAI,EAAE,GAAG,CAAC,IAAI;SACf,EAAE,GAAG,CAAC,CACR,CAAC;IACJ,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,gBAAgB,CACvB,KAAc,EACd,OAAwB,EACxB,IAAiB;IAEjB,MAAM,EAAE,GAAG,OAAO,CAAC,aAAa,CAAC;IAEjC,8EAA8E;IAC9E,2EAA2E;IAC3E,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QACnB,IAAI,OAAO,EAAE,CAAC,QAAQ,KAAK,QAAQ,IAAI,EAAE,CAAC,QAAQ,GAAG,CAAC,EAAE,CAAC;YACvD,OAAO;gBACL,SAAS,CACP,OAAO,EACP,KAAK,CAAC,2BAA2B,EACjC,aAAa,OAAO,CAAC,EAAE,CAAC,uBAAuB,EAAE,CAAC,QAAQ,kCAAkC,CAC7F;aACF,CAAC;QACJ,CAAC;QACD,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,4EAA4E;IAC5E,IAAI,eAAe,CAAC,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAEtC,4EAA4E;IAC5E,2EAA2E;IAC3E,8EAA8E;IAC9E,4EAA4E;IAC5E,iDAAiD;IACjD,IAAI,iBAAiB,CAAC,KAAK,CAAC,EAAE,CAAC;QAC7B,MAAM,EAAC,GAAG,EAAC,GAAG,KAAwB,CAAC;QACvC,IAAI,GAAG,KAAK,SAAS;YAAE,OAAO,EAAE,CAAC;QACjC,OAAO,SAAS,CAAC,iBAAiB,EAAE,QAAQ,CAAC,GAAG,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;IACpE,CAAC;IAED,OAAO,SAAS,CAAC,oBAAoB,EAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;AACzE,CAAC;AAED,oFAAoF;AACpF,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;AAChD,CAAC;AAED;;;;;GAKG;AACH,SAAS,SAAS,CAChB,MAAyB,EACzB,MAAiB,EACjB,OAAwB,EACxB,IAAiB;IAEjB,MAAM,OAAO,GAAuB,EAAE,CAAC;IACvC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,OAAO,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAC1C,CAAC;IAED,IAAI,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC/B,KAAK,MAAM,EAAE,IAAI,MAAM,EAAE,CAAC;YACxB,IAAI,CAAC,iBAAiB,CAAC,EAAE,CAAC;gBAAE,SAAS;YACrC,MAAM,WAAW,GAAG,iBAAiB,CAAC,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC;YACjE,IAAI,CAAC,WAAW,EAAE,CAAC;gBACjB,yEAAyE;gBACzE,sEAAsE;gBACtE,0DAA0D;gBAC1D,OAAO,CAAC,IAAI,CACV,SAAS,CACP,OAAO,EACP,KAAK,CAAC,uBAAuB,EAC7B,2BAA2B,CAAC,OAAO,CAAC,aAAa,EAAE,OAAO,CAAC,KAAK,CAAC,CAClE,CACF,CAAC;gBACF,SAAS;YACX,CAAC;YACD,OAAO,CAAC,IAAI,CACV,GAAG,YAAY,CAAC,WAAW,EAAE,EAAE,kCAC1B,IAAI,KACP,KAAK,EAAE,IAAI,CAAC,KAAK,GAAG,CAAC,EACrB,MAAM,EAAE,OAAO,CAAC,QAAQ,EACxB,SAAS,EAAE,SAAS,IACpB,CACH,CAAC;QACJ,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;GAIG;AACH,SAAS,2BAA2B,CAAC,EAAqB,EAAE,KAAoB;IAC9E,MAAM,KAAK,GAAG,OAAO,CAAC,EAAE,CAAC,CAAC;IAC1B,MAAM,GAAG,GAAG,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,kBAAkB,CAAC,2BAA2B,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC5F,OAAO,EAAE,CAAC,UAAU;QAClB,CAAC,CAAC,iCAAiC,KAAK,iBAAiB,EAAE,CAAC,UAAU,CAAC,EAAE,oBAAoB;YACzF,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC;QAC9B,CAAC,CAAC,iCAAiC,KAAK,SAAS,KAAK,CAAC,EAAE,oDAAoD;YACzG,kFAAkF,CAAC;AAC3F,CAAC;AAED;;;;;GAKG;AACH,SAAS,iBAAiB,CACxB,EAAqB,EACrB,KAAc;;IAEd,MAAM,GAAG,GAAG,MAAC,KAA2C,CAAC,KAAK,0CAAE,KAAK,CAAC;IACtE,IAAI,CAAC,EAAE,CAAC,UAAU;QAAE,OAAO,GAAG,CAAC;IAC/B,MAAM,QAAQ,GAAG,MAAA,kBAAkB,CAAC,EAAE,CAAC,UAAU,CAAC,0CAAE,KAAK,CAAC;IAC1D,iFAAiF;IACjF,IAAI,GAAG,IAAI,QAAQ,IAAI,YAAY,CAAC,GAAG,EAAE,QAAQ,CAAC;QAAE,OAAO,GAAG,CAAC;IAC/D,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,SAAS,IAAI,CAAC,MAAc,EAAE,KAAa;IACzC,OAAO,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC;AAC/C,CAAC","sourcesContent":["/*\n * This Source Code Form is subject to the terms of the Mozilla Public\n * License, v. 2.0. If a copy of the MPL was not distributed with this\n * file, You can obtain one at https://mozilla.org/MPL/2.0/.\n */\n/**\n * SHACL-aligned validation of plain data objects against a node shape.\n *\n * One entry point — {@link validate} — used by the create and update pipelines\n * (via `MutationQueryFactory.describe()`) and directly by callers that want to\n * know how well an object fits a shape without building a mutation.\n *\n * **Shape of the output.** This library has no triple/Turtle layer and this\n * module does not add one: a {@link ValidationReport} is plain JavaScript. It is\n * however 1-1 with the SHACL vocabulary — one key per SHACL property, named\n * after it, holding a value the mutation pipeline accepts (a literal, or a\n * `{id}` node reference for IRI-valued properties). So a report can be\n * materialized by an ordinary create query as soon as shape classes for\n * `sh:ValidationReport` / `sh:ValidationResult` exist, with no transform step:\n *\n * ```ts\n * const report = validate(Slide, data);\n * await ValidationReport.create(report); // once those shape classes exist\n * ```\n *\n * Two deliberate departures, both documented on the types: `results` is plural\n * where SHACL's repeated property is `sh:result`, and `propertyPath` is a\n * non-SHACL locator. Both map cleanly — a shape class chooses its own labels for\n * SHACL paths, and an extension property is legal on a SHACL report.\n *\n * **Coverage.** Cardinality (`sh:minCount` / `sh:maxCount`), node kind (literal\n * vs relation), undeclared properties (as `sh:closed`), `sh:datatype`, the four\n * `sh:min/maxInclusive/Exclusive` bounds, `sh:min/maxLength`, `sh:pattern` and\n * `sh:in`. Each is one entry in {@link CARDINALITY_CONSTRAINTS} or\n * {@link VALUE_CONSTRAINTS}, so adding another is one function and one test.\n *\n * Not covered: `sh:languageIn` / `sh:uniqueLang` (skipped at serialization time\n * too, so there is no metadata to check against) and `sh:hasValue`.\n */\nimport {getShapeRegistryInstanceCount, getQueryShapeClass} from '../utils/ShapeClass.js';\nimport {shacl} from '../ontologies/shacl.js';\nimport {brandLinkedError} from '../utils/linkedError.js';\nimport {xsd} from '../ontologies/xsd.js';\nimport {isNodeReferenceValue, type NodeReferenceValue} from '../utils/NodeReference.js';\nimport {getUniquePropertyShapes} from './nodeShapeData.js';\nimport type {NodeShapeData, PropertyShapeData} from './nodeShapeData.js';\nimport {getNodeShape, getShapeClass, isSubShapeOf} from '../utils/ShapeClass.js';\nimport {isExpressionNode} from '../expressions/ExpressionNode.js';\nimport {asContextRef} from '../queries/QueryContext.js';\nimport {describeUnresolved, unresolvedValueShapeDetails} from '../utils/unresolvedShape.js';\n\n/**\n * Which constraints apply to the data being validated.\n *\n * - `complete` — the object describes a whole node (a create, or a standalone\n * object being checked for fit). Properties absent from the data are genuinely\n * absent, so `sh:minCount` presence is checkable.\n * - `partial` — the object describes a change to an existing node (an update).\n * The store holds whatever the payload does not mention, so presence is\n * unknowable; only the values actually provided are checked.\n */\nexport type ValidationMode = 'complete' | 'partial';\n\n/**\n * A single constraint violation — an `sh:ValidationResult`.\n *\n * Every key is the local name of the SHACL property it carries, and every value\n * is in a form the create pipeline accepts (a literal, or a `{id}` node\n * reference for IRI-valued properties). A shape class declaring these\n * properties therefore materializes a result with no transform step:\n * `ValidationResult.create(result)`. The one non-SHACL key is `propertyPath`;\n * see {@link ValidationReport}.\n */\nexport interface ValidationResult {\n /** `sh:focusNode` — the node the violation is about, when its id is known. */\n focusNode?: NodeReferenceValue;\n /** `sh:resultPath` — the IRI of the property the violation is about. */\n resultPath?: NodeReferenceValue;\n /**\n * `sh:value` — the offending value, present only when it is an RDF term (a\n * literal or a node reference). Cardinality violations are about the property\n * rather than any one value, so they carry none.\n */\n value?: LiteralTerm | NodeReferenceValue;\n /** `sh:sourceShape` — the node or property shape carrying the constraint. */\n sourceShape?: NodeReferenceValue;\n /** `sh:sourceConstraintComponent` — which SHACL constraint failed. */\n sourceConstraintComponent: NodeReferenceValue;\n /** `sh:resultSeverity` — `sh:Violation`, `sh:Warning` or `sh:Info`. */\n resultSeverity: NodeReferenceValue;\n /** `sh:resultMessage` — human-readable explanation. */\n resultMessage: string;\n /**\n * **Not SHACL.** The property's label, dot-joined through nested shapes\n * (`author.fullName`) — the locator a caller needs to point at a field in the\n * object they passed in, which `sh:resultPath` alone cannot give (it names the\n * property, not where the nesting reached it). Materializes like any other\n * property once a shape class declares it; drop it for a pure-SHACL result.\n */\n propertyPath?: string;\n}\n\n/**\n * The outcome of a validation run — an `sh:ValidationReport`.\n *\n * Plain objects, 1-1 with the SHACL vocabulary, so a report can later be\n * materialized through an ordinary create query against shape classes for\n * `sh:ValidationReport` / `sh:ValidationResult` — whether or not this library\n * ever ships those classes. `results` is the sole plural rename (SHACL's\n * property is `sh:result`, repeated); a shape class maps it with\n * `@objectProperty({path: shacl.result, …}) get results()`.\n */\nexport interface ValidationReport {\n /** `sh:conforms` — true when there are no `sh:Violation`-severity results. */\n conforms: boolean;\n /** `sh:result` — every violation found, in deterministic order. */\n results: ValidationResult[];\n}\n\n/** The literal types the mutation pipeline accepts as a value. */\ntype LiteralTerm = string | number | boolean | Date;\n\nexport interface ValidateOptions {\n /** Defaults to `complete`. */\n mode?: ValidationMode;\n /** How deep to descend into nested node descriptions. Defaults to 10. */\n maxDepth?: number;\n}\n\n/** Thrown by {@link assertValid} — carries the full report, not just the first violation. */\nexport class ShapeValidationError extends Error {\n readonly report: ValidationReport;\n constructor(report: ValidationReport) {\n super(report.results.map((r) => r.resultMessage).join('\\n'));\n this.name = 'ShapeValidationError';\n this.report = report;\n }\n}\nbrandLinkedError(ShapeValidationError, '@_linked/core', 'ShapeValidationError');\n\n/**\n * Keys that carry metadata about the node rather than a property value: `id` /\n * `__id` name it, and `shape` names the shape of a nested value when the\n * property shape itself doesn't declare one (see `convertUpdateValue`).\n */\nconst RESERVED_KEYS = new Set(['id', '__id', 'shape']);\n\n/**\n * The message for an undeclared property key. Shared with the normalization path\n * in `MutationQuery`, which needs the same guard to build a field at all.\n */\nexport function undeclaredPropertyMessage(key: string, shape: NodeShapeData): string {\n const shapeName = shape.label || shape.id?.split('/').pop();\n const base =\n `Invalid property key: ${key}. The shape ${shapeName} does not have a registered ` +\n `property with this name. Make sure the get/set method exists, and that it uses a ` +\n `@objectProperty or @literalProperty decorator.`;\n\n // If more than one copy of the shape registry module has evaluated, this message is\n // very probably lying: the property IS declared, on a copy this code cannot see.\n // Saying so here is the whole point — the previous version of this error accused\n // correct application code, and finding the real cause took a day of eliminating\n // innocent suspects. See docs/reports/043-module-identity-in-the-backend.md.\n const copies = getShapeRegistryInstanceCount();\n if (copies > 1) {\n return (\n `${base}\\n\\n` +\n `NOTE: ${copies} copies of the shape registry have loaded in this process. If this ` +\n `property is declared, it almost certainly registered on a different copy than the ` +\n `one validating here, and the declaration is not the problem. This happens when part ` +\n `of the app resolves a framework package to its source and part to its built output.`\n );\n }\n return base;\n}\n\n// ---------------------------------------------------------------------------\n// Constraint components\n// ---------------------------------------------------------------------------\n\n/** What a constraint check needs to know about the property it is checking. */\ninterface PropertyContext {\n shape: NodeShapeData;\n propertyShape: PropertyShapeData;\n /** Dot-joined label path from the root of the validated object. */\n property: string;\n focusNode?: string;\n mode: ValidationMode;\n}\n\n/**\n * A constraint check. Receives the property's values already normalized to an\n * array (a single value becomes a one-element array) and returns any violations.\n */\ntype ConstraintCheck = (values: unknown[], ctx: PropertyContext) => ValidationResult[];\n\n/**\n * `sh:value` must be an RDF term. A literal or a node reference is one; a plain\n * object, array or function is not, so it is left off rather than emitted as\n * something no store could materialize — the message still names it.\n */\nfunction asTerm(value: unknown): LiteralTerm | NodeReferenceValue | undefined {\n if (isScalarValue(value)) return value as LiteralTerm;\n if (isNodeReference(value)) return {id: (value as NodeReferenceValue).id};\n return undefined;\n}\n\n/**\n * A violation about the node itself rather than one of its property shapes —\n * `sh:sourceShape` is the node shape, and there is no `sh:resultPath` (an\n * undeclared key has no property IRI to point at).\n */\nfunction nodeViolation(\n shape: NodeShapeData,\n ctx: {focusNode?: string},\n component: NodeReferenceValue,\n message: string,\n propertyPath?: string,\n value?: unknown,\n): ValidationResult {\n const result: ValidationResult = {\n sourceConstraintComponent: component,\n resultSeverity: shacl.Violation,\n resultMessage: message,\n };\n if (ctx.focusNode) result.focusNode = {id: ctx.focusNode};\n if (propertyPath) result.propertyPath = propertyPath;\n const term = asTerm(value);\n if (term !== undefined) result.value = term;\n if (shape.id) result.sourceShape = {id: shape.id};\n return result;\n}\n\n/**\n * Build a result, omitting absent keys entirely — an `undefined` value is not a\n * property the create pipeline should see.\n */\nfunction violation(\n ctx: PropertyContext,\n component: NodeReferenceValue,\n message: string,\n value?: unknown,\n): ValidationResult {\n const result: ValidationResult = {\n sourceConstraintComponent: component,\n resultSeverity: shacl.Violation,\n resultMessage: message,\n };\n if (ctx.focusNode) result.focusNode = {id: ctx.focusNode};\n const path = ctx.propertyShape.path as NodeReferenceValue | undefined;\n if (path?.id) result.resultPath = {id: path.id};\n if (ctx.property) result.propertyPath = ctx.property;\n const term = asTerm(value);\n if (term !== undefined) result.value = term;\n const sourceShape = ctx.propertyShape.id || ctx.shape.id;\n if (sourceShape) result.sourceShape = {id: sourceShape};\n return result;\n}\n\n/** The label used in messages — the property's own label, not its nested path. */\nfunction labelOf(ps: PropertyShapeData): string {\n return ps.label || ps.id;\n}\n\n/** `sh:maxCount` — no more values than the shape allows. */\nconst maxCountCheck: ConstraintCheck = (values, ctx) => {\n const {maxCount} = ctx.propertyShape;\n if (typeof maxCount !== 'number' || values.length <= maxCount) return [];\n return [\n violation(\n ctx,\n shacl.MaxCountConstraintComponent,\n `Property '${labelOf(ctx.propertyShape)}' allows at most ${maxCount} value(s), but ${values.length} were provided.`,\n ),\n ];\n};\n\n/** `sh:minCount` — at least as many values as the shape requires. */\nconst minCountCheck: ConstraintCheck = (values, ctx) => {\n const {minCount} = ctx.propertyShape;\n if (typeof minCount !== 'number' || minCount <= 0 || values.length >= minCount) return [];\n return [\n violation(\n ctx,\n shacl.MinCountConstraintComponent,\n `Property '${labelOf(ctx.propertyShape)}' requires at least ${minCount} value(s), but ${values.length} were provided.`,\n ),\n ];\n};\n\n/** True when the property clearly accepts only literal values. */\nfunction expectsLiteral(ps: PropertyShapeData): boolean {\n if (ps.nodeKind) return ps.nodeKind.id === shacl.Literal.id;\n return !!ps.datatype && !ps.valueShape && !ps.class;\n}\n\n/**\n * True when the property clearly accepts only nodes (IRIs/blank nodes). `sh:class` counts\n * as much as `sh:node`: a value that is an instance of a class is a node, whether or not\n * the property names a shape for it.\n */\nfunction expectsNode(ps: PropertyShapeData): boolean {\n if (ps.nodeKind) {\n return (\n ps.nodeKind.id === shacl.IRI.id ||\n ps.nodeKind.id === shacl.BlankNode.id ||\n ps.nodeKind.id === shacl.BlankNodeOrIRI.id\n );\n }\n return !!(ps.valueShape || ps.class);\n}\n\nfunction isScalarValue(value: unknown): boolean {\n return (\n typeof value === 'string' ||\n typeof value === 'number' ||\n typeof value === 'boolean' ||\n value instanceof Date\n );\n}\n\n/**\n * `sh:nodeKind` — literal properties reject nodes/objects, relation properties\n * reject bare scalars. Ambiguous kinds (`sh:IRIOrLiteral`, or no `nodeKind` and\n * no `datatype`/`valueShape`/`class` to infer from) are not enforced.\n */\nconst nodeKindCheck: ConstraintCheck = (values, ctx) => {\n const ps = ctx.propertyShape;\n const literalExpected = expectsLiteral(ps);\n const nodeExpected = expectsNode(ps);\n if (!literalExpected && !nodeExpected) return [];\n\n const results: ValidationResult[] = [];\n for (const el of values) {\n if (!isCheckableElement(el)) continue;\n const scalar = isScalarValue(el);\n if (literalExpected && !scalar) {\n results.push(\n violation(\n ctx,\n shacl.NodeKindConstraintComponent,\n `Property '${labelOf(ps)}' is a literal property but was given a ${typeof el === 'object' ? 'node/object' : typeof el} value.`,\n el,\n ),\n );\n } else if (nodeExpected && scalar) {\n results.push(\n violation(\n ctx,\n shacl.NodeKindConstraintComponent,\n `Property '${labelOf(ps)}' is a relation (object) property but was given a literal (${typeof el}). Provide a {id} reference or a nested object.`,\n el,\n ),\n );\n }\n }\n return results;\n};\n\n/**\n * An element worth checking: a concrete value rather than something whose final\n * form is decided elsewhere (an expression, a context ref, an absent value).\n */\nfunction isCheckableElement(el: unknown): boolean {\n return el !== null && el !== undefined && !isExpressionNode(el) && !asContextRef(el);\n}\n\nconst XSD_BASE = xsd.string.id.slice(0, -'string'.length);\n\n/** `xsd:integer` rather than the full IRI, when the datatype is an XSD one. */\nfunction datatypeLabel(datatype: NodeReferenceValue): string {\n return datatype.id.startsWith(XSD_BASE)\n ? `xsd:${datatype.id.slice(XSD_BASE.length)}`\n : datatype.id;\n}\n\n/** How a value reads in a message — its JS kind, which is what went wrong. */\nfunction describeValue(value: unknown): string {\n if (value instanceof Date) return 'a Date';\n if (Array.isArray(value)) return 'an array';\n if (typeof value === 'number') return Number.isInteger(value) ? 'a whole number' : 'a decimal number';\n if (typeof value === 'object') return 'a node/object';\n return `a ${typeof value}`;\n}\n\nconst isFiniteNumber = (v: unknown) => typeof v === 'number' && Number.isFinite(v);\n\n/**\n * What each XSD datatype accepts as a JavaScript value.\n *\n * This matters more than a normal type check: mutation literals are typed from\n * the *JavaScript* type when they reach SPARQL (`irToAlgebra`), not from the\n * declared datatype — a number becomes `xsd:integer`/`xsd:double`, a boolean\n * `xsd:boolean`, a `Date` `xsd:dateTime`, and a string an untyped literal. So a\n * string handed to an `xsd:integer` property does not merely skip a check, it\n * writes the wrong RDF term. Rejecting it is a correctness fix.\n *\n * `xsd:date` and `xsd:dateTime` take a `Date` and nothing else — one representation for a point\n * in time, rather than a JS object and a hand-written lexical string that behave differently.\n * The serializer derives the right lexical form from the declared datatype\n * (`irToAlgebra.dateToTerm`), so an `xsd:date` property gets `\"2020-06-15\"^^xsd:date` from the\n * same `Date` an `xsd:dateTime` property gets a full timestamp from.\n *\n * `xsd:time` is the exception, and takes a STRING. A `Date` cannot express a time of day without\n * inventing a date to carry it: the date half is meaningless, has to be discarded on\n * serialization, and makes two identical clock times on different days compare unequal. JS has\n * no time-only type — `Temporal.PlainTime` is the right answer and is not available yet — so the\n * lexical form is the honest representation. It is pattern-checked here, and `irToAlgebra` types\n * it from the declared datatype so it is written `\"10:30:00\"^^xsd:time` rather than as a plain\n * literal.\n *\n * Datatypes with no obvious JS counterpart (`xsd:duration`, `xsd:gYear`,\n * `xsd:Bytes`) are not checked.\n */\n/**\n * `HH:MM:SS` with optional milliseconds and optional timezone.\n *\n * Ranges are enforced by the pattern rather than parsed: hours 00-23, minutes and seconds 00-59,\n * so \"25:00:00\" is rejected where a looser `\\d{2}` would let it through and write a malformed\n * literal. The optional `Z`/offset is included because it is valid `xsd:time` — rejecting\n * \"14:30:00Z\" would make this stricter than the datatype it validates.\n */\nconst XSD_TIME_PATTERN = /^([01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(\\.\\d{1,3})?(Z|[+-]([01]\\d|2[0-3]):[0-5]\\d)?$/;\n\nconst DATATYPE_RULES: Record<string, {accepts: (v: unknown) => boolean; expected: string}> = {\n [xsd.string.id]: {accepts: (v) => typeof v === 'string', expected: 'a string'},\n [xsd.boolean.id]: {accepts: (v) => typeof v === 'boolean', expected: 'a boolean'},\n [xsd.integer.id]: {accepts: (v) => isFiniteNumber(v) && Number.isInteger(v), expected: 'a whole number'},\n [xsd.long.id]: {accepts: (v) => isFiniteNumber(v) && Number.isInteger(v), expected: 'a whole number'},\n [xsd.decimal.id]: {accepts: isFiniteNumber, expected: 'a number'},\n [xsd.float.id]: {accepts: isFiniteNumber, expected: 'a number'},\n [xsd.double.id]: {accepts: isFiniteNumber, expected: 'a number'},\n [xsd.date.id]: {accepts: (v) => v instanceof Date, expected: 'a Date'},\n [xsd.dateTime.id]: {accepts: (v) => v instanceof Date, expected: 'a Date'},\n [xsd.time.id]: {\n accepts: (v) => typeof v === 'string' && XSD_TIME_PATTERN.test(v),\n expected: 'a time string like \"14:30:00\", \"14:30:00.250\" or \"14:30:00Z\"',\n },\n};\n\n/** `sh:datatype` — the value's JavaScript type must match the declared datatype. */\nconst datatypeCheck: ConstraintCheck = (values, ctx) => {\n const ps = ctx.propertyShape;\n if (!ps.datatype) return [];\n const rule = DATATYPE_RULES[ps.datatype.id];\n if (!rule) return [];\n\n const results: ValidationResult[] = [];\n for (const el of values) {\n // A node reference is a node-kind problem, not a datatype one — one\n // violation per mistake, reported by the check that owns it.\n if (!isCheckableElement(el) || isNodeReference(el) || rule.accepts(el)) continue;\n results.push(\n violation(\n ctx,\n shacl.DatatypeConstraintComponent,\n `Property '${labelOf(ps)}' expects ${datatypeLabel(ps.datatype)} (${rule.expected}), but was given ${describeValue(el)}.`,\n el,\n ),\n );\n }\n return results;\n};\n\n/** The four `sh:min/maxInclusive/Exclusive` range constraints, on numbers. */\nconst rangeCheck: ConstraintCheck = (values, ctx) => {\n const ps = ctx.propertyShape;\n const bounds: {\n limit: unknown;\n component: NodeReferenceValue;\n ok: (v: number, limit: number) => boolean;\n phrase: string;\n }[] = [\n {limit: ps.minInclusive, component: shacl.MinInclusiveConstraintComponent, ok: (v, l) => v >= l, phrase: 'at least'},\n {limit: ps.maxInclusive, component: shacl.MaxInclusiveConstraintComponent, ok: (v, l) => v <= l, phrase: 'at most'},\n {limit: ps.minExclusive, component: shacl.MinExclusiveConstraintComponent, ok: (v, l) => v > l, phrase: 'greater than'},\n {limit: ps.maxExclusive, component: shacl.MaxExclusiveConstraintComponent, ok: (v, l) => v < l, phrase: 'less than'},\n ];\n const active = bounds.filter((b) => typeof b.limit === 'number');\n if (!active.length) return [];\n\n const results: ValidationResult[] = [];\n for (const el of values) {\n // Non-numbers are the datatype check's business.\n if (!isCheckableElement(el) || typeof el !== 'number') continue;\n for (const bound of active) {\n if (bound.ok(el, bound.limit as number)) continue;\n results.push(\n violation(\n ctx,\n bound.component,\n `Property '${labelOf(ps)}' must be ${bound.phrase} ${bound.limit}, but was given ${el}.`,\n el,\n ),\n );\n }\n }\n return results;\n};\n\n/** `sh:minLength` / `sh:maxLength`, on strings. */\nconst lengthCheck: ConstraintCheck = (values, ctx) => {\n const ps = ctx.propertyShape;\n if (typeof ps.minLength !== 'number' && typeof ps.maxLength !== 'number') return [];\n\n const results: ValidationResult[] = [];\n for (const el of values) {\n if (!isCheckableElement(el) || typeof el !== 'string') continue;\n if (typeof ps.minLength === 'number' && el.length < ps.minLength) {\n results.push(\n violation(\n ctx,\n shacl.MinLengthConstraintComponent,\n `Property '${labelOf(ps)}' must be at least ${ps.minLength} character(s), but was given ${el.length}.`,\n el,\n ),\n );\n }\n if (typeof ps.maxLength === 'number' && el.length > ps.maxLength) {\n results.push(\n violation(\n ctx,\n shacl.MaxLengthConstraintComponent,\n `Property '${labelOf(ps)}' must be at most ${ps.maxLength} character(s), but was given ${el.length}.`,\n el,\n ),\n );\n }\n }\n return results;\n};\n\n/** `sh:pattern` — the string form of the value must match the shape's regex. */\nconst patternCheck: ConstraintCheck = (values, ctx) => {\n const ps = ctx.propertyShape;\n if (!ps.pattern) return [];\n // Rebuild without `g`/`y`: those carry `lastIndex` between calls, so a shared\n // shape regex would match every other value.\n const regex = new RegExp(ps.pattern.source, ps.pattern.flags.replace(/[gy]/g, ''));\n\n const results: ValidationResult[] = [];\n for (const el of values) {\n if (!isCheckableElement(el) || typeof el !== 'string') continue;\n if (regex.test(el)) continue;\n results.push(\n violation(\n ctx,\n shacl.PatternConstraintComponent,\n `Property '${labelOf(ps)}' must match ${String(ps.pattern)}, but was given \"${el}\".`,\n el,\n ),\n );\n }\n return results;\n};\n\n/** `sh:in` — the value must be one of the shape's allowed values. */\nconst inCheck: ConstraintCheck = (values, ctx) => {\n const ps = ctx.propertyShape;\n if (!ps.in?.length) return [];\n const allowed = ps.in;\n const matches = (el: unknown) =>\n allowed.some((a) =>\n isNodeReferenceValue(a)\n ? isNodeReference(el) && (el as NodeReferenceValue).id === a.id\n : a === el,\n );\n\n const results: ValidationResult[] = [];\n for (const el of values) {\n if (!isCheckableElement(el) || matches(el)) continue;\n const rendered = allowed\n .map((a) => (isNodeReferenceValue(a) ? a.id : JSON.stringify(a)))\n .join(', ');\n results.push(\n violation(\n ctx,\n shacl.InConstraintComponent,\n `Property '${labelOf(ps)}' must be one of [${rendered}].`,\n el,\n ),\n );\n }\n return results;\n};\n\n/**\n * The registry. Every property-level constraint the library enforces lives here;\n * adding another SHACL component is one more entry plus its test.\n *\n * Split by what each kind of check needs to see. **Cardinality** needs the\n * property's whole value set, so it cannot run against a set modification —\n * `{add: […]}` changes a count that lives in the store. **Value** checks need\n * only the value in hand, so they run everywhere a concrete value appears,\n * including inside `add`.\n *\n * Cardinality runs first when it runs at all: a count problem explains itself\n * better than the per-value violations that would follow it.\n */\nconst CARDINALITY_CONSTRAINTS: ConstraintCheck[] = [maxCountCheck, minCountCheck];\n\nconst VALUE_CONSTRAINTS: ConstraintCheck[] = [\n nodeKindCheck,\n datatypeCheck,\n rangeCheck,\n lengthCheck,\n patternCheck,\n inCheck,\n];\n\nconst PROPERTY_CONSTRAINTS: ConstraintCheck[] = [\n ...CARDINALITY_CONSTRAINTS,\n ...VALUE_CONSTRAINTS,\n];\n\n// ---------------------------------------------------------------------------\n// Value classification\n// ---------------------------------------------------------------------------\n\n/**\n * A `{add, remove}` set modification. The resulting value count depends on the\n * node's current state, so cardinality and kind are unknowable here.\n */\nfunction isSetModification(value: unknown): boolean {\n if (typeof value !== 'object' || value === null) return false;\n const obj = value as Record<string, unknown>;\n const expected = (obj.add ? 1 : 0) + (obj.remove ? 1 : 0);\n return expected > 0 && Object.getOwnPropertyNames(obj).length === expected;\n}\n\n/** An object carrying only an `id` — a reference to an existing node, not a description. */\nfunction isNodeReference(value: unknown): boolean {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'id' in value &&\n Object.keys(value).length === 1\n );\n}\n\n/**\n * A value that stands for something resolved later — an expression, a query\n * context reference, a callback, or nothing at all.\n *\n * Must be ruled out *before* anything reads properties off the value: a resolved\n * context ref is a query proxy that throws on any undecorated key, so probing it\n * for `.add` is not a safe way to ask what it is.\n */\nfunction isDeferredValue(value: unknown): boolean {\n return (\n value === undefined ||\n typeof value === 'function' ||\n isExpressionNode(value) ||\n !!asContextRef(value)\n );\n}\n\n/** Values whose final shape isn't knowable without the store or a lowering pass. */\nfunction isOpaqueValue(value: unknown): boolean {\n return isDeferredValue(value) || isSetModification(value);\n}\n\n/** A nested node description — an object to descend into, rather than a leaf value. */\nfunction isNodeDescription(value: unknown): boolean {\n return (\n typeof value === 'object' &&\n value !== null &&\n !Array.isArray(value) &&\n !(value instanceof Date) &&\n !isNodeReference(value) &&\n !isOpaqueValue(value)\n );\n}\n\n// ---------------------------------------------------------------------------\n// Entry points\n// ---------------------------------------------------------------------------\n\n/**\n * What can be validated against: a shape class (`Person`) or the plain\n * `NodeShapeData` the decorators generate (`Person.shape`, or the same object\n * obtained anywhere else). The two are interchangeable — the class is unwrapped\n * to its `shape` and nothing else about it is read.\n */\nexport type ValidatableShape = NodeShapeData | {shape: NodeShapeData};\n\nfunction resolveShapeData(shape: ValidatableShape): NodeShapeData {\n const resolved = 'propertyShapes' in shape ? shape : (shape as {shape: NodeShapeData}).shape;\n if (!resolved) {\n throw new Error(\n 'validate() requires a node shape or a shape class with a static `shape`. ' +\n 'Did you pass an unregistered class (missing @linkedShape)?',\n );\n }\n return resolved as NodeShapeData;\n}\n\n/**\n * Validate a plain data object against a node shape.\n *\n * Never throws for invalid *data* — a violation is a result, not an exception.\n * (It does throw when the *shape* argument itself is unusable.)\n *\n * ```ts\n * const report = validate(Person, {name: ['a', 'b']});\n * report.conforms; // false\n * report.results[0].sourceConstraintComponent.id; // …shacl#MaxCountConstraintComponent\n * ```\n *\n * **A shape class is optional.** The plain `NodeShapeData` the decorators\n * generate validates identically, so a caller that only ever holds shape\n * objects needs no class reference:\n *\n * ```ts\n * validate(Person, data); // ≡\n * validate(Person.shape, data); // same report\n * ```\n *\n * That holds even though a shape object carries neither its inherited property\n * shapes (a subclass's `propertyShapes` holds only its own) nor its nested\n * shapes (`valueShape` is a bare `{id}`): both are resolved through the shape\n * registry by id. A shape whose id is not registered therefore cannot be fully\n * checked, and says so — see {@link unresolvedValueShapeMessage} and the\n * inherited-properties check in `validateNode` — rather than reporting a node\n * as conforming on the strength of a branch it could not look at.\n */\nexport function validate(\n shape: ValidatableShape,\n data: unknown,\n options: ValidateOptions = {},\n): ValidationReport {\n const {mode = 'complete', maxDepth = 10} = options;\n const results = validateNode(resolveShapeData(shape), data, {\n mode,\n maxDepth,\n depth: 0,\n prefix: '',\n });\n return {\n conforms: !results.some((r) => r.resultSeverity.id === shacl.Violation.id),\n results,\n };\n}\n\n/** {@link validate}, but throws a {@link ShapeValidationError} when the data doesn't conform. */\nexport function assertValid(\n shape: ValidatableShape,\n data: unknown,\n options: ValidateOptions = {},\n): void {\n const report = validate(shape, data, options);\n if (!report.conforms) throw new ShapeValidationError(report);\n}\n\n// ---------------------------------------------------------------------------\n// Walk\n// ---------------------------------------------------------------------------\n\ninterface WalkContext {\n mode: ValidationMode;\n maxDepth: number;\n depth: number;\n /** Dot-joined label path of the node being validated (`''` at the root). */\n prefix: string;\n focusNode?: string;\n}\n\nfunction validateNode(\n shape: NodeShapeData,\n data: unknown,\n ctx: WalkContext,\n): ValidationResult[] {\n if (typeof data !== 'object' || data === null || Array.isArray(data)) {\n return [\n nodeViolation(\n shape,\n ctx,\n shacl.NodeConstraintComponent,\n `Expected an object describing '${shape.label || shape.id}', but got ${data === null ? 'null' : typeof data}.`,\n ctx.prefix,\n data,\n ),\n ];\n }\n\n const obj = data as Record<string, unknown>;\n const propertyShapes = getUniquePropertyShapes(shape);\n const byLabel = new Map(propertyShapes.map((ps) => [ps.label, ps]));\n const focusNode =\n typeof obj.__id === 'string'\n ? obj.__id\n : typeof obj.id === 'string'\n ? obj.id\n : ctx.focusNode;\n const results: ValidationResult[] = [];\n\n // A shape declaring a superclass carries only its *own* property shapes; the\n // inherited ones are resolved through the registry by id. If this shape's id\n // is not registered, that resolution quietly yields half a shape — required\n // inherited properties go unchecked, and any that *are* supplied look\n // undeclared. Report it rather than let a partial shape pass as a clean bill.\n //\n // \"Registered\" means present in EITHER registry. Checking only for a class rejected\n // exactly the shapes the metamodel work exists to support: a data-only child is\n // registered, its parent resolves, and its inherited properties are checked — it simply\n // has no class, which is not a defect.\n if (shape.extends?.id && !getShapeClass(shape.id) && !getNodeShape(shape.id)) {\n results.push(\n nodeViolation(\n shape,\n {focusNode},\n shacl.NodeConstraintComponent,\n `Cannot resolve the properties '${shape.label || shape.id}' inherits from '${shape.extends.id}': shape '${shape.id}' is not registered, so only its own properties could be checked.`,\n ctx.prefix,\n ),\n );\n }\n\n // Presence of required properties — only decidable for a complete description.\n if (ctx.mode === 'complete') {\n for (const ps of propertyShapes) {\n if (typeof ps.minCount !== 'number' || ps.minCount <= 0) continue;\n if (ps.label in obj) continue;\n results.push(\n violation(\n {shape, propertyShape: ps, property: join(ctx.prefix, ps.label), focusNode, mode: ctx.mode},\n shacl.MinCountConstraintComponent,\n `Property '${labelOf(ps)}' requires at least ${ps.minCount} value(s), but none were provided.`,\n ),\n );\n }\n }\n\n // The values actually provided.\n for (const [key, value] of Object.entries(obj)) {\n if (RESERVED_KEYS.has(key)) continue;\n const propertyShape = byLabel.get(key);\n if (!propertyShape) {\n results.push(\n nodeViolation(\n shape,\n {...ctx, focusNode},\n shacl.ClosedConstraintComponent,\n undeclaredPropertyMessage(key, shape),\n join(ctx.prefix, key),\n value,\n ),\n );\n continue;\n }\n results.push(\n ...validateProperty(value, {\n shape,\n propertyShape,\n property: join(ctx.prefix, key),\n focusNode,\n mode: ctx.mode,\n }, ctx),\n );\n }\n\n return results;\n}\n\nfunction validateProperty(\n value: unknown,\n propCtx: PropertyContext,\n walk: WalkContext,\n): ValidationResult[] {\n const ps = propCtx.propertyShape;\n\n // `null` clears the property — the same as providing zero values, so clearing\n // a required one is a cardinality violation (both spellings behave alike).\n if (value === null) {\n if (typeof ps.minCount === 'number' && ps.minCount > 0) {\n return [\n violation(\n propCtx,\n shacl.MinCountConstraintComponent,\n `Property '${labelOf(ps)}' requires at least ${ps.minCount} value(s) and cannot be cleared.`,\n ),\n ];\n }\n return [];\n }\n\n // Ruled out first: reading `.add` off a resolved context proxy would throw.\n if (isDeferredValue(value)) return [];\n\n // A set modification adds to and removes from what the store already holds,\n // so the resulting *count* is unknowable here — but each added value is as\n // checkable as any other, and skipping them let mistyped literals through the\n // one door the rest of this module closes. `remove` takes `{id}` references\n // only, which normalization enforces on its own.\n if (isSetModification(value)) {\n const {add} = value as {add?: unknown};\n if (add === undefined) return [];\n return runChecks(VALUE_CONSTRAINTS, toValues(add), propCtx, walk);\n }\n\n return runChecks(PROPERTY_CONSTRAINTS, toValues(value), propCtx, walk);\n}\n\n/** A property's value(s) as an array — a single value becomes a one-element one. */\nfunction toValues(value: unknown): unknown[] {\n return Array.isArray(value) ? value : [value];\n}\n\n/**\n * Run a set of constraint checks over a property's values, then descend into any\n * nested node descriptions among them (`sh:node`-style recursion). A bare `{id}`\n * is a reference to an existing node and has nothing to validate; an object with\n * an id *and* data is a nested create with a predefined id.\n */\nfunction runChecks(\n checks: ConstraintCheck[],\n values: unknown[],\n propCtx: PropertyContext,\n walk: WalkContext,\n): ValidationResult[] {\n const results: ValidationResult[] = [];\n for (const check of checks) {\n results.push(...check(values, propCtx));\n }\n\n if (walk.depth < walk.maxDepth) {\n for (const el of values) {\n if (!isNodeDescription(el)) continue;\n const nestedShape = resolveValueShape(propCtx.propertyShape, el);\n if (!nestedShape) {\n // The value is a node description we have no shape for, so nothing about\n // it can be checked. Silently skipping would report the whole node as\n // conforming on the strength of a branch never looked at.\n results.push(\n violation(\n propCtx,\n shacl.NodeConstraintComponent,\n unresolvedValueShapeMessage(propCtx.propertyShape, propCtx.shape),\n ),\n );\n continue;\n }\n results.push(\n ...validateNode(nestedShape, el, {\n ...walk,\n depth: walk.depth + 1,\n prefix: propCtx.property,\n focusNode: undefined,\n }),\n );\n }\n }\n\n return results;\n}\n\n/**\n * Why a nested value could not be resolved to a shape — the property named one\n * that is not registered, or named none and the value did not carry one either.\n * Both are actionable, and they are fixed differently.\n */\nfunction unresolvedValueShapeMessage(ps: PropertyShapeData, owner: NodeShapeData): string {\n const label = labelOf(ps);\n const why = ps.valueShape ? describeUnresolved(unresolvedValueShapeDetails(ps, owner)) : '';\n return ps.valueShape\n ? `Cannot validate the value of '${label}': its shape '${ps.valueShape.id}' does not resolve` +\n (why ? ` (${why}).` : '.')\n : `Cannot validate the value of '${label}' of '${owner.id}': the property declares no shape for its values. ` +\n `Add a 'shape' to its @objectProperty decorator, or give the value a 'shape' key.`;\n}\n\n/**\n * The shape a nested value should be validated against: the shape class carried\n * in the value's reserved `shape` key when the property declares no `valueShape`\n * or the key names a subclass of it, otherwise the declared `valueShape`. Mirrors\n * `convertUpdateValue`; returns undefined when neither is available.\n */\nfunction resolveValueShape(\n ps: PropertyShapeData,\n value: unknown,\n): NodeShapeData | undefined {\n const own = (value as {shape?: {shape?: NodeShapeData}}).shape?.shape;\n if (!ps.valueShape) return own;\n const declared = getQueryShapeClass(ps.valueShape)?.shape;\n // A value naming a subclass of the declared shape is validated as that subclass.\n if (own && declared && isSubShapeOf(own, declared)) return own;\n return declared;\n}\n\nfunction join(prefix: string, label: string): string {\n return prefix ? `${prefix}.${label}` : label;\n}\n"]}
|
|
@@ -6,7 +6,8 @@ export interface IErrorLogger {
|
|
|
6
6
|
* Install any error client package like lincd-sentry in your app to log errors.
|
|
7
7
|
*/
|
|
8
8
|
export declare class LinkedErrorLogging {
|
|
9
|
-
private static logger;
|
|
9
|
+
private static get logger();
|
|
10
|
+
private static set logger(value);
|
|
10
11
|
static setDefaultLogger(logger: IErrorLogger): void;
|
|
11
12
|
static hasDefaultLogger(): boolean;
|
|
12
13
|
static log(error: Error): Promise<void>;
|
|
@@ -1,8 +1,19 @@
|
|
|
1
|
+
import { sharedState } from './sharedState.js';
|
|
2
|
+
/** The logger, shared so one set through any copy of core (e.g. by `@_linked/sentry`) logs for all. */
|
|
3
|
+
const loggingState = sharedState('@_linked/core', 'LinkedErrorLogging', () => ({
|
|
4
|
+
logger: undefined,
|
|
5
|
+
}));
|
|
1
6
|
/**
|
|
2
7
|
* Utility class to log errors.
|
|
3
8
|
* Install any error client package like lincd-sentry in your app to log errors.
|
|
4
9
|
*/
|
|
5
10
|
export class LinkedErrorLogging {
|
|
11
|
+
static get logger() {
|
|
12
|
+
return loggingState.logger;
|
|
13
|
+
}
|
|
14
|
+
static set logger(logger) {
|
|
15
|
+
loggingState.logger = logger;
|
|
16
|
+
}
|
|
6
17
|
static setDefaultLogger(logger) {
|
|
7
18
|
this.logger = logger;
|
|
8
19
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LinkedErrorLogging.js","sourceRoot":"","sources":["../../../src/utils/LinkedErrorLogging.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"LinkedErrorLogging.js","sourceRoot":"","sources":["../../../src/utils/LinkedErrorLogging.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,WAAW,EAAC,MAAM,kBAAkB,CAAC;AAM7C,uGAAuG;AACvG,MAAM,YAAY,GAAG,WAAW,CAAC,eAAe,EAAE,oBAAoB,EAAE,GAAG,EAAE,CAAC,CAAC;IAC7E,MAAM,EAAE,SAAqC;CAC9C,CAAC,CAAC,CAAC;AAEJ;;;GAGG;AACH,MAAM,OAAO,kBAAkB;IACrB,MAAM,KAAK,MAAM;QACvB,OAAO,YAAY,CAAC,MAAM,CAAC;IAC7B,CAAC;IACO,MAAM,KAAK,MAAM,CAAC,MAAgC;QACxD,YAAY,CAAC,MAAM,GAAG,MAAM,CAAC;IAC/B,CAAC;IAED,MAAM,CAAC,gBAAgB,CAAC,MAAoB;QAC1C,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAED,MAAM,CAAC,gBAAgB;QACrB,OAAO,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC;IAC7B,CAAC;IAED,MAAM,CAAC,GAAG,CAAC,KAAY;QACrB,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAChC,CAAC;IACH,CAAC;CACF","sourcesContent":["import {sharedState} from './sharedState.js';\n\nexport interface IErrorLogger {\n log?(error: any): Promise<void>;\n}\n\n/** The logger, shared so one set through any copy of core (e.g. by `@_linked/sentry`) logs for all. */\nconst loggingState = sharedState('@_linked/core', 'LinkedErrorLogging', () => ({\n logger: undefined as IErrorLogger | undefined,\n}));\n\n/**\n * Utility class to log errors.\n * Install any error client package like lincd-sentry in your app to log errors.\n */\nexport class LinkedErrorLogging {\n private static get logger(): IErrorLogger | undefined {\n return loggingState.logger;\n }\n private static set logger(logger: IErrorLogger | undefined) {\n loggingState.logger = logger;\n }\n\n static setDefaultLogger(logger: IErrorLogger) {\n this.logger = logger;\n }\n\n static hasDefaultLogger() {\n return this.logger && true;\n }\n\n static log(error: Error) {\n if (this.logger) {\n return this.logger.log(error);\n }\n }\n}\n"]}
|
|
@@ -24,12 +24,14 @@ export interface FileStorePurposeListing {
|
|
|
24
24
|
configured: boolean;
|
|
25
25
|
}
|
|
26
26
|
export declare abstract class LinkedFileStorage {
|
|
27
|
-
private static defaultStore;
|
|
28
|
-
private static
|
|
27
|
+
private static get defaultStore();
|
|
28
|
+
private static set defaultStore(value);
|
|
29
|
+
private static get url();
|
|
30
|
+
private static set url(value);
|
|
29
31
|
/** Purpose → the store configured for it. */
|
|
30
|
-
private static stores;
|
|
32
|
+
private static get stores();
|
|
31
33
|
/** Every declared purpose, configured or not. */
|
|
32
|
-
private static purposes;
|
|
34
|
+
private static get purposes();
|
|
33
35
|
/** Purposes already reported as falling back, so the log fires once each. */
|
|
34
36
|
private static loggedFallbacks;
|
|
35
37
|
static get accessURL(): string;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { sharedState } from './sharedState.js';
|
|
1
2
|
/**
|
|
2
3
|
* Well-known file store purposes shipped with core.
|
|
3
4
|
*
|
|
@@ -12,7 +13,40 @@ export const FileStorePurposes = {
|
|
|
12
13
|
/** Built app bundles published by `linked build-app`. */
|
|
13
14
|
appAssets: 'appAssets',
|
|
14
15
|
};
|
|
16
|
+
/**
|
|
17
|
+
* The configured stores, shared by every copy of core in the runtime: the server configures
|
|
18
|
+
* them through one copy and an upload may reach them through another.
|
|
19
|
+
*/
|
|
20
|
+
const storageState = sharedState('@_linked/core', 'LinkedFileStorage', () => ({
|
|
21
|
+
defaultStore: undefined,
|
|
22
|
+
/** The default accessURL, used while no default store is set. */
|
|
23
|
+
url: undefined,
|
|
24
|
+
/** Purpose → the store configured for it. */
|
|
25
|
+
stores: new Map(),
|
|
26
|
+
/** Every declared purpose, configured or not. */
|
|
27
|
+
purposes: new Map(),
|
|
28
|
+
}));
|
|
15
29
|
export class LinkedFileStorage {
|
|
30
|
+
static get defaultStore() {
|
|
31
|
+
return storageState.defaultStore;
|
|
32
|
+
}
|
|
33
|
+
static set defaultStore(store) {
|
|
34
|
+
storageState.defaultStore = store;
|
|
35
|
+
}
|
|
36
|
+
static get url() {
|
|
37
|
+
return storageState.url;
|
|
38
|
+
}
|
|
39
|
+
static set url(accessURL) {
|
|
40
|
+
storageState.url = accessURL;
|
|
41
|
+
}
|
|
42
|
+
/** Purpose → the store configured for it. */
|
|
43
|
+
static get stores() {
|
|
44
|
+
return storageState.stores;
|
|
45
|
+
}
|
|
46
|
+
/** Every declared purpose, configured or not. */
|
|
47
|
+
static get purposes() {
|
|
48
|
+
return storageState.purposes;
|
|
49
|
+
}
|
|
16
50
|
static get accessURL() {
|
|
17
51
|
// check if default store is not set, return default accessURL
|
|
18
52
|
if (!this.defaultStore) {
|
|
@@ -170,10 +204,6 @@ export class LinkedFileStorage {
|
|
|
170
204
|
registerWellKnownPurposes();
|
|
171
205
|
}
|
|
172
206
|
}
|
|
173
|
-
/** Purpose → the store configured for it. */
|
|
174
|
-
LinkedFileStorage.stores = new Map();
|
|
175
|
-
/** Every declared purpose, configured or not. */
|
|
176
|
-
LinkedFileStorage.purposes = new Map();
|
|
177
207
|
/** Purposes already reported as falling back, so the log fires once each. */
|
|
178
208
|
LinkedFileStorage.loggedFallbacks = new Set();
|
|
179
209
|
/** The purposes core ships with are declared at module load. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LinkedFileStorage.js","sourceRoot":"","sources":["../../../src/utils/LinkedFileStorage.ts"],"names":[],"mappings":"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","sourcesContent":["import type {IFileStore, SaveFileOptions} from '../interfaces/IFileStore.js';\nimport type {Readable} from 'stream';\n\n/**\n * Well-known file store purposes shipped with core.\n *\n * Core itself never writes to `appAssets`; it lives here as the documented\n * convention (plan 011 D4) so the CLI and apps agree on the same key without a\n * shared runtime dependency. Any *new* purpose's constant belongs in the\n * runtime package that owns the concept, not here and not in the CLI.\n */\nexport const FileStorePurposes = {\n /** User-generated files. Resolves to the default store unless split out. */\n uploads: 'uploads',\n /** Built app bundles published by `linked build-app`. */\n appAssets: 'appAssets',\n} as const;\n\nexport type FileStorePurpose =\n (typeof FileStorePurposes)[keyof typeof FileStorePurposes];\n\nexport interface FileStorePurposeInfo {\n description?: string;\n}\n\nexport interface FileStorePurposeListing {\n purpose: string;\n description?: string;\n configured: boolean;\n}\n\nexport abstract class LinkedFileStorage {\n private static defaultStore: IFileStore;\n private static url: string; // default accessURL\n\n /** Purpose → the store configured for it. */\n private static stores: Map<string, IFileStore> = new Map();\n /** Every declared purpose, configured or not. */\n private static purposes: Map<string, FileStorePurposeInfo> = new Map();\n /** Purposes already reported as falling back, so the log fires once each. */\n private static loggedFallbacks: Set<string> = new Set();\n\n static get accessURL(): string {\n // check if default store is not set, return default accessURL\n if (!this.defaultStore) {\n return this.url;\n }\n\n return this.defaultStore.accessURL;\n }\n\n static setDefaultAccessURL(accessURL: string): string {\n return (this.url = accessURL);\n }\n\n static getDefaultStore(): IFileStore {\n return this.defaultStore;\n }\n\n /**\n * Configure the default store: the fallback for *every* purpose, `uploads`\n * included.\n *\n * It deliberately writes no entry into the purpose → store map, so `uploads`\n * behaves exactly like `appAssets`: an explicit `setStore('uploads', other)`\n * wins whenever it is called, before or after this, and `hasStore('uploads')`\n * stays false until such a call is made.\n */\n static setDefaultStore(store: IFileStore) {\n this.defaultStore = store;\n\n if (this.defaultStore.init) {\n this.defaultStore.init();\n }\n }\n\n /** @deprecated use {@link LinkedFileStorage.getDefaultStore} */\n static getDefaultDataset(): IFileStore {\n return this.getDefaultStore();\n }\n\n /** @deprecated use {@link LinkedFileStorage.setDefaultStore} */\n static setDefaultDataset(dataset: IFileStore) {\n this.setDefaultStore(dataset);\n }\n\n /**\n * Declare a purpose without configuring a store for it.\n *\n * A package that *reads* a purpose the app may leave unconfigured registers\n * it in the same module that exports its constant, so importing the constant\n * is the registration and ordering resolves itself.\n */\n static registerPurpose(purpose: string, info: FileStorePurposeInfo = {}) {\n const existing = this.purposes.get(purpose);\n // Keep an existing description rather than blanking it on a re-register.\n this.purposes.set(purpose, {\n description: info.description ?? existing?.description,\n });\n }\n\n /** Configure the store for a purpose. Also registers the purpose. */\n static setStore(purpose: string, store: IFileStore) {\n this.registerPurpose(purpose);\n this.stores.set(purpose, store);\n\n if (store.init) {\n store.init();\n }\n }\n\n /**\n * Resolve the store for a purpose (plan 011 D2):\n * - configured → that store;\n * - registered, not configured → the default store, logged once;\n * - not registered → throws.\n *\n * Unregistered throws on purpose: only a registry can tell \"the app did not\n * split this purpose out\" apart from a typo. Without it, `'appAsset'` would\n * silently write release bundles into the uploads store.\n *\n * The returned store is a **live reference**, resolved once at call time. A\n * caller that holds on to a store returned through the default-store fallback\n * keeps that object even after a later `setStore(purpose, other)`; call\n * `getStore` again per operation if the configuration can change at runtime.\n */\n static getStore(purpose: string): IFileStore {\n const configured = this.stores.get(purpose);\n if (configured) {\n return configured;\n }\n\n if (!this.purposes.has(purpose)) {\n throw new Error(\n `Unknown file store purpose '${purpose}'. Register it with LinkedFileStorage.setStore(), ` +\n `or import the package that defines it. Known purposes: ${\n this.listPurposes()\n .map((entry) => entry.purpose)\n .join(', ') || '(none)'\n }`,\n );\n }\n\n if (!this.defaultStore) {\n throw new Error(\n `No file store is configured for purpose '${purpose}', and no default store is configured. ` +\n `Call LinkedFileStorage.setStore('${purpose}', store) or LinkedFileStorage.setDefaultStore(store).`,\n );\n }\n\n if (!this.loggedFallbacks.has(purpose)) {\n this.loggedFallbacks.add(purpose);\n // `debug`, not `info`: falling back is the normal configuration for an\n // app that runs one store, so this must not read as a problem or show up\n // in default-level logs. It stays available when diagnosing which store a\n // purpose actually resolved to.\n console.debug(\n `[LinkedFileStorage] Purpose '${purpose}' has no dedicated store; using the default store.`,\n );\n }\n\n return this.defaultStore;\n }\n\n /**\n * Whether a store was *explicitly configured* for this purpose.\n *\n * The default-store fallback is deliberately ignored: `hasStore(p)` is false\n * while `getStore(p)` still returns a usable store via the default. Use this\n * to ask \"did the app split this purpose out?\", never as a guard before\n * `getStore` — that would skip a perfectly working fallback.\n */\n static hasStore(purpose: string): boolean {\n return this.stores.has(purpose);\n }\n\n /** Every declared purpose, with whether it has its own store. */\n static listPurposes(): FileStorePurposeListing[] {\n return Array.from(this.purposes.entries()).map(([purpose, info]) => ({\n purpose,\n description: info.description,\n configured: this.stores.has(purpose),\n }));\n }\n\n /** The access URL of the store resolved for this purpose. */\n static accessURLFor(purpose: string): string {\n return this.getStore(purpose).accessURL;\n }\n\n static deleteFile(filePath: string): Promise<void> {\n return this.defaultStore.deleteFile(filePath);\n }\n\n static fileExists(filePath: string): Promise<boolean> {\n return this.defaultStore.fileExists(filePath);\n }\n\n static getFile(filePath: string): Promise<Buffer> {\n return this.defaultStore.getFile(filePath);\n }\n\n static listFiles(prefix?: string): Promise<string[]> {\n return this.defaultStore.listFiles(prefix);\n }\n\n static saveFile(\n filePath: string,\n fileContent: string | Uint8Array | Buffer | Readable,\n options?: SaveFileOptions | string,\n /**\n * Forwarded exactly as given. No default here on purpose: \"unspecified\"\n * must reach the store so it can apply its own default.\n */\n preventDuplicates?: boolean,\n ): Promise<string> {\n return this.defaultStore.saveFile(\n filePath,\n fileContent,\n options,\n preventDuplicates,\n );\n }\n\n /**\n * Clears the module-global registry and default store.\n * For tests only — the registry is process-wide state.\n *\n * @internal\n */\n static resetForTests() {\n this.stores.clear();\n this.purposes.clear();\n this.loggedFallbacks.clear();\n this.defaultStore = undefined as unknown as IFileStore;\n this.url = undefined as unknown as string;\n registerWellKnownPurposes();\n }\n}\n\n/** The purposes core ships with are declared at module load. */\nfunction registerWellKnownPurposes() {\n LinkedFileStorage.registerPurpose(FileStorePurposes.uploads, {\n description: 'User-generated files. Falls back to the default store.',\n });\n LinkedFileStorage.registerPurpose(FileStorePurposes.appAssets, {\n description: 'Built app bundles published by `linked build-app`.',\n });\n}\n\nregisterWellKnownPurposes();\n\n/**\n * Get the full path of an asset based on the way LinkedFileStorage is configured\n * Returns accessURL + directory (/public by default) + path\n * @param path asset path\n * @param directory asset directory (optional, default is /public)\n * @returns asset url. e.g. https://cdn.example.com/public/image.png\n */\nexport function asset(path: string, directory: string = '/public'): string {\n // Some callers pass a raw app-relative path like `/images/foo.webp`, while\n // others may already have a fully qualified asset URL from an earlier\n // `asset(...)` call or backend response normalization. Keep this helper\n // idempotent so shared card/image components can safely call `asset(...)`\n // without duplicating the access URL prefix.\n if (/^(?:[a-z]+:)?\\/\\//i.test(path) || path.startsWith('data:') || path.startsWith('blob:')) {\n return path;\n }\n\n const accessURL = LinkedFileStorage.accessURL;\n const assetUrl = accessURL + directory + path;\n return assetUrl;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"LinkedFileStorage.js","sourceRoot":"","sources":["../../../src/utils/LinkedFileStorage.ts"],"names":[],"mappings":"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","sourcesContent":["import type {IFileStore, SaveFileOptions} from '../interfaces/IFileStore.js';\nimport type {Readable} from 'stream';\nimport {sharedState} from './sharedState.js';\n\n/**\n * Well-known file store purposes shipped with core.\n *\n * Core itself never writes to `appAssets`; it lives here as the documented\n * convention (plan 011 D4) so the CLI and apps agree on the same key without a\n * shared runtime dependency. Any *new* purpose's constant belongs in the\n * runtime package that owns the concept, not here and not in the CLI.\n */\nexport const FileStorePurposes = {\n /** User-generated files. Resolves to the default store unless split out. */\n uploads: 'uploads',\n /** Built app bundles published by `linked build-app`. */\n appAssets: 'appAssets',\n} as const;\n\nexport type FileStorePurpose =\n (typeof FileStorePurposes)[keyof typeof FileStorePurposes];\n\nexport interface FileStorePurposeInfo {\n description?: string;\n}\n\nexport interface FileStorePurposeListing {\n purpose: string;\n description?: string;\n configured: boolean;\n}\n\n/**\n * The configured stores, shared by every copy of core in the runtime: the server configures\n * them through one copy and an upload may reach them through another.\n */\nconst storageState = sharedState('@_linked/core', 'LinkedFileStorage', () => ({\n defaultStore: undefined as IFileStore | undefined,\n /** The default accessURL, used while no default store is set. */\n url: undefined as string | undefined,\n /** Purpose → the store configured for it. */\n stores: new Map<string, IFileStore>(),\n /** Every declared purpose, configured or not. */\n purposes: new Map<string, FileStorePurposeInfo>(),\n}));\n\nexport abstract class LinkedFileStorage {\n private static get defaultStore(): IFileStore {\n return storageState.defaultStore as IFileStore;\n }\n private static set defaultStore(store: IFileStore) {\n storageState.defaultStore = store;\n }\n private static get url(): string {\n return storageState.url as string;\n }\n private static set url(accessURL: string) {\n storageState.url = accessURL;\n }\n\n /** Purpose → the store configured for it. */\n private static get stores(): Map<string, IFileStore> {\n return storageState.stores;\n }\n /** Every declared purpose, configured or not. */\n private static get purposes(): Map<string, FileStorePurposeInfo> {\n return storageState.purposes;\n }\n /** Purposes already reported as falling back, so the log fires once each. */\n private static loggedFallbacks: Set<string> = new Set();\n\n static get accessURL(): string {\n // check if default store is not set, return default accessURL\n if (!this.defaultStore) {\n return this.url;\n }\n\n return this.defaultStore.accessURL;\n }\n\n static setDefaultAccessURL(accessURL: string): string {\n return (this.url = accessURL);\n }\n\n static getDefaultStore(): IFileStore {\n return this.defaultStore;\n }\n\n /**\n * Configure the default store: the fallback for *every* purpose, `uploads`\n * included.\n *\n * It deliberately writes no entry into the purpose → store map, so `uploads`\n * behaves exactly like `appAssets`: an explicit `setStore('uploads', other)`\n * wins whenever it is called, before or after this, and `hasStore('uploads')`\n * stays false until such a call is made.\n */\n static setDefaultStore(store: IFileStore) {\n this.defaultStore = store;\n\n if (this.defaultStore.init) {\n this.defaultStore.init();\n }\n }\n\n /** @deprecated use {@link LinkedFileStorage.getDefaultStore} */\n static getDefaultDataset(): IFileStore {\n return this.getDefaultStore();\n }\n\n /** @deprecated use {@link LinkedFileStorage.setDefaultStore} */\n static setDefaultDataset(dataset: IFileStore) {\n this.setDefaultStore(dataset);\n }\n\n /**\n * Declare a purpose without configuring a store for it.\n *\n * A package that *reads* a purpose the app may leave unconfigured registers\n * it in the same module that exports its constant, so importing the constant\n * is the registration and ordering resolves itself.\n */\n static registerPurpose(purpose: string, info: FileStorePurposeInfo = {}) {\n const existing = this.purposes.get(purpose);\n // Keep an existing description rather than blanking it on a re-register.\n this.purposes.set(purpose, {\n description: info.description ?? existing?.description,\n });\n }\n\n /** Configure the store for a purpose. Also registers the purpose. */\n static setStore(purpose: string, store: IFileStore) {\n this.registerPurpose(purpose);\n this.stores.set(purpose, store);\n\n if (store.init) {\n store.init();\n }\n }\n\n /**\n * Resolve the store for a purpose (plan 011 D2):\n * - configured → that store;\n * - registered, not configured → the default store, logged once;\n * - not registered → throws.\n *\n * Unregistered throws on purpose: only a registry can tell \"the app did not\n * split this purpose out\" apart from a typo. Without it, `'appAsset'` would\n * silently write release bundles into the uploads store.\n *\n * The returned store is a **live reference**, resolved once at call time. A\n * caller that holds on to a store returned through the default-store fallback\n * keeps that object even after a later `setStore(purpose, other)`; call\n * `getStore` again per operation if the configuration can change at runtime.\n */\n static getStore(purpose: string): IFileStore {\n const configured = this.stores.get(purpose);\n if (configured) {\n return configured;\n }\n\n if (!this.purposes.has(purpose)) {\n throw new Error(\n `Unknown file store purpose '${purpose}'. Register it with LinkedFileStorage.setStore(), ` +\n `or import the package that defines it. Known purposes: ${\n this.listPurposes()\n .map((entry) => entry.purpose)\n .join(', ') || '(none)'\n }`,\n );\n }\n\n if (!this.defaultStore) {\n throw new Error(\n `No file store is configured for purpose '${purpose}', and no default store is configured. ` +\n `Call LinkedFileStorage.setStore('${purpose}', store) or LinkedFileStorage.setDefaultStore(store).`,\n );\n }\n\n if (!this.loggedFallbacks.has(purpose)) {\n this.loggedFallbacks.add(purpose);\n // `debug`, not `info`: falling back is the normal configuration for an\n // app that runs one store, so this must not read as a problem or show up\n // in default-level logs. It stays available when diagnosing which store a\n // purpose actually resolved to.\n console.debug(\n `[LinkedFileStorage] Purpose '${purpose}' has no dedicated store; using the default store.`,\n );\n }\n\n return this.defaultStore;\n }\n\n /**\n * Whether a store was *explicitly configured* for this purpose.\n *\n * The default-store fallback is deliberately ignored: `hasStore(p)` is false\n * while `getStore(p)` still returns a usable store via the default. Use this\n * to ask \"did the app split this purpose out?\", never as a guard before\n * `getStore` — that would skip a perfectly working fallback.\n */\n static hasStore(purpose: string): boolean {\n return this.stores.has(purpose);\n }\n\n /** Every declared purpose, with whether it has its own store. */\n static listPurposes(): FileStorePurposeListing[] {\n return Array.from(this.purposes.entries()).map(([purpose, info]) => ({\n purpose,\n description: info.description,\n configured: this.stores.has(purpose),\n }));\n }\n\n /** The access URL of the store resolved for this purpose. */\n static accessURLFor(purpose: string): string {\n return this.getStore(purpose).accessURL;\n }\n\n static deleteFile(filePath: string): Promise<void> {\n return this.defaultStore.deleteFile(filePath);\n }\n\n static fileExists(filePath: string): Promise<boolean> {\n return this.defaultStore.fileExists(filePath);\n }\n\n static getFile(filePath: string): Promise<Buffer> {\n return this.defaultStore.getFile(filePath);\n }\n\n static listFiles(prefix?: string): Promise<string[]> {\n return this.defaultStore.listFiles(prefix);\n }\n\n static saveFile(\n filePath: string,\n fileContent: string | Uint8Array | Buffer | Readable,\n options?: SaveFileOptions | string,\n /**\n * Forwarded exactly as given. No default here on purpose: \"unspecified\"\n * must reach the store so it can apply its own default.\n */\n preventDuplicates?: boolean,\n ): Promise<string> {\n return this.defaultStore.saveFile(\n filePath,\n fileContent,\n options,\n preventDuplicates,\n );\n }\n\n /**\n * Clears the module-global registry and default store.\n * For tests only — the registry is process-wide state.\n *\n * @internal\n */\n static resetForTests() {\n this.stores.clear();\n this.purposes.clear();\n this.loggedFallbacks.clear();\n this.defaultStore = undefined as unknown as IFileStore;\n this.url = undefined as unknown as string;\n registerWellKnownPurposes();\n }\n}\n\n/** The purposes core ships with are declared at module load. */\nfunction registerWellKnownPurposes() {\n LinkedFileStorage.registerPurpose(FileStorePurposes.uploads, {\n description: 'User-generated files. Falls back to the default store.',\n });\n LinkedFileStorage.registerPurpose(FileStorePurposes.appAssets, {\n description: 'Built app bundles published by `linked build-app`.',\n });\n}\n\nregisterWellKnownPurposes();\n\n/**\n * Get the full path of an asset based on the way LinkedFileStorage is configured\n * Returns accessURL + directory (/public by default) + path\n * @param path asset path\n * @param directory asset directory (optional, default is /public)\n * @returns asset url. e.g. https://cdn.example.com/public/image.png\n */\nexport function asset(path: string, directory: string = '/public'): string {\n // Some callers pass a raw app-relative path like `/images/foo.webp`, while\n // others may already have a fully qualified asset URL from an earlier\n // `asset(...)` call or backend response normalization. Keep this helper\n // idempotent so shared card/image components can safely call `asset(...)`\n // without duplicating the access URL prefix.\n if (/^(?:[a-z]+:)?\\/\\//i.test(path) || path.startsWith('data:') || path.startsWith('blob:')) {\n return path;\n }\n\n const accessURL = LinkedFileStorage.accessURL;\n const assetUrl = accessURL + directory + path;\n return assetUrl;\n}\n"]}
|
|
@@ -158,8 +158,14 @@ export interface LinkedPackageObject {
|
|
|
158
158
|
*/
|
|
159
159
|
registerPackageModule(_module: any): void;
|
|
160
160
|
}
|
|
161
|
+
/**
|
|
162
|
+
* The default page size. A live binding that follows `setDefaultPageLimit` calls made through
|
|
163
|
+
* any copy of core; {@link getDefaultPageLimit} reads the same value.
|
|
164
|
+
*/
|
|
161
165
|
export declare var DEFAULT_LIMIT: number;
|
|
162
166
|
export declare function setDefaultPageLimit(limit: number): void;
|
|
167
|
+
/** The default page size set with {@link setDefaultPageLimit} (12 unless set). */
|
|
168
|
+
export declare function getDefaultPageLimit(): number;
|
|
163
169
|
export declare function autoLoadOntologyData(value: boolean): void;
|
|
164
170
|
export declare function linkedPackage(packageName: string, options?: {
|
|
165
171
|
baseUri?: string;
|
package/lib/esm/utils/Package.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
var _a, _b;
|
|
1
2
|
/*
|
|
2
3
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
3
4
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
@@ -8,6 +9,7 @@ import { createNodeShapeData } from '../shapes/nodeShapeData.js';
|
|
|
8
9
|
import { Shape } from '../shapes/Shape.js';
|
|
9
10
|
import { List } from '../shapes/List.class.js';
|
|
10
11
|
import { Prefix } from './Prefix.js';
|
|
12
|
+
import { sharedState } from './sharedState.js';
|
|
11
13
|
import { coreOntology } from '../ontologies/linked-core.js';
|
|
12
14
|
import { rdf } from '../ontologies/rdf.js';
|
|
13
15
|
import { addNodeShapeToShapeClass, getShapeClass } from './ShapeClass.js';
|
|
@@ -16,16 +18,42 @@ import { rdfs } from '../ontologies/rdfs.js';
|
|
|
16
18
|
import { xsd } from '../ontologies/xsd.js';
|
|
17
19
|
// var packageParsePromises: Map<string,Promise<any>> = new Map();
|
|
18
20
|
// var loadedPackages: Set<NamedNode> = new Set();
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
/**
|
|
22
|
+
* Ontology registrations and package settings, shared by every copy of core in the runtime:
|
|
23
|
+
* `autoLoadOntologyData(true)` through one copy loads ontologies another copy registered, and
|
|
24
|
+
* `setDefaultPageLimit` through either sets the limit both read.
|
|
25
|
+
*/
|
|
26
|
+
const packageState = sharedState('@_linked/core', 'Package', () => ({
|
|
27
|
+
ontologies: new Set(),
|
|
28
|
+
autoLoadOntologyData: false,
|
|
29
|
+
defaultLimit: 12,
|
|
30
|
+
/** One setter per copy of this module, keeping that copy's `DEFAULT_LIMIT` binding in step. */
|
|
31
|
+
limitBindings: new Set(),
|
|
32
|
+
}));
|
|
33
|
+
// A container an older copy of core created lacks the fields added since.
|
|
34
|
+
(_a = packageState.defaultLimit) !== null && _a !== void 0 ? _a : (packageState.defaultLimit = 12);
|
|
35
|
+
(_b = packageState.limitBindings) !== null && _b !== void 0 ? _b : (packageState.limitBindings = new Set());
|
|
36
|
+
const ontologies = packageState.ontologies;
|
|
37
|
+
/**
|
|
38
|
+
* The default page size. A live binding that follows `setDefaultPageLimit` calls made through
|
|
39
|
+
* any copy of core; {@link getDefaultPageLimit} reads the same value.
|
|
40
|
+
*/
|
|
41
|
+
export var DEFAULT_LIMIT = packageState.defaultLimit;
|
|
42
|
+
packageState.limitBindings.add((limit) => {
|
|
23
43
|
DEFAULT_LIMIT = limit;
|
|
44
|
+
});
|
|
45
|
+
export function setDefaultPageLimit(limit) {
|
|
46
|
+
packageState.defaultLimit = limit;
|
|
47
|
+
packageState.limitBindings.forEach((bind) => bind(limit));
|
|
48
|
+
}
|
|
49
|
+
/** The default page size set with {@link setDefaultPageLimit} (12 unless set). */
|
|
50
|
+
export function getDefaultPageLimit() {
|
|
51
|
+
return packageState.defaultLimit;
|
|
24
52
|
}
|
|
25
53
|
export function autoLoadOntologyData(value) {
|
|
26
|
-
|
|
54
|
+
packageState.autoLoadOntologyData = value;
|
|
27
55
|
//this may be set to true after some ontologies have already indexed,
|
|
28
|
-
if (
|
|
56
|
+
if (value) {
|
|
29
57
|
// so in that case we load all data of ontologies that are already indexed
|
|
30
58
|
ontologies.forEach((ontologyExport) => {
|
|
31
59
|
//see linkedOntology() where we store the data loading method under the _load key
|
|
@@ -203,7 +231,7 @@ export function linkedPackage(packageName, options) {
|
|
|
203
231
|
//register all the exports under the prefix. NOTE: this means the file name HAS to match the prefix
|
|
204
232
|
registerInPackageTree(prefixAndFileName, exportsCopy);
|
|
205
233
|
// });
|
|
206
|
-
if (
|
|
234
|
+
if (packageState.autoLoadOntologyData) {
|
|
207
235
|
loadData().catch((err) => {
|
|
208
236
|
console.warn('Could not load ontology data. Do you need to rebuild the module of the ' +
|
|
209
237
|
prefixAndFileName +
|