@canon-protocol/sdk 8.0.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 (165) hide show
  1. package/dist/canons/Canon.d.ts +2 -0
  2. package/dist/canons/Canon.js +2 -0
  3. package/dist/canons/DefinedCanon.d.ts +5 -0
  4. package/dist/canons/DefinedCanon.js +4 -0
  5. package/dist/canons/EmbeddedCanon.d.ts +3 -0
  6. package/dist/canons/EmbeddedCanon.js +3 -0
  7. package/dist/canons/ReferenceCanon.d.ts +6 -0
  8. package/dist/canons/ReferenceCanon.js +10 -0
  9. package/dist/canons/SubjectCanon.d.ts +6 -0
  10. package/dist/canons/SubjectCanon.js +6 -0
  11. package/dist/canons/index.d.ts +5 -0
  12. package/dist/canons/index.js +5 -0
  13. package/dist/ctl/CtlCanonUri.d.ts +28 -0
  14. package/dist/ctl/CtlCanonUri.js +230 -0
  15. package/dist/ctl/CtlGraphResolver.d.ts +14 -0
  16. package/dist/ctl/CtlGraphResolver.js +411 -0
  17. package/dist/ctl/CtlMarkdownRenderer.d.ts +17 -0
  18. package/dist/ctl/CtlMarkdownRenderer.js +262 -0
  19. package/dist/ctl/CtlParser.d.ts +10 -0
  20. package/dist/ctl/CtlParser.js +331 -0
  21. package/dist/ctl/CtlValidator.d.ts +12 -0
  22. package/dist/ctl/CtlValidator.js +207 -0
  23. package/dist/ctl/ResourceTypeClassifier.d.ts +21 -0
  24. package/dist/ctl/ResourceTypeClassifier.js +126 -0
  25. package/dist/ctl/index.d.ts +12 -0
  26. package/dist/ctl/index.js +9 -0
  27. package/dist/filtering/GitIgnoreFilter.d.ts +7 -0
  28. package/dist/filtering/GitIgnoreFilter.js +32 -0
  29. package/dist/filtering/IGitIgnoreFilter.d.ts +3 -0
  30. package/dist/filtering/IGitIgnoreFilter.js +1 -0
  31. package/dist/filtering/index.d.ts +2 -0
  32. package/dist/filtering/index.js +1 -0
  33. package/dist/index.d.ts +19 -0
  34. package/dist/index.js +8 -0
  35. package/dist/parsing/CanonObjectParser.d.ts +21 -0
  36. package/dist/parsing/CanonObjectParser.js +242 -0
  37. package/dist/parsing/CanonParser.d.ts +21 -0
  38. package/dist/parsing/CanonParser.js +457 -0
  39. package/dist/parsing/ICanonObjectParser.d.ts +7 -0
  40. package/dist/parsing/ICanonObjectParser.js +1 -0
  41. package/dist/parsing/PropertyMetadata.d.ts +7 -0
  42. package/dist/parsing/PropertyMetadata.js +7 -0
  43. package/dist/parsing/index.d.ts +6 -0
  44. package/dist/parsing/index.js +3 -0
  45. package/dist/repositories/CompositeCanonDocumentRepository.d.ts +28 -0
  46. package/dist/repositories/CompositeCanonDocumentRepository.js +125 -0
  47. package/dist/repositories/FileSystemCanonDocumentRepository.d.ts +28 -0
  48. package/dist/repositories/FileSystemCanonDocumentRepository.js +295 -0
  49. package/dist/repositories/HttpCanonDocumentRepository.d.ts +24 -0
  50. package/dist/repositories/HttpCanonDocumentRepository.js +79 -0
  51. package/dist/repositories/InMemoryCanonDocumentRepository.d.ts +23 -0
  52. package/dist/repositories/InMemoryCanonDocumentRepository.js +149 -0
  53. package/dist/repositories/PublisherConfig.d.ts +12 -0
  54. package/dist/repositories/PublisherConfig.js +62 -0
  55. package/dist/repositories/PublisherIndex.d.ts +20 -0
  56. package/dist/repositories/PublisherIndex.js +127 -0
  57. package/dist/repositories/RepositoryFactory.d.ts +6 -0
  58. package/dist/repositories/RepositoryFactory.js +13 -0
  59. package/dist/repositories/index.d.ts +9 -0
  60. package/dist/repositories/index.js +7 -0
  61. package/dist/resolution/CanonUri.d.ts +10 -0
  62. package/dist/resolution/CanonUri.js +55 -0
  63. package/dist/resolution/CanonUriBuilder.d.ts +12 -0
  64. package/dist/resolution/CanonUriBuilder.js +51 -0
  65. package/dist/resolution/ResourceResolutionResult.d.ts +9 -0
  66. package/dist/resolution/ResourceResolutionResult.js +1 -0
  67. package/dist/resolution/ResourceResolver.d.ts +27 -0
  68. package/dist/resolution/ResourceResolver.js +266 -0
  69. package/dist/resolution/TypeResolver.d.ts +15 -0
  70. package/dist/resolution/TypeResolver.js +110 -0
  71. package/dist/resolution/index.d.ts +6 -0
  72. package/dist/resolution/index.js +4 -0
  73. package/dist/statements/BooleanStatement.d.ts +3 -0
  74. package/dist/statements/BooleanStatement.js +3 -0
  75. package/dist/statements/EmbeddedStatement.d.ts +4 -0
  76. package/dist/statements/EmbeddedStatement.js +3 -0
  77. package/dist/statements/IStatement.d.ts +2 -0
  78. package/dist/statements/IStatement.js +1 -0
  79. package/dist/statements/ListStatement.d.ts +4 -0
  80. package/dist/statements/ListStatement.js +3 -0
  81. package/dist/statements/NumberStatement.d.ts +4 -0
  82. package/dist/statements/NumberStatement.js +10 -0
  83. package/dist/statements/ReferenceStatement.d.ts +5 -0
  84. package/dist/statements/ReferenceStatement.js +10 -0
  85. package/dist/statements/ScalarStatement.d.ts +3 -0
  86. package/dist/statements/ScalarStatement.js +3 -0
  87. package/dist/statements/Statement.d.ts +6 -0
  88. package/dist/statements/Statement.js +4 -0
  89. package/dist/statements/StringStatement.d.ts +4 -0
  90. package/dist/statements/StringStatement.js +10 -0
  91. package/dist/statements/index.d.ts +9 -0
  92. package/dist/statements/index.js +8 -0
  93. package/dist/validation/CanonObjectValidator.d.ts +21 -0
  94. package/dist/validation/CanonObjectValidator.js +150 -0
  95. package/dist/validation/ICanonObjectValidator.d.ts +7 -0
  96. package/dist/validation/ICanonObjectValidator.js +1 -0
  97. package/dist/validation/OntologyValidationError.d.ts +15 -0
  98. package/dist/validation/OntologyValidationError.js +25 -0
  99. package/dist/validation/OntologyValidationResult.d.ts +7 -0
  100. package/dist/validation/OntologyValidationResult.js +8 -0
  101. package/dist/validation/ValidationContext.d.ts +6 -0
  102. package/dist/validation/ValidationContext.js +10 -0
  103. package/dist/validation/ValidationSeverity.d.ts +4 -0
  104. package/dist/validation/ValidationSeverity.js +5 -0
  105. package/dist/validation/index.d.ts +10 -0
  106. package/dist/validation/index.js +7 -0
  107. package/dist/validation/rules/document/EmbeddedCanonNoExplicitTypeRule.d.ts +8 -0
  108. package/dist/validation/rules/document/EmbeddedCanonNoExplicitTypeRule.js +53 -0
  109. package/dist/validation/rules/document/IDocumentValidationRule.d.ts +6 -0
  110. package/dist/validation/rules/document/IDocumentValidationRule.js +1 -0
  111. package/dist/validation/rules/document/NamespacePrefixRule.d.ts +10 -0
  112. package/dist/validation/rules/document/NamespacePrefixRule.js +51 -0
  113. package/dist/validation/rules/document/PropertyTypeSpecificityRule.d.ts +11 -0
  114. package/dist/validation/rules/document/PropertyTypeSpecificityRule.js +89 -0
  115. package/dist/validation/rules/document/ResourceNamingRule.d.ts +12 -0
  116. package/dist/validation/rules/document/ResourceNamingRule.js +79 -0
  117. package/dist/validation/rules/document/SubjectCanonTypeRequiredRule.d.ts +7 -0
  118. package/dist/validation/rules/document/SubjectCanonTypeRequiredRule.js +33 -0
  119. package/dist/validation/rules/document/index.d.ts +6 -0
  120. package/dist/validation/rules/document/index.js +5 -0
  121. package/dist/validation/rules/normalizeToStringList.d.ts +1 -0
  122. package/dist/validation/rules/normalizeToStringList.js +9 -0
  123. package/dist/validation/rules/repository/AmbiguousReferenceRule.d.ts +14 -0
  124. package/dist/validation/rules/repository/AmbiguousReferenceRule.js +155 -0
  125. package/dist/validation/rules/repository/ClassDefinitionRule.d.ts +12 -0
  126. package/dist/validation/rules/repository/ClassDefinitionRule.js +205 -0
  127. package/dist/validation/rules/repository/ClassHierarchyCycleRule.d.ts +11 -0
  128. package/dist/validation/rules/repository/ClassHierarchyCycleRule.js +98 -0
  129. package/dist/validation/rules/repository/DefinitionPropertyReferenceRule.d.ts +13 -0
  130. package/dist/validation/rules/repository/DefinitionPropertyReferenceRule.js +162 -0
  131. package/dist/validation/rules/repository/IRepositoryValidationRule.d.ts +7 -0
  132. package/dist/validation/rules/repository/IRepositoryValidationRule.js +1 -0
  133. package/dist/validation/rules/repository/ImportExistenceRule.d.ts +12 -0
  134. package/dist/validation/rules/repository/ImportExistenceRule.js +124 -0
  135. package/dist/validation/rules/repository/InstancePropertyReferenceRule.d.ts +13 -0
  136. package/dist/validation/rules/repository/InstancePropertyReferenceRule.js +161 -0
  137. package/dist/validation/rules/repository/NamespaceImportCycleRule.d.ts +11 -0
  138. package/dist/validation/rules/repository/NamespaceImportCycleRule.js +85 -0
  139. package/dist/validation/rules/repository/ObjectPropertyImportRule.d.ts +9 -0
  140. package/dist/validation/rules/repository/ObjectPropertyImportRule.js +113 -0
  141. package/dist/validation/rules/repository/ObjectPropertyValueValidationRule.d.ts +12 -0
  142. package/dist/validation/rules/repository/ObjectPropertyValueValidationRule.js +281 -0
  143. package/dist/validation/rules/repository/PropertyDomainRule.d.ts +14 -0
  144. package/dist/validation/rules/repository/PropertyDomainRule.js +221 -0
  145. package/dist/validation/rules/repository/PropertyHierarchyCycleRule.d.ts +11 -0
  146. package/dist/validation/rules/repository/PropertyHierarchyCycleRule.js +104 -0
  147. package/dist/validation/rules/repository/PropertyRangeReferenceRule.d.ts +13 -0
  148. package/dist/validation/rules/repository/PropertyRangeReferenceRule.js +184 -0
  149. package/dist/validation/rules/repository/PropertyRangeRequiredRule.d.ts +8 -0
  150. package/dist/validation/rules/repository/PropertyRangeRequiredRule.js +40 -0
  151. package/dist/validation/rules/repository/PropertyValueTypeRule.d.ts +11 -0
  152. package/dist/validation/rules/repository/PropertyValueTypeRule.js +171 -0
  153. package/dist/validation/rules/repository/SubClassOfReferenceRule.d.ts +11 -0
  154. package/dist/validation/rules/repository/SubClassOfReferenceRule.js +133 -0
  155. package/dist/validation/rules/repository/SubPropertyOfReferenceRule.d.ts +11 -0
  156. package/dist/validation/rules/repository/SubPropertyOfReferenceRule.js +133 -0
  157. package/dist/validation/rules/repository/TypeAmbiguityRule.d.ts +10 -0
  158. package/dist/validation/rules/repository/TypeAmbiguityRule.js +104 -0
  159. package/dist/validation/rules/repository/UnresolvedReferenceRule.d.ts +11 -0
  160. package/dist/validation/rules/repository/UnresolvedReferenceRule.js +91 -0
  161. package/dist/validation/rules/repository/XsdImportRule.d.ts +11 -0
  162. package/dist/validation/rules/repository/XsdImportRule.js +125 -0
  163. package/dist/validation/rules/repository/index.d.ts +20 -0
  164. package/dist/validation/rules/repository/index.js +19 -0
  165. package/package.json +82 -0
