@_linked/core 2.12.0 → 2.13.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.
Files changed (246) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/lib/esm/queries/IRPipeline.d.ts +7 -1
  3. package/lib/esm/queries/IRPipeline.js +20 -6
  4. package/lib/esm/queries/IRPipeline.js.map +1 -1
  5. package/lib/esm/queries/queryDispatch.js +12 -2
  6. package/lib/esm/queries/queryDispatch.js.map +1 -1
  7. package/package.json +10 -13
  8. package/lib/cjs/collections/CoreSet.d.ts +0 -47
  9. package/lib/cjs/collections/CoreSet.js +0 -136
  10. package/lib/cjs/collections/CoreSet.js.map +0 -1
  11. package/lib/cjs/collections/ShapeSet.d.ts +0 -6
  12. package/lib/cjs/collections/ShapeSet.js +0 -20
  13. package/lib/cjs/collections/ShapeSet.js.map +0 -1
  14. package/lib/cjs/expressions/Expr.d.ts +0 -29
  15. package/lib/cjs/expressions/Expr.js +0 -80
  16. package/lib/cjs/expressions/Expr.js.map +0 -1
  17. package/lib/cjs/expressions/ExpressionMethods.d.ts +0 -85
  18. package/lib/cjs/expressions/ExpressionMethods.js +0 -3
  19. package/lib/cjs/expressions/ExpressionMethods.js.map +0 -1
  20. package/lib/cjs/expressions/ExpressionNode.d.ts +0 -144
  21. package/lib/cjs/expressions/ExpressionNode.js +0 -432
  22. package/lib/cjs/expressions/ExpressionNode.js.map +0 -1
  23. package/lib/cjs/index.d.ts +0 -29
  24. package/lib/cjs/index.js +0 -65
  25. package/lib/cjs/index.js.map +0 -1
  26. package/lib/cjs/interfaces/ICoreIterable.d.ts +0 -14
  27. package/lib/cjs/interfaces/ICoreIterable.js +0 -3
  28. package/lib/cjs/interfaces/ICoreIterable.js.map +0 -1
  29. package/lib/cjs/interfaces/IDataset.d.ts +0 -26
  30. package/lib/cjs/interfaces/IDataset.js +0 -3
  31. package/lib/cjs/interfaces/IDataset.js.map +0 -1
  32. package/lib/cjs/interfaces/IFileStore.d.ts +0 -16
  33. package/lib/cjs/interfaces/IFileStore.js +0 -3
  34. package/lib/cjs/interfaces/IFileStore.js.map +0 -1
  35. package/lib/cjs/ontologies/linked-core.d.ts +0 -15
  36. package/lib/cjs/ontologies/linked-core.js +0 -38
  37. package/lib/cjs/ontologies/linked-core.js.map +0 -1
  38. package/lib/cjs/ontologies/npm.d.ts +0 -6
  39. package/lib/cjs/ontologies/npm.js +0 -15
  40. package/lib/cjs/ontologies/npm.js.map +0 -1
  41. package/lib/cjs/ontologies/owl.d.ts +0 -14
  42. package/lib/cjs/ontologies/owl.js +0 -21
  43. package/lib/cjs/ontologies/owl.js.map +0 -1
  44. package/lib/cjs/ontologies/rdf.d.ts +0 -13
  45. package/lib/cjs/ontologies/rdf.js +0 -27
  46. package/lib/cjs/ontologies/rdf.js.map +0 -1
  47. package/lib/cjs/ontologies/rdfs.d.ts +0 -16
  48. package/lib/cjs/ontologies/rdfs.js +0 -33
  49. package/lib/cjs/ontologies/rdfs.js.map +0 -1
  50. package/lib/cjs/ontologies/shacl.d.ts +0 -103
  51. package/lib/cjs/ontologies/shacl.js +0 -152
  52. package/lib/cjs/ontologies/shacl.js.map +0 -1
  53. package/lib/cjs/ontologies/xsd.d.ts +0 -19
  54. package/lib/cjs/ontologies/xsd.js +0 -41
  55. package/lib/cjs/ontologies/xsd.js.map +0 -1
  56. package/lib/cjs/package.d.ts +0 -4
  57. package/lib/cjs/package.js +0 -6
  58. package/lib/cjs/package.js.map +0 -1
  59. package/lib/cjs/package.json +0 -9
  60. package/lib/cjs/paths/PropertyPathExpr.d.ts +0 -38
  61. package/lib/cjs/paths/PropertyPathExpr.js +0 -221
  62. package/lib/cjs/paths/PropertyPathExpr.js.map +0 -1
  63. package/lib/cjs/paths/normalizePropertyPath.d.ts +0 -23
  64. package/lib/cjs/paths/normalizePropertyPath.js +0 -75
  65. package/lib/cjs/paths/normalizePropertyPath.js.map +0 -1
  66. package/lib/cjs/paths/pathExprToSparql.d.ts +0 -14
  67. package/lib/cjs/paths/pathExprToSparql.js +0 -136
  68. package/lib/cjs/paths/pathExprToSparql.js.map +0 -1
  69. package/lib/cjs/queries/ContextRef.d.ts +0 -32
  70. package/lib/cjs/queries/ContextRef.js +0 -69
  71. package/lib/cjs/queries/ContextRef.js.map +0 -1
  72. package/lib/cjs/queries/CreateBuilder.d.ts +0 -59
  73. package/lib/cjs/queries/CreateBuilder.js +0 -138
  74. package/lib/cjs/queries/CreateBuilder.js.map +0 -1
  75. package/lib/cjs/queries/CreateQuery.d.ts +0 -20
  76. package/lib/cjs/queries/CreateQuery.js +0 -3
  77. package/lib/cjs/queries/CreateQuery.js.map +0 -1
  78. package/lib/cjs/queries/DeleteBuilder.d.ts +0 -56
  79. package/lib/cjs/queries/DeleteBuilder.js +0 -172
  80. package/lib/cjs/queries/DeleteBuilder.js.map +0 -1
  81. package/lib/cjs/queries/DeleteQuery.d.ts +0 -37
  82. package/lib/cjs/queries/DeleteQuery.js +0 -3
  83. package/lib/cjs/queries/DeleteQuery.js.map +0 -1
  84. package/lib/cjs/queries/DslJsonExpression.d.ts +0 -68
  85. package/lib/cjs/queries/DslJsonExpression.js +0 -427
  86. package/lib/cjs/queries/DslJsonExpression.js.map +0 -1
  87. package/lib/cjs/queries/FieldSet.d.ts +0 -310
  88. package/lib/cjs/queries/FieldSet.js +0 -802
  89. package/lib/cjs/queries/FieldSet.js.map +0 -1
  90. package/lib/cjs/queries/IRAliasScope.d.ts +0 -20
  91. package/lib/cjs/queries/IRAliasScope.js +0 -52
  92. package/lib/cjs/queries/IRAliasScope.js.map +0 -1
  93. package/lib/cjs/queries/IRCanonicalize.d.ts +0 -19
  94. package/lib/cjs/queries/IRCanonicalize.js +0 -19
  95. package/lib/cjs/queries/IRCanonicalize.js.map +0 -1
  96. package/lib/cjs/queries/IRDesugar.d.ts +0 -123
  97. package/lib/cjs/queries/IRDesugar.js +0 -261
  98. package/lib/cjs/queries/IRDesugar.js.map +0 -1
  99. package/lib/cjs/queries/IRLower.d.ts +0 -25
  100. package/lib/cjs/queries/IRLower.js +0 -398
  101. package/lib/cjs/queries/IRLower.js.map +0 -1
  102. package/lib/cjs/queries/IRMutation.d.ts +0 -53
  103. package/lib/cjs/queries/IRMutation.js +0 -130
  104. package/lib/cjs/queries/IRMutation.js.map +0 -1
  105. package/lib/cjs/queries/IRPipeline.d.ts +0 -8
  106. package/lib/cjs/queries/IRPipeline.js +0 -25
  107. package/lib/cjs/queries/IRPipeline.js.map +0 -1
  108. package/lib/cjs/queries/IRProjection.d.ts +0 -39
  109. package/lib/cjs/queries/IRProjection.js +0 -105
  110. package/lib/cjs/queries/IRProjection.js.map +0 -1
  111. package/lib/cjs/queries/IntermediateRepresentation.d.ts +0 -282
  112. package/lib/cjs/queries/IntermediateRepresentation.js +0 -3
  113. package/lib/cjs/queries/IntermediateRepresentation.js.map +0 -1
  114. package/lib/cjs/queries/MutationQuery.d.ts +0 -50
  115. package/lib/cjs/queries/MutationQuery.js +0 -334
  116. package/lib/cjs/queries/MutationQuery.js.map +0 -1
  117. package/lib/cjs/queries/MutationSerialization.d.ts +0 -102
  118. package/lib/cjs/queries/MutationSerialization.js +0 -207
  119. package/lib/cjs/queries/MutationSerialization.js.map +0 -1
  120. package/lib/cjs/queries/MutationThenable.d.ts +0 -18
  121. package/lib/cjs/queries/MutationThenable.js +0 -32
  122. package/lib/cjs/queries/MutationThenable.js.map +0 -1
  123. package/lib/cjs/queries/PropertyPath.d.ts +0 -38
  124. package/lib/cjs/queries/PropertyPath.js +0 -82
  125. package/lib/cjs/queries/PropertyPath.js.map +0 -1
  126. package/lib/cjs/queries/ProxiedPathBuilder.d.ts +0 -14
  127. package/lib/cjs/queries/ProxiedPathBuilder.js +0 -29
  128. package/lib/cjs/queries/ProxiedPathBuilder.js.map +0 -1
  129. package/lib/cjs/queries/QueryBuilder.d.ts +0 -193
  130. package/lib/cjs/queries/QueryBuilder.js +0 -519
  131. package/lib/cjs/queries/QueryBuilder.js.map +0 -1
  132. package/lib/cjs/queries/QueryBuilderSerialization.d.ts +0 -31
  133. package/lib/cjs/queries/QueryBuilderSerialization.js +0 -68
  134. package/lib/cjs/queries/QueryBuilderSerialization.js.map +0 -1
  135. package/lib/cjs/queries/QueryContext.d.ts +0 -50
  136. package/lib/cjs/queries/QueryContext.js +0 -147
  137. package/lib/cjs/queries/QueryContext.js.map +0 -1
  138. package/lib/cjs/queries/QueryFactory.d.ts +0 -80
  139. package/lib/cjs/queries/QueryFactory.js +0 -21
  140. package/lib/cjs/queries/QueryFactory.js.map +0 -1
  141. package/lib/cjs/queries/SelectQuery.d.ts +0 -302
  142. package/lib/cjs/queries/SelectQuery.js +0 -761
  143. package/lib/cjs/queries/SelectQuery.js.map +0 -1
  144. package/lib/cjs/queries/UpdateBuilder.d.ts +0 -69
  145. package/lib/cjs/queries/UpdateBuilder.js +0 -199
  146. package/lib/cjs/queries/UpdateBuilder.js.map +0 -1
  147. package/lib/cjs/queries/UpdateQuery.d.ts +0 -18
  148. package/lib/cjs/queries/UpdateQuery.js +0 -3
  149. package/lib/cjs/queries/UpdateQuery.js.map +0 -1
  150. package/lib/cjs/queries/fromJSON.d.ts +0 -16
  151. package/lib/cjs/queries/fromJSON.js +0 -41
  152. package/lib/cjs/queries/fromJSON.js.map +0 -1
  153. package/lib/cjs/queries/lower.d.ts +0 -28
  154. package/lib/cjs/queries/lower.js +0 -114
  155. package/lib/cjs/queries/lower.js.map +0 -1
  156. package/lib/cjs/queries/lowerMutationJSON.d.ts +0 -25
  157. package/lib/cjs/queries/lowerMutationJSON.js +0 -173
  158. package/lib/cjs/queries/lowerMutationJSON.js.map +0 -1
  159. package/lib/cjs/queries/mutationLowerSpec.d.ts +0 -32
  160. package/lib/cjs/queries/mutationLowerSpec.js +0 -8
  161. package/lib/cjs/queries/mutationLowerSpec.js.map +0 -1
  162. package/lib/cjs/queries/queryDispatch.d.ts +0 -33
  163. package/lib/cjs/queries/queryDispatch.js +0 -33
  164. package/lib/cjs/queries/queryDispatch.js.map +0 -1
  165. package/lib/cjs/queries/resolveShape.d.ts +0 -10
  166. package/lib/cjs/queries/resolveShape.js +0 -23
  167. package/lib/cjs/queries/resolveShape.js.map +0 -1
  168. package/lib/cjs/queries/wireVersion.d.ts +0 -7
  169. package/lib/cjs/queries/wireVersion.js +0 -25
  170. package/lib/cjs/queries/wireVersion.js.map +0 -1
  171. package/lib/cjs/shapes/List.d.ts +0 -35
  172. package/lib/cjs/shapes/List.js +0 -72
  173. package/lib/cjs/shapes/List.js.map +0 -1
  174. package/lib/cjs/shapes/PathNode.d.ts +0 -20
  175. package/lib/cjs/shapes/PathNode.js +0 -68
  176. package/lib/cjs/shapes/PathNode.js.map +0 -1
  177. package/lib/cjs/shapes/SHACL.d.ts +0 -300
  178. package/lib/cjs/shapes/SHACL.js +0 -612
  179. package/lib/cjs/shapes/SHACL.js.map +0 -1
  180. package/lib/cjs/shapes/Shape.d.ts +0 -74
  181. package/lib/cjs/shapes/Shape.js +0 -124
  182. package/lib/cjs/shapes/Shape.js.map +0 -1
  183. package/lib/cjs/shapes/serializePathToNodeData.d.ts +0 -24
  184. package/lib/cjs/shapes/serializePathToNodeData.js +0 -67
  185. package/lib/cjs/shapes/serializePathToNodeData.js.map +0 -1
  186. package/lib/cjs/shapes/syncShapes.d.ts +0 -38
  187. package/lib/cjs/shapes/syncShapes.js +0 -214
  188. package/lib/cjs/shapes/syncShapes.js.map +0 -1
  189. package/lib/cjs/sparql/SparqlAlgebra.d.ts +0 -190
  190. package/lib/cjs/sparql/SparqlAlgebra.js +0 -4
  191. package/lib/cjs/sparql/SparqlAlgebra.js.map +0 -1
  192. package/lib/cjs/sparql/SparqlDataset.d.ts +0 -60
  193. package/lib/cjs/sparql/SparqlDataset.js +0 -117
  194. package/lib/cjs/sparql/SparqlDataset.js.map +0 -1
  195. package/lib/cjs/sparql/algebraToString.d.ts +0 -13
  196. package/lib/cjs/sparql/algebraToString.js +0 -385
  197. package/lib/cjs/sparql/algebraToString.js.map +0 -1
  198. package/lib/cjs/sparql/index.d.ts +0 -9
  199. package/lib/cjs/sparql/index.js +0 -41
  200. package/lib/cjs/sparql/index.js.map +0 -1
  201. package/lib/cjs/sparql/irToAlgebra.d.ts +0 -79
  202. package/lib/cjs/sparql/irToAlgebra.js +0 -2042
  203. package/lib/cjs/sparql/irToAlgebra.js.map +0 -1
  204. package/lib/cjs/sparql/resultMapping.d.ts +0 -36
  205. package/lib/cjs/sparql/resultMapping.js +0 -563
  206. package/lib/cjs/sparql/resultMapping.js.map +0 -1
  207. package/lib/cjs/sparql/sparqlUtils.d.ts +0 -53
  208. package/lib/cjs/sparql/sparqlUtils.js +0 -154
  209. package/lib/cjs/sparql/sparqlUtils.js.map +0 -1
  210. package/lib/cjs/utils/LinkedErrorLogging.d.ts +0 -13
  211. package/lib/cjs/utils/LinkedErrorLogging.js +0 -22
  212. package/lib/cjs/utils/LinkedErrorLogging.js.map +0 -1
  213. package/lib/cjs/utils/LinkedFileStorage.d.ts +0 -23
  214. package/lib/cjs/utils/LinkedFileStorage.js +0 -62
  215. package/lib/cjs/utils/LinkedFileStorage.js.map +0 -1
  216. package/lib/cjs/utils/LinkedStorage.d.ts +0 -40
  217. package/lib/cjs/utils/LinkedStorage.js +0 -148
  218. package/lib/cjs/utils/LinkedStorage.js.map +0 -1
  219. package/lib/cjs/utils/NameSpace.d.ts +0 -2
  220. package/lib/cjs/utils/NameSpace.js +0 -8
  221. package/lib/cjs/utils/NameSpace.js.map +0 -1
  222. package/lib/cjs/utils/NodeReference.d.ts +0 -30
  223. package/lib/cjs/utils/NodeReference.js +0 -54
  224. package/lib/cjs/utils/NodeReference.js.map +0 -1
  225. package/lib/cjs/utils/Package.d.ts +0 -153
  226. package/lib/cjs/utils/Package.js +0 -419
  227. package/lib/cjs/utils/Package.js.map +0 -1
  228. package/lib/cjs/utils/Prefix.d.ts +0 -22
  229. package/lib/cjs/utils/Prefix.js +0 -104
  230. package/lib/cjs/utils/Prefix.js.map +0 -1
  231. package/lib/cjs/utils/ShapeClass.d.ts +0 -30
  232. package/lib/cjs/utils/ShapeClass.js +0 -180
  233. package/lib/cjs/utils/ShapeClass.js.map +0 -1
  234. package/lib/cjs/utils/URI.d.ts +0 -18
  235. package/lib/cjs/utils/URI.js +0 -42
  236. package/lib/cjs/utils/URI.js.map +0 -1
  237. package/lib/cjs/utils/cached.d.ts +0 -14
  238. package/lib/cjs/utils/cached.js +0 -71
  239. package/lib/cjs/utils/cached.js.map +0 -1
  240. package/lib/cjs/utils/loadStores.d.ts +0 -34
  241. package/lib/cjs/utils/loadStores.js +0 -105
  242. package/lib/cjs/utils/loadStores.js.map +0 -1
  243. package/lib/cjs/utils/parseDatasetsConfig.d.ts +0 -49
  244. package/lib/cjs/utils/parseDatasetsConfig.js +0 -110
  245. package/lib/cjs/utils/parseDatasetsConfig.js.map +0 -1
  246. package/lib/esm/package.json +0 -9
