@kanonak-protocol/sdk 4.13.0 → 4.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/dist/browser.d.ts +1 -1
  2. package/dist/browser.js +2 -2
  3. package/dist/chunk-2HNPPYSK.js +1 -0
  4. package/dist/chunk-6U26UASC.js +1 -0
  5. package/dist/chunk-7BHDZHJY.js +1 -0
  6. package/dist/{chunk-V72IVYR4.js → chunk-H37TY5AQ.js} +4 -4
  7. package/dist/{chunk-VWS25JH4.js → chunk-HQQ4OAZ2.js} +1 -1
  8. package/dist/chunk-MRNELSJF.js +63 -0
  9. package/dist/{chunk-RGOBWOBB.js → chunk-OR3F4WIF.js} +1 -1
  10. package/dist/chunk-QDSN5VM3.js +2 -0
  11. package/dist/chunk-R73T4RUO.js +1 -0
  12. package/dist/{chunk-CR55WXIN.js → chunk-VDVJJ62W.js} +1 -1
  13. package/dist/chunk-WGKIRLMA.js +1 -0
  14. package/dist/index.d.ts +1 -1
  15. package/dist/index.js +12 -12
  16. package/dist/kanonaks/DefinedKanonak.d.ts +12 -0
  17. package/dist/parsing/KanonakObjectParser.d.ts +14 -1
  18. package/dist/parsing/index.js +1 -1
  19. package/dist/reasoning/index.js +1 -1
  20. package/dist/resolution/ResourceResolver.d.ts +0 -4
  21. package/dist/resolution/index.js +1 -1
  22. package/dist/search/index.js +1 -1
  23. package/dist/server/index.js +1 -1
  24. package/dist/transformations/index.js +1 -1
  25. package/dist/uri-helpers/index.js +1 -1
  26. package/dist/validation/ValidationCache.d.ts +34 -76
  27. package/dist/validation/documentModel.d.ts +47 -1
  28. package/dist/validation/index.d.ts +1 -1
  29. package/dist/validation/index.js +1 -1
  30. package/dist/validation/rules/repository/ClassDefinitionRule.d.ts +21 -6
  31. package/dist/validation/rules/repository/ClassHierarchyCycleRule.d.ts +9 -4
  32. package/dist/validation/rules/repository/EmbeddedKanonakTypeRule.d.ts +29 -90
  33. package/dist/validation/rules/repository/ObjectPropertyValueValidationRule.d.ts +20 -6
  34. package/dist/validation/rules/repository/PropertyDomainRule.d.ts +21 -17
  35. package/dist/validation/rules/repository/PropertyHierarchyCycleRule.d.ts +8 -4
  36. package/dist/validation/rules/repository/PropertyKindRangeConsistencyRule.d.ts +29 -0
  37. package/dist/validation/rules/repository/PropertyRangeReferenceRule.d.ts +14 -7
  38. package/dist/validation/rules/repository/PropertyRangeRequiredRule.d.ts +13 -2
  39. package/dist/validation/rules/repository/SubClassOfReferenceRule.d.ts +16 -13
  40. package/dist/validation/rules/repository/SubPropertyOfReferenceRule.d.ts +12 -5
  41. package/dist/validation/rules/repository/UnresolvedReferenceRule.d.ts +16 -4
  42. package/dist/validation/rules/repository/hierarchyCycle.d.ts +25 -0
  43. package/dist/validation/rules/repository/index.d.ts +1 -4
  44. package/package.json +2 -2
  45. package/dist/chunk-4UT2CLAT.js +0 -1
  46. package/dist/chunk-7HRKWTBB.js +0 -1
  47. package/dist/chunk-7TKJHKC2.js +0 -1
  48. package/dist/chunk-BKVPSPG4.js +0 -1
  49. package/dist/chunk-IEOSSSB5.js +0 -1
  50. package/dist/chunk-NUXUITUC.js +0 -2
  51. package/dist/chunk-SHDHMKMJ.js +0 -1
  52. package/dist/chunk-UBBZWWRB.js +0 -86
  53. package/dist/validation/rules/repository/DefinitionPropertyReferenceRule.d.ts +0 -13
  54. package/dist/validation/rules/repository/ObjectPropertyImportRule.d.ts +0 -9
  55. package/dist/validation/rules/repository/PropertyValueTypeRule.d.ts +0 -11
  56. package/dist/validation/rules/repository/XsdImportRule.d.ts +0 -11
@@ -8,4 +8,4 @@ export { KanonakObjectValidator } from './KanonakObjectValidator.js';
8
8
  export type { IDocumentValidationRule } from './rules/document/IDocumentValidationRule.js';
9
9
  export type { IRepositoryValidationRule } from './rules/repository/IRepositoryValidationRule.js';
10
10
  export { NamespacePrefixRule, ResourceNamingRule, PropertyTypeSpecificityRule, SubjectKanonakTypeRequiredRule, PackageHeaderRule } from './rules/document/index.js';
11
- export { ImportExistenceRule, UnresolvedReferenceRule, ClassHierarchyCycleRule, PropertyHierarchyCycleRule, PropertyRangeRequiredRule, SubClassOfReferenceRule, SubPropertyOfReferenceRule, NamespaceImportCycleRule, UnresolvedPredicateRule, DefinitionPropertyReferenceRule, XsdImportRule, AmbiguousReferenceRule, PropertyRangeReferenceRule, ObjectPropertyImportRule, ObjectPropertyValueValidationRule, PropertyDomainRule, PropertyValueTypeRule, ClassDefinitionRule, EmbeddedKanonakTypeRule, MarkdownLinkRule, DisplayLensScopeRule, LookSemanticSvgPathRule, TxExpressionPathRule, ShaclShapeRule, OwlOneOfRule, DiamondNameClashRule } from './rules/repository/index.js';
11
+ export { ImportExistenceRule, UnresolvedReferenceRule, ClassHierarchyCycleRule, PropertyHierarchyCycleRule, PropertyRangeRequiredRule, SubClassOfReferenceRule, SubPropertyOfReferenceRule, NamespaceImportCycleRule, UnresolvedPredicateRule, AmbiguousReferenceRule, PropertyRangeReferenceRule, ObjectPropertyValueValidationRule, PropertyDomainRule, PropertyKindRangeConsistencyRule, ClassDefinitionRule, EmbeddedKanonakTypeRule, MarkdownLinkRule, DisplayLensScopeRule, LookSemanticSvgPathRule, TxExpressionPathRule, ShaclShapeRule, OwlOneOfRule, DiamondNameClashRule } from './rules/repository/index.js';
@@ -1 +1 @@
1
- import{A,B,C,D,E,F,G,H,I,L as J,M as K,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z}from"../chunk-UBBZWWRB.js";import"../chunk-SHDHMKMJ.js";import"../chunk-BKVPSPG4.js";import"../chunk-NJ3AZYQD.js";import"../chunk-IEOSSSB5.js";import"../chunk-7TKJHKC2.js";import"../chunk-7HRKWTBB.js";import"../chunk-4UT2CLAT.js";import"../chunk-FUUTGGJS.js";import"../chunk-2ACBWC7K.js";export{w as AmbiguousReferenceRule,C as ClassDefinitionRule,n as ClassHierarchyCycleRule,u as DefinitionPropertyReferenceRule,J as DiamondNameClashRule,E as DisplayLensScopeRule,k as EmbeddedKanonakTypeRule,l as ImportExistenceRule,K as KanonakObjectValidator,F as LookSemanticSvgPathRule,D as MarkdownLinkRule,s as NamespaceImportCycleRule,f as NamespacePrefixRule,y as ObjectPropertyImportRule,z as ObjectPropertyValueValidationRule,c as OntologyValidationError,a as OntologyValidationResult,I as OwlOneOfRule,j as PackageHeaderRule,A as PropertyDomainRule,o as PropertyHierarchyCycleRule,x as PropertyRangeReferenceRule,p as PropertyRangeRequiredRule,h as PropertyTypeSpecificityRule,B as PropertyValueTypeRule,g as ResourceNamingRule,H as ShaclShapeRule,q as SubClassOfReferenceRule,r as SubPropertyOfReferenceRule,i as SubjectKanonakTypeRequiredRule,G as TxExpressionPathRule,t as UnresolvedPredicateRule,m as UnresolvedReferenceRule,e as ValidationCache,d as ValidationContext,b as ValidationSeverity,v as XsdImportRule};
1
+ import{A,B,C,D,E,F,I as G,J as H,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z}from"../chunk-MRNELSJF.js";import"../chunk-R73T4RUO.js";import"../chunk-NJ3AZYQD.js";import"../chunk-2HNPPYSK.js";import"../chunk-6U26UASC.js";import"../chunk-WGKIRLMA.js";import"../chunk-7BHDZHJY.js";import"../chunk-FUUTGGJS.js";import"../chunk-2ACBWC7K.js";export{u as AmbiguousReferenceRule,z as ClassDefinitionRule,n as ClassHierarchyCycleRule,G as DiamondNameClashRule,B as DisplayLensScopeRule,k as EmbeddedKanonakTypeRule,l as ImportExistenceRule,H as KanonakObjectValidator,C as LookSemanticSvgPathRule,A as MarkdownLinkRule,s as NamespaceImportCycleRule,f as NamespacePrefixRule,w as ObjectPropertyValueValidationRule,c as OntologyValidationError,a as OntologyValidationResult,F as OwlOneOfRule,j as PackageHeaderRule,x as PropertyDomainRule,o as PropertyHierarchyCycleRule,y as PropertyKindRangeConsistencyRule,v as PropertyRangeReferenceRule,p as PropertyRangeRequiredRule,h as PropertyTypeSpecificityRule,g as ResourceNamingRule,E as ShaclShapeRule,q as SubClassOfReferenceRule,r as SubPropertyOfReferenceRule,i as SubjectKanonakTypeRequiredRule,D as TxExpressionPathRule,t as UnresolvedPredicateRule,m as UnresolvedReferenceRule,e as ValidationCache,d as ValidationContext,b as ValidationSeverity};
@@ -2,11 +2,26 @@ import type { KanonakDocument } from '@kanonak-protocol/types/document/models/ty
2
2
  import type { IKanonakDocumentRepository } from '@kanonak-protocol/types/document/models';
