@shaclmate/compiler 4.0.25 → 4.0.26
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/generators/ts/TsGenerator.js +15 -7
- package/dist/generators/ts/_NamedObjectType/NamedObjectType_objectSetMethodNames.js +8 -3
- package/dist/generators/ts/_snippets/snippets_compactRecord.js +1 -1
- package/dist/generators/ts/rdfjsDatasetObjectSetClassDeclaration.js +4 -4
- package/dist/generators/ts/sparqlObjectSetClassDeclaration.js +39 -36
- package/package.json +2 -2
|
@@ -3,6 +3,7 @@ import { graphqlSchemaVariableStatement } from "./graphqlSchemaVariableStatement
|
|
|
3
3
|
import { objectSetDeclarations } from "./objectSetDeclarations.js";
|
|
4
4
|
import { snippets } from "./snippets.js";
|
|
5
5
|
import { synthesizeUberObjectUnionType } from "./synthesizeUberObjectUnionType.js";
|
|
6
|
+
import { syntheticNamePrefix } from "./syntheticNamePrefix.js";
|
|
6
7
|
import { TypeFactory } from "./TypeFactory.js";
|
|
7
8
|
import { code, joinCode } from "./ts-poet-wrapper.js";
|
|
8
9
|
export class TsGenerator {
|
|
@@ -32,13 +33,20 @@ export class TsGenerator {
|
|
|
32
33
|
}
|
|
33
34
|
const namedObjectTypesNameSorted = namedObjectTypesToposorted.toSorted((left, right) => left.name.localeCompare(right.name));
|
|
34
35
|
const namedObjectUnionTypesNameSorted = namedObjectUnionTypesToposorted.toSorted((left, right) => left.name.localeCompare(right.name));
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
36
|
+
switch (namedObjectTypesNameSorted.length) {
|
|
37
|
+
case 0:
|
|
38
|
+
break;
|
|
39
|
+
case 1:
|
|
40
|
+
declarations.push(code `type ${syntheticNamePrefix}Object = ${namedObjectTypesNameSorted[0].name};`);
|
|
41
|
+
break;
|
|
42
|
+
default: {
|
|
43
|
+
const uberObjectUnionType = synthesizeUberObjectUnionType({
|
|
44
|
+
logger: this.logger,
|
|
45
|
+
namedObjectTypes: namedObjectTypesToposorted.toReversed(), // Reverse topological order so children ane before parents
|
|
46
|
+
});
|
|
47
|
+
declarations = declarations.concat(uberObjectUnionType.declaration.toList());
|
|
48
|
+
namedObjectUnionTypesNameSorted.push(uberObjectUnionType);
|
|
49
|
+
}
|
|
42
50
|
}
|
|
43
51
|
declarations.push(...objectSetDeclarations({
|
|
44
52
|
namedObjectTypes: namedObjectTypesNameSorted,
|
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
import { camelCase, trainCase } from "change-case";
|
|
2
2
|
import plur from "plur";
|
|
3
|
+
import { syntheticNamePrefix } from "../syntheticNamePrefix.js";
|
|
3
4
|
export function NamedObjectType_objectSetMethodNames() {
|
|
4
|
-
const prefixSingular = camelCase(this.name
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
const prefixSingular = camelCase(this.name, {
|
|
6
|
+
prefixCharacters: syntheticNamePrefix,
|
|
7
|
+
});
|
|
8
|
+
const thisNameParts = trainCase(this.name, {
|
|
9
|
+
prefixCharacters: syntheticNamePrefix,
|
|
10
|
+
}).split("-");
|
|
11
|
+
let prefixPlural = camelCase(`${thisNameParts.slice(0, thisNameParts.length - 1).join("")}${plur(thisNameParts[thisNameParts.length - 1])}`, { prefixCharacters: syntheticNamePrefix });
|
|
7
12
|
if (prefixPlural === prefixSingular) {
|
|
8
13
|
// Happens with singular-s nouns like "series"
|
|
9
14
|
prefixPlural = `${prefixPlural}s`;
|
|
@@ -6,7 +6,7 @@ export const snippets_compactRecord = conditionalOutput(`${syntheticNamePrefix}c
|
|
|
6
6
|
*/
|
|
7
7
|
function ${syntheticNamePrefix}compactRecord<KeyT extends string, ValueT extends {}>(record: Record<KeyT, ValueT | undefined>): Record<KeyT, ValueT> {
|
|
8
8
|
return \
|
|
9
|
-
Object.entries(record).reduce((definedProperties, [propertyName, propertyValue]) => {
|
|
9
|
+
globalThis.Object.entries(record).reduce((definedProperties, [propertyName, propertyValue]) => {
|
|
10
10
|
if (propertyValue !== undefined) {
|
|
11
11
|
definedProperties[propertyName as KeyT] = propertyValue as ValueT;
|
|
12
12
|
}
|
|
@@ -98,13 +98,13 @@ async ${methodSignatures.objects.name}(${methodSignatures.objects.parameters}):
|
|
|
98
98
|
case "NamedObjectType": {
|
|
99
99
|
return delegatingMethods.concat(code `\
|
|
100
100
|
${methodSignatures.objects.name}Sync(${methodSignatures.objects.parameters}): ${imports.Either}<Error, readonly ${namedObjectType.name}[]> {
|
|
101
|
-
return this
|
|
101
|
+
return this.#objectsSync<${namedObjectType.name}, ${namedObjectType.filterType}, ${namedObjectType.identifierTypeAlias}>(${runtimeObjectType(namedObjectType.filterFunction, namedObjectType)}, query);
|
|
102
102
|
}`);
|
|
103
103
|
}
|
|
104
104
|
case "NamedObjectUnionType":
|
|
105
105
|
return delegatingMethods.concat(code `\
|
|
106
106
|
${methodSignatures.objects.name}Sync(${methodSignatures.objects.parameters}): ${imports.Either}<Error, readonly ${namedObjectType.name}[]> {
|
|
107
|
-
return this
|
|
107
|
+
return this.#objectUnionsSync<${namedObjectType.name}, ${namedObjectType.filterType}, ${namedObjectType.identifierTypeAlias}>([
|
|
108
108
|
${joinCode(namedObjectType.members.map((member) => runtimeObjectType(namedObjectType.filterFunction, member.type)), { on: ", " })}
|
|
109
109
|
], query);
|
|
110
110
|
}`);
|
|
@@ -116,7 +116,7 @@ ${methodSignatures.objects.name}Sync(${methodSignatures.objects.parameters}): ${
|
|
|
116
116
|
...(namedObjectTypes.length > 0
|
|
117
117
|
? [
|
|
118
118
|
code `\
|
|
119
|
-
|
|
119
|
+
#objectsSync<${typeParameters.ObjectT}, ${typeParameters.ObjectFilterT}, ${typeParameters.ObjectIdentifierT}>(namedObjectType: ${namedObjectTypeType}, ${parameters.query}): ${imports.Either}<Error, readonly ObjectT[]> {
|
|
120
120
|
const graph = query?.graph ?? this.${syntheticNamePrefix}graph;
|
|
121
121
|
|
|
122
122
|
const limit = query?.limit ?? Number.MAX_SAFE_INTEGER;
|
|
@@ -208,7 +208,7 @@ protected ${syntheticNamePrefix}objectsSync<${typeParameters.ObjectT}, ${typePar
|
|
|
208
208
|
...(namedObjectUnionTypes.length > 0
|
|
209
209
|
? [
|
|
210
210
|
code `\
|
|
211
|
-
|
|
211
|
+
#objectUnionsSync<${typeParameters.ObjectT}, ${typeParameters.ObjectFilterT}, ${typeParameters.ObjectIdentifierT}>(namedObjectTypes: readonly ${namedObjectTypeType}[], ${parameters.query}): ${imports.Either}<Error, readonly ObjectT[]> {
|
|
212
212
|
const graph = query?.graph ?? this.${syntheticNamePrefix}graph;
|
|
213
213
|
|
|
214
214
|
const limit = query?.limit ?? Number.MAX_SAFE_INTEGER;
|
|
@@ -14,6 +14,7 @@ export function sparqlObjectSetClassDeclaration({ namedObjectTypes, namedObjectU
|
|
|
14
14
|
query: code `query?: ${syntheticNamePrefix}SparqlObjectSet.Query<ObjectFilterT, ObjectIdentifierT>`,
|
|
15
15
|
selectObjectTypeType: code `namedObjectType: { ${syntheticNamePrefix}focusSparqlWherePatterns: ${snippets.FocusSparqlWherePatternsFunction}<ObjectFilterT> }`,
|
|
16
16
|
};
|
|
17
|
+
const sparqlClientType = code `{ queryBindings: (query: string) => Promise<readonly Record<string, ${imports.BlankNode} | ${imports.Literal} | ${imports.NamedNode}>[]>; queryQuads: (query: string) => Promise<readonly ${imports.Quad}[]>; }`;
|
|
17
18
|
const typeParameters = {
|
|
18
19
|
ObjectT: code `ObjectT extends { readonly $identifier: () => ObjectIdentifierT }`,
|
|
19
20
|
ObjectFilterT: code `ObjectFilterT`,
|
|
@@ -21,13 +22,15 @@ export function sparqlObjectSetClassDeclaration({ namedObjectTypes, namedObjectU
|
|
|
21
22
|
};
|
|
22
23
|
return code `\
|
|
23
24
|
export class ${syntheticNamePrefix}SparqlObjectSet implements ${syntheticNamePrefix}ObjectSet {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
25
|
+
readonly #countVariable = ${imports.dataFactory}.variable!("count");;
|
|
26
|
+
readonly #graph?: Exclude<${imports.Quad_Graph}, ${imports.Variable}>;
|
|
27
|
+
readonly #objectVariable = ${imports.dataFactory}.variable!("object");
|
|
28
|
+
readonly #sparqlClient: ${sparqlClientType};
|
|
29
|
+
readonly #sparqlGenerator = new ${imports.sparqljs}.Generator();
|
|
30
|
+
|
|
31
|
+
constructor(sparqlClient: ${sparqlClientType}, options?: { graph?: Exclude<${imports.Quad_Graph}, ${imports.Variable}> }) {
|
|
32
|
+
this.#graph = options?.graph;
|
|
33
|
+
this.#sparqlClient = sparqlClient;
|
|
31
34
|
}
|
|
32
35
|
|
|
33
36
|
${joinCode([...namedObjectTypes, ...namedObjectUnionTypes].flatMap((namedObjectType) => {
|
|
@@ -48,20 +51,20 @@ async ${methodSignatures.object.name}(${methodSignatures.object.parameters}): ${
|
|
|
48
51
|
}`,
|
|
49
52
|
code `\
|
|
50
53
|
async ${methodSignatures.objectCount.name}(${methodSignatures.objectCount.parameters}): ${methodSignatures.objectCount.returnType} {
|
|
51
|
-
return this
|
|
54
|
+
return this.#objectCount<${namedObjectType.filterType}, ${namedObjectType.identifierTypeAlias}>(${runtimeObjectType}, query);
|
|
52
55
|
}`,
|
|
53
56
|
code `\
|
|
54
57
|
async ${methodSignatures.objectIdentifiers.name}(${methodSignatures.objectIdentifiers.parameters}): ${methodSignatures.objectIdentifiers.returnType} {
|
|
55
|
-
return this
|
|
58
|
+
return this.#objectIdentifiers<${namedObjectType.filterType}, ${namedObjectType.identifierTypeAlias}>(${runtimeObjectType}, query);
|
|
56
59
|
}`,
|
|
57
60
|
code `\
|
|
58
61
|
async ${methodSignatures.objects.name}(${methodSignatures.objects.parameters}): ${methodSignatures.objects.returnType} {
|
|
59
|
-
return this
|
|
62
|
+
return this.#objects<${namedObjectType.name}, ${namedObjectType.filterType}, ${namedObjectType.identifierTypeAlias}>(${runtimeObjectType}, query);
|
|
60
63
|
}`,
|
|
61
64
|
];
|
|
62
65
|
}), { on: "\n\n" })}
|
|
63
66
|
|
|
64
|
-
|
|
67
|
+
#mapBindingsToCount(bindings: readonly Record<string, ${imports.BlankNode} | ${imports.Literal} | ${imports.NamedNode}>[], variable: string): ${imports.Either}<Error, number> {
|
|
65
68
|
if (bindings.length === 0) {
|
|
66
69
|
return ${imports.Left}(new Error("empty result rows"));
|
|
67
70
|
}
|
|
@@ -82,7 +85,7 @@ async ${methodSignatures.objects.name}(${methodSignatures.objects.parameters}):
|
|
|
82
85
|
return ${imports.Right}(parsedCount);
|
|
83
86
|
}
|
|
84
87
|
|
|
85
|
-
|
|
88
|
+
#mapBindingsToIdentifiers(bindings: readonly Record<string, ${imports.BlankNode} | ${imports.Literal} | ${imports.NamedNode}>[], variable: string): readonly ${imports.NamedNode}[] {
|
|
86
89
|
const identifiers: ${imports.NamedNode}[] = [];
|
|
87
90
|
for (const bindings_ of bindings) {
|
|
88
91
|
const identifier = bindings_[variable];
|
|
@@ -96,7 +99,7 @@ async ${methodSignatures.objects.name}(${methodSignatures.objects.parameters}):
|
|
|
96
99
|
return identifiers;
|
|
97
100
|
}
|
|
98
101
|
|
|
99
|
-
|
|
102
|
+
async #objectIdentifiers<${typeParameters.ObjectFilterT}, ${typeParameters.ObjectIdentifierT}>(${parameters.selectObjectTypeType}, ${parameters.query}): Promise<${imports.Either}<Error, readonly ObjectIdentifierT[]>> {
|
|
100
103
|
if (query?.identifiers) {
|
|
101
104
|
return ${imports.Right}(query.identifiers);
|
|
102
105
|
}
|
|
@@ -111,41 +114,41 @@ async ${methodSignatures.objects.name}(${methodSignatures.objects.parameters}):
|
|
|
111
114
|
offset = 0;
|
|
112
115
|
}
|
|
113
116
|
|
|
114
|
-
const wherePatterns = this
|
|
117
|
+
const wherePatterns = this.#wherePatterns(namedObjectType, query);
|
|
115
118
|
if (wherePatterns.length === 0) {
|
|
116
119
|
return ${imports.Left}(new Error("no SPARQL WHERE patterns for identifiers"));
|
|
117
120
|
}
|
|
118
121
|
|
|
119
122
|
const selectQueryString = \
|
|
120
|
-
this
|
|
123
|
+
this.#sparqlGenerator.stringify({
|
|
121
124
|
distinct: true,
|
|
122
125
|
limit: limit < Number.MAX_SAFE_INTEGER ? limit : undefined,
|
|
123
126
|
offset,
|
|
124
|
-
order: query?.order ? query.order(this
|
|
127
|
+
order: query?.order ? query.order(this.#objectVariable).concat() : [{ expression: this.#objectVariable }],
|
|
125
128
|
prefixes: {},
|
|
126
129
|
queryType: "SELECT",
|
|
127
130
|
type: "query",
|
|
128
|
-
variables: [this
|
|
131
|
+
variables: [this.#objectVariable],
|
|
129
132
|
where: wherePatterns.concat()
|
|
130
133
|
});
|
|
131
134
|
|
|
132
135
|
return ${imports.EitherAsync}(async () =>
|
|
133
|
-
this
|
|
134
|
-
await this
|
|
135
|
-
this
|
|
136
|
+
this.#mapBindingsToIdentifiers(
|
|
137
|
+
await this.#sparqlClient.queryBindings(selectQueryString),
|
|
138
|
+
this.#objectVariable.value,
|
|
136
139
|
) as readonly ObjectIdentifierT[],
|
|
137
140
|
);
|
|
138
141
|
}
|
|
139
142
|
|
|
140
|
-
|
|
143
|
+
async #objects<${typeParameters.ObjectT}, ${typeParameters.ObjectFilterT}, ${typeParameters.ObjectIdentifierT}>(${parameters.constructObjectType}, ${parameters.query}): Promise<${imports.Either}<Error, readonly ObjectT[]>> {
|
|
141
144
|
return ${imports.EitherAsync}(async ({ liftEither }) => {
|
|
142
|
-
const identifiers = await liftEither(await this
|
|
145
|
+
const identifiers = await liftEither(await this.#objectIdentifiers<ObjectFilterT, ObjectIdentifierT>(namedObjectType, query));
|
|
143
146
|
if (identifiers.length === 0) {
|
|
144
147
|
return [];
|
|
145
148
|
}
|
|
146
149
|
|
|
147
150
|
const constructQueryString = namedObjectType.${syntheticNamePrefix}sparqlConstructQueryString({
|
|
148
|
-
subject: this
|
|
151
|
+
subject: this.#objectVariable,
|
|
149
152
|
where: [{
|
|
150
153
|
type: "values" as const,
|
|
151
154
|
values: identifiers.map((identifier) => {
|
|
@@ -156,7 +159,7 @@ async ${methodSignatures.objects.name}(${methodSignatures.objects.parameters}):
|
|
|
156
159
|
}]
|
|
157
160
|
});
|
|
158
161
|
|
|
159
|
-
const quads = await this
|
|
162
|
+
const quads = await this.#sparqlClient.queryQuads(constructQueryString);
|
|
160
163
|
|
|
161
164
|
const dataset = ${imports.datasetFactory}.dataset(quads.concat());
|
|
162
165
|
const objects: ObjectT[] = [];
|
|
@@ -167,14 +170,14 @@ async ${methodSignatures.objects.name}(${methodSignatures.objects.parameters}):
|
|
|
167
170
|
});
|
|
168
171
|
}
|
|
169
172
|
|
|
170
|
-
|
|
171
|
-
const wherePatterns = this
|
|
173
|
+
async #objectCount<${typeParameters.ObjectFilterT}, ${typeParameters.ObjectIdentifierT}>(${parameters.selectObjectTypeType}, ${parameters.query}): Promise<${imports.Either}<Error, number>> {
|
|
174
|
+
const wherePatterns = this.#wherePatterns(namedObjectType, query);
|
|
172
175
|
if (wherePatterns.length === 0) {
|
|
173
176
|
return ${imports.Left}(new Error("no SPARQL WHERE patterns for count"));
|
|
174
177
|
}
|
|
175
178
|
|
|
176
179
|
const selectQueryString = \
|
|
177
|
-
this
|
|
180
|
+
this.#sparqlGenerator.stringify({
|
|
178
181
|
prefixes: {},
|
|
179
182
|
queryType: "SELECT",
|
|
180
183
|
type: "query",
|
|
@@ -183,10 +186,10 @@ async ${methodSignatures.objects.name}(${methodSignatures.objects.parameters}):
|
|
|
183
186
|
expression: {
|
|
184
187
|
aggregation: "COUNT",
|
|
185
188
|
distinct: true,
|
|
186
|
-
expression: this
|
|
189
|
+
expression: this.#objectVariable,
|
|
187
190
|
type: "aggregate",
|
|
188
191
|
},
|
|
189
|
-
variable: this
|
|
192
|
+
variable: this.#countVariable,
|
|
190
193
|
},
|
|
191
194
|
],
|
|
192
195
|
where: wherePatterns.concat()
|
|
@@ -194,27 +197,27 @@ async ${methodSignatures.objects.name}(${methodSignatures.objects.parameters}):
|
|
|
194
197
|
|
|
195
198
|
return ${imports.EitherAsync}(async ({ liftEither }) =>
|
|
196
199
|
liftEither(
|
|
197
|
-
this
|
|
198
|
-
await this
|
|
199
|
-
this
|
|
200
|
+
this.#mapBindingsToCount(
|
|
201
|
+
await this.#sparqlClient.queryBindings(selectQueryString),
|
|
202
|
+
this.#countVariable.value,
|
|
200
203
|
),
|
|
201
204
|
),
|
|
202
205
|
);
|
|
203
206
|
}
|
|
204
207
|
|
|
205
|
-
|
|
208
|
+
#wherePatterns<${typeParameters.ObjectFilterT}, ${typeParameters.ObjectIdentifierT}>(${parameters.selectObjectTypeType}, ${parameters.query}): readonly ${imports.sparqljs}.Pattern[] {
|
|
206
209
|
// Patterns should be most to least specific.
|
|
207
210
|
let patterns: ${imports.sparqljs}.Pattern[] = [];
|
|
208
211
|
|
|
209
212
|
if (query?.where) {
|
|
210
|
-
patterns = patterns.concat(query.where(this
|
|
213
|
+
patterns = patterns.concat(query.where(this.#objectVariable));
|
|
211
214
|
}
|
|
212
215
|
|
|
213
|
-
patterns = patterns.concat(namedObjectType.${syntheticNamePrefix}focusSparqlWherePatterns({ filter: query?.filter, focusIdentifier: this
|
|
216
|
+
patterns = patterns.concat(namedObjectType.${syntheticNamePrefix}focusSparqlWherePatterns({ filter: query?.filter, focusIdentifier: this.#objectVariable, ignoreRdfType: false, preferredLanguages: query?.preferredLanguages, variablePrefix: this.#objectVariable.value }));
|
|
214
217
|
|
|
215
218
|
patterns = ${snippets.normalizeSparqlWherePatterns}(patterns).concat();
|
|
216
219
|
|
|
217
|
-
const graph = query?.graph ?? this
|
|
220
|
+
const graph = query?.graph ?? this.#graph;
|
|
218
221
|
if (graph) {
|
|
219
222
|
switch (graph.termType) {
|
|
220
223
|
case "DefaultGraph":
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"dependencies": {
|
|
3
|
-
"@shaclmate/shacl-ast": "4.0.
|
|
3
|
+
"@shaclmate/shacl-ast": "4.0.26",
|
|
4
4
|
"@rdfjs/dataset": "~2.0.2",
|
|
5
5
|
"@rdfjs/prefix-map": "~0.1.2",
|
|
6
6
|
"@rdfjs/term-map": "~2.0.2",
|
|
@@ -68,5 +68,5 @@
|
|
|
68
68
|
},
|
|
69
69
|
"type": "module",
|
|
70
70
|
"types": "./dist/index.d.ts",
|
|
71
|
-
"version": "4.0.
|
|
71
|
+
"version": "4.0.26"
|
|
72
72
|
}
|