@ng-org/shex-orm 0.1.2-alpha.1

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 (47) hide show
  1. package/README.md +236 -0
  2. package/dist/ShexJTypes.d.ts +542 -0
  3. package/dist/ShexJTypes.d.ts.map +1 -0
  4. package/dist/ShexJTypes.js +10 -0
  5. package/dist/build.d.ts +8 -0
  6. package/dist/build.d.ts.map +1 -0
  7. package/dist/build.js +72 -0
  8. package/dist/cli.d.ts +3 -0
  9. package/dist/cli.d.ts.map +1 -0
  10. package/dist/cli.js +15 -0
  11. package/dist/index.d.ts +2 -0
  12. package/dist/index.d.ts.map +1 -0
  13. package/dist/index.js +1 -0
  14. package/dist/schema-converter/__tests__/typingTransformer.test.d.ts +2 -0
  15. package/dist/schema-converter/__tests__/typingTransformer.test.d.ts.map +1 -0
  16. package/dist/schema-converter/__tests__/typingTransformer.test.js +76 -0
  17. package/dist/schema-converter/converter.d.ts +12 -0
  18. package/dist/schema-converter/converter.d.ts.map +1 -0
  19. package/dist/schema-converter/converter.js +79 -0
  20. package/dist/schema-converter/templates/schema.ejs +8 -0
  21. package/dist/schema-converter/templates/shapeTypes.ejs +14 -0
  22. package/dist/schema-converter/templates/typings.ejs +14 -0
  23. package/dist/schema-converter/transformers/ShexJSchemaTransformer.d.ts +348 -0
  24. package/dist/schema-converter/transformers/ShexJSchemaTransformer.d.ts.map +1 -0
  25. package/dist/schema-converter/transformers/ShexJSchemaTransformer.js +239 -0
  26. package/dist/schema-converter/transformers/ShexJTypingTransformer.d.ts +366 -0
  27. package/dist/schema-converter/transformers/ShexJTypingTransformer.d.ts.map +1 -0
  28. package/dist/schema-converter/transformers/ShexJTypingTransformer.js +623 -0
  29. package/dist/schema-converter/util/ShapeInterfaceDeclaration.d.ts +5 -0
  30. package/dist/schema-converter/util/ShapeInterfaceDeclaration.d.ts.map +1 -0
  31. package/dist/schema-converter/util/ShapeInterfaceDeclaration.js +1 -0
  32. package/dist/schema-converter/util/annotateReadablePredicates.d.ts +8 -0
  33. package/dist/schema-converter/util/annotateReadablePredicates.d.ts.map +1 -0
  34. package/dist/schema-converter/util/annotateReadablePredicates.js +148 -0
  35. package/dist/schema-converter/util/dedupeObjectTypeMembers.d.ts +3 -0
  36. package/dist/schema-converter/util/dedupeObjectTypeMembers.d.ts.map +1 -0
  37. package/dist/schema-converter/util/dedupeObjectTypeMembers.js +47 -0
  38. package/dist/schema-converter/util/getRdfTypesForTripleConstraint.d.ts +4 -0
  39. package/dist/schema-converter/util/getRdfTypesForTripleConstraint.d.ts.map +1 -0
  40. package/dist/schema-converter/util/getRdfTypesForTripleConstraint.js +98 -0
  41. package/dist/types.d.ts +37 -0
  42. package/dist/types.d.ts.map +1 -0
  43. package/dist/types.js +10 -0
  44. package/dist/util/forAllShapes.d.ts +2 -0
  45. package/dist/util/forAllShapes.d.ts.map +1 -0
  46. package/dist/util/forAllShapes.js +25 -0
  47. package/package.json +61 -0