3
3
  import type { IRepositoryValidationRule } from './IRepositoryValidationRule.js';
4
4
  import { OntologyValidationError } from '../../OntologyValidationError.js';
5
+ import type { ValidationCache } from '../../ValidationCache.js';
6
+ /**
7
+ * Every `type` target — the class an entity is declared an instance of — must
8
+ * resolve to a class-like resource. A built-in meta-class (`Class`,
9
+ * `ObjectProperty`, `Datatype`, `Package`, …) is itself a `type: Class` subject
10
+ * in the core packages, so it resolves the same way as a user-defined class —
11
+ * no hardcoded built-in allow-list is needed, and a real typo (`type: Conatiner`)
12
+ * is correctly flagged regardless of how it was aliased.
13
+ *
14
+ * Reads the resolved object model recursively ({@link walkDefinedKanonaks}), so
15
+ * a bad `type` on an embedded kanonak at any depth is caught, not just on
16
+ * top-level subjects (the #65 gap). The `type` target parses to a
17
+ * `ReferenceKanonak` whose `subject` URI the parser canonicalizes; existence +
18
+ * class-ness are checked by `findSubjectByUri` + `ResourceTypeClassifier`, never
19
+ * by a built-in-name set or `split('.')` alias extraction. (`type` is the
20
+ * structural predicate this rule owns — `UnresolvedReferenceRule` skips it.)
21
+ */
5
22
  export declare class ClassDefinitionRule implements IRepositoryValidationRule {
6
- private readonly builtInClasses;
7
- get ruleName(): string;
8
- validateAsync(document: KanonakDocument, repository: IKanonakDocumentRepository): Promise<OntologyValidationError[]>;
9
- private checkNestedTypes;
10
- private isClassEntity;
11
- private isDefinitionType;
23
+ readonly ruleName = "ClassDefinition";
24
+ validateAsync(document: KanonakDocument, repository: IKanonakDocumentRepository, cache?: ValidationCache): Promise<OntologyValidationError[]>;
25
+ private resolvesToClassLike;
26
+ private error;
12
27
  }
@@ -2,10 +2,15 @@ import type { IKanonakDocumentRepository } from '@kanonak-protocol/types/documen
2
2
  import type { KanonakDocument } from '@kanonak-protocol/types/document/models/types';
3
3
  import { OntologyValidationError } from '../../OntologyValidationError.js';
4
4
  import type { IRepositoryValidationRule } from './IRepositoryValidationRule.js';
5
+ import type { ValidationCache } from '../../ValidationCache.js';
6
+ /**
7
+ * Detects a circular `subClassOf` hierarchy. Reads the resolved object model: the
8
+ * subClassOf graph is walked by canonical `KanonakUri` (resolved through the
9
+ * import closure) and compared by `uriKey` identity, so a cycle that closes
10
+ * across packages — where the same class is spelled with different aliases in
11
+ * each hop — is caught, where the old local-name hierarchy map would miss it.
12
+ */
5
13
  export declare class ClassHierarchyCycleRule implements IRepositoryValidationRule {
6
14
  readonly ruleName = "ClassHierarchyCycle";
7
- validateAsync(document: KanonakDocument, repository: IKanonakDocumentRepository): Promise<OntologyValidationError[]>;
8
- private buildClassHierarchy;
9
- private detectCycle;
10
- private detectCycleRecursive;
15
+ validateAsync(document: KanonakDocument, repository: IKanonakDocumentRepository, cache?: ValidationCache): Promise<OntologyValidationError[]>;
11
16
  }
@@ -2,101 +2,40 @@ import type { KanonakDocument } from '@kanonak-protocol/types/document/models/ty
2
2
  import type { IKanonakDocumentRepository } from '@kanonak-protocol/types/document/models';
3
3
  import type { IRepositoryValidationRule } from './IRepositoryValidationRule.js';
4
4
  import { OntologyValidationError } from '../../OntologyValidationError.js';
5
+ import type { ValidationCache } from '../../ValidationCache.js';
5
6
  /**
6
- * Validates `type:` declarations on embedded kanonaks.
7
+ * Validates an explicit `type:` on an embedded kanonak against the range of the
8
+ * parent property it is embedded under: the declared type must be the range
9
+ * itself (redundant — a Warning) or a `subClassOf` descendant of it (accepted),
10
+ * supporting discriminated-union modelling with real OWL semantics.
7
11
  *
8
- * An embedded object MAY declare a `type:` property. If declared, the
9
- * declared type must be a subclass of (or equal to) the range of the
10
- * parent property under which the object is embedded. This relaxes
11
- * the previous "no explicit type on embeddeds" rule so authors can
12
- * model tagged-union / discriminated-union hierarchies with proper
13
- * OWL `subClassOf` semantics instead of working around the validator
14
- * with a separate discriminator class and named-instance enumeration.
12
+ * Reads the resolved object model, NOT raw `document.body`. The parser has
13
+ * already resolved every embedding predicate to its canonical property URI, so
14
+ * the parent property is known directly from the `EmbeddedStatement`/`ListStatement`
15
+ * predicate collapsing the old local-name property-range map and its
16
+ * alias/parent-class disambiguation entirely. The subclass test is the single
17
+ * canonical `superClassChain` walk compared by `uriKey` identity, so a
18
+ * cross-package subclass resolves regardless of the alias spelling each document
19
+ * used (`fml.Expression` vs `Expression` both being `…/formula/Expression`) —
20
+ * fixing the string-comparison false-negative the old `isSubclassOfAsync` +
21
+ * local-name fallback produced (#65, comment 4). Coverage is recursive on
22
+ * embeddeds at any depth.
15
23
  *
16
- * - Equal-to-range declarations are accepted but emit a Warning
17
- * ("redundant"). Authors who want explicit redundancy can opt in
18
- * by ignoring the warning.
19
- * - Strict-subclass declarations are accepted (no diagnostic).
20
- * - Non-subclass declarations error with a suggestion to either
21
- * drop the type or add a matching `subClassOf:` to the declared
22
- * class.
23
- * - When the parent property has no `range:`, or the range is a
24
- * "universal" class (`Resource`, `Class`), no constraint is
25
- * enforced — every declared embedded type is accepted.
26
- *
27
- * Why this is a repository rule rather than a document rule: deciding
28
- * whether `cp.OrCondition` is a subclass of `Condition` requires
29
- * walking `subClassOf` across the importing document's transitive
30
- * imports, which the document-only validator interface can't reach.
31
- * The class hierarchy walk is delegated to
32
- * `ResourceResolver.isSubclassOfAsync`, the same helper other
33
- * range-aware rules already share.
24
+ * - A "universal" range (`rdfs.Resource`, `rdfs.Class`) imposes no constraint.
25
+ * - An embedded with no explicit `type:` is fine (the type is inferred).
26
+ * - An unresolved parent property or range is reported by the dedicated
27
+ * reference rules, not here.
34
28
  */