@@ -0,0 +1,110 @@
1
+ export class TypeResolver {
2
+ static KNOWN_XSD_DATATYPES = new Set([
3
+ 'string',
4
+ 'integer',
5
+ 'int',
6
+ 'boolean',
7
+ 'bool',
8
+ 'decimal',
9
+ 'float',
10
+ 'double',
11
+ 'date',
12
+ 'datetime',
13
+ 'time',
14
+ 'duration',
15
+ 'anyuri',
16
+ 'base64binary',
17
+ 'hexbinary',
18
+ 'long',
19
+ 'short',
20
+ 'byte',
21
+ 'nonnegativeinteger',
22
+ 'positiveinteger',
23
+ 'negativeinteger',
24
+ 'nonpositiveinteger',
25
+ 'unsignedint',
26
+ 'unsignedlong',
27
+ 'unsignedshort',
28
+ 'unsignedbyte'
29
+ ]);
30
+ resourceResolver;
31
+ constructor(resourceResolver) {
32
+ this.resourceResolver = resourceResolver;
33
+ }
34
+ isXsdDatatype(uri) {
35
+ if (!uri)
36
+ return false;
37
+ return uri.publisher === 'canon-protocol.org' &&
38
+ uri.package_ === 'core.xsd' &&
39
+ TypeResolver.KNOWN_XSD_DATATYPES.has(uri.name.toLowerCase());
40
+ }
41
+ isLiteralType(uri) {
42
+ if (!uri)
43
+ return false;
44
+ return uri.publisher === 'canon-protocol.org' &&
45
+ uri.package_ === 'core.rdf' &&
46
+ uri.name === 'Literal';
47
+ }
48
+ isKnownXsdDatatypeName(typeName) {
49
+ const name = typeName.includes('.') ? typeName.split('.')[1] : typeName;
50
+ return TypeResolver.KNOWN_XSD_DATATYPES.has(name.toLowerCase());
51
+ }
52
+ async isClassTypeAsync(typeName, currentDocument) {
53
+ if (this.isKnownXsdDatatypeName(typeName)) {
54
+ return false;
55
+ }
56
+ const result = await this.resourceResolver.resolveEntityAsync(typeName, currentDocument);
57
+ if (result) {
58
+ const typeValue = result.entity['type'];
59
+ if (typeValue) {
60
+ const typeStr = String(typeValue);
61
+ return typeStr === 'Class' ||
62
+ typeStr === 'rdfs.Class' ||
63
+ typeStr.endsWith('.Class');
64
+ }
65
+ }
66
+ return true;
67
+ }
68
+ getPropertyTypeClassification(propertyType) {
69
+ if (!propertyType || propertyType.trim().length === 0) {
70
+ return 'Property'; // Default to base Property
71
+ }
72
+ const typeName = propertyType.includes('.') ? propertyType.split('.')[1] : propertyType;
73
+ switch (typeName) {
74
+ case 'DatatypeProperty':
75
+ return 'DatatypeProperty';
76
+ case 'ObjectProperty':
77
+ return 'ObjectProperty';
78
+ case 'AnnotationProperty':
79
+ return 'AnnotationProperty';
80
+ case 'Property':
81
+ return 'Property';
82
+ default:
83
+ return 'Property'; // Unknown types default to base Property
84
+ }
85
+ }
86
+ isEffectiveDatatypeProperty(propertyTypeClassification, rangeUri) {
87
+ if (propertyTypeClassification === 'DatatypeProperty') {
88
+ return true;
89
+ }
90
+ if (propertyTypeClassification === 'Property' && this.isXsdDatatype(rangeUri)) {
91
+ return true;
92
+ }
93
+ if (propertyTypeClassification === 'Property' && this.isLiteralType(rangeUri)) {
94
+ return true;
95
+ }
96
+ return false;
97
+ }
98
+ isEffectiveObjectProperty(propertyTypeClassification, rangeUri) {
99
+ if (propertyTypeClassification === 'ObjectProperty') {
100
+ return true;
101
+ }
102
+ if (propertyTypeClassification === 'Property' &&
103
+ rangeUri &&
104
+ !this.isXsdDatatype(rangeUri) &&
105
+ !this.isLiteralType(rangeUri)) {
106
+ return true;
107
+ }
108
+ return false;
109
+ }
110
+ }
@@ -0,0 +1,6 @@
1
+ export { ResourceResolver } from './ResourceResolver.js';
2
+ export type { ILogger } from './ResourceResolver.js';
3
+ export { CanonUri } from './CanonUri.js';
4
+ export { CanonUriBuilder } from './CanonUriBuilder.js';
5
+ export type { ResourceResolutionResult } from './ResourceResolutionResult.js';
6
+ export { TypeResolver } from './TypeResolver.js';
@@ -0,0 +1,4 @@
1
+ export { ResourceResolver } from './ResourceResolver.js';
2
+ export { CanonUri } from './CanonUri.js';
3
+ export { CanonUriBuilder } from './CanonUriBuilder.js';
4
+ export { TypeResolver } from './TypeResolver.js';
@@ -0,0 +1,3 @@
1
+ import { ScalarStatement } from './ScalarStatement.js';
2
+ export declare class BooleanStatement extends ScalarStatement<boolean> {
3
+ }
@@ -0,0 +1,3 @@
1
+ import { ScalarStatement } from './ScalarStatement.js';
2
+ export class BooleanStatement extends ScalarStatement {
3
+ }
@@ -0,0 +1,4 @@
1
+ import { Statement } from './Statement.js';
2
+ import type { EmbeddedCanon } from '../canons/EmbeddedCanon.js';
3
+ export declare class EmbeddedStatement extends Statement<EmbeddedCanon> {
4
+ }
@@ -0,0 +1,3 @@
1
+ import { Statement } from './Statement.js';
2
+ export class EmbeddedStatement extends Statement {
3
+ }
@@ -0,0 +1,2 @@
1
+ export interface IStatement {
2
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,4 @@
1
+ import { Statement } from './Statement.js';
2
+ import type { Canon } from '../canons/Canon.js';
3
+ export declare class ListStatement extends Statement<Canon[]> {
4
+ }
@@ -0,0 +1,3 @@
1
+ import { Statement } from './Statement.js';
2
+ export class ListStatement extends Statement {
3
+ }
@@ -0,0 +1,4 @@
1
+ import { ScalarStatement } from './ScalarStatement.js';
2
+ export declare class NumberStatement extends ScalarStatement<number> {
3
+ static parse(predicateCanonUri: string, objectValue: number): NumberStatement;
4
+ }
@@ -0,0 +1,10 @@
1
+ import { ScalarStatement } from './ScalarStatement.js';
2
+ import { ReferenceCanon } from '../canons/ReferenceCanon.js';
3
+ export class NumberStatement extends ScalarStatement {
4
+ static parse(predicateCanonUri, objectValue) {
5
+ const stmt = new NumberStatement();
6
+ stmt.predicate = ReferenceCanon.parse(predicateCanonUri);
7
+ stmt.object = objectValue;
8
+ return stmt;
9
+ }
10
+ }
@@ -0,0 +1,5 @@
1
+ import { Statement } from './Statement.js';
2
+ import { ReferenceCanon } from '../canons/ReferenceCanon.js';
3
+ export declare class ReferenceStatement extends Statement<ReferenceCanon> {
4
+ static parse(predicateCanonUri: string, objectCanonUri: string): ReferenceStatement;
5
+ }
@@ -0,0 +1,10 @@
1
+ import { Statement } from './Statement.js';
2
+ import { ReferenceCanon } from '../canons/ReferenceCanon.js';
3
+ export class ReferenceStatement extends Statement {
4
+ static parse(predicateCanonUri, objectCanonUri) {
5
+ const stmt = new ReferenceStatement();
6
+ stmt.predicate = ReferenceCanon.parse(predicateCanonUri);
7
+ stmt.object = ReferenceCanon.parse(objectCanonUri);
8
+ return stmt;
9
+ }
10
+ }
@@ -0,0 +1,3 @@
1
+ import { Statement } from './Statement.js';
2
+ export declare abstract class ScalarStatement<TScalar> extends Statement<TScalar> {
3
+ }
@@ -0,0 +1,3 @@
1
+ import { Statement } from './Statement.js';
2
+ export class ScalarStatement extends Statement {
3
+ }
@@ -0,0 +1,6 @@
1
+ import type { IStatement } from './IStatement.js';
2
+ import type { ReferenceCanon } from '../canons/ReferenceCanon.js';
3
+ export declare abstract class Statement<TObject> implements IStatement {
4
+ predicate: ReferenceCanon;
5
+ object: TObject;
6
+ }
@@ -0,0 +1,4 @@
1
+ export class Statement {
2
+ predicate;
3
+ object;
4
+ }
@@ -0,0 +1,4 @@
1
+ import { ScalarStatement } from './ScalarStatement.js';
2
+ export declare class StringStatement extends ScalarStatement<string> {
3
+ static parse(predicateCanonUri: string, objectValue: string): StringStatement;
4
+ }
@@ -0,0 +1,10 @@
1
+ import { ScalarStatement } from './ScalarStatement.js';
2
+ import { ReferenceCanon } from '../canons/ReferenceCanon.js';
3
+ export class StringStatement extends ScalarStatement {
4
+ static parse(predicateCanonUri, objectValue) {
5
+ const stmt = new StringStatement();
6
+ stmt.predicate = ReferenceCanon.parse(predicateCanonUri);
7
+ stmt.object = objectValue;
8
+ return stmt;
9
+ }
10
+ }
@@ -0,0 +1,9 @@
1
+ export type { IStatement } from './IStatement.js';
2
+ export { Statement } from './Statement.js';
3
+ export { ScalarStatement } from './ScalarStatement.js';
4
+ export { StringStatement } from './StringStatement.js';
5
+ export { NumberStatement } from './NumberStatement.js';
6
+ export { BooleanStatement } from './BooleanStatement.js';
7
+ export { ReferenceStatement } from './ReferenceStatement.js';
8
+ export { EmbeddedStatement } from './EmbeddedStatement.js';
9
+ export { ListStatement } from './ListStatement.js';
@@ -0,0 +1,8 @@
1
+ export { Statement } from './Statement.js';
2
+ export { ScalarStatement } from './ScalarStatement.js';
3
+ export { StringStatement } from './StringStatement.js';
4
+ export { NumberStatement } from './NumberStatement.js';
5
+ export { BooleanStatement } from './BooleanStatement.js';
6
+ export { ReferenceStatement } from './ReferenceStatement.js';
7
+ export { EmbeddedStatement } from './EmbeddedStatement.js';
8
+ export { ListStatement } from './ListStatement.js';
@@ -0,0 +1,21 @@
1
+ import type { ICanonDocumentRepository } from '@canon-protocol/types/document/models';
2
+ import type { CanonDocument } from '@canon-protocol/types/document/models/types';
3
+ import type { ICanonParser } from '@canon-protocol/types/document/parsing';
4
+ import type { ICanonObjectValidator } from './ICanonObjectValidator.js';
5
+ import type { IDocumentValidationRule } from './rules/document/IDocumentValidationRule.js';
6
+ import type { IRepositoryValidationRule } from './rules/repository/IRepositoryValidationRule.js';
7
+ import { OntologyValidationResult } from './OntologyValidationResult.js';
8
+ export declare class CanonObjectValidator implements ICanonObjectValidator {
9
+ private readonly parser;
10
+ private readonly documentRules;
11
+ private readonly repositoryRules;
12
+ includeWarnings: boolean;
13
+ constructor(parser?: ICanonParser);
14
+ validateAsync(document: CanonDocument, repository?: ICanonDocumentRepository | null): Promise<OntologyValidationResult>;
15
+ validateYamlAsync(yamlText: string, repository?: ICanonDocumentRepository | null): Promise<OntologyValidationResult>;
16
+ addDocumentRule(rule: IDocumentValidationRule): void;
17
+ addRepositoryRule(rule: IRepositoryValidationRule): void;
18
+ removeDocumentRule<T extends IDocumentValidationRule>(ruleType: new () => T): void;
19
+ removeRepositoryRule<T extends IRepositoryValidationRule>(ruleType: new () => T): void;
20
+ private addErrorsToResult;
21
+ }
@@ -0,0 +1,150 @@
1
+ import { CanonParser } from '../parsing/CanonParser.js';
2
+ import { OntologyValidationResult } from './OntologyValidationResult.js';
3
+ import { OntologyValidationError } from './OntologyValidationError.js';
4
+ import { ValidationSeverity } from './ValidationSeverity.js';
5
+ import { NamespacePrefixRule } from './rules/document/NamespacePrefixRule.js';
6
+ import { ResourceNamingRule } from './rules/document/ResourceNamingRule.js';
7
+ import { PropertyTypeSpecificityRule } from './rules/document/PropertyTypeSpecificityRule.js';
8
+ import { SubjectCanonTypeRequiredRule } from './rules/document/SubjectCanonTypeRequiredRule.js';
9
+ import { EmbeddedCanonNoExplicitTypeRule } from './rules/document/EmbeddedCanonNoExplicitTypeRule.js';
10
+ import { ImportExistenceRule } from './rules/repository/ImportExistenceRule.js';
11
+ import { UnresolvedReferenceRule } from './rules/repository/UnresolvedReferenceRule.js';
12
+ import { TypeAmbiguityRule } from './rules/repository/TypeAmbiguityRule.js';
13
+ import { ClassHierarchyCycleRule } from './rules/repository/ClassHierarchyCycleRule.js';
14
+ import { PropertyHierarchyCycleRule } from './rules/repository/PropertyHierarchyCycleRule.js';
15
+ import { PropertyRangeRequiredRule } from './rules/repository/PropertyRangeRequiredRule.js';
16
+ import { SubClassOfReferenceRule } from './rules/repository/SubClassOfReferenceRule.js';
17
+ import { SubPropertyOfReferenceRule } from './rules/repository/SubPropertyOfReferenceRule.js';
18
+ import { NamespaceImportCycleRule } from './rules/repository/NamespaceImportCycleRule.js';
19
+ import { InstancePropertyReferenceRule } from './rules/repository/InstancePropertyReferenceRule.js';
20
+ import { DefinitionPropertyReferenceRule } from './rules/repository/DefinitionPropertyReferenceRule.js';
21
+ import { XsdImportRule } from './rules/repository/XsdImportRule.js';
22
+ import { AmbiguousReferenceRule } from './rules/repository/AmbiguousReferenceRule.js';
23
+ import { PropertyRangeReferenceRule } from './rules/repository/PropertyRangeReferenceRule.js';
24
+ import { ObjectPropertyImportRule } from './rules/repository/ObjectPropertyImportRule.js';
25
+ import { ObjectPropertyValueValidationRule } from './rules/repository/ObjectPropertyValueValidationRule.js';
26
+ import { PropertyDomainRule } from './rules/repository/PropertyDomainRule.js';
27
+ import { PropertyValueTypeRule } from './rules/repository/PropertyValueTypeRule.js';
28
+ import { ClassDefinitionRule } from './rules/repository/ClassDefinitionRule.js';
29
+ export class CanonObjectValidator {
30
+ parser;
31
+ documentRules;
32
+ repositoryRules;
33
+ includeWarnings = true;
34
+ constructor(parser) {
35
+ this.parser = parser ?? new CanonParser();
36
+ this.documentRules = [
37
+ new NamespacePrefixRule(),
38
+ new ResourceNamingRule(),
39
+ new PropertyTypeSpecificityRule(),
40
+ new SubjectCanonTypeRequiredRule(),
41
+ new EmbeddedCanonNoExplicitTypeRule()
42
+ ];
43
+ this.repositoryRules = [
44
+ new ImportExistenceRule(),
45
+ new UnresolvedReferenceRule(),
46
+ new TypeAmbiguityRule(),
47
+ new ClassHierarchyCycleRule(),
48
+ new PropertyHierarchyCycleRule(),
49
+ new PropertyRangeRequiredRule(),
50
+ new SubClassOfReferenceRule(),
51
+ new SubPropertyOfReferenceRule(),
52
+ new NamespaceImportCycleRule(),
53
+ new InstancePropertyReferenceRule(),
54
+ new DefinitionPropertyReferenceRule(),
55
+ new XsdImportRule(),
56
+ new AmbiguousReferenceRule(),
57
+ new PropertyRangeReferenceRule(),
58
+ new ObjectPropertyImportRule(),
59
+ new ObjectPropertyValueValidationRule(),
60
+ new PropertyDomainRule(),
61
+ new PropertyValueTypeRule(),
62
+ new ClassDefinitionRule()
63
+ ];
64
+ }
65
+ async validateAsync(document, repository) {
66
+ const result = new OntologyValidationResult();
67
+ for (const rule of this.documentRules) {
68
+ try {
69
+ const ruleErrors = rule.validate(document);
70
+ this.addErrorsToResult(result, ruleErrors);
71
+ }
72
+ catch (error) {
73
+ const validationError = new OntologyValidationError();
74
+ validationError.ruleType = rule.ruleName;
75
+ validationError.severity = ValidationSeverity.Error;
76
+ validationError.message = `Validation rule '${rule.ruleName}' failed: ${error instanceof Error ? error.message : String(error)}`;
77
+ result.errors.push(validationError);
78
+ }
79
+ }
80
+ if (repository) {
81
+ for (const rule of this.repositoryRules) {
82
+ try {
83
+ const ruleErrors = await rule.validateAsync(document, repository);
84
+ this.addErrorsToResult(result, ruleErrors);
85
+ }
86
+ catch (error) {
87
+ const validationError = new OntologyValidationError();
88
+ validationError.ruleType = rule.ruleName;
89
+ validationError.severity = ValidationSeverity.Error;
90
+ validationError.message = `Validation rule '${rule.ruleName}' failed: ${error instanceof Error ? error.message : String(error)}`;
91
+ result.errors.push(validationError);
92
+ }
93
+ }
94
+ }
95
+ result.isValid = result.errors.length === 0;
96
+ return result;
97
+ }
98
+ async validateYamlAsync(yamlText, repository) {
99
+ const parseResult = this.parser.parseWithErrors(yamlText);
100
+ if (!parseResult.isValid) {
101
+ const result = new OntologyValidationResult();
102
+ result.isValid = false;
103
+ for (const parseError of parseResult.errors) {
104
+ const validationError = new OntologyValidationError();
105
+ validationError.ruleType = 'ParseError';
106
+ validationError.severity = ValidationSeverity.Error;
107
+ validationError.lineNumber = parseError.line;
108
+ validationError.column = parseError.column;
109
+ validationError.message = parseError.message;
110
+ if (parseError.keyName) {
111
+ validationError.entityName = parseError.keyName; // For duplicate keys, store the key name
112
+ }
113
+ if (parseError.errorType === 'DuplicateKey') {
114
+ validationError.suggestion = 'All property names must be unique across the entire document. Rename one of the duplicate properties to make them unique.';
115
+ }
116
+ result.errors.push(validationError);
117
+ }
118
+ return result;
119
+ }
120
+ return await this.validateAsync(parseResult.document, repository);
121
+ }
122
+ addDocumentRule(rule) {
123
+ this.documentRules.push(rule);
124
+ }
125
+ addRepositoryRule(rule) {
126
+ this.repositoryRules.push(rule);
127
+ }
128
+ removeDocumentRule(ruleType) {
129
+ const index = this.documentRules.findIndex(r => r instanceof ruleType);
130
+ if (index >= 0) {
131
+ this.documentRules.splice(index, 1);
132
+ }
133
+ }
134
+ removeRepositoryRule(ruleType) {
135
+ const index = this.repositoryRules.findIndex(r => r instanceof ruleType);
136
+ if (index >= 0) {
137
+ this.repositoryRules.splice(index, 1);
138
+ }
139
+ }
140
+ addErrorsToResult(result, errors) {
141
+ for (const error of errors) {
142
+ if (error.severity === ValidationSeverity.Error) {
143
+ result.errors.push(error);
144
+ }
145
+ else if (this.includeWarnings) {
146
+ result.warnings.push(error);
147
+ }
148
+ }
149
+ }
150
+ }
@@ -0,0 +1,7 @@
1
+ import type { ICanonDocumentRepository } from '@canon-protocol/types/document/models';
2
+ import type { CanonDocument } from '@canon-protocol/types/document/models/types';
3
+ import type { OntologyValidationResult } from './OntologyValidationResult.js';
4
+ export interface ICanonObjectValidator {
5
+ validateAsync(document: CanonDocument, repository?: ICanonDocumentRepository | null): Promise<OntologyValidationResult>;
6
+ validateYamlAsync(yamlText: string, repository?: ICanonDocumentRepository | null): Promise<OntologyValidationResult>;
7
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,15 @@
1
+ import { ValidationSeverity } from './ValidationSeverity.js';
2
+ export declare class OntologyValidationError {
3
+ ruleType: string;
4
+ severity: ValidationSeverity;
5
+ lineNumber?: number;
6
+ column?: number;
7
+ entityName?: string;
8
+ propertyName?: string;
9
+ propertyPath?: string;
10
+ message: string;
11
+ suggestion?: string;
12
+ actualValue?: string;
13
+ expectedValue?: string;
14
+ toString(): string;
15
+ }
@@ -0,0 +1,25 @@
1
+ import { ValidationSeverity } from './ValidationSeverity.js';
2
+ export class OntologyValidationError {
3
+ ruleType = '';
4
+ severity = ValidationSeverity.Error;
5
+ lineNumber;
6
+ column;
7
+ entityName;
8
+ propertyName;
9
+ propertyPath;
10
+ message = '';
11
+ suggestion;
12
+ actualValue;
13
+ expectedValue;
14
+ toString() {
15
+ let result = '';
16
+ if (this.lineNumber !== undefined) {
17
+ result += `Line ${this.lineNumber}: `;
18
+ }
19
+ if (this.entityName) {
20
+ result += `[${this.entityName}] `;
21
+ }
22
+ result += this.message;
23
+ return result;
24
+ }
25
+ }
@@ -0,0 +1,7 @@
1
+ import { OntologyValidationError } from './OntologyValidationError.js';
2
+ export declare class OntologyValidationResult {
3
+ isValid: boolean;
4
+ errors: OntologyValidationError[];
5
+ warnings: OntologyValidationError[];
6
+ get totalIssues(): number;
7
+ }
@@ -0,0 +1,8 @@
1
+ export class OntologyValidationResult {
2
+ isValid = false;
3
+ errors = [];
4
+ warnings = [];
5
+ get totalIssues() {
6
+ return this.errors.length + this.warnings.length;
7
+ }
8
+ }
@@ -0,0 +1,6 @@
1
+ import type { CanonDocument } from '@canon-protocol/types/document/models/types';
2
+ export declare class ValidationContext {
3
+ resolvedDocuments: CanonDocument[];
4
+ currentEntityPath?: string;
5
+ withPath(path: string): ValidationContext;
6
+ }
@@ -0,0 +1,10 @@
1
+ export class ValidationContext {
2
+ resolvedDocuments = [];
3
+ currentEntityPath;
4
+ withPath(path) {
5
+ const newContext = new ValidationContext();
6
+ newContext.resolvedDocuments = this.resolvedDocuments;
7
+ newContext.currentEntityPath = path;
8
+ return newContext;
9
+ }
10
+ }
@@ -0,0 +1,4 @@
1
+ export declare enum ValidationSeverity {
2
+ Warning = "Warning",
3
+ Error = "Error"
4
+ }
@@ -0,0 +1,5 @@
1
+ export var ValidationSeverity;
2
+ (function (ValidationSeverity) {
3
+ ValidationSeverity["Warning"] = "Warning";
4
+ ValidationSeverity["Error"] = "Error";
5
+ })(ValidationSeverity || (ValidationSeverity = {}));
@@ -0,0 +1,10 @@
1
+ export { OntologyValidationResult } from './OntologyValidationResult.js';
2
+ export { OntologyValidationError } from './OntologyValidationError.js';
3
+ export { ValidationSeverity } from './ValidationSeverity.js';
4
+ export { ValidationContext } from './ValidationContext.js';
5
+ export type { ICanonObjectValidator } from './ICanonObjectValidator.js';
6
+ export { CanonObjectValidator } from './CanonObjectValidator.js';
7
+ export type { IDocumentValidationRule } from './rules/document/IDocumentValidationRule.js';
8
+ export type { IRepositoryValidationRule } from './rules/repository/IRepositoryValidationRule.js';
9
+ export { NamespacePrefixRule, ResourceNamingRule, PropertyTypeSpecificityRule, SubjectCanonTypeRequiredRule, EmbeddedCanonNoExplicitTypeRule } from './rules/document/index.js';
10
+ export { ImportExistenceRule, UnresolvedReferenceRule, TypeAmbiguityRule, ClassHierarchyCycleRule, PropertyHierarchyCycleRule, PropertyRangeRequiredRule, SubClassOfReferenceRule, SubPropertyOfReferenceRule, NamespaceImportCycleRule, InstancePropertyReferenceRule, DefinitionPropertyReferenceRule, XsdImportRule, AmbiguousReferenceRule, PropertyRangeReferenceRule, ObjectPropertyImportRule, ObjectPropertyValueValidationRule, PropertyDomainRule, PropertyValueTypeRule, ClassDefinitionRule } from './rules/repository/index.js';
@@ -0,0 +1,7 @@
1
+ export { OntologyValidationResult } from './OntologyValidationResult.js';
2
+ export { OntologyValidationError } from './OntologyValidationError.js';
3
+ export { ValidationSeverity } from './ValidationSeverity.js';
4
+ export { ValidationContext } from './ValidationContext.js';
5
+ export { CanonObjectValidator } from './CanonObjectValidator.js';
6
+ export { NamespacePrefixRule, ResourceNamingRule, PropertyTypeSpecificityRule, SubjectCanonTypeRequiredRule, EmbeddedCanonNoExplicitTypeRule } from './rules/document/index.js';
7
+ export { ImportExistenceRule, UnresolvedReferenceRule, TypeAmbiguityRule, ClassHierarchyCycleRule, PropertyHierarchyCycleRule, PropertyRangeRequiredRule, SubClassOfReferenceRule, SubPropertyOfReferenceRule, NamespaceImportCycleRule, InstancePropertyReferenceRule, DefinitionPropertyReferenceRule, XsdImportRule, AmbiguousReferenceRule, PropertyRangeReferenceRule, ObjectPropertyImportRule, ObjectPropertyValueValidationRule, PropertyDomainRule, PropertyValueTypeRule, ClassDefinitionRule } from './rules/repository/index.js';
@@ -0,0 +1,8 @@
1
+ import type { CanonDocument } from '@canon-protocol/types/document/models/types';
2
+ import type { IDocumentValidationRule } from './IDocumentValidationRule.js';
3
+ import { OntologyValidationError } from '../../OntologyValidationError.js';
4
+ export declare class EmbeddedCanonNoExplicitTypeRule implements IDocumentValidationRule {
5
+ get ruleName(): string;
6
+ validate(document: CanonDocument): OntologyValidationError[];
7
+ private checkForEmbeddedTypeViolations;
8
+ }
@@ -0,0 +1,53 @@
1
+ import { OntologyValidationError } from '../../OntologyValidationError.js';
2
+ import { ValidationSeverity } from '../../ValidationSeverity.js';
3
+ export class EmbeddedCanonNoExplicitTypeRule {
4
+ get ruleName() {
5
+ return 'EmbeddedCanonNoExplicitType';
6
+ }
7
+ validate(document) {
8
+ const errors = [];
9
+ for (const [entityName, entityDef] of Object.entries(document.body)) {
10
+ if (typeof entityDef === 'object' && entityDef !== null && !Array.isArray(entityDef)) {
11
+ this.checkForEmbeddedTypeViolations(entityName, entityDef, errors, 0);
12
+ }
13
+ }
14
+ return errors;
15
+ }
16
+ checkForEmbeddedTypeViolations(path, dict, errors, depth) {
17
+ for (const [key, value] of Object.entries(dict)) {
18
+ const propertyName = key;
19
+ if (depth > 0 && propertyName.toLowerCase() === 'type') {
20
+ const typeValue = value?.toString();
21
+ const rootEntity = path.split('.')[0];
22
+ const error = new OntologyValidationError();
23
+ error.ruleType = this.ruleName;
24
+ error.severity = ValidationSeverity.Error;
25
+ error.entityName = rootEntity; // Root entity for lookup
26
+ error.propertyName = path; // Full nested path for navigation
27
+ error.actualValue = 'type'; // Property to find at end of path
28
+ error.message = `Embedded object at '${path}' cannot have explicit 'type' property.`;
29
+ error.suggestion =
30
+ `Remove the 'type: ${typeValue}' line.\n\n` +
31
+ "Type is automatically inferred from the containing property's range.\n" +
32
+ "If you need a different type, modify the 'range' of the parent property and version it appropriately.\n\n" +
33
+ "Example: If the parent property is 'hasCharacter' with range 'Character', " +
34
+ "all embedded objects in that property will be typed as 'Character' automatically.";
35
+ error.expectedValue = "No explicit type (inferred from parent property's range)";
36
+ errors.push(error);
37
+ }
38
+ if (typeof value === 'object' && value !== null) {
39
+ if (Array.isArray(value)) {
40
+ for (let i = 0; i < value.length; i++) {
41
+ const item = value[i];
42
+ if (typeof item === 'object' && item !== null && !Array.isArray(item)) {
43
+ this.checkForEmbeddedTypeViolations(`${path}.${propertyName}[${i}]`, item, errors, depth + 1);
44
+ }
45
+ }
46
+ }
47
+ else {
48
+ this.checkForEmbeddedTypeViolations(`${path}.${propertyName}`, value, errors, depth + 1);
49
+ }
50
+ }
51
+ }
52
+ }
53
+ }
@@ -0,0 +1,6 @@
1
+ import type { CanonDocument } from '@canon-protocol/types/document/models/types';
2
+ import type { OntologyValidationError } from '../../OntologyValidationError.js';
3
+ export interface IDocumentValidationRule {
4
+ readonly ruleName: string;
5
+ validate(document: CanonDocument): OntologyValidationError[];
6
+ }