xcraft-core-pickaxe 0.1.24 → 0.1.26
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/lib/examples.js +3 -3
- package/lib/level-set-utils.js +3 -2
- package/lib/operator-to-sql.js +41 -21
- package/lib/operators.js +26 -50
- package/lib/optional-object-type.js +38 -0
- package/lib/pick-operators.js +128 -0
- package/lib/pick-or-value.js +76 -0
- package/lib/picks.js +244 -295
- package/lib/query-builder.js +140 -65
- package/lib/query-to-sql.js +8 -8
- package/package.json +1 -1
- package/test/sql.spec.js +38 -6
package/lib/examples.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/* eslint-disable no-inner-declarations */
|
|
2
2
|
// @ts-check
|
|
3
|
-
const {
|
|
3
|
+
const {expressionToSql} = require('./operator-to-sql.js');
|
|
4
4
|
const {
|
|
5
5
|
string,
|
|
6
6
|
number,
|
|
@@ -80,8 +80,8 @@ example1: {
|
|
|
80
80
|
user.get('address').get('streetName').eq('Mine road')
|
|
81
81
|
);
|
|
82
82
|
|
|
83
|
-
console.log(
|
|
84
|
-
console.log(
|
|
83
|
+
console.log(expressionToSql(filter1));
|
|
84
|
+
console.log(expressionToSql(filter2));
|
|
85
85
|
}
|
|
86
86
|
|
|
87
87
|
example2: {
|
package/lib/level-set-utils.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
/* eslint-disable jsdoc/require-returns */
|
|
2
2
|
// @ts-check
|
|
3
3
|
|
|
4
|
-
const $ = require('xcraft-core-pickaxe/lib/operators.js');
|
|
4
|
+
const {pickOperators: $} = require('xcraft-core-pickaxe/lib/pick-operators.js');
|
|
5
5
|
const {RecordPick, ValuePick} = require('./picks.js');
|
|
6
6
|
const {StringType, NumberType} = require('xcraft-core-stones');
|
|
7
|
+
const {pickFromValue} = require('./pick-or-value.js');
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
* @typedef {Record<string, number>} LevelSet
|
|
@@ -36,7 +37,7 @@ function levelSetHasValue2(set, key, value) {
|
|
|
36
37
|
*/
|
|
37
38
|
function levelSetIsEmpty(set) {
|
|
38
39
|
if (!(set instanceof RecordPick)) {
|
|
39
|
-
return
|
|
40
|
+
return pickFromValue(Object.keys(set).length === 0);
|
|
40
41
|
}
|
|
41
42
|
return set.keys().length.eq(0);
|
|
42
43
|
}
|
package/lib/operator-to-sql.js
CHANGED
|
@@ -1,12 +1,9 @@
|
|
|
1
1
|
// @ts-check
|
|
2
2
|
|
|
3
|
-
const {isAnyPick} = require('./picks.js');
|
|
3
|
+
const {isAnyPick, BasePick} = require('./picks.js');
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
|
-
* @typedef {import("./operators.js").
|
|
7
|
-
*/
|
|
8
|
-
/**
|
|
9
|
-
* @typedef {import('./picks.js').AnyPick} AnyPick
|
|
6
|
+
* @typedef {import("./operators.js").Expression} Expression
|
|
10
7
|
*/
|
|
11
8
|
|
|
12
9
|
function escape(value) {
|
|
@@ -16,6 +13,16 @@ function escape(value) {
|
|
|
16
13
|
return value;
|
|
17
14
|
}
|
|
18
15
|
|
|
16
|
+
function squashValueAndPath(value, path) {
|
|
17
|
+
if (value) {
|
|
18
|
+
const operatorName = value.operator;
|
|
19
|
+
if (operatorName === 'get') {
|
|
20
|
+
return squashValueAndPath(value.value, [value.path, ...path]);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return [value, path];
|
|
24
|
+
}
|
|
25
|
+
|
|
19
26
|
const operators = {
|
|
20
27
|
unsafeSql({sql}, context) {
|
|
21
28
|
return sql;
|
|
@@ -60,6 +67,8 @@ const operators = {
|
|
|
60
67
|
// TODO: try values.push(path) => '?'
|
|
61
68
|
// return `json_extract(${field}, ${sql(path, values)})`;
|
|
62
69
|
|
|
70
|
+
[value, path] = squashValueAndPath(value, path);
|
|
71
|
+
|
|
63
72
|
if (value) {
|
|
64
73
|
return `json_extract(${sql(value, context)}, ${escape(
|
|
65
74
|
'$.' + path.join('.')
|
|
@@ -165,6 +174,17 @@ const operators = {
|
|
|
165
174
|
return `(${sqlConditions.join(' OR ')})`;
|
|
166
175
|
},
|
|
167
176
|
|
|
177
|
+
ifNull({a, b}, context) {
|
|
178
|
+
return `IFNULL(${sql(a, context)},${sql(b, context)})`;
|
|
179
|
+
},
|
|
180
|
+
|
|
181
|
+
if({condition, a, b}, context) {
|
|
182
|
+
return `IF(${sql(condition, context)},${sql(a, context)},${sql(
|
|
183
|
+
b,
|
|
184
|
+
context
|
|
185
|
+
)})`;
|
|
186
|
+
},
|
|
187
|
+
|
|
168
188
|
abs({value}, context) {
|
|
169
189
|
return `ABS(${sql(value, context)})`;
|
|
170
190
|
},
|
|
@@ -275,14 +295,14 @@ const operators = {
|
|
|
275
295
|
};
|
|
276
296
|
|
|
277
297
|
/**
|
|
278
|
-
* @param {
|
|
279
|
-
* @returns {
|
|
298
|
+
* @param {Expression | BasePick} expressionOrPick
|
|
299
|
+
* @returns {Expression}
|
|
280
300
|
*/
|
|
281
|
-
function
|
|
282
|
-
if (isAnyPick(
|
|
283
|
-
return
|
|
301
|
+
function getExpression(expressionOrPick) {
|
|
302
|
+
if (isAnyPick(expressionOrPick)) {
|
|
303
|
+
return expressionOrPick.expression;
|
|
284
304
|
}
|
|
285
|
-
return
|
|
305
|
+
return expressionOrPick;
|
|
286
306
|
}
|
|
287
307
|
|
|
288
308
|
/**
|
|
@@ -291,24 +311,24 @@ function getOperator(operatorOrPick) {
|
|
|
291
311
|
* scope?: any,
|
|
292
312
|
* useTableNames?: boolean,
|
|
293
313
|
* equalOperator: 'IS' | '=',
|
|
294
|
-
* }}
|
|
314
|
+
* }} ExpressionToSqlContext
|
|
295
315
|
*/
|
|
296
316
|
|
|
297
317
|
/**
|
|
298
|
-
* @param {
|
|
299
|
-
* @param {
|
|
318
|
+
* @param {Expression | BasePick} expressionOrPick
|
|
319
|
+
* @param {ExpressionToSqlContext} context
|
|
300
320
|
* @returns {string}
|
|
301
321
|
*/
|
|
302
|
-
function sql(
|
|
303
|
-
const
|
|
304
|
-
const operatorName =
|
|
322
|
+
function sql(expressionOrPick, context) {
|
|
323
|
+
const expression = getExpression(expressionOrPick);
|
|
324
|
+
const operatorName = expression.operator;
|
|
305
325
|
if (!(operatorName in operators)) {
|
|
306
|
-
throw new Error(`Unknown operator '${JSON.stringify(
|
|
326
|
+
throw new Error(`Unknown operator for '${JSON.stringify(expression)}'`);
|
|
307
327
|
}
|
|
308
|
-
return operators[operatorName](
|
|
328
|
+
return operators[operatorName](expression, context);
|
|
309
329
|
}
|
|
310
330
|
|
|
311
|
-
function
|
|
331
|
+
function expressionToSql(operator) {
|
|
312
332
|
const context = {
|
|
313
333
|
values: [],
|
|
314
334
|
};
|
|
@@ -320,5 +340,5 @@ function operatorToSql(operator) {
|
|
|
320
340
|
|
|
321
341
|
module.exports = {
|
|
322
342
|
sql,
|
|
323
|
-
|
|
343
|
+
expressionToSql,
|
|
324
344
|
};
|
package/lib/operators.js
CHANGED
|
@@ -1,12 +1,7 @@
|
|
|
1
1
|
/* eslint-disable jsdoc/require-returns */
|
|
2
2
|
// @ts-check
|
|
3
3
|
|
|
4
|
-
const {number
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* @template {AnyTypeOrShape} T
|
|
8
|
-
* @typedef {import("./picks.js").ValuePick<T>} ValuePick
|
|
9
|
-
*/
|
|
4
|
+
const {number} = require('xcraft-core-stones');
|
|
10
5
|
|
|
11
6
|
function op(value) {
|
|
12
7
|
if (value === null) {
|
|
@@ -19,9 +14,9 @@ function op(value) {
|
|
|
19
14
|
if (type === 'object' && 'operator' in value) {
|
|
20
15
|
return value;
|
|
21
16
|
}
|
|
22
|
-
const {isAnyPick} = require('./picks.js');
|
|
17
|
+
const {isAnyPick} = /** @type {any} */ (require('./picks.js'));
|
|
23
18
|
if (isAnyPick(value)) {
|
|
24
|
-
return value.
|
|
19
|
+
return value.expression;
|
|
25
20
|
}
|
|
26
21
|
|
|
27
22
|
throw new Error(`Bad value '${value}'`);
|
|
@@ -222,6 +217,23 @@ const operators = {
|
|
|
222
217
|
});
|
|
223
218
|
},
|
|
224
219
|
|
|
220
|
+
ifNull(a, b) {
|
|
221
|
+
return /** @type {const} */ ({
|
|
222
|
+
operator: 'ifNull',
|
|
223
|
+
a,
|
|
224
|
+
b,
|
|
225
|
+
});
|
|
226
|
+
},
|
|
227
|
+
|
|
228
|
+
if(condition, a, b) {
|
|
229
|
+
return /** @type {const} */ ({
|
|
230
|
+
operator: 'if',
|
|
231
|
+
condition: op(condition),
|
|
232
|
+
a: op(a),
|
|
233
|
+
b: op(b),
|
|
234
|
+
});
|
|
235
|
+
},
|
|
236
|
+
|
|
225
237
|
abs(value) {
|
|
226
238
|
value = op(value);
|
|
227
239
|
return /** @type {const} */ ({
|
|
@@ -330,69 +342,43 @@ const operators = {
|
|
|
330
342
|
count(field, distinct) {
|
|
331
343
|
return /** @type {const} */ ({
|
|
332
344
|
operator: 'count',
|
|
333
|
-
type: number,
|
|
334
345
|
field,
|
|
335
346
|
distinct,
|
|
336
347
|
});
|
|
337
348
|
},
|
|
338
349
|
|
|
339
|
-
/**
|
|
340
|
-
* @template {AnyTypeOrShape} T
|
|
341
|
-
* @param {ValuePick<T>} field
|
|
342
|
-
*/
|
|
343
350
|
avg(field) {
|
|
344
351
|
return /** @type {const} */ ({
|
|
345
352
|
operator: 'avg',
|
|
346
|
-
|
|
347
|
-
field: field.value,
|
|
353
|
+
field,
|
|
348
354
|
});
|
|
349
355
|
},
|
|
350
356
|
|
|
351
|
-
/**
|
|
352
|
-
* @template {AnyTypeOrShape} T
|
|
353
|
-
* @param {ValuePick<T>} field
|
|
354
|
-
*/
|
|
355
357
|
max(field) {
|
|
356
358
|
return /** @type {const} */ ({
|
|
357
359
|
operator: 'max',
|
|
358
|
-
|
|
359
|
-
field: field.value,
|
|
360
|
+
field,
|
|
360
361
|
});
|
|
361
362
|
},
|
|
362
363
|
|
|
363
|
-
/**
|
|
364
|
-
* @template {AnyTypeOrShape} T
|
|
365
|
-
* @param {ValuePick<T>} field
|
|
366
|
-
*/
|
|
367
364
|
min(field) {
|
|
368
365
|
return /** @type {const} */ ({
|
|
369
366
|
operator: 'min',
|
|
370
|
-
|
|
371
|
-
field: field.value,
|
|
367
|
+
field,
|
|
372
368
|
});
|
|
373
369
|
},
|
|
374
370
|
|
|
375
|
-
/**
|
|
376
|
-
* @template {AnyTypeOrShape} T
|
|
377
|
-
* @param {ValuePick<T>} field
|
|
378
|
-
*/
|
|
379
371
|
sum(field) {
|
|
380
372
|
return /** @type {const} */ ({
|
|
381
373
|
operator: 'sum',
|
|
382
|
-
|
|
383
|
-
field: field.value,
|
|
374
|
+
field,
|
|
384
375
|
});
|
|
385
376
|
},
|
|
386
377
|
|
|
387
|
-
/**
|
|
388
|
-
* @template {AnyTypeOrShape} T
|
|
389
|
-
* @param {ValuePick<T>} field
|
|
390
|
-
*/
|
|
391
378
|
groupArray(field) {
|
|
392
379
|
return /** @type {const} */ ({
|
|
393
380
|
operator: 'groupArray',
|
|
394
|
-
|
|
395
|
-
field: field.value,
|
|
381
|
+
field,
|
|
396
382
|
});
|
|
397
383
|
},
|
|
398
384
|
};
|
|
@@ -407,17 +393,7 @@ const operators = {
|
|
|
407
393
|
*/
|
|
408
394
|
|
|
409
395
|
/**
|
|
410
|
-
* @typedef {Values<{[k in keyof typeof operators] : ReturnType<typeof operators[k]>}>}
|
|
411
|
-
*/
|
|
412
|
-
|
|
413
|
-
/**
|
|
414
|
-
* @typedef {Operators["count"] | Operators["avg"] | Operators["max"] | Operators["min"] | Operators["sum"] | Operators["groupArray"]} Aggregator
|
|
415
|
-
*/
|
|
416
|
-
/**
|
|
417
|
-
* @typedef {Operators["eq"] | Operators["neq"] | Operators["and"] | Operators["or"] | Operators["not"] | Operators["gt"] | Operators["gte"] | Operators["lt"] | Operators["lte"] | Operators["in"] | Operators["includes"] | Operators["some"] | Operators["glob"] | Operators["like"] | Operators["match"] | Operators["unsafeSql"]} BooleanOperator
|
|
418
|
-
*/
|
|
419
|
-
/**
|
|
420
|
-
* @typedef {Operators["abs"] | Operators["plus"] | Operators["minus"]} MathOperator
|
|
396
|
+
* @typedef {Values<{[k in keyof typeof operators] : ReturnType<typeof operators[k]>}>} Expression
|
|
421
397
|
*/
|
|
422
398
|
|
|
423
399
|
module.exports = operators;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @template {AnyTypeOrShape} T
|
|
3
|
+
* @typedef {T extends OptionType ? T : OptionType<T>} WrapOption
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const {toObjectType, OptionType, option} = require('xcraft-core-stones');
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @template {ObjectShape} T
|
|
10
|
+
* @typedef {{[K in keyof T]: WrapOption<T[K]>}} OptionalObjectShape
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* @template {ObjectShape} T
|
|
15
|
+
* @param {ObjectType<T>} type
|
|
16
|
+
* @returns {ObjectType<OptionalObjectShape<T>>}
|
|
17
|
+
*/
|
|
18
|
+
function optionalObjectType(type) {
|
|
19
|
+
return type.map((subType) =>
|
|
20
|
+
subType instanceof OptionType ? subType : option(subType)
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* @template {AnyObjectShape} T
|
|
26
|
+
* @param {T} shape
|
|
27
|
+
* @returns {OptionalObjectShape<GetShape<T>>}
|
|
28
|
+
*/
|
|
29
|
+
function optionalObjectShape(shape) {
|
|
30
|
+
const type = toObjectType(shape);
|
|
31
|
+
const optionalType = optionalObjectType(type);
|
|
32
|
+
return optionalType.properties;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
module.exports = {
|
|
36
|
+
optionalObjectType,
|
|
37
|
+
optionalObjectShape,
|
|
38
|
+
};
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/* eslint-disable jsdoc/require-returns */
|
|
2
|
+
// @ts-check
|
|
3
|
+
|
|
4
|
+
const {
|
|
5
|
+
array,
|
|
6
|
+
number,
|
|
7
|
+
boolean,
|
|
8
|
+
union,
|
|
9
|
+
UnionType,
|
|
10
|
+
any,
|
|
11
|
+
} = require('xcraft-core-stones');
|
|
12
|
+
const $o = require('./operators.js');
|
|
13
|
+
const {
|
|
14
|
+
BasePick,
|
|
15
|
+
ValuePick,
|
|
16
|
+
BooleanPick,
|
|
17
|
+
NumberPick,
|
|
18
|
+
makePick,
|
|
19
|
+
ArrayPick,
|
|
20
|
+
} = require('./picks.js');
|
|
21
|
+
const {getPickOrValueType} = require('./pick-or-value.js');
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* @typedef {import('./pick-or-value.js').PickOrValue} PickOrValue
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* @template {PickOrValue} T
|
|
29
|
+
* @typedef {import('./pick-or-value.js').PickOrValueType<T>} PickOrValueType
|
|
30
|
+
*/
|
|
31
|
+
|
|
32
|
+
const pickOperators = {
|
|
33
|
+
...$o,
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* @param {string} sql
|
|
37
|
+
*/
|
|
38
|
+
unsafeSql(sql) {
|
|
39
|
+
return new BasePick(any, $o.unsafeSql(sql));
|
|
40
|
+
},
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* @param {BooleanPick} value
|
|
44
|
+
* @returns {BooleanPick}
|
|
45
|
+
*/
|
|
46
|
+
not(value) {
|
|
47
|
+
return new BooleanPick(boolean, $o.not(value));
|
|
48
|
+
},
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* @param {BooleanPick[]} conditions
|
|
52
|
+
* @returns {BooleanPick}
|
|
53
|
+
*/
|
|
54
|
+
and(...conditions) {
|
|
55
|
+
return new BooleanPick(boolean, $o.and(...conditions));
|
|
56
|
+
},
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* @param {BooleanPick[]} conditions
|
|
60
|
+
* @returns {BooleanPick}
|
|
61
|
+
*/
|
|
62
|
+
or(...conditions) {
|
|
63
|
+
return new BooleanPick(boolean, $o.or(...conditions));
|
|
64
|
+
},
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* @template {PickOrValue} T
|
|
68
|
+
* @template {PickOrValue} U
|
|
69
|
+
* @param {BooleanPick} condition
|
|
70
|
+
* @param {T} a
|
|
71
|
+
* @param {U} b
|
|
72
|
+
* @returns {ValuePick<UnionType<[PickOrValueType<T>, PickOrValueType<U>]>>}
|
|
73
|
+
*/
|
|
74
|
+
if(condition, a, b) {
|
|
75
|
+
const newType = union(getPickOrValueType(a), getPickOrValueType(b));
|
|
76
|
+
return new ValuePick(newType, $o.if(condition, a, b));
|
|
77
|
+
},
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* @param {BasePick} [field]
|
|
81
|
+
* @param {boolean} [distinct]
|
|
82
|
+
*/
|
|
83
|
+
count(field, distinct) {
|
|
84
|
+
return new NumberPick(number, $o.count(field, distinct));
|
|
85
|
+
},
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* @param {NumberPick} field
|
|
89
|
+
*/
|
|
90
|
+
avg(field) {
|
|
91
|
+
return new NumberPick(number, $o.avg(field));
|
|
92
|
+
},
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* @template {AnyTypeOrShape} T
|
|
96
|
+
* @param {ValuePick<T>} field
|
|
97
|
+
*/
|
|
98
|
+
max(field) {
|
|
99
|
+
return makePick(field.type, $o.max(field));
|
|
100
|
+
},
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* @template {AnyTypeOrShape} T
|
|
104
|
+
* @param {ValuePick<T>} field
|
|
105
|
+
*/
|
|
106
|
+
min(field) {
|
|
107
|
+
return makePick(field.type, $o.min(field));
|
|
108
|
+
},
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* @param {NumberPick} field
|
|
112
|
+
*/
|
|
113
|
+
sum(field) {
|
|
114
|
+
return new NumberPick(number, $o.sum(field));
|
|
115
|
+
},
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* @template {AnyTypeOrShape} T
|
|
119
|
+
* @param {ValuePick<T>} field
|
|
120
|
+
*/
|
|
121
|
+
groupArray(field) {
|
|
122
|
+
return new ArrayPick(array(field.type), $o.groupArray(field));
|
|
123
|
+
},
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
module.exports = {
|
|
127
|
+
pickOperators,
|
|
128
|
+
};
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/* eslint-disable jsdoc/require-returns */
|
|
2
|
+
// @ts-check
|
|
3
|
+
|
|
4
|
+
const {
|
|
5
|
+
number,
|
|
6
|
+
NumberType,
|
|
7
|
+
string,
|
|
8
|
+
StringType,
|
|
9
|
+
boolean,
|
|
10
|
+
BooleanType,
|
|
11
|
+
} = require('xcraft-core-stones');
|
|
12
|
+
const {BasePick, makeTypePick} = require('./picks.js');
|
|
13
|
+
const $o = require('./operators.js');
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* @typedef {string | number | boolean} PickValue
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* @typedef {BasePick<any> | PickValue} PickOrValue
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* @template {PickValue} T
|
|
25
|
+
* @typedef {T extends boolean ? BooleanType : T extends number ? NumberType : T extends string ? StringType : never} GetValueType
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* @template {PickOrValue} T
|
|
30
|
+
* @typedef {T extends BasePick<infer U> ? U : T extends PickValue ? GetValueType<T> : never} PickOrValueType
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* @template {PickValue} T
|
|
35
|
+
* @param {T} value
|
|
36
|
+
* @returns {GetValueType<T>}
|
|
37
|
+
*/
|
|
38
|
+
function getValueType(value) {
|
|
39
|
+
if (typeof value === 'string') {
|
|
40
|
+
return /** @type {any} */ (string);
|
|
41
|
+
}
|
|
42
|
+
if (typeof value === 'number') {
|
|
43
|
+
return /** @type {any} */ (number);
|
|
44
|
+
}
|
|
45
|
+
if (typeof value === 'boolean') {
|
|
46
|
+
return /** @type {any} */ (boolean);
|
|
47
|
+
}
|
|
48
|
+
throw new Error('Unknown value type');
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* @template {PickOrValue} T
|
|
53
|
+
* @param {T} pickOrValue
|
|
54
|
+
* @returns {PickOrValueType<T>}
|
|
55
|
+
*/
|
|
56
|
+
function getPickOrValueType(pickOrValue) {
|
|
57
|
+
if (pickOrValue instanceof BasePick) {
|
|
58
|
+
return pickOrValue.type;
|
|
59
|
+
}
|
|
60
|
+
return /** @type {any} */ (getValueType(pickOrValue));
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* @template {PickValue} T
|
|
65
|
+
* @param {T} value
|
|
66
|
+
*/
|
|
67
|
+
function pickFromValue(value) {
|
|
68
|
+
const type = getValueType(value);
|
|
69
|
+
return makeTypePick(type, $o.value(value));
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
module.exports = {
|
|
73
|
+
getPickOrValueType,
|
|
74
|
+
getValueType,
|
|
75
|
+
pickFromValue,
|
|
76
|
+
};
|