@shaclmate/compiler 2.0.14 → 2.0.16
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/_ShapesGraphToAstTransformer/transformNodeShapeToAstType.js +22 -7
- package/_ShapesGraphToAstTransformer/transformPropertyShapeToAstCompositeType.js +5 -3
- package/ast/ListType.d.ts +2 -2
- package/ast/ObjectType.d.ts +18 -12
- package/enums/IdentifierMintingStrategy.d.ts +5 -0
- package/enums/IdentifierMintingStrategy.js +2 -0
- package/enums/index.d.ts +1 -1
- package/enums/index.js +1 -1
- package/generators/json/AstJsonGenerator.js +5 -1
- package/generators/ts/DateTimeType.d.ts +3 -1
- package/generators/ts/DateTimeType.js +9 -1
- package/generators/ts/IdentifierType.d.ts +2 -0
- package/generators/ts/IdentifierType.js +11 -0
- package/generators/ts/Import.d.ts +0 -1
- package/generators/ts/Import.js +0 -5
- package/generators/ts/ListType.d.ts +4 -3
- package/generators/ts/ListType.js +27 -16
- package/generators/ts/ObjectType.d.ts +5 -4
- package/generators/ts/ObjectType.js +21 -9
- package/generators/ts/ObjectUnionType.d.ts +1 -1
- package/generators/ts/ObjectUnionType.js +22 -52
- package/generators/ts/OptionType.d.ts +3 -1
- package/generators/ts/OptionType.js +12 -11
- package/generators/ts/PrimitiveType.d.ts +2 -2
- package/generators/ts/PrimitiveType.js +9 -4
- package/generators/ts/SetType.d.ts +3 -1
- package/generators/ts/SetType.js +12 -8
- package/generators/ts/SnippetDeclarations.d.ts +11 -0
- package/generators/ts/SnippetDeclarations.js +215 -0
- package/generators/ts/TermType.d.ts +3 -1
- package/generators/ts/TermType.js +16 -8
- package/generators/ts/TsGenerator.js +15 -1
- package/generators/ts/Type.d.ts +15 -5
- package/generators/ts/Type.js +17 -0
- package/generators/ts/TypeFactory.js +18 -8
- package/generators/ts/UnionType.d.ts +2 -1
- package/generators/ts/UnionType.js +3 -3
- package/generators/ts/_ObjectType/IdentifierProperty.d.ts +7 -8
- package/generators/ts/_ObjectType/IdentifierProperty.js +99 -25
- package/generators/ts/_ObjectType/Property.d.ts +17 -3
- package/generators/ts/_ObjectType/Property.js +2 -1
- package/generators/ts/_ObjectType/ShaclProperty.d.ts +1 -0
- package/generators/ts/_ObjectType/ShaclProperty.js +4 -1
- package/generators/ts/_ObjectType/TypeDiscriminatorProperty.d.ts +3 -5
- package/generators/ts/_ObjectType/TypeDiscriminatorProperty.js +11 -4
- package/generators/ts/_ObjectType/equalsFunctionOrMethodDeclaration.js +1 -1
- package/generators/ts/_ObjectType/fromJsonFunctionDeclarations.js +1 -1
- package/generators/ts/_ObjectType/fromRdfFunctionDeclarations.js +1 -1
- package/generators/ts/_ObjectType/fromRdfTypeVariableStatement.d.ts +5 -0
- package/generators/ts/_ObjectType/fromRdfTypeVariableStatement.js +25 -0
- package/generators/ts/_ObjectType/index.d.ts +1 -0
- package/generators/ts/_ObjectType/index.js +1 -0
- package/generators/ts/_ObjectType/sparqlConstructQueryFunctionDeclaration.d.ts +5 -0
- package/generators/ts/_ObjectType/sparqlConstructQueryFunctionDeclaration.js +21 -0
- package/generators/ts/_ObjectType/sparqlConstructQueryStringFunctionDeclaration.d.ts +5 -0
- package/generators/ts/_ObjectType/sparqlConstructQueryStringFunctionDeclaration.js +20 -0
- package/generators/ts/_ObjectType/sparqlFunctionDeclarations.js +35 -58
- package/generators/ts/_ObjectType/toJsonFunctionOrMethodDeclaration.js +1 -1
- package/generators/ts/_ObjectType/toRdfFunctionOrMethodDeclaration.js +3 -3
- package/input/NodeShape.d.ts +2 -2
- package/input/generated.d.ts +24 -16
- package/input/generated.js +53 -8
- package/input/tsFeatures.d.ts +1 -1
- package/input/tsFeatures.js +21 -13
- package/package.json +4 -4
- package/enums/MintingStrategy.d.ts +0 -5
- package/enums/MintingStrategy.js +0 -2
|
@@ -9,6 +9,7 @@ import { Maybe } from "purify-ts";
|
|
|
9
9
|
import { invariant } from "ts-invariant";
|
|
10
10
|
import { Memoize } from "typescript-memoize";
|
|
11
11
|
import { Import } from "./Import.js";
|
|
12
|
+
import { SnippetDeclarations } from "./SnippetDeclarations.js";
|
|
12
13
|
import { Type } from "./Type.js";
|
|
13
14
|
import { objectInitializer } from "./objectInitializer.js";
|
|
14
15
|
/**
|
|
@@ -17,7 +18,7 @@ import { objectInitializer } from "./objectInitializer.js";
|
|
|
17
18
|
export class TermType extends Type {
|
|
18
19
|
constructor({ defaultValue, hasValues, in_, nodeKinds, ...superParameters }) {
|
|
19
20
|
super(superParameters);
|
|
20
|
-
this.equalsFunction = "
|
|
21
|
+
this.equalsFunction = "booleanEquals";
|
|
21
22
|
this.mutable = false;
|
|
22
23
|
this.defaultValue = defaultValue;
|
|
23
24
|
this.hasValues = hasValues;
|
|
@@ -80,13 +81,6 @@ export class TermType extends Type {
|
|
|
80
81
|
.map((nodeKind) => `rdfjs.${nodeKind}`)
|
|
81
82
|
.join(" | ")})`;
|
|
82
83
|
}
|
|
83
|
-
get useImports() {
|
|
84
|
-
const imports = [Import.RDFJS_TYPES];
|
|
85
|
-
if (this.nodeKinds.has("Literal")) {
|
|
86
|
-
imports.push(Import.RDF_LITERAL);
|
|
87
|
-
}
|
|
88
|
-
return imports;
|
|
89
|
-
}
|
|
90
84
|
fromJsonExpression({ variables, }) {
|
|
91
85
|
invariant(this.nodeKinds.has("Literal") &&
|
|
92
86
|
(this.nodeKinds.has("BlankNode") || this.nodeKinds.has("NamedNode")), "IdentifierType and LiteralType should override");
|
|
@@ -161,6 +155,13 @@ export class TermType extends Type {
|
|
|
161
155
|
})
|
|
162
156
|
.join(", ")}])`;
|
|
163
157
|
}
|
|
158
|
+
snippetDeclarations(features) {
|
|
159
|
+
const snippetDeclarations = [];
|
|
160
|
+
if (features.has("equals")) {
|
|
161
|
+
snippetDeclarations.push(SnippetDeclarations.booleanEquals);
|
|
162
|
+
}
|
|
163
|
+
return snippetDeclarations;
|
|
164
|
+
}
|
|
164
165
|
sparqlWherePatterns(parameters) {
|
|
165
166
|
switch (parameters.context) {
|
|
166
167
|
case "property":
|
|
@@ -201,6 +202,13 @@ export class TermType extends Type {
|
|
|
201
202
|
.map((defaultValue) => `!${variables.value}.equals(${this.rdfjsTermExpression(defaultValue)}) ? ${variables.value} : undefined`)
|
|
202
203
|
.orDefault(variables.value);
|
|
203
204
|
}
|
|
205
|
+
useImports() {
|
|
206
|
+
const imports = [Import.RDFJS_TYPES];
|
|
207
|
+
if (this.nodeKinds.has("Literal")) {
|
|
208
|
+
imports.push(Import.RDF_LITERAL);
|
|
209
|
+
}
|
|
210
|
+
return imports;
|
|
211
|
+
}
|
|
204
212
|
/**
|
|
205
213
|
* Filter the rdfjsResource.Resource.Values to those that are relevant to the type.
|
|
206
214
|
*
|
|
@@ -30,9 +30,13 @@ export class TsGenerator {
|
|
|
30
30
|
addDeclarations({ objectTypes, objectUnionTypes, sourceFile, }) {
|
|
31
31
|
// sourceFile.addStatements(this.configuration.dataFactoryImport);
|
|
32
32
|
sourceFile.addStatements('import { DataFactory as dataFactory } from "n3"');
|
|
33
|
+
const declaredTypes = [
|
|
34
|
+
...objectTypes,
|
|
35
|
+
...objectUnionTypes,
|
|
36
|
+
];
|
|
33
37
|
// Gather imports
|
|
34
38
|
const imports = [];
|
|
35
|
-
for (const declaredType of
|
|
39
|
+
for (const declaredType of declaredTypes) {
|
|
36
40
|
imports.push(...declaredType.declarationImports);
|
|
37
41
|
}
|
|
38
42
|
// Deduplicate and add imports
|
|
@@ -51,6 +55,16 @@ export class TsGenerator {
|
|
|
51
55
|
addedStructureImports.push(import_);
|
|
52
56
|
}
|
|
53
57
|
}
|
|
58
|
+
// Deduplicate and add snippet declarations
|
|
59
|
+
const addedSnippetDeclarations = new Set();
|
|
60
|
+
for (const declaredType of declaredTypes) {
|
|
61
|
+
for (const snippetDeclaration of declaredType.snippetDeclarations(declaredType.features)) {
|
|
62
|
+
if (!addedSnippetDeclarations.has(snippetDeclaration)) {
|
|
63
|
+
sourceFile.addStatements([snippetDeclaration]);
|
|
64
|
+
addedSnippetDeclarations.add(snippetDeclaration);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
54
68
|
// Add type declarations
|
|
55
69
|
for (const objectType of objectTypes) {
|
|
56
70
|
sourceFile.addStatements(objectType.declarations);
|
package/generators/ts/Type.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { BlankNode, Literal, NamedNode, Variable } from "@rdfjs/types";
|
|
2
2
|
import { Maybe } from "purify-ts";
|
|
3
|
+
import type { TsFeature } from "../../enums/index.js";
|
|
3
4
|
import type { Import } from "./Import.js";
|
|
4
5
|
/**
|
|
5
6
|
* Abstract base class for generating TypeScript expressions and statemenst in the TypeScript generator.
|
|
@@ -13,7 +14,7 @@ export declare abstract class Type {
|
|
|
13
14
|
abstract readonly conversions: readonly Type.Conversion[];
|
|
14
15
|
/**
|
|
15
16
|
* A function (reference or declaration) that compares two property values of this type, returning a
|
|
16
|
-
*
|
|
17
|
+
* EqualsResult.
|
|
17
18
|
*/
|
|
18
19
|
abstract readonly equalsFunction: string;
|
|
19
20
|
/**
|
|
@@ -28,10 +29,6 @@ export declare abstract class Type {
|
|
|
28
29
|
* Name of the type.
|
|
29
30
|
*/
|
|
30
31
|
abstract readonly name: string;
|
|
31
|
-
/**
|
|
32
|
-
* Imports necessary to use this type.
|
|
33
|
-
*/
|
|
34
|
-
abstract readonly useImports: readonly Import[];
|
|
35
32
|
protected readonly dataFactoryVariable: string;
|
|
36
33
|
constructor({ dataFactoryVariable, }: {
|
|
37
34
|
dataFactoryVariable: string;
|
|
@@ -87,6 +84,15 @@ export declare abstract class Type {
|
|
|
87
84
|
zod: string;
|
|
88
85
|
};
|
|
89
86
|
}): string;
|
|
87
|
+
/**
|
|
88
|
+
* Reusable function, type, and other declarations that are not particular to this type but that type-specific code
|
|
89
|
+
* relies on. For example, the equals function/method of ObjectType has a custom return type that's the same across all
|
|
90
|
+
* ObjectType's. Instead of re-declaring the return type anonymously on every equals function, declare a named type
|
|
91
|
+
* as a snippet and reference it.
|
|
92
|
+
*
|
|
93
|
+
* The generator deduplicates snippet declarations across all types before adding them to the source.
|
|
94
|
+
*/
|
|
95
|
+
snippetDeclarations(_features: Set<TsFeature>): readonly string[];
|
|
90
96
|
/**
|
|
91
97
|
* An array of SPARQL.js CONSTRUCT template triples for a value of this type, as strings (so they can incorporate runtime calls).
|
|
92
98
|
*
|
|
@@ -153,6 +159,10 @@ export declare abstract class Type {
|
|
|
153
159
|
value: string;
|
|
154
160
|
};
|
|
155
161
|
}): string;
|
|
162
|
+
/**
|
|
163
|
+
* Imports necessary to use this type.
|
|
164
|
+
*/
|
|
165
|
+
useImports(_features: Set<TsFeature>): readonly Import[];
|
|
156
166
|
protected rdfjsTermExpression(rdfjsTerm: Omit<BlankNode, "equals"> | Omit<Literal, "equals"> | Omit<NamedNode, "equals"> | Omit<Variable, "equals">): string;
|
|
157
167
|
}
|
|
158
168
|
export declare namespace Type {
|
package/generators/ts/Type.js
CHANGED
|
@@ -23,6 +23,17 @@ export class Type {
|
|
|
23
23
|
jsonUiSchemaElement(_parameters) {
|
|
24
24
|
return Maybe.empty();
|
|
25
25
|
}
|
|
26
|
+
/**
|
|
27
|
+
* Reusable function, type, and other declarations that are not particular to this type but that type-specific code
|
|
28
|
+
* relies on. For example, the equals function/method of ObjectType has a custom return type that's the same across all
|
|
29
|
+
* ObjectType's. Instead of re-declaring the return type anonymously on every equals function, declare a named type
|
|
30
|
+
* as a snippet and reference it.
|
|
31
|
+
*
|
|
32
|
+
* The generator deduplicates snippet declarations across all types before adding them to the source.
|
|
33
|
+
*/
|
|
34
|
+
snippetDeclarations(_features) {
|
|
35
|
+
return [];
|
|
36
|
+
}
|
|
26
37
|
/**
|
|
27
38
|
* An array of SPARQL.js CONSTRUCT template triples for a value of this type, as strings (so they can incorporate runtime calls).
|
|
28
39
|
*
|
|
@@ -90,6 +101,12 @@ export class Type {
|
|
|
90
101
|
return [];
|
|
91
102
|
}
|
|
92
103
|
}
|
|
104
|
+
/**
|
|
105
|
+
* Imports necessary to use this type.
|
|
106
|
+
*/
|
|
107
|
+
useImports(_features) {
|
|
108
|
+
return [];
|
|
109
|
+
}
|
|
93
110
|
rdfjsTermExpression(rdfjsTerm) {
|
|
94
111
|
return rdfjsTermExpression({
|
|
95
112
|
dataFactoryVariable: this.dataFactoryVariable,
|
|
@@ -214,8 +214,8 @@ export class TypeFactory {
|
|
|
214
214
|
dataFactoryVariable: this.dataFactoryVariable,
|
|
215
215
|
defaultValue: Maybe.empty(),
|
|
216
216
|
hasValues: [],
|
|
217
|
-
in_:
|
|
218
|
-
nodeKinds: astType.
|
|
217
|
+
in_: astType.identifierIn,
|
|
218
|
+
nodeKinds: astType.identifierKinds,
|
|
219
219
|
});
|
|
220
220
|
const objectType = new ObjectType({
|
|
221
221
|
abstract: astType.abstract,
|
|
@@ -232,7 +232,7 @@ export class TypeFactory {
|
|
|
232
232
|
lazyDescendantObjectTypes: () => astType.descendantObjectTypes.map((astType) => this.createObjectTypeFromAstType(astType)),
|
|
233
233
|
lazyParentObjectTypes: () => astType.parentObjectTypes.map((astType) => this.createObjectTypeFromAstType(astType)),
|
|
234
234
|
lazyProperties: () => {
|
|
235
|
-
const properties = astType.properties.map((astProperty) => this.createObjectTypePropertyFromAstProperty(astProperty));
|
|
235
|
+
const properties = astType.properties.map((astProperty) => this.createObjectTypePropertyFromAstProperty(astType, astProperty));
|
|
236
236
|
let identifierPropertyClassDeclarationVisibility;
|
|
237
237
|
if (astType.abstract) {
|
|
238
238
|
// If the type is abstract, don't declare a property.
|
|
@@ -253,10 +253,13 @@ export class TypeFactory {
|
|
|
253
253
|
abstract: astType.abstract,
|
|
254
254
|
classDeclarationVisibility: identifierPropertyClassDeclarationVisibility,
|
|
255
255
|
dataFactoryVariable: this.dataFactoryVariable,
|
|
256
|
-
|
|
256
|
+
identifierMintingStrategy: astType.identifierMintingStrategy,
|
|
257
257
|
name: astType.tsIdentifierPropertyName,
|
|
258
258
|
lazyObjectTypeMutable: () => properties.some((property) => property.mutable || property.type.mutable),
|
|
259
|
-
|
|
259
|
+
objectType: {
|
|
260
|
+
declarationType: astType.tsObjectDeclarationType,
|
|
261
|
+
features: astType.tsFeatures,
|
|
262
|
+
},
|
|
260
263
|
override: astType.parentObjectTypes.length > 0,
|
|
261
264
|
type: identifierType,
|
|
262
265
|
visibility: "public",
|
|
@@ -277,7 +280,10 @@ export class TypeFactory {
|
|
|
277
280
|
abstract: astType.abstract,
|
|
278
281
|
dataFactoryVariable: this.dataFactoryVariable,
|
|
279
282
|
name: astType.tsTypeDiscriminatorPropertyName,
|
|
280
|
-
|
|
283
|
+
objectType: {
|
|
284
|
+
declarationType: astType.tsObjectDeclarationType,
|
|
285
|
+
features: astType.tsFeatures,
|
|
286
|
+
},
|
|
281
287
|
override: objectType.parentObjectTypes.length > 0,
|
|
282
288
|
type: new ObjectType.TypeDiscriminatorProperty.Type({
|
|
283
289
|
mutable: false,
|
|
@@ -289,14 +295,14 @@ export class TypeFactory {
|
|
|
289
295
|
}
|
|
290
296
|
return properties.sort((left, right) => left.name.localeCompare(right.name));
|
|
291
297
|
},
|
|
292
|
-
mintingStrategy: astType.
|
|
298
|
+
mintingStrategy: astType.identifierMintingStrategy,
|
|
293
299
|
name: tsName(astType.name),
|
|
294
300
|
toRdfTypes: astType.toRdfTypes,
|
|
295
301
|
});
|
|
296
302
|
this.cachedObjectTypesByIdentifier.set(astType.name.identifier, objectType);
|
|
297
303
|
return objectType;
|
|
298
304
|
}
|
|
299
|
-
createObjectTypePropertyFromAstProperty(astObjectTypeProperty) {
|
|
305
|
+
createObjectTypePropertyFromAstProperty(astObjectType, astObjectTypeProperty) {
|
|
300
306
|
{
|
|
301
307
|
const cachedProperty = this.cachedObjectTypePropertiesByIdentifier.get(astObjectTypeProperty.name.identifier);
|
|
302
308
|
if (cachedProperty) {
|
|
@@ -309,6 +315,10 @@ export class TypeFactory {
|
|
|
309
315
|
description: astObjectTypeProperty.description,
|
|
310
316
|
label: astObjectTypeProperty.label,
|
|
311
317
|
mutable: astObjectTypeProperty.mutable.orDefault(false),
|
|
318
|
+
objectType: {
|
|
319
|
+
declarationType: astObjectType.tsObjectDeclarationType,
|
|
320
|
+
features: astObjectType.tsFeatures,
|
|
321
|
+
},
|
|
312
322
|
name: tsName(astObjectTypeProperty.name),
|
|
313
323
|
path: astObjectTypeProperty.path.iri,
|
|
314
324
|
type: this.createTypeFromAstType(astObjectTypeProperty.type),
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Maybe } from "purify-ts";
|
|
2
|
+
import type { TsFeature } from "../../enums/index.js";
|
|
2
3
|
import type { Import } from "./Import.js";
|
|
3
4
|
import { Type } from "./Type.js";
|
|
4
5
|
export declare class UnionType extends Type {
|
|
@@ -15,7 +16,6 @@ export declare class UnionType extends Type {
|
|
|
15
16
|
get equalsFunction(): string;
|
|
16
17
|
get jsonName(): string;
|
|
17
18
|
get mutable(): boolean;
|
|
18
|
-
get useImports(): readonly Import[];
|
|
19
19
|
private get _discriminatorProperty();
|
|
20
20
|
private get memberTypeTraits();
|
|
21
21
|
fromJsonExpression({ variables, }: Parameters<Type["fromJsonExpression"]>[0]): string;
|
|
@@ -26,6 +26,7 @@ export declare class UnionType extends Type {
|
|
|
26
26
|
sparqlWherePatterns(parameters: Parameters<Type["sparqlWherePatterns"]>[0]): readonly string[];
|
|
27
27
|
toJsonExpression({ variables, }: Parameters<Type["toJsonExpression"]>[0]): string;
|
|
28
28
|
toRdfExpression({ variables, }: Parameters<Type["toRdfExpression"]>[0]): string;
|
|
29
|
+
useImports(features: Set<TsFeature>): readonly Import[];
|
|
29
30
|
private ternaryExpression;
|
|
30
31
|
}
|
|
31
32
|
//# sourceMappingURL=UnionType.d.ts.map
|
|
@@ -71,9 +71,6 @@ ${this.memberTypeTraits
|
|
|
71
71
|
get mutable() {
|
|
72
72
|
return this.memberTypes.some((memberType) => memberType.mutable);
|
|
73
73
|
}
|
|
74
|
-
get useImports() {
|
|
75
|
-
return this.memberTypes.flatMap((memberType) => memberType.useImports);
|
|
76
|
-
}
|
|
77
74
|
get _discriminatorProperty() {
|
|
78
75
|
let sharedDiscriminatorProperty;
|
|
79
76
|
for (const memberType of this.memberTypes) {
|
|
@@ -252,6 +249,9 @@ ${this.memberTypeTraits
|
|
|
252
249
|
variables,
|
|
253
250
|
});
|
|
254
251
|
}
|
|
252
|
+
useImports(features) {
|
|
253
|
+
return this.memberTypes.flatMap((memberType) => memberType.useImports(features));
|
|
254
|
+
}
|
|
255
255
|
ternaryExpression({ memberTypeExpression, variables, }) {
|
|
256
256
|
return this.memberTypeTraits.reduce((expression, memberTypeTraits) => {
|
|
257
257
|
if (expression.length === 0) {
|
|
@@ -1,24 +1,22 @@
|
|
|
1
1
|
import { Maybe } from "purify-ts";
|
|
2
2
|
import type { GetAccessorDeclarationStructure, OptionalKind, PropertyDeclarationStructure, PropertySignatureStructure } from "ts-morph";
|
|
3
|
-
import type {
|
|
3
|
+
import type { IdentifierMintingStrategy, PropertyVisibility } from "../../../enums/index.js";
|
|
4
4
|
import type { IdentifierType } from "../IdentifierType.js";
|
|
5
5
|
import { Import } from "../Import.js";
|
|
6
6
|
import { Property } from "./Property.js";
|
|
7
7
|
export declare class IdentifierProperty extends Property<IdentifierType> {
|
|
8
8
|
readonly abstract: boolean;
|
|
9
|
-
readonly equalsFunction = "
|
|
9
|
+
readonly equalsFunction = "booleanEquals";
|
|
10
10
|
readonly mutable = false;
|
|
11
11
|
private readonly classDeclarationVisibility;
|
|
12
|
+
private readonly identifierMintingStrategy;
|
|
12
13
|
private readonly lazyObjectTypeMutable;
|
|
13
|
-
private readonly mintingStrategy;
|
|
14
|
-
private readonly objectTypeDeclarationType;
|
|
15
14
|
private readonly override;
|
|
16
|
-
constructor({ abstract, classDeclarationVisibility, lazyObjectTypeMutable,
|
|
15
|
+
constructor({ abstract, classDeclarationVisibility, lazyObjectTypeMutable, identifierMintingStrategy, override, ...superParameters }: {
|
|
17
16
|
abstract: boolean;
|
|
18
17
|
classDeclarationVisibility: Maybe<PropertyVisibility>;
|
|
19
18
|
lazyObjectTypeMutable: () => boolean;
|
|
20
|
-
|
|
21
|
-
objectTypeDeclarationType: TsObjectDeclarationType;
|
|
19
|
+
identifierMintingStrategy: Maybe<IdentifierMintingStrategy>;
|
|
22
20
|
override: boolean;
|
|
23
21
|
type: IdentifierType;
|
|
24
22
|
} & ConstructorParameters<typeof Property>[0]);
|
|
@@ -28,10 +26,11 @@ export declare class IdentifierProperty extends Property<IdentifierType> {
|
|
|
28
26
|
get declarationImports(): readonly Import[];
|
|
29
27
|
get interfacePropertySignature(): OptionalKind<PropertySignatureStructure>;
|
|
30
28
|
get jsonPropertySignature(): OptionalKind<PropertySignatureStructure>;
|
|
29
|
+
get snippetDeclarations(): readonly string[];
|
|
31
30
|
classConstructorStatements({ variables, }: Parameters<Property<IdentifierType>["classConstructorStatements"]>[0]): readonly string[];
|
|
32
31
|
fromJsonStatements({ variables, }: Parameters<Property<IdentifierType>["fromJsonStatements"]>[0]): readonly string[];
|
|
33
32
|
fromRdfStatements({ variables, }: Parameters<Property<IdentifierType>["fromRdfStatements"]>[0]): readonly string[];
|
|
34
|
-
hashStatements(): readonly string[];
|
|
33
|
+
hashStatements({ variables, }: Parameters<Property<IdentifierType>["hashStatements"]>[0]): readonly string[];
|
|
35
34
|
interfaceConstructorStatements({ variables, }: Parameters<Property<IdentifierType>["interfaceConstructorStatements"]>[0]): readonly string[];
|
|
36
35
|
jsonUiSchemaElement({ variables, }: Parameters<Property<IdentifierType>["jsonUiSchemaElement"]>[0]): Maybe<string>;
|
|
37
36
|
jsonZodSchema({ variables, }: Parameters<Property<IdentifierType>["jsonZodSchema"]>[0]): ReturnType<Property<IdentifierType>["jsonZodSchema"]>;
|
|
@@ -1,25 +1,26 @@
|
|
|
1
|
+
import { rdf } from "@tpluscode/rdf-ns-builders";
|
|
1
2
|
import { Maybe } from "purify-ts";
|
|
2
3
|
import { invariant } from "ts-invariant";
|
|
3
4
|
import { Import } from "../Import.js";
|
|
5
|
+
import { SnippetDeclarations } from "../SnippetDeclarations.js";
|
|
4
6
|
import { Property } from "./Property.js";
|
|
5
7
|
export class IdentifierProperty extends Property {
|
|
6
|
-
constructor({ abstract, classDeclarationVisibility, lazyObjectTypeMutable,
|
|
8
|
+
constructor({ abstract, classDeclarationVisibility, lazyObjectTypeMutable, identifierMintingStrategy, override, ...superParameters }) {
|
|
7
9
|
super(superParameters);
|
|
8
|
-
this.equalsFunction = "
|
|
10
|
+
this.equalsFunction = "booleanEquals";
|
|
9
11
|
this.mutable = false;
|
|
10
12
|
invariant(this.visibility === "public");
|
|
11
13
|
this.abstract = abstract;
|
|
12
14
|
this.classDeclarationVisibility = classDeclarationVisibility;
|
|
13
|
-
if (
|
|
14
|
-
this.
|
|
15
|
+
if (identifierMintingStrategy.isJust()) {
|
|
16
|
+
this.identifierMintingStrategy = identifierMintingStrategy.unsafeCoerce();
|
|
15
17
|
}
|
|
16
18
|
else if (this.type.nodeKinds.has("BlankNode")) {
|
|
17
|
-
this.
|
|
19
|
+
this.identifierMintingStrategy = "blankNode";
|
|
18
20
|
}
|
|
19
21
|
else {
|
|
20
|
-
this.
|
|
22
|
+
this.identifierMintingStrategy = "none";
|
|
21
23
|
}
|
|
22
|
-
this.objectTypeDeclarationType = objectTypeDeclarationType;
|
|
23
24
|
this.lazyObjectTypeMutable = lazyObjectTypeMutable;
|
|
24
25
|
this.override = override;
|
|
25
26
|
}
|
|
@@ -28,7 +29,7 @@ export class IdentifierProperty extends Property {
|
|
|
28
29
|
return Maybe.empty();
|
|
29
30
|
}
|
|
30
31
|
let mintIdentifier;
|
|
31
|
-
switch (this.
|
|
32
|
+
switch (this.identifierMintingStrategy) {
|
|
32
33
|
case "blankNode":
|
|
33
34
|
mintIdentifier = "dataFactory.blankNode()";
|
|
34
35
|
break;
|
|
@@ -72,10 +73,11 @@ export class IdentifierProperty extends Property {
|
|
|
72
73
|
if (!this.classDeclarationVisibility.isJust()) {
|
|
73
74
|
return Maybe.empty();
|
|
74
75
|
}
|
|
75
|
-
switch (this.
|
|
76
|
+
switch (this.identifierMintingStrategy) {
|
|
76
77
|
case "none":
|
|
77
78
|
// Immutable, public identifier property, no getter
|
|
78
79
|
return Maybe.of({
|
|
80
|
+
isReadonly: true,
|
|
79
81
|
name: this.name,
|
|
80
82
|
type: this.type.name,
|
|
81
83
|
});
|
|
@@ -91,21 +93,28 @@ export class IdentifierProperty extends Property {
|
|
|
91
93
|
}
|
|
92
94
|
}
|
|
93
95
|
get constructorParametersPropertySignature() {
|
|
94
|
-
if (this.
|
|
96
|
+
if (this.objectType.declarationType === "class" && this.abstract) {
|
|
95
97
|
return Maybe.empty();
|
|
96
98
|
}
|
|
99
|
+
const typeNames = new Set(); // Remove duplicates with a set
|
|
100
|
+
for (const conversion of this.type.conversions) {
|
|
101
|
+
if (conversion.sourceTypeName !== "undefined") {
|
|
102
|
+
typeNames.add(conversion.sourceTypeName);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
97
105
|
return Maybe.of({
|
|
98
|
-
hasQuestionToken: this.
|
|
99
|
-
this.
|
|
106
|
+
hasQuestionToken: this.objectType.declarationType === "class" &&
|
|
107
|
+
this.identifierMintingStrategy !== "none",
|
|
100
108
|
isReadonly: true,
|
|
101
109
|
name: this.name,
|
|
102
|
-
type:
|
|
110
|
+
type: [...typeNames].sort().join(" | "),
|
|
103
111
|
});
|
|
104
112
|
}
|
|
105
113
|
get declarationImports() {
|
|
106
|
-
const imports = this.type.useImports.concat();
|
|
107
|
-
if (this.
|
|
108
|
-
|
|
114
|
+
const imports = this.type.useImports().concat();
|
|
115
|
+
if (this.objectType.features.has("hash") &&
|
|
116
|
+
this.objectType.declarationType === "class") {
|
|
117
|
+
switch (this.identifierMintingStrategy) {
|
|
109
118
|
case "sha256":
|
|
110
119
|
imports.push(Import.SHA256);
|
|
111
120
|
break;
|
|
@@ -130,15 +139,38 @@ export class IdentifierProperty extends Property {
|
|
|
130
139
|
type: "string",
|
|
131
140
|
};
|
|
132
141
|
}
|
|
142
|
+
get snippetDeclarations() {
|
|
143
|
+
const snippetDeclarations = [];
|
|
144
|
+
if (this.objectType.features.has("equals")) {
|
|
145
|
+
snippetDeclarations.push(SnippetDeclarations.booleanEquals);
|
|
146
|
+
}
|
|
147
|
+
return snippetDeclarations;
|
|
148
|
+
}
|
|
133
149
|
classConstructorStatements({ variables, }) {
|
|
134
150
|
if (this.abstract) {
|
|
135
151
|
return [];
|
|
136
152
|
}
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
153
|
+
if (this.classPropertyDeclaration.isNothing()) {
|
|
154
|
+
return [];
|
|
155
|
+
}
|
|
156
|
+
const classPropertyDeclaration = this.classPropertyDeclaration.unsafeCoerce();
|
|
157
|
+
const typeConversions = this.type.conversions;
|
|
158
|
+
if (typeConversions.length === 1) {
|
|
159
|
+
return [
|
|
160
|
+
`this.${classPropertyDeclaration.name} = ${variables.parameter};`,
|
|
161
|
+
];
|
|
162
|
+
}
|
|
163
|
+
const statements = [];
|
|
164
|
+
for (const conversion of this.type.conversions) {
|
|
165
|
+
if (conversion.sourceTypeName !== "undefined") {
|
|
166
|
+
statements.push(`if (${conversion.sourceTypeCheckExpression(variables.parameter)}) { this.${classPropertyDeclaration.name} = ${conversion.conversionExpression(variables.parameter)}; }`);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
if (!classPropertyDeclaration.hasQuestionToken) {
|
|
170
|
+
// We shouldn't need this else, since the parameter now has the never type, but have to add it to appease the TypeScript compiler
|
|
171
|
+
statements.push(`{ this.${classPropertyDeclaration.name} =( ${variables.parameter}) as never;\n }`);
|
|
172
|
+
}
|
|
173
|
+
return [statements.join(" else ")];
|
|
142
174
|
}
|
|
143
175
|
fromJsonStatements({ variables, }) {
|
|
144
176
|
return [
|
|
@@ -146,21 +178,63 @@ export class IdentifierProperty extends Property {
|
|
|
146
178
|
];
|
|
147
179
|
}
|
|
148
180
|
fromRdfStatements({ variables, }) {
|
|
181
|
+
if (this.type.in_.length > 0 && this.type.isNamedNodeKind) {
|
|
182
|
+
// Treat sh:in as a union of the IRIs
|
|
183
|
+
// rdfjs.NamedNode<"http://example.com/1" | "http://example.com/2">
|
|
184
|
+
return [
|
|
185
|
+
`let ${this.name}: ${this.type.name};`,
|
|
186
|
+
`switch (${variables.resource}.identifier.value) { ${this.type.in_.map((iri) => `case "${iri.value}": ${this.name} = ${this.rdfjsTermExpression(iri)}; break;`).join(" ")} default: return purify.Left(new rdfjsResource.Resource.MistypedValueError({ actualValue: ${variables.resource}.identifier, expectedValueType: ${JSON.stringify(this.type.name)}, focusResource: ${variables.resource}, predicate: ${this.rdfjsTermExpression(rdf.subject)} })); }`,
|
|
187
|
+
];
|
|
188
|
+
}
|
|
149
189
|
return [`const ${this.name} = ${variables.resource}.identifier`];
|
|
150
190
|
}
|
|
151
|
-
hashStatements() {
|
|
152
|
-
|
|
191
|
+
hashStatements({ variables, }) {
|
|
192
|
+
if (this.abstract) {
|
|
193
|
+
// Identifier will only be hashed by a concrete class.
|
|
194
|
+
return [];
|
|
195
|
+
}
|
|
196
|
+
switch (this.identifierMintingStrategy) {
|
|
197
|
+
case "blankNode":
|
|
198
|
+
case "none":
|
|
199
|
+
case "uuidv4":
|
|
200
|
+
// The identifier minting won't call hash, so we should hash the identifier.
|
|
201
|
+
return [`${variables.hasher}.update(${variables.value}.value);`];
|
|
202
|
+
case "sha256":
|
|
203
|
+
// The identifier minting will call hash, so we can't hash the identifier.
|
|
204
|
+
return [];
|
|
205
|
+
}
|
|
153
206
|
}
|
|
154
207
|
interfaceConstructorStatements({ variables, }) {
|
|
155
|
-
|
|
208
|
+
const typeConversions = this.type.conversions;
|
|
209
|
+
if (typeConversions.length === 1) {
|
|
210
|
+
return [`const ${this.name} = ${variables.parameter};`];
|
|
211
|
+
}
|
|
212
|
+
const statements = [`let ${this.name}: ${this.type.name};`];
|
|
213
|
+
const conversionBranches = [];
|
|
214
|
+
for (const conversion of this.type.conversions) {
|
|
215
|
+
conversionBranches.push(`if (${conversion.sourceTypeCheckExpression(variables.parameter)}) { ${this.name} = ${conversion.conversionExpression(variables.parameter)}; }`);
|
|
216
|
+
}
|
|
217
|
+
// We shouldn't need this else, since the parameter now has the never type, but have to add it to appease the TypeScript compiler
|
|
218
|
+
conversionBranches.push(`{ ${this.name} =( ${variables.parameter}) as never;\n }`);
|
|
219
|
+
statements.push(conversionBranches.join(" else "));
|
|
220
|
+
return statements;
|
|
156
221
|
}
|
|
157
222
|
jsonUiSchemaElement({ variables, }) {
|
|
158
223
|
return Maybe.of(`{ label: "Identifier", scope: \`\${${variables.scopePrefix}}/properties/${this.jsonPropertySignature.name}\`, type: "Control" }`);
|
|
159
224
|
}
|
|
160
225
|
jsonZodSchema({ variables, }) {
|
|
226
|
+
let schema;
|
|
227
|
+
if (this.type.in_.length > 0 && this.type.isNamedNodeKind) {
|
|
228
|
+
// Treat sh:in as a union of the IRIs
|
|
229
|
+
// rdfjs.NamedNode<"http://example.com/1" | "http://example.com/2">
|
|
230
|
+
schema = `${variables.zod}.enum(${JSON.stringify(this.type.in_.map((iri) => iri.value))})`;
|
|
231
|
+
}
|
|
232
|
+
else {
|
|
233
|
+
schema = `${variables.zod}.string().min(1)`;
|
|
234
|
+
}
|
|
161
235
|
return {
|
|
162
236
|
key: this.jsonPropertySignature.name,
|
|
163
|
-
schema
|
|
237
|
+
schema,
|
|
164
238
|
};
|
|
165
239
|
}
|
|
166
240
|
sparqlConstructTemplateTriples() {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { BlankNode, Literal, NamedNode, Variable } from "@rdfjs/types";
|
|
2
2
|
import type { Maybe } from "purify-ts";
|
|
3
3
|
import { type GetAccessorDeclarationStructure, type OptionalKind, type PropertyDeclarationStructure, type PropertySignatureStructure, Scope } from "ts-morph";
|
|
4
|
-
import type { PropertyVisibility } from "../../../enums/index.js";
|
|
4
|
+
import type { PropertyVisibility, TsFeature, TsObjectDeclarationType } from "../../../enums/index.js";
|
|
5
5
|
import type { Import } from "../Import.js";
|
|
6
6
|
import type { Type } from "../Type.js";
|
|
7
7
|
export declare abstract class Property<TypeT extends {
|
|
@@ -21,7 +21,7 @@ export declare abstract class Property<TypeT extends {
|
|
|
21
21
|
*/
|
|
22
22
|
abstract readonly constructorParametersPropertySignature: Maybe<OptionalKind<PropertySignatureStructure>>;
|
|
23
23
|
/**
|
|
24
|
-
* Function declaration that takes two values of the property and compares them, returning and
|
|
24
|
+
* Function declaration that takes two values of the property and compares them, returning and EqualsResult.
|
|
25
25
|
*/
|
|
26
26
|
abstract readonly equalsFunction: string;
|
|
27
27
|
/**
|
|
@@ -40,6 +40,15 @@ export declare abstract class Property<TypeT extends {
|
|
|
40
40
|
* TypeScript identifier-safe name of the property.
|
|
41
41
|
*/
|
|
42
42
|
readonly name: string;
|
|
43
|
+
/**
|
|
44
|
+
* Reusable function, type, and other declarations that are not particular to this property but that property-specific code
|
|
45
|
+
* relies on. For example, the equals function/method of ObjectType has a custom return type that's the same across all
|
|
46
|
+
* ObjectType's. Instead of re-declaring the return type anonymously on every equals function, declare a named type
|
|
47
|
+
* as a snippet and reference it.
|
|
48
|
+
*
|
|
49
|
+
* The generator deduplicates snippet declarations across all types before adding them to the source.
|
|
50
|
+
*/
|
|
51
|
+
abstract readonly snippetDeclarations: readonly string[];
|
|
43
52
|
/**
|
|
44
53
|
* Property type
|
|
45
54
|
. */
|
|
@@ -49,9 +58,14 @@ export declare abstract class Property<TypeT extends {
|
|
|
49
58
|
*/
|
|
50
59
|
readonly visibility: PropertyVisibility;
|
|
51
60
|
protected readonly dataFactoryVariable: string;
|
|
52
|
-
|
|
61
|
+
protected readonly objectType: {
|
|
62
|
+
readonly declarationType: TsObjectDeclarationType;
|
|
63
|
+
readonly features: Set<TsFeature>;
|
|
64
|
+
};
|
|
65
|
+
constructor({ dataFactoryVariable, name, objectType, type, visibility, }: {
|
|
53
66
|
dataFactoryVariable: string;
|
|
54
67
|
name: string;
|
|
68
|
+
objectType: Property<TypeT>["objectType"];
|
|
55
69
|
type: TypeT;
|
|
56
70
|
visibility: PropertyVisibility;
|
|
57
71
|
});
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { Scope, } from "ts-morph";
|
|
2
2
|
import { rdfjsTermExpression } from "./rdfjsTermExpression.js";
|
|
3
3
|
export class Property {
|
|
4
|
-
constructor({ dataFactoryVariable, name, type, visibility, }) {
|
|
4
|
+
constructor({ dataFactoryVariable, name, objectType, type, visibility, }) {
|
|
5
5
|
this.dataFactoryVariable = dataFactoryVariable;
|
|
6
6
|
this.name = name;
|
|
7
|
+
this.objectType = objectType;
|
|
7
8
|
this.type = type;
|
|
8
9
|
this.visibility = visibility;
|
|
9
10
|
}
|
|
@@ -26,6 +26,7 @@ export declare class ShaclProperty extends Property<Type> {
|
|
|
26
26
|
get equalsFunction(): string;
|
|
27
27
|
get interfacePropertySignature(): OptionalKind<PropertySignatureStructure>;
|
|
28
28
|
get jsonPropertySignature(): OptionalKind<PropertySignatureStructure>;
|
|
29
|
+
get snippetDeclarations(): readonly string[];
|
|
29
30
|
private get declarationComment();
|
|
30
31
|
private get pathExpression();
|
|
31
32
|
classConstructorStatements({ variables, }: Parameters<Property<Type>["classConstructorStatements"]>[0]): readonly string[];
|
|
@@ -50,7 +50,7 @@ export class ShaclProperty extends Property {
|
|
|
50
50
|
});
|
|
51
51
|
}
|
|
52
52
|
get declarationImports() {
|
|
53
|
-
return this.type.useImports;
|
|
53
|
+
return this.type.useImports(this.objectType.features);
|
|
54
54
|
}
|
|
55
55
|
get equalsFunction() {
|
|
56
56
|
return this.type.equalsFunction;
|
|
@@ -70,6 +70,9 @@ export class ShaclProperty extends Property {
|
|
|
70
70
|
type: this.type.jsonName,
|
|
71
71
|
};
|
|
72
72
|
}
|
|
73
|
+
get snippetDeclarations() {
|
|
74
|
+
return this.type.snippetDeclarations(this.objectType.features);
|
|
75
|
+
}
|
|
73
76
|
get declarationComment() {
|
|
74
77
|
return this.comment
|
|
75
78
|
.alt(this.description)
|
|
@@ -1,17 +1,14 @@
|
|
|
1
1
|
import { Maybe } from "purify-ts";
|
|
2
2
|
import type { GetAccessorDeclarationStructure, OptionalKind, PropertyDeclarationStructure, PropertySignatureStructure } from "ts-morph";
|
|
3
|
-
import type { TsObjectDeclarationType } from "../../../enums/index.js";
|
|
4
3
|
import { Property } from "./Property.js";
|
|
5
4
|
export declare class TypeDiscriminatorProperty extends Property<TypeDiscriminatorProperty.Type> {
|
|
6
|
-
readonly equalsFunction = "
|
|
5
|
+
readonly equalsFunction = "strictEquals";
|
|
7
6
|
readonly mutable = false;
|
|
8
7
|
readonly value: string;
|
|
9
8
|
private readonly abstract;
|
|
10
|
-
private readonly objectTypeDeclarationType;
|
|
11
9
|
private readonly override;
|
|
12
|
-
constructor({ abstract,
|
|
10
|
+
constructor({ abstract, override, type, value, ...superParameters }: {
|
|
13
11
|
abstract: boolean;
|
|
14
|
-
objectTypeDeclarationType: TsObjectDeclarationType;
|
|
15
12
|
override: boolean;
|
|
16
13
|
type: TypeDiscriminatorProperty.Type;
|
|
17
14
|
value: string;
|
|
@@ -21,6 +18,7 @@ export declare class TypeDiscriminatorProperty extends Property<TypeDiscriminato
|
|
|
21
18
|
get constructorParametersPropertySignature(): Maybe<OptionalKind<PropertySignatureStructure>>;
|
|
22
19
|
get interfacePropertySignature(): OptionalKind<PropertySignatureStructure>;
|
|
23
20
|
get jsonPropertySignature(): OptionalKind<PropertySignatureStructure>;
|
|
21
|
+
get snippetDeclarations(): readonly string[];
|
|
24
22
|
classConstructorStatements(): readonly string[];
|
|
25
23
|
fromJsonStatements(): readonly string[];
|
|
26
24
|
fromRdfStatements(): readonly string[];
|