@@ -0,0 +1,623 @@
1
+ // Copyright (c) 2025 Laurin Weger, Par le Peuple, NextGraph.org developers
2
+ // All rights reserved.
3
+ // Copyright (c) 2023 Jackson Morgan
4
+ // Licensed under the Apache License, Version 2.0
5
+ // <LICENSE-APACHE2 or http://www.apache.org/licenses/LICENSE-2.0>
6
+ // or the MIT license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
7
+ // at your option. All files in the project carrying such
8
+ // notice may not be copied, modified, or distributed except
9
+ // according to those terms.
10
+ // SPDX-License-Identifier: Apache-2.0 OR MIT
11
+ /* eslint-disable @typescript-eslint/no-explicit-any */
12
+ import ShexJTraverser from "@ldo/traverser-shexj";
13
+ import * as dom from "dts-dom";
14
+ // Collected enum alias names (e.g., AuthenticatedAgentId) to emit at end
15
+ export const additionalCompactEnumAliases = new Set();
16
+ function commentFromAnnotations(annotations) {
17
+ const commentAnnotationObject = annotations?.find((annotation) => annotation.predicate ===
18
+ "http://www.w3.org/2000/01/rdf-schema#comment")?.object;
19
+ if (typeof commentAnnotationObject === "string")
20
+ return commentAnnotationObject;
21
+ return commentAnnotationObject?.value;
22
+ }
23
+ export function toCamelCase(text) {
24
+ return text
25
+ .replace(/([-_ ]){1,}/g, " ")
26
+ .split(/[-_ ]/)
27
+ .reduce((cur, acc) => {
28
+ return cur + acc[0].toUpperCase() + acc.substring(1);
29
+ });
30
+ }
31
+ /**
32
+ * Name functions
33
+ */
34
+ export function iriToName(iri) {
35
+ try {
36
+ const url = new URL(iri);
37
+ let name;
38
+ if (url.hash) {
39
+ name = url.hash.slice(1);
40
+ }
41
+ else {
42
+ const splitPathname = url.pathname.split("/");
43
+ name = splitPathname[splitPathname.length - 1];
44
+ }
45
+ return name.replace(/(?<!^)Shape$/, "");
46
+ }
47
+ catch (err) {
48
+ return iri;
49
+ }
50
+ }
51
+ export function nameFromAnnotationOrId(obj) {
52
+ const labelAnnotationObject = obj.annotations?.find((annotation) => annotation.predicate ===
53
+ "http://www.w3.org/2000/01/rdf-schema#label")?.object;
54
+ if (labelAnnotationObject && typeof labelAnnotationObject === "string") {
55
+ return toCamelCase(iriToName(labelAnnotationObject));
56
+ }
57
+ else if (labelAnnotationObject &&
58
+ typeof labelAnnotationObject !== "string") {
59
+ return toCamelCase(labelAnnotationObject.value);
60
+ }
61
+ else if (obj.id) {
62
+ return toCamelCase(iriToName(obj.id));
63
+ }
64
+ }
65
+ // Helper: classify a dom.Type into categories we care about.
66
+ function isObjectLike(t) {
67
+ return (t.kind === "object" ||
68
+ t.kind === "interface");
69
+ }
70
+ function isPrimitiveLike(t) {
71
+ const kind = t?.kind;
72
+ if (kind === "name")
73
+ return true; // named references and intrinsic tokens
74
+ if (kind === "union") {
75
+ return t.members.every(isPrimitiveLike);
76
+ }
77
+ if (kind === "type-parameter")
78
+ return true;
79
+ // Fallback: treat scalar intrinsic tokens as primitive
80
+ const intrinsicKinds = new Set([
81
+ "string",
82
+ "number",
83
+ "boolean",
84
+ "undefined",
85
+ ]);
86
+ return intrinsicKinds.has(kind || "");
87
+ }
88
+ // Small helpers for unions and alias naming
89
+ function isUnionType(t) {
90
+ return t?.kind === "union";
91
+ }
92
+ function unionOf(types) {
93
+ const flat = [];
94
+ const collect = (tt) => {
95
+ if (isUnionType(tt))
96
+ tt.members.forEach(collect);
97
+ else
98
+ flat.push(tt);
99
+ };
100
+ types.forEach(collect);
101
+ const seen = new Set();
102
+ const unique = [];
103
+ flat.forEach((m) => {
104
+ const key = m.name ||
105
+ m.value ||
106
+ m.kind + JSON.stringify(m);
107
+ if (!seen.has(key)) {
108
+ seen.add(key);
109
+ unique.push(m);
110
+ }
111
+ });
112
+ if (unique.length === 0)
113
+ return dom.type.any;
114
+ if (unique.length === 1)
115
+ return unique[0];
116
+ return dom.create.union(unique);
117
+ }
118
+ function setOf(inner) {
119
+ return {
120
+ kind: "name",
121
+ name: "Set",
122
+ typeArguments: [inner],
123
+ };
124
+ }
125
+ function recordOf(key, value) {
126
+ return {
127
+ kind: "name",
128
+ name: "Record",
129
+ typeArguments: [key, value],
130
+ };
131
+ }
132
+ function literalFromValueSetValue(value) {
133
+ if (typeof value === "string")
134
+ return value;
135
+ if (value && typeof value === "object") {
136
+ const candidate = value;
137
+ if (typeof candidate.value === "string")
138
+ return candidate.value;
139
+ if (typeof candidate.id === "string")
140
+ return candidate.id;
141
+ if (typeof candidate.languageTag === "string")
142
+ return candidate.languageTag;
143
+ if (typeof candidate.stem === "string")
144
+ return candidate.stem;
145
+ }
146
+ return undefined;
147
+ }
148
+ const extraTripleConstraints = new WeakSet();
149
+ function tagExtraPredicatesFromExpression(expression, extras) {
150
+ if (!expression || typeof expression !== "object")
151
+ return;
152
+ const exprType = expression.type;
153
+ if (exprType === "TripleConstraint") {
154
+ if (extras.has(expression.predicate)) {
155
+ extraTripleConstraints.add(expression);
156
+ }
157
+ return;
158
+ }
159
+ if (exprType === "EachOf" || exprType === "OneOf") {
160
+ (expression.expressions || []).forEach((child) => tagExtraPredicatesFromExpression(child, extras));
161
+ return;
162
+ }
163
+ if (exprType === "Shape") {
164
+ tagExtraPredicatesFromExpression(expression.expression, extras);
165
+ }
166
+ }
167
+ // Note: aliasing helpers previously used in earlier versions were removed.
168
+ // Property name collision resolution using predicate IRI mapping
169
+ const predicateIriByProp = new WeakMap();
170
+ // Note: collisions are handled by annotateReadablePredicates pre-pass.
171
+ // Merge duplicate properties without introducing LdSet. If a property appears multiple
172
+ // times (e.g., via EXTENDS or grouped expressions) we:
173
+ // - union the types (flattening existing unions)
174
+ // - if one side is Set<T> and the other is plain U, produce Set<T|U>
175
+ // - if both are Set<A>, Set<B> -> Set<A|B>
176
+ // - preserve optional flag if any occurrence optional
177
+ function dedupeCompactProperties(props) {
178
+ const isSetRef = (t) => t.kind === "name" && t.name === "Set";
179
+ const getSetInner = (t) => isSetRef(t) ? t.typeArguments[0] : t;
180
+ // Group by composite key (name + predicate IRI)
181
+ const groups = new Map();
182
+ for (const p of props) {
183
+ const pred = predicateIriByProp.get(p) || "";
184
+ const key = `${p.name}\u0000${pred}`;
185
+ if (!groups.has(key))
186
+ groups.set(key, []);
187
+ groups.get(key).push(p);
188
+ }
189
+ const merged = [];
190
+ for (const [, group] of groups) {
191
+ if (group.length === 1) {
192
+ merged.push(group[0]);
193
+ continue;
194
+ }
195
+ let acc = group[0];
196
+ for (let i = 1; i < group.length; i++) {
197
+ const next = group[i];
198
+ const accSet = isSetRef(acc.type);
199
+ const nextSet = isSetRef(next.type);
200
+ let mergedType;
201
+ if (accSet && nextSet) {
202
+ mergedType = setOf(unionOf([getSetInner(acc.type), getSetInner(next.type)]));
203
+ }
204
+ else if (accSet && !nextSet) {
205
+ mergedType = setOf(unionOf([getSetInner(acc.type), next.type]));
206
+ }
207
+ else if (!accSet && nextSet) {
208
+ mergedType = setOf(unionOf([acc.type, getSetInner(next.type)]));
209
+ }
210
+ else {
211
+ mergedType = unionOf([acc.type, next.type]);
212
+ }
213
+ const optional = acc.flags === dom.DeclarationFlags.Optional ||
214
+ next.flags === dom.DeclarationFlags.Optional
215
+ ? dom.DeclarationFlags.Optional
216
+ : dom.DeclarationFlags.None;
217
+ const mergedProp = dom.create.property(acc.name, mergedType, optional);
218
+ mergedProp.jsDocComment =
219
+ acc.jsDocComment && next.jsDocComment
220
+ ? `${acc.jsDocComment} | ${next.jsDocComment}`
221
+ : acc.jsDocComment || next.jsDocComment;
222
+ const pred = predicateIriByProp.get(acc) || predicateIriByProp.get(next);
223
+ if (pred)
224
+ predicateIriByProp.set(mergedProp, pred);
225
+ acc = mergedProp;
226
+ }
227
+ merged.push(acc);
228
+ }
229
+ return merged;
230
+ }
231
+ /** Add `@id` and `@graph` optional readonly props for nested objects */
232
+ function addIdAndGraphProperties(t) {
233
+ if (t?.kind === "object") {
234
+ const members = t.members;
235
+ if (!members)
236
+ return t;
237
+ const props = (members.filter?.((m) => m?.kind === "property") ||
238
+ []);
239
+ if (!props.some((m) => m.name === "@id")) {
240
+ members.unshift(dom.create.property("@id", dom.create.namedTypeReference("IRI"), dom.DeclarationFlags.Optional |
241
+ dom.DeclarationFlags.ReadOnly), dom.create.property("@graph", dom.create.namedTypeReference("IRI"), dom.DeclarationFlags.Optional |
242
+ dom.DeclarationFlags.ReadOnly));
243
+ }
244
+ }
245
+ return t;
246
+ }
247
+ function addIdAndGraphIriToUnionObjects(t) {
248
+ if (!isUnionType(t))
249
+ return t;
250
+ const members = t.members.map((m) => m?.kind === "object" ? addIdAndGraphProperties(m) : m);
251
+ return dom.create.union(members);
252
+ }
253
+ // Create property and attach predicate IRI and annotations consistently
254
+ function createProperty(name, type, flags, predicateIri, annotations) {
255
+ const prop = dom.create.property(name, type, flags);
256
+ if (predicateIri)
257
+ predicateIriByProp.set(prop, predicateIri);
258
+ const cmt = commentFromAnnotations(annotations) || "";
259
+ prop.jsDocComment = cmt
260
+ ? `${cmt}\n\nOriginal IRI: ${predicateIri ?? ""}`.trim()
261
+ : `Original IRI: ${predicateIri ?? ""}`;
262
+ return prop;
263
+ }
264
+ export const ShexJTypingTransformerCompact = ShexJTraverser.createTransformer({
265
+ // Transformer from Schema to interfaces
266
+ Schema: {
267
+ transformer: async (_schema, getTransformedChildren) => {
268
+ const transformedChildren = await getTransformedChildren();
269
+ const interfaces = [];
270
+ transformedChildren.shapes?.forEach((shape) => {
271
+ if (typeof shape !== "string" &&
272
+ shape.kind === "interface") {
273
+ interfaces.push(shape);
274
+ }
275
+ });
276
+ return interfaces;
277
+ },
278
+ },
279
+ // Transformer from ShapeDecl to interface
280
+ ShapeDecl: {
281
+ transformer: async (shapeDecl, getTransformedChildren) => {
282
+ const shapeName = nameFromAnnotationOrId(shapeDecl) || "Shape";
283
+ const { shapeExpr } = await getTransformedChildren();
284
+ if (shapeExpr.kind === "interface") {
285
+ const shapeInterface = shapeExpr;
286
+ shapeInterface.name = shapeName;
287
+ // Preserve shape id for downstream shapeTypes generation
288
+ shapeInterface.shapeId = shapeDecl.id;
289
+ // Ensure root-level @id and @graph are present as readonly (mandatory)
290
+ const hasId = shapeInterface.members.find((m) => m.kind === "property" && m.name === "@id");
291
+ const hasGraph = shapeInterface.members.find((m) => m.kind === "property" && m.name === "@graph");
292
+ if (!hasId || !hasGraph) {
293
+ const propsToAdd = [];
294
+ if (!hasGraph) {
295
+ const graphProp = dom.create.property("@graph", dom.create.namedTypeReference("IRI"), dom.DeclarationFlags.ReadOnly);
296
+ graphProp.jsDocComment = "The graph IRI.";
297
+ propsToAdd.push(graphProp);
298
+ }
299
+ if (!hasId) {
300
+ const idProp = dom.create.property("@id", dom.create.namedTypeReference("IRI"), dom.DeclarationFlags.ReadOnly);
301
+ idProp.jsDocComment = "The subject IRI.";
302
+ propsToAdd.push(idProp);
303
+ }
304
+ shapeInterface.members.unshift(...propsToAdd);
305
+ }
306
+ return shapeInterface;
307
+ }
308
+ throw new Error("Unsupported direct shape expression on ShapeDecl for compact format.");
309
+ },
310
+ },
311
+ // Transformer from Shape to interface
312
+ Shape: {
313
+ transformer: async (_shape, getTransformedChildren, setReturnPointer) => {
314
+ const newInterface = dom.create.interface("");
315
+ setReturnPointer(newInterface);
316
+ if (_shape.extra?.length ?? 0 > 0) {
317
+ tagExtraPredicatesFromExpression(_shape.expression, new Set(_shape.extra));
318
+ }
319
+ const transformedChildren = await getTransformedChildren();
320
+ if (typeof transformedChildren.expression !== "string" &&
321
+ transformedChildren.expression &&
322
+ (transformedChildren.expression.kind ===
323
+ "object" ||
324
+ transformedChildren.expression
325
+ .kind === "interface")) {
326
+ newInterface.members.push(...transformedChildren.expression
327
+ .members);
328
+ }
329
+ else if (transformedChildren.expression
330
+ ?.kind === "property") {
331
+ newInterface.members.push(transformedChildren.expression);
332
+ }
333
+ if (transformedChildren.extends) {
334
+ transformedChildren.extends.forEach((ext) => {
335
+ const extInt = ext;
336
+ if (extInt.kind === "interface") {
337
+ const merged = [
338
+ ...extInt.members.filter((m) => !(m.kind === "property" && m.name === "@id")),
339
+ ...newInterface.members,
340
+ ].filter((m) => m.kind === "property");
341
+ newInterface.members = dedupeCompactProperties(merged);
342
+ }
343
+ });
344
+ }
345
+ // Final pass: ensure only a single @id and a single @graph property, normalize to readonly
346
+ const idSeen = new Set();
347
+ const graphSeen = new Set();
348
+ newInterface.members = newInterface.members.filter((m, idx) => {
349
+ if (m.kind !== "property")
350
+ return true;
351
+ if (m.name === "@id") {
352
+ if (idSeen.size === 0) {
353
+ idSeen.add(idx);
354
+ // normalize id type to IRI and make readonly
355
+ m.type = dom.create.namedTypeReference("IRI");
356
+ m.flags = dom.DeclarationFlags.ReadOnly;
357
+ return true;
358
+ }
359
+ return false;
360
+ }
361
+ if (m.name === "@graph") {
362
+ if (graphSeen.size === 0) {
363
+ graphSeen.add(idx);
364
+ // normalize graph type to IRI and make readonly
365
+ m.type = dom.create.namedTypeReference("IRI");
366
+ m.flags = dom.DeclarationFlags.ReadOnly;
367
+ return true;
368
+ }
369
+ return false;
370
+ }
371
+ return true;
372
+ });
373
+ return newInterface;
374
+ },
375
+ },
376
+ // Transformer from EachOf to object type. EachOf contains the `expressions` array of properties (TripleConstraint)
377
+ EachOf: {
378
+ transformer: async (eachOf, getTransformedChildren, setReturnPointer) => {
379
+ const transformedChildren = await getTransformedChildren();
380
+ const name = nameFromAnnotationOrId(eachOf);
381
+ const objectType = name
382
+ ? dom.create.interface(name)
383
+ : dom.create.objectType([]);
384
+ setReturnPointer(objectType);
385
+ const inputProps = [];
386
+ transformedChildren.expressions.forEach((expr) => {
387
+ if (!expr || typeof expr === "string")
388
+ return;
389
+ const kind = expr.kind;
390
+ if (kind === "property") {
391
+ inputProps.push(expr);
392
+ }
393
+ else if (kind === "object" || kind === "interface") {
394
+ const mlist = expr.members;
395
+ mlist.forEach((m) => {
396
+ if (m.kind === "property") {
397
+ inputProps.push(m);
398
+ }
399
+ });
400
+ }
401
+ });
402
+ const deduped = dedupeCompactProperties(inputProps);
403
+ objectType.members.push(...deduped);
404
+ return objectType;
405
+ },
406
+ },
407
+ // Transformer from triple constraints to type properties.
408
+ TripleConstraint: {
409
+ transformer: async (tripleConstraint, getTransformedChildren, _setReturnPointer, _node) => {
410
+ const transformedChildren = await getTransformedChildren();
411
+ const baseName = tripleConstraint
412
+ .readablePredicate;
413
+ const max = tripleConstraint.max;
414
+ const isExtra = extraTripleConstraints.has(tripleConstraint);
415
+ const isPlural = isExtra || max === -1 || (max !== undefined && max !== 1);
416
+ const isOptional = tripleConstraint.min === 0 && tripleConstraint.max == 1;
417
+ let valueType = dom.type.any;
418
+ if (transformedChildren.valueExpr)
419
+ valueType = transformedChildren.valueExpr;
420
+ // Generic: If valueExpr is a NodeConstraint with concrete `values`,
421
+ // build a union of named alias references derived from those values.
422
+ // Works for any predicate (not only rdf:type).
423
+ const originalValueExpr = tripleConstraint?.valueExpr;
424
+ if (originalValueExpr &&
425
+ typeof originalValueExpr === "object" &&
426
+ originalValueExpr.type === "NodeConstraint" &&
427
+ Array.isArray(originalValueExpr.values) &&
428
+ originalValueExpr.values.length > 0) {
429
+ const aliasRefs = [];
430
+ for (const v of originalValueExpr.values) {
431
+ const literalVal = literalFromValueSetValue(v);
432
+ if (literalVal !== undefined) {
433
+ aliasRefs.push(dom.type.stringLiteral(literalVal));
434
+ }
435
+ }
436
+ if (aliasRefs.length > 0) {
437
+ let union = unionOf(aliasRefs);
438
+ if (isExtra) {
439
+ // Type like (string & {}), to preserve literal values.
440
+ const intersectedString = dom.create.intersection([
441
+ dom.create.namedTypeReference("IRI"),
442
+ dom.create.objectType([]),
443
+ ]);
444
+ union = unionOf([union, intersectedString]);
445
+ }
446
+ const final = isPlural ? setOf(union) : union;
447
+ return createProperty(baseName, final, isOptional
448
+ ? dom.DeclarationFlags.Optional
449
+ : dom.DeclarationFlags.None, tripleConstraint.predicate, tripleConstraint.annotations);
450
+ }
451
+ }
452
+ if (valueType.kind === "interface" &&
453
+ !valueType.name) {
454
+ valueType = dom.create.objectType(valueType
455
+ .members);
456
+ }
457
+ // Normalize NodeConstraint returned object forms for IRIs into IRI
458
+ // Heuristic: existing transformer (compact) returns string/number/boolean OR object/interface.
459
+ // We treat any simple string/number/boolean/name as primitive.
460
+ // Determine category
461
+ const objLike = isObjectLike(valueType);
462
+ const isUnion = valueType?.kind === "union";
463
+ const unionMembers = isUnion
464
+ ? valueType.members
465
+ : [];
466
+ const unionAllObjLike = isUnion &&
467
+ unionMembers.length > 0 &&
468
+ unionMembers.every(isObjectLike);
469
+ const primLike = isPrimitiveLike(valueType);
470
+ if (!primLike &&
471
+ !objLike &&
472
+ valueType.kind === "union") {
473
+ const u = valueType;
474
+ const hasObj = u.members.some(isObjectLike);
475
+ const hasPrim = u.members.some(isPrimitiveLike);
476
+ if (isPlural && hasObj && hasPrim) {
477
+ throw new Error(`Mixed plural union (object + primitive) not supported for predicate ${tripleConstraint.predicate}`);
478
+ }
479
+ }
480
+ let finalType;
481
+ if (isPlural) {
482
+ if (objLike || unionAllObjLike) {
483
+ if (valueType.kind ===
484
+ "interface" &&
485
+ valueType.name) {
486
+ const ifaceName = valueType.name;
487
+ // Set of full object instances
488
+ finalType = setOf(dom.create.namedTypeReference(ifaceName));
489
+ }
490
+ else {
491
+ // Anonymous object or union of anonymous/interface objects
492
+ let valueForSet = valueType;
493
+ if (unionAllObjLike) {
494
+ // Ensure each union member has @id and @graph as optional readonly
495
+ valueForSet =
496
+ addIdAndGraphIriToUnionObjects(valueType);
497
+ }
498
+ else {
499
+ valueForSet = addIdAndGraphProperties(valueType);
500
+ }
501
+ finalType = setOf(valueForSet);
502
+ }
503
+ }
504
+ else {
505
+ finalType = setOf(valueType);
506
+ }
507
+ }
508
+ else {
509
+ // Singular
510
+ // If anonymous object or union of object-like types, ensure id: IRI is present (mandatory)
511
+ if (objLike) {
512
+ if (valueType.kind === "object") {
513
+ valueType = addIdAndGraphProperties(valueType);
514
+ }
515
+ }
516
+ else if (isUnion && unionAllObjLike) {
517
+ valueType = addIdAndGraphIriToUnionObjects(valueType);
518
+ }
519
+ // Singular: always the interface/object type itself (never Id union)
520
+ if (valueType.kind ===
521
+ "interface" &&
522
+ valueType.name) {
523
+ finalType = dom.create.namedTypeReference(valueType.name);
524
+ }
525
+ else {
526
+ finalType = valueType;
527
+ }
528
+ }
529
+ return createProperty(baseName, finalType, isOptional
530
+ ? dom.DeclarationFlags.Optional
531
+ : dom.DeclarationFlags.None, tripleConstraint.predicate, tripleConstraint.annotations);
532
+ },
533
+ },
534
+ // Transformer from node constraint to type
535
+ NodeConstraint: {
536
+ transformer: async (nodeConstraint) => {
537
+ if (nodeConstraint.datatype) {
538
+ switch (nodeConstraint.datatype) {
539
+ case "http://www.w3.org/2001/XMLSchema#boolean":
540
+ return dom.type.boolean;
541
+ case "http://www.w3.org/2001/XMLSchema#byte":
542
+ case "http://www.w3.org/2001/XMLSchema#decimal":
543
+ case "http://www.w3.org/2001/XMLSchema#double":
544
+ case "http://www.w3.org/2001/XMLSchema#float":
545
+ case "http://www.w3.org/2001/XMLSchema#int":
546
+ case "http://www.w3.org/2001/XMLSchema#integer":
547
+ case "http://www.w3.org/2001/XMLSchema#long":
548
+ case "http://www.w3.org/2001/XMLSchema#negativeInteger":
549
+ case "http://www.w3.org/2001/XMLSchema#nonNegativeInteger":
550
+ case "http://www.w3.org/2001/XMLSchema#nonPositiveInteger":
551
+ case "http://www.w3.org/2001/XMLSchema#positiveInteger":
552
+ case "http://www.w3.org/2001/XMLSchema#short":
553
+ case "http://www.w3.org/2001/XMLSchema#unsignedLong":
554
+ case "http://www.w3.org/2001/XMLSchema#unsignedInt":
555
+ case "http://www.w3.org/2001/XMLSchema#unsignedShort":
556
+ case "http://www.w3.org/2001/XMLSchema#unsignedByte":
557
+ return dom.type.number;
558
+ default:
559
+ return dom.type.string; // treat most as string
560
+ }
561
+ }
562
+ if (nodeConstraint.nodeKind) {
563
+ switch (nodeConstraint.nodeKind) {
564
+ case "iri":
565
+ return dom.create.namedTypeReference("IRI");
566
+ case "bnode":
567
+ return dom.type.string; // opaque id as string
568
+ case "nonliteral":
569
+ return dom.create.namedTypeReference("IRI");
570
+ case "literal":
571
+ default:
572
+ return dom.type.string;
573
+ }
574
+ }
575
+ if (nodeConstraint.values) {
576
+ const union = dom.create.union([]);
577
+ nodeConstraint.values.forEach((v) => {
578
+ const literalVal = literalFromValueSetValue(v);
579
+ if (literalVal !== undefined) {
580
+ union.members.push(dom.type.stringLiteral(literalVal));
581
+ }
582
+ });
583
+ if (!union.members.length)
584
+ return dom.type.string;
585
+ if (union.members.length === 1)
586
+ return union.members[0];
587
+ return union;
588
+ }
589
+ return dom.type.any;
590
+ },
591
+ },
592
+ // Transformer from ShapeOr to union type
593
+ ShapeOr: {
594
+ transformer: async (_shapeOr, getTransformedChildren) => {
595
+ const tc = await getTransformedChildren();
596
+ return dom.create.union(tc.shapeExprs);
597
+ },
598
+ },
599
+ // Transformer from ShapeAnd to intersection type
600
+ ShapeAnd: {
601
+ transformer: async (_shapeAnd, getTransformedChildren) => {
602
+ const tc = await getTransformedChildren();
603
+ const valid = [];
604
+ tc.shapeExprs.forEach((t) => {
605
+ if (typeof t === "object")
606
+ valid.push(t);
607
+ });
608
+ return dom.create.intersection(valid);
609
+ },
610
+ },
611
+ // Transformer from ShapeNot to type - not supported.
612
+ ShapeNot: {
613
+ transformer: async () => {
614
+ throw new Error("ShapeNot not supported (compact)");
615
+ },
616
+ },
617
+ // Transformer from ShapeExternal to type - not supported.
618
+ ShapeExternal: {
619
+ transformer: async () => {
620
+ throw new Error("ShapeExternal not supported (compact)");
621
+ },
622
+ },
623
+ });
@@ -0,0 +1,5 @@
1
+ import type { InterfaceDeclaration } from "dts-dom";
2
+ export interface ShapeInterfaceDeclaration extends InterfaceDeclaration {
3
+ shapeId?: string;
4
+ }
5
+ //# sourceMappingURL=ShapeInterfaceDeclaration.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ShapeInterfaceDeclaration.d.ts","sourceRoot":"","sources":["../../../src/schema-converter/util/ShapeInterfaceDeclaration.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAEpD,MAAM,WAAW,yBAA0B,SAAQ,oBAAoB;IACrE,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB"}
@@ -0,0 +1,8 @@
1
+ import type { Schema } from "shexj";
2
+ /**
3
+ * Annotate EachOf-level TripleConstraints with a collision-free readablePredicate.
4
+ * Rule: for any group that shares the same local token, rename all members using
5
+ * prefix-first `${prefix}_${local}` from right to left; fallback to composite.
6
+ */
7
+ export default function annotateReadablePredicates(schema: Schema): void;
8
+ //# sourceMappingURL=annotateReadablePredicates.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"annotateReadablePredicates.d.ts","sourceRoot":"","sources":["../../../src/schema-converter/util/annotateReadablePredicates.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,MAAM,EAA8C,MAAM,OAAO,CAAC;AAUhF;;;;GAIG;AACH,MAAM,CAAC,OAAO,UAAU,0BAA0B,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAmJvE"}