@_linked/rdf-mem-store 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (137) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/README.md +285 -0
  3. package/lib/cjs/Datafactory.d.ts +29 -0
  4. package/lib/cjs/Datafactory.js +101 -0
  5. package/lib/cjs/Datafactory.js.map +1 -0
  6. package/lib/cjs/InMemoryStore.d.ts +35 -0
  7. package/lib/cjs/InMemoryStore.js +98 -0
  8. package/lib/cjs/InMemoryStore.js.map +1 -0
  9. package/lib/cjs/collections/NodeMap.d.ts +35 -0
  10. package/lib/cjs/collections/NodeMap.js +244 -0
  11. package/lib/cjs/collections/NodeMap.js.map +1 -0
  12. package/lib/cjs/collections/NodeSet.d.ts +55 -0
  13. package/lib/cjs/collections/NodeSet.js +296 -0
  14. package/lib/cjs/collections/NodeSet.js.map +1 -0
  15. package/lib/cjs/collections/NodeURIMappings.d.ts +20 -0
  16. package/lib/cjs/collections/NodeURIMappings.js +65 -0
  17. package/lib/cjs/collections/NodeURIMappings.js.map +1 -0
  18. package/lib/cjs/collections/NodeValuesSet.d.ts +63 -0
  19. package/lib/cjs/collections/NodeValuesSet.js +100 -0
  20. package/lib/cjs/collections/NodeValuesSet.js.map +1 -0
  21. package/lib/cjs/collections/QuadArray.d.ts +17 -0
  22. package/lib/cjs/collections/QuadArray.js +67 -0
  23. package/lib/cjs/collections/QuadArray.js.map +1 -0
  24. package/lib/cjs/collections/QuadMap.d.ts +64 -0
  25. package/lib/cjs/collections/QuadMap.js +155 -0
  26. package/lib/cjs/collections/QuadMap.js.map +1 -0
  27. package/lib/cjs/collections/QuadSet.d.ts +22 -0
  28. package/lib/cjs/collections/QuadSet.js +106 -0
  29. package/lib/cjs/collections/QuadSet.js.map +1 -0
  30. package/lib/cjs/collections/SearchMap.d.ts +5 -0
  31. package/lib/cjs/collections/SearchMap.js +13 -0
  32. package/lib/cjs/collections/SearchMap.js.map +1 -0
  33. package/lib/cjs/events/EventBatcher.d.ts +20 -0
  34. package/lib/cjs/events/EventBatcher.js +97 -0
  35. package/lib/cjs/events/EventBatcher.js.map +1 -0
  36. package/lib/cjs/events/EventEmitter.d.ts +15 -0
  37. package/lib/cjs/events/EventEmitter.js +102 -0
  38. package/lib/cjs/events/EventEmitter.js.map +1 -0
  39. package/lib/cjs/index.d.ts +14 -0
  40. package/lib/cjs/index.js +48 -0
  41. package/lib/cjs/index.js.map +1 -0
  42. package/lib/cjs/interfaces/IGraphObject.d.ts +29 -0
  43. package/lib/cjs/interfaces/IGraphObject.js +3 -0
  44. package/lib/cjs/interfaces/IGraphObject.js.map +1 -0
  45. package/lib/cjs/interfaces/IGraphObjectSet.d.ts +24 -0
  46. package/lib/cjs/interfaces/IGraphObjectSet.js +3 -0
  47. package/lib/cjs/interfaces/IGraphObjectSet.js.map +1 -0
  48. package/lib/cjs/interfaces/IShape.d.ts +22 -0
  49. package/lib/cjs/interfaces/IShape.js +3 -0
  50. package/lib/cjs/interfaces/IShape.js.map +1 -0
  51. package/lib/cjs/interfaces/ISingleGraphObject.d.ts +3 -0
  52. package/lib/cjs/interfaces/ISingleGraphObject.js +3 -0
  53. package/lib/cjs/interfaces/ISingleGraphObject.js.map +1 -0
  54. package/lib/cjs/models.d.ts +1167 -0
  55. package/lib/cjs/models.js +2668 -0
  56. package/lib/cjs/models.js.map +1 -0
  57. package/lib/cjs/package.json +3 -0
  58. package/lib/cjs/utils/Debug.d.ts +3 -0
  59. package/lib/cjs/utils/Debug.js +46 -0
  60. package/lib/cjs/utils/Debug.js.map +1 -0
  61. package/lib/cjs/utils/LocalQueryResolver.d.ts +21 -0
  62. package/lib/cjs/utils/LocalQueryResolver.js +1442 -0
  63. package/lib/cjs/utils/LocalQueryResolver.js.map +1 -0
  64. package/lib/cjs/utils/URI.d.ts +18 -0
  65. package/lib/cjs/utils/URI.js +42 -0
  66. package/lib/cjs/utils/URI.js.map +1 -0
  67. package/lib/cjs/utils/toNamedNode.d.ts +8 -0
  68. package/lib/cjs/utils/toNamedNode.js +15 -0
  69. package/lib/cjs/utils/toNamedNode.js.map +1 -0
  70. package/lib/esm/Datafactory.d.ts +29 -0
  71. package/lib/esm/Datafactory.js +97 -0
  72. package/lib/esm/Datafactory.js.map +1 -0
  73. package/lib/esm/InMemoryStore.d.ts +35 -0
  74. package/lib/esm/InMemoryStore.js +94 -0
  75. package/lib/esm/InMemoryStore.js.map +1 -0
  76. package/lib/esm/collections/NodeMap.d.ts +35 -0
  77. package/lib/esm/collections/NodeMap.js +240 -0
  78. package/lib/esm/collections/NodeMap.js.map +1 -0
  79. package/lib/esm/collections/NodeSet.d.ts +55 -0
  80. package/lib/esm/collections/NodeSet.js +292 -0
  81. package/lib/esm/collections/NodeSet.js.map +1 -0
  82. package/lib/esm/collections/NodeURIMappings.d.ts +20 -0
  83. package/lib/esm/collections/NodeURIMappings.js +61 -0
  84. package/lib/esm/collections/NodeURIMappings.js.map +1 -0
  85. package/lib/esm/collections/NodeValuesSet.d.ts +63 -0
  86. package/lib/esm/collections/NodeValuesSet.js +96 -0
  87. package/lib/esm/collections/NodeValuesSet.js.map +1 -0
  88. package/lib/esm/collections/QuadArray.d.ts +17 -0
  89. package/lib/esm/collections/QuadArray.js +63 -0
  90. package/lib/esm/collections/QuadArray.js.map +1 -0
  91. package/lib/esm/collections/QuadMap.d.ts +64 -0
  92. package/lib/esm/collections/QuadMap.js +151 -0
  93. package/lib/esm/collections/QuadMap.js.map +1 -0
  94. package/lib/esm/collections/QuadSet.d.ts +22 -0
  95. package/lib/esm/collections/QuadSet.js +102 -0
  96. package/lib/esm/collections/QuadSet.js.map +1 -0
  97. package/lib/esm/collections/SearchMap.d.ts +5 -0
  98. package/lib/esm/collections/SearchMap.js +9 -0
  99. package/lib/esm/collections/SearchMap.js.map +1 -0
  100. package/lib/esm/events/EventBatcher.d.ts +20 -0
  101. package/lib/esm/events/EventBatcher.js +90 -0
  102. package/lib/esm/events/EventBatcher.js.map +1 -0
  103. package/lib/esm/events/EventEmitter.d.ts +15 -0
  104. package/lib/esm/events/EventEmitter.js +98 -0
  105. package/lib/esm/events/EventEmitter.js.map +1 -0
  106. package/lib/esm/index.d.ts +14 -0
  107. package/lib/esm/index.js +22 -0
  108. package/lib/esm/index.js.map +1 -0
  109. package/lib/esm/interfaces/IGraphObject.d.ts +29 -0
  110. package/lib/esm/interfaces/IGraphObject.js +2 -0
  111. package/lib/esm/interfaces/IGraphObject.js.map +1 -0
  112. package/lib/esm/interfaces/IGraphObjectSet.d.ts +24 -0
  113. package/lib/esm/interfaces/IGraphObjectSet.js +2 -0
  114. package/lib/esm/interfaces/IGraphObjectSet.js.map +1 -0
  115. package/lib/esm/interfaces/IShape.d.ts +22 -0
  116. package/lib/esm/interfaces/IShape.js +2 -0
  117. package/lib/esm/interfaces/IShape.js.map +1 -0
  118. package/lib/esm/interfaces/ISingleGraphObject.d.ts +3 -0
  119. package/lib/esm/interfaces/ISingleGraphObject.js +2 -0
  120. package/lib/esm/interfaces/ISingleGraphObject.js.map +1 -0
  121. package/lib/esm/models.d.ts +1167 -0
  122. package/lib/esm/models.js +2659 -0
  123. package/lib/esm/models.js.map +1 -0
  124. package/lib/esm/package.json +3 -0
  125. package/lib/esm/utils/Debug.d.ts +3 -0
  126. package/lib/esm/utils/Debug.js +42 -0
  127. package/lib/esm/utils/Debug.js.map +1 -0
  128. package/lib/esm/utils/LocalQueryResolver.d.ts +21 -0
  129. package/lib/esm/utils/LocalQueryResolver.js +1434 -0
  130. package/lib/esm/utils/LocalQueryResolver.js.map +1 -0
  131. package/lib/esm/utils/URI.d.ts +18 -0
  132. package/lib/esm/utils/URI.js +38 -0
  133. package/lib/esm/utils/URI.js.map +1 -0
  134. package/lib/esm/utils/toNamedNode.d.ts +8 -0
  135. package/lib/esm/utils/toNamedNode.js +12 -0
  136. package/lib/esm/utils/toNamedNode.js.map +1 -0
  137. package/package.json +57 -0