35
29
  export declare class EmbeddedKanonakTypeRule implements IRepositoryValidationRule {
36
- get ruleName(): string;
37
- validateAsync(document: KanonakDocument, repository: IKanonakDocumentRepository): Promise<OntologyValidationError[]>;
38
- /**
39
- * Pick the right property-range candidate when multiple packages
40
- * declare a property with the same local name (e.g. `tx.Not.operand`
41
- * range `Expression` vs. `wv.NotCondition.operand` range `Condition`).
42
- *
43
- * Disambiguation strategy, in priority order:
44
- *
45
- * 1. If the property name as authored is alias-prefixed
46
- * (`tx.operand`), match candidates whose declaring entity
47
- * shares the same alias prefix. This is the unambiguous case
48
- * most authors hit — the YAML key carries the disambiguator.
49
- * 2. Otherwise, if the parent dict has a `type:` declaration,
50
- * match candidates whose `domain` local-name equals the parent
51
- * class's local-name. The embedded under `type: tx.Not` only
52
- * reasonably refers to the `operand` property whose domain is
53
- * `tx.Not` (kanonak-protocol/typescript#17).
54
- * 3. Last resort: return the first candidate. Authors who hit this
55
- * branch have a genuinely ambiguous shape — bare property name,
56
- * no parent type, multiple matching properties — and the rule
57
- * can't tell which they meant.
58
- */
59
- private pickRange;
60
- /**
61
- * Recursively descend through a YAML dict, validating any `type:`
62
- * declarations encountered at depth > 0 against the closest known
63
- * parent-property range.
64
- *
65
- * `parentPropertyRange` flows down from the property under which
66
- * this dict sits. Two cases preserve it correctly:
67
- *
68
- * 1. **Single embedded under a property** — keys here are the
69
- * embedded's properties; we look up each key's own range and
70
- * pass it down for the next level.
71
- * 2. **Dict-keyed list of embeddeds** (e.g.
72
- * `hasArgument: { foo: {...}, bar: {...} }`) — keys are labels
73
- * rather than properties, so they resolve to no range. In that
74
- * case we propagate the OUTER property's range through the
75
- * label level so the embedded values still get checked.
76
- *
77
- * List items are handled identically: a list under property P
78
- * means each item is an embedded under P, regardless of whether
79
- * the list is positional (`- item`) or dict-keyed.
80
- */
81
- private checkEmbeddedTypes;
82
- private validateEmbeddedType;
83
- private localName;
30
+ readonly ruleName = "EmbeddedKanonakType";
31
+ validateAsync(document: KanonakDocument, repository: IKanonakDocumentRepository, cache?: ValidationCache): Promise<OntologyValidationError[]>;
84
32
  /**
85
- * Build a map from property local name list of candidate
86
- * declarations (range + domain + declaring alias). Multiple
87
- * candidates exist when more than one imported package declares a
88
- * property with the same local name (e.g. `tx.Not.operand` range
89
- * `Expression` AND `wv.NotCondition.operand` range `Condition`).
90
- *
91
- * Pre-#17, this map collapsed candidates by overwriting each prior
92
- * entry, so the last-loaded property won and silently shadowed the
93
- * others. Now all candidates are kept; `pickRange` picks the right
94
- * one at lookup time using alias-prefix and parent-class context.
95
- *
96
- * The local-name keying mirrors the lookup pattern in
97
- * `checkEmbeddedTypes` (which uses `localName(propertyName)` for
98
- * the lookup). Same convention as `PropertyValueTypeRule` and
99
- * `ObjectPropertyValueValidationRule`.
33
+ * Descend a node's statements: every embedded object (single or list item) is
34
+ * checked against its embedding property's range, then recursed into so a
35
+ * deeper embedded is checked against ITS own embedding property.
100
36
  */
101
- private buildPropertyRangeMap;
37
+ private walk;
38
+ private check;
39
+ private redundant;
40
+ private notSubclass;
102
41
  }
@@ -2,11 +2,25 @@ import type { KanonakDocument } from '@kanonak-protocol/types/document/models/ty
2
2
  import type { IKanonakDocumentRepository } from '@kanonak-protocol/types/document/models';
3
3
  import type { IRepositoryValidationRule } from './IRepositoryValidationRule.js';
4
4
  import { OntologyValidationError } from '../../OntologyValidationError.js';
5
+ import type { ValidationCache } from '../../ValidationCache.js';
6
+ /**
7
+ * When an ObjectProperty's range is a schema-level meta-class, a value that
8
+ * REFERENCES an entity must reference one of that nature — e.g. a property whose
9
+ * range is `rdfs.Class` must point at a class, not an instance. This is the
10
+ * named-reference analogue of {@link EmbeddedKanonakTypeRule} (which constrains
11
+ * the declared type of an EMBEDDED value against its property's range).
12
+ *
13
+ * Reads the resolved object model (recursive on embeddeds at any depth): the
14
+ * property and its range are canonical URIs, the referent's nature is decided by
15
+ * `ResourceTypeClassifier`, identity by `uriMatches` — never by local-name range
16
+ * matching. Ordinary (non-meta) ranges and unresolved references are out of
17
+ * scope here (the latter is owned by `UnresolvedReferenceRule`); value-shape
18
+ * (scalar-vs-reference) is enforced structurally by the parser.
19
+ */
5
20
  export declare class ObjectPropertyValueValidationRule implements IRepositoryValidationRule {
6
- private readonly standardProperties;
7
- get ruleName(): string;
8
- validateAsync(document: KanonakDocument, repository: IKanonakDocumentRepository): Promise<OntologyValidationError[]>;
9
- private scanEntityForObjectProperties;
10
- private validateRangeType;
11
- private buildPropertyMetadataAsync;
21
+ readonly ruleName = "ObjectPropertyValue";
22
+ validateAsync(document: KanonakDocument, repository: IKanonakDocumentRepository, cache?: ValidationCache): Promise<OntologyValidationError[]>;
23
+ private walk;
24
+ private check;
25
+ private warn;
12
26
  }
@@ -1,24 +1,28 @@
1
1
  import type { KanonakDocument } from '@kanonak-protocol/types/document/models/types';
2
2
  import type { IKanonakDocumentRepository } from '@kanonak-protocol/types/document/models';
3
3
  import type { IRepositoryValidationRule } from './IRepositoryValidationRule.js';
4
- import type { ValidationCache } from '../../ValidationCache.js';
5
4
  import { OntologyValidationError } from '../../OntologyValidationError.js';
5
+ import type { ValidationCache } from '../../ValidationCache.js';
6
+ /**
7
+ * Every property used on an instance must be in scope for that instance's type:
8
+ * the property's `domain` must be the instance's type, an ancestor of it, or
9
+ * `rdfs.Resource` (which every resource is, so Resource-domain properties like
10
+ * `rdfs.label` apply universally). A property with no declared `domain` imposes
11
+ * no constraint.
12
+ *
13
+ * Reads the resolved object model (recursively, on embeddeds at any depth), NOT
14
+ * raw `document.body`: the predicate is the property's canonical URI, scope is
15
+ * the single canonical `superClassChain` walk, and domain membership is compared
16
+ * by `uriKey` identity — never by `lastIndexOf('.')` alias splitting or a
17
+ * local-name class-hierarchy map. Built-in predicates (`type`, `label`,
18
+ * `subClassOf`, …) are protocol-defined and skipped here. An unresolved
19
+ * predicate/property is reported by the dedicated predicate/reference rules.
20
+ */
6
21
  export declare class PropertyDomainRule implements IRepositoryValidationRule {
7
- private readonly standardProperties;
8
- get ruleName(): string;
22
+ readonly ruleName = "PropertyDomain";
9
23
  validateAsync(document: KanonakDocument, repository: IKanonakDocumentRepository, cache?: ValidationCache): Promise<OntologyValidationError[]>;
10
- /**
11
- * Cache-driven hierarchy: union of `getClassDeclarations(docId)`
12
- * across the document's transitive import closure. Each closure
13
- * document's body is walked at most once per validation pass
14
- * regardless of how many workspace documents share that closure
15
- * member. Result shape matches `buildCompleteClassHierarchyAsync`
16
- * so downstream `isTypeCompatibleWithDomain` works unchanged.
17
- */
18
- private buildClassHierarchyViaCache;
19
- private buildCompleteClassHierarchyAsync;
20
- private validateEntityProperties;
21
- private isTypeCompatibleWithDomain;
22
- private getPropertyValue;
23
- private extractFirstValue;
24
+ private walk;
25
+ /** Check every non-built-in property used ON this node against its type's scope. */
26
+ private checkNode;
27
+ private error;
24
28
  }
@@ -2,10 +2,14 @@ import type { IKanonakDocumentRepository } from '@kanonak-protocol/types/documen
2
2
  import type { KanonakDocument } from '@kanonak-protocol/types/document/models/types';
3
3
  import { OntologyValidationError } from '../../OntologyValidationError.js';
4
4
  import type { IRepositoryValidationRule } from './IRepositoryValidationRule.js';
5
+ import type { ValidationCache } from '../../ValidationCache.js';
6
+ /**
7
+ * Detects a circular `subPropertyOf` hierarchy. Reads the resolved object model:
8
+ * the subPropertyOf graph is walked by canonical `KanonakUri` and compared by
9
+ * `uriKey` identity, so a cycle that closes across packages with differing alias
10
+ * spellings is caught, where the old local-name hierarchy map would miss it.
11
+ */
5
12
  export declare class PropertyHierarchyCycleRule implements IRepositoryValidationRule {
6
13
  readonly ruleName = "PropertyHierarchyCycle";
7
- validateAsync(document: KanonakDocument, repository: IKanonakDocumentRepository): Promise<OntologyValidationError[]>;
8
- private buildPropertyHierarchy;
9
- private detectCycle;
10
- private detectCycleRecursive;
14
+ validateAsync(document: KanonakDocument, repository: IKanonakDocumentRepository, cache?: ValidationCache): Promise<OntologyValidationError[]>;
11
15
  }
