@_linked/core 1.3.0 → 2.0.0-next.20260310085832

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 (143) hide show
  1. package/CHANGELOG.md +113 -10
  2. package/README.md +209 -14
  3. package/lib/cjs/index.d.ts +10 -2
  4. package/lib/cjs/index.js +31 -6
  5. package/lib/cjs/index.js.map +1 -1
  6. package/lib/cjs/package.d.ts +1 -1
  7. package/lib/cjs/queries/CreateBuilder.d.ts +38 -0
  8. package/lib/cjs/queries/CreateBuilder.js +100 -0
  9. package/lib/cjs/queries/CreateBuilder.js.map +1 -0
  10. package/lib/cjs/queries/CreateQuery.d.ts +3 -3
  11. package/lib/cjs/queries/CreateQuery.js.map +1 -1
  12. package/lib/cjs/queries/DeleteBuilder.d.ts +39 -0
  13. package/lib/cjs/queries/DeleteBuilder.js +85 -0
  14. package/lib/cjs/queries/DeleteBuilder.js.map +1 -0
  15. package/lib/cjs/queries/DeleteQuery.d.ts +3 -3
  16. package/lib/cjs/queries/DeleteQuery.js.map +1 -1
  17. package/lib/cjs/queries/FieldSet.d.ts +203 -0
  18. package/lib/cjs/queries/FieldSet.js +533 -0
  19. package/lib/cjs/queries/FieldSet.js.map +1 -0
  20. package/lib/cjs/queries/IRDesugar.d.ts +13 -8
  21. package/lib/cjs/queries/IRDesugar.js +143 -132
  22. package/lib/cjs/queries/IRDesugar.js.map +1 -1
  23. package/lib/cjs/queries/IRLower.js +1 -0
  24. package/lib/cjs/queries/IRLower.js.map +1 -1
  25. package/lib/cjs/queries/IntermediateRepresentation.d.ts +1 -0
  26. package/lib/cjs/queries/MutationQuery.d.ts +1 -1
  27. package/lib/cjs/queries/MutationQuery.js +1 -6
  28. package/lib/cjs/queries/MutationQuery.js.map +1 -1
  29. package/lib/cjs/queries/PropertyPath.d.ts +38 -0
  30. package/lib/cjs/queries/PropertyPath.js +82 -0
  31. package/lib/cjs/queries/PropertyPath.js.map +1 -0
  32. package/lib/cjs/queries/ProxiedPathBuilder.d.ts +14 -0
  33. package/lib/cjs/queries/ProxiedPathBuilder.js +29 -0
  34. package/lib/cjs/queries/ProxiedPathBuilder.js.map +1 -0
  35. package/lib/cjs/queries/QueryBuilder.d.ts +141 -0
  36. package/lib/cjs/queries/QueryBuilder.js +334 -0
  37. package/lib/cjs/queries/QueryBuilder.js.map +1 -0
  38. package/lib/cjs/queries/SelectQuery.d.ts +60 -134
  39. package/lib/cjs/queries/SelectQuery.js +67 -526
  40. package/lib/cjs/queries/SelectQuery.js.map +1 -1
  41. package/lib/cjs/queries/UpdateBuilder.d.ts +37 -0
  42. package/lib/cjs/queries/UpdateBuilder.js +84 -0
  43. package/lib/cjs/queries/UpdateBuilder.js.map +1 -0
  44. package/lib/cjs/queries/UpdateQuery.d.ts +3 -3
  45. package/lib/cjs/queries/UpdateQuery.js.map +1 -1
  46. package/lib/cjs/queries/WhereCondition.d.ts +18 -0
  47. package/lib/cjs/queries/WhereCondition.js +3 -0
  48. package/lib/cjs/queries/WhereCondition.js.map +1 -0
  49. package/lib/cjs/queries/resolveShape.d.ts +10 -0
  50. package/lib/cjs/queries/resolveShape.js +23 -0
  51. package/lib/cjs/queries/resolveShape.js.map +1 -0
  52. package/lib/cjs/shapes/SHACL.js +7 -5
  53. package/lib/cjs/shapes/SHACL.js.map +1 -1
  54. package/lib/cjs/shapes/Shape.d.ts +33 -52
  55. package/lib/cjs/shapes/Shape.js +36 -56
  56. package/lib/cjs/shapes/Shape.js.map +1 -1
  57. package/lib/cjs/sparql/SparqlAlgebra.d.ts +6 -1
  58. package/lib/cjs/sparql/algebraToString.js +10 -0
  59. package/lib/cjs/sparql/algebraToString.js.map +1 -1
  60. package/lib/cjs/sparql/irToAlgebra.js +6 -2
  61. package/lib/cjs/sparql/irToAlgebra.js.map +1 -1
  62. package/lib/cjs/test-helpers/query-fixtures.d.ts +568 -3049
  63. package/lib/cjs/test-helpers/query-fixtures.js +59 -18
  64. package/lib/cjs/test-helpers/query-fixtures.js.map +1 -1
  65. package/lib/cjs/test-helpers/test-utils.d.ts +18 -0
  66. package/lib/cjs/test-helpers/test-utils.js +47 -0
  67. package/lib/cjs/test-helpers/test-utils.js.map +1 -0
  68. package/lib/cjs/utils/Package.d.ts +8 -8
  69. package/lib/cjs/utils/Package.js.map +1 -1
  70. package/lib/cjs/utils/ShapeClass.d.ts +2 -2
  71. package/lib/cjs/utils/ShapeClass.js +4 -22
  72. package/lib/cjs/utils/ShapeClass.js.map +1 -1
  73. package/lib/esm/index.d.ts +10 -2
  74. package/lib/esm/index.js +23 -2
  75. package/lib/esm/index.js.map +1 -1
  76. package/lib/esm/package.d.ts +1 -1
  77. package/lib/esm/queries/CreateBuilder.d.ts +38 -0
  78. package/lib/esm/queries/CreateBuilder.js +96 -0
  79. package/lib/esm/queries/CreateBuilder.js.map +1 -0
  80. package/lib/esm/queries/CreateQuery.d.ts +3 -3
  81. package/lib/esm/queries/CreateQuery.js.map +1 -1
  82. package/lib/esm/queries/DeleteBuilder.d.ts +39 -0
  83. package/lib/esm/queries/DeleteBuilder.js +81 -0
  84. package/lib/esm/queries/DeleteBuilder.js.map +1 -0
  85. package/lib/esm/queries/DeleteQuery.d.ts +3 -3
  86. package/lib/esm/queries/DeleteQuery.js.map +1 -1
  87. package/lib/esm/queries/FieldSet.d.ts +203 -0
  88. package/lib/esm/queries/FieldSet.js +529 -0
  89. package/lib/esm/queries/FieldSet.js.map +1 -0
  90. package/lib/esm/queries/IRDesugar.d.ts +13 -8
  91. package/lib/esm/queries/IRDesugar.js +143 -132
  92. package/lib/esm/queries/IRDesugar.js.map +1 -1
  93. package/lib/esm/queries/IRLower.js +1 -0
  94. package/lib/esm/queries/IRLower.js.map +1 -1
  95. package/lib/esm/queries/IntermediateRepresentation.d.ts +1 -0
  96. package/lib/esm/queries/MutationQuery.d.ts +1 -1
  97. package/lib/esm/queries/MutationQuery.js +1 -6
  98. package/lib/esm/queries/MutationQuery.js.map +1 -1
  99. package/lib/esm/queries/PropertyPath.d.ts +38 -0
  100. package/lib/esm/queries/PropertyPath.js +77 -0
  101. package/lib/esm/queries/PropertyPath.js.map +1 -0
  102. package/lib/esm/queries/ProxiedPathBuilder.d.ts +14 -0
  103. package/lib/esm/queries/ProxiedPathBuilder.js +26 -0
  104. package/lib/esm/queries/ProxiedPathBuilder.js.map +1 -0
  105. package/lib/esm/queries/QueryBuilder.d.ts +141 -0
  106. package/lib/esm/queries/QueryBuilder.js +330 -0
  107. package/lib/esm/queries/QueryBuilder.js.map +1 -0
  108. package/lib/esm/queries/SelectQuery.d.ts +60 -134
  109. package/lib/esm/queries/SelectQuery.js +61 -515
  110. package/lib/esm/queries/SelectQuery.js.map +1 -1
  111. package/lib/esm/queries/UpdateBuilder.d.ts +37 -0
  112. package/lib/esm/queries/UpdateBuilder.js +80 -0
  113. package/lib/esm/queries/UpdateBuilder.js.map +1 -0
  114. package/lib/esm/queries/UpdateQuery.d.ts +3 -3
  115. package/lib/esm/queries/UpdateQuery.js.map +1 -1
  116. package/lib/esm/queries/WhereCondition.d.ts +18 -0
  117. package/lib/esm/queries/WhereCondition.js +2 -0
  118. package/lib/esm/queries/WhereCondition.js.map +1 -0
  119. package/lib/esm/queries/resolveShape.d.ts +10 -0
  120. package/lib/esm/queries/resolveShape.js +20 -0
  121. package/lib/esm/queries/resolveShape.js.map +1 -0
  122. package/lib/esm/shapes/SHACL.js +7 -5
  123. package/lib/esm/shapes/SHACL.js.map +1 -1
  124. package/lib/esm/shapes/Shape.d.ts +33 -52
  125. package/lib/esm/shapes/Shape.js +36 -53
  126. package/lib/esm/shapes/Shape.js.map +1 -1
  127. package/lib/esm/sparql/SparqlAlgebra.d.ts +6 -1
  128. package/lib/esm/sparql/algebraToString.js +10 -0
  129. package/lib/esm/sparql/algebraToString.js.map +1 -1
  130. package/lib/esm/sparql/irToAlgebra.js +6 -2
  131. package/lib/esm/sparql/irToAlgebra.js.map +1 -1
  132. package/lib/esm/test-helpers/query-fixtures.d.ts +568 -3049
  133. package/lib/esm/test-helpers/query-fixtures.js +59 -18
  134. package/lib/esm/test-helpers/query-fixtures.js.map +1 -1
  135. package/lib/esm/test-helpers/test-utils.d.ts +18 -0
  136. package/lib/esm/test-helpers/test-utils.js +41 -0
  137. package/lib/esm/test-helpers/test-utils.js.map +1 -0
  138. package/lib/esm/utils/Package.d.ts +8 -8
  139. package/lib/esm/utils/Package.js.map +1 -1
  140. package/lib/esm/utils/ShapeClass.d.ts +2 -2
  141. package/lib/esm/utils/ShapeClass.js +4 -22
  142. package/lib/esm/utils/ShapeClass.js.map +1 -1
  143. package/package.json +1 -1
