@_linked/core 2.12.0 → 2.13.0-next.20260706164859
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/lib/esm/queries/IRPipeline.d.ts +7 -1
- package/lib/esm/queries/IRPipeline.js +20 -6
- package/lib/esm/queries/IRPipeline.js.map +1 -1
- package/lib/esm/queries/queryDispatch.js +12 -2
- package/lib/esm/queries/queryDispatch.js.map +1 -1
- package/package.json +10 -13
- package/lib/cjs/collections/CoreSet.d.ts +0 -47
- package/lib/cjs/collections/CoreSet.js +0 -136
- package/lib/cjs/collections/CoreSet.js.map +0 -1
- package/lib/cjs/collections/ShapeSet.d.ts +0 -6
- package/lib/cjs/collections/ShapeSet.js +0 -20
- package/lib/cjs/collections/ShapeSet.js.map +0 -1
- package/lib/cjs/expressions/Expr.d.ts +0 -29
- package/lib/cjs/expressions/Expr.js +0 -80
- package/lib/cjs/expressions/Expr.js.map +0 -1
- package/lib/cjs/expressions/ExpressionMethods.d.ts +0 -85
- package/lib/cjs/expressions/ExpressionMethods.js +0 -3
- package/lib/cjs/expressions/ExpressionMethods.js.map +0 -1
- package/lib/cjs/expressions/ExpressionNode.d.ts +0 -144
- package/lib/cjs/expressions/ExpressionNode.js +0 -432
- package/lib/cjs/expressions/ExpressionNode.js.map +0 -1
- package/lib/cjs/index.d.ts +0 -29
- package/lib/cjs/index.js +0 -65
- package/lib/cjs/index.js.map +0 -1
- package/lib/cjs/interfaces/ICoreIterable.d.ts +0 -14
- package/lib/cjs/interfaces/ICoreIterable.js +0 -3
- package/lib/cjs/interfaces/ICoreIterable.js.map +0 -1
- package/lib/cjs/interfaces/IDataset.d.ts +0 -26
- package/lib/cjs/interfaces/IDataset.js +0 -3
- package/lib/cjs/interfaces/IDataset.js.map +0 -1
- package/lib/cjs/interfaces/IFileStore.d.ts +0 -16
- package/lib/cjs/interfaces/IFileStore.js +0 -3
- package/lib/cjs/interfaces/IFileStore.js.map +0 -1
- package/lib/cjs/ontologies/linked-core.d.ts +0 -15
- package/lib/cjs/ontologies/linked-core.js +0 -38
- package/lib/cjs/ontologies/linked-core.js.map +0 -1
- package/lib/cjs/ontologies/npm.d.ts +0 -6
- package/lib/cjs/ontologies/npm.js +0 -15
- package/lib/cjs/ontologies/npm.js.map +0 -1
- package/lib/cjs/ontologies/owl.d.ts +0 -14
- package/lib/cjs/ontologies/owl.js +0 -21
- package/lib/cjs/ontologies/owl.js.map +0 -1
- package/lib/cjs/ontologies/rdf.d.ts +0 -13
- package/lib/cjs/ontologies/rdf.js +0 -27
- package/lib/cjs/ontologies/rdf.js.map +0 -1
- package/lib/cjs/ontologies/rdfs.d.ts +0 -16
- package/lib/cjs/ontologies/rdfs.js +0 -33
- package/lib/cjs/ontologies/rdfs.js.map +0 -1
- package/lib/cjs/ontologies/shacl.d.ts +0 -103
- package/lib/cjs/ontologies/shacl.js +0 -152
- package/lib/cjs/ontologies/shacl.js.map +0 -1
- package/lib/cjs/ontologies/xsd.d.ts +0 -19
- package/lib/cjs/ontologies/xsd.js +0 -41
- package/lib/cjs/ontologies/xsd.js.map +0 -1
- package/lib/cjs/package.d.ts +0 -4
- package/lib/cjs/package.js +0 -6
- package/lib/cjs/package.js.map +0 -1
- package/lib/cjs/package.json +0 -9
- package/lib/cjs/paths/PropertyPathExpr.d.ts +0 -38
- package/lib/cjs/paths/PropertyPathExpr.js +0 -221
- package/lib/cjs/paths/PropertyPathExpr.js.map +0 -1
- package/lib/cjs/paths/normalizePropertyPath.d.ts +0 -23
- package/lib/cjs/paths/normalizePropertyPath.js +0 -75
- package/lib/cjs/paths/normalizePropertyPath.js.map +0 -1
- package/lib/cjs/paths/pathExprToSparql.d.ts +0 -14
- package/lib/cjs/paths/pathExprToSparql.js +0 -136
- package/lib/cjs/paths/pathExprToSparql.js.map +0 -1
- package/lib/cjs/queries/ContextRef.d.ts +0 -32
- package/lib/cjs/queries/ContextRef.js +0 -69
- package/lib/cjs/queries/ContextRef.js.map +0 -1
- package/lib/cjs/queries/CreateBuilder.d.ts +0 -59
- package/lib/cjs/queries/CreateBuilder.js +0 -138
- package/lib/cjs/queries/CreateBuilder.js.map +0 -1
- package/lib/cjs/queries/CreateQuery.d.ts +0 -20
- package/lib/cjs/queries/CreateQuery.js +0 -3
- package/lib/cjs/queries/CreateQuery.js.map +0 -1
- package/lib/cjs/queries/DeleteBuilder.d.ts +0 -56
- package/lib/cjs/queries/DeleteBuilder.js +0 -172
- package/lib/cjs/queries/DeleteBuilder.js.map +0 -1
- package/lib/cjs/queries/DeleteQuery.d.ts +0 -37
- package/lib/cjs/queries/DeleteQuery.js +0 -3
- package/lib/cjs/queries/DeleteQuery.js.map +0 -1
- package/lib/cjs/queries/DslJsonExpression.d.ts +0 -68
- package/lib/cjs/queries/DslJsonExpression.js +0 -427
- package/lib/cjs/queries/DslJsonExpression.js.map +0 -1
- package/lib/cjs/queries/FieldSet.d.ts +0 -310
- package/lib/cjs/queries/FieldSet.js +0 -802
- package/lib/cjs/queries/FieldSet.js.map +0 -1
- package/lib/cjs/queries/IRAliasScope.d.ts +0 -20
- package/lib/cjs/queries/IRAliasScope.js +0 -52
- package/lib/cjs/queries/IRAliasScope.js.map +0 -1
- package/lib/cjs/queries/IRCanonicalize.d.ts +0 -19
- package/lib/cjs/queries/IRCanonicalize.js +0 -19
- package/lib/cjs/queries/IRCanonicalize.js.map +0 -1
- package/lib/cjs/queries/IRDesugar.d.ts +0 -123
- package/lib/cjs/queries/IRDesugar.js +0 -261
- package/lib/cjs/queries/IRDesugar.js.map +0 -1
- package/lib/cjs/queries/IRLower.d.ts +0 -25
- package/lib/cjs/queries/IRLower.js +0 -398
- package/lib/cjs/queries/IRLower.js.map +0 -1
- package/lib/cjs/queries/IRMutation.d.ts +0 -53
- package/lib/cjs/queries/IRMutation.js +0 -130
- package/lib/cjs/queries/IRMutation.js.map +0 -1
- package/lib/cjs/queries/IRPipeline.d.ts +0 -8
- package/lib/cjs/queries/IRPipeline.js +0 -25
- package/lib/cjs/queries/IRPipeline.js.map +0 -1
- package/lib/cjs/queries/IRProjection.d.ts +0 -39
- package/lib/cjs/queries/IRProjection.js +0 -105
- package/lib/cjs/queries/IRProjection.js.map +0 -1
- package/lib/cjs/queries/IntermediateRepresentation.d.ts +0 -282
- package/lib/cjs/queries/IntermediateRepresentation.js +0 -3
- package/lib/cjs/queries/IntermediateRepresentation.js.map +0 -1
- package/lib/cjs/queries/MutationQuery.d.ts +0 -50
- package/lib/cjs/queries/MutationQuery.js +0 -334
- package/lib/cjs/queries/MutationQuery.js.map +0 -1
- package/lib/cjs/queries/MutationSerialization.d.ts +0 -102
- package/lib/cjs/queries/MutationSerialization.js +0 -207
- package/lib/cjs/queries/MutationSerialization.js.map +0 -1
- package/lib/cjs/queries/MutationThenable.d.ts +0 -18
- package/lib/cjs/queries/MutationThenable.js +0 -32
- package/lib/cjs/queries/MutationThenable.js.map +0 -1
- package/lib/cjs/queries/PropertyPath.d.ts +0 -38
- package/lib/cjs/queries/PropertyPath.js +0 -82
- package/lib/cjs/queries/PropertyPath.js.map +0 -1
- package/lib/cjs/queries/ProxiedPathBuilder.d.ts +0 -14
- package/lib/cjs/queries/ProxiedPathBuilder.js +0 -29
- package/lib/cjs/queries/ProxiedPathBuilder.js.map +0 -1
- package/lib/cjs/queries/QueryBuilder.d.ts +0 -193
- package/lib/cjs/queries/QueryBuilder.js +0 -519
- package/lib/cjs/queries/QueryBuilder.js.map +0 -1
- package/lib/cjs/queries/QueryBuilderSerialization.d.ts +0 -31
- package/lib/cjs/queries/QueryBuilderSerialization.js +0 -68
- package/lib/cjs/queries/QueryBuilderSerialization.js.map +0 -1
- package/lib/cjs/queries/QueryContext.d.ts +0 -50
- package/lib/cjs/queries/QueryContext.js +0 -147
- package/lib/cjs/queries/QueryContext.js.map +0 -1
- package/lib/cjs/queries/QueryFactory.d.ts +0 -80
- package/lib/cjs/queries/QueryFactory.js +0 -21
- package/lib/cjs/queries/QueryFactory.js.map +0 -1
- package/lib/cjs/queries/SelectQuery.d.ts +0 -302
- package/lib/cjs/queries/SelectQuery.js +0 -761
- package/lib/cjs/queries/SelectQuery.js.map +0 -1
- package/lib/cjs/queries/UpdateBuilder.d.ts +0 -69
- package/lib/cjs/queries/UpdateBuilder.js +0 -199
- package/lib/cjs/queries/UpdateBuilder.js.map +0 -1
- package/lib/cjs/queries/UpdateQuery.d.ts +0 -18
- package/lib/cjs/queries/UpdateQuery.js +0 -3
- package/lib/cjs/queries/UpdateQuery.js.map +0 -1
- package/lib/cjs/queries/fromJSON.d.ts +0 -16
- package/lib/cjs/queries/fromJSON.js +0 -41
- package/lib/cjs/queries/fromJSON.js.map +0 -1
- package/lib/cjs/queries/lower.d.ts +0 -28
- package/lib/cjs/queries/lower.js +0 -114
- package/lib/cjs/queries/lower.js.map +0 -1
- package/lib/cjs/queries/lowerMutationJSON.d.ts +0 -25
- package/lib/cjs/queries/lowerMutationJSON.js +0 -173
- package/lib/cjs/queries/lowerMutationJSON.js.map +0 -1
- package/lib/cjs/queries/mutationLowerSpec.d.ts +0 -32
- package/lib/cjs/queries/mutationLowerSpec.js +0 -8
- package/lib/cjs/queries/mutationLowerSpec.js.map +0 -1
- package/lib/cjs/queries/queryDispatch.d.ts +0 -33
- package/lib/cjs/queries/queryDispatch.js +0 -33
- package/lib/cjs/queries/queryDispatch.js.map +0 -1
- package/lib/cjs/queries/resolveShape.d.ts +0 -10
- package/lib/cjs/queries/resolveShape.js +0 -23
- package/lib/cjs/queries/resolveShape.js.map +0 -1
- package/lib/cjs/queries/wireVersion.d.ts +0 -7
- package/lib/cjs/queries/wireVersion.js +0 -25
- package/lib/cjs/queries/wireVersion.js.map +0 -1
- package/lib/cjs/shapes/List.d.ts +0 -35
- package/lib/cjs/shapes/List.js +0 -72
- package/lib/cjs/shapes/List.js.map +0 -1
- package/lib/cjs/shapes/PathNode.d.ts +0 -20
- package/lib/cjs/shapes/PathNode.js +0 -68
- package/lib/cjs/shapes/PathNode.js.map +0 -1
- package/lib/cjs/shapes/SHACL.d.ts +0 -300
- package/lib/cjs/shapes/SHACL.js +0 -612
- package/lib/cjs/shapes/SHACL.js.map +0 -1
- package/lib/cjs/shapes/Shape.d.ts +0 -74
- package/lib/cjs/shapes/Shape.js +0 -124
- package/lib/cjs/shapes/Shape.js.map +0 -1
- package/lib/cjs/shapes/serializePathToNodeData.d.ts +0 -24
- package/lib/cjs/shapes/serializePathToNodeData.js +0 -67
- package/lib/cjs/shapes/serializePathToNodeData.js.map +0 -1
- package/lib/cjs/shapes/syncShapes.d.ts +0 -38
- package/lib/cjs/shapes/syncShapes.js +0 -214
- package/lib/cjs/shapes/syncShapes.js.map +0 -1
- package/lib/cjs/sparql/SparqlAlgebra.d.ts +0 -190
- package/lib/cjs/sparql/SparqlAlgebra.js +0 -4
- package/lib/cjs/sparql/SparqlAlgebra.js.map +0 -1
- package/lib/cjs/sparql/SparqlDataset.d.ts +0 -60
- package/lib/cjs/sparql/SparqlDataset.js +0 -117
- package/lib/cjs/sparql/SparqlDataset.js.map +0 -1
- package/lib/cjs/sparql/algebraToString.d.ts +0 -13
- package/lib/cjs/sparql/algebraToString.js +0 -385
- package/lib/cjs/sparql/algebraToString.js.map +0 -1
- package/lib/cjs/sparql/index.d.ts +0 -9
- package/lib/cjs/sparql/index.js +0 -41
- package/lib/cjs/sparql/index.js.map +0 -1
- package/lib/cjs/sparql/irToAlgebra.d.ts +0 -79
- package/lib/cjs/sparql/irToAlgebra.js +0 -2042
- package/lib/cjs/sparql/irToAlgebra.js.map +0 -1
- package/lib/cjs/sparql/resultMapping.d.ts +0 -36
- package/lib/cjs/sparql/resultMapping.js +0 -563
- package/lib/cjs/sparql/resultMapping.js.map +0 -1
- package/lib/cjs/sparql/sparqlUtils.d.ts +0 -53
- package/lib/cjs/sparql/sparqlUtils.js +0 -154
- package/lib/cjs/sparql/sparqlUtils.js.map +0 -1
- package/lib/cjs/utils/LinkedErrorLogging.d.ts +0 -13
- package/lib/cjs/utils/LinkedErrorLogging.js +0 -22
- package/lib/cjs/utils/LinkedErrorLogging.js.map +0 -1
- package/lib/cjs/utils/LinkedFileStorage.d.ts +0 -23
- package/lib/cjs/utils/LinkedFileStorage.js +0 -62
- package/lib/cjs/utils/LinkedFileStorage.js.map +0 -1
- package/lib/cjs/utils/LinkedStorage.d.ts +0 -40
- package/lib/cjs/utils/LinkedStorage.js +0 -148
- package/lib/cjs/utils/LinkedStorage.js.map +0 -1
- package/lib/cjs/utils/NameSpace.d.ts +0 -2
- package/lib/cjs/utils/NameSpace.js +0 -8
- package/lib/cjs/utils/NameSpace.js.map +0 -1
- package/lib/cjs/utils/NodeReference.d.ts +0 -30
- package/lib/cjs/utils/NodeReference.js +0 -54
- package/lib/cjs/utils/NodeReference.js.map +0 -1
- package/lib/cjs/utils/Package.d.ts +0 -153
- package/lib/cjs/utils/Package.js +0 -419
- package/lib/cjs/utils/Package.js.map +0 -1
- package/lib/cjs/utils/Prefix.d.ts +0 -22
- package/lib/cjs/utils/Prefix.js +0 -104
- package/lib/cjs/utils/Prefix.js.map +0 -1
- package/lib/cjs/utils/ShapeClass.d.ts +0 -30
- package/lib/cjs/utils/ShapeClass.js +0 -180
- package/lib/cjs/utils/ShapeClass.js.map +0 -1
- package/lib/cjs/utils/URI.d.ts +0 -18
- package/lib/cjs/utils/URI.js +0 -42
- package/lib/cjs/utils/URI.js.map +0 -1
- package/lib/cjs/utils/cached.d.ts +0 -14
- package/lib/cjs/utils/cached.js +0 -71
- package/lib/cjs/utils/cached.js.map +0 -1
- package/lib/cjs/utils/loadStores.d.ts +0 -34
- package/lib/cjs/utils/loadStores.js +0 -105
- package/lib/cjs/utils/loadStores.js.map +0 -1
- package/lib/cjs/utils/parseDatasetsConfig.d.ts +0 -49
- package/lib/cjs/utils/parseDatasetsConfig.js +0 -110
- package/lib/cjs/utils/parseDatasetsConfig.js.map +0 -1
- 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
|