@@ -0,0 +1,29 @@
1
+ import type { KanonakDocument } from '@kanonak-protocol/types/document/models/types';
2
+ import type { IKanonakDocumentRepository } from '@kanonak-protocol/types/document/models';
3
+ import type { IRepositoryValidationRule } from './IRepositoryValidationRule.js';
4
+ import { OntologyValidationError } from '../../OntologyValidationError.js';
5
+ import type { ValidationCache } from '../../ValidationCache.js';
6
+ /**
7
+ * A property's declared KIND must match the NATURE of its range (#65 Gap A):
8
+ *
9
+ * - `owl.DatatypeProperty` → a DATATYPE-valued range: an xsd type, `rdfs.Literal`,
10
+ * or a datatype-derived class (e.g. `prose.Markdown`, declared `Datatype` and
11
+ * ultimately `subClassOf` an xsd type).
12
+ * - `owl.ObjectProperty` → a plain `rdfs.Class` range that is NOT datatype-derived.
13
+ *
14
+ * Without this the mismatch only surfaces LATE at resolution time ("value could
15
+ * not be resolved" when an object property tries to resolve literal text as a
16
+ * reference). The decision MUST be made by walking the range's `subClassOf`
17
+ * chain, because a datatype-derived class is datatype-valued even though
18
+ * `rdfs.Datatype` is itself a kind of `rdfs.Class` — a naive "is the range an
19
+ * `rdfs.Class`?" test gets it exactly backwards. "Datatype-valued" here means a
20
+ * chain node whose OWN type is `Datatype` (so xsd types and every datatype-
21
+ * derived class qualify) or `rdfs.Literal`; identity by `KanonakUri`, no
22
+ * hardcoded xsd-name set. An unresolved range is owned by
23
+ * `PropertyRangeReferenceRule`, a missing range by `PropertyRangeRequiredRule`.
24
+ */
25
+ export declare class PropertyKindRangeConsistencyRule implements IRepositoryValidationRule {
26
+ readonly ruleName = "PropertyKindRangeConsistency";
27
+ validateAsync(document: KanonakDocument, repository: IKanonakDocumentRepository, cache?: ValidationCache): Promise<OntologyValidationError[]>;
28
+ private error;
29
+ }
@@ -2,12 +2,19 @@ import type { KanonakDocument } from '@kanonak-protocol/types/document/models/ty
2
2
  import type { IKanonakDocumentRepository } from '@kanonak-protocol/types/document/models';
3
3
  import type { IRepositoryValidationRule } from './IRepositoryValidationRule.js';
4
4
  import { OntologyValidationError } from '../../OntologyValidationError.js';
5
+ import type { ValidationCache } from '../../ValidationCache.js';
6
+ /**
7
+ * Every Object/Datatype property `range` must resolve to a class-like resource:
8
+ * a Class, or a Datatype (core-xsd types — `string`, `integer`, … — and
9
+ * datatype-derived classes are all `type: Datatype` subjects). Reads the
10
+ * resolved object model: the range is a `ReferenceKanonak` resolved through the
11
+ * import closure (alias-agnostic), checked by `findSubjectByUri` +
12
+ * `ResourceTypeClassifier`, never by hardcoded primitive/built-in name sets or
13
+ * `split('.')` alias extraction. (Missing range is `PropertyRangeRequiredRule`.)
14
+ */
5
15
  export declare class PropertyRangeReferenceRule implements IRepositoryValidationRule {
6
- private readonly builtInClasses;
7
- private readonly primitiveTypes;
8
- get ruleName(): string;
9
- validateAsync(document: KanonakDocument, repository: IKanonakDocumentRepository): Promise<OntologyValidationError[]>;
10
- private isTypeAvailableInImports;
11
- private isTypeAvailableInImportsRecursive;
12
- private isValidRangeTargetType;
16
+ readonly ruleName = "PropertyRangeReference";
17
+ validateAsync(document: KanonakDocument, repository: IKanonakDocumentRepository, cache?: ValidationCache): Promise<OntologyValidationError[]>;
18
+ private resolvesToClassLike;
19
+ private error;
13
20
  }
@@ -2,7 +2,18 @@ import type { KanonakDocument } from '@kanonak-protocol/types/document/models/ty
2
2
  import type { IKanonakDocumentRepository } from '@kanonak-protocol/types/document/models';
3
3
  import type { IRepositoryValidationRule } from './IRepositoryValidationRule.js';
4
4
  import { OntologyValidationError } from '../../OntologyValidationError.js';
5
+ import type { ValidationCache } from '../../ValidationCache.js';
6
+ /**
7
+ * Every Object/Datatype property must declare a `range`. Reads the resolved
8
+ * object model: presence is tested by the `range` predicate's canonical URI
9
+ * (`hasProperty`), so the aliased `rdfs.range` form is recognised exactly like
10
+ * the bare `range` — fixing the alias-blind raw-dict check that keyed off the
11
+ * literal `'range'` dict key and falsely reported "must have a range" for a
12
+ * property authored with `rdfs.range:` (#65 Gap B). Whether the declared range
13
+ * actually RESOLVES is `PropertyRangeReferenceRule`'s concern.
14
+ */
5
15
  export declare class PropertyRangeRequiredRule implements IRepositoryValidationRule {
6
- get ruleName(): string;
7
- validateAsync(document: KanonakDocument, _repository: IKanonakDocumentRepository): Promise<OntologyValidationError[]>;
16
+ readonly ruleName = "PropertyRangeRequired";
17
+ validateAsync(document: KanonakDocument, repository: IKanonakDocumentRepository, cache?: ValidationCache): Promise<OntologyValidationError[]>;
18
+ private error;
8
19
  }
@@ -2,18 +2,21 @@ import type { KanonakDocument } from '@kanonak-protocol/types/document/models/ty
2
2
  import type { IKanonakDocumentRepository } from '@kanonak-protocol/types/document/models';
3
3
  import type { IRepositoryValidationRule } from './IRepositoryValidationRule.js';
4
4
  import { OntologyValidationError } from '../../OntologyValidationError.js';
5
+ import type { ValidationCache } from '../../ValidationCache.js';
6
+ /**
7
+ * Every `subClassOf` target must resolve to a class-like resource. Per core-rdf
8
+ * (`Datatype subClassOf Class`) a Datatype is a Class, so datatype hierarchies
9
+ * (`xsd.integer subClassOf xsd.decimal`, `Markdown subClassOf SubstitutableString`)
10
+ * are well-formed — the target check accepts both.
11
+ *
12
+ * Reads the resolved object model: the parser turns each `subClassOf` value into
13
+ * a `ReferenceKanonak`, so the target is a `KanonakUri` resolved through the
14
+ * import closure (alias-agnostic) and existence is checked by `findSubjectByUri`,
15
+ * never by a hardcoded built-in-name list or `split('.')` alias extraction.
16
+ */
5
17
  export declare class SubClassOfReferenceRule implements IRepositoryValidationRule {
6
- private readonly builtInClasses;
7
- get ruleName(): string;
8
- /**
9
- * A valid `subClassOf` target is anything that is a Class — and per
10
- * core-rdf's `Datatype subClassOf Class`, a Datatype is a Class. So
11
- * datatype hierarchies (`xsd.integer subClassOf xsd.decimal`,
12
- * `Markdown subClassOf SubstitutableString`) are well-formed and the
13
- * target check must accept both `Class` and `Datatype` (aliased or not).
14
- */
15
- private isClassLikeType;
16
- validateAsync(document: KanonakDocument, repository: IKanonakDocumentRepository): Promise<OntologyValidationError[]>;
17
- private isClassAvailableInImports;
18
- private isClassAvailableInImportsRecursive;
18
+ readonly ruleName = "SubClassOfReference";
19
+ validateAsync(document: KanonakDocument, repository: IKanonakDocumentRepository, cache?: ValidationCache): Promise<OntologyValidationError[]>;
20
+ private resolvesToClassLike;
21
+ private error;
19
22
  }
@@ -2,10 +2,17 @@ import type { KanonakDocument } from '@kanonak-protocol/types/document/models/ty
2
2
  import type { IKanonakDocumentRepository } from '@kanonak-protocol/types/document/models';
3
3
  import type { IRepositoryValidationRule } from './IRepositoryValidationRule.js';
4
4
  import { OntologyValidationError } from '../../OntologyValidationError.js';
5
+ import type { ValidationCache } from '../../ValidationCache.js';
6
+ /**
7
+ * Every `subPropertyOf` target must resolve to a defined or imported property.
8
+ * Reads the resolved object model: the target is a `ReferenceKanonak` resolved
9
+ * through the import closure (alias-agnostic), and its existence + property-ness
10
+ * are checked by `findSubjectByUri` + `ResourceTypeClassifier`, never by a
11
+ * hardcoded built-in-name list or `split('.')` alias extraction.
12
+ */
5
13
  export declare class SubPropertyOfReferenceRule implements IRepositoryValidationRule {
6
- private readonly builtInProperties;
7
- get ruleName(): string;
8
- validateAsync(document: KanonakDocument, repository: IKanonakDocumentRepository): Promise<OntologyValidationError[]>;
9
- private isPropertyAvailableInImports;
10
- private isPropertyAvailableInImportsRecursive;
14
+ readonly ruleName = "SubPropertyOfReference";
15
+ validateAsync(document: KanonakDocument, repository: IKanonakDocumentRepository, cache?: ValidationCache): Promise<OntologyValidationError[]>;
16
+ private resolvesToProperty;
17
+ private error;
11
18
  }
@@ -2,10 +2,22 @@ import type { IKanonakDocumentRepository } from '@kanonak-protocol/types/documen
2
2
  import type { KanonakDocument } from '@kanonak-protocol/types/document/models/types';
3
3
  import { OntologyValidationError } from '../../OntologyValidationError.js';
4
4
  import type { IRepositoryValidationRule } from './IRepositoryValidationRule.js';
