ldkit 2.6.0 → 2.7.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.
@@ -1,8 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.NAMESPACES = void 0;
3
4
  exports.schemaToScript = schemaToScript;
4
5
  const namespaces_js_1 = require("../namespaces.js");
5
- const NAMESPACES = [
6
+ exports.NAMESPACES = [
6
7
  namespaces_js_1.dbo,
7
8
  namespaces_js_1.dc,
8
9
  namespaces_js_1.dcterms,
@@ -17,12 +18,12 @@ const NAMESPACES = [
17
18
  namespaces_js_1.skos,
18
19
  namespaces_js_1.xsd,
19
20
  ];
20
- function schemaToScript(schemas) {
21
- const printer = new SchemaPrinter();
21
+ function schemaToScript(schemas, extraNamespaces = [], options = {}) {
22
+ const printer = new SchemaPrinter(extraNamespaces, options);
22
23
  return printer.print(schemas);
23
24
  }
24
25
  class SchemaPrinter {
25
- constructor() {
26
+ constructor(extraNamespaces = [], options = {}) {
26
27
  Object.defineProperty(this, "usedNamespaces", {
27
28
  enumerable: true,
28
29
  configurable: true,
@@ -35,6 +36,68 @@ class SchemaPrinter {
35
36
  writable: true,
36
37
  value: " "
37
38
  });
39
+ // Sorted by IRI length desc so longer prefixes match before shorter ones.
40
+ Object.defineProperty(this, "extraNamespaces", {
41
+ enumerable: true,
42
+ configurable: true,
43
+ writable: true,
44
+ value: void 0
45
+ });
46
+ Object.defineProperty(this, "extraNamespaceTerms", {
47
+ enumerable: true,
48
+ configurable: true,
49
+ writable: true,
50
+ value: new Map()
51
+ });
52
+ Object.defineProperty(this, "shadowedBuiltins", {
53
+ enumerable: true,
54
+ configurable: true,
55
+ writable: true,
56
+ value: void 0
57
+ });
58
+ Object.defineProperty(this, "schemaLocations", {
59
+ enumerable: true,
60
+ configurable: true,
61
+ writable: true,
62
+ value: void 0
63
+ });
64
+ Object.defineProperty(this, "currentFile", {
65
+ enumerable: true,
66
+ configurable: true,
67
+ writable: true,
68
+ value: void 0
69
+ });
70
+ Object.defineProperty(this, "extraNamespaceFiles", {
71
+ enumerable: true,
72
+ configurable: true,
73
+ writable: true,
74
+ value: void 0
75
+ });
76
+ Object.defineProperty(this, "extraNamespaceTermsOverride", {
77
+ enumerable: true,
78
+ configurable: true,
79
+ writable: true,
80
+ value: void 0
81
+ });
82
+ Object.defineProperty(this, "extraNamespacesImportFrom", {
83
+ enumerable: true,
84
+ configurable: true,
85
+ writable: true,
86
+ value: void 0
87
+ });
88
+ Object.defineProperty(this, "crossFileImports", {
89
+ enumerable: true,
90
+ configurable: true,
91
+ writable: true,
92
+ value: new Map()
93
+ });
94
+ this.extraNamespaces = [...extraNamespaces].sort((a, b) => b.iri.length - a.iri.length);
95
+ this.shadowedBuiltins = new Set(this.extraNamespaces.map((ns) => ns.prefix));
96
+ this.schemaLocations = options.schemaLocations ?? new Map();
97
+ this.currentFile = options.currentFile;
98
+ this.extraNamespaceFiles = options.extraNamespaceFiles ?? new Map();
99
+ this.extraNamespaceTermsOverride = options.extraNamespaceTermsOverride;
100
+ this.extraNamespacesImportFrom = options.extraNamespacesImportFrom;
38
101
  }
39
102
  print(schemas) {
40
103
  const orderedSchemas = this.orderSchemasByDependencies(schemas);
@@ -44,18 +107,20 @@ class SchemaPrinter {
44
107
  const printedSchema = this.printSchema(schema);
45
108
  printedSchemas.push(printedSchema);
46
109
  }
47
- if (this.usedNamespaces.size > 0) {
48
- printedSchemas.unshift(this.printImports());
110
+ const header = this.printHeader();
111
+ if (header) {
112
+ printedSchemas.unshift(header);
49
113
  }
50
114
  return printedSchemas.join("\n");
51
115
  }
52
116
  orderSchemasByDependencies(schemas) {
53
117
  const orderedSchemas = [];
54
118
  const processedSchemas = new Set();
119
+ const localNames = new Set(schemas.map((s) => s.name));
55
120
  const dependencies = schemas.map((schema) => {
56
121
  return {
57
122
  schemaName: schema.name,
58
- dependencies: this.getSchemaDependencies(schema),
123
+ dependencies: this.getSchemaDependencies(schema).filter((dep) => localNames.has(dep)),
59
124
  };
60
125
  });
61
126
  let unresolved = schemas.length;
@@ -96,9 +161,25 @@ class SchemaPrinter {
96
161
  this.usedNamespaces.add(this.printPrefix(namespaces_js_1.ldkit));
97
162
  return;
98
163
  }
99
- for (const namespace of NAMESPACES) {
164
+ for (const ns of this.extraNamespaces) {
165
+ if (value.startsWith(ns.iri)) {
166
+ const localPart = value.substring(ns.iri.length);
167
+ let terms = this.extraNamespaceTerms.get(ns.prefix);
168
+ if (!terms) {
169
+ terms = new Set();
170
+ this.extraNamespaceTerms.set(ns.prefix, terms);
171
+ }
172
+ terms.add(localPart);
173
+ return;
174
+ }
175
+ }
176
+ for (const namespace of exports.NAMESPACES) {
100
177
  if (value.startsWith(namespace.$iri)) {
101
- this.usedNamespaces.add(this.printPrefix(namespace));
178
+ const name = this.printPrefix(namespace);
179
+ if (this.shadowedBuiltins.has(name)) {
180
+ return;
181
+ }
182
+ this.usedNamespaces.add(name);
102
183
  return;
103
184
  }
104
185
  }
@@ -117,11 +198,88 @@ class SchemaPrinter {
117
198
  }
118
199
  }
119
200
  }
120
- printImports() {
121
- const namespacesString = Array.from(this.usedNamespaces)
122
- .toSorted()
123
- .join(", ");
124
- return `import { ${namespacesString} } from "ldkit/namespaces";\n`;
201
+ trackCrossFileRef(schemaRef) {
202
+ if (!this.currentFile)
203
+ return;
204
+ const refFile = this.schemaLocations.get(schemaRef);
205
+ if (!refFile || refFile === this.currentFile)
206
+ return;
207
+ let names = this.crossFileImports.get(refFile);
208
+ if (!names) {
209
+ names = new Set();
210
+ this.crossFileImports.set(refFile, names);
211
+ }
212
+ names.add(schemaRef);
213
+ }
214
+ printHeader() {
215
+ const lines = [];
216
+ const usedPrefixes = new Set(this.extraNamespaces.map((ns) => ns.prefix))
217
+ .intersection(new Set(this.extraNamespaceTerms.keys()));
218
+ const usedExtras = this.extraNamespaces.filter((ns) => usedPrefixes.has(ns.prefix));
219
+ const declaredExtras = [];
220
+ const importedByFile = new Map();
221
+ if (this.extraNamespacesImportFrom !== undefined) {
222
+ if (usedExtras.length > 0) {
223
+ importedByFile.set(this.extraNamespacesImportFrom, new Set(usedExtras.map((ns) => ns.prefix)));
224
+ }
225
+ }
226
+ else {
227
+ for (const ns of usedExtras) {
228
+ const home = this.extraNamespaceFiles.get(ns.prefix);
229
+ if (!home || !this.currentFile || home === this.currentFile) {
230
+ declaredExtras.push(ns);
231
+ continue;
232
+ }
233
+ let names = importedByFile.get(home);
234
+ if (!names) {
235
+ names = new Set();
236
+ importedByFile.set(home, names);
237
+ }
238
+ names.add(ns.prefix);
239
+ }
240
+ }
241
+ if (declaredExtras.length > 0) {
242
+ lines.push(`import { createNamespace } from "ldkit";`);
243
+ }
244
+ if (this.usedNamespaces.size > 0) {
245
+ const namespacesString = Array.from(this.usedNamespaces)
246
+ .toSorted()
247
+ .join(", ");
248
+ lines.push(`import { ${namespacesString} } from "ldkit/namespaces";`);
249
+ }
250
+ const crossFileEntries = [...this.crossFileImports.entries()]
251
+ .toSorted(([a], [b]) => a.localeCompare(b));
252
+ for (const [file, names] of crossFileEntries) {
253
+ const sortedNames = [...names].toSorted().join(", ");
254
+ lines.push(`import { ${sortedNames} } from "./${file}";`);
255
+ }
256
+ const importedExtraEntries = [...importedByFile.entries()]
257
+ .toSorted(([a], [b]) => a.localeCompare(b));
258
+ for (const [file, prefixes] of importedExtraEntries) {
259
+ const sortedPrefixes = [...prefixes].toSorted().join(", ");
260
+ lines.push(`import { ${sortedPrefixes} } from "./${file}";`);
261
+ }
262
+ if (lines.length > 0) {
263
+ lines.push("");
264
+ }
265
+ for (const ns of declaredExtras) {
266
+ const termSet = this.extraNamespaceTermsOverride?.get(ns.prefix) ??
267
+ this.extraNamespaceTerms.get(ns.prefix);
268
+ const terms = Array.from(termSet).toSorted();
269
+ lines.push(`export const ${ns.prefix} = createNamespace(`);
270
+ lines.push(` {`);
271
+ lines.push(` iri: ${JSON.stringify(ns.iri)},`);
272
+ lines.push(` prefix: ${JSON.stringify(`${ns.prefix}:`)},`);
273
+ lines.push(` terms: [`);
274
+ for (const term of terms) {
275
+ lines.push(` ${JSON.stringify(term)},`);
276
+ }
277
+ lines.push(` ],`);
278
+ lines.push(` } as const,`);
279
+ lines.push(`);`);
280
+ lines.push("");
281
+ }
282
+ return lines.join("\n");
125
283
  }
126
284
  printSchema(schema) {
127
285
  const type = this.printType(schema);
@@ -170,6 +328,7 @@ class SchemaPrinter {
170
328
  builder.push(this.indent(subSchema));
171
329
  }
172
330
  else if (prop.schemaRef) {
331
+ this.trackCrossFileRef(prop.schemaRef);
173
332
  builder.push(this.indent(`"@schema": ${prop.schemaRef},`));
174
333
  }
175
334
  const flags = ["optional", "array", "multilang", "inverse"];
@@ -201,13 +360,29 @@ class SchemaPrinter {
201
360
  if (value === "@id") {
202
361
  return `${this.printPrefix(namespaces_js_1.ldkit)}.IRI`;
203
362
  }
204
- for (const namespace of NAMESPACES) {
363
+ for (const ns of this.extraNamespaces) {
364
+ if (value.startsWith(ns.iri)) {
365
+ const localPart = value.substring(ns.iri.length);
366
+ return this.formatNamespaceAccess(ns.prefix, localPart);
367
+ }
368
+ }
369
+ for (const namespace of exports.NAMESPACES) {
205
370
  if (value.startsWith(namespace.$iri)) {
206
- return `${this.printPrefix(namespace)}.${value.substring(namespace.$iri.length)}`;
371
+ const name = this.printPrefix(namespace);
372
+ if (this.shadowedBuiltins.has(name)) {
373
+ return `"${value}"`;
374
+ }
375
+ return `${name}.${value.substring(namespace.$iri.length)}`;
207
376
  }
208
377
  }
209
378
  return `"${value}"`;
210
379
  }
380
+ formatNamespaceAccess(prefix, localPart) {
381
+ if (/^[A-Za-z_$]\w*$/.test(localPart)) {
382
+ return `${prefix}.${localPart}`;
383
+ }
384
+ return `${prefix}["${localPart}"]`;
385
+ }
211
386
  printKey(key) {
212
387
  if (key.match(/^[a-zA-Z0-9_]+$/)) {
213
388
  return key;
@@ -0,0 +1,11 @@
1
+ import { type ExtraNamespace, type SchemaSpec } from "./schema_to_script.js";
2
+ export type ShaclConversionResult = {
3
+ schemas: SchemaSpec[];
4
+ extraNamespaces: ExtraNamespace[];
5
+ schemaSourcePrefixes: Map<string, string>;
6
+ };
7
+ export type ShaclConversionOptions = {
8
+ prefixAliases?: Record<string, string>;
9
+ };
10
+ export declare function shaclToSchema(turtle: string, options?: ShaclConversionOptions): ShaclConversionResult;
11
+ //# sourceMappingURL=shacl_to_schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shacl_to_schema.d.ts","sourceRoot":"","sources":["../../src/scripts/shacl_to_schema.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,KAAK,cAAc,EAGnB,KAAK,UAAU,EAChB,MAAM,uBAAuB,CAAC;AAkE/B,MAAM,MAAM,qBAAqB,GAAG;IAClC,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,eAAe,EAAE,cAAc,EAAE,CAAC;IAClC,oBAAoB,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC3C,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACnC,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACxC,CAAC;AAEF,wBAAgB,aAAa,CAC3B,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,sBAA2B,GACnC,qBAAqB,CAGvB"}