@@ -0,0 +1,1442 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.createLocal = createLocal;
13
+ exports.deleteLocal = deleteLocal;
14
+ exports.updateLocal = updateLocal;
15
+ exports.resolveLocal = resolveLocal;
16
+ exports.resolveLocalEndResults = resolveLocalEndResults;
17
+ exports.resolveQueryPropertyPath = resolveQueryPropertyPath;
18
+ const SelectQuery_1 = require("@_linked/core/queries/SelectQuery");
19
+ const ShapeSet_1 = require("@_linked/core/collections/ShapeSet");
20
+ const Shape_1 = require("@_linked/core/shapes/Shape");
21
+ const shacl_1 = require("@_linked/core/ontologies/shacl");
22
+ const CoreMap_1 = require("@_linked/core/collections/CoreMap");
23
+ const QueryFactory_1 = require("@_linked/core/queries/QueryFactory");
24
+ const models_js_1 = require("../models.js");
25
+ const xsd_1 = require("@_linked/core/ontologies/xsd");
26
+ const rdf_1 = require("@_linked/core/ontologies/rdf");
27
+ const NodeSet_js_1 = require("../collections/NodeSet.js");
28
+ const toNamedNode_js_1 = require("./toNamedNode.js");
29
+ const ShapeClass_1 = require("@_linked/core/utils/ShapeClass");
30
+ const primitiveTypes = ['string', 'number', 'boolean', 'Date'];
31
+ /**
32
+ * Convert a property path from core's NodeReferenceValue format to NamedNode(s).
33
+ */
34
+ function toPropertyPath(path) {
35
+ if (Array.isArray(path)) {
36
+ return path.map(p => (0, toNamedNode_js_1.toNamedNode)(p));
37
+ }
38
+ return (0, toNamedNode_js_1.toNamedNode)(path);
39
+ }
40
+ /**
41
+ * Find all instances of a type (and its subtypes) in the global graph.
42
+ * Replaces Shape.getLocalInstancesByType() which doesn't exist in core.
43
+ */
44
+ function getInstancesByType(shapeClass) {
45
+ if (!shapeClass.targetClass) {
46
+ return new NodeSet_js_1.NodeSet();
47
+ }
48
+ const typeNode = (0, toNamedNode_js_1.toNamedNode)(shapeClass.targetClass);
49
+ const rdfType = (0, toNamedNode_js_1.toNamedNode)(rdf_1.rdf.type);
50
+ let nodes = typeNode.getAllInverse(rdfType) || new NodeSet_js_1.NodeSet();
51
+ // Also get instances of subtypes
52
+ try {
53
+ (0, ShapeClass_1.getSubShapesClasses)(shapeClass).forEach((sub) => {
54
+ if (sub.targetClass) {
55
+ const subNodes = (0, toNamedNode_js_1.toNamedNode)(sub.targetClass).getAllInverse(rdfType);
56
+ if (subNodes) {
57
+ subNodes.forEach((n) => nodes.add(n));
58
+ }
59
+ }
60
+ });
61
+ }
62
+ catch (e) {
63
+ // getSubShapesClasses may not work for all shape types
64
+ }
65
+ return nodes;
66
+ }
67
+ /**
68
+ * Convert a ShapeSet to a NodeSet by looking up each shape's id as a NamedNode.
69
+ * Replaces ShapeSet.getNodes() which doesn't exist in core.
70
+ */
71
+ function shapeSetToNodeSet(set) {
72
+ const nodes = new NodeSet_js_1.NodeSet();
73
+ set.forEach((s) => nodes.add(models_js_1.NamedNode.getOrCreate(s.id)));
74
+ return nodes;
75
+ }
76
+ function createLocal(query) {
77
+ return __awaiter(this, void 0, void 0, function* () {
78
+ if (query.type === 'create') {
79
+ //convert the description of the node to create just like in update(),
80
+ // but this time there is no parent propertyShape, so we use null
81
+ //this will also set the rdf:type and save() the node.
82
+ const { value, plainValue } = yield convertNodeDescription(null, query.description, true);
83
+ return plainValue;
84
+ }
85
+ else {
86
+ throw new Error('Unknown query type: ' + query.type);
87
+ }
88
+ });
89
+ }
90
+ function deleteLocal(query) {
91
+ return __awaiter(this, void 0, void 0, function* () {
92
+ if (query.type === 'delete') {
93
+ const response = {
94
+ deleted: [],
95
+ count: 0,
96
+ };
97
+ const errors = {};
98
+ const failed = [];
99
+ query.ids.forEach((id) => {
100
+ let subject;
101
+ try {
102
+ subject = convertNodeReferenceOrId(null, id);
103
+ }
104
+ catch (err) {
105
+ let idString = typeof id === 'string'
106
+ ? id
107
+ : (id === null || id === void 0 ? void 0 : id.id)
108
+ ? id.id
109
+ : id && id['uri']
110
+ ? id['uri']
111
+ : '';
112
+ if (idString === '') {
113
+ errors[Object.keys(errors).length] = 'Invalid id: ' + id;
114
+ failed.push(id);
115
+ }
116
+ else {
117
+ errors[idString] = 'Could not find node with id: ' + idString;
118
+ failed.push(idString);
119
+ }
120
+ return;
121
+ }
122
+ if (!subject.value) {
123
+ errors[subject.plainValue.id] =
124
+ 'No node found with id: ' + subject.plainValue.id;
125
+ failed.push(subject.plainValue.id);
126
+ return;
127
+ }
128
+ //remove the node from the graph
129
+ subject.value.remove();
130
+ response.deleted.push(subject.plainValue.id);
131
+ response.count++;
132
+ });
133
+ if (failed.length > 0) {
134
+ response.failed = failed;
135
+ response.errors = errors;
136
+ }
137
+ }
138
+ else {
139
+ throw new Error('Invalid query type: ' + query.type);
140
+ }
141
+ return null;
142
+ });
143
+ }
144
+ function updateLocal(query) {
145
+ return __awaiter(this, void 0, void 0, function* () {
146
+ if (query.type === 'update') {
147
+ let subject = models_js_1.NamedNode.getNamedNode(query.id);
148
+ if (!subject) {
149
+ throw new Error('No subject found for id: ' + query.id);
150
+ }
151
+ // let shapeClass = getShapeClass(query.shape.namedNode);
152
+ // let shape = new (shapeClass as any)(subject);
153
+ let plainResults = yield applyFieldUpdates(query.updates.fields, subject);
154
+ plainResults['id'] = query.id;
155
+ return plainResults;
156
+ }
157
+ else {
158
+ throw new Error('Invalid query type: ' + query.type);
159
+ }
160
+ });
161
+ }
162
+ function applyFieldUpdates(fields_1, subject_1) {
163
+ return __awaiter(this, arguments, void 0, function* (fields, subject, createQuery = false) {
164
+ let plainValues = {};
165
+ for (let field of fields) {
166
+ let propShape = field.prop;
167
+ let propertyPath = toPropertyPath(propShape.path);
168
+ if (typeof field.val === 'undefined') {
169
+ unsetPropertyPath(subject, propertyPath);
170
+ if (propShape.maxCount >= 1) {
171
+ //when clearing a single property we return undefined
172
+ plainValues[propShape.label] = undefined;
173
+ }
174
+ else {
175
+ plainValues[propShape.label] = [];
176
+ //when clearing a set of values we return an empty array
177
+ }
178
+ }
179
+ else if (Array.isArray(field.val)) {
180
+ (0, QueryFactory_1.checkNewCount)(propShape, field.val.length);
181
+ let values = [];
182
+ let plainValueArr = [];
183
+ //see check above, we already know it's an array, so we can cast it
184
+ for (let singleVal of field.val) {
185
+ let res = yield convertValue(propShape, singleVal, createQuery);
186
+ plainValueArr.push(res.plainValue);
187
+ values.push(res.value);
188
+ }
189
+ if (values.every((v) => typeof v === 'undefined')) {
190
+ //clearing a property
191
+ plainValues[propShape.label] = undefined;
192
+ unsetPropertyPath(subject, propertyPath);
193
+ }
194
+ else if (values.some((v) => typeof v === 'undefined')) {
195
+ throw new Error('Invalid use of undefined for property: ' +
196
+ propShape.label +
197
+ '. You cannot mix undefined with defined values. Values given:' +
198
+ values.map((v) => v === null || v === void 0 ? void 0 : v.toString()).join(', '));
199
+ }
200
+ else {
201
+ // For multi-value properties, return updatedTo structure if this is an UPDATE query (if it's a CREATE query we just return the array)
202
+ plainValues[propShape.label] = createQuery
203
+ ? plainValueArr
204
+ : { updatedTo: plainValueArr };
205
+ overwritePropertyPathMultipleValues(subject, propertyPath, values);
206
+ }
207
+ }
208
+ else if ((0, QueryFactory_1.isSetModificationValue)(field.val)) {
209
+ //check if the new UPDATED number of properties would be allowed
210
+ //by getting the current values, and counting how many remain after adding/removing values
211
+ const currentValues = getPropertyPath(subject, propertyPath);
212
+ const numCurrentValues = currentValues.size;
213
+ const numFinalValues = numCurrentValues +
214
+ (field.val.$add ? field.val.$add.length : 0) -
215
+ (field.val.$remove ? field.val.$remove.length : 0);
216
+ (0, QueryFactory_1.checkNewCount)(propShape, numFinalValues);
217
+ //prepare object to keep track of the plain values that are added and removed
218
+ const plainUpdates = {};
219
+ if (field.val.$remove) {
220
+ let removedPlainValues = [];
221
+ //remove the values from the property path
222
+ field.val.$remove.forEach((val) => {
223
+ //convert the node reference value to a real node
224
+ let nodeToRemove = convertNodeReference(propShape, val, '$remove');
225
+ //keep track of what's removed
226
+ removedPlainValues.push(nodeToRemove.plainValue);
227
+ //remove the value from the property path
228
+ unsetPropertyPathValue(subject, propertyPath, nodeToRemove.value);
229
+ });
230
+ plainUpdates.removed = removedPlainValues;
231
+ }
232
+ if (field.val.$add) {
233
+ let addedPlainValues = [];
234
+ //add the values to the property path
235
+ let values = [];
236
+ for (let singleVal of field.val.$add) {
237
+ //convert the value (which can be a node reference or a node description)
238
+ let res = yield convertValue(propShape, singleVal, createQuery);
239
+ //keep track of what's added
240
+ addedPlainValues.push(res.plainValue);
241
+ values.push(res.value);
242
+ }
243
+ //add the new values to the set of values at the end of the path
244
+ addToResultSets(subject, propertyPath, values);
245
+ //if all that went well, keep track of the added values
246
+ plainUpdates.added = addedPlainValues;
247
+ }
248
+ plainValues[propShape.label] = plainUpdates;
249
+ }
250
+ else {
251
+ //single value is provided
252
+ //check if that fits with the maxCount and minCount of the property
253
+ (0, QueryFactory_1.checkNewCount)(propShape, 1);
254
+ let res = yield convertValue(propShape, field.val, createQuery);
255
+ // if(typeof res.value === 'undefined') {
256
+ // unsetPropertyPath(subject,propertyPath);
257
+ // plainValues[propShape.label] = undefined;
258
+ // } else {
259
+ //save the plain value for the result
260
+ plainValues[propShape.label] = res.plainValue;
261
+ //Note, we are using SET here, to ADD a value.
262
+ //If there are multiple values possible and the user wants to overwrite all the values,
263
+ //they need to use an update function instead of an update object
264
+ overwritePropertyPathSingleValue(subject, propertyPath, res.value);
265
+ // }
266
+ }
267
+ }
268
+ return plainValues;
269
+ });
270
+ }
271
+ function getPropertyPath(subject, path) {
272
+ if (Array.isArray(path)) {
273
+ let target = new NodeSet_js_1.NodeSet([subject]);
274
+ for (let p of path) {
275
+ target = target.getAll(p);
276
+ }
277
+ return target;
278
+ }
279
+ else {
280
+ return subject.getAll(path);
281
+ }
282
+ }
283
+ function addToResultSets(subject, path, values) {
284
+ if (Array.isArray(path)) {
285
+ //save the last property, that's the one we want to add values to
286
+ let lastPath = path.pop();
287
+ let target = new NodeSet_js_1.NodeSet([subject]);
288
+ //for the remaining parts, follow the path to the end
289
+ for (let p of path) {
290
+ target = target.getAll(p);
291
+ }
292
+ //for each node in the target nodes, add the values with the last property from the path as predicate
293
+ //the existing quads with this subject and predicate will remain, and the new values will be added to the graph
294
+ target.msetEach(lastPath, values);
295
+ }
296
+ else {
297
+ //if it's a single property, we can just add the values with the given path as predicate
298
+ //the existing quads with this subject and predicate will remain, and the new values will be added to the graph
299
+ subject.mset(path, values);
300
+ }
301
+ }
302
+ function overwritePropertyPathMultipleValues(subject, path, values) {
303
+ if (Array.isArray(path)) {
304
+ //NOTE: for now we are removing the entire path, not just the last part of the path
305
+ // Not sure yet if we need to distinguish between the two
306
+ console.warn(`Overwriting each end values in property path (${path.map((p) => p.uri).join(' -> ')}) with multiple values ${values.map((v) => v.uri).join(', ')}. Is that expected behaviour?`);
307
+ let lastPath = path.pop();
308
+ let target = new NodeSet_js_1.NodeSet([subject]);
309
+ for (let p of path) {
310
+ target = target.getAll(p);
311
+ }
312
+ target.forEach((node) => {
313
+ node.moverwrite(lastPath, values);
314
+ });
315
+ }
316
+ else {
317
+ subject.moverwrite(path, values);
318
+ }
319
+ }
320
+ function overwritePropertyPathSingleValue(subject, path, value) {
321
+ if (Array.isArray(path)) {
322
+ //NOTE: for now we are removing the entire path, not just the last part of the path
323
+ // Not sure yet if we need to distinguish between the two
324
+ console.warn(`Overwriting each end values in property path (${path.map((p) => p.uri).join(' -> ')}) with single value ${value.toString()}. Is that expected behaviour? `);
325
+ let lastPath = path.pop();
326
+ let target = subject;
327
+ for (let p of path) {
328
+ target = target.getAll(p);
329
+ }
330
+ target.forEach((node) => {
331
+ node.overwrite(lastPath, value);
332
+ });
333
+ }
334
+ else {
335
+ subject.overwrite(path, value);
336
+ }
337
+ }
338
+ function unsetPropertyPathValue(subject, path, value) {
339
+ if (Array.isArray(path)) {
340
+ //NOTE: for unsetting a specific value we are just unsetting the final connection NOT the entire path
341
+ console.warn(`Unsetting each end value in property path (${path.map((p) => p.uri).join(' -> ')}) with value ${value.toString()}. Is that expected behaviour? `);
342
+ let lastPath = path.pop();
343
+ let target = new NodeSet_js_1.NodeSet([subject]);
344
+ for (let p of path) {
345
+ target = target.getAll(p);
346
+ }
347
+ target.forEach((node) => {
348
+ node.unset(lastPath, value);
349
+ });
350
+ }
351
+ else {
352
+ subject.unset(path, value);
353
+ }
354
+ }
355
+ function unsetPropertyPath(subject, path) {
356
+ if (Array.isArray(path)) {
357
+ //NOTE: for now we are removing the last part of the path, disconnecting the end values from the subject at the final property of the path
358
+ // If we need to remove the entire path this should likely be done with other structures, like a ItemListElement being dependent on having an item defined and automatically being removed when we remove the item
359
+ console.warn('Unsetting the final property-value pair of the property path. Is that expected behaviour? : ' +
360
+ path.map((p) => p.uri).join(' -> '));
361
+ let lastPath = path.pop();
362
+ let targets = new NodeSet_js_1.NodeSet([subject]);
363
+ for (let p of path) {
364
+ targets = targets.getAll(p);
365
+ }
366
+ targets.forEach((node) => {
367
+ node.unsetAll(lastPath);
368
+ });
369
+ }
370
+ else {
371
+ subject.unsetAll(path);
372
+ }
373
+ }
374
+ function convertValue(propShape_1, value_1) {
375
+ return __awaiter(this, arguments, void 0, function* (propShape, value, createQuery = false) {
376
+ var _a;
377
+ const nkId = (_a = propShape.nodeKind) === null || _a === void 0 ? void 0 : _a.id;
378
+ if (nkId === shacl_1.shacl.Literal.id) {
379
+ return convertLiteral(propShape, value);
380
+ }
381
+ else if (nkId === shacl_1.shacl.BlankNodeOrIRI.id ||
382
+ nkId === shacl_1.shacl.BlankNode.id ||
383
+ nkId === shacl_1.shacl.IRI.id) {
384
+ return yield convertNamedNode(propShape, value, createQuery);
385
+ }
386
+ else {
387
+ //we currently don't support other node kinds, like shacl.BlankNodeOrLiteral and shacl.BlankNodeOrIRI
388
+ //so in this case, we allow all types of values,
389
+ //next we look at datatype and shapeValue to determine the correct type of value
390
+ if (propShape.datatype) {
391
+ return convertLiteral(propShape, value);
392
+ }
393
+ else if (propShape.valueShape) {
394
+ return yield convertNamedNode(propShape, value, createQuery);
395
+ }
396
+ //these are clearly meant to be literals
397
+ if (typeof value === 'number' ||
398
+ typeof value === 'boolean' ||
399
+ value instanceof Date ||
400
+ typeof value === 'string') {
401
+ return convertLiteral(propShape, value);
402
+ }
403
+ //arrays mean it's an array of field+value objects
404
+ else if (Array.isArray(value)) {
405
+ return yield convertNamedNode(propShape, value, createQuery);
406
+ }
407
+ throw new Error('Unknown value type for property: ' + propShape.label);
408
+ }
409
+ });
410
+ }
411
+ function convertNamedNode(propShape, value, createQuery = true) {
412
+ //value is expected to be an array of fields, or an object with an id for a direct node reference
413
+ if (isNodeReference(value)) {
414
+ return Promise.resolve(convertNodeReference(propShape, value));
415
+ }
416
+ else {
417
+ return convertNodeDescription(propShape, value, createQuery);
418
+ }
419
+ }
420
+ function isNodeReference(value) {
421
+ //check if the value is an object with an id field
422
+ //NOTE: all objects with an id key are considered node references
423
+ //and all other properties are ignored
424
+ //to DEFINE the ID of a new node, the user should use __id as a key in the object
425
+ return typeof value === 'object' && value !== null && 'id' in value;
426
+ // && Object.keys(value).length === 1;
427
+ //and check if there is only 1 key in the object
428
+ }
429
+ function convertNodeReferenceOrId(propShape, value, suffixKey) {
430
+ if (typeof value === 'string') {
431
+ return {
432
+ value: models_js_1.NamedNode.getNamedNode(value),
433
+ plainValue: { id: value },
434
+ };
435
+ }
436
+ return convertNodeReference(propShape, value, suffixKey);
437
+ }
438
+ function convertNodeReference(propShape, value, suffixKey) {
439
+ if (!value.id) {
440
+ throw new Error('Expected a node reference for property: ' +
441
+ (propShape === null || propShape === void 0 ? void 0 : propShape.label) +
442
+ (suffixKey ? '.' + suffixKey : ''));
443
+ }
444
+ //if other keys are present
445
+ if (Object.keys(value).length > 1) {
446
+ throw new Error('Invalid value for property: ' +
447
+ propShape.label +
448
+ (suffixKey ? '.' + suffixKey : '') +
449
+ '. A node reference should only contain the id field.');
450
+ }
451
+ //NOTE: changed this to getOrCreate. Which means also unknown id's will be converted to a named node
452
+ //We need this for example when we load shapes in one app of another app, and the shapes are not yet defined in the graph
453
+ return {
454
+ value: models_js_1.NamedNode.getOrCreate(value.id),
455
+ //return an object only with the ID (a NodeReferenceValue should always only have an id field)
456
+ plainValue: { id: value.id },
457
+ };
458
+ }
459
+ function convertNodeDescription(propShape_1, value_1) {
460
+ return __awaiter(this, arguments, void 0, function* (propShape, value, createQuery = false) {
461
+ if (!value.shape || !value.fields) {
462
+ throw new Error('Expected a node description for property: ' + (propShape === null || propShape === void 0 ? void 0 : propShape.label));
463
+ }
464
+ //use the provided id as URI or create a new node if not defined
465
+ let node = value.__id
466
+ ? models_js_1.NamedNode.getOrCreate(value.__id)
467
+ : models_js_1.NamedNode.create();
468
+ let plainResults = yield applyFieldUpdates(value.fields, node, createQuery);
469
+ let valueShape = (propShape === null || propShape === void 0 ? void 0 : propShape.valueShape) || value.shape;
470
+ //if this property comes with a restriction that all values need to be of a certain shape
471
+ if (valueShape && 'targetClass' in valueShape && valueShape.targetClass) {
472
+ //then we set the type of the node to the target class
473
+ //this is a "free" automatic property that we set for the user, so they don't need to always manually type it into the create() or update() queries
474
+ node.set((0, toNamedNode_js_1.toNamedNode)(rdf_1.rdf.type), (0, toNamedNode_js_1.toNamedNode)(valueShape.targetClass));
475
+ }
476
+ //mark as non-temporary so save() is a no-op in local-only context
477
+ //data is already in the global graph from set()/overwrite() calls above
478
+ node.isTemporaryNode = false;
479
+ plainResults['id'] = node.uri;
480
+ return {
481
+ value: node,
482
+ plainValue: plainResults,
483
+ };
484
+ });
485
+ }
486
+ function convertLiteral(propShape, value) {
487
+ var _a;
488
+ if (typeof value === 'object' && !(value instanceof Date)) {
489
+ throw new Error('Object values are not allowed for property: ' + propShape.label);
490
+ }
491
+ let datatype = propShape.datatype;
492
+ let res;
493
+ if (datatype) {
494
+ const dtId = (_a = datatype.id) !== null && _a !== void 0 ? _a : datatype;
495
+ if (dtId === xsd_1.xsd.integer.id) {
496
+ if (typeof value === 'number') {
497
+ res = new models_js_1.Literal(value.toString(), (0, toNamedNode_js_1.toNamedNode)(xsd_1.xsd.integer));
498
+ }
499
+ else {
500
+ throw new Error(`Property ${propShape.parentNodeShape.label}.${propShape.label} has datatype xsd.integer, so it expects a number value. Given value: ` +
501
+ JSON.stringify(value) +
502
+ ' of type: ' +
503
+ typeof value);
504
+ }
505
+ }
506
+ else if (dtId === xsd_1.xsd.boolean.id) {
507
+ if (typeof value === 'boolean') {
508
+ res = Boolean_toLiteral(value);
509
+ }
510
+ else {
511
+ throw new Error(`Property ${propShape.parentNodeShape.label}.${propShape.label} has datatype xsd.boolean, so it expects a boolean value. Given value: ` +
512
+ JSON.stringify(value) +
513
+ ' of type: ' +
514
+ typeof value);
515
+ }
516
+ }
517
+ else if (dtId === xsd_1.xsd.string.id) {
518
+ res = new models_js_1.Literal(value.toString(), (0, toNamedNode_js_1.toNamedNode)(xsd_1.xsd.string));
519
+ }
520
+ else if (dtId === xsd_1.xsd.date.id || dtId === xsd_1.xsd.dateTime.id) {
521
+ //check if value is a date
522
+ if (value instanceof Date) {
523
+ res = XSDDate_fromNativeDate(value, datatype);
524
+ }
525
+ else {
526
+ throw new Error(`Property ${propShape.parentNodeShape.label}.${propShape.label} has datatype xsd.dateTime, so it expects a Date value. Given value: ` +
527
+ JSON.stringify(value) +
528
+ ' of type: ' +
529
+ typeof value);
530
+ }
531
+ }
532
+ else {
533
+ console.warn(`Unknown datatype :${datatype.toString()}. Assuming it's a string value`);
534
+ }
535
+ }
536
+ if (typeof value === 'undefined') {
537
+ return {
538
+ value: undefined,
539
+ plainValue: undefined,
540
+ };
541
+ }
542
+ if (value === null) {
543
+ throw new Error('Value cannot be null. If you want to unset a value, use undefined');
544
+ }
545
+ //if none of the previous options matched (and therefor res is not set yet), then we assume the value is a string
546
+ if (!res) {
547
+ if (typeof value !== 'string') {
548
+ throw new Error(`Property ${propShape.parentNodeShape.label}.${propShape.label} has no datatype defined in its decorator, so it expects a string value. Given value: ` +
549
+ JSON.stringify(value) +
550
+ ' of type: ' +
551
+ typeof value);
552
+ }
553
+ //and we convert the string to a literal
554
+ //Note: datatype could be null or any other unsupported datatype
555
+ res = new models_js_1.Literal(value, datatype ? (0, toNamedNode_js_1.toNamedNode)(datatype) : null);
556
+ }
557
+ return {
558
+ value: res,
559
+ plainValue: value,
560
+ };
561
+ }
562
+ /**
563
+ * Resolves the query locally, by searching the graph in local memory, without using stores.
564
+ * Returns the result immediately.
565
+ * The results will be the end point reached by the query
566
+ */
567
+ function resolveLocal(query) {
568
+ //TODO: review if we need the shape here or if we can get it from the query
569
+ // if(!shape) {
570
+ // shape = query.subject
571
+ // }
572
+ let subject;
573
+ if (query.subject) {
574
+ if ('id' in query.subject) {
575
+ if (typeof query.subject.id !== 'string') {
576
+ throw new Error('When providing a subject in a query, the id must be a string. Given: ' +
577
+ JSON.stringify(query.subject.id));
578
+ }
579
+ if (models_js_1.NamedNode.getNamedNode(query.subject.id)) {
580
+ // subject = query.shape.getFromURI((query.subject as QResult<any>).id) as Shape;
581
+ subject = models_js_1.NamedNode.getOrCreate(query.subject.id);
582
+ }
583
+ else {
584
+ return null;
585
+ }
586
+ }
587
+ else if (query.subject instanceof ShapeSet_1.ShapeSet) {
588
+ subject = shapeSetToNodeSet(query.subject);
589
+ }
590
+ else {
591
+ subject = models_js_1.NamedNode.getOrCreate(query.subject.id);
592
+ }
593
+ }
594
+ else {
595
+ subject = getInstancesByType(query.shape);
596
+ }
597
+ // let subject2 = query.subject ? query.subject : query.shape.getLocalInstancesByType();
598
+ // console.log(ValidationReport.printForShapeInstances(query.shape));
599
+ //filter the instances down based on the where clause
600
+ if (query.where) {
601
+ subject = filterResults(subject, query.where);
602
+ }
603
+ //sort the instances before slicing
604
+ if (query.sortBy) {
605
+ subject = sortResults(subject, query.sortBy);
606
+ }
607
+ //slice the instances based on the limit and offset
608
+ if (query.limit && subject instanceof NodeSet_js_1.NodeSet) {
609
+ subject = subject.slice(query.offset || 0, (query.offset || 0) + query.limit);
610
+ }
611
+ let resultObjects;
612
+ if (query.subject instanceof ShapeSet_1.ShapeSet) {
613
+ resultObjects = nodesToResultObjects(subject);
614
+ }
615
+ else if (query.subject instanceof Shape_1.Shape) {
616
+ resultObjects = shapeToResultObject(subject);
617
+ }
618
+ else if (query.subject && query.subject.id) {
619
+ //when a query subject is given as an object with an id, probably from a previous query result
620
+ resultObjects = {
621
+ id: query.subject.id,
622
+ // shape: query.shape,
623
+ };
624
+ }
625
+ else {
626
+ //no specific subject is given, so subjects will be a NodeSet of filtered instances,
627
+ resultObjects = nodesToResultObjects(subject);
628
+ }
629
+ //SELECT - go over the select path and resolve the values
630
+ if (Array.isArray(query.select)) {
631
+ query.select.forEach((queryPath) => {
632
+ resolveQueryPath(subject, queryPath, resultObjects);
633
+ });
634
+ }
635
+ else {
636
+ const r = (singleShape) => resolveCustomObject(singleShape, query.select, resultObjects instanceof Map
637
+ ? resultObjects.get(singleShape.uri)
638
+ : resultObjects);
639
+ query.subject ? r(subject) : subject.map(r);
640
+ }
641
+ const results = (resultObjects instanceof Map ? [...resultObjects.values()] : resultObjects);
642
+ if (query.singleResult) {
643
+ return Array.isArray(results) ? results[0] : results;
644
+ }
645
+ return results;
646
+ }
647
+ /**
648
+ * resolves each key of the custom query object
649
+ * and writes the result to the resultObject with the same keys
650
+ * @param subject
651
+ * @param query
652
+ * @param resultObject
653
+ */
654
+ function resolveCustomObject(subject, query, resultObject) {
655
+ for (let key of Object.getOwnPropertyNames(query)) {
656
+ let result = resolveQueryPath(subject, query[key]);
657
+ writeResultObject(resultObject, key, result);
658
+ }
659
+ return resultObject;
660
+ }
661
+ function writeResultObject(resultObject, key, result) {
662
+ //convert undefined to null, because JSON.stringify will KEEP keys that have a null value. Which is required for LINCD to work properly with nested queries
663
+ if (typeof result === 'undefined') {
664
+ result = null;
665
+ }
666
+ //if this key was already set
667
+ if (key in resultObject) {
668
+ //if both the existing value and the new value are objects, we can merge them
669
+ if (result &&
670
+ resultObject[key] &&
671
+ typeof result === 'object' &&
672
+ typeof resultObject[key] === 'object') {
673
+ resultObject[key] = Object.assign(Object.assign({}, resultObject[key]), result);
674
+ return;
675
+ }
676
+ else if (result && result[key] !== null) {
677
+ console.warn('Overwriting existing value for key: ' +
678
+ key +
679
+ ' in result object. Existing value: ' +
680
+ JSON.stringify(resultObject[key]) +
681
+ ', new value: ' +
682
+ JSON.stringify(result));
683
+ }
684
+ }
685
+ resultObject[key] = result;
686
+ }
687
+ function resolveLocalEndResults(query, subject, queryPaths) {
688
+ queryPaths = queryPaths || query.getQueryPaths();
689
+ subject = subject || query.shape.getLocalInstances();
690
+ let results = [];
691
+ if (Array.isArray(queryPaths)) {
692
+ queryPaths.forEach((queryPath) => {
693
+ results.push(resolveQueryPathEndResults(subject, queryPath));
694
+ });
695
+ }
696
+ else {
697
+ throw new Error('TODO: implement support for custom query object: ' + queryPaths);
698
+ }
699
+ // convert the result of each instance into the shape that was requested
700
+ if (query.traceResponse instanceof SelectQuery_1.QueryBuilderObject) {
701
+ //even though resolveQueryPaths always returns an array, if a single value was requested
702
+ //we will return the first value of that array to match the request
703
+ return results.shift();
704
+ //map((result) => {
705
+ //return result.shift();
706
+ //});
707
+ }
708
+ else if (Array.isArray(query.traceResponse)) {
709
+ //nothing to convert if an array was requested
710
+ return results;
711
+ }
712
+ else if (
713
+ // query.traceResponse instanceof QueryValueSetOfSets ||
714
+ query.traceResponse instanceof SelectQuery_1.SelectQueryFactory) {
715
+ return results.shift();
716
+ }
717
+ else if (query.traceResponse instanceof SelectQuery_1.QueryPrimitiveSet ||
718
+ query.traceResponse instanceof SelectQuery_1.Evaluation) {
719
+ //TODO: see how traceResponse is made for QueryValue. Here we need to return an array of the first item in the results?
720
+ //does that also work if there is multiple values?
721
+ //do we need to check the size of the traceresponse
722
+ //why is a CoreSet created? start there
723
+ return results.length > 0 ? [...results[0]] : [];
724
+ }
725
+ else if (typeof query.traceResponse === 'object') {
726
+ throw new Error('Objects are not yet supported');
727
+ }
728
+ }
729
+ function resolveQueryPath(subject, queryPath, resultObjects) {
730
+ //start with the local instance as the subject
731
+ if (Array.isArray(queryPath)) {
732
+ //if the queryPath is an array of query steps, then resolve the query steps and let that convert the result
733
+ return resolveQuerySteps(subject, queryPath, resultObjects);
734
+ }
735
+ else {
736
+ if (subject instanceof models_js_1.NamedNode) {
737
+ return evaluate(subject, queryPath);
738
+ }
739
+ return subject.map((node) => {
740
+ return evaluate(node, queryPath);
741
+ });
742
+ }
743
+ }
744
+ function resolveQueryPathEndResults(subject, queryPath) {
745
+ //start with the local instance as the subject
746
+ let result = subject;
747
+ if (Array.isArray(queryPath)) {
748
+ for (let queryStep of queryPath) {
749
+ //then resolve each of the query steps and use the result as the new subject for the next step
750
+ result = resolveQueryStepEndResults(result, queryStep);
751
+ if (!result) {
752
+ break;
753
+ }
754
+ }
755
+ }
756
+ else {
757
+ result = subject.map((singleNode) => {
758
+ return evaluate(singleNode, queryPath);
759
+ });
760
+ }
761
+ //return the final value at the end of the path
762
+ return result;
763
+ }
764
+ function evaluateWhere(node, method, args) {
765
+ let filterMethod;
766
+ if (method === SelectQuery_1.WhereMethods.EQUALS) {
767
+ filterMethod = resolveWhereEquals;
768
+ }
769
+ else if (method === SelectQuery_1.WhereMethods.SOME) {
770
+ filterMethod = resolveWhereSome;
771
+ }
772
+ else if (method === SelectQuery_1.WhereMethods.EVERY) {
773
+ filterMethod = resolveWhereEvery;
774
+ }
775
+ else {
776
+ throw new Error('Unimplemented where method: ' + method);
777
+ }
778
+ return filterMethod.apply(null, [node, ...args]);
779
+ }
780
+ function sortResults(subject, sortBy) {
781
+ if (subject instanceof models_js_1.NamedNode)
782
+ return subject;
783
+ //SORTING - how it works
784
+ //If a query is sorted by 2 paths (e.g. sort by lastName then by firstName), it will first sort by the first, then by the second if the first one didn't give a result
785
+ let ascending = sortBy.direction === 'ASC';
786
+ let sorted = [...subject].sort((a, b) => {
787
+ //go over each sort path (sortBy contains an array with 1 or more paths to sort by)
788
+ for (let sortPath of sortBy.paths) {
789
+ //resolve the value of the sort path for both a and b
790
+ let aValue = resolveQueryPathEndResults(a, sortPath);
791
+ let bValue = resolveQueryPathEndResults(b, sortPath);
792
+ //if the values are different, we can return the result
793
+ if (aValue < bValue) {
794
+ return ascending ? -1 : 1;
795
+ }
796
+ if (aValue > bValue) {
797
+ return ascending ? 1 : -1;
798
+ }
799
+ //else sort by the next path
800
+ }
801
+ //if we reach the end of the loop, then the values are equal by all paths
802
+ return 0;
803
+ });
804
+ return new NodeSet_js_1.NodeSet(sorted);
805
+ }
806
+ /**
807
+ * Filters down the given subjects to only those what match the where clause
808
+ * @param subject
809
+ * @param where
810
+ * @private
811
+ */
812
+ function filterResults(subject, where, resultObjects) {
813
+ // if ((where as WhereEvaluationPath).path) {
814
+ //for nested where clauses the subject will already be a QueryValue
815
+ //TODO: check if subject is ever not a shape, shapeset or string
816
+ //we're about to remove values from the subject set, so we need to clone it first so that we don't alter the graph
817
+ if (subject instanceof NodeSet_js_1.NodeSet) {
818
+ subject = subject.clone();
819
+ subject.forEach((node) => {
820
+ if (!evaluate(node, where)) {
821
+ resultObjects === null || resultObjects === void 0 ? void 0 : resultObjects.delete(node.uri);
822
+ subject.delete(node);
823
+ }
824
+ });
825
+ return subject;
826
+ }
827
+ else if (subject instanceof models_js_1.NamedNode) {
828
+ return evaluate(subject, where)
829
+ ? subject
830
+ : undefined;
831
+ }
832
+ else if (typeof subject === 'string') {
833
+ return evaluate(subject, where)
834
+ ? subject
835
+ : undefined;
836
+ }
837
+ else if (typeof subject === 'undefined') {
838
+ //this can happen when comparing literals, and there is no value
839
+ return undefined;
840
+ }
841
+ else {
842
+ throw Error('Unknown subject type: ' + subject);
843
+ }
844
+ }
845
+ /**
846
+ * Pre-processes the where clause to resolve the args if it is a path with args
847
+ * This prevents the need to resolve the args multiple times when evaluating the where clause
848
+ * @param where
849
+ */
850
+ function preProcessWhere(where) {
851
+ //if the where clause is a path, we need to resolve the args
852
+ if (where.path && where.args) {
853
+ where.processedArgs = resolveWhereArgs(where.args);
854
+ return where.processedArgs;
855
+ }
856
+ return [];
857
+ }
858
+ function resolveWhereArgs(args) {
859
+ if (!args || !Array.isArray(args)) {
860
+ return [];
861
+ }
862
+ return args.map((arg) => {
863
+ //if this is an argpath
864
+ if (arg.path && !arg.args) {
865
+ //in this case we need to follow the path to the end value
866
+ if (!arg.subject) {
867
+ //if this happens, we probably need to NOT pre-process the where clause for args coming from the main query (as opposed to args from query context)
868
+ throw new Error('Expected a subject for arg path: ' + JSON.stringify(arg));
869
+ }
870
+ const node = models_js_1.NamedNode.getNamedNode(arg.subject.id);
871
+ if (!node) {
872
+ return [];
873
+ }
874
+ // const shapeClass = getShapeClass(node);
875
+ // const shape = (shapeClass as ShapeType).getFromURI((arg as ArgPath).subject.id) as Shape;
876
+ return resolveQueryPath(node, arg.path);
877
+ }
878
+ return arg;
879
+ });
880
+ }
881
+ function evaluate(singleNode, where) {
882
+ if (where.path) {
883
+ let shapeEndValue = resolveQueryPathEndResults(singleNode, where.path);
884
+ let args = where.processedArgs ||
885
+ preProcessWhere(where);
886
+ //when multiple values are the subject of the evaluation
887
+ //and, we're NOT evaluating some() or every()
888
+ if ((shapeEndValue instanceof NodeSet_js_1.NodeSet || Array.isArray(shapeEndValue)) &&
889
+ where.method !== SelectQuery_1.WhereMethods.SOME &&
890
+ where.method !== SelectQuery_1.WhereMethods.EVERY) {
891
+ //then by default we use some()
892
+ //that means, if any of the results matches the where clause, then the subject shape is returned
893
+ return shapeEndValue.some((singleEndValue) => {
894
+ return evaluateWhere(singleEndValue, where.method, args);
895
+ });
896
+ }
897
+ return evaluateWhere(shapeEndValue, where.method, args);
898
+ }
899
+ else if (where.andOr) {
900
+ //the first run we simply take the result as the combined result
901
+ let initialResult = evaluate(singleNode, where.firstPath);
902
+ let booleanPaths = [initialResult];
903
+ where.andOr.forEach((andOr) => {
904
+ if (andOr.and) {
905
+ //if there is an and, we add the result of that and to the array
906
+ booleanPaths.push({ and: evaluate(singleNode, andOr.and) });
907
+ }
908
+ else if (andOr.or) {
909
+ //if there is an or, we add the result of that or to the array
910
+ booleanPaths.push({ or: evaluate(singleNode, andOr.or) });
911
+ }
912
+ });
913
+ //Say that we have: booleanPaths = [boolean,{and:boolean},{or:boolean},{and:boolean}]
914
+ //We should first process the AND: by combining the results of 0 & 1 and also 2 & 3
915
+ //So that it becomes: booleanPaths = [boolean,{or:boolean}]
916
+ var i = booleanPaths.length;
917
+ while (i--) {
918
+ let previous = booleanPaths[i - 1];
919
+ let current = booleanPaths[i];
920
+ if (typeof previous === 'undefined' || typeof current === 'undefined')
921
+ break;
922
+ //if the previous is a ShapeSet and the current is a ShapeSet, we combine them
923
+ if (current.hasOwnProperty('and')) {
924
+ if (previous.hasOwnProperty('and')) {
925
+ booleanPaths[i - 1].and =
926
+ previous.and && current.and;
927
+ }
928
+ else if (previous.hasOwnProperty('or')) {
929
+ booleanPaths[i - 1].or =
930
+ previous.or && current.and;
931
+ }
932
+ else if (typeof previous === 'boolean') {
933
+ booleanPaths[i - 1] = previous && current.and;
934
+ }
935
+ booleanPaths.splice(i, 1);
936
+ }
937
+ }
938
+ //next we process the OR clauses
939
+ var i = booleanPaths.length;
940
+ while (i--) {
941
+ let previous = booleanPaths[i - 1];
942
+ let current = booleanPaths[i];
943
+ if (typeof previous === 'undefined' || typeof current === 'undefined')
944
+ break;
945
+ //for all or clauses, keep the results that are in either of the sets, so simply combine them
946
+ if (current.hasOwnProperty('or')) {
947
+ if (previous.hasOwnProperty('and')) {
948
+ booleanPaths[i - 1].and =
949
+ previous.and || current.or;
950
+ }
951
+ else if (previous.hasOwnProperty('or')) {
952
+ booleanPaths[i - 1].or =
953
+ previous.or || current.or;
954
+ }
955
+ else if (typeof previous === 'boolean') {
956
+ booleanPaths[i - 1] = previous || current.or;
957
+ }
958
+ //remove the current item from the array now that its processed
959
+ booleanPaths.splice(i, 1);
960
+ }
961
+ }
962
+ if (booleanPaths.length > 1) {
963
+ throw new Error('booleanPaths should only have one item left: ' + booleanPaths.length);
964
+ }
965
+ //there should only be a single boolean left
966
+ return booleanPaths[0];
967
+ }
968
+ }
969
+ function resolveWhereEquals(queryEndValue, otherValue) {
970
+ if (queryEndValue instanceof models_js_1.NamedNode &&
971
+ otherValue.id) {
972
+ return queryEndValue.uri === otherValue.id;
973
+ }
974
+ return queryEndValue === otherValue;
975
+ }
976
+ function resolveWhereSome(nodes, evaluation) {
977
+ return nodes.some((node) => {
978
+ return evaluate(node, evaluation);
979
+ });
980
+ }
981
+ function resolveWhereEvery(nodes, evaluation) {
982
+ //there is an added check to see if there are any shapes
983
+ // because for example for this query where(p => p.friends.every(f => f.name.equals('Semmy')))
984
+ // it would be natural to expect that if there are no friends, the query would return false
985
+ return (nodes.size > 0 &&
986
+ nodes.every((node) => {
987
+ return evaluate(node, evaluation);
988
+ }));
989
+ }
990
+ function resolveQuerySteps(subject, queryPath, resultObjects) {
991
+ if (queryPath.length === 0) {
992
+ return subject;
993
+ }
994
+ //queryPath.slice(1,queryPath.length);
995
+ let [currentStep, ...restPath] = queryPath;
996
+ //if the first step is a ShapeReferenceValue, it comes from a QueryContextVariable
997
+ //and it serves as a replacement for the subject
998
+ if (currentStep.id &&
999
+ currentStep.shape) {
1000
+ // let shape = getShapeClass(NamedNode.getNamedNode((currentStep as ShapeReferenceValue).shape.id));
1001
+ // const shapeInstance = (shape as any).getFromURI((currentStep as ShapeReferenceValue).id) as Shape;
1002
+ // subject = shapeInstance;
1003
+ subject = models_js_1.NamedNode.getOrCreate(currentStep.id);
1004
+ //continue with the next step for this new subject
1005
+ [currentStep, ...restPath] = restPath;
1006
+ }
1007
+ if (subject instanceof models_js_1.NamedNode) {
1008
+ if (Array.isArray(currentStep)) {
1009
+ return resolveQueryPathsForNode(queryPath, subject, resultObjects);
1010
+ }
1011
+ //TODO: review differences between shape vs shapes and make it DRY
1012
+ return resolveQueryStepForNode(currentStep, subject, restPath, resultObjects);
1013
+ // } else if (subject instanceof CoreMap) {
1014
+ }
1015
+ else if (subject instanceof NodeSet_js_1.NodeSet) {
1016
+ if (Array.isArray(currentStep)) {
1017
+ resolveQueryPathsForNodes(currentStep, subject, restPath, resultObjects);
1018
+ }
1019
+ else {
1020
+ resolveQueryStepForNodes(currentStep, subject, resultObjects, restPath);
1021
+ }
1022
+ //return converted subjects
1023
+ return subject;
1024
+ //turn the map into an array of results
1025
+ // return [...resultObjects.values()];
1026
+ }
1027
+ else {
1028
+ throw new Error('Unknown subject type: ' + typeof subject);
1029
+ }
1030
+ }
1031
+ function shapeToResultObject(subject) {
1032
+ return {
1033
+ id: subject.uri,
1034
+ // shape: subject,
1035
+ };
1036
+ }
1037
+ function namedNodeToResultObject(subject) {
1038
+ return {
1039
+ id: subject.uri,
1040
+ };
1041
+ }
1042
+ function literalNodeToResultObject(literal, property) {
1043
+ var _a;
1044
+ let datatype = property.datatype;
1045
+ let value = literal.value;
1046
+ if (datatype) {
1047
+ const dtId = (_a = datatype.id) !== null && _a !== void 0 ? _a : datatype;
1048
+ if (dtId === xsd_1.xsd.boolean.id) {
1049
+ return value === 'true';
1050
+ }
1051
+ else if (dtId === xsd_1.xsd.integer.id) {
1052
+ return parseInt(value);
1053
+ }
1054
+ else if (dtId === xsd_1.xsd.decimal.id || dtId === xsd_1.xsd.double.id) {
1055
+ return parseFloat(value);
1056
+ }
1057
+ else if (dtId === xsd_1.xsd.date.id || dtId === xsd_1.xsd.dateTime.id) {
1058
+ return new Date(value);
1059
+ }
1060
+ }
1061
+ //for other datatypes we just return the string value
1062
+ return value;
1063
+ }
1064
+ function nodesToResultObjects(subject) {
1065
+ //create the start of the result JS object for each subject node
1066
+ let resultObjects = new CoreMap_1.CoreMap();
1067
+ subject.forEach((sub) => {
1068
+ resultObjects.set(sub.uri, shapeToResultObject(sub));
1069
+ });
1070
+ return resultObjects;
1071
+ }
1072
+ function resolveQueryStepEndResults(subject, queryStep) {
1073
+ // if (subject instanceof NamedNode) {
1074
+ // if (Array.isArray(queryStep)) {
1075
+ // return resolveQueryPathsForNodeEndResults(queryStep, subject);
1076
+ // }
1077
+ // //TODO: review differences between shape vs shapes and make it DRY
1078
+ // return resolveQueryStepForNodeEndResults(queryStep, subject);
1079
+ // } else {
1080
+ // throw new Error('Unknown subject type: ' + typeof subject);
1081
+ // }
1082
+ if (subject instanceof models_js_1.NamedNode) {
1083
+ if (Array.isArray(queryStep)) {
1084
+ return resolveQueryPathsForNodeEndResults(queryStep, subject);
1085
+ }
1086
+ //TODO: review differences between shape vs shapes and make it DRY
1087
+ return resolveQueryStepForNodeEndResults(queryStep, subject);
1088
+ }
1089
+ if (subject instanceof NodeSet_js_1.NodeSet) {
1090
+ if (Array.isArray(queryStep)) {
1091
+ return resolveQueryPathsForNodesEndResults(queryStep, subject);
1092
+ }
1093
+ return resolveQueryStepForNodesEndResults(queryStep, subject);
1094
+ }
1095
+ else {
1096
+ throw new Error('Unknown subject type: ' + typeof subject);
1097
+ }
1098
+ }
1099
+ function resolveQueryPathsForNodes(queryPaths, subjects, restPath, resultObjects) {
1100
+ let results = [];
1101
+ subjects.forEach((subject) => {
1102
+ let resultObject = resultObjects.get(subject.uri);
1103
+ let subjectResult = resolveQueryPathsForNode(queryPaths, subject, resultObject);
1104
+ let subResult = resolveQuerySteps(subjectResult, restPath, resultObject);
1105
+ results.push(subResult);
1106
+ });
1107
+ return results;
1108
+ }
1109
+ function resolveQueryPathsForNodesEndResults(queryPaths, subjects) {
1110
+ let results = [];
1111
+ subjects.forEach((subject) => {
1112
+ results.push(resolveQueryPathsForNodeEndResults(queryPaths, subject));
1113
+ });
1114
+ return results;
1115
+ }
1116
+ function resolveQueryPathsForNode(queryPaths, subject, resultObject) {
1117
+ if (Array.isArray(queryPaths)) {
1118
+ return queryPaths.map((queryPath) => {
1119
+ return resolveQueryPath(subject, queryPath, resultObject);
1120
+ });
1121
+ }
1122
+ else {
1123
+ throw new Error('TODO: implement support for custom query object: ' + queryPaths);
1124
+ }
1125
+ }
1126
+ function resolveQueryPathsForNodeEndResults(queryPaths, subject) {
1127
+ if (Array.isArray(queryPaths)) {
1128
+ return queryPaths.map((queryPath) => {
1129
+ return resolveQueryPathEndResults(subject, queryPath);
1130
+ });
1131
+ }
1132
+ else {
1133
+ throw new Error('TODO: implement support for custom query object: ' + queryPaths);
1134
+ }
1135
+ }
1136
+ function resolveQueryStepForNode(queryStep, subject, restPath, resultObject) {
1137
+ if (queryStep.property) {
1138
+ return resolvePropertyStep(subject, queryStep, restPath, resultObject);
1139
+ }
1140
+ else if (queryStep.count) {
1141
+ return resolveCountStep(subject, queryStep, resultObject);
1142
+ }
1143
+ else if (queryStep.where) {
1144
+ throw new Error('Cannot filter a single shape');
1145
+ // } else if ((queryStep as BoundComponentQueryStep).component) {
1146
+ // return (queryStep as BoundComponentQueryStep).component.create(subject);
1147
+ }
1148
+ else if (typeof queryStep === 'object') {
1149
+ return resolveCustomObject(subject, queryStep, resultObject);
1150
+ }
1151
+ else {
1152
+ throw Error('Invalid query step: ' + queryStep);
1153
+ }
1154
+ }
1155
+ function resolveQueryStepForNodeEndResults(queryStep, subject) {
1156
+ if (queryStep.property) {
1157
+ let result = resolveQueryPropertyPath(subject, queryStep.property);
1158
+ if (queryStep.where) {
1159
+ result = filterResults(result, queryStep.where);
1160
+ }
1161
+ return result;
1162
+ }
1163
+ else if (queryStep.count) {
1164
+ return resolveCountStep(subject, queryStep);
1165
+ }
1166
+ else if (queryStep.where) {
1167
+ //in some cases there is a query step without property but WITH where
1168
+ //this happens when the where clause is on the root of the query
1169
+ //like Person.select(p => p.where(...))
1170
+ //in that case the where clause is directly applied to the given subject
1171
+ debugger;
1172
+ // let whereResult = resolveWhere(subject as ShapeSet, queryStep.where);
1173
+ // return whereResult;
1174
+ // } else if ((queryStep as BoundComponentQueryStep).component) {
1175
+ // return (queryStep as BoundComponentQueryStep).component.create(subject);
1176
+ // debugger;
1177
+ }
1178
+ else {
1179
+ throw Error('Invalid query step: ' + queryStep.toString());
1180
+ }
1181
+ }
1182
+ function stepResultToSubResult(stepResult, property) {
1183
+ //TODO: review if this ever happens once we move away from relying on accessor implementation, review where this method is used
1184
+ // and if this code ever triggers
1185
+ if (stepResult instanceof NodeSet_js_1.NodeSet) {
1186
+ return nodesToResultObjects(stepResult);
1187
+ }
1188
+ // else if (stepResult instanceof Shape) {
1189
+ // return shapeToResultObject(stepResult);
1190
+ // }
1191
+ //temporary support for accessors returning named nodes
1192
+ else if (stepResult instanceof models_js_1.NamedNode) {
1193
+ return namedNodeToResultObject(stepResult);
1194
+ }
1195
+ else if (stepResult instanceof models_js_1.Literal) {
1196
+ return literalNodeToResultObject(stepResult, property);
1197
+ }
1198
+ else if (Array.isArray(stepResult)) {
1199
+ return stepResult.map((r) => stepResultToSubResult(r, property));
1200
+ }
1201
+ else {
1202
+ //strings,numbers,booleans,dates can just pass. but not other objects
1203
+ if (stepResult && typeof stepResult === 'object') {
1204
+ if (!(stepResult instanceof Date)) {
1205
+ console.warn('New warning, is this a warning? Unknown step result type: ', stepResult);
1206
+ }
1207
+ }
1208
+ return stepResult;
1209
+ }
1210
+ }
1211
+ function resolveQueryPropertyPath(node, property) {
1212
+ const singleValueProperty = property.maxCount === 1;
1213
+ let pathResult;
1214
+ let rawPath = property.path;
1215
+ let pathNodes = Array.isArray(rawPath)
1216
+ ? rawPath.map(p => (0, toNamedNode_js_1.toNamedNode)(p))
1217
+ : [(0, toNamedNode_js_1.toNamedNode)(rawPath)];
1218
+ let lastProp = pathNodes.pop();
1219
+ let target = node;
1220
+ while (pathNodes.length > 0) {
1221
+ let prop = pathNodes.pop();
1222
+ target = target.getAll(prop);
1223
+ }
1224
+ if (singleValueProperty) {
1225
+ pathResult = convertLiteralToPrimitive(target.getOne(lastProp), property);
1226
+ }
1227
+ else {
1228
+ pathResult = target.getAll(lastProp);
1229
+ //if every value is a literal, we convert it to a plain array of plain/primitive values
1230
+ //if not, we keep using NodeSet, so we can more easily access sub paths from this potentially intermediate result.
1231
+ if (pathResult.every((n) => n instanceof models_js_1.Literal) && pathResult.size > 0) {
1232
+ pathResult = pathResult.map((v) => convertLiteralToPrimitive(v, property));
1233
+ }
1234
+ }
1235
+ return pathResult;
1236
+ }
1237
+ function convertLiteralToPrimitive(node, property) {
1238
+ if (node instanceof models_js_1.Literal) {
1239
+ return literalNodeToResultObject(node, property);
1240
+ }
1241
+ return node;
1242
+ }
1243
+ function resolvePropertyStep(singleNode, queryStep, restPath, resultObjects) {
1244
+ //sometimes when .as() was used we may get a singleShape as subject that does not match with the nodeShape of the property of this step
1245
+ //If the singleShape does not match the nodeShape of the property, we change the shape
1246
+ // if(!singleNode.equals(queryStep.property.parentNodeShape.namedNode)) {
1247
+ // singleNode = new (getShapeClass(queryStep.property.parentNodeShape.namedNode) as any)(singleNode);
1248
+ // }
1249
+ //access the result on a node level
1250
+ let stepResult = resolveQueryPropertyPath(singleNode, queryStep.property);
1251
+ //directly access the get/set method of the shape
1252
+ // let stepResult = singleShape[(queryStep as PropertyQueryStep).property.label];
1253
+ let subResultObjects = stepResultToSubResult(stepResult, queryStep.property);
1254
+ if (queryStep.where) {
1255
+ stepResult = filterResults(stepResult, queryStep.where, subResultObjects);
1256
+ //if the result is empty, then the shape didn't make it through the filter and needs to be removed from the results
1257
+ // if (typeof stepResult === 'undefined' || stepResult === null) {
1258
+ // resultObjects.delete(singleShape.uri);
1259
+ // return;
1260
+ // }
1261
+ //if the filtered result is null or undefined, then we don't need to add it to the result object
1262
+ if (typeof stepResult === 'undefined' || stepResult === null) {
1263
+ return;
1264
+ }
1265
+ }
1266
+ if (restPath.length > 0 && typeof stepResult !== 'undefined') {
1267
+ //if there is more properties left, continue to fill the result object by resolving the next steps
1268
+ stepResult = resolveQuerySteps(stepResult, restPath, subResultObjects);
1269
+ }
1270
+ //TODO: refactor/review this code - although it works and its inticrate, its moved around
1271
+ // just change names so its more clear
1272
+ //This converts the subResultObjects into the step result, but are there always "subResultObjects"?
1273
+ //Moved this outside the if because customObject results also need this (so we return an array of result objects, not a nodeset)
1274
+ stepResult =
1275
+ subResultObjects instanceof Map
1276
+ ? [...subResultObjects.values()]
1277
+ : subResultObjects;
1278
+ if (typeof resultObjects !== 'undefined') {
1279
+ // }
1280
+ // if (stepResult instanceof ShapeSet) {
1281
+ // stepResult = [...subResultObjects.values()];
1282
+ // }
1283
+ // if (stepResult instanceof Shape) {
1284
+ // stepResult = subResultObjects;
1285
+ // }
1286
+ //get the current result object for this shape
1287
+ // if (typeof resultObjects !== 'undefined') {
1288
+ let nodeResult = resultObjects instanceof Map
1289
+ ? resultObjects.get(singleNode.uri)
1290
+ : resultObjects;
1291
+ //write the result for this property into the result object
1292
+ writeResultObject(nodeResult, queryStep.property.label, stepResult);
1293
+ // nodeResult[(queryStep as PropertyQueryStep).property.label] = stepResult;
1294
+ return subResultObjects ? nodeResult : stepResult;
1295
+ }
1296
+ // nodeResult[(queryStep as PropertyQueryStep).property.label] = subResultObjects
1297
+ // ? subResultObjects instanceof Map
1298
+ // ? [...subResultObjects.values()]
1299
+ // : subResultObjects
1300
+ // : stepResult;
1301
+ // return stepResult;
1302
+ return stepResult;
1303
+ // resultObjects
1304
+ // ? resultObjects instanceof Map
1305
+ // ? [...resultObjects.values()]
1306
+ // : resultObjects
1307
+ // : stepResult;
1308
+ }
1309
+ function resolveCountStep(singleNode, queryStep, resultObjects) {
1310
+ //We use the flat version of resolveQuerySteps here, because we don't need QResult objects here
1311
+ // we're only interested in the final results
1312
+ let countable = resolveQueryPathEndResults(singleNode, queryStep.count);
1313
+ let result;
1314
+ if (Array.isArray(countable)) {
1315
+ result = countable.length;
1316
+ }
1317
+ else if (countable instanceof Set) {
1318
+ result = countable.size;
1319
+ }
1320
+ else {
1321
+ throw Error('Not sure how to count this: ' + countable.toString());
1322
+ }
1323
+ updateResultObjects(singleNode, queryStep, result, resultObjects, 'count');
1324
+ return result;
1325
+ }
1326
+ function updateResultObjects(node, queryStep, result, resultObjects, defaultLabel) {
1327
+ if (resultObjects) {
1328
+ let nodeResult = resultObjects instanceof Map
1329
+ ? resultObjects.get(node.uri)
1330
+ : resultObjects;
1331
+ if (nodeResult) {
1332
+ writeResultObject(nodeResult, queryStep.label || defaultLabel, result);
1333
+ }
1334
+ }
1335
+ }
1336
+ function resolveQueryStepForNodes(queryStep, subject, resultObjects, restPath) {
1337
+ if (queryStep.property) {
1338
+ subject.forEach((singleNode) => {
1339
+ resolvePropertyStep(singleNode, queryStep, restPath, resultObjects);
1340
+ });
1341
+ // return result;
1342
+ }
1343
+ else if (queryStep.count) {
1344
+ //count the countable
1345
+ subject.forEach((singleNode) => {
1346
+ resolveCountStep(singleNode, queryStep, resultObjects);
1347
+ });
1348
+ }
1349
+ else if (queryStep.where) {
1350
+ //in some cases there is a query step without property but WITH where
1351
+ //this happens when the where clause is on the root of the query
1352
+ //like Person.select(p => p.where(...))
1353
+ //in that case the where clause is directly applied to the given subject
1354
+ subject = filterResults(subject, queryStep.where, resultObjects);
1355
+ if (restPath.length > 0) {
1356
+ //if there is more properties left, continue to fill the result object by resolving the next steps
1357
+ resolveQuerySteps(subject, restPath, resultObjects);
1358
+ }
1359
+ // return whereResult;
1360
+ }
1361
+ else if (typeof queryStep === 'object') {
1362
+ subject.forEach((singleShape) => {
1363
+ resolveCustomObject(singleShape, queryStep, resultObjects ? resultObjects.get(singleShape.uri) : null);
1364
+ });
1365
+ }
1366
+ }
1367
+ function resolveQueryStepForNodesEndResults(queryStep, subject) {
1368
+ var _a;
1369
+ if (queryStep.property) {
1370
+ //if the propertyshape states that it only accepts literal values in the graph,
1371
+ // then the result will be an Array
1372
+ let result = ((_a = queryStep.property.nodeKind) === null || _a === void 0 ? void 0 : _a.id) === shacl_1.shacl.Literal.id ||
1373
+ queryStep.count
1374
+ ? []
1375
+ : new NodeSet_js_1.NodeSet();
1376
+ subject.forEach((singleNode) => {
1377
+ // //directly access the get/set method of the shape
1378
+ // let stepResult =
1379
+ // singleNode[(queryStep as PropertyQueryStep).property.label];
1380
+ // let stepResult:NodeSet<NamedNode>|NamedNode[]|NamedNode|number = getPropertyPath(singleNode,(queryStep as PropertyQueryStep).property.path);
1381
+ let stepResult = resolveQueryPropertyPath(singleNode, queryStep.property);
1382
+ if (queryStep.where) {
1383
+ stepResult = filterResults(stepResult, queryStep.where);
1384
+ }
1385
+ if (queryStep.count) {
1386
+ if (Array.isArray(stepResult)) {
1387
+ stepResult = stepResult.length;
1388
+ }
1389
+ else if (stepResult instanceof Set) {
1390
+ stepResult = stepResult.size;
1391
+ }
1392
+ else {
1393
+ throw Error('Not sure how to count this: ' + stepResult.toString());
1394
+ }
1395
+ }
1396
+ if (typeof stepResult === 'undefined' || stepResult === null) {
1397
+ return;
1398
+ }
1399
+ if (stepResult instanceof NodeSet_js_1.NodeSet) {
1400
+ stepResult = [...stepResult];
1401
+ }
1402
+ if (Array.isArray(stepResult)) {
1403
+ result = result.concat(stepResult);
1404
+ }
1405
+ else if (stepResult instanceof models_js_1.NamedNode) {
1406
+ result.add(stepResult);
1407
+ }
1408
+ else if (primitiveTypes.includes(typeof stepResult)) {
1409
+ result.push(stepResult);
1410
+ }
1411
+ else {
1412
+ throw Error('Unknown result type: ' +
1413
+ typeof stepResult +
1414
+ ' for property ' +
1415
+ queryStep.property.label +
1416
+ ' on shape ' +
1417
+ singleNode.toString() +
1418
+ ')');
1419
+ }
1420
+ });
1421
+ return result;
1422
+ }
1423
+ else if (queryStep.where) {
1424
+ //in some cases there is a query step without property but WITH where
1425
+ //this happens when the where clause is on the root of the query
1426
+ //like Person.select(p => p.where(...))
1427
+ //in that case the where clause is directly applied to the given subject
1428
+ let whereResult = filterResults(subject, queryStep.where);
1429
+ return whereResult;
1430
+ }
1431
+ }
1432
+ function XSDDate_fromNativeDate(nativeDate, datatype) {
1433
+ if (!nativeDate)
1434
+ return null;
1435
+ var value = nativeDate.toISOString();
1436
+ let literal = new models_js_1.Literal(value, (0, toNamedNode_js_1.toNamedNode)(datatype));
1437
+ return literal;
1438
+ }
1439
+ function Boolean_toLiteral(value) {
1440
+ return new models_js_1.Literal(value.toString(), (0, toNamedNode_js_1.toNamedNode)(xsd_1.xsd.boolean));
1441
+ }
1442
+ //# sourceMappingURL=LocalQueryResolver.js.map