@query-graph/core 1.1.5 → 1.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +2 -1
- package/README.md +104 -20
- package/definition.d.ts +1 -1
- package/definition.js +13 -0
- package/docs/authoring.md +108 -10
- package/docs/composition.md +1 -1
- package/docs/diagnostics.md +25 -1
- package/docs/sql.md +89 -1
- package/docs/type-system.md +63 -1
- package/dsl.d.ts +20 -0
- package/dsl.js +13 -0
- package/lib/authoring/definition.js +1 -1
- package/lib/authoring/primitives.js +91 -3
- package/lib/authoring/symbols.js +2 -0
- package/native.d.ts +1 -0
- package/native.js +50 -50
- package/package.json +5 -5
- package/types/authoring.d.ts +133 -21
- package/types/composition.d.ts +3 -21
- package/types/model.d.ts +25 -3
- package/types/runtime.d.ts +14 -8
package/dsl.d.ts
CHANGED
|
@@ -27,6 +27,9 @@ export type {
|
|
|
27
27
|
LikeExpression,
|
|
28
28
|
InExpression,
|
|
29
29
|
InParameterExpression,
|
|
30
|
+
GroupKeyExpression,
|
|
31
|
+
InGroupValuesExpression,
|
|
32
|
+
AllGroupsExpression,
|
|
30
33
|
ExpressionGroup,
|
|
31
34
|
UnaryExpression,
|
|
32
35
|
ExistsExpression,
|
|
@@ -94,6 +97,10 @@ export type {
|
|
|
94
97
|
SourceRef,
|
|
95
98
|
ScalarParameterRef,
|
|
96
99
|
ListParameterRef,
|
|
100
|
+
GroupedListParameterRef,
|
|
101
|
+
GroupedListParameterTypes,
|
|
102
|
+
GroupValuesRef,
|
|
103
|
+
GroupScope,
|
|
97
104
|
ParameterRef,
|
|
98
105
|
RelationRef,
|
|
99
106
|
LiteralInput,
|
|
@@ -120,9 +127,18 @@ export {
|
|
|
120
127
|
hidden,
|
|
121
128
|
source,
|
|
122
129
|
requiredParameter,
|
|
130
|
+
requiredParam,
|
|
123
131
|
optionalParameter,
|
|
132
|
+
optionalParam,
|
|
124
133
|
requiredListParameter,
|
|
134
|
+
requiredListParam,
|
|
125
135
|
optionalListParameter,
|
|
136
|
+
optionalListParam,
|
|
137
|
+
requiredGroupsParameter,
|
|
138
|
+
requiredGroupsParam,
|
|
139
|
+
optionalGroupsParameter,
|
|
140
|
+
optionalGroupsParam,
|
|
141
|
+
allGroups,
|
|
126
142
|
param,
|
|
127
143
|
literal,
|
|
128
144
|
integer,
|
|
@@ -137,6 +153,7 @@ export {
|
|
|
137
153
|
inList,
|
|
138
154
|
and,
|
|
139
155
|
inParameter,
|
|
156
|
+
inParam,
|
|
140
157
|
or,
|
|
141
158
|
not,
|
|
142
159
|
isNull,
|
|
@@ -146,6 +163,9 @@ export {
|
|
|
146
163
|
upper,
|
|
147
164
|
coalesce,
|
|
148
165
|
concat,
|
|
166
|
+
divide,
|
|
167
|
+
truncate,
|
|
168
|
+
modulo,
|
|
149
169
|
count,
|
|
150
170
|
countDistinct,
|
|
151
171
|
sum,
|
package/dsl.js
CHANGED
|
@@ -9,13 +9,22 @@ exports.nullable = primitives.nullable
|
|
|
9
9
|
exports.hidden = primitives.hidden
|
|
10
10
|
exports.source = primitives.source
|
|
11
11
|
exports.requiredParameter = primitives.requiredParameter
|
|
12
|
+
exports.requiredParam = primitives.requiredParam
|
|
12
13
|
exports.optionalParameter = primitives.optionalParameter
|
|
14
|
+
exports.optionalParam = primitives.optionalParam
|
|
13
15
|
exports.param = primitives.param
|
|
14
16
|
exports.literal = primitives.literal
|
|
15
17
|
exports.integer = primitives.integer
|
|
16
18
|
exports.decimal = primitives.decimal
|
|
17
19
|
exports.requiredListParameter = primitives.requiredListParameter
|
|
20
|
+
exports.requiredListParam = primitives.requiredListParam
|
|
18
21
|
exports.optionalListParameter = primitives.optionalListParameter
|
|
22
|
+
exports.optionalListParam = primitives.optionalListParam
|
|
23
|
+
exports.requiredGroupsParameter = primitives.requiredGroupsParameter
|
|
24
|
+
exports.requiredGroupsParam = primitives.requiredGroupsParam
|
|
25
|
+
exports.optionalGroupsParameter = primitives.optionalGroupsParameter
|
|
26
|
+
exports.optionalGroupsParam = primitives.optionalGroupsParam
|
|
27
|
+
exports.allGroups = primitives.allGroups
|
|
19
28
|
exports.eq = primitives.eq
|
|
20
29
|
exports.neq = primitives.neq
|
|
21
30
|
exports.lt = primitives.lt
|
|
@@ -30,11 +39,15 @@ exports.not = primitives.not
|
|
|
30
39
|
exports.isNull = primitives.isNull
|
|
31
40
|
exports.isNotNull = primitives.isNotNull
|
|
32
41
|
exports.inParameter = primitives.inParameter
|
|
42
|
+
exports.inParam = primitives.inParam
|
|
33
43
|
exports.exists = primitives.exists
|
|
34
44
|
exports.lower = primitives.lower
|
|
35
45
|
exports.upper = primitives.upper
|
|
36
46
|
exports.coalesce = primitives.coalesce
|
|
37
47
|
exports.concat = primitives.concat
|
|
48
|
+
exports.divide = primitives.divide
|
|
49
|
+
exports.truncate = primitives.truncate
|
|
50
|
+
exports.modulo = primitives.modulo
|
|
38
51
|
exports.count = primitives.count
|
|
39
52
|
exports.countDistinct = primitives.countDistinct
|
|
40
53
|
exports.sum = primitives.sum
|
|
@@ -11,7 +11,7 @@ const {
|
|
|
11
11
|
const { asExpression, copySource, referenceName } = require('./primitives.js')
|
|
12
12
|
const { GRAPH_MODULE_BRAND, SUMMARY_FIELD_BRAND } = require('./symbols.js')
|
|
13
13
|
|
|
14
|
-
const GRAPH_DEFINITION_VERSION =
|
|
14
|
+
const GRAPH_DEFINITION_VERSION = 12
|
|
15
15
|
const RELATION_CONFIGURATION_KEYS = new Set(['name', 'from', 'to', 'on', 'required', 'cardinality', 'selection'])
|
|
16
16
|
const CONSTRAINT_CONFIGURATION_KEYS = new Set(['predicate', 'when'])
|
|
17
17
|
const PROJECTION_CONFIGURATION_KEYS = new Set(['path', 'expression', 'default'])
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
+
const { randomUUID } = require('node:crypto')
|
|
3
4
|
const { arrayOf, configurationOf, nonEmptyString, objectOf, optionalBoolean } = require('../configuration.js')
|
|
4
|
-
const { SUMMARY_FIELD_BRAND } = require('./symbols.js')
|
|
5
|
+
const { GROUP_VALUES_REF_BRAND, PARAMETER_REF_BRAND, SUMMARY_FIELD_BRAND } = require('./symbols.js')
|
|
5
6
|
|
|
6
7
|
const SCALAR_TYPES = new Set([
|
|
7
8
|
'boolean',
|
|
@@ -18,6 +19,7 @@ const SCALAR_TYPES = new Set([
|
|
|
18
19
|
const FIELD_TYPE_OPTIONS_KEYS = new Set(['nullable', 'selectable'])
|
|
19
20
|
const FIELD_SPECIFICATION_KEYS = new Set(['scalarType', 'nullable', 'selectable'])
|
|
20
21
|
const EXISTS_CONFIGURATION_KEYS = new Set(['from'])
|
|
22
|
+
const GROUPED_LIST_CONFIGURATION_KEYS = new Set(['key', 'value'])
|
|
21
23
|
|
|
22
24
|
function fieldType(scalarType, options = {}) {
|
|
23
25
|
assertScalarType(scalarType)
|
|
@@ -100,10 +102,32 @@ function optionalListParameter(name, scalarType) {
|
|
|
100
102
|
return parameterDefinition(name, scalarType, false, 'list')
|
|
101
103
|
}
|
|
102
104
|
|
|
105
|
+
function requiredGroupsParameter(name, types) {
|
|
106
|
+
return groupedListParameterDefinition(name, types, true)
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
function optionalGroupsParameter(name, types) {
|
|
110
|
+
return groupedListParameterDefinition(name, types, false)
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function groupedListParameterDefinition(name, types, required) {
|
|
114
|
+
const configuration = configurationOf('grouped list parameter', types, GROUPED_LIST_CONFIGURATION_KEYS)
|
|
115
|
+
assertScalarType(configuration.key)
|
|
116
|
+
const definition = parameterDefinition(name, configuration.value, required, 'groupedList')
|
|
117
|
+
definition.keyType = configuration.key
|
|
118
|
+
return definition
|
|
119
|
+
}
|
|
120
|
+
|
|
103
121
|
function param(parameterReference) {
|
|
104
122
|
if (typeof parameterReference !== 'string' && parameterReference?.shape === 'list') {
|
|
105
123
|
throw new TypeError(`List parameter ${parameterReference.name} cannot be used as a scalar expression`)
|
|
106
124
|
}
|
|
125
|
+
if (parameterReference?.shape === 'groupedList') {
|
|
126
|
+
throw new TypeError(`Grouped list parameter ${parameterReference.name} cannot be used as a scalar expression`)
|
|
127
|
+
}
|
|
128
|
+
if (parameterReference?.[GROUP_VALUES_REF_BRAND] === true) {
|
|
129
|
+
throw new TypeError('Group values cannot be used as a scalar expression')
|
|
130
|
+
}
|
|
107
131
|
|
|
108
132
|
return {
|
|
109
133
|
kind: 'parameter',
|
|
@@ -184,6 +208,13 @@ function inList(expression, values) {
|
|
|
184
208
|
}
|
|
185
209
|
|
|
186
210
|
function inParameter(expression, parameterReference) {
|
|
211
|
+
if (parameterReference?.[GROUP_VALUES_REF_BRAND] === true) {
|
|
212
|
+
return {
|
|
213
|
+
kind: 'inGroupValues',
|
|
214
|
+
expression: asExpression(expression),
|
|
215
|
+
scope: parameterReference.scope,
|
|
216
|
+
}
|
|
217
|
+
}
|
|
187
218
|
if (typeof parameterReference !== 'string' && parameterReference?.shape !== 'list') {
|
|
188
219
|
throw new TypeError(`Parameter ${parameterReference?.name ?? '<unknown>'} is not a list parameter`)
|
|
189
220
|
}
|
|
@@ -195,6 +226,31 @@ function inParameter(expression, parameterReference) {
|
|
|
195
226
|
}
|
|
196
227
|
}
|
|
197
228
|
|
|
229
|
+
function allGroups(parameterReference, predicate) {
|
|
230
|
+
if (parameterReference?.[PARAMETER_REF_BRAND] !== true || parameterReference.shape !== 'groupedList') {
|
|
231
|
+
throw new TypeError('allGroups requires a grouped list parameter')
|
|
232
|
+
}
|
|
233
|
+
const parameter = referenceName(parameterReference, 'parameter')
|
|
234
|
+
assertScalarType(parameterReference.keyType)
|
|
235
|
+
assertScalarType(parameterReference.scalarType)
|
|
236
|
+
if (typeof predicate !== 'function') {
|
|
237
|
+
throw new TypeError('allGroups predicate must be a function')
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
const scope = randomUUID()
|
|
241
|
+
const key = Object.freeze({ kind: 'groupKey', scope })
|
|
242
|
+
const values = { scope }
|
|
243
|
+
Object.defineProperty(values, GROUP_VALUES_REF_BRAND, { value: true })
|
|
244
|
+
Object.freeze(values)
|
|
245
|
+
|
|
246
|
+
return {
|
|
247
|
+
kind: 'allGroups',
|
|
248
|
+
parameter,
|
|
249
|
+
scope,
|
|
250
|
+
predicate: asExpression(predicate({ key, values })),
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
198
254
|
function and(...expressions) {
|
|
199
255
|
return {
|
|
200
256
|
kind: 'and',
|
|
@@ -266,6 +322,18 @@ function concat(first, ...rest) {
|
|
|
266
322
|
return call('concat', first, ...rest)
|
|
267
323
|
}
|
|
268
324
|
|
|
325
|
+
function divide(left, right) {
|
|
326
|
+
return call('divide', left, right)
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
function truncate(expression) {
|
|
330
|
+
return call('truncate', expression)
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
function modulo(left, right) {
|
|
334
|
+
return call('modulo', left, right)
|
|
335
|
+
}
|
|
336
|
+
|
|
269
337
|
function aggregate(functionName, expression) {
|
|
270
338
|
const definition = {
|
|
271
339
|
kind: 'aggregate',
|
|
@@ -322,9 +390,10 @@ function parameterDefinition(name, scalarType, required, shape = 'scalar') {
|
|
|
322
390
|
if (required) {
|
|
323
391
|
definition.required = true
|
|
324
392
|
}
|
|
325
|
-
if (shape
|
|
326
|
-
definition.shape =
|
|
393
|
+
if (shape !== 'scalar') {
|
|
394
|
+
definition.shape = shape
|
|
327
395
|
}
|
|
396
|
+
Object.defineProperty(definition, PARAMETER_REF_BRAND, { value: true })
|
|
328
397
|
return definition
|
|
329
398
|
}
|
|
330
399
|
|
|
@@ -351,9 +420,15 @@ function unaryExpression(kind, expression) {
|
|
|
351
420
|
}
|
|
352
421
|
|
|
353
422
|
function asExpression(value) {
|
|
423
|
+
if (value?.[GROUP_VALUES_REF_BRAND] === true) {
|
|
424
|
+
throw new TypeError('Group values cannot be used as a scalar expression')
|
|
425
|
+
}
|
|
354
426
|
if (value?.[SUMMARY_FIELD_BRAND] === true) {
|
|
355
427
|
return value.expression
|
|
356
428
|
}
|
|
429
|
+
if (value?.[PARAMETER_REF_BRAND] === true) {
|
|
430
|
+
return param(value)
|
|
431
|
+
}
|
|
357
432
|
if (value && typeof value === 'object' && typeof value.kind === 'string') {
|
|
358
433
|
return value
|
|
359
434
|
}
|
|
@@ -390,6 +465,7 @@ function assertScalarType(scalarType) {
|
|
|
390
465
|
}
|
|
391
466
|
|
|
392
467
|
module.exports = {
|
|
468
|
+
allGroups,
|
|
393
469
|
and,
|
|
394
470
|
asExpression,
|
|
395
471
|
average,
|
|
@@ -399,6 +475,7 @@ module.exports = {
|
|
|
399
475
|
count,
|
|
400
476
|
countDistinct,
|
|
401
477
|
decimal,
|
|
478
|
+
divide,
|
|
402
479
|
eq,
|
|
403
480
|
exists,
|
|
404
481
|
fieldType,
|
|
@@ -406,6 +483,7 @@ module.exports = {
|
|
|
406
483
|
gte,
|
|
407
484
|
hidden,
|
|
408
485
|
inList,
|
|
486
|
+
inParam: inParameter,
|
|
409
487
|
inParameter,
|
|
410
488
|
integer,
|
|
411
489
|
isNotNull,
|
|
@@ -417,17 +495,27 @@ module.exports = {
|
|
|
417
495
|
lte,
|
|
418
496
|
maximum,
|
|
419
497
|
minimum,
|
|
498
|
+
modulo,
|
|
420
499
|
neq,
|
|
421
500
|
not,
|
|
422
501
|
nullable,
|
|
502
|
+
optionalGroupsParam: optionalGroupsParameter,
|
|
503
|
+
optionalGroupsParameter,
|
|
504
|
+
optionalListParam: optionalListParameter,
|
|
423
505
|
optionalListParameter,
|
|
506
|
+
optionalParam: optionalParameter,
|
|
424
507
|
optionalParameter,
|
|
425
508
|
or,
|
|
426
509
|
param,
|
|
427
510
|
referenceName,
|
|
511
|
+
requiredGroupsParam: requiredGroupsParameter,
|
|
512
|
+
requiredGroupsParameter,
|
|
513
|
+
requiredListParam: requiredListParameter,
|
|
428
514
|
requiredListParameter,
|
|
515
|
+
requiredParam: requiredParameter,
|
|
429
516
|
requiredParameter,
|
|
430
517
|
source,
|
|
431
518
|
sum,
|
|
519
|
+
truncate,
|
|
432
520
|
upper,
|
|
433
521
|
}
|
package/lib/authoring/symbols.js
CHANGED