@shaclmate/compiler 4.0.36 → 4.0.37

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 (42) hide show
  1. package/dist/ShapesGraphToAstTransformer.js +10 -0
  2. package/dist/ast/Ast.d.ts +1 -0
  3. package/dist/generators/ts/AbstractNamedUnionType.js +6 -2
  4. package/dist/generators/ts/AbstractObjectSetType.d.ts +35 -0
  5. package/dist/generators/ts/AbstractObjectSetType.js +44 -0
  6. package/dist/generators/ts/GraphqlSchema.d.ts +22 -0
  7. package/dist/generators/ts/GraphqlSchema.js +87 -0
  8. package/dist/generators/ts/NamedObjectType.js +6 -2
  9. package/dist/generators/ts/ObjectSetType.d.ts +6 -0
  10. package/dist/generators/ts/ObjectSetType.js +36 -0
  11. package/dist/generators/ts/RdfjsDatasetObjectSetType.d.ts +6 -0
  12. package/dist/generators/ts/{rdfjsDatasetObjectSetClassDeclaration.js → RdfjsDatasetObjectSetType.js} +73 -63
  13. package/dist/generators/ts/Snippets.d.ts +1 -0
  14. package/dist/generators/ts/Snippets.js +7 -0
  15. package/dist/generators/ts/SparqlObjectSetType.d.ts +6 -0
  16. package/dist/generators/ts/{sparqlObjectSetClassDeclaration.js → SparqlObjectSetType.js} +40 -29
  17. package/dist/generators/ts/TsGenerator.d.ts +7 -8
  18. package/dist/generators/ts/TsGenerator.js +108 -77
  19. package/dist/generators/ts/ZodGenerator.d.ts +1 -2
  20. package/dist/generators/ts/ZodGenerator.js +12 -12
  21. package/dist/generators/ts/_NamedObjectType/NamedObjectType_createFunctionDeclaration.js +17 -11
  22. package/dist/generators/ts/_NamedObjectType/NamedObjectType_toJsonFunctionDeclaration.js +2 -1
  23. package/dist/generators/ts/_NamedObjectType/NamedObjectType_toStringFunctionDeclarations.js +2 -4
  24. package/dist/generators/ts/_snippets/snippets_FromRdfResourceFunction.js +2 -2
  25. package/dist/generators/ts/_snippets/snippets_FromRdfResourceValuesFunction.js +2 -2
  26. package/dist/generators/ts/_snippets/snippets__FromRdfResourceFunction.js +2 -2
  27. package/dist/generators/ts/_snippets/snippets_monkeyPatchObject.d.ts +3 -0
  28. package/dist/generators/ts/_snippets/snippets_monkeyPatchObject.js +16 -0
  29. package/dist/generators/ts/_snippets/snippets_wrap_FromRdfResourceFunction.js +3 -4
  30. package/dist/input/generated.d.ts +1 -286
  31. package/dist/input/generated.js +26 -1015
  32. package/package.json +2 -2
  33. package/dist/generators/ts/graphqlSchemaVariableStatement.d.ts +0 -10
  34. package/dist/generators/ts/graphqlSchemaVariableStatement.js +0 -84
  35. package/dist/generators/ts/objectSetDeclarations.d.ts +0 -9
  36. package/dist/generators/ts/objectSetDeclarations.js +0 -27
  37. package/dist/generators/ts/objectSetInterfaceDeclaration.d.ts +0 -9
  38. package/dist/generators/ts/objectSetInterfaceDeclaration.js +0 -26
  39. package/dist/generators/ts/objectSetMethodSignatures.d.ts +0 -18
  40. package/dist/generators/ts/objectSetMethodSignatures.js +0 -31
  41. package/dist/generators/ts/rdfjsDatasetObjectSetClassDeclaration.d.ts +0 -9
  42. package/dist/generators/ts/sparqlObjectSetClassDeclaration.d.ts +0 -9
@@ -1,23 +1,31 @@
1
- import { objectSetMethodSignatures } from "./objectSetMethodSignatures.js";
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ import { Memoize } from "typescript-memoize";
8
+ import { AbstractObjectSetType } from "./AbstractObjectSetType.js";
2
9
  import { code, joinCode } from "./ts-poet-wrapper.js";