5
+ import type { ValidationCache } from '../../ValidationCache.js';
6
+ /**
7
+ * Reports an object-property value that references an entity which does not
8
+ * resolve to a defined or imported resource — a typo, a moved entity, or an
9
+ * unimported namespace. Reads the resolved object model recursively
10
+ * ({@link walkDefinedKanonaks}), so a bad reference on an embedded object at any
11
+ * depth is caught, not just on top-level subjects (the #65 gap).
12
+ *
13
+ * A reference value parses to a `ReferenceKanonak` whose `subject` is the
14
+ * resolved (or, for an unresolvable authored name, fabricated doc-local) URI;
15
+ * resolution succeeds iff that URI names a subject in the catalog. Identity is
16
+ * compared by `findSubjectByUri`, never by string/alias shape.
17
+ */
5
18
  export declare class UnresolvedReferenceRule implements IRepositoryValidationRule {
6
19
  readonly ruleName = "UnresolvedReference";
7
- validateAsync(document: KanonakDocument, repository: IKanonakDocumentRepository): Promise<OntologyValidationError[]>;
8
- private validateReferenceValue;
9
- private createUnresolvedReferenceError;
10
- private getPropertyValue;
20
+ validateAsync(document: KanonakDocument, repository: IKanonakDocumentRepository, cache?: ValidationCache): Promise<OntologyValidationError[]>;
21
+ private check;
22
+ private unresolvedError;
11
23
  }
@@ -0,0 +1,25 @@
1
+ import type { Kanonak } from '../../../kanonaks/Kanonak.js';
2
+ import type { KanonakUri } from '../../../resolution/KanonakUri.js';
3
+ import { type EntityUri } from '../../../uri-helpers/index.js';
4
+ export declare const URI_SUBCLASSOF: EntityUri;
5
+ export declare const URI_SUBPROPERTYOF: EntityUri;
6
+ /**
7
+ * Walk the `edge` (`subClassOf` / `subPropertyOf`) graph from `start`, resolving
8
+ * each hop to its canonical `KanonakUri` through the catalog, and return the
9
+ * first ILL-FOUNDED cycle reachable from `start` (the looping segment, with the
10
+ * repeated node appended) or `null`.
11
+ *
12
+ * Identity is VERSION-AWARE — keyed by the resolved subject's version-specific
13
+ * namespace, not the version-agnostic `uriKey`. With several versions of a
14
+ * package in the catalog (`core-rdf@1.0.0` and `@1.1.0`), a version-agnostic key
15
+ * would collapse them and could report a cycle that exists only by conflating
16
+ * two versions; the version-aware key follows the actual per-version edges and
17
+ * only closes a cycle when the SAME version is re-entered.
18
+ *
19
+ * A reflexive self-loop (`X subClassOf X`, the looping segment being a single
20
+ * node) is NOT reported: `subClassOf` is reflexive, so a class being its own
21
+ * superclass is valid (if redundant), not an ill-founded hierarchy. Only a cycle
22
+ * through ≥2 distinct classes is an error. Standard DFS with a recursion-stack
23
+ * set for back-edges and a done-set to prune shared subtrees.
24
+ */
25
+ export declare function detectHierarchyCycle(catalog: Kanonak[], start: KanonakUri, edge: EntityUri): KanonakUri[] | null;
@@ -8,14 +8,11 @@ export { SubClassOfReferenceRule } from './SubClassOfReferenceRule.js';
8
8
  export { SubPropertyOfReferenceRule } from './SubPropertyOfReferenceRule.js';
9
9
  export { NamespaceImportCycleRule } from './NamespaceImportCycleRule.js';
10
10
  export { UnresolvedPredicateRule } from './UnresolvedPredicateRule.js';
11
- export { DefinitionPropertyReferenceRule } from './DefinitionPropertyReferenceRule.js';
12
- export { XsdImportRule } from './XsdImportRule.js';
13
11
  export { AmbiguousReferenceRule } from './AmbiguousReferenceRule.js';
14
12
  export { PropertyRangeReferenceRule } from './PropertyRangeReferenceRule.js';
15
- export { ObjectPropertyImportRule } from './ObjectPropertyImportRule.js';
16
13
  export { ObjectPropertyValueValidationRule } from './ObjectPropertyValueValidationRule.js';
17
14
  export { PropertyDomainRule } from './PropertyDomainRule.js';
18
- export { PropertyValueTypeRule } from './PropertyValueTypeRule.js';
15
+ export { PropertyKindRangeConsistencyRule } from './PropertyKindRangeConsistencyRule.js';
19
16
  export { ClassDefinitionRule } from './ClassDefinitionRule.js';
20
17
  export { EmbeddedKanonakTypeRule } from './EmbeddedKanonakTypeRule.js';
21
18
  export { MarkdownLinkRule } from './MarkdownLinkRule.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kanonak-protocol/sdk",
3
- "version": "4.13.0",
3
+ "version": "4.14.0",
4
4
  "description": "TypeScript SDK for the Kanonak Protocol — parse, resolve, validate, reason over, and render .kan.yml packages.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -126,7 +126,7 @@
126
126
  ],