@@ -1,15 +1,15 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.LinkedWhereQuery = exports.SetSize = exports.SelectQueryFactory = exports.onQueriesReady = exports.QueryPrimitiveSet = exports.QueryBoolean = exports.QueryNumber = exports.QueryDate = exports.QueryString = exports.QueryPrimitive = exports.Evaluation = exports.QueryShape = exports.QueryShapeSet = exports.BoundComponent = exports.QueryBuilderObject = exports.isWhereEvaluationPath = exports.WhereMethods = void 0;
3
+ exports.SetSize = exports.QueryPrimitiveSet = exports.QueryPrimitive = exports.Evaluation = exports.QueryShape = exports.QueryShapeSet = exports.evaluateSortCallback = exports.processWhereClause = exports.BoundComponent = exports.QueryBuilderObject = exports.isWhereEvaluationPath = exports.WhereMethods = void 0;
4
4
  const Shape_js_1 = require("../shapes/Shape.js");
5
5
  const ShapeSet_js_1 = require("../collections/ShapeSet.js");
6
6
  const shacl_js_1 = require("../ontologies/shacl.js");
7
7
  const CoreSet_js_1 = require("../collections/CoreSet.js");
8
8
  const ShapeClass_js_1 = require("../utils/ShapeClass.js");
9
- const QueryFactory_js_1 = require("./QueryFactory.js");
10
9
  const xsd_js_1 = require("../ontologies/xsd.js");
