@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/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 = 10
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 === 'list') {
326
- definition.shape = 'list'
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
  }
@@ -1,4 +1,6 @@
1
1
  'use strict'
2
2
 
3
3
  exports.GRAPH_MODULE_BRAND = Symbol('GraphModule')
4
+ exports.GROUP_VALUES_REF_BRAND = Symbol('GroupValuesRef')
5
+ exports.PARAMETER_REF_BRAND = Symbol('ParameterRef')
4
6
  exports.SUMMARY_FIELD_BRAND = Symbol('SummaryField')
package/native.d.ts CHANGED
@@ -95,4 +95,5 @@ export interface SqlBinding {
95
95
  parameter: string
96
96
  scalarType: import('./dsl.js').ScalarType
97
97
  index?: number
98
+ path?: Array<number | string>
98
99
  }