127
127
  "dependencies": {
128
128
  "@kanonak-protocol/canonical": "^0.1.1",
129
- "@kanonak-protocol/types": "^4.13.0",
129
+ "@kanonak-protocol/types": "^4.14.0",
130
130
  "ignore": "^7.0.5",
131
131
  "js-yaml": "^4.1.0",
132
132
  "yaml": "^2.7.0"
@@ -1 +0,0 @@
1
- import{a as p}from"./chunk-FUUTGGJS.js";var m=class{};var c=class extends m{statement=[];unresolvedPredicates=[]};var i=class extends c{namespace;name;icon};var a=class e extends m{subject;static parse(o){let n=new e;return n.subject=p.parse(o),n}};var r=class{predicate;object};var s=class extends r{carrier;lexical};var d=class e extends s{static parse(o,n){let t=new e;return t.predicate=a.parse(o),t.object=n,t}};var f=class e extends s{static parse(o,n){let t=new e;return t.predicate=a.parse(o),t.object=n,t}};var k=class extends s{};var l=class e extends r{static parse(o,n){let t=new e;return t.predicate=a.parse(o),t.object=a.parse(n),t}};var x=class extends r{};var b=class extends r{};export{m as a,c as b,i as c,a as d,r as e,s as f,d as g,f as h,k as i,l as j,x as k,b as l};
@@ -1 +0,0 @@
1
- import{a as w}from"./chunk-FUUTGGJS.js";function K(r){if(Array.isArray(r))return r.map(t=>t?.toString()??"").filter(t=>t.length>0);let e=r?.toString();return e?[e]:[]}var S=class{cache=new Map;repository;logger;constructor(e,t){this.repository=e,this.logger=t}async resolveEntityAsync(e,t){let a=t.metadata?.namespace_?.toString()??"unknown",s=this.cache.get(a);if(s){let o=s.get(e);if(o)return o}let n=await this.buildEntityIndexAsyncInternal(t,new Set,"",new Map);return this.cache.set(a,n),n.get(e)??null}async resolveAllEntitiesAsync(e,t){let a=await this.buildAllEntitiesIndexAsync(t,new Set,"");if(e.includes(".")){let s=e.split("."),n=s[0],o=s[1],g=await this.findDocumentForAlias(t,n);return g?await this.resolveAllEntitiesAsync(o,g):[]}return a.filter(s=>s.entityName===e)}async buildAllEntitiesIndexAsync(e,t,a){let s=[],n=e.metadata?.namespace_?.toString()??"unknown";if(this.logger?.debug?.(`Building ALL entities index for namespace: ${n}`),t.has(n))return this.logger?.debug?.(`Skipping ${n} - already visited (circular import prevention)`),s;t.add(n);let o=a.length===0?n:`${a} \u2192 ${n}`;for(let[g,u]of Object.entries(e.body))if(!g.includes(".")&&u&&typeof u=="object"&&!Array.isArray(u)){if(!e.metadata.namespace_)continue;let f=e.metadata.namespace_.version??{major:1,minor:0,patch:0,toString:()=>"1.0.0",equals:()=>!1,getHashCode:()=>0,compareTo:()=>0};s.push({entityName:g,uri:new w(e.metadata.namespace_.publisher,e.metadata.namespace_.package_,g,f),entity:u,definedInNamespace:n,isImported:a.length>0,importPath:o})}if(this.logger?.debug?.(`Collected ${s.length} entities from ${n}`),e.metadata?.imports){let g=Object.values(e.metadata.imports).reduce((u,f)=>u+f.length,0);this.logger?.debug?.(`Processing ${g} import(s) for ${n}`);for(let[u,f]of Object.entries(e.metadata.imports))for(let d of f)try{this.logger?.debug?.(`Resolving import: ${u}/${d.packageName}`);let p=await this.repository.getHighestCompatibleVersionAsync(u,d);if(p){this.logger?.debug?.(`Successfully loaded import: ${p.metadata?.namespace_?.toString()}`);let m=await this.buildAllEntitiesIndexAsync(p,t,o);s.push(...m),this.logger?.debug?.(`Added ${m.length} entities from import ${p.metadata?.namespace_?.toString()}`)}else this.logger?.warn?.(`Failed to load import: ${u}/${d.packageName}`)}catch(p){let m=p;throw this.logger?.error?.(`Failed to process import ${u}/${d.packageName} for namespace ${n}. Error: ${m.message}`,m),new Error(`Failed to process import ${u}/${d.packageName} for namespace ${n}. See inner exception for details.`,{cause:p})}}return s}async buildEntityIndexAsync(e){return await this.buildEntityIndexAsyncInternal(e,new Set,"",new Map)}async buildEntityIndexAsyncInternal(e,t,a,s){let n=new Map,o=e.metadata?.namespace_?.toString()??"unknown";if(this.logger?.debug?.(`Building entity index for namespace: ${o}`),t.has(o))return this.logger?.debug?.(`Skipping ${o} - circular import in progress`),n;let g=s.get(o);if(g)return g;t.add(o);let u=a.length===0?o:`${a} \u2192 ${o}`,f=0;for(let[d,p]of Object.entries(e.body))if(!d.includes(".")&&p&&typeof p=="object"&&!Array.isArray(p)){if(!e.metadata.namespace_)continue;if(!n.has(d)){let m=e.metadata.namespace_.version??{major:1,minor:0,patch:0,toString:()=>"1.0.0",equals:()=>!1,getHashCode:()=>0,compareTo:()=>0};n.set(d,{entityName:d,uri:new w(e.metadata.namespace_.publisher,e.metadata.namespace_.package_,d,m),entity:p,definedInNamespace:o,isImported:a.length>0,importPath:u}),f++}}if(this.logger?.debug?.(`Indexed ${f} entities from ${o}`),e.metadata?.imports){let d=Object.values(e.metadata.imports).reduce((p,m)=>p+m.length,0);this.logger?.debug?.(`Processing ${d} import(s) for ${o}`);for(let[p,m]of Object.entries(e.metadata.imports))for(let h of m)try{this.logger?.debug?.(`Resolving import: ${p}/${h.packageName}`);let k=await this.repository.getHighestCompatibleVersionAsync(p,h);if(k){this.logger?.debug?.(`Successfully loaded import: ${k.metadata?.namespace_?.toString()}`);let P=await this.buildEntityIndexAsyncInternal(k,t,u,s),v=0;for(let[$,R]of P.entries()){let b=n.get($);if(!b)n.set($,R),v++;else if(b.isImported&&R.isImported&&(b.uri.publisher!==R.uri.publisher||b.uri.package_!==R.uri.package_)){let A=b.isAmbiguous?b:{...b,isAmbiguous:!0,ambiguousNamespaces:[b.definedInNamespace]};A.ambiguousNamespaces.includes(R.definedInNamespace)||A.ambiguousNamespaces.push(R.definedInNamespace),n.set($,A),this.logger?.warn?.(`Ambiguous reference '${$}': defined in ${A.ambiguousNamespaces.join(", ")}`)}if(h.alias&&!$.includes(".")){let A=`${h.alias}.${$}`;n.has(A)||(n.set(A,R),v++)}}this.logger?.debug?.(`Merged ${v} entities from import ${k.metadata?.namespace_?.toString()}`)}else this.logger?.warn?.(`Failed to load import: ${p}/${h.packageName}`)}catch(k){let P=k;throw this.logger?.error?.(`Failed to process import ${p}/${h.packageName} for namespace ${o}. Error: ${P.message}`,P),new Error(`Failed to process import ${p}/${h.packageName} for namespace ${o}. See inner exception for details.`,{cause:k})}}return t.delete(o),s.set(o,n),n}async findDocumentForAlias(e,t){if(!e.metadata?.imports)return null;for(let[a,s]of Object.entries(e.metadata.imports))for(let n of s){if(n.alias===t)return await this.repository.getHighestCompatibleVersionAsync(a,n);if(!n.alias&&n.packageName===t)return await this.repository.getHighestCompatibleVersionAsync(a,n)}return null}clearCache(){this.cache.clear()}clearCacheForDocument(e){this.cache.delete(e)}async isSubclassOfAsync(e,t,a){if(e===t)return!0;let s=new Set;return await this.isSubclassOfRecursiveAsync(e,t,a,s)}async isSubclassOfRecursiveAsync(e,t,a,s){if(s.has(e))return!1;s.add(e);let n=await this.resolveEntityAsync(e,a);if(!n?.entity)return!1;let o=n.entity.subClassOf;if(o){let g=K(o);for(let u of g)if(u===t||await this.isSubclassOfRecursiveAsync(u,t,a,s))return!0}return!1}async isSubpropertyOfAsync(e,t,a){if(e===t)return!0;let s=new Set;return await this.isSubpropertyOfRecursiveAsync(e,t,a,s)}async isSubpropertyOfRecursiveAsync(e,t,a,s){if(s.has(e))return!1;s.add(e);let n=await this.resolveEntityAsync(e,a);if(!n?.entity)return!1;let o=n.entity.subPropertyOf;if(o){let g=K(o);for(let u of g)if(u===t||await this.isSubpropertyOfRecursiveAsync(u,t,a,s))return!0}return!1}};var D=class r{static KNOWN_XSD_DATATYPES=new Set(["string","integer","int","boolean","decimal","float","double","date","datetime","time","duration","anyuri","base64binary","hexbinary","long","short","byte","nonnegativeinteger","positiveinteger","negativeinteger","nonpositiveinteger","unsignedint","unsignedlong","unsignedshort","unsignedbyte"]);resourceResolver;constructor(e){this.resourceResolver=e}isXsdDatatype(e){return e?e.publisher==="kanonak.org"&&e.package_==="core-xsd"&&r.KNOWN_XSD_DATATYPES.has(e.name.toLowerCase()):!1}isLiteralType(e){return e?e.publisher==="kanonak.org"&&e.package_==="core-rdf"&&e.name==="Literal":!1}isMarkdownDatatype(e){return e?e.publisher==="kanonak.org"&&e.package_==="core-prose"&&e.name==="Markdown":!1}isSubstitutableDatatype(e){return e?e.publisher==="kanonak.org"&&e.package_==="core-prose"&&(e.name==="SubstitutableString"||e.name==="Markdown"):!1}isKnownXsdDatatypeName(e){let t=e.includes(".")?e.split(".")[1]:e;return r.KNOWN_XSD_DATATYPES.has(t.toLowerCase())}async isClassTypeAsync(e,t){if(this.isKnownXsdDatatypeName(e))return!1;let a=await this.resourceResolver.resolveEntityAsync(e,t);if(a){let s=a.entity.type;if(s){let n=String(s);return n==="Class"||n==="rdfs.Class"||n.endsWith(".Class")}}return!0}getPropertyTypeClassification(e){if(!e||e.trim().length===0)return"Property";switch(e.includes(".")?e.split(".")[1]:e){case"DatatypeProperty":return"DatatypeProperty";case"ObjectProperty":return"ObjectProperty";case"AnnotationProperty":return"AnnotationProperty";case"Property":return"Property";default:return"Property"}}isEffectiveDatatypeProperty(e,t){return!!(e==="DatatypeProperty"||e==="Property"&&this.isXsdDatatype(t)||e==="Property"&&this.isLiteralType(t))}isEffectiveObjectProperty(e,t){return!!(e==="ObjectProperty"||e==="Property"&&t&&!this.isXsdDatatype(t)&&!this.isLiteralType(t))}};function L(r){return`${r.publisher}/${r.package_}/${r.name}`}function c(r,e,t){return`${r}/${e}/${t}`}function M(r){return`${r.s}|${r.p}|${I(r.o)}`}function I(r){switch(r.kind){case"uri":return`u:${r.key}`;case"literal":return`l:${r.datatype}:${r.lexical}`;case"blank":return`b:${r.id}`}}function F(r,e,t){return{s:r,p:e,o:{kind:"uri",key:t}}}var l="kanonak.org",i="core-rdf",y="core-owl",_="core-kanonak",x=new Map([["type",i],["subClassOf",i],["subPropertyOf",i],["domain",i],["range",i],["label",i],["comment",i],["seeAlso",i],["isDefinedBy",i],["member",i],["Resource",i],["Class",i],["Property",i],["Datatype",i],["Literal",i],["List",i],["ObjectProperty",y],["DatatypeProperty",y],["AnnotationProperty",y],["Thing",y],["Nothing",y],["Package",_]]),E=new Set(["type","subClassOf","subPropertyOf","domain","range"]);function X(r){return x.has(r)}function B(r,e,t){if(!r||!r.name)return;let a=x.get(r.name);if(!a)return;let s=()=>{r.publisher=l,r.package_=a,t&&(r.version=t.get(a))};if(E.has(r.name)){let n=r.publisher===l&&r.package_===a;r.publisher=l,r.package_=a,!n&&t&&(r.version=t.get(a));return}r.publisher===l&&r.package_===a||r.publisher&&r.publisher.length>0&&(!e||e(r))||s()}var O=class{type=c(l,i,"type");subClassOf=c(l,i,"subClassOf");subPropertyOf=c(l,i,"subPropertyOf");domain=c(l,i,"domain");range=c(l,i,"range");label=c(l,i,"label");comment=c(l,i,"comment");resource=c(l,i,"Resource");class_=c(l,i,"Class");datatype=c(l,i,"Datatype");literal=c(l,i,"Literal");equivalentClass=c(l,y,"equivalentClass");equivalentProperty=c(l,y,"equivalentProperty");inverseOf=c(l,y,"inverseOf");sameAs=c(l,y,"sameAs");transitiveProperty=c(l,y,"TransitiveProperty");symmetricProperty=c(l,y,"SymmetricProperty");objectProperty=c(l,y,"ObjectProperty");datatypeProperty=c(l,y,"DatatypeProperty");annotationProperty=c(l,y,"AnnotationProperty");package_=c(l,_,"Package")};export{K as a,S as b,D as c,L as d,c as e,M as f,I as g,F as h,X as i,B as j,O as k};
@@ -1 +0,0 @@
1
- import{b as y,c as s,g as l,h as g,i as b,j as u,k,l as K}from"./chunk-4UT2CLAT.js";import{c as d,g as m}from"./chunk-2ACBWC7K.js";function S(t){return`${t.publisher}/${t.package_}/${t.name}`}function f(t,e){return t.publisher===e.publisher&&t.package_===e.package_&&t.name===e.name}function U(t){let e=t.version;return e&&typeof e.major=="number"?`https://${t.publisher}/${t.package_}/${e.major}.${e.minor}.${e.patch}/${t.name}`:`https://${t.publisher}/${t.package_}/${t.name}`}function h(t,e){if(!(t instanceof y))return!1;for(let n of t.statement)if(n.predicate?.subject?.name==="type"&&n instanceof u){let r=n.object;if(f(r.subject,e))return!0}return!1}function j(t,e){let n=[];for(let o of t)o instanceof s&&h(o,e)&&n.push(o);return n}function E(t,e){let n=e.version,o=n&&typeof n.major=="number"?`${e.publisher}/${e.package_}@${n.major}.${n.minor}.${n.patch}`:void 0;for(let r of t){if(!(r instanceof s)||r.name!==e.name)continue;let a=r.namespace||"";if(o!==void 0){if(a===o)return r}else if(a.startsWith(`${e.publisher}/${e.package_}@`))return r}}function $(t,e){let n=[];for(let o of t){if(!(o instanceof s)||o.name!==e.name)continue;(o.namespace||"").startsWith(`${e.publisher}/${e.package_}@`)&&n.push(o)}return n.sort((o,r)=>{let a=m((o.namespace||"").split("@")[1]??""),c=m((r.namespace||"").split("@")[1]??"");return a?c?d(c,a):-1:c?1:0}),n}function i(t,e){for(let n of t.statement){let o=n.predicate;if(o?.subject&&f(o.subject,e))return n}}function x(t,e){return i(t,e)!==void 0}function D(t,e){let n=i(t,e);if(n&&(n instanceof l||n instanceof g||n instanceof b))return n.object}function A(t,e){let n=D(t,e);return typeof n=="string"?n:void 0}function R(t,e){let n=i(t,e);if(n instanceof u)return n.object.subject}function P(t,e){let n=i(t,e);if(n instanceof k)return n.object}function v(t,e){let n=i(t,e);return n instanceof K?n.object??[]:[]}var p=class{constructor(e,n){this.doc=e;this.broader=n}doc;broader;async getAllDocumentsAsync(){return[this.doc]}async getDocumentAsync(e){return this.broader.getDocumentAsync(e)}async getDocumentsByNamespaceAsync(e,n){return this.broader.getDocumentsByNamespaceAsync(e,n)}async getHighestCompatibleVersionAsync(e,n){return this.broader.getHighestCompatibleVersionAsync(e,n)}async saveDocumentAsync(){throw new Error("SingleDocumentRepository is read-only")}async deleteDocumentAsync(){throw new Error("SingleDocumentRepository is read-only")}async clearNamespaceAsync(){throw new Error("SingleDocumentRepository is read-only")}async getAllDocumentReferencesAsync(){return[]}async getDocumentContentAsync(e){return this.broader.getDocumentContentAsync(e)}async getDocumentUriAsync(e){return this.broader.getDocumentUriAsync(e)}};export{S as a,f as b,U as c,h as d,j as e,E as f,$ as g,x as h,D as i,A as j,R as k,P as l,v as m,p as n};
@@ -1 +0,0 @@
1
- import{a as N}from"./chunk-NJ3AZYQD.js";import{b as V,c as C,i as B,j as M}from"./chunk-7HRKWTBB.js";import{a as _,b as U,c as S,d as k,g as P,h as x,i as O,j as I,k as R,l as v}from"./chunk-4UT2CLAT.js";import{j as $}from"./chunk-2ACBWC7K.js";var w=class extends U{name};var K=class extends _{value;carrier;lexical};var D=class extends P{links=[]};import{Carrier as j,carrierOf as F}from"@kanonak-protocol/canonical";function T(p){return F(`${p.publisher}/${p.package_}/${p.name}`)}var Y=/\[\[([^\[\]\n]+)\]\]/g,G=/\[\[/g,z=/```[\s\S]*?```|`[^`\n]*`/g;function q(p){let e=[];for(let t of p.matchAll(z))e.push([t.index,t.index+t[0].length]);return e}function ae(p){if(!p||!p.includes("[["))return[];let e=q(p),t=s=>e.some(([r,i])=>s>=r&&s<i),a=new Set(E(p).map(s=>s.startOffset)),n=[];for(let s of p.matchAll(G)){let r=s.index;if(t(r)||a.has(r))continue;let i=p.slice(r,r+48).replace(/\s+/g," ").trim();n.push({startOffset:r,snippet:i})}return n}function E(p){if(!p||!p.includes("[["))return[];let e=[];for(let n of p.matchAll(z))e.push([n.index,n.index+n[0].length]);let t=n=>e.some(([s,r])=>n>=s&&n<r),a=[];for(let n of p.matchAll(Y)){let s=n.index;if(t(s))continue;let r=n[1],i=r.indexOf("|"),c=(i===-1?r:r.slice(0,i)).trim();if(c.length===0)continue;let f=i===-1?"":r.slice(i+1).trim(),g={reference:c,startOffset:s,endOffset:s+n[0].length};f.length>0&&(g.displayText=f),a.push(g)}return a}var X=class{constructor(e){}async parseKanonaks(e){let t=[],a=await e.getAllDocumentsAsync(),n=new V(e),s=new C(n);for(let o of a){let m=o.metadata.namespace_?.toString()??"";for(let[u,y]of Object.entries(o.body)){let d=new S,b=this.resolveCanonicalEntity(u,o,m);d.namespace=b.namespace,d.name=b.name,d.statement=[];let h=await this.parseStatements(y,o,n,s,e);d.statement.push(...h.statements),d.unresolvedPredicates=h.unresolved,t.push(d)}}let r=new Map,i=new Map,c=[];for(let o of t)if(o instanceof S){let m=`${o.namespace}/${o.name}`,u=r.get(m);if(u){let y=i.get(m);for(let d of o.statement){let b=L(d);y.has(b)||(y.add(b),u.statement.push(d))}for(let d of o.unresolvedPredicates)u.unresolvedPredicates.some(b=>b.key===d.key&&b.sourceDoc===d.sourceDoc)||u.unresolvedPredicates.push(d)}else{let y=new Set,d=[];for(let b of o.statement){let h=L(b);y.has(h)||(y.add(h),d.push(b))}o.statement=d,i.set(m,y),r.set(m,o),c.push(o)}}else c.push(o);let f=new Set;for(let o of c)if(o instanceof S){let m=o.namespace||"",u=m.indexOf("/"),y=u>=0?m.slice(0,u):"",d=u>=0?m.slice(u+1):"",b=d.indexOf("@"),h=b>=0?d.slice(0,b):d;f.add(`${y}/${h}/${o.name}`)}let g=o=>f.has(`${o.publisher}/${o.package_}/${o.name}`),l=new Map;for(let o of["core-rdf","core-owl","core-kanonak"]){let m=await e.getDocumentsByNamespaceAsync("kanonak.org",o);l.set(o,$(m).chosen?.metadata.namespace_?.version??void 0)}for(let o of c)o instanceof S&&this.canonicalizeStatementBuiltins(o.statement,g,l);return c}canonicalizeStatementBuiltins(e,t,a){for(let n of e){let s=n.predicate?.subject;if(M(s,t,a),n instanceof I)n.object instanceof k&&M(n.object.subject,t,a);else if(n instanceof R)n.object&&this.canonicalizeStatementBuiltins(n.object.statement,t,a);else if(n instanceof v)for(let r of n.object??[])r instanceof k?M(r.subject,t,a):r instanceof w&&this.canonicalizeStatementBuiltins(r.statement,t,a)}}resolveCanonicalEntity(e,t,a){if(!e.includes(".")||!t.metadata?.imports)return{namespace:a,name:e};let n=e.indexOf("."),s=e.substring(0,n),r=e.substring(n+1);for(let[i,c]of Object.entries(t.metadata.imports))for(let f of c)if((f.alias??f.packageName)===s){let l=f.version;return{namespace:`${i}/${f.packageName}@${l.major}.${l.minor}.${l.patch}`,name:r}}return{namespace:a,name:e}}async parseStatements(e,t,a,n,s){let r=[],i=[];if(typeof e!="object"||e===null||Array.isArray(e))return{statements:r,unresolved:i};let c=t.metadata.namespace_?.toString()??"";for(let[f,g]of Object.entries(e))try{let l=await this.getPropertyMetadata(f,t,a,s,n);if(!l){let m=f.includes(".")?f.slice(f.lastIndexOf(".")+1):f;B(m)||i.push({key:f,sourceDoc:c});continue}let o=await this.parsePropertyValue(f,g,l,t,a,n,s);o&&r.push(o)}catch(l){throw new Error(`Failed to parse property '${f}': ${l.message}`,{cause:l})}return{statements:r,unresolved:i}}async getPropertyMetadata(e,t,a,n,s){let r=await a.resolveEntityAsync(e,t);if(!r)return;let i=r.entity,c=i.type?.toString()??"",f=c.includes(".")?c.substring(c.lastIndexOf(".")+1):c;if(!new Set(["Property","DatatypeProperty","ObjectProperty","AnnotationProperty"]).has(f))return;let l=s.getPropertyTypeClassification(c),o=i.range?.toString(),m;if(l==="ObjectProperty")m="ObjectProperty";else if(l==="DatatypeProperty")m="DatatypeProperty";else{let d=o&&o.includes(".")?o.substring(o.lastIndexOf(".")+1):o??"";(o?s.isKnownXsdDatatypeName(o):!1)||d==="Literal"?m="DatatypeProperty":m="ObjectProperty"}let u;if(o){let d=t;if(r.isImported&&r.definedInNamespace){if(typeof n.getDocumentAsync!="function")throw new Error(`Cannot resolve the range of imported property '${e}': the parse repository cannot fetch defining document '${r.definedInNamespace}'. Thread the real repository through to embedded-object parsing \u2014 no stub, no fallback.`);let h=await n.getDocumentAsync(r.definedInNamespace);if(!h)throw new Error(`Cannot resolve the range of imported property '${e}': defining document '${r.definedInNamespace}' was not found in the repository.`);d=h}u=(await a.resolveEntityAsync(o,d))?.uri}return{propertyUri:r.uri.toString(),propertyType:m,range:o,rangeUri:u,isImported:r.isImported,definedInNamespace:r.definedInNamespace}}async parsePropertyValue(e,t,a,n,s,r,i){let c=a.propertyUri;if(t!=null){if(Array.isArray(t))return this.parseListValue(c,t,a,n,s,r,i);if(a.propertyType==="DatatypeProperty")return this.parseDatatypeValue(c,t,a,n,s,r);if(a.propertyType==="ObjectProperty")return this.parseObjectValue(c,t,a,n,s,r,i)}}async parseDatatypeValue(e,t,a,n,s,r){let i;if(typeof t=="string"){if(r.isSubstitutableDatatype(a.rangeUri))return await this.parseSubstitutableValue(e,t,n,s);i=t}else if(typeof t=="number"||typeof t=="boolean")i=String(t);else return;return this.typedScalarStatement(e,i,a)}typedScalarStatement(e,t,a){let n=k.parse(e),s=a.rangeUri?T(a.rangeUri):void 0;if(s===j.Boolean){let i=new O;return i.predicate=n,i.object=t==="true"||t==="1",i.carrier=s,i.lexical=t,i}if(s===j.Integer||s===j.Decimal||s===j.Double||s===j.Float){let i=new x;return i.predicate=n,i.object=Number(t),i.carrier=s,i.lexical=t,i}let r=P.parse(e,t);return s&&(r.carrier=s,r.lexical=t),r}typedListLiteral(e,t){let a=new K,n=t.rangeUri?T(t.rangeUri):void 0;return n===j.Boolean?a.value=e==="true"||e==="1":n===j.Integer||n===j.Decimal||n===j.Double||n===j.Float?a.value=Number(e):a.value=e,n&&(a.carrier=n,a.lexical=e),a}async parseSubstitutableValue(e,t,a,n){let s=new D;s.predicate=k.parse(e),s.object=t;for(let r of E(t)){let i=await n.resolveEntityAsync(r.reference,a),c;i&&(c=new k,c.subject=i.uri);let f={reference:r.reference,startOffset:r.startOffset,endOffset:r.endOffset};r.displayText!==void 0&&(f.displayText=r.displayText),c!==void 0&&(f.target=c),s.links.push(f)}return s}async parseObjectValue(e,t,a,n,s,r,i){if(typeof t=="string"){let c=await this.resolveReference(t,n,s);if(!c)return;let f=new I;return f.predicate=k.parse(e),f.object=c,f}if(typeof t=="object"&&!Array.isArray(t)){let c=await this.parseStatements(t,n,s,r,i);if(c.statements.length>0){let l=new w;l.statement=c.statements,l.unresolvedPredicates=c.unresolved;let o=new R;return o.predicate=k.parse(e),o.object=l,o}let f=[];for(let[l,o]of Object.entries(t))if(typeof o=="object"&&o!==null&&!Array.isArray(o)){let m=new w;m.name=l;let u=await this.parseStatements(o,n,s,r,i);m.statement=u.statements,m.unresolvedPredicates=u.unresolved,f.push(m)}else if(typeof o=="string"){let m=await this.resolveReference(o,n,s);m&&f.push(m)}if(f.length>0){let l=new v;return l.predicate=k.parse(e),l.object=f,l}let g=new R;return g.predicate=k.parse(e),g.object=new w,g}}async parseListValue(e,t,a,n,s,r,i){let c=[],f=a.propertyType==="DatatypeProperty",g=a.rangeUri?.publisher==="kanonak.org"&&a.rangeUri?.package_==="core-rdf"&&a.rangeUri?.name==="List"||!a.rangeUri&&(a.range?.includes(".")?a.range.substring(a.range.lastIndexOf(".")+1):a.range)==="List";for(let o of t){let m=typeof o=="string"||typeof o=="number"||typeof o=="boolean";if(f&&m){let u=typeof o=="string"?o:String(o);c.push(this.typedListLiteral(u,a));continue}if(g&&m){if(typeof o=="string"){let u=await s.resolveEntityAsync(o,n);if(u){let y=new k;y.subject=u.uri,c.push(y)}else{let y=new K;y.value=o,c.push(y)}}else{let u=new K;u.value=o,c.push(u)}continue}if(typeof o=="string"){let u=await this.resolveReference(o,n,s);u&&c.push(u)}else if(typeof o=="object"&&o!==null&&!Array.isArray(o)){let u=new w,y=await this.parseStatements(o,n,s,r,i);u.statement=y.statements,u.unresolvedPredicates=y.unresolved,c.push(u)}}let l=new v;return l.predicate=k.parse(e),l.object=c,l}async resolveReference(e,t,a){let n=await a.resolveEntityAsync(e,t);if(n){let r=new k;return r.subject=n.uri,r}let s=t.metadata?.namespace_;if(s){let{KanonakUri:r}=await import("./KanonakUri-4VJGV3FN.js");if(e.includes(".")){let c=e.indexOf("."),f=e.substring(0,c),g=e.substring(c+1);if(t.metadata?.imports){for(let[l,o]of Object.entries(t.metadata.imports))for(let m of o)if((m.alias??m.packageName)===f){let y=new k;return y.subject=new r(l,m.packageName,g,m.version),y}}}let i=new k;return i.subject=new r(s.publisher,s.package_,e,s.version??void 0),i}return null}async saveKanonaks(e,t){let a=new Map;for(let n of e)n instanceof S&&n.namespace&&(a.has(n.namespace)||a.set(n.namespace,[]),a.get(n.namespace).push(n));for(let[n,s]of a){let r=await this.convertKanonaksToDocument(n,s),i=`${n.split("@")[0]}.yml`;await t.saveDocumentAsync(r,i)}}async serializeToYaml(e,t){let a=e.filter(r=>r instanceof S&&r.namespace===t);if(a.length===0)throw new Error(`No kanonaks found with namespace '${t}'`);let n=await this.convertKanonaksToDocument(t,a);return new N().save(n)}async convertKanonaksToDocument(e,t){let n={metadata:{namespace_:e,get allImports(){if(!this.imports)return[];let r=[];for(let i of Object.values(this.imports))r.push(...i);return r}},body:{}},s=new Map;for(let r of t){let i={};for(let c of r.statement){let[f,g]=this.convertStatementToProperty(c);f&&g!==null&&g!==void 0&&(i[f]=g),this.collectImportsFromStatement(c,e,s)}n.body[r.name]=i}return n}convertStatementToProperty(e){if(e instanceof P)return[e.predicate.subject.name,e.object];if(e instanceof x)return[e.predicate.subject.name,e.object];if(e instanceof O)return[e.predicate.subject.name,e.object];if(e instanceof I)return[e.predicate.subject.name,e.object.subject.name];if(e instanceof v){let t=this.convertKanonakListToValue(e.object);return[e.predicate.subject.name,t]}else if(e instanceof R){let t=this.convertEmbeddedKanonakToValue(e.object);return[e.predicate.subject.name,t]}return[null,null]}convertKanonakListToValue(e){let t=[];for(let a of e)a instanceof k?t.push(a.subject.name):a instanceof w&&t.push(this.convertEmbeddedKanonakToValue(a));return t}convertEmbeddedKanonakToValue(e){let t={};for(let a of e.statement){let[n,s]=this.convertStatementToProperty(a);n&&s!==null&&s!==void 0&&(t[n]=s)}return t}collectImportsFromStatement(e,t,a){}};function L(p){let e=p.predicate?.subject;return(e?`${e.publisher}/${e.package_}/${e.name}`:"?")+"="+H(p)}function H(p){return p instanceof D?"m:"+String(p.object):p instanceof P?"s:"+String(p.object):p instanceof x?"n:"+String(p.object):p instanceof O?"b:"+String(p.object):p instanceof I?"r:"+A(p.object):p instanceof R?"e:"+A(p.object):p instanceof v?"l:["+(p.object??[]).map(A).join("|")+"]":"x"}function A(p){if(!p)return"";if(p instanceof k){let e=p.subject;return"R("+(e?`${e.publisher}/${e.package_}/${e.name}`:"")+")"}return p instanceof w?"E("+(p.statement??[]).map(L).join(";")+")":p instanceof K?"L("+String(p.value)+")":"N"}export{w as a,K as b,D as c,j as d,T as e,ae as f,E as g,X as h};