@_linked/core 2.34.0 → 2.36.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.
- package/CHANGELOG.md +22 -0
- package/README.md +54 -0
- package/lib/esm/index.d.ts +5 -1
- package/lib/esm/index.js +6 -0
- package/lib/esm/index.js.map +1 -1
- package/lib/esm/live/LiveQueryStore.d.ts +22 -0
- package/lib/esm/live/LiveQueryStore.js +88 -20
- package/lib/esm/live/LiveQueryStore.js.map +1 -1
- package/lib/esm/live/changes.d.ts +9 -1
- package/lib/esm/live/changes.js +7 -2
- package/lib/esm/live/changes.js.map +1 -1
- package/lib/esm/live/keys.d.ts +6 -0
- package/lib/esm/live/keys.js +10 -1
- package/lib/esm/live/keys.js.map +1 -1
- package/lib/esm/live/matcher.d.ts +4 -1
- package/lib/esm/live/matcher.js +10 -5
- package/lib/esm/live/matcher.js.map +1 -1
- package/lib/esm/queries/AskBuilder.d.ts +6 -0
- package/lib/esm/queries/AskBuilder.js +14 -0
- package/lib/esm/queries/AskBuilder.js.map +1 -1
- package/lib/esm/queries/CountBuilder.d.ts +6 -0
- package/lib/esm/queries/CountBuilder.js +14 -0
- package/lib/esm/queries/CountBuilder.js.map +1 -1
- package/lib/esm/queries/CreateBuilder.d.ts +4 -0
- package/lib/esm/queries/CreateBuilder.js +15 -1
- package/lib/esm/queries/CreateBuilder.js.map +1 -1
- package/lib/esm/queries/DeleteBuilder.d.ts +4 -0
- package/lib/esm/queries/DeleteBuilder.js +15 -1
- package/lib/esm/queries/DeleteBuilder.js.map +1 -1
- package/lib/esm/queries/FieldSet.d.ts +17 -0
- package/lib/esm/queries/FieldSet.js +110 -22
- package/lib/esm/queries/FieldSet.js.map +1 -1
- package/lib/esm/queries/IRLower.js +3 -2
- package/lib/esm/queries/IRLower.js.map +1 -1
- package/lib/esm/queries/IRMutation.js +15 -14
- package/lib/esm/queries/IRMutation.js.map +1 -1
- package/lib/esm/queries/MutationQuery.js +3 -2
- package/lib/esm/queries/MutationQuery.js.map +1 -1
- package/lib/esm/queries/MutationSerialization.js +2 -2
- package/lib/esm/queries/MutationSerialization.js.map +1 -1
- package/lib/esm/queries/PropertyPath.js +4 -3
- package/lib/esm/queries/PropertyPath.js.map +1 -1
- package/lib/esm/queries/QueryBuilder.d.ts +7 -0
- package/lib/esm/queries/QueryBuilder.js +42 -4
- package/lib/esm/queries/QueryBuilder.js.map +1 -1
- package/lib/esm/queries/QueryContext.js +2 -0
- package/lib/esm/queries/QueryContext.js.map +1 -1
- package/lib/esm/queries/SelectQuery.js +8 -3
- package/lib/esm/queries/SelectQuery.js.map +1 -1
- package/lib/esm/queries/UpdateBuilder.d.ts +4 -0
- package/lib/esm/queries/UpdateBuilder.js +15 -1
- package/lib/esm/queries/UpdateBuilder.js.map +1 -1
- package/lib/esm/queries/fromJSON.d.ts +12 -1
- package/lib/esm/queries/fromJSON.js +5 -1
- package/lib/esm/queries/fromJSON.js.map +1 -1
- package/lib/esm/queries/lower.js +12 -5
- package/lib/esm/queries/lower.js.map +1 -1
- package/lib/esm/queries/queryDependencies.js +14 -10
- package/lib/esm/queries/queryDependencies.js.map +1 -1
- package/lib/esm/queries/resolveShape.js +16 -3
- package/lib/esm/queries/resolveShape.js.map +1 -1
- package/lib/esm/shapes/Shape.js +2 -1
- package/lib/esm/shapes/Shape.js.map +1 -1
- package/lib/esm/shapes/nodeShapeData.js +7 -10
- package/lib/esm/shapes/nodeShapeData.js.map +1 -1
- package/lib/esm/shapes/registerRuntimeShape.js +3 -1
- package/lib/esm/shapes/registerRuntimeShape.js.map +1 -1
- package/lib/esm/shapes/syncShapes.d.ts +6 -2
- package/lib/esm/shapes/syncShapes.js +16 -9
- package/lib/esm/shapes/syncShapes.js.map +1 -1
- package/lib/esm/shapes/validation.js +10 -6
- package/lib/esm/shapes/validation.js.map +1 -1
- package/lib/esm/sparql/irToAlgebra.js +117 -52
- package/lib/esm/sparql/irToAlgebra.js.map +1 -1
- package/lib/esm/sparql/ownedLinkCheck.js +6 -1
- package/lib/esm/sparql/ownedLinkCheck.js.map +1 -1
- package/lib/esm/utils/LinkedStorage.d.ts +7 -0
- package/lib/esm/utils/LinkedStorage.js +39 -12
- package/lib/esm/utils/LinkedStorage.js.map +1 -1
- package/lib/esm/utils/ShapeCatalog.d.ts +57 -0
- package/lib/esm/utils/ShapeCatalog.js +86 -0
- package/lib/esm/utils/ShapeCatalog.js.map +1 -0
- package/lib/esm/utils/ShapeClass.d.ts +73 -8
- package/lib/esm/utils/ShapeClass.js +245 -66
- package/lib/esm/utils/ShapeClass.js.map +1 -1
- package/lib/esm/utils/linkedError.d.ts +35 -0
- package/lib/esm/utils/linkedError.js +52 -0
- package/lib/esm/utils/linkedError.js.map +1 -0
- package/lib/esm/utils/registryCache.d.ts +15 -0
- package/lib/esm/utils/registryCache.js +50 -0
- package/lib/esm/utils/registryCache.js.map +1 -0
- package/lib/esm/utils/sharedState.d.ts +25 -0
- package/lib/esm/utils/sharedState.js +34 -0
- package/lib/esm/utils/sharedState.js.map +1 -0
- package/lib/esm/utils/unresolvedShape.d.ts +42 -0
- package/lib/esm/utils/unresolvedShape.js +68 -0
- package/lib/esm/utils/unresolvedShape.js.map +1 -0
- package/package.json +1 -1
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { getUniquePropertyShapes, getPropertyShape } from '../shapes/nodeShapeData.js';
|
|
2
2
|
import { PropertyPath, walkPropertyPath } from './PropertyPath.js';
|
|
3
|
-
import {
|
|
3
|
+
import { captureCatalog, getActiveShapeCatalog, getAllNodeShapes, getAllShapeClasses, getNodeShape, getShapeClass, withShapeCatalog, getQueryShapeClass, } from '../utils/ShapeClass.js';
|
|
4
4
|
import { createProxiedPathBuilder } from './ProxiedPathBuilder.js';
|
|
5
5
|
import { isExpressionNode, ExpressionNode } from '../expressions/ExpressionNode.js';
|
|
6
6
|
import { encodeValueExpr, decodeValueExpr } from './DslJsonExpression.js';
|
|
7
7
|
import { serializeWherePath, deserializeWherePath, } from './QueryBuilderSerialization.js';
|
|
8
|
+
import { topLevelDetails, unresolvedShapeError, unresolvedValueShapeError } from '../utils/unresolvedShape.js';
|
|
8
9
|
const isQueryBuilderObject = (obj) => obj !== null &&
|
|
9
10
|
typeof obj === 'object' &&
|
|
10
11
|
'property' in obj &&
|
|
@@ -45,11 +46,33 @@ const RELATION_OPTION_KEYS = new Set([
|
|
|
45
46
|
* Every mutation method returns a new FieldSet — the original is never modified.
|
|
46
47
|
*/
|
|
47
48
|
export class FieldSet {
|
|
48
|
-
constructor(shape, entries) {
|
|
49
|
+
constructor(shape, entries, catalog = FieldSet.captureFor(shape)) {
|
|
49
50
|
this.shape = shape;
|
|
50
51
|
this.entries = entries;
|
|
52
|
+
this._catalog = catalog;
|
|
53
|
+
}
|
|
54
|
+
/** The catalog this FieldSet resolves shapes in (undefined = the global registry). */
|
|
55
|
+
get catalog() {
|
|
56
|
+
return this._catalog;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* The catalog a FieldSet rooted at `shape` captures: the active one for an IRI or a
|
|
60
|
+
* shape it holds, none for a shape it does not (an authored class built by code that
|
|
61
|
+
* runs inside a project scope), else the catalog an adapter class came from.
|
|
62
|
+
*/
|
|
63
|
+
static captureFor(shape) {
|
|
64
|
+
if (typeof shape === 'function')
|
|
65
|
+
return captureCatalog(shape);
|
|
66
|
+
const active = getActiveShapeCatalog();
|
|
67
|
+
if (active === undefined || typeof shape === 'string')
|
|
68
|
+
return active;
|
|
69
|
+
return active.has(shape.id) ? active : undefined;
|
|
51
70
|
}
|
|
52
71
|
static for(shape, fieldsOrFn) {
|
|
72
|
+
const catalog = FieldSet.captureFor(shape);
|
|
73
|
+
if (catalog !== getActiveShapeCatalog()) {
|
|
74
|
+
return withShapeCatalog(catalog, () => FieldSet.for(shape, fieldsOrFn));
|
|
75
|
+
}
|
|
53
76
|
const resolved = FieldSet.resolveShapeInput(shape);
|
|
54
77
|
const resolvedShape = resolved.nodeShape;
|
|
55
78
|
if (typeof fieldsOrFn === 'function') {
|
|
@@ -97,6 +120,10 @@ export class FieldSet {
|
|
|
97
120
|
}
|
|
98
121
|
static all(shape, opts) {
|
|
99
122
|
var _a;
|
|
123
|
+
const catalog = FieldSet.captureFor(shape);
|
|
124
|
+
if (catalog !== getActiveShapeCatalog()) {
|
|
125
|
+
return withShapeCatalog(catalog, () => FieldSet.all(shape, opts));
|
|
126
|
+
}
|
|
100
127
|
const depth = (_a = opts === null || opts === void 0 ? void 0 : opts.depth) !== null && _a !== void 0 ? _a : 1;
|
|
101
128
|
if (depth < 1) {
|
|
102
129
|
throw new Error('FieldSet.all() requires depth >= 1. Use a node reference ({id}) for depth 0.');
|
|
@@ -117,7 +144,7 @@ export class FieldSet {
|
|
|
117
144
|
const entry = { path: new PropertyPath(nodeShape, [ps]) };
|
|
118
145
|
// If depth > 1, recurse into nested shapes
|
|
119
146
|
if (depth > 1 && ps.valueShape) {
|
|
120
|
-
const nestedShapeClass =
|
|
147
|
+
const nestedShapeClass = getQueryShapeClass(ps.valueShape);
|
|
121
148
|
if ((nestedShapeClass === null || nestedShapeClass === void 0 ? void 0 : nestedShapeClass.shape) && !visited.has(nestedShapeClass.shape.id)) {
|
|
122
149
|
visited.add(nestedShapeClass.shape.id);
|
|
123
150
|
const nestedFs = FieldSet.allForShape(nestedShapeClass.shape, depth - 1, visited);
|
|
@@ -158,15 +185,19 @@ export class FieldSet {
|
|
|
158
185
|
}
|
|
159
186
|
}
|
|
160
187
|
}
|
|
161
|
-
return new FieldSet(shape, merged);
|
|
188
|
+
return new FieldSet(shape, merged, sets[0]._catalog);
|
|
162
189
|
}
|
|
163
190
|
// ---------------------------------------------------------------------------
|
|
164
191
|
// Composition methods — each returns a new FieldSet
|
|
165
192
|
// ---------------------------------------------------------------------------
|
|
166
193
|
/** Returns a new FieldSet with only the given fields. */
|
|
167
194
|
select(fields) {
|
|
195
|
+
const catalog = this._catalog;
|
|
196
|
+
if (catalog !== getActiveShapeCatalog()) {
|
|
197
|
+
return withShapeCatalog(catalog, () => this.select(fields));
|
|
198
|
+
}
|
|
168
199
|
const entries = FieldSet.resolveInputs(this.shape, fields);
|
|
169
|
-
return new FieldSet(this.shape, entries);
|
|
200
|
+
return new FieldSet(this.shape, entries, this._catalog);
|
|
170
201
|
}
|
|
171
202
|
/**
|
|
172
203
|
* Clone this FieldSet, preserving the sub-select carrier fields
|
|
@@ -174,7 +205,7 @@ export class FieldSet {
|
|
|
174
205
|
* applying the supplied overrides. Used by `.limit()`/`.offset()`/`.orderBy()`.
|
|
175
206
|
*/
|
|
176
207
|
cloneWith(overrides) {
|
|
177
|
-
const clone = new FieldSet(this.shape, this.entries);
|
|
208
|
+
const clone = new FieldSet(this.shape, this.entries, this._catalog);
|
|
178
209
|
// The sub-select carrier fields are declared `readonly` (normally set once at
|
|
179
210
|
// construction via `forSubSelect`). Copy this FieldSet's identity onto the
|
|
180
211
|
// clone through a mutable view, then layer the pagination overrides on top.
|
|
@@ -201,6 +232,10 @@ export class FieldSet {
|
|
|
201
232
|
* the rest of the DSL, or a property-name string (`.orderBy('name')`).
|
|
202
233
|
*/
|
|
203
234
|
orderBy(paths, direction = 'ASC') {
|
|
235
|
+
const catalog = this._catalog;
|
|
236
|
+
if (catalog !== getActiveShapeCatalog()) {
|
|
237
|
+
return withShapeCatalog(catalog, () => this.orderBy(paths, direction));
|
|
238
|
+
}
|
|
204
239
|
const orderBy = typeof paths === 'function'
|
|
205
240
|
? this.orderByFromProxy(paths, direction)
|
|
206
241
|
: (Array.isArray(paths) ? paths : [paths]).map((label) => {
|
|
@@ -231,6 +266,10 @@ export class FieldSet {
|
|
|
231
266
|
}
|
|
232
267
|
/** Returns a new FieldSet with additional entries. */
|
|
233
268
|
add(fields) {
|
|
269
|
+
const catalog = this._catalog;
|
|
270
|
+
if (catalog !== getActiveShapeCatalog()) {
|
|
271
|
+
return withShapeCatalog(catalog, () => this.add(fields));
|
|
272
|
+
}
|
|
234
273
|
const newEntries = FieldSet.resolveInputs(this.shape, fields);
|
|
235
274
|
// Deduplicate
|
|
236
275
|
const existing = new Set(this.entries.map((e) => e.path.toString()));
|
|
@@ -240,24 +279,28 @@ export class FieldSet {
|
|
|
240
279
|
combined.push(entry);
|
|
241
280
|
}
|
|
242
281
|
}
|
|
243
|
-
return new FieldSet(this.shape, combined);
|
|
282
|
+
return new FieldSet(this.shape, combined, this._catalog);
|
|
244
283
|
}
|
|
245
284
|
/** Returns a new FieldSet without entries matching the given labels. */
|
|
246
285
|
remove(labels) {
|
|
247
286
|
const labelSet = new Set(labels);
|
|
248
287
|
const filtered = this.entries.filter((e) => { var _a; return !labelSet.has((_a = e.path.terminal) === null || _a === void 0 ? void 0 : _a.label); });
|
|
249
|
-
return new FieldSet(this.shape, filtered);
|
|
288
|
+
return new FieldSet(this.shape, filtered, this._catalog);
|
|
250
289
|
}
|
|
251
290
|
/** Synonym for replacing all entries — returns a new FieldSet with only the given fields. */
|
|
252
291
|
set(fields) {
|
|
292
|
+
const catalog = this._catalog;
|
|
293
|
+
if (catalog !== getActiveShapeCatalog()) {
|
|
294
|
+
return withShapeCatalog(catalog, () => this.set(fields));
|
|
295
|
+
}
|
|
253
296
|
const entries = FieldSet.resolveInputs(this.shape, fields);
|
|
254
|
-
return new FieldSet(this.shape, entries);
|
|
297
|
+
return new FieldSet(this.shape, entries, this._catalog);
|
|
255
298
|
}
|
|
256
299
|
/** Returns a new FieldSet keeping only entries matching the given labels. */
|
|
257
300
|
pick(labels) {
|
|
258
301
|
const labelSet = new Set(labels);
|
|
259
302
|
const filtered = this.entries.filter((e) => { var _a; return labelSet.has((_a = e.path.terminal) === null || _a === void 0 ? void 0 : _a.label); });
|
|
260
|
-
return new FieldSet(this.shape, filtered);
|
|
303
|
+
return new FieldSet(this.shape, filtered, this._catalog);
|
|
261
304
|
}
|
|
262
305
|
/** Returns all PropertyPaths in this FieldSet. */
|
|
263
306
|
paths() {
|
|
@@ -275,6 +318,10 @@ export class FieldSet {
|
|
|
275
318
|
* Shape is identified by its IRI, paths by dot-separated labels.
|
|
276
319
|
*/
|
|
277
320
|
toJSON() {
|
|
321
|
+
const catalog = this._catalog;
|
|
322
|
+
if (catalog !== getActiveShapeCatalog()) {
|
|
323
|
+
return withShapeCatalog(catalog, () => this.toJSON());
|
|
324
|
+
}
|
|
278
325
|
return { shape: this.shape.id, fields: this.toFieldsJSON() };
|
|
279
326
|
}
|
|
280
327
|
/** Serialize just the field entries (used for nested relation sub-fields). */
|
|
@@ -337,7 +384,7 @@ export class FieldSet {
|
|
|
337
384
|
var _a, _b;
|
|
338
385
|
const seg = entry.path.segments[idx];
|
|
339
386
|
const valueShapeId = (_a = seg === null || seg === void 0 ? void 0 : seg.valueShape) === null || _a === void 0 ? void 0 : _a.id;
|
|
340
|
-
return (valueShapeId && ((_b =
|
|
387
|
+
return (valueShapeId && ((_b = getQueryShapeClass(valueShapeId)) === null || _b === void 0 ? void 0 : _b.shape)) || this.shape;
|
|
341
388
|
}
|
|
342
389
|
/**
|
|
343
390
|
* Reconstruct a FieldSet from a JSON object.
|
|
@@ -352,7 +399,7 @@ export class FieldSet {
|
|
|
352
399
|
}
|
|
353
400
|
/** Parse one field entry (string leaf / computed / relation-keyed) against `shape`. */
|
|
354
401
|
static parseField(shape, raw) {
|
|
355
|
-
var _a, _b, _c, _d
|
|
402
|
+
var _a, _b, _c, _d;
|
|
356
403
|
// Leaf path (may carry inline `as(Shape)` casts).
|
|
357
404
|
if (typeof raw === 'string') {
|
|
358
405
|
return { path: FieldSet.walkPathWithCasts(shape, raw) };
|
|
@@ -392,7 +439,7 @@ export class FieldSet {
|
|
|
392
439
|
const idx = (_a = opts.whereIndex) !== null && _a !== void 0 ? _a : path.segments.length - 1;
|
|
393
440
|
const seg = path.segments[idx];
|
|
394
441
|
const valueShapeId = (_b = seg === null || seg === void 0 ? void 0 : seg.valueShape) === null || _b === void 0 ? void 0 : _b.id;
|
|
395
|
-
const scopedShape = (valueShapeId && ((_c =
|
|
442
|
+
const scopedShape = (valueShapeId && ((_c = getQueryShapeClass(valueShapeId)) === null || _c === void 0 ? void 0 : _c.shape)) || shape;
|
|
396
443
|
entry.scopedFilter = deserializeWherePath(scopedShape, opts.where);
|
|
397
444
|
entry.scopedFilterIndex = idx;
|
|
398
445
|
}
|
|
@@ -413,17 +460,37 @@ export class FieldSet {
|
|
|
413
460
|
if (subFields) {
|
|
414
461
|
const nested = opts.shape
|
|
415
462
|
? FieldSet.resolveShape(opts.shape)
|
|
416
|
-
:
|
|
463
|
+
: FieldSet.requireNestedShapeOf(path, shape);
|
|
417
464
|
entry.subSelect = FieldSet.fromFields(nested, subFields);
|
|
418
465
|
}
|
|
419
466
|
return entry;
|
|
420
467
|
}
|
|
468
|
+
/**
|
|
469
|
+
* The shape sub-fields of `path` are read against: its terminal segment's value shape, or
|
|
470
|
+
* `shape` when that segment declares none. A declared value shape that does not resolve is
|
|
471
|
+
* an error: reading the sub-fields against `shape` instead would resolve them on the wrong
|
|
472
|
+
* shape (or fail with a message about the wrong property).
|
|
473
|
+
*/
|
|
474
|
+
static requireNestedShapeOf(path, shape) {
|
|
475
|
+
var _a;
|
|
476
|
+
const nested = FieldSet.nestedShapeOf(path);
|
|
477
|
+
if (nested)
|
|
478
|
+
return nested;
|
|
479
|
+
const seg = path.segments[path.segments.length - 1];
|
|
480
|
+
if ((_a = seg === null || seg === void 0 ? void 0 : seg.valueShape) === null || _a === void 0 ? void 0 : _a.id) {
|
|
481
|
+
const owner = path.segments.length > 1
|
|
482
|
+
? FieldSet.nestedShapeOf(new PropertyPath(path.rootShape, path.segments.slice(0, -1)))
|
|
483
|
+
: path.rootShape;
|
|
484
|
+
throw unresolvedValueShapeError(`Cannot resolve valueShape '${seg.valueShape.id}' for property '${seg.label}' in path '${path.toString()}'`, seg, owner);
|
|
485
|
+
}
|
|
486
|
+
return shape;
|
|
487
|
+
}
|
|
421
488
|
/** The shape reached at the end of a relation path (its terminal segment's value shape). */
|
|
422
489
|
static nestedShapeOf(path) {
|
|
423
490
|
var _a, _b;
|
|
424
491
|
const seg = path.segments[path.segments.length - 1];
|
|
425
492
|
const valueShapeId = (_a = seg === null || seg === void 0 ? void 0 : seg.valueShape) === null || _a === void 0 ? void 0 : _a.id;
|
|
426
|
-
return (valueShapeId && ((_b =
|
|
493
|
+
return (valueShapeId && ((_b = getQueryShapeClass(valueShapeId)) === null || _b === void 0 ? void 0 : _b.shape)) || undefined;
|
|
427
494
|
}
|
|
428
495
|
// ---------------------------------------------------------------------------
|
|
429
496
|
// Private helpers
|
|
@@ -433,8 +500,21 @@ export class FieldSet {
|
|
|
433
500
|
* Accepts: ShapeConstructor (class with .shape), NodeShapeData, or IRI string.
|
|
434
501
|
*/
|
|
435
502
|
static resolveShapeInput(shape) {
|
|
503
|
+
var _a;
|
|
504
|
+
// Inside a catalog the catalog's data is the authority for every IRI it holds, so an
|
|
505
|
+
// authored class (or metadata) for one of them resolves to the catalog's shape — as
|
|
506
|
+
// `resolveShape` does for the builders.
|
|
507
|
+
const catalog = getActiveShapeCatalog();
|
|
508
|
+
if (catalog !== undefined && typeof shape !== 'string') {
|
|
509
|
+
const id = typeof shape === 'function' ? (_a = shape.shape) === null || _a === void 0 ? void 0 : _a.id : shape === null || shape === void 0 ? void 0 : shape.id;
|
|
510
|
+
const own = id ? catalog.get(id) : undefined;
|
|
511
|
+
if (own) {
|
|
512
|
+
const shapeClass = getQueryShapeClass(id);
|
|
513
|
+
return shapeClass ? { nodeShape: own, shapeClass } : { nodeShape: own };
|
|
514
|
+
}
|
|
515
|
+
}
|
|
436
516
|
if (typeof shape === 'string') {
|
|
437
|
-
const shapeClass =
|
|
517
|
+
const shapeClass = getQueryShapeClass(shape);
|
|
438
518
|
if (shapeClass === null || shapeClass === void 0 ? void 0 : shapeClass.shape) {
|
|
439
519
|
return { nodeShape: shapeClass.shape, shapeClass };
|
|
440
520
|
}
|
|
@@ -442,7 +522,7 @@ export class FieldSet {
|
|
|
442
522
|
// below is already supported, it just was not reachable from an IRI.
|
|
443
523
|
const nodeShape = getNodeShape(shape);
|
|
444
524
|
if (!nodeShape) {
|
|
445
|
-
throw
|
|
525
|
+
throw unresolvedShapeError(`Cannot resolve shape for '${shape}'`, topLevelDetails(shape));
|
|
446
526
|
}
|
|
447
527
|
return { nodeShape };
|
|
448
528
|
}
|
|
@@ -452,7 +532,7 @@ export class FieldSet {
|
|
|
452
532
|
}
|
|
453
533
|
// NodeShapeData: has .id directly — try to look up its ShapeConstructor for full proxy support
|
|
454
534
|
const nodeShape = shape;
|
|
455
|
-
const shapeClass = nodeShape.id ?
|
|
535
|
+
const shapeClass = nodeShape.id ? getQueryShapeClass(nodeShape.id) : undefined;
|
|
456
536
|
return shapeClass
|
|
457
537
|
? { nodeShape, shapeClass }
|
|
458
538
|
: { nodeShape };
|
|
@@ -493,9 +573,9 @@ export class FieldSet {
|
|
|
493
573
|
if (!(basePropertyShape === null || basePropertyShape === void 0 ? void 0 : basePropertyShape.valueShape)) {
|
|
494
574
|
throw new Error(`Property '${key}' has no valueShape; cannot resolve nested fields`);
|
|
495
575
|
}
|
|
496
|
-
const nestedShapeClass =
|
|
576
|
+
const nestedShapeClass = getQueryShapeClass(basePropertyShape.valueShape);
|
|
497
577
|
if (!nestedShapeClass || !nestedShapeClass.shape) {
|
|
498
|
-
throw
|
|
578
|
+
throw unresolvedValueShapeError(`Cannot resolve valueShape '${basePropertyShape.valueShape.id}' for property '${key}'`, basePropertyShape);
|
|
499
579
|
}
|
|
500
580
|
for (const nestedField of value) {
|
|
501
581
|
const nestedPath = walkPropertyPath(nestedShapeClass.shape, nestedField);
|
|
@@ -656,11 +736,19 @@ export class FieldSet {
|
|
|
656
736
|
return (_b = (_a = getShapeClass(id)) === null || _a === void 0 ? void 0 : _a.shape) !== null && _b !== void 0 ? _b : getNodeShape(id);
|
|
657
737
|
}
|
|
658
738
|
static shapeByLabel(label) {
|
|
739
|
+
// Inside a catalog every shape is data (core's built-ins aside), so scan its shapes;
|
|
740
|
+
// the global registry keeps scanning authored classes.
|
|
741
|
+
const matches = (shape) => !!shape && (shape.label === label || FieldSet.labelOfId(shape.id) === label);
|
|
742
|
+
if (getActiveShapeCatalog() !== undefined) {
|
|
743
|
+
for (const shape of getAllNodeShapes().values())
|
|
744
|
+
if (matches(shape))
|
|
745
|
+
return shape;
|
|
746
|
+
return undefined;
|
|
747
|
+
}
|
|
659
748
|
for (const cls of getAllShapeClasses().values()) {
|
|
660
749
|
const shape = cls.shape;
|
|
661
|
-
if (
|
|
750
|
+
if (matches(shape))
|
|
662
751
|
return shape;
|
|
663
|
-
}
|
|
664
752
|
}
|
|
665
753
|
return undefined;
|
|
666
754
|
}
|