11
- const IRPipeline_js_1 = require("./IRPipeline.js");
12
- const queryDispatch_js_1 = require("./queryDispatch.js");
10
+ const ProxiedPathBuilder_js_1 = require("./ProxiedPathBuilder.js");
11
+ const FieldSet_js_1 = require("./FieldSet.js");
12
+ const PropertyPath_js_1 = require("./PropertyPath.js");
13
13
  const isSameRef = (a, b) => !!a && !!b && a.id === b.id;
14
14
  var WhereMethods;
15
15
  (function (WhereMethods) {
@@ -47,16 +47,16 @@ class QueryBuilderObject {
47
47
  return QueryShapeSet.create(originalValue, property, subject);
48
48
  }
49
49
  else if (typeof originalValue === 'string') {
50
- return new QueryString(originalValue, property, subject);
50
+ return new QueryPrimitive(originalValue, property, subject);
51
51
  }
52
52
  else if (typeof originalValue === 'number') {
53
- return new QueryNumber(originalValue, property, subject);
53
+ return new QueryPrimitive(originalValue, property, subject);
54
54
  }
55
55
  else if (typeof originalValue === 'boolean') {
56
- return new QueryBoolean(originalValue, property, subject);
56
+ return new QueryPrimitive(originalValue, property, subject);
57
57
  }
58
58
  else if (originalValue instanceof Date) {
59
- return new QueryDate(originalValue, property, subject);
59
+ return new QueryPrimitive(originalValue, property, subject);
60
60
  }
61
61
  else if (Array.isArray(originalValue)) {
62
62
  return new QueryPrimitiveSet(originalValue, property, subject);
@@ -95,23 +95,23 @@ class QueryBuilderObject {
95
95
  if (datatype) {
96
96
  if (singleValue) {
97
97
  if (isSameRef(datatype, xsd_js_1.xsd.integer)) {
98
- return new QueryNumber(0, property, subject);
98
+ return new QueryPrimitive(0, property, subject);
99
99
  }
100
100
  else if (isSameRef(datatype, xsd_js_1.xsd.boolean)) {
101
- return new QueryBoolean(false, property, subject);
101
+ return new QueryPrimitive(false, property, subject);
102
102
  }
103
103
  else if (isSameRef(datatype, xsd_js_1.xsd.dateTime) ||
104
104
  isSameRef(datatype, xsd_js_1.xsd.date)) {
105
- return new QueryDate(new Date(), property, subject);
105
+ return new QueryPrimitive(new Date(), property, subject);
106
106
  }
107
107
  else if (isSameRef(datatype, xsd_js_1.xsd.string)) {
108
- return new QueryString('', property, subject);
108
+ return new QueryPrimitive('', property, subject);
109
109
  }
110
110
  }
111
111
  else {
112
112
  //TODO review this, do we need property & subject in both of these? currently yes, but why
113
113
  return new QueryPrimitiveSet([''], property, subject, [
114
- new QueryString('', property, subject),
114
+ new QueryPrimitive('', property, subject),
115
115
  ]);
116
116
  }
117
117
  }
@@ -138,30 +138,17 @@ class QueryBuilderObject {
138
138
  isSameRef(property.nodeKind, shacl_js_1.shacl.BlankNodeOrLiteral)) {
139
139
  if (singleValue) {
140
140
  //default to string if no datatype is set
141
- return new QueryString('', property, subject);
141
+ return new QueryPrimitive('', property, subject);
142
142
  }
143
143
  else {
144
144
  //TODO review this, do we need property & subject in both of these? currently yes, but why
145
145
  return new QueryPrimitiveSet([''], property, subject, [
146
- new QueryString('', property, subject),
146
+ new QueryPrimitive('', property, subject),
147
147
  ]);
148
148
  }
149
149
  }
150
150
  //if an object is expected and no value shape is set, then warn
151
151
  throw Error(`No shape set for objectProperty ${property.parentNodeShape.label}.${property.label}`);
152
- // //and use a generic shape
153
- // const shapeValue = new (Shape as any)(new TestNode(path));
154
- // if (singleValue) {
155
- // return QueryShape.create(shapeValue, property, subject);
156
- // } else {
157
- // //check if shapeValue is iterable
158
- // if (!(Symbol.iterator in Object(shapeValue))) {
159
- // throw new Error(
160
- // `Property ${property.parentNodeShape.label}.${property.label} is not marked as single value (maxCount:1), but the value is not iterable`,
161
- // );
162
- // }
163
- // return QueryShapeSet.create(new ShapeSet(shapeValue), property, subject);
164
- // }
165
152
  }
166
153
  static getOriginalSource(endValue) {
167
154
  if (typeof endValue === 'undefined')
@@ -169,7 +156,7 @@ class QueryBuilderObject {
169
156
  if (endValue instanceof QueryPrimitiveSet) {
170
157
  return new ShapeSet_js_1.ShapeSet(endValue.contents.map((endValue) => this.getOriginalSource(endValue)));
171
158
  }
172
- if (endValue instanceof QueryString) {
159
+ if (endValue instanceof QueryPrimitive) {
173
160
  return endValue.subject
174
161
  ? this.getOriginalSource(endValue.subject)
175
162
  : endValue.originalValue;
@@ -203,7 +190,6 @@ class QueryBuilderObject {
203
190
  return new BoundComponent(component, this);
204
191
  }
205
192
  limit(lim) {
206
- console.log(lim);
207
193
  }
208
194
  /**
209
195
  * Returns the path of properties that were requested to reach this value
@@ -232,45 +218,6 @@ class BoundComponent extends QueryBuilderObject {
232
218
  this.originalValue = originalValue;
233
219
  this.source = source;
234
220
  }
235
- getParentQueryFactory() {
236
- let parentQuery = this.originalValue.query;
237
- if (parentQuery instanceof SelectQueryFactory) {
238
- return parentQuery;
239
- }
240
- if (typeof parentQuery === 'object') {
241
- if (Object.keys(parentQuery).length > 1) {
242
- throw new Error('Only one key is allowed to map a query to a property for linkedSetComponents');
243
- }
244
- for (let key in parentQuery) {
245
- if (parentQuery[key] instanceof SelectQueryFactory) {
246
- return parentQuery[key];
247
- }
248
- throw new Error('Unknown value type for query object. Keep to this format: {propName: Shape.query(s => ...)}');
249
- }
250
- }
251
- throw new Error('Unknown data query type. Expected a SelectQueryFactory (from Shape.query()) or an object with 1 key whose value is a SelectQueryFactory');
252
- }
253
- getPropertyPath() {
254
- let sourcePath = this.source.getPropertyPath();
255
- let requestQuery = this.getParentQueryFactory();
256
- let compSelectQuery = requestQuery.getQueryPaths();
257
- if (Array.isArray(sourcePath)) {
258
- if (Array.isArray(compSelectQuery)) {
259
- // QueryPath[] — unwrap single-element arrays for compact representation
260
- const unwrapped = compSelectQuery.length === 1
261
- ? Array.isArray(compSelectQuery[0]) && compSelectQuery[0].length === 1
262
- ? compSelectQuery[0][0]
263
- : compSelectQuery[0]
264
- : compSelectQuery;
265
- sourcePath.push(unwrapped);
266
- }
267
- else {
268
- // CustomQueryObject
269
- sourcePath.push(compSelectQuery);
270
- }
271
- }
272
- return sourcePath;
273
- }
274
221
  }
275
222
  exports.BoundComponent = BoundComponent;
276
223
  /**
@@ -289,12 +236,37 @@ const processWhereClause = (validation, shape) => {
289
236
  if (!shape) {
290
237
  throw new Error('Cannot process where clause without shape');
291
238
  }
292
- return new LinkedWhereQuery(shape, validation).getWherePath();
239
+ const proxy = (0, ProxiedPathBuilder_js_1.createProxiedPathBuilder)(shape);
240
+ const evaluation = validation(proxy);
241
+ return evaluation.getWherePath();
293
242
  }
294
243
  else {
295
244
  return validation.getWherePath();
296
245
  }
297
246
  };
247
+ exports.processWhereClause = processWhereClause;
248
+ /**
249
+ * Evaluate a sort callback through the proxy and extract a SortByPath.
250
+ * This is a standalone helper that replaces the need for the former SelectQueryFactory.sortBy().
251
+ */
252
+ const evaluateSortCallback = (shape, sortFn, direction = 'ASC') => {
253
+ const proxy = (0, ProxiedPathBuilder_js_1.createProxiedPathBuilder)(shape);
254
+ const response = sortFn(proxy);
255
+ const nodeShape = shape.shape;
256
+ const paths = [];
257
+ if (response instanceof QueryBuilderObject || response instanceof QueryPrimitiveSet) {
258
+ paths.push(new PropertyPath_js_1.PropertyPath(nodeShape, FieldSet_js_1.FieldSet.collectPropertySegments(response)));
259
+ }
260
+ else if (Array.isArray(response)) {
261
+ for (const item of response) {
262
+ if (item instanceof QueryBuilderObject) {
263
+ paths.push(new PropertyPath_js_1.PropertyPath(nodeShape, FieldSet_js_1.FieldSet.collectPropertySegments(item)));
264
+ }
265
+ }
266
+ }
267
+ return { paths, direction };
268
+ };
269
+ exports.evaluateSortCallback = evaluateSortCallback;
298
270
  class QueryShapeSet extends QueryBuilderObject {
299
271
  constructor(_originalValue, property, subject) {
300
272
  super(property, subject);
@@ -350,8 +322,6 @@ class QueryShapeSet extends QueryBuilderObject {
350
322
  return originalShapeSet[key].bind(originalShapeSet);
351
323
  }
352
324
  else if (key !== 'then' && key !== '$$typeof') {
353
- //TODO: there is a strange bug with "then" being called, only for queries that access ShapeSets (multi value props), but I'm not sure where it comes from
354
- //hiding the warning for now in that case as it doesn't seem to affect the results
355
325
  console.warn('Could not find property shape for key ' +
356
326
  key +
357
327
  ' on shape ' +
@@ -452,16 +422,16 @@ class QueryShapeSet extends QueryBuilderObject {
452
422
  throw new Error('You cannot call where() from within a where() clause. Consider using some() or every() instead');
453
423
  }
454
424
  let leastSpecificShape = this.getOriginalValue().getLeastSpecificShape();
455
- this.wherePath = processWhereClause(validation, leastSpecificShape);
425
+ this.wherePath = (0, exports.processWhereClause)(validation, leastSpecificShape);
456
426
  //return this.proxy because after Shape.friends.where() we can call other methods of Shape.friends
457
427
  //and for that we need the proxy
458
428
  return this.proxy;
459
429
  }
460
430
  select(subQueryFn) {
461
- let leastSpecificShape = this.getOriginalValue().getLeastSpecificShape();
462
- let subQuery = new SelectQueryFactory(leastSpecificShape, subQueryFn);
463
- subQuery.parentQueryPath = this.getPropertyPath();
464
- return subQuery;
431
+ const leastSpecificShape = this.getOriginalValue().getLeastSpecificShape();
432
+ const parentSegments = FieldSet_js_1.FieldSet.collectPropertySegments(this);
433
+ const fs = FieldSet_js_1.FieldSet.forSubSelect(leastSpecificShape, subQueryFn, parentSegments);
434
+ return fs;
465
435
  }
466
436
  selectAll() {
467
437
  let leastSpecificShape = this.getOriginalValue().getLeastSpecificShape();
@@ -480,7 +450,7 @@ class QueryShapeSet extends QueryBuilderObject {
480
450
  let leastSpecificShape = this.getOriginalValue().getLeastSpecificShape();
481
451
  //do we need to store this here? or are we accessing the evaluation and then going backwards?
482
452
  //in that case just pass it to the evaluation and don't use this.wherePath
483
- let wherePath = processWhereClause(validation, leastSpecificShape);
453
+ let wherePath = (0, exports.processWhereClause)(validation, leastSpecificShape);
484
454
  return new SetEvaluation(this, method, [wherePath]);
485
455
  }
486
456
  }
@@ -494,12 +464,6 @@ class QueryShape extends QueryBuilderObject {
494
464
  return (this.originalValue.__queryContextId ||
495
465
  this.originalValue['id']);
496
466
  }
497
- // where(validation: WhereClause<S>): this {
498
- // let nodeShape = this.originalValue.nodeShape;
499
- // this.wherePath = processWhereClause(validation, nodeShape);
500
- // //return this because after Shape.friends.where() we can call other methods of Shape.friends
501
- // return this.proxy;
502
- // }
503
467
  static create(original, property, subject) {
504
468
  let instance = new QueryShape(original, property, subject);
505
469
  let proxy = this.proxifyQueryShape(instance);
@@ -524,27 +488,9 @@ class QueryShape extends QueryBuilderObject {
524
488
  //if not, then a method/accessor of the original shape was called
525
489
  //then check if we have indexed any property shapes with that name for this shapes NodeShape
526
490
  //NOTE: this will only work with a @linkedProperty decorator
527
- // let propertyShape = originalShape.nodeShape
528
- // .getPropertyShapes()
529
- // .find((propertyShape) => propertyShape.label === key);
530
491
  let propertyShape = (0, ShapeClass_js_1.getPropertyShapeByLabel)(originalShape.constructor, key);
531
492
  if (propertyShape) {
532
- //generate the query shape based on the property shape
533
- // let nodeValue;
534
- // if(propertyShape.maxCount <= 1) {
535
- // nodeValue = new TestNode(propertyShape.path);
536
- // } else {
537
- // nodeValue = new NodeSet(new TestNode(propertyShape.path));
538
- // }
539
493
  return QueryBuilderObject.generatePathValue(propertyShape, target);
540
- //get the value of the property from the original shape
541
- // let value = originalShape[key];
542
- // //convert the value into a query value
543
- // return QueryBuilderObject.convertOriginal(
544
- // value,
545
- // propertyShape,
546
- // queryShape,
547
- // );
548
494
  }
549
495
  }
550
496
  if (key !== 'then' && key !== '$$typeof') {
@@ -554,8 +500,6 @@ class QueryShape extends QueryBuilderObject {
554
500
  //https://stackoverflow.com/a/49725198/977206
555
501
  const stackLines = stack.split('\n').slice(1); //remove the "Error" line
556
502
  console.warn(`${originalShape.constructor.name}.${key.toString()} is accessed in a query, but it does not have a @linkedProperty decorator. Queries can only access decorated get/set methods. ${stackLines.join('\n')}`);
557
- // } else {
558
- // console.error('Proxy is accessed like a promise');
559
503
  }
560
504
  return originalShape[key];
561
505
  },
@@ -571,18 +515,16 @@ class QueryShape extends QueryBuilderObject {
571
515
  }
572
516
  return QueryShape.create(newOriginal, this.property, this.subject);
573
517
  }
574
- // else return this
575
518
  return this;
576
- // return this.proxy;
577
519
  }
578
520
  equals(otherValue) {
579
521
  return new Evaluation(this, WhereMethods.EQUALS, [otherValue]);
580
522
  }
581
523
  select(subQueryFn) {
582
- let leastSpecificShape = (0, ShapeClass_js_1.getShapeClass)(this.getOriginalValue().nodeShape.id);
583
- let subQuery = new SelectQueryFactory(leastSpecificShape, subQueryFn);
584
- subQuery.parentQueryPath = this.getPropertyPath();
585
- return subQuery;
524
+ const leastSpecificShape = (0, ShapeClass_js_1.getShapeClass)(this.getOriginalValue().nodeShape.id);
525
+ const parentSegments = FieldSet_js_1.FieldSet.collectPropertySegments(this);
526
+ const fs = FieldSet_js_1.FieldSet.forSubSelect(leastSpecificShape, subQueryFn, parentSegments);
527
+ return fs;
586
528
  }
587
529
  selectAll() {
588
530
  let leastSpecificShape = (0, ShapeClass_js_1.getShapeClass)(this.getOriginalValue().nodeShape.id);
@@ -645,13 +587,13 @@ class Evaluation {
645
587
  }
646
588
  and(subQuery) {
647
589
  this._andOr.push({
648
- and: processWhereClause(subQuery),
590
+ and: (0, exports.processWhereClause)(subQuery),
649
591
  });
650
592
  return this;
651
593
  }
652
594
  or(subQuery) {
653
595
  this._andOr.push({
654
- or: processWhereClause(subQuery),
596
+ or: (0, exports.processWhereClause)(subQuery),
655
597
  });
656
598
  return this;
657
599
  }
@@ -660,8 +602,11 @@ exports.Evaluation = Evaluation;
660
602
  class SetEvaluation extends Evaluation {
661
603
  }
662
604
  /**
663
- * The class that is used for when JS primitives are converted to a QueryValue
664
- * This is extended by QueryString, QueryNumber, QueryBoolean, etc
605
+ * Concrete query wrapper for JS primitive values (string, number, boolean, Date).
606
+ *
607
+ * Replaces the former abstract class + subclasses (QueryString, QueryNumber,
608
+ * QueryBoolean, QueryDate) — the type parameter T carries the primitive type,
609
+ * so separate subclasses are unnecessary.
665
610
  */
666
611
  class QueryPrimitive extends QueryBuilderObject {
667
612
  constructor(originalValue, property, subject) {
@@ -676,26 +621,12 @@ class QueryPrimitive extends QueryBuilderObject {
676
621
  }
677
622
  where(validation) {
678
623
  // let nodeShape = this.subject.getOriginalValue().nodeShape;
679
- this.wherePath = processWhereClause(validation, new QueryString(''));
624
+ this.wherePath = (0, exports.processWhereClause)(validation, new QueryPrimitive(''));
680
625
  //return this because after Shape.friends.where() we can call other methods of Shape.friends
681
626
  return this;
682
627
  }
683
628
  }
684
629
  exports.QueryPrimitive = QueryPrimitive;
685
- //@TODO: QueryString, QueryNumber, QueryBoolean, QueryDate can all be replaced with QueryPrimitive, and we can infer the original type, no need for these extra classes
686
- //UPDATE some of this has started. Query response to result conversion is using QueryPrimitive only
687
- class QueryString extends QueryPrimitive {
688
- }
689
- exports.QueryString = QueryString;
690
- class QueryDate extends QueryPrimitive {
691
- }
692
- exports.QueryDate = QueryDate;
693
- class QueryNumber extends QueryPrimitive {
694
- }
695
- exports.QueryNumber = QueryNumber;
696
- class QueryBoolean extends QueryPrimitive {
697
- }
698
- exports.QueryBoolean = QueryBoolean;
699
630
  class QueryPrimitiveSet extends QueryBuilderObject {
700
631
  constructor(originalValue, property, subject, items) {
701
632
  super(property, subject);
@@ -714,7 +645,7 @@ class QueryPrimitiveSet extends QueryBuilderObject {
714
645
  createNew(...args) {
715
646
  return new this.constructor(this.property, this.subject, ...args);
716
647
  }
717
- //TODO: see if we can merge these methods of QueryString and QueryPrimitiveSet and soon other things like QueryNumber
648
+ //TODO: see if we can merge these methods of QueryPrimitive and QueryPrimitiveSet
718
649
  // so that they're only defined once
719
650
  equals(other) {
720
651
  return new Evaluation(this, WhereMethods.EQUALS, [other]);
@@ -750,360 +681,7 @@ class QueryPrimitiveSet extends QueryBuilderObject {
750
681
  }
751
682
  }
752
683
  exports.QueryPrimitiveSet = QueryPrimitiveSet;
753
- let documentLoaded = false;
754
- let callbackStack = [];
755
- const docReady = () => {
756
- documentLoaded = true;
757
- callbackStack.forEach((callback) => callback());
758
- callbackStack = [];
759
- };
760
- if (typeof document === 'undefined' || document.readyState !== 'loading') {
761
- docReady();
762
- }
763
- else {
764
- documentLoaded = false;
765
- document.addEventListener('DOMContentLoaded', () => () => {
766
- docReady();
767
- });
768
- setTimeout(() => {
769
- if (!documentLoaded) {
770
- console.warn('⚠️ Forcing init after timeout');
771
- docReady();
772
- }
773
- }, 3500);
774
- }
775
- //only continue to parse the query if the document is ready, and all shapes from initial bundles are loaded
776
- var onQueriesReady = (callback) => {
777
- if (!documentLoaded) {
778
- callbackStack.push(callback);
779
- }
780
- else {
781
- callback();
782
- }
783
- };
784
- exports.onQueriesReady = onQueriesReady;
785
- class SelectQueryFactory extends QueryFactory_js_1.QueryFactory {
786
- constructor(shape, queryBuildFn, subject) {
787
- super();
788
- this.shape = shape;
789
- this.queryBuildFn = queryBuildFn;
790
- this.subject = subject;
791
- let promise, resolve, reject;
792
- promise = new Promise((res, rej) => {
793
- resolve = res;
794
- reject = rej;
795
- });
796
- this.initPromise = { promise, resolve, reject, complete: false };
797
- //only continue to parse the query if the document is ready, and all shapes from initial bundles are loaded
798
- if (typeof document === 'undefined' || document.readyState !== 'loading') {
799
- this.init();
800
- }
801
- else {
802
- document.addEventListener('DOMContentLoaded', () => this.init());
803
- setTimeout(() => {
804
- if (!this.initPromise.complete) {
805
- console.warn('⚠️ Forcing init after timeout');
806
- this.init();
807
- }
808
- }, 3500);
809
- }
810
- }
811
- setLimit(limit) {
812
- this.limit = limit;
813
- }
814
- getLimit() {
815
- return this.limit;
816
- }
817
- setOffset(offset) {
818
- this.offset = offset;
819
- }
820
- getOffset() {
821
- return this.offset;
822
- }
823
- setSubject(subject) {
824
- this.subject = subject;
825
- return this;
826
- }
827
- where(validation) {
828
- this.wherePath = processWhereClause(validation, this.shape);
829
- return this;
830
- }
831
- exec() {
832
- return (0, queryDispatch_js_1.getQueryDispatch)().selectQuery(this.build());
833
- }
834
- /**
835
- * Returns the raw pipeline input for this query.
836
- * Used internally by build() and by test helpers that need
837
- * to feed factory state into individual pipeline stages.
838
- */
839
- toRawInput() {
840
- const input = {
841
- select: this.getQueryPaths(),
842
- subject: this.getSubject(),
843
- limit: this.limit,
844
- offset: this.offset,
845
- shape: this.shape,
846
- sortBy: this.getSortByPath(),
847
- singleResult: this.singleResult ||
848
- !!(this.subject &&
849
- ('id' in this.subject || 'id' in this.subject)),
850
- };
851
- if (this.wherePath) {
852
- input.where = this.wherePath;
853
- }
854
- return input;
855
- }
856
- build() {
857
- return (0, IRPipeline_js_1.buildSelectQuery)(this.toRawInput());
858
- }
859
- getSubject() {
860
- var _a, _b;
861
- //if the subject is a QueryShape which comes from query context
862
- //then it will carry a query context id and we convert it to a node reference
863
- //NOTE: its important to access originalValue instead of .node directly because QueryShape.node may be undefined
864
- if ((_b = (_a = this.subject) === null || _a === void 0 ? void 0 : _a.originalValue) === null || _b === void 0 ? void 0 : _b.__queryContextId) {
865
- return convertQueryContext(this.subject);
866
- }
867
- // }
868
- return this.subject;
869
- }
870
- /**
871
- * Returns an array of query paths
872
- * A single query can request multiple things in multiple "query paths" (For example this is using 2 paths: Shape.select(p => [p.name, p.friends.name]))
873
- * Each query path is returned as array of the property paths requested, with potential where clauses (together called a QueryStep)
874
- */
875
- getQueryPaths(response = this.traceResponse) {
876
- let queryPaths = [];
877
- let queryObject;
878
- //if the trace response is an array, then multiple paths were requested
879
- if (response instanceof QueryBuilderObject ||
880
- response instanceof QueryPrimitiveSet) {
881
- //if it's a single value, then only one path was requested, and we can add it directly
882
- queryPaths.push(response.getPropertyPath());
883
- }
884
- else if (Array.isArray(response) || response instanceof Set) {
885
- response.forEach((endValue) => {
886
- if (endValue instanceof QueryBuilderObject) {
887
- queryPaths.push(endValue.getPropertyPath());
888
- }
889
- else if (endValue instanceof SelectQueryFactory) {
890
- queryPaths.push(endValue.getQueryPaths());
891
- }
892
- });
893
- }
894
- else if (response instanceof Evaluation) {
895
- queryPaths.push(response.getWherePath());
896
- }
897
- else if (response instanceof SelectQueryFactory) {
898
- queryPaths.push(response.getQueryPaths());
899
- }
900
- else if (!response) {
901
- //that's totally fine. For example Person.select().where(p => p.name.equals('John'))
902
- //will return all persons with the name John, but no properties are selected for these persons
903
- }
904
- //if it's an object
905
- else if (typeof response === 'object') {
906
- queryObject = {};
907
- //then loop over all the keys
908
- Object.getOwnPropertyNames(response).forEach((key) => {
909
- //and add the property paths for each key
910
- const value = response[key];
911
- //TODO: we could potentially make Evaluation extend QueryValue, and rename getPropertyPath to something more generic,
912
- //that way we can simplify the code perhaps? Or would we loose type clarity? (QueryStep is the generic one for QueryValue, and Evaluation can just return WherePath right?)
913
- if (value instanceof QueryBuilderObject ||
914
- value instanceof QueryPrimitiveSet) {
915
- queryObject[key] = value.getPropertyPath();
916
- }
917
- else if (value instanceof Evaluation) {
918
- queryObject[key] = value.getWherePath();
919
- }
920
- else {
921
- throw Error('Unknown trace response type for key ' + key);
922
- }
923
- });
924
- }
925
- else {
926
- throw Error('Unknown trace response type');
927
- }
928
- if (this.parentQueryPath) {
929
- queryPaths = this.parentQueryPath.concat([
930
- queryObject || queryPaths,
931
- ]);
932
- //reset the variable so it doesn't get used again below
933
- queryObject = null;
934
- }
935
- return queryObject || queryPaths;
936
- }
937
- isValidSetResult(qResults) {
938
- return qResults.every((qResult) => {
939
- return this.isValidResult(qResult);
940
- });
941
- }
942
- isValidResult(qResult) {
943
- let select = this.getQueryPaths();
944
- if (Array.isArray(select)) {
945
- return this.isValidQueryPathsResult(qResult, select);
946
- }
947
- else if (typeof select === 'object') {
948
- return this.isValidCustomObjectResult(qResult, select);
949
- }
950
- }
951
- clone() {
952
- return new SelectQueryFactory(this.shape, this.queryBuildFn, this.subject);
953
- }
954
- /**
955
- * Makes a clone of the query template, sets the subject and executes the query
956
- * @param subject
957
- */
958
- execFor(subject) {
959
- //TODO: Differentiate between the result of Shape.query and the internal query in Shape.select?
960
- // so that Shape.query can never be executed. Its just a template
961
- return this.clone().setSubject(subject).exec();
962
- }
963
- patchResultPromise(p) {
964
- let pAdjusted = p;
965
- p['where'] = (validation) => {
966
- // preventExec();
967
- this.where(validation);
968
- return pAdjusted;
969
- };
970
- p['limit'] = (lim) => {
971
- this.setLimit(lim);
972
- return pAdjusted;
973
- };
974
- p['sortBy'] = (sortFn, direction = 'ASC') => {
975
- this.sortBy(sortFn, direction);
976
- return pAdjusted;
977
- };
978
- p['one'] = () => {
979
- this.setLimit(1);
980
- this.singleResult = true;
981
- return pAdjusted;
982
- };
983
- return p;
984
- }
985
- sortBy(sortFn, direction) {
986
- let queryShape = this.getQueryShape();
987
- if (sortFn) {
988
- this.sortResponse = sortFn(queryShape, this);
989
- this.sortDirection = direction;
990
- }
991
- return this;
992
- }
993
- init() {
994
- let queryShape = this.getQueryShape();
995
- if (this.queryBuildFn) {
996
- let queryResponse = this.queryBuildFn(queryShape, this);
997
- this.traceResponse = queryResponse;
998
- }
999
- this.initPromise.resolve(this.traceResponse);
1000
- this.initPromise.complete = true;
1001
- }
1002
- initialized() {
1003
- return this.initPromise.promise;
1004
- }
1005
- /**
1006
- * Returns the dummy shape instance who's properties can be accessed freely inside a queryBuildFn
1007
- * It is used to trace the properties that are accessed in the queryBuildFn
1008
- * @private
1009
- */
1010
- getQueryShape() {
1011
- let queryShape;
1012
- //if the given class already extends QueryValue
1013
- if (this.shape instanceof QueryBuilderObject) {
1014
- //then we're likely dealing with QueryPrimitives (end values like strings)
1015
- //and we can use the given query value directly for the query evaluation
1016
- queryShape = this.shape;
1017
- }
1018
- else {
1019
- //else a shape class is given, and we need to create a dummy node to apply and trace the query
1020
- let dummyShape = new this.shape();
1021
- queryShape = QueryShape.create(dummyShape);
1022
- }
1023
- return queryShape;
1024
- }
1025
- getSortByPath() {
1026
- if (!this.sortResponse)
1027
- return null;
1028
- //TODO: we should put more restrictions on sortBy and getting query paths from the response
1029
- // currently it reuses much of the select logic, but for example using .where() should probably not be allowed in a sortBy function?
1030
- return {
1031
- paths: this.getQueryPaths(this.sortResponse),
1032
- direction: this.sortDirection,
1033
- };
1034
- }
1035
- isValidQueryPathsResult(qResult, select) {
1036
- return select.every((path) => {
1037
- return this.isValidQueryPathResult(qResult, path);
1038
- });
1039
- }
1040
- isValidQueryPathResult(qResult, path, nameOverwrite) {
1041
- if (Array.isArray(path)) {
1042
- return this.isValidQueryStepResult(qResult, path[0], path.splice(1), nameOverwrite);
1043
- }
1044
- else {
1045
- if (path.firstPath) {
1046
- return this.isValidQueryPathResult(qResult, path.firstPath);
1047
- }
1048
- else if (path.path) {
1049
- return this.isValidQueryPathResult(qResult, path.path);
1050
- }
1051
- }
1052
- }
1053
- isValidQueryStepResult(qResult, step, restPath = [], nameOverwrite) {
1054
- if (!qResult) {
1055
- return false;
1056
- }
1057
- if (step.property) {
1058
- //if a name overwrite is given we check if that key exists instead of the property label
1059
- //this happens with custom objects: for the first property step, the named key will be the accessKey used in the result instead of the first property label.
1060
- //e.g. {title:item.name} in a query will result in a "title" key in the result, not "name"
1061
- const accessKey = nameOverwrite || step.property.label;
1062
- //also check if this property needs to have a value (minCount > 0), if not it can be empty and undefined
1063
- // if (!qResult.hasOwnProperty(accessKey) && (step as PropertyQueryStep).property.minCount > 0) {
1064
- //the key must be in the object. If there is no value then it should be null (or undefined, but null works better with JSON.stringify, as it keeps the key. Whilst undefined keys get removed)
1065
- if (!qResult.hasOwnProperty(accessKey)) {
1066
- return false;
1067
- }
1068
- if (restPath.length > 0) {
1069
- return this.isValidQueryStepResult(qResult[accessKey], restPath[0], restPath.splice(1));
1070
- }
1071
- return true;
1072
- }
1073
- else if (step.count) {
1074
- return this.isValidQueryStepResult(qResult, step.count[0]);
1075
- }
1076
- else if (Array.isArray(step)) {
1077
- return step.every((subStep) => {
1078
- return this.isValidQueryPathResult(qResult, subStep);
1079
- });
1080
- }
1081
- else if (typeof step === 'object') {
1082
- if (Array.isArray(qResult)) {
1083
- return qResult.every((singleResult) => {
1084
- return this.isValidQueryStepResult(singleResult, step);
1085
- });
1086
- }
1087
- return this.isValidCustomObjectResult(qResult, step);
1088
- }
1089
- }
1090
- isValidCustomObjectResult(qResult, step) {
1091
- //for custom objects, all keys need to be defined, even if the value is undefined
1092
- for (let key in step) {
1093
- if (!qResult.hasOwnProperty(key)) {
1094
- return false;
1095
- }
1096
- let path = step[key];
1097
- if (!this.isValidQueryPathResult(qResult, path, key)) {
1098
- return false;
1099
- }
1100
- // return this.isValidQueryPathResult(qResult[key], path);
1101
- }
1102
- return true;
1103
- }
1104
- }
1105
- exports.SelectQueryFactory = SelectQueryFactory;
1106
- class SetSize extends QueryNumber {
684
+ class SetSize extends QueryPrimitive {
1107
685
  constructor(subject, countable, label) {
1108
686
  super();
1109
687
  this.subject = subject;
@@ -1115,59 +693,22 @@ class SetSize extends QueryNumber {
1115
693
  return this;
1116
694
  }
1117
695
  getPropertyPath() {
1118
- //if a countable argument was given
1119
- // if (this.countable) {
1120
- //then creating the count step is straightforward
1121
- // let countablePath = this.countable.getPropertyPath();
1122
- // if (countablePath.some((step) => Array.isArray(step))) {
1123
- // throw new Error(
1124
- // 'Cannot count a diverging path. Provide one path of properties to count',
1125
- // );
1126
- // }
1127
- // let self: CountStep = {
1128
- // count: this.countable?.getPropertyPath(),
1129
- // label: this.label,
1130
- // };
1131
- // //and we can add the count step to the path of the subject
1132
- // let parent = this.subject.getPropertyPath();
1133
- // parent.push(self);
1134
- // return parent;
1135
- // } else {
1136
- //if nothing to count was given as an argument,
1137
- //then we just count the last property in the path
1138
- //also, we use the label of the last property as the label of the count step
696
+ //count the last property in the path
697
+ //use the label of the last property as the label of the count step
1139
698
  let countable = this.subject.getPropertyStep();
1140
699
  let self = {
1141
700
  count: [countable],
1142
- label: this.label || this.subject.property.label, //the default is property name + 'Size', i.e., friendsSize
1143
- //numFriends
1144
- // label: this.label || 'num'+this.subject.property.label[0].toUpperCase()+this.subject.property.label.slice(1),//the default is property name + 'Size', i.e., friendsSize
701
+ label: this.label || this.subject.property.label,
1145
702
  };
1146
- //in that case we request the path of the subject of the subject (the parent of the parent)
1147
- //and add the CountStep to that path
1148
- //since we already used the subject as the thing that's counted.
703
+ //request the path of the subject's subject (the parent of the parent)
704
+ //and add the SizeStep to that path, since we already used the subject as the thing that's counted
1149
705
  if (this.subject.subject) {
1150
706
  let path = this.subject.subject.getPropertyPath();
1151
707
  path.push(self);
1152
708
  return path;
1153
709
  }
1154
- //if there is no parent of a parent, then we just return the count step as the whole path
1155
710
  return [self];
1156
- // }
1157
711
  }
1158
712
  }
1159
713
  exports.SetSize = SetSize;
1160
- /**
1161
- * A sub query that is used to filter results
1162
- * i.e p.friends.where(f => //LinkedWhereQuery here)
1163
- */
1164
- class LinkedWhereQuery extends SelectQueryFactory {
1165
- getResponse() {
1166
- return this.traceResponse;
1167
- }
1168
- getWherePath() {
1169
- return this.traceResponse.getWherePath();
1170
- }
1171
- }
1172
- exports.LinkedWhereQuery = LinkedWhereQuery;
1173
714
  //# sourceMappingURL=SelectQuery.js.map