3
- export function sparqlObjectSetClassDeclaration({ namedObjectTypes, namedObjectUnionTypes, }) {
4
- const syntheticNamePrefix = this.configuration.syntheticNamePrefix;
5
- const parameters = {
6
- constructObjectType: code `namedObjectType: {\
10
+ export class SparqlObjectSetType extends AbstractObjectSetType {
11
+ get declaration() {
12
+ const syntheticNamePrefix = this.configuration.syntheticNamePrefix;
13
+ const parameters = {
14
+ constructObjectType: code `namedObjectType: {\
7
15
  focusSparqlWherePatterns: ${this.reusables.snippets.FocusSparqlWherePatternsFunction}<ObjectFilterT>;
8
16
  fromRdfResource: ${this.reusables.snippets.FromRdfResourceFunction}<ObjectT>;
9
17
  sparqlConstructQueryString: (parameters: { filter?: ObjectFilterT; subject: ${this.reusables.imports.NamedNode} | ${this.reusables.imports.Variable}; } & Omit<${this.reusables.imports.sparqljs}.ConstructQuery, "prefixes" | "queryType" | "type"> & ${this.reusables.imports.sparqljs}.GeneratorOptions) => string;
10
18
  }`,
11
- query: code `query?: ${syntheticNamePrefix}SparqlObjectSet.Query<ObjectFilterT, ObjectIdentifierT>`,
12
- selectObjectTypeType: code `namedObjectType: { focusSparqlWherePatterns: ${this.reusables.snippets.FocusSparqlWherePatternsFunction}<ObjectFilterT> }`,
13
- };
14
- const sparqlClientType = code `{ queryBindings: (query: string) => Promise<readonly Record<string, ${this.reusables.imports.BlankNode} | ${this.reusables.imports.Literal} | ${this.reusables.imports.NamedNode}>[]>; queryQuads: (query: string) => Promise<readonly ${this.reusables.imports.Quad}[]>; }`;
15
- const typeParameters = {
16
- ObjectT: code `ObjectT extends { readonly $identifier: () => ObjectIdentifierT }`,
17
- ObjectFilterT: code `ObjectFilterT`,
18
- ObjectIdentifierT: code `ObjectIdentifierT extends ${this.reusables.imports.BlankNode} | ${this.reusables.imports.NamedNode}`,
19
- };
20
- return code `\
19
+ query: code `query?: ${syntheticNamePrefix}SparqlObjectSet.Query<ObjectFilterT, ObjectIdentifierT>`,
20
+ selectObjectTypeType: code `namedObjectType: { focusSparqlWherePatterns: ${this.reusables.snippets.FocusSparqlWherePatternsFunction}<ObjectFilterT> }`,
21
+ };
22
+ const sparqlClientType = code `{ queryBindings: (query: string) => Promise<readonly Record<string, ${this.reusables.imports.BlankNode} | ${this.reusables.imports.Literal} | ${this.reusables.imports.NamedNode}>[]>; queryQuads: (query: string) => Promise<readonly ${this.reusables.imports.Quad}[]>; }`;
23
+ const typeParameters = {
24
+ ObjectT: code `ObjectT extends { readonly $identifier: () => ObjectIdentifierT }`,
25
+ ObjectFilterT: code `ObjectFilterT`,
26
+ ObjectIdentifierT: code `ObjectIdentifierT extends ${this.reusables.imports.BlankNode} | ${this.reusables.imports.NamedNode}`,
27
+ };
28
+ return code `\
21
29
  export class ${syntheticNamePrefix}SparqlObjectSet implements ${syntheticNamePrefix}ObjectSet {
22
30
  readonly #countVariable = ${this.reusables.imports.dataFactory}.variable!("count");;
23
31
  readonly #graph?: Exclude<${this.reusables.imports.Quad_Graph}, ${this.reusables.imports.Variable}>;
@@ -30,31 +38,30 @@ export class ${syntheticNamePrefix}SparqlObjectSet implements ${syntheticNamePre
30
38
  this.#sparqlClient = sparqlClient;
31
39
  }
32
40
 
33
- ${joinCode([...namedObjectTypes, ...namedObjectUnionTypes].flatMap((namedObjectType) => {
34
- const methodSignatures = objectSetMethodSignatures.call(this, {
35
- namedObjectType,
36
- queryT: `${syntheticNamePrefix}SparqlObjectSet.Query`,
37
- });
38
- const runtimeObjectType = namedObjectType.name;
39
- return [
40
- code `\
41
+ ${joinCode([...this.namedObjectTypes, ...this.namedObjectUnionTypes].flatMap((namedObjectType) => {
42
+ const methodSignatures = this.methodSignatures(namedObjectType, {
43
+ queryT: `${syntheticNamePrefix}SparqlObjectSet.Query`,
44
+ });
45
+ const runtimeObjectType = namedObjectType.name;
46
+ return [
47
+ code `\
41
48
  async ${methodSignatures.object.name}(${methodSignatures.object.parameters}): ${methodSignatures.object.returnType} {
42
49
  return (await this.${methodSignatures.objects.name}({ identifiers: [identifier], preferredLanguages: options?.preferredLanguages })).map(objects => objects[0]);
43
50
  }`,
44
- code `\
51
+ code `\
45
52
  async ${methodSignatures.objectCount.name}(${methodSignatures.objectCount.parameters}): ${methodSignatures.objectCount.returnType} {
46
53
  return this.#objectCount<${namedObjectType.filterType}, ${namedObjectType.identifierTypeAlias}>(${runtimeObjectType}, query);
47
54
  }`,
48
- code `\
55
+ code `\
49
56
  async ${methodSignatures.objectIdentifiers.name}(${methodSignatures.objectIdentifiers.parameters}): ${methodSignatures.objectIdentifiers.returnType} {
50
57
  return this.#objectIdentifiers<${namedObjectType.filterType}, ${namedObjectType.identifierTypeAlias}>(${runtimeObjectType}, query);
51
58
  }`,
52
- code `\
59
+ code `\
53
60
  async ${methodSignatures.objects.name}(${methodSignatures.objects.parameters}): ${methodSignatures.objects.returnType} {
54
61
  return this.#objects<${namedObjectType.name}, ${namedObjectType.filterType}, ${namedObjectType.identifierTypeAlias}>(${runtimeObjectType}, query);
55
62
  }`,
56
- ];
57
- }), { on: "\n\n" })}
63
+ ];
64
+ }), { on: "\n\n" })}
58
65
 
59
66
  #mapBindingsToCount(bindings: readonly Record<string, ${this.reusables.imports.BlankNode} | ${this.reusables.imports.Literal} | ${this.reusables.imports.NamedNode}>[], variable: string): ${this.reusables.imports.Either}<Error, number> {
60
67
  if (bindings.length === 0) {
@@ -226,5 +233,9 @@ async ${methodSignatures.objects.name}(${methodSignatures.objects.parameters}):
226
233
  export namespace ${syntheticNamePrefix}SparqlObjectSet {
227
234
  export type Query<${typeParameters.ObjectFilterT}, ${typeParameters.ObjectIdentifierT}> = ${syntheticNamePrefix}ObjectSet.Query<ObjectFilterT, ObjectIdentifierT> & { readonly order?: (objectVariable: ${this.reusables.imports.Variable}) => readonly ${this.reusables.imports.sparqljs}.Ordering[]; readonly where?: (objectVariable: ${this.reusables.imports.Variable}) => readonly ${this.reusables.imports.sparqljs}.Pattern[] };
228
235
  }`;
236
+ }
229
237
  }
230
- //# sourceMappingURL=sparqlObjectSetClassDeclaration.js.map
238
+ __decorate([
239
+ Memoize()
240
+ ], SparqlObjectSetType.prototype, "declaration", null);
241
+ //# sourceMappingURL=SparqlObjectSetType.js.map
@@ -1,18 +1,16 @@
1
1
  import type { Logger } from "ts-log";
2
2
  import * as ast from "../../ast/index.js";
3
3
  import type { Generator } from "../Generator.js";
4
- import { Reusables } from "./Reusables.js";
5
4
  import type { TsFeature } from "./TsFeature.js";
6
5
  export declare class TsGenerator implements Generator {
7
- private readonly typeFactory;
8
- protected readonly configuration: TsGenerator.Configuration;
9
- protected readonly logger: Logger;
10
- protected readonly reusables: Reusables;
6
+ private readonly configuration?;
7
+ private readonly logger;
11
8
  constructor({ configuration, logger, }: {
12
- configuration?: TsGenerator.Configuration;
9
+ configuration?: Partial<TsGenerator.Configuration>;
13
10
  logger: Logger;
14
11
  });
15
12
  generate(ast_: ast.Ast): string;
13
+ private objectSetTypeDeclarations;
16
14
  /**
17
15
  * Synthesize the $Object union.
18
16
  */
@@ -21,11 +19,12 @@ export declare class TsGenerator implements Generator {
21
19
  export declare namespace TsGenerator {
22
20
  interface Configuration {
23
21
  readonly features: ReadonlySet<TsFeature>;
22
+ readonly finalized: true;
24
23
  readonly syntheticNamePrefix: string;
25
24
  }
26
25
  namespace Configuration {
27
- function inferFeatures(features: ReadonlySet<TsFeature>): Set<"JSON" | "GraphQL" | "Object.create" | "Object.equals" | "Object.filter" | "Object.fromJson" | "Object.fromRdf" | "Object.hash" | "Object.JSON" | "Object.JSON.type" | "Object.JSON.parse" | "Object.JSON.schema" | "Object.JSON.uiSchema" | "Object.RDF" | "Object.schema" | "Object.SPARQL" | "Object.toJson" | "Object.toRdf" | "Object.toString" | "Object.type" | "ObjectSet" | "RDF" | "RdfjsDatasetObjectSet" | "SPARQL" | "SparqlObjectSet">;
28
- const default_: Configuration;
26
+ const default_: Omit<Configuration, "finalized">;
27
+ function finalize(ast: ast.Ast, partialConfiguration?: Partial<Configuration>): Configuration;
29
28
  }
30
29
  }
31
30
  //# sourceMappingURL=TsGenerator.d.ts.map
@@ -2,39 +2,34 @@ import { Maybe } from "purify-ts";
2
2
  import { invariant } from "ts-invariant";
3
3
  import * as ast from "../../ast/index.js";
4
4
  import { BlankNodeType } from "./BlankNodeType.js";
5
- import { graphqlSchemaVariableStatement } from "./graphqlSchemaVariableStatement.js";
5
+ import { GraphqlSchema } from "./GraphqlSchema.js";
6
6
  import { IdentifierType } from "./IdentifierType.js";
7
7
  import { IriType } from "./IriType.js";
8
8
  import { NamedObjectUnionType } from "./NamedObjectUnionType.js";
9
- import { objectSetDeclarations } from "./objectSetDeclarations.js";
9
+ import { ObjectSetType } from "./ObjectSetType.js";
10
+ import { RdfjsDatasetObjectSetType } from "./RdfjsDatasetObjectSetType.js";
10
11
  import { Reusables } from "./Reusables.js";
12
+ import { SparqlObjectSetType } from "./SparqlObjectSetType.js";
11
13
  import { TypeFactory } from "./TypeFactory.js";
12
14
  import { code, joinCode } from "./ts-poet-wrapper.js";
13
15
  export class TsGenerator {
14
- typeFactory;
15
16
  configuration;
16
17
  logger;
17
- reusables;
18
18
  constructor({ configuration, logger, }) {
19
- if (!configuration) {
20
- configuration = TsGenerator.Configuration.default_;
21
- }
22
- this.configuration = {
23
- ...configuration,
24
- features: TsGenerator.Configuration.inferFeatures(configuration.features),
25
- };
19
+ this.configuration = configuration;
26
20
  this.logger = logger;
27
- this.reusables = new Reusables({
28
- configuration: this.configuration,
29
- logger,
30
- });
31
- this.typeFactory = new TypeFactory({
32
- configuration: this.configuration,
33
- logger,
34
- reusables: this.reusables,
35
- });
36
21
  }
37
22
  generate(ast_) {
23
+ const configuration = TsGenerator.Configuration.finalize(ast_, this.configuration);
24
+ const reusables = new Reusables({
25
+ configuration,
26
+ logger: this.logger,
27
+ });
28
+ const typeFactory = new TypeFactory({
29
+ configuration,
30
+ logger: this.logger,
31
+ reusables,
32
+ });
38
33
  let declarations = [];
39
34
  for (const namedObjectType of ast_.namedObjectTypes) {
40
35
  for (const tsImport of namedObjectType.tsImports) {
@@ -45,12 +40,12 @@ export class TsGenerator {
45
40
  if (astNamedUnionType.isObjectUnionType()) {
46
41
  continue;
47
42
  }
48
- declarations = declarations.concat(this.typeFactory.createType(astNamedUnionType).declaration.toList());
43
+ declarations = declarations.concat(typeFactory.createType(astNamedUnionType).declaration.toList());
49
44
  }
50
- const namedObjectTypesToposorted = ast.ObjectType.toposort(ast_.namedObjectTypes).map((astObjectType) => this.typeFactory.createNamedObjectType(astObjectType));
45
+ const namedObjectTypesToposorted = ast.ObjectType.toposort(ast_.namedObjectTypes).map((astObjectType) => typeFactory.createNamedObjectType(astObjectType));
51
46
  const namedObjectUnionTypesToposorted = ast_.namedUnionTypes
52
47
  .filter((_) => _.isObjectUnionType())
53
- .map((astObjectUnionType) => this.typeFactory.createNamedObjectUnionType(astObjectUnionType));
48
+ .map((astObjectUnionType) => typeFactory.createNamedObjectUnionType(astObjectUnionType));
54
49
  for (const namedObjectType of namedObjectTypesToposorted) {
55
50
  declarations = declarations.concat(namedObjectType.declaration.toList());
56
51
  }
@@ -63,31 +58,64 @@ export class TsGenerator {
63
58
  case 0:
64
59
  break;
65
60
  case 1:
66
- declarations.push(code `type ${this.configuration.syntheticNamePrefix}Object = ${namedObjectTypesNameSorted[0].name};`);
61
+ declarations.push(code `type ${configuration.syntheticNamePrefix}Object = ${namedObjectTypesNameSorted[0].name};`);
67
62
  break;
68
63
  default: {
69
- const uberObjectUnionType = this.synthesizeUberObjectUnionType(namedObjectTypesToposorted.toReversed());
64
+ const uberObjectUnionType = this.synthesizeUberObjectUnionType({
65
+ configuration,
66
+ namedObjectTypes: namedObjectTypesToposorted.toReversed(), // Reverse topological order so children ane before parents
67
+ reusables,
68
+ });
70
69
  declarations = declarations.concat(uberObjectUnionType.declaration.toList());
71
70
  namedObjectUnionTypesNameSorted.push(uberObjectUnionType);
72
71
  }
73
72
  }
74
- declarations.push(...objectSetDeclarations.call(this, {
73
+ declarations.push(...this.objectSetTypeDeclarations({
74
+ configuration,
75
75
  namedObjectTypes: namedObjectTypesNameSorted,
76
76
  namedObjectUnionTypes: namedObjectUnionTypesNameSorted,
77
+ reusables,
77
78
  }));
78
- declarations.push(...graphqlSchemaVariableStatement
79
- .call(this, {
80
- namedObjectTypes: namedObjectTypesNameSorted,
81
- namedObjectUnionTypes: namedObjectUnionTypesNameSorted,
82
- })
83
- .toList());
84
- declarations.splice(0, 0, joinCode(this.reusables.snippets.ifUsed, { on: "\n\n" }));
79
+ if (configuration.features.has("GraphQL")) {
80
+ const graphqlNamedObjectTypes = namedObjectTypesNameSorted.filter((namedObjectType) => !namedObjectType.synthetic);
81
+ const graphqlNamedObjectUnionTypes = namedObjectUnionTypesNameSorted.filter((namedObjectUnionType) => !namedObjectUnionType.synthetic);
82
+ if (graphqlNamedObjectTypes.length > 0) {
83
+ declarations.push(new GraphqlSchema({
84
+ configuration,
85
+ logger: this.logger,
86
+ namedObjectTypes: graphqlNamedObjectTypes,
87
+ namedObjectUnionTypes: graphqlNamedObjectUnionTypes,
88
+ reusables,
89
+ }).declaration);
90
+ }
91
+ }
92
+ declarations.splice(0, 0, joinCode(reusables.snippets.ifUsed, { on: "\n\n" }));
85
93
  return joinCode(declarations).toString({});
86
94
  }
95
+ objectSetTypeDeclarations({ configuration, namedObjectTypes, namedObjectUnionTypes, reusables, }) {
96
+ const constructorParameters = {
97
+ configuration,
98
+ logger: this.logger,
99
+ namedObjectTypes: namedObjectTypes.filter((namedObjectType) => !namedObjectType.extern && !namedObjectType.synthetic),
100
+ namedObjectUnionTypes,
101
+ reusables,
102
+ };
103
+ const declarations = [];
104
+ if (configuration.features.has("ObjectSet")) {
105
+ declarations.push(new ObjectSetType(constructorParameters).declaration);
106
+ }
107
+ if (configuration.features.has("RdfjsDatasetObjectSet")) {
108
+ declarations.push(new RdfjsDatasetObjectSetType(constructorParameters).declaration);
109
+ }
110
+ if (configuration.features.has("SparqlObjectSet")) {
111
+ declarations.push(new SparqlObjectSetType(constructorParameters).declaration);
112
+ }
113
+ return declarations;
114
+ }
87
115
  /**
88
116
  * Synthesize the $Object union.
89
117
  */
90
- synthesizeUberObjectUnionType(namedObjectTypes) {
118
+ synthesizeUberObjectUnionType({ configuration, namedObjectTypes, reusables, }) {
91
119
  const filteredNamedObjectTypes = namedObjectTypes.filter((namedObjectType) => !namedObjectType.extern);
92
120
  invariant(filteredNamedObjectTypes.length > 0);
93
121
  const nodeKinds = filteredNamedObjectTypes.reduce((nodeKinds, namedObjectType) => {
@@ -100,10 +128,10 @@ export class TsGenerator {
100
128
  if (nodeKinds.size === 2) {
101
129
  identifierType = new IdentifierType({
102
130
  comment: Maybe.empty(),
103
- configuration: this.configuration,
131
+ configuration,
104
132
  label: Maybe.empty(),
105
133
  logger: this.logger,
106
- reusables: this.reusables,
134
+ reusables,
107
135
  });
108
136
  }
109
137
  else {
@@ -111,28 +139,28 @@ export class TsGenerator {
111
139
  case "BlankNode":
112
140
  identifierType = new BlankNodeType({
113
141
  comment: Maybe.empty(),
114
- configuration: this.configuration,
142
+ configuration,
115
143
  label: Maybe.empty(),
116
144
  logger: this.logger,
117
- reusables: this.reusables,
145
+ reusables,
118
146
  });
119
147
  break;
120
148
  case "IRI":
121
149
  identifierType = new IriType({
122
150
  comment: Maybe.empty(),
123
- configuration: this.configuration,
151
+ configuration,
124
152
  hasValues: [],
125
153
  in_: [],
126
154
  label: Maybe.empty(),
127
155
  logger: this.logger,
128
- reusables: this.reusables,
156
+ reusables,
129
157
  });
130
158
  break;
131
159
  }
132
160
  }
133
161
  return new NamedObjectUnionType({
134
162
  comment: Maybe.empty(),
135
- configuration: this.configuration,
163
+ configuration,
136
164
  identifierType,
137
165
  label: Maybe.empty(),
138
166
  logger: this.logger,
@@ -140,9 +168,9 @@ export class TsGenerator {
140
168
  discriminantValue: Maybe.empty(),
141
169
  type: namedObjectType,
142
170
  })),
143
- name: `${this.configuration.syntheticNamePrefix}Object`,
171
+ name: `${configuration.syntheticNamePrefix}Object`,
144
172
  recursive: false,
145
- reusables: this.reusables,
173
+ reusables,
146
174
  synthetic: true,
147
175
  });
148
176
  }
@@ -150,25 +178,25 @@ export class TsGenerator {
150
178
  (function (TsGenerator) {
151
179
  let Configuration;
152
180
  (function (Configuration) {
153
- const featureDependencies = {
181
+ Configuration.default_ = {
182
+ features: new Set([
183
+ "Object.create",
184
+ "Object.equals",
185
+ "Object.hash",
186
+ "JSON",
187
+ "RDF",
188
+ ]),
189
+ syntheticNamePrefix: "$",
190
+ };
191
+ const featureDependenciesStatic = {
154
192
  GraphQL: ["ObjectSet"],
155
193
  // Alias for other features, not dependencies per se
156
194
  JSON: ["Object.JSON"],
157
195
  "Object.create": ["Object.schema", "Object.toString", "Object.type"],
158
196
  "Object.equals": ["Object.type"],
159
197
  "Object.filter": ["Object.type"],
160
- "Object.fromJson": [
161
- "Object.create",
162
- "Object.JSON.type",
163
- "Object.type",
164
- "ObjectSet",
165
- ],
166
- "Object.fromRdf": [
167
- "Object.create",
168
- "Object.schema",
169
- "ObjectSet",
170
- "RdfjsDatasetObjectSet",
171
- ],
198
+ "Object.fromJson": ["Object.create", "Object.JSON.type", "Object.type"],
199
+ "Object.fromRdf": ["Object.create", "Object.schema"],
172
200
  "Object.hash": [],
173
201
  // Alias for other features, not dependencies per se
174
202
  "Object.JSON": [
@@ -198,31 +226,34 @@ export class TsGenerator {
198
226
  SPARQL: ["Object.SPARQL", "SparqlObjectSet"],
199
227
  SparqlObjectSet: ["Object.SPARQL", "ObjectSet"],
200
228
  };
201
- function inferFeatures(features) {
202
- const inferredFeatures = new Set(features);
203
- const queue = [...features];
204
- while (queue.length > 0) {
205
- const feature = queue.shift();
206
- for (const featureDependency of featureDependencies[feature]) {
207
- if (!inferredFeatures.has(featureDependency)) {
208
- inferredFeatures.add(featureDependency);
209
- queue.push(featureDependency);
229
+ function finalize(ast, partialConfiguration) {
230
+ const requestedFeatures = partialConfiguration?.features ?? Configuration.default_.features;
231
+ const featureDependencies = Object.fromEntries(Object.entries(featureDependenciesStatic).map(([k, v]) => [k, [...v]]));
232
+ if (ast.lazyTypesCount > 0) {
233
+ featureDependencies["Object.fromJson"].push("ObjectSet");
234
+ featureDependencies["Object.fromRdf"].push("ObjectSet", "RdfjsDatasetObjectSet");
235
+ }
236
+ const inferredFeatures = new Set(requestedFeatures);
237
+ {
238
+ const inferredFeaturesQueue = [...requestedFeatures];
239
+ while (inferredFeaturesQueue.length > 0) {
240
+ const feature = inferredFeaturesQueue.shift();
241
+ for (const featureDependency of featureDependencies[feature]) {
242
+ if (!inferredFeatures.has(featureDependency)) {
243
+ inferredFeatures.add(featureDependency);
244
+ inferredFeaturesQueue.push(featureDependency);
245
+ }
210
246
  }
211
247
  }
212
248
  }
213
- return inferredFeatures;
249
+ return {
250
+ features: inferredFeatures,
251
+ finalized: true,
252
+ syntheticNamePrefix: partialConfiguration?.syntheticNamePrefix ??
253
+ Configuration.default_.syntheticNamePrefix,
254
+ };
214
255
  }
215
- Configuration.inferFeatures = inferFeatures;
216
- Configuration.default_ = {
217
- features: inferFeatures(new Set([
218
- "Object.create",
219
- "Object.equals",
220
- "Object.hash",
221
- "JSON",
222
- "RDF",
223
- ])),
224
- syntheticNamePrefix: "$",
225
- };
256
+ Configuration.finalize = finalize;
226
257
  })(Configuration = TsGenerator.Configuration || (TsGenerator.Configuration = {}));
227
258
  })(TsGenerator || (TsGenerator = {}));
228
259
  //# sourceMappingURL=TsGenerator.js.map
@@ -2,8 +2,7 @@ import type { Logger } from "ts-log";
2
2
  import * as ast from "../../ast/index.js";
3
3
  import type { Generator } from "../Generator.js";
4
4
  export declare class ZodGenerator implements Generator {
5
- private readonly reusables;
6
- private readonly typeFactory;
5
+ private readonly logger;
7
6
  constructor({ logger }: {
8
7
  logger: Logger;
9
8
  });
@@ -7,20 +7,20 @@ import { TsGenerator } from "./TsGenerator.js";
7
7
  import { TypeFactory } from "./TypeFactory.js";
8
8
  import { code, joinCode } from "./ts-poet-wrapper.js";
9
9
  export class ZodGenerator {
10
- reusables;
11
- typeFactory;
10
+ logger;
12
11
  constructor({ logger }) {
13
- const configuration = TsGenerator.Configuration.default_;
14
- this.reusables = new Reusables({ configuration, logger });
15
- this.typeFactory = new TypeFactory({
16
- configuration,
17
- logger,
18
- reusables: this.reusables,
19
- });
12
+ this.logger = logger;
20
13
  }
21
14
  generate(ast_) {
15
+ const configuration = TsGenerator.Configuration.finalize(ast_, TsGenerator.Configuration.default_);
16
+ const reusables = new Reusables({ configuration, logger: this.logger });
17
+ const typeFactory = new TypeFactory({
18
+ configuration,
19
+ logger: this.logger,
20
+ reusables,
21
+ });
22
22
  const declarations = [];
23
- for (const namedObjectType of ast.ObjectType.toposort(ast_.namedObjectTypes).map((astObjectType) => this.typeFactory.createNamedObjectType(astObjectType))) {
23
+ for (const namedObjectType of ast.ObjectType.toposort(ast_.namedObjectTypes).map((astObjectType) => typeFactory.createNamedObjectType(astObjectType))) {
24
24
  declarations.push(code `\
25
25
  export namespace ${namedObjectType.name} {
26
26
  ${joinCode(NamedObjectType_jsonTypeAliasDeclaration.call(namedObjectType).toList())}
@@ -30,7 +30,7 @@ export namespace ${namedObjectType.name} {
30
30
  }
31
31
  }`);
32
32
  }
33
- for (const astNamedUnionType of ast_.namedUnionTypes.map((astNamedUnionType) => this.typeFactory.createUnionType(astNamedUnionType))) {
33
+ for (const astNamedUnionType of ast_.namedUnionTypes.map((astNamedUnionType) => typeFactory.createUnionType(astNamedUnionType))) {
34
34
  invariant(astNamedUnionType.kind !== "AnonymousUnionType");
35
35
  declarations.push(code `\
36
36
  export namespace ${astNamedUnionType.name} {
@@ -40,7 +40,7 @@ export namespace ${astNamedUnionType.name} {
40
40
  }
41
41
  }`);
42
42
  }
43
- declarations.splice(0, 0, joinCode(this.reusables.snippets.ifUsed, { on: "\n\n" }));
43
+ declarations.splice(0, 0, joinCode(reusables.snippets.ifUsed, { on: "\n\n" }));
44
44
  return joinCode(declarations, { on: "\n\n" }).toString({});
45
45
  }
46
46
  }
@@ -37,19 +37,25 @@ export function NamedObjectType_createFunctionDeclaration() {
37
37
  expression: code `${this.reusables.snippets.sequenceRecord}({ ${joinCode(propertyInitializers, { on: "," })} })`,
38
38
  variable: "properties",
39
39
  });
40
- const syntheticNamePrefix = this.configuration.syntheticNamePrefix;
40
+ let returnExpression = code `{ ${chains
41
+ .map((chain) => `...${chain.variable}`)
42
+ .join(", ")}, ${this._discriminantProperty.name}: ${literalOf(this.discriminantValue)} as const }`;
43
+ const monkeyPatchMethods = [];
44
+ if (this.configuration.features.has("Object.toJson")) {
45
+ monkeyPatchMethods.push("toJson");
46
+ }
47
+ if (this.configuration.features.has("Object.toString")) {
48
+ monkeyPatchMethods.push(`${this.configuration.syntheticNamePrefix}toString`);
49
+ }
50
+ if (monkeyPatchMethods.length > 0) {
51
+ returnExpression = code `${this.reusables.snippets.monkeyPatchObject}(${returnExpression}, { ${monkeyPatchMethods.join(", ")} })`;
52
+ }
53
+ returnExpression = chains
54
+ .toReversed()
55
+ .reduce((acc, { expression, variable }, chainI) => code `(${expression}).${chainI === 0 ? "map" : "chain"}(${variable} => ${acc})`, returnExpression);
41
56
  return Maybe.of(code `\
42
57
  export function create(${parametersSignature}): ${this.reusables.imports.Either}<Error, ${this.name}> {
43
- return ${chains.toReversed().reduce((acc, { expression, variable }, chainI) => code `(${expression}).${chainI === 0 ? "map" : "chain"}(${variable} => ${acc})`, code `\
44
- {
45
- const finalObject = { ${chains
46
- .map((chain) => `...${chain.variable}`)
47
- .join(", ")}, ${this._discriminantProperty.name}: ${literalOf(this.discriminantValue)} as const };
48
- if (!globalThis.Object.prototype.hasOwnProperty.call(finalObject, "toString")) {
49
- (finalObject as any).toString = ${syntheticNamePrefix}toString;
50
- }
51
- return finalObject;
52
- }`)};
58
+ return ${returnExpression};
53
59
  }
54
60
 
55
61
  export function createUnsafe(${parametersSignature}): ${this.name} {
@@ -19,6 +19,7 @@ export function NamedObjectType_toJsonFunctionDeclaration() {
19
19
  })
20
20
  .toList()));
21
21
  }
22
+ const returnType = this.jsonType().name;
22
23
  // 20241220: don't add @type until we're doing JSON-LD
23
24
  // switch (this.toRdfTypes.length) {
24
25
  // case 0:
@@ -33,7 +34,7 @@ export function NamedObjectType_toJsonFunctionDeclaration() {
33
34
  // break;
34
35
  // }
35
36
  return Maybe.of(code `\
36
- export function toJson(${this.thisVariable}: ${this.name}): ${this.jsonType().name} {
37
+ export function toJson(${this.thisVariable}: ${this.name}): ${returnType} {
37
38
  return JSON.parse(JSON.stringify({ ${joinCode(jsonObjectMembers, { on: "," })} } satisfies ${this.jsonType().name}));
38
39
  }`);
39
40
  }
@@ -28,10 +28,8 @@ export function _propertiesToStrings(${this.thisVariable}: ${this.name}): Record
28
28
  return ${propertiesToStringsReturnExpression};
29
29
  }`,
30
30
  code `\
31
- export function ${syntheticNamePrefix}toString(this: ${this.name}): string;
32
- export function ${syntheticNamePrefix}toString(${this.thisVariable}: ${this.name}): string;
33
- export function ${syntheticNamePrefix}toString(this: ${this.name} | undefined, ${this.thisVariable}?: ${this.name}): string {
34
- return ${toStringReturnExpression(code `_propertiesToStrings((${this.thisVariable} ?? this)!)`)};
31
+ export function ${syntheticNamePrefix}toString(${this.thisVariable}: ${this.name}): string {
32
+ return ${toStringReturnExpression(code `_propertiesToStrings(${this.thisVariable})`)};
35
33
  }`,
36
34
  ];
37
35
  }
@@ -1,12 +1,12 @@
1
1
  import { code, conditionalOutput } from "../ts-poet-wrapper.js";
2
- export const snippets_FromRdfResourceFunction = ({ imports, syntheticNamePrefix, }) => conditionalOutput(`${syntheticNamePrefix}FromRdfResourceFunction`, code `\
2
+ export const snippets_FromRdfResourceFunction = ({ configuration, imports, syntheticNamePrefix, }) => conditionalOutput(`${syntheticNamePrefix}FromRdfResourceFunction`, code `\
3
3
  export type ${syntheticNamePrefix}FromRdfResourceFunction<T> = (
4
4
  resource: ${imports.Resource},
5
5
  options?: {
6
6
  context?: unknown;
7
7
  graph?: Exclude<${imports.Quad_Graph}, ${imports.Variable}>;
8
8
  ignoreRdfType?: boolean;
9
- objectSet?: ${syntheticNamePrefix}ObjectSet;
9
+ ${configuration.features.has("ObjectSet") ? code `objectSet?: ${syntheticNamePrefix}ObjectSet;` : ""}
10
10
  preferredLanguages?: readonly string[];
11
11
  }
12
12
  ) => ${imports.Either}<Error, T>`);
@@ -1,12 +1,12 @@
1
1
  import { code, conditionalOutput } from "../ts-poet-wrapper.js";
2
- export const snippets_FromRdfResourceValuesFunction = ({ imports, syntheticNamePrefix, }) => conditionalOutput(`${syntheticNamePrefix}FromRdfResourceValuesFunction`, code `\
2
+ export const snippets_FromRdfResourceValuesFunction = ({ configuration, imports, syntheticNamePrefix, }) => conditionalOutput(`${syntheticNamePrefix}FromRdfResourceValuesFunction`, code `\
3
3
  export type ${syntheticNamePrefix}FromRdfResourceValuesFunction<T> = (
4
4
  resourceValues: ${imports.Either}<Error, ${imports.Resource}.Values>,
5
5
  options: {
6
6
  context?: unknown;
7
7
  graph?: Exclude<${imports.Quad_Graph}, ${imports.Variable}>;
8
8
  ignoreRdfType?: boolean;
9
- objectSet?: ${syntheticNamePrefix}ObjectSet;
9
+ ${configuration.features.has("ObjectSet") ? code `objectSet?: ${syntheticNamePrefix}ObjectSet;` : ""}
10
10
  preferredLanguages?: readonly string[];
11
11
  propertyPath: ${syntheticNamePrefix}PropertyPath;
12
12
  resource: ${imports.Resource};
@@ -1,12 +1,12 @@
1
1
  import { code, conditionalOutput } from "../ts-poet-wrapper.js";
2
- export const snippets__FromRdfResourceFunction = ({ imports, syntheticNamePrefix, }) => conditionalOutput(`${syntheticNamePrefix}_FromRdfResourceFunction`, code `\
2
+ export const snippets__FromRdfResourceFunction = ({ configuration, imports, syntheticNamePrefix, }) => conditionalOutput(`${syntheticNamePrefix}_FromRdfResourceFunction`, code `\
3
3
  type ${syntheticNamePrefix}_FromRdfResourceFunction<T> = (
4
4
  resource: ${imports.Resource},
5
5
  options: {
6
6
  context: undefined | unknown;
7
7
  graph: Exclude<${imports.Quad_Graph}, ${imports.Variable}> | undefined;
8
8
  ignoreRdfType: boolean;
9
- objectSet: ${syntheticNamePrefix}ObjectSet;
9
+ ${configuration.features.has("ObjectSet") ? code `objectSet: ${syntheticNamePrefix}ObjectSet;` : ""}
10
10
  preferredLanguages: readonly string[] | undefined;
11
11
  }
12
12
  ) => ${imports.Either}<Error, T>;`);
@@ -0,0 +1,3 @@
1
+ import type { SnippetFactory } from "../SnippetFactory.js";
2
+ export declare const snippets_monkeyPatchObject: SnippetFactory;
3
+ //# sourceMappingURL=snippets_monkeyPatchObject.d.ts.map
@@ -0,0 +1,16 @@
1
+ import { code, conditionalOutput } from "../ts-poet-wrapper.js";
2
+ export const snippets_monkeyPatchObject = ({ syntheticNamePrefix, }) => conditionalOutput(`${syntheticNamePrefix}monkeyPatchObject`, code `\
3
+ function ${syntheticNamePrefix}monkeyPatchObject<T extends object>(obj: T, methods: { toJson?: (obj: T) => object, ${syntheticNamePrefix}toString?: (obj: T) => string }): T {
4
+ if (methods.toJson && !globalThis.Object.prototype.hasOwnProperty.call(obj, "toJSON")) {
5
+ const toJsonMethod = methods.toJson;
6
+ (obj as any).toJSON = function(this: T, _key: string) { return toJsonMethod(this); }
7
+ }
8
+
9
+ if (methods.${syntheticNamePrefix}toString && !globalThis.Object.prototype.hasOwnProperty.call(obj, "toString")) {
10
+ const toStringMethod = methods.${syntheticNamePrefix}toString;
11
+ (obj as any).toString = function(this: T) { return toStringMethod(this); }
12
+ }
13
+
14
+ return obj;
15
+ }`);
16
+ //# sourceMappingURL=snippets_monkeyPatchObject.js.map