@@ -1,802 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.FieldSet = void 0;
4
- const PropertyPath_js_1 = require("./PropertyPath.js");
5
- const ShapeClass_js_1 = require("../utils/ShapeClass.js");
6
- const ProxiedPathBuilder_js_1 = require("./ProxiedPathBuilder.js");
7
- const ExpressionNode_js_1 = require("../expressions/ExpressionNode.js");
8
- const DslJsonExpression_js_1 = require("./DslJsonExpression.js");
9
- const QueryBuilderSerialization_js_1 = require("./QueryBuilderSerialization.js");
10
- const isQueryBuilderObject = (obj) => obj !== null &&
11
- typeof obj === 'object' &&
12
- 'property' in obj &&
13
- 'subject' in obj &&
14
- typeof obj.getPropertyPath === 'function';
15
- const isSetSize = (obj) => obj !== null &&
16
- typeof obj === 'object' &&
17
- 'subject' in obj &&
18
- typeof obj.as === 'function' &&
19
- typeof obj.getPropertyPath === 'function' &&
20
- // SetSize has a 'countable' field (may be undefined) and 'label' field
21
- 'label' in obj;
22
- // BoundComponent: has .source (QueryBuilderObject) and .originalValue (component-like)
23
- const isBoundComponent = (obj) => obj !== null &&
24
- typeof obj === 'object' &&
25
- 'source' in obj &&
26
- 'originalValue' in obj;
27
- /** Option keys reserved inside a relation options object (never a relation path). */
28
- const RELATION_OPTION_KEYS = new Set([
29
- 'as',
30
- 'where',
31
- 'whereIndex',
32
- 'aggregation',
33
- 'customKey',
34
- 'limit',
35
- 'offset',
36
- 'orderBy',
37
- 'fields',
38
- ]);
39
- /**
40
- * An immutable, composable collection of property paths for a shape.
41
- *
42
- * FieldSet describes which properties to select, independent of
43
- * how the query is built. It integrates with QueryBuilder via
44
- * `.select(fieldSet)`.
45
- *
46
- * Every mutation method returns a new FieldSet — the original is never modified.
47
- */
48
- class FieldSet {
49
- constructor(shape, entries) {
50
- this.shape = shape;
51
- this.entries = entries;
52
- }
53
- static for(shape, fieldsOrFn) {
54
- const resolved = FieldSet.resolveShapeInput(shape);
55
- const resolvedShape = resolved.nodeShape;
56
- if (typeof fieldsOrFn === 'function') {
57
- if (!resolved.shapeClass) {
58
- throw new Error(`Cannot use callback form for shape '${resolved.nodeShape.id}': no ShapeConstructor registered. ` +
59
- `Use string field names instead, or pass the Shape class directly.`);
60
- }
61
- const fields = FieldSet.traceFieldsWithProxy(resolved.nodeShape, resolved.shapeClass, fieldsOrFn);
62
- return new FieldSet(resolved.nodeShape, fields);
63
- }
64
- const entries = FieldSet.resolveInputs(resolvedShape, fieldsOrFn);
65
- return new FieldSet(resolvedShape, entries);
66
- }
67
- /**
68
- * Create a typed FieldSet for a sub-select. Traces the callback through the proxy,
69
- * stores parentSegments and traceResponse for runtime compatibility, and preserves
70
- * R and Source generics for conditional type inference.
71
- */
72
- static forSubSelect(shapeClass, fn, parentSegments, source) {
73
- const nodeShape = shapeClass.shape || shapeClass;
74
- // Trace once: get both the raw response (for type carriers) and the entries
75
- const proxy = (0, ProxiedPathBuilder_js_1.createProxiedPathBuilder)(shapeClass);
76
- const traceResponse = fn(proxy);
77
- const entries = FieldSet.extractSubSelectEntries(nodeShape, traceResponse);
78
- const fs = new FieldSet(nodeShape, entries);
79
- // Writable cast — these readonly fields are initialised once here at construction time
80
- const w = fs;
81
- w.traceResponse = traceResponse;
82
- w.parentSegments = parentSegments;
83
- w.shapeType = shapeClass;
84
- // Carry an inline `.where()` from the parent traversal chain (walked
85
- // leaf→root, same convention as convertTraceResult for plain paths).
86
- let current = source;
87
- let leafDistance = 0;
88
- while (current) {
89
- if (current.wherePath) {
90
- w.parentWherePath = current.wherePath;
91
- w.parentWherePathIndex = parentSegments.length - 1 - leafDistance;
92
- break;
93
- }
94
- current = current.subject;
95
- leafDistance++;
96
- }
97
- return fs;
98
- }
99
- static all(shape, opts) {
100
- var _a;
101
- const depth = (_a = opts === null || opts === void 0 ? void 0 : opts.depth) !== null && _a !== void 0 ? _a : 1;
102
- if (depth < 1) {
103
- throw new Error('FieldSet.all() requires depth >= 1. Use a node reference ({id}) for depth 0.');
104
- }
105
- const resolved = FieldSet.resolveShapeInput(shape);
106
- // Seed visited with the root shape to prevent self-referencing cycles
107
- const visited = new Set([resolved.nodeShape.id]);
108
- return FieldSet.allForShape(resolved.nodeShape, depth, visited);
109
- }
110
- /**
111
- * Recursive helper for all(). Tracks visited shape IDs to prevent infinite loops
112
- * from circular shape references.
113
- */
114
- static allForShape(nodeShape, depth, visited) {
115
- const propertyShapes = nodeShape.getUniquePropertyShapes();
116
- const entries = [];
117
- for (const ps of propertyShapes) {
118
- const entry = { path: new PropertyPath_js_1.PropertyPath(nodeShape, [ps]) };
119
- // If depth > 1, recurse into nested shapes
120
- if (depth > 1 && ps.valueShape) {
121
- const nestedShapeClass = (0, ShapeClass_js_1.getShapeClass)(ps.valueShape);
122
- if ((nestedShapeClass === null || nestedShapeClass === void 0 ? void 0 : nestedShapeClass.shape) && !visited.has(nestedShapeClass.shape.id)) {
123
- visited.add(nestedShapeClass.shape.id);
124
- const nestedFs = FieldSet.allForShape(nestedShapeClass.shape, depth - 1, visited);
125
- if (nestedFs.entries.length > 0) {
126
- entry.subSelect = nestedFs;
127
- }
128
- }
129
- }
130
- entries.push(entry);
131
- }
132
- return new FieldSet(nodeShape, entries);
133
- }
134
- /**
135
- * Merge multiple FieldSets into one, deduplicating by path equality.
136
- * All FieldSets must share the same root shape.
137
- */
138
- static merge(sets) {
139
- if (sets.length === 0) {
140
- throw new Error('Cannot merge empty array of FieldSets');
141
- }
142
- const shape = sets[0].shape;
143
- for (const set of sets) {
144
- if (set.shape.id !== shape.id) {
145
- throw new Error(`Cannot merge FieldSets with different shapes: '${shape.label || shape.id}' and '${set.shape.label || set.shape.id}'`);
146
- }
147
- }
148
- const merged = [];
149
- const seen = new Set();
150
- for (const set of sets) {
151
- for (const entry of set.entries) {
152
- // Include aggregation in the dedup key so that 'friends' and 'friends(count)' are distinct
153
- const key = entry.aggregation
154
- ? `${entry.path.toString()}:${entry.aggregation}`
155
- : entry.path.toString();
156
- if (!seen.has(key)) {
157
- seen.add(key);
158
- merged.push(entry);
159
- }
160
- }
161
- }
162
- return new FieldSet(shape, merged);
163
- }
164
- // ---------------------------------------------------------------------------
165
- // Composition methods — each returns a new FieldSet
166
- // ---------------------------------------------------------------------------
167
- /** Returns a new FieldSet with only the given fields. */
168
- select(fields) {
169
- const entries = FieldSet.resolveInputs(this.shape, fields);
170
- return new FieldSet(this.shape, entries);
171
- }
172
- /**
173
- * Clone this FieldSet, preserving the sub-select carrier fields
174
- * (traceResponse / parentSegments / shapeType / inner pagination) and
175
- * applying the supplied overrides. Used by `.limit()`/`.offset()`/`.orderBy()`.
176
- */
177
- cloneWith(overrides) {
178
- const clone = new FieldSet(this.shape, this.entries);
179
- // The sub-select carrier fields are declared `readonly` (normally set once at
180
- // construction via `forSubSelect`). Copy this FieldSet's identity onto the
181
- // clone through a mutable view, then layer the pagination overrides on top.
182
- Object.assign(clone, Object.assign({ traceResponse: this.traceResponse, parentSegments: this.parentSegments, shapeType: this.shapeType, parentWherePath: this.parentWherePath, parentWherePathIndex: this.parentWherePathIndex, innerLimit: this.innerLimit, innerOffset: this.innerOffset, innerOrderBy: this.innerOrderBy }, overrides));
183
- return clone;
184
- }
185
- /**
186
- * Bound a nested select's related collection to at most `lim` items per parent.
187
- * Only honoured when the outer query targets a single subject; otherwise the
188
- * pipeline throws (per-group pagination across multiple parents is unsupported).
189
- */
190
- limit(lim) {
191
- return this.cloneWith({ innerLimit: lim });
192
- }
193
- /** Skip the first `off` items of a nested select's related collection (single-subject only). */
194
- offset(off) {
195
- return this.cloneWith({ innerOffset: off });
196
- }
197
- /**
198
- * Order a nested select's related collection, producing a deterministic window
199
- * for inner LIMIT/OFFSET. Defaults to ascending.
200
- *
201
- * Accepts either a proxy callback — `.orderBy(f => f.name)` — consistent with
202
- * the rest of the DSL, or a property-name string (`.orderBy('name')`).
203
- */
204
- orderBy(paths, direction = 'ASC') {
205
- const orderBy = typeof paths === 'function'
206
- ? this.orderByFromProxy(paths, direction)
207
- : (Array.isArray(paths) ? paths : [paths]).map((label) => {
208
- const ps = (0, PropertyPath_js_1.walkPropertyPath)(this.shape, label).terminal;
209
- if (!ps) {
210
- throw new Error(`orderBy: cannot resolve property '${label}' on shape '${this.shape.id}'`);
211
- }
212
- return { propertyShapeId: ps.id, direction };
213
- });
214
- return this.cloneWith({ innerOrderBy: orderBy });
215
- }
216
- /** Resolve a proxy `orderBy` callback (e.g. `f => f.name` or `f => [f.a, f.b]`)
217
- * to inner order-by clauses by tracing the sub-select shape's property proxy. */
218
- orderByFromProxy(fn, direction) {
219
- if (!this.shapeType) {
220
- throw new Error('orderBy(callback) is only available on a nested select(); pass a property-name string otherwise');
221
- }
222
- const response = fn((0, ProxiedPathBuilder_js_1.createProxiedPathBuilder)(this.shapeType));
223
- const results = Array.isArray(response) ? response : [response];
224
- return results.map((result) => {
225
- const segments = FieldSet.collectPropertySegments(result);
226
- const terminal = segments[segments.length - 1];
227
- if (!terminal) {
228
- throw new Error('orderBy: callback did not resolve to a property of the sub-select shape');
229
- }
230
- return { propertyShapeId: terminal.id, direction };
231
- });
232
- }
233
- /** Returns a new FieldSet with additional entries. */
234
- add(fields) {
235
- const newEntries = FieldSet.resolveInputs(this.shape, fields);
236
- // Deduplicate
237
- const existing = new Set(this.entries.map((e) => e.path.toString()));
238
- const combined = [...this.entries];
239
- for (const entry of newEntries) {
240
- if (!existing.has(entry.path.toString())) {
241
- combined.push(entry);
242
- }
243
- }
244
- return new FieldSet(this.shape, combined);
245
- }
246
- /** Returns a new FieldSet without entries matching the given labels. */
247
- remove(labels) {
248
- const labelSet = new Set(labels);
249
- const filtered = this.entries.filter((e) => { var _a; return !labelSet.has((_a = e.path.terminal) === null || _a === void 0 ? void 0 : _a.label); });
250
- return new FieldSet(this.shape, filtered);
251
- }
252
- /** Synonym for replacing all entries — returns a new FieldSet with only the given fields. */
253
- set(fields) {
254
- const entries = FieldSet.resolveInputs(this.shape, fields);
255
- return new FieldSet(this.shape, entries);
256
- }
257
- /** Returns a new FieldSet keeping only entries matching the given labels. */
258
- pick(labels) {
259
- const labelSet = new Set(labels);
260
- const filtered = this.entries.filter((e) => { var _a; return labelSet.has((_a = e.path.terminal) === null || _a === void 0 ? void 0 : _a.label); });
261
- return new FieldSet(this.shape, filtered);
262
- }
263
- /** Returns all PropertyPaths in this FieldSet. */
264
- paths() {
265
- return this.entries.map((e) => e.path);
266
- }
267
- /** Returns terminal property labels of all entries. */
268
- labels() {
269
- return this.entries.map((e) => { var _a; return (_a = e.path.terminal) === null || _a === void 0 ? void 0 : _a.label; }).filter(Boolean);
270
- }
271
- // ---------------------------------------------------------------------------
272
- // Serialization
273
- // ---------------------------------------------------------------------------
274
- /**
275
- * Serialize this FieldSet to a plain JSON object.
276
- * Shape is identified by its IRI, paths by dot-separated labels.
277
- */
278
- toJSON() {
279
- return { shape: this.shape.id, fields: this.toFieldsJSON() };
280
- }
281
- /** Serialize just the field entries (used for nested relation sub-fields). */
282
- toFieldsJSON() {
283
- return this.entries.map((entry) => this.serializeEntry(entry));
284
- }
285
- serializeEntry(entry) {
286
- var _a, _b;
287
- // Computed projection — no path; carry the DSL-JSON value.
288
- if (entry.expressionNode) {
289
- const out = {
290
- value: (0, DslJsonExpression_js_1.encodeValueExpr)(entry.expressionNode.ir, entry.expressionNode._refs),
291
- };
292
- if (entry.alias)
293
- out.as = entry.alias;
294
- if (entry.customKey)
295
- out.customKey = entry.customKey;
296
- return out;
297
- }
298
- const pathStr = FieldSet.pathToStringWithCasts(this.shape, entry.path.segments);
299
- const sub = (_a = entry.subSelect) !== null && _a !== void 0 ? _a : entry.preloadSubSelect;
300
- const subFields = sub ? sub.toFieldsJSON() : undefined;
301
- const opts = {};
302
- if (entry.alias)
303
- opts.as = entry.alias;
304
- if (entry.aggregation)
305
- opts.aggregation = entry.aggregation;
306
- if (entry.customKey)
307
- opts.customKey = entry.customKey;
308
- if (entry.scopedFilter) {
309
- const idx = (_b = entry.scopedFilterIndex) !== null && _b !== void 0 ? _b : entry.path.segments.length - 1;
310
- opts.where = (0, QueryBuilderSerialization_js_1.serializeWherePath)(entry.scopedFilter, this.scopedShapeAt(entry, idx));
311
- opts.whereIndex = idx;
312
- }
313
- // Nested-select pagination (G10) — was previously dropped on the wire.
314
- if (typeof entry.innerLimit === 'number')
315
- opts.limit = entry.innerLimit;
316
- if (typeof entry.innerOffset === 'number')
317
- opts.offset = entry.innerOffset;
318
- if (entry.innerOrderBy && entry.innerOrderBy.length > 0) {
319
- opts.orderBy = entry.innerOrderBy.map((o) => ({
320
- [FieldSet.labelOfId(o.propertyShapeId)]: o.direction,
321
- }));
322
- }
323
- const hasOpts = Object.keys(opts).length > 0;
324
- // Bare-string shorthand: a plain leaf/relation with no options or sub-fields.
325
- if (!subFields && !hasOpts)
326
- return pathStr;
327
- // Array shorthand: sub-fields only, no other options.
328
- if (subFields && !hasOpts)
329
- return { [pathStr]: subFields };
330
- // Full options object (optionally carrying `fields`).
331
- return { [pathStr]: Object.assign(Object.assign({}, opts), (subFields ? { fields: subFields } : {})) };
332
- }
333
- /** The shape a scoped filter at segment `idx` is evaluated against (the segment's value shape). */
334
- scopedShapeAt(entry, idx) {
335
- var _a, _b;
336
- const seg = entry.path.segments[idx];
337
- const valueShapeId = (_a = seg === null || seg === void 0 ? void 0 : seg.valueShape) === null || _a === void 0 ? void 0 : _a.id;
338
- return (valueShapeId && ((_b = (0, ShapeClass_js_1.getShapeClass)(valueShapeId)) === null || _b === void 0 ? void 0 : _b.shape)) || this.shape;
339
- }
340
- /**
341
- * Reconstruct a FieldSet from a JSON object.
342
- * Resolves shape IRI via getShapeClass() and paths via walkPropertyPath().
343
- */
344
- static fromJSON(json) {
345
- return FieldSet.fromFields(FieldSet.resolveShape(json.shape), json.fields);
346
- }
347
- /** Build a FieldSet from a shape + relation-keyed field list (recursion entry). */
348
- static fromFields(shape, fields) {
349
- return new FieldSet(shape, fields.map((raw) => FieldSet.parseField(shape, raw)));
350
- }
351
- /** Parse one field entry (string leaf / computed / relation-keyed) against `shape`. */
352
- static parseField(shape, raw) {
353
- var _a, _b, _c, _d, _e;
354
- // Leaf path (may carry inline `as(Shape)` casts).
355
- if (typeof raw === 'string') {
356
- return { path: FieldSet.walkPathWithCasts(shape, raw) };
357
- }
358
- // Computed projection — carries `value`.
359
- if ('value' in raw && raw.value !== undefined) {
360
- const computed = raw;
361
- const { ir, refs } = (0, DslJsonExpression_js_1.decodeValueExpr)(computed.value, shape);
362
- const entry = {
363
- path: new PropertyPath_js_1.PropertyPath(shape, []),
364
- expressionNode: new ExpressionNode_js_1.ExpressionNode(ir, refs),
365
- };
366
- if (computed.as)
367
- entry.alias = computed.as;
368
- if (computed.customKey)
369
- entry.customKey = computed.customKey;
370
- return entry;
371
- }
372
- // Relation-keyed: the single non-option key is the relation path.
373
- const rel = raw;
374
- const pathKey = Object.keys(rel).find((k) => !RELATION_OPTION_KEYS.has(k));
375
- if (!pathKey) {
376
- throw new Error(`FieldSet field has no relation path: ${JSON.stringify(raw)}`);
377
- }
378
- const spec = rel[pathKey];
379
- const path = FieldSet.walkPathWithCasts(shape, pathKey);
380
- const entry = { path };
381
- const subFields = Array.isArray(spec) ? spec : spec.fields;
382
- const opts = Array.isArray(spec) ? {} : spec;
383
- if (opts.as)
384
- entry.alias = opts.as;
385
- if (opts.customKey)
386
- entry.customKey = opts.customKey;
387
- if (opts.aggregation)
388
- entry.aggregation = opts.aggregation;
389
- if (opts.where) {
390
- const idx = (_a = opts.whereIndex) !== null && _a !== void 0 ? _a : path.segments.length - 1;
391
- const seg = path.segments[idx];
392
- const valueShapeId = (_b = seg === null || seg === void 0 ? void 0 : seg.valueShape) === null || _b === void 0 ? void 0 : _b.id;
393
- const scopedShape = (valueShapeId && ((_c = (0, ShapeClass_js_1.getShapeClass)(valueShapeId)) === null || _c === void 0 ? void 0 : _c.shape)) || shape;
394
- entry.scopedFilter = (0, QueryBuilderSerialization_js_1.deserializeWherePath)(scopedShape, opts.where);
395
- entry.scopedFilterIndex = idx;
396
- }
397
- // Nested-select pagination (G10).
398
- if (typeof opts.limit === 'number')
399
- entry.innerLimit = opts.limit;
400
- if (typeof opts.offset === 'number')
401
- entry.innerOffset = opts.offset;
402
- if (opts.orderBy && opts.orderBy.length > 0) {
403
- const nested = (_d = FieldSet.nestedShapeOf(path)) !== null && _d !== void 0 ? _d : shape;
404
- entry.innerOrderBy = opts.orderBy.map((e) => {
405
- var _a;
406
- const label = Object.keys(e)[0];
407
- const ps = nested.getPropertyShape(label);
408
- return { propertyShapeId: (_a = ps === null || ps === void 0 ? void 0 : ps.id) !== null && _a !== void 0 ? _a : label, direction: Object.values(e)[0] };
409
- });
410
- }
411
- if (subFields) {
412
- const nested = (_e = FieldSet.nestedShapeOf(path)) !== null && _e !== void 0 ? _e : shape;
413
- entry.subSelect = FieldSet.fromFields(nested, subFields);
414
- }
415
- return entry;
416
- }
417
- /** The shape reached at the end of a relation path (its terminal segment's value shape). */
418
- static nestedShapeOf(path) {
419
- var _a, _b;
420
- const seg = path.segments[path.segments.length - 1];
421
- const valueShapeId = (_a = seg === null || seg === void 0 ? void 0 : seg.valueShape) === null || _a === void 0 ? void 0 : _a.id;
422
- return (valueShapeId && ((_b = (0, ShapeClass_js_1.getShapeClass)(valueShapeId)) === null || _b === void 0 ? void 0 : _b.shape)) || undefined;
423
- }
424
- // ---------------------------------------------------------------------------
425
- // Private helpers
426
- // ---------------------------------------------------------------------------
427
- /**
428
- * Resolves any of the accepted shape input types to a NodeShape and optional ShapeClass.
429
- * Accepts: ShapeConstructor (class with .shape), NodeShape, or IRI string.
430
- */
431
- static resolveShapeInput(shape) {
432
- if (typeof shape === 'string') {
433
- const shapeClass = (0, ShapeClass_js_1.getShapeClass)(shape);
434
- if (!shapeClass || !shapeClass.shape) {
435
- throw new Error(`Cannot resolve shape for '${shape}'`);
436
- }
437
- return { nodeShape: shapeClass.shape, shapeClass };
438
- }
439
- // ShapeConstructor: has a static .shape property that is a NodeShape
440
- if ('shape' in shape && typeof shape.shape === 'object' && shape.shape !== null && 'id' in shape.shape) {
441
- return { nodeShape: shape.shape, shapeClass: shape };
442
- }
443
- // NodeShape: has .id directly — try to look up its ShapeConstructor for full proxy support
444
- const nodeShape = shape;
445
- const shapeClass = nodeShape.id ? (0, ShapeClass_js_1.getShapeClass)(nodeShape.id) : undefined;
446
- return shapeClass
447
- ? { nodeShape, shapeClass }
448
- : { nodeShape };
449
- }
450
- /** @deprecated Use resolveShapeInput instead. Kept for fromJSON which only passes NodeShape|string. */
451
- static resolveShape(shape) {
452
- return FieldSet.resolveShapeInput(shape).nodeShape;
453
- }
454
- static resolveInputs(shape, inputs) {
455
- const entries = [];
456
- for (const input of inputs) {
457
- if (typeof input === 'string') {
458
- entries.push({ path: (0, PropertyPath_js_1.walkPropertyPath)(shape, input) });
459
- }
460
- else if (input instanceof PropertyPath_js_1.PropertyPath) {
461
- entries.push({ path: input });
462
- }
463
- else if (input instanceof FieldSet) {
464
- entries.push(...input.entries);
465
- }
466
- else if (typeof input === 'object') {
467
- // Nested object form: { friends: ['name', 'hobby'] }
468
- for (const [key, value] of Object.entries(input)) {
469
- const basePath = (0, PropertyPath_js_1.walkPropertyPath)(shape, key);
470
- if (value instanceof FieldSet) {
471
- // Merge nested FieldSet entries under this path
472
- for (const entry of value.entries) {
473
- const combined = new PropertyPath_js_1.PropertyPath(shape, [
474
- ...basePath.segments,
475
- ...entry.path.segments,
476
- ]);
477
- entries.push({ path: combined, alias: entry.alias, scopedFilter: entry.scopedFilter });
478
- }
479
- }
480
- else if (Array.isArray(value)) {
481
- // Resolve nested string fields
482
- const basePropertyShape = basePath.terminal;
483
- if (!(basePropertyShape === null || basePropertyShape === void 0 ? void 0 : basePropertyShape.valueShape)) {
484
- throw new Error(`Property '${key}' has no valueShape; cannot resolve nested fields`);
485
- }
486
- const nestedShapeClass = (0, ShapeClass_js_1.getShapeClass)(basePropertyShape.valueShape);
487
- if (!nestedShapeClass || !nestedShapeClass.shape) {
488
- throw new Error(`Cannot resolve valueShape for property '${key}'`);
489
- }
490
- for (const nestedField of value) {
491
- const nestedPath = (0, PropertyPath_js_1.walkPropertyPath)(nestedShapeClass.shape, nestedField);
492
- const combined = new PropertyPath_js_1.PropertyPath(shape, [
493
- ...basePath.segments,
494
- ...nestedPath.segments,
495
- ]);
496
- entries.push({ path: combined });
497
- }
498
- }
499
- }
500
- }
501
- }
502
- return entries;
503
- }
504
- /**
505
- * Trace fields using the full ProxiedPathBuilder proxy (createProxiedPathBuilder).
506
- * Handles nested paths, where conditions, aggregations, and sub-selects.
507
- */
508
- static traceFieldsWithProxy(nodeShape, shapeClass, fn) {
509
- const proxy = (0, ProxiedPathBuilder_js_1.createProxiedPathBuilder)(shapeClass);
510
- const result = fn(proxy);
511
- // Normalize result: could be a single value, array, or custom object
512
- if (Array.isArray(result)) {
513
- return result.map((item) => FieldSet.convertTraceResult(nodeShape, item));
514
- }
515
- if (isQueryBuilderObject(result)) {
516
- return [FieldSet.convertTraceResult(nodeShape, result)];
517
- }
518
- // Single FieldSet sub-select (e.g. p.friends.select(f => [f.name]))
519
- if (result instanceof FieldSet && result.parentSegments !== undefined) {
520
- return [FieldSet.convertTraceResult(nodeShape, result)];
521
- }
522
- // Single SetSize (e.g. p.friends.size())
523
- if (isSetSize(result)) {
524
- return [FieldSet.convertTraceResult(nodeShape, result)];
525
- }
526
- // Single BoundComponent (e.g. p.bestFriend.preloadFor(comp))
527
- if (isBoundComponent(result)) {
528
- return [FieldSet.convertTraceResult(nodeShape, result)];
529
- }
530
- // Single ExpressionNode (e.g. p.age.times(12))
531
- if ((0, ExpressionNode_js_1.isExpressionNode)(result)) {
532
- return [FieldSet.convertTraceResult(nodeShape, result)];
533
- }
534
- if (typeof result === 'object' && result !== null) {
535
- // Custom object form: {name: p.name, hobby: p.hobby}
536
- const entries = [];
537
- for (const [key, value] of Object.entries(result)) {
538
- const entry = FieldSet.convertTraceResult(nodeShape, value);
539
- entry.customKey = key;
540
- entries.push(entry);
541
- }
542
- return entries;
543
- }
544
- return [];
545
- }
546
- /**
547
- * Convert a single proxy trace result (QueryBuilderObject, SetSize, or FieldSet sub-select)
548
- * into a FieldSetEntry.
549
- */
550
- static convertTraceResult(rootShape, obj) {
551
- // SetSize → aggregation: 'count'
552
- if (isSetSize(obj)) {
553
- const segments = FieldSet.collectPropertySegments(obj.subject);
554
- return {
555
- path: new PropertyPath_js_1.PropertyPath(rootShape, segments),
556
- aggregation: 'count',
557
- };
558
- }
559
- // FieldSet sub-select — use its entries directly (created by forSubSelect)
560
- if (obj instanceof FieldSet && obj.parentSegments !== undefined) {
561
- const subSelect = obj.entries.length > 0 ? obj : undefined;
562
- const entry = {
563
- path: new PropertyPath_js_1.PropertyPath(rootShape, obj.parentSegments),
564
- subSelect: subSelect,
565
- };
566
- // Carry an inline `.where()` from the parent traversal chain
567
- // (e.g. `p.friends.where(...).select(...)`).
568
- if (obj.parentWherePath) {
569
- entry.scopedFilter = obj.parentWherePath;
570
- entry.scopedFilterIndex = obj.parentWherePathIndex;
571
- }
572
- // Carry inner LIMIT/OFFSET/ORDER BY from `.limit()`/`.offset()`/`.orderBy()`.
573
- if (typeof obj.innerLimit === 'number')
574
- entry.innerLimit = obj.innerLimit;
575
- if (typeof obj.innerOffset === 'number')
576
- entry.innerOffset = obj.innerOffset;
577
- if (obj.innerOrderBy)
578
- entry.innerOrderBy = obj.innerOrderBy;
579
- return entry;
580
- }
581
- // BoundComponent → preload composition (e.g. p.bestFriend.preloadFor(component))
582
- // Extract the component's FieldSet and store it as preloadSubSelect.
583
- if (isBoundComponent(obj)) {
584
- const segments = FieldSet.collectPropertySegments(obj.source);
585
- const componentFieldSet = FieldSet.extractComponentFieldSet(obj.originalValue);
586
- return {
587
- path: new PropertyPath_js_1.PropertyPath(rootShape, segments),
588
- preloadSubSelect: componentFieldSet,
589
- };
590
- }
591
- // ExpressionNode → computed expression (e.g. p.age.times(12))
592
- if ((0, ExpressionNode_js_1.isExpressionNode)(obj)) {
593
- return {
594
- path: new PropertyPath_js_1.PropertyPath(rootShape, []),
595
- expressionNode: obj,
596
- };
597
- }
598
- // QueryBuilderObject → walk the chain to collect PropertyPath segments
599
- if (isQueryBuilderObject(obj)) {
600
- const segments = FieldSet.collectPropertySegments(obj);
601
- const entry = {
602
- path: new PropertyPath_js_1.PropertyPath(rootShape, segments),
603
- };
604
- // Walk from leaf to root to find wherePath on any object in the chain.
605
- // Track which segment it belongs to so desugarEntry attaches the filter correctly.
606
- let current = obj;
607
- let leafDistance = 0;
608
- while (current) {
609
- if (current.wherePath) {
610
- entry.scopedFilter = current.wherePath;
611
- entry.scopedFilterIndex = segments.length - 1 - leafDistance;
612
- break;
613
- }
614
- current = current.subject;
615
- leafDistance++;
616
- }
617
- return entry;
618
- }
619
- // Fallback: string label
620
- if (typeof obj === 'string') {
621
- return { path: (0, PropertyPath_js_1.walkPropertyPath)(rootShape, obj) };
622
- }
623
- throw new Error(`Unknown trace result type: ${obj}`);
624
- }
625
- /**
626
- * Walk a QueryBuilderObject-like chain (via .subject) collecting PropertyShape segments
627
- * from leaf to root, then reverse to get root-to-leaf order.
628
- */
629
- static collectPropertySegments(obj) {
630
- const segments = [];
631
- let current = obj;
632
- while (current) {
633
- if (current.property) {
634
- segments.unshift(current.property);
635
- }
636
- current = current.subject;
637
- }
638
- return segments;
639
- }
640
- // ---------------------------------------------------------------------------
641
- // Cast-aware path (de)serialization — carries `.as(Shape)` narrowing inline as
642
- // an `as(<ShapeLabel>)` path segment (documentation/dsl-json.md, backlog 002 G5).
643
- // ---------------------------------------------------------------------------
644
- static shapeById(id) {
645
- var _a;
646
- return (_a = (0, ShapeClass_js_1.getShapeClass)(id)) === null || _a === void 0 ? void 0 : _a.shape;
647
- }
648
- static shapeByLabel(label) {
649
- for (const cls of (0, ShapeClass_js_1.getAllShapeClasses)().values()) {
650
- const shape = cls.shape;
651
- if (shape && (shape.label === label || FieldSet.labelOfId(shape.id) === label)) {
652
- return shape;
653
- }
654
- }
655
- return undefined;
656
- }
657
- static labelOfId(id) {
658
- const i = id.lastIndexOf('/');
659
- return i >= 0 ? id.slice(i + 1) : id;
660
- }
661
- /**
662
- * Render a segment chain as a dotted label path, inserting `as(<ShapeLabel>)`
663
- * wherever a segment is not resolvable by label from the natural (walked) shape
664
- * — i.e. a `.as(Shape)` narrowing happened before it.
665
- */
666
- static pathToStringWithCasts(rootShape, segments) {
667
- var _a, _b;
668
- const parts = [];
669
- let current = rootShape;
670
- for (const seg of segments) {
671
- const label = FieldSet.labelOfId(seg.id);
672
- const natural = current === null || current === void 0 ? void 0 : current.getPropertyShape(label);
673
- if (!natural || natural.id !== seg.id) {
674
- // A cast narrowed the context to the segment's owner shape.
675
- const ownerId = seg.id.slice(0, seg.id.lastIndexOf('/'));
676
- const owner = FieldSet.shapeById(ownerId);
677
- parts.push(`as(${(_a = owner === null || owner === void 0 ? void 0 : owner.label) !== null && _a !== void 0 ? _a : FieldSet.labelOfId(ownerId)})`);
678
- current = owner !== null && owner !== void 0 ? owner : current;
679
- }
680
- parts.push(label);
681
- const vs = seg.valueShape;
682
- current = vs ? (_b = FieldSet.shapeById(vs.id)) !== null && _b !== void 0 ? _b : current : current;
683
- }
684
- return parts.join('.');
685
- }
686
- /** Inverse of {@link pathToStringWithCasts}: resolve a dotted path with `as(X)` casts. */
687
- static walkPathWithCasts(rootShape, path) {
688
- var _a, _b;
689
- if (!path.includes('as('))
690
- return (0, PropertyPath_js_1.walkPropertyPath)(rootShape, path);
691
- const segments = [];
692
- let current = rootShape;
693
- for (const token of path.split('.')) {
694
- const cast = /^as\((.+)\)$/.exec(token);
695
- if (cast) {
696
- current = (_a = FieldSet.shapeByLabel(cast[1])) !== null && _a !== void 0 ? _a : current;
697
- continue;
698
- }
699
- const ps = current === null || current === void 0 ? void 0 : current.getPropertyShape(token);
700
- if (!ps) {
701
- throw new Error(`Property '${token}' not found on shape '${(current === null || current === void 0 ? void 0 : current.label) || (current === null || current === void 0 ? void 0 : current.id)}' while resolving path '${path}'`);
702
- }
703
- segments.push(ps);
704
- const vs = ps.valueShape;
705
- current = vs ? (_b = FieldSet.shapeById(vs.id)) !== null && _b !== void 0 ? _b : current : current;
706
- }
707
- return new PropertyPath_js_1.PropertyPath(rootShape, segments);
708
- }
709
- /**
710
- * Extract a FieldSet from a component-like object for preload composition.
711
- *
712
- * Supports multiple component interfaces:
713
- * - `.fields` as a FieldSet directly
714
- * - `.query` as a FieldSet, QueryBuilder (duck-typed via .fields()), or
715
- * Record<string, QueryBuilder> (e.g. `{person: PersonQuery}`)
716
- */
717
- static extractComponentFieldSet(component) {
718
- // Prefer .fields if it's a FieldSet
719
- if (component.fields instanceof FieldSet) {
720
- return component.fields;
721
- }
722
- const query = component.query;
723
- if (query instanceof FieldSet) {
724
- return query;
725
- }
726
- // QueryBuilder duck-type — has .fields() method
727
- if (query && typeof query.fields === 'function') {
728
- return query.fields();
729
- }
730
- // Record form: { propName: QueryBuilder }
731
- if (typeof query === 'object') {
732
- for (const key in query) {
733
- const value = query[key];
734
- if (value && typeof value.fields === 'function') {
735
- return value.fields();
736
- }
737
- }
738
- }
739
- return undefined;
740
- }
741
- /**
742
- * Internal factory that bypasses the private constructor for use by static methods.
743
- */
744
- static createInternal(shape, entries) {
745
- return new FieldSet(shape, entries);
746
- }
747
- /**
748
- * Create a FieldSet from raw entries. Used by QueryBuilder to merge preload entries.
749
- */
750
- static createFromEntries(shape, entries) {
751
- return new FieldSet(shape, entries);
752
- }
753
- /**
754
- * Extract FieldSetEntry[] from a sub-query's traceResponse.
755
- * Public alias for use by lightweight sub-select wrappers.
756
- */
757
- static extractSubSelectEntriesPublic(rootShape, traceResponse) {
758
- return FieldSet.extractSubSelectEntries(rootShape, traceResponse);
759
- }
760
- /**
761
- * Extract FieldSetEntry[] from a sub-select's traceResponse.
762
- * The traceResponse is the result of calling the sub-query callback with a proxy,
763
- * containing QueryBuilderObjects, arrays, custom objects, etc.
764
- */
765
- static extractSubSelectEntries(rootShape, traceResponse) {
766
- if (Array.isArray(traceResponse)) {
767
- return traceResponse
768
- .filter((item) => item !== null && item !== undefined)
769
- .map((item) => FieldSet.convertTraceResult(rootShape, item));
770
- }
771
- if (isQueryBuilderObject(traceResponse)) {
772
- return [FieldSet.convertTraceResult(rootShape, traceResponse)];
773
- }
774
- // Single FieldSet sub-select — convert directly
775
- if (traceResponse instanceof FieldSet && traceResponse.parentSegments !== undefined) {
776
- return [FieldSet.convertTraceResult(rootShape, traceResponse)];
777
- }
778
- // Single SetSize
779
- if (isSetSize(traceResponse)) {
780
- return [FieldSet.convertTraceResult(rootShape, traceResponse)];
781
- }
782
- // Single ExpressionNode
783
- if ((0, ExpressionNode_js_1.isExpressionNode)(traceResponse)) {
784
- return [FieldSet.convertTraceResult(rootShape, traceResponse)];
785
- }
786
- if (typeof traceResponse === 'object' && traceResponse !== null) {
787
- // Custom object form: {name: p.name, hobby: p.hobby}
788
- const entries = [];
789
- for (const [key, value] of Object.entries(traceResponse)) {
790
- if (value !== null && value !== undefined) {
791
- const entry = FieldSet.convertTraceResult(rootShape, value);
792
- entry.customKey = key;
793
- entries.push(entry);
794
- }
795
- }
796
- return entries;
797
- }
798
- return [];
799
- }
800
- }
801
- exports.FieldSet = FieldSet;
802
- //# sourceMappingURL=FieldSet.js.map