@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.
- package/dist/canons/Canon.d.ts +2 -0
- package/dist/canons/Canon.js +2 -0
- package/dist/canons/DefinedCanon.d.ts +5 -0
- package/dist/canons/DefinedCanon.js +4 -0
- package/dist/canons/EmbeddedCanon.d.ts +3 -0
- package/dist/canons/EmbeddedCanon.js +3 -0
- package/dist/canons/ReferenceCanon.d.ts +6 -0
- package/dist/canons/ReferenceCanon.js +10 -0
- package/dist/canons/SubjectCanon.d.ts +6 -0
- package/dist/canons/SubjectCanon.js +6 -0
- package/dist/canons/index.d.ts +5 -0
- package/dist/canons/index.js +5 -0
- package/dist/ctl/CtlCanonUri.d.ts +28 -0
- package/dist/ctl/CtlCanonUri.js +230 -0
- package/dist/ctl/CtlGraphResolver.d.ts +14 -0
- package/dist/ctl/CtlGraphResolver.js +411 -0
- package/dist/ctl/CtlMarkdownRenderer.d.ts +17 -0
- package/dist/ctl/CtlMarkdownRenderer.js +262 -0
- package/dist/ctl/CtlParser.d.ts +10 -0
- package/dist/ctl/CtlParser.js +331 -0
- package/dist/ctl/CtlValidator.d.ts +12 -0
- package/dist/ctl/CtlValidator.js +207 -0
- package/dist/ctl/ResourceTypeClassifier.d.ts +21 -0
- package/dist/ctl/ResourceTypeClassifier.js +126 -0
- package/dist/ctl/index.d.ts +12 -0
- package/dist/ctl/index.js +9 -0
- package/dist/filtering/GitIgnoreFilter.d.ts +7 -0
- package/dist/filtering/GitIgnoreFilter.js +32 -0
- package/dist/filtering/IGitIgnoreFilter.d.ts +3 -0
- package/dist/filtering/IGitIgnoreFilter.js +1 -0
- package/dist/filtering/index.d.ts +2 -0
- package/dist/filtering/index.js +1 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.js +8 -0
- package/dist/parsing/CanonObjectParser.d.ts +21 -0
- package/dist/parsing/CanonObjectParser.js +242 -0
- package/dist/parsing/CanonParser.d.ts +21 -0
- package/dist/parsing/CanonParser.js +457 -0
- package/dist/parsing/ICanonObjectParser.d.ts +7 -0
- package/dist/parsing/ICanonObjectParser.js +1 -0
- package/dist/parsing/PropertyMetadata.d.ts +7 -0
- package/dist/parsing/PropertyMetadata.js +7 -0
- package/dist/parsing/index.d.ts +6 -0
- package/dist/parsing/index.js +3 -0
- package/dist/repositories/CompositeCanonDocumentRepository.d.ts +28 -0
- package/dist/repositories/CompositeCanonDocumentRepository.js +125 -0
- package/dist/repositories/FileSystemCanonDocumentRepository.d.ts +28 -0
- package/dist/repositories/FileSystemCanonDocumentRepository.js +295 -0
- package/dist/repositories/HttpCanonDocumentRepository.d.ts +24 -0
- package/dist/repositories/HttpCanonDocumentRepository.js +79 -0
- package/dist/repositories/InMemoryCanonDocumentRepository.d.ts +23 -0
- package/dist/repositories/InMemoryCanonDocumentRepository.js +149 -0
- package/dist/repositories/PublisherConfig.d.ts +12 -0
- package/dist/repositories/PublisherConfig.js +62 -0
- package/dist/repositories/PublisherIndex.d.ts +20 -0
- package/dist/repositories/PublisherIndex.js +127 -0
- package/dist/repositories/RepositoryFactory.d.ts +6 -0
- package/dist/repositories/RepositoryFactory.js +13 -0
- package/dist/repositories/index.d.ts +9 -0
- package/dist/repositories/index.js +7 -0
- package/dist/resolution/CanonUri.d.ts +10 -0
- package/dist/resolution/CanonUri.js +55 -0
- package/dist/resolution/CanonUriBuilder.d.ts +12 -0
- package/dist/resolution/CanonUriBuilder.js +51 -0
- package/dist/resolution/ResourceResolutionResult.d.ts +9 -0
- package/dist/resolution/ResourceResolutionResult.js +1 -0
- package/dist/resolution/ResourceResolver.d.ts +27 -0
- package/dist/resolution/ResourceResolver.js +266 -0
- package/dist/resolution/TypeResolver.d.ts +15 -0
- package/dist/resolution/TypeResolver.js +110 -0
- package/dist/resolution/index.d.ts +6 -0
- package/dist/resolution/index.js +4 -0
- package/dist/statements/BooleanStatement.d.ts +3 -0
- package/dist/statements/BooleanStatement.js +3 -0
- package/dist/statements/EmbeddedStatement.d.ts +4 -0
- package/dist/statements/EmbeddedStatement.js +3 -0
- package/dist/statements/IStatement.d.ts +2 -0
- package/dist/statements/IStatement.js +1 -0
- package/dist/statements/ListStatement.d.ts +4 -0
- package/dist/statements/ListStatement.js +3 -0
- package/dist/statements/NumberStatement.d.ts +4 -0
- package/dist/statements/NumberStatement.js +10 -0
- package/dist/statements/ReferenceStatement.d.ts +5 -0
- package/dist/statements/ReferenceStatement.js +10 -0
- package/dist/statements/ScalarStatement.d.ts +3 -0
- package/dist/statements/ScalarStatement.js +3 -0
- package/dist/statements/Statement.d.ts +6 -0
- package/dist/statements/Statement.js +4 -0
- package/dist/statements/StringStatement.d.ts +4 -0
- package/dist/statements/StringStatement.js +10 -0
- package/dist/statements/index.d.ts +9 -0
- package/dist/statements/index.js +8 -0
- package/dist/validation/CanonObjectValidator.d.ts +21 -0
- package/dist/validation/CanonObjectValidator.js +150 -0
- package/dist/validation/ICanonObjectValidator.d.ts +7 -0
- package/dist/validation/ICanonObjectValidator.js +1 -0
- package/dist/validation/OntologyValidationError.d.ts +15 -0
- package/dist/validation/OntologyValidationError.js +25 -0
- package/dist/validation/OntologyValidationResult.d.ts +7 -0
- package/dist/validation/OntologyValidationResult.js +8 -0
- package/dist/validation/ValidationContext.d.ts +6 -0
- package/dist/validation/ValidationContext.js +10 -0
- package/dist/validation/ValidationSeverity.d.ts +4 -0
- package/dist/validation/ValidationSeverity.js +5 -0
- package/dist/validation/index.d.ts +10 -0
- package/dist/validation/index.js +7 -0
- package/dist/validation/rules/document/EmbeddedCanonNoExplicitTypeRule.d.ts +8 -0
- package/dist/validation/rules/document/EmbeddedCanonNoExplicitTypeRule.js +53 -0
- package/dist/validation/rules/document/IDocumentValidationRule.d.ts +6 -0
- package/dist/validation/rules/document/IDocumentValidationRule.js +1 -0
- package/dist/validation/rules/document/NamespacePrefixRule.d.ts +10 -0
- package/dist/validation/rules/document/NamespacePrefixRule.js +51 -0
- package/dist/validation/rules/document/PropertyTypeSpecificityRule.d.ts +11 -0
- package/dist/validation/rules/document/PropertyTypeSpecificityRule.js +89 -0
- package/dist/validation/rules/document/ResourceNamingRule.d.ts +12 -0
- package/dist/validation/rules/document/ResourceNamingRule.js +79 -0
- package/dist/validation/rules/document/SubjectCanonTypeRequiredRule.d.ts +7 -0
- package/dist/validation/rules/document/SubjectCanonTypeRequiredRule.js +33 -0
- package/dist/validation/rules/document/index.d.ts +6 -0
- package/dist/validation/rules/document/index.js +5 -0
- package/dist/validation/rules/normalizeToStringList.d.ts +1 -0
- package/dist/validation/rules/normalizeToStringList.js +9 -0
- package/dist/validation/rules/repository/AmbiguousReferenceRule.d.ts +14 -0
- package/dist/validation/rules/repository/AmbiguousReferenceRule.js +155 -0
- package/dist/validation/rules/repository/ClassDefinitionRule.d.ts +12 -0
- package/dist/validation/rules/repository/ClassDefinitionRule.js +205 -0
- package/dist/validation/rules/repository/ClassHierarchyCycleRule.d.ts +11 -0
- package/dist/validation/rules/repository/ClassHierarchyCycleRule.js +98 -0
- package/dist/validation/rules/repository/DefinitionPropertyReferenceRule.d.ts +13 -0
- package/dist/validation/rules/repository/DefinitionPropertyReferenceRule.js +162 -0
- package/dist/validation/rules/repository/IRepositoryValidationRule.d.ts +7 -0
- package/dist/validation/rules/repository/IRepositoryValidationRule.js +1 -0
- package/dist/validation/rules/repository/ImportExistenceRule.d.ts +12 -0
- package/dist/validation/rules/repository/ImportExistenceRule.js +124 -0
- package/dist/validation/rules/repository/InstancePropertyReferenceRule.d.ts +13 -0
- package/dist/validation/rules/repository/InstancePropertyReferenceRule.js +161 -0
- package/dist/validation/rules/repository/NamespaceImportCycleRule.d.ts +11 -0
- package/dist/validation/rules/repository/NamespaceImportCycleRule.js +85 -0
- package/dist/validation/rules/repository/ObjectPropertyImportRule.d.ts +9 -0
- package/dist/validation/rules/repository/ObjectPropertyImportRule.js +113 -0
- package/dist/validation/rules/repository/ObjectPropertyValueValidationRule.d.ts +12 -0
- package/dist/validation/rules/repository/ObjectPropertyValueValidationRule.js +281 -0
- package/dist/validation/rules/repository/PropertyDomainRule.d.ts +14 -0
- package/dist/validation/rules/repository/PropertyDomainRule.js +221 -0
- package/dist/validation/rules/repository/PropertyHierarchyCycleRule.d.ts +11 -0
- package/dist/validation/rules/repository/PropertyHierarchyCycleRule.js +104 -0
- package/dist/validation/rules/repository/PropertyRangeReferenceRule.d.ts +13 -0
- package/dist/validation/rules/repository/PropertyRangeReferenceRule.js +184 -0
- package/dist/validation/rules/repository/PropertyRangeRequiredRule.d.ts +8 -0
- package/dist/validation/rules/repository/PropertyRangeRequiredRule.js +40 -0
- package/dist/validation/rules/repository/PropertyValueTypeRule.d.ts +11 -0
- package/dist/validation/rules/repository/PropertyValueTypeRule.js +171 -0
- package/dist/validation/rules/repository/SubClassOfReferenceRule.d.ts +11 -0
- package/dist/validation/rules/repository/SubClassOfReferenceRule.js +133 -0
- package/dist/validation/rules/repository/SubPropertyOfReferenceRule.d.ts +11 -0
- package/dist/validation/rules/repository/SubPropertyOfReferenceRule.js +133 -0
- package/dist/validation/rules/repository/TypeAmbiguityRule.d.ts +10 -0
- package/dist/validation/rules/repository/TypeAmbiguityRule.js +104 -0
- package/dist/validation/rules/repository/UnresolvedReferenceRule.d.ts +11 -0
- package/dist/validation/rules/repository/UnresolvedReferenceRule.js +91 -0
- package/dist/validation/rules/repository/XsdImportRule.d.ts +11 -0
- package/dist/validation/rules/repository/XsdImportRule.js +125 -0
- package/dist/validation/rules/repository/index.d.ts +20 -0
- package/dist/validation/rules/repository/index.js +19 -0
- 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 @@
|
|
|
1
|
+
export {};
|
|
@@ -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,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,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,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
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|