@routier/core 0.6.0 → 0.8.0
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/dist/assertions/index.cjs +19 -8
- package/dist/assertions/index.cjs.map +1 -1
- package/dist/assertions/index.d.ts +5 -1
- package/dist/assertions/index.js +21 -9
- package/dist/assertions/index.js.map +1 -1
- package/dist/codegen/blocks.d.ts +17 -1
- package/dist/codegen/handlers/types.d.ts +13 -5
- package/dist/codegen/index.cjs +28 -0
- package/dist/codegen/index.cjs.map +1 -1
- package/dist/codegen/index.js +28 -0
- package/dist/codegen/index.js.map +1 -1
- package/dist/collections/MemoryDataCollection.d.ts +8 -0
- package/dist/collections/index.cjs +141 -4
- package/dist/collections/index.cjs.map +1 -1
- package/dist/collections/index.js +141 -4
- package/dist/collections/index.js.map +1 -1
- package/dist/expressions/callSource.d.ts +41 -0
- package/dist/expressions/evaluate.d.ts +3 -0
- package/dist/expressions/fold.d.ts +7 -0
- package/dist/expressions/index.cjs +1985 -242
- package/dist/expressions/index.cjs.map +1 -1
- package/dist/expressions/index.d.ts +2 -0
- package/dist/expressions/index.js +1997 -243
- package/dist/expressions/index.js.map +1 -1
- package/dist/expressions/parser.d.ts +42 -1
- package/dist/expressions/types.d.ts +45 -26
- package/dist/expressions/utils.d.ts +19 -1
- package/dist/index.cjs +3139 -680
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +3479 -997
- package/dist/index.js.map +1 -1
- package/dist/performance/index.cjs +6 -4
- package/dist/performance/index.cjs.map +1 -1
- package/dist/performance/index.js +6 -4
- package/dist/performance/index.js.map +1 -1
- package/dist/pipeline/index.cjs +6 -4
- package/dist/pipeline/index.cjs.map +1 -1
- package/dist/pipeline/index.js +6 -4
- package/dist/pipeline/index.js.map +1 -1
- package/dist/plugins/EphemeralDataPlugin.d.ts +8 -0
- package/dist/plugins/index.cjs +2921 -411
- package/dist/plugins/index.cjs.map +1 -1
- package/dist/plugins/index.js +2863 -343
- package/dist/plugins/index.js.map +1 -1
- package/dist/plugins/query/QueryOptionsCollection.d.ts +48 -10
- package/dist/plugins/query/describeFilter.d.ts +83 -0
- package/dist/plugins/query/explain.d.ts +71 -9
- package/dist/plugins/query/index.d.ts +2 -0
- package/dist/plugins/query/join.d.ts +4 -1
- package/dist/plugins/query/renames.d.ts +27 -0
- package/dist/plugins/query/types.d.ts +50 -4
- package/dist/plugins/translators/SqlTranslator.d.ts +15 -0
- package/dist/schema/PropertyInfo.d.ts +0 -1
- package/dist/schema/SchemaDefinition.d.ts +8 -0
- package/dist/schema/changeTracker.d.ts +10 -0
- package/dist/schema/index.cjs +298 -288
- package/dist/schema/index.cjs.map +1 -1
- package/dist/schema/index.d.ts +1 -0
- package/dist/schema/index.js +301 -290
- package/dist/schema/index.js.map +1 -1
- package/dist/schema/types.d.ts +8 -7
- package/dist/schema/utils/storageDates.d.ts +25 -0
- package/dist/transfer/index.cjs.map +1 -1
- package/dist/transfer/index.js.map +1 -1
- package/dist/utilities/index.cjs +306 -68
- package/dist/utilities/index.cjs.map +1 -1
- package/dist/utilities/index.js +306 -68
- package/dist/utilities/index.js.map +1 -1
- package/package.json +2 -2
- package/dist/codegen/utils.d.ts +0 -22
package/dist/schema/index.js
CHANGED
|
@@ -344,6 +344,14 @@ class FunctionFactoryBuilder extends ContainerBlock {
|
|
|
344
344
|
this._params.push(...params);
|
|
345
345
|
return this;
|
|
346
346
|
}
|
|
347
|
+
/**
|
|
348
|
+
* Adds a factory parameter carrying `value` and returns its name, for generated code to
|
|
349
|
+
* refer to. See `CodeBuilder.bind` for why values travel this way.
|
|
350
|
+
*/ bind(value) {
|
|
351
|
+
const parameter = this.createParameter(value);
|
|
352
|
+
this._params.push(parameter);
|
|
353
|
+
return parameter.name;
|
|
354
|
+
}
|
|
347
355
|
return() {
|
|
348
356
|
this._return = true;
|
|
349
357
|
return this;
|
|
@@ -459,6 +467,26 @@ class IfBuilder extends ContainerBlock {
|
|
|
459
467
|
}
|
|
460
468
|
}
|
|
461
469
|
class CodeBuilder extends ContainerBlock {
|
|
470
|
+
_bindings = [];
|
|
471
|
+
/**
|
|
472
|
+
* Makes `value` available to the generated function under the returned name.
|
|
473
|
+
*
|
|
474
|
+
* Generated code must never reach a runtime value by its source name or by pasting its
|
|
475
|
+
* source text: a minifier renames the declaration and cannot see inside the generated
|
|
476
|
+
* string, and pasted source loses the scope it closed over (#40, #46). A binding is passed
|
|
477
|
+
* in as a real value when the function is compiled, so it survives any bundler.
|
|
478
|
+
*/ bind(value, name = `binding${this._bindings.length}`) {
|
|
479
|
+
this._bindings.push({
|
|
480
|
+
name,
|
|
481
|
+
value
|
|
482
|
+
});
|
|
483
|
+
return name;
|
|
484
|
+
}
|
|
485
|
+
getBindings() {
|
|
486
|
+
return [
|
|
487
|
+
...this._bindings
|
|
488
|
+
];
|
|
489
|
+
}
|
|
462
490
|
toString() {
|
|
463
491
|
return this._lines.map((line)=>typeof line === 'string' ? this.indent(line) : line.toString()).join('\n\n');
|
|
464
492
|
}
|
|
@@ -541,6 +569,129 @@ var HashType = /*#__PURE__*/ function(HashType) {
|
|
|
541
569
|
}({});
|
|
542
570
|
|
|
543
571
|
|
|
572
|
+
},
|
|
573
|
+
575(__unused_rspack_module, __webpack_exports__, __webpack_require__) {
|
|
574
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
575
|
+
L: () => (hasPrimitiveElements),
|
|
576
|
+
l: () => (isArrayValued)
|
|
577
|
+
});
|
|
578
|
+
/* import */ var _types__rspack_import_0 = __webpack_require__(537);
|
|
579
|
+
|
|
580
|
+
/**
|
|
581
|
+
* Types whose runtime value is a JS array.
|
|
582
|
+
*
|
|
583
|
+
* `Array` and `Vector` are the same thing to every layer that copies, compares, hashes or
|
|
584
|
+
* freezes a value — a vector is a list of numbers and nothing more. They differ only where a
|
|
585
|
+
* backend chooses storage, which is the one place that should ask for `SchemaTypes.Vector` by
|
|
586
|
+
* name.
|
|
587
|
+
*
|
|
588
|
+
* This exists so adding a third array-shaped type is one edit rather than a hunt through
|
|
589
|
+
* twelve handlers. Missing one of those is silent in the worst way: a vector that clones by
|
|
590
|
+
* reference is shared with the change tracker's copy, so overwriting an embedding produces no
|
|
591
|
+
* diff and the save reports nothing to do.
|
|
592
|
+
*/ const ARRAY_VALUED_TYPES = new Set([
|
|
593
|
+
_types__rspack_import_0/* .SchemaTypes.Array */.L.Array,
|
|
594
|
+
_types__rspack_import_0/* .SchemaTypes.Vector */.L.Vector
|
|
595
|
+
]);
|
|
596
|
+
/** True when the property's value is a JS array and needs value rather than reference semantics. */ const isArrayValued = (type)=>ARRAY_VALUED_TYPES.has(type);
|
|
597
|
+
/**
|
|
598
|
+
* True when the property's elements are primitives, so a spread is a sufficient copy.
|
|
599
|
+
*
|
|
600
|
+
* A vector is always numbers, so it never needs the per-element deep copy an array of objects
|
|
601
|
+
* or dates does.
|
|
602
|
+
*/ const PRIMITIVE_ELEMENT_TYPES = new Set([
|
|
603
|
+
_types__rspack_import_0/* .SchemaTypes.String */.L.String,
|
|
604
|
+
_types__rspack_import_0/* .SchemaTypes.Number */.L.Number,
|
|
605
|
+
_types__rspack_import_0/* .SchemaTypes.Boolean */.L.Boolean
|
|
606
|
+
]);
|
|
607
|
+
const hasPrimitiveElements = (type, elementType)=>type === _types__rspack_import_0/* .SchemaTypes.Vector */.L.Vector || PRIMITIVE_ELEMENT_TYPES.has(elementType);
|
|
608
|
+
|
|
609
|
+
|
|
610
|
+
},
|
|
611
|
+
894(__unused_rspack_module, __webpack_exports__, __webpack_require__) {
|
|
612
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
613
|
+
T: () => (getStorageDateReviver)
|
|
614
|
+
});
|
|
615
|
+
/* import */ var _types__rspack_import_0 = __webpack_require__(537);
|
|
616
|
+
/* import */ var _propertyKind__rspack_import_1 = __webpack_require__(575);
|
|
617
|
+
|
|
618
|
+
|
|
619
|
+
const collectDatePaths = (properties, paths)=>{
|
|
620
|
+
for (const property of properties){
|
|
621
|
+
// The stored value belongs to whoever wrote it: a custom serializer, deserializer or
|
|
622
|
+
// transform reads it back, and would be handed a Date it did not expect. Unmapped
|
|
623
|
+
// properties are never stored.
|
|
624
|
+
if (property.valueSerializer != null || property.valueDeserializer != null || property.transform != null || property.isUnmapped) {
|
|
625
|
+
continue;
|
|
626
|
+
}
|
|
627
|
+
if (property.type === _types__rspack_import_0/* .SchemaTypes.Object */.L.Object) {
|
|
628
|
+
collectDatePaths(property.children, paths);
|
|
629
|
+
continue;
|
|
630
|
+
}
|
|
631
|
+
const isArray = (0,_propertyKind__rspack_import_1/* .isArrayValued */.l)(property.type) && property.innerSchema?.type === _types__rspack_import_0/* .SchemaTypes.Date */.L.Date;
|
|
632
|
+
if (property.type !== _types__rspack_import_0/* .SchemaTypes.Date */.L.Date && isArray === false) {
|
|
633
|
+
continue;
|
|
634
|
+
}
|
|
635
|
+
paths.push({
|
|
636
|
+
segments: [
|
|
637
|
+
...property.getParentPathArray({
|
|
638
|
+
useFromPropertyName: true
|
|
639
|
+
}),
|
|
640
|
+
property.getResolvedName()
|
|
641
|
+
],
|
|
642
|
+
isArray
|
|
643
|
+
});
|
|
644
|
+
}
|
|
645
|
+
};
|
|
646
|
+
const reviveAt = (record, path)=>{
|
|
647
|
+
const { segments } = path;
|
|
648
|
+
let parent = record;
|
|
649
|
+
for(let i = 0, length = segments.length - 1; i < length; i++){
|
|
650
|
+
parent = parent[segments[i]];
|
|
651
|
+
// An absent or null parent holds no date
|
|
652
|
+
if (parent == null || typeof parent !== "object") {
|
|
653
|
+
return;
|
|
654
|
+
}
|
|
655
|
+
}
|
|
656
|
+
const key = segments[segments.length - 1];
|
|
657
|
+
const value = parent[key];
|
|
658
|
+
if (path.isArray === false) {
|
|
659
|
+
if (typeof value === "string") {
|
|
660
|
+
parent[key] = new Date(value);
|
|
661
|
+
}
|
|
662
|
+
return;
|
|
663
|
+
}
|
|
664
|
+
if (Array.isArray(value)) {
|
|
665
|
+
for(let i = 0, length = value.length; i < length; i++){
|
|
666
|
+
if (typeof value[i] === "string") {
|
|
667
|
+
value[i] = new Date(value[i]);
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
};
|
|
672
|
+
/** Per schema: `null` for a schema with no dates, so a caller can skip the pass. */ const revivers = new WeakMap();
|
|
673
|
+
/**
|
|
674
|
+
* The reviver for `schema`'s records, or `null` when it declares no dates.
|
|
675
|
+
*
|
|
676
|
+
* Built once per compiled schema. A read revives every row it returns, so the paths are resolved
|
|
677
|
+
* here rather than per row.
|
|
678
|
+
*/ const getStorageDateReviver = (schema)=>{
|
|
679
|
+
const cached = revivers.get(schema);
|
|
680
|
+
if (cached !== undefined) {
|
|
681
|
+
return cached;
|
|
682
|
+
}
|
|
683
|
+
const paths = [];
|
|
684
|
+
collectDatePaths(schema.properties, paths);
|
|
685
|
+
const reviver = paths.length === 0 ? null : (record)=>{
|
|
686
|
+
for(let i = 0, length = paths.length; i < length; i++){
|
|
687
|
+
reviveAt(record, paths[i]);
|
|
688
|
+
}
|
|
689
|
+
};
|
|
690
|
+
revivers.set(schema, reviver);
|
|
691
|
+
return reviver;
|
|
692
|
+
};
|
|
693
|
+
|
|
694
|
+
|
|
544
695
|
},
|
|
545
696
|
581(__unused_rspack_module, __webpack_exports__, __webpack_require__) {
|
|
546
697
|
__webpack_require__.d(__webpack_exports__, {
|
|
@@ -616,12 +767,14 @@ const isLogLevel = (value)=>typeof value === 'string' && LOG_LEVELS.includes(val
|
|
|
616
767
|
const debug = process.env.DEBUG;
|
|
617
768
|
if (debug === 'routier' || debug === '*') return 'debug';
|
|
618
769
|
const env = "production"?.toLowerCase();
|
|
619
|
-
// `test` is deliberately absent. It used to be here, which meant no test suite anywhere
|
|
620
|
-
// could run Routier quietly. Opt in with DEBUG=routier or ROUTIER_LOG_LEVEL when a test
|
|
621
|
-
// needs the output.
|
|
622
770
|
if (env === 'dev' || env === 'development') return 'debug';
|
|
623
771
|
}
|
|
624
|
-
|
|
772
|
+
// Warnings are on unless something turns them off.
|
|
773
|
+
//
|
|
774
|
+
// Routier warns when a query returns correct rows a slower way than it could, or when a filter
|
|
775
|
+
// compares types that can never match. Both are the caller's to act on, and a default of
|
|
776
|
+
// `silent` meant the only people who ever saw them were the ones who already knew to look.
|
|
777
|
+
return 'warn';
|
|
625
778
|
};
|
|
626
779
|
let level = resolveLevel();
|
|
627
780
|
let rank = RANK[level];
|
|
@@ -918,7 +1071,7 @@ var __webpack_exports__ = {};
|
|
|
918
1071
|
|
|
919
1072
|
// EXPORTS
|
|
920
1073
|
__webpack_require__.d(__webpack_exports__, {
|
|
921
|
-
ly: () => (/* reexport */ isArrayValued),
|
|
1074
|
+
ly: () => (/* reexport */ propertyKind/* .isArrayValued */.l),
|
|
922
1075
|
Qc: () => (/* reexport */ SchemaDate),
|
|
923
1076
|
dF: () => (/* reexport */ SchemaDefinition),
|
|
924
1077
|
VG: () => (/* reexport */ compiledSchemaToJsonSchema),
|
|
@@ -929,7 +1082,7 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
929
1082
|
qQ: () => (/* reexport */ SchemaIdentity),
|
|
930
1083
|
_t: () => (/* reexport */ SchemaDistinct),
|
|
931
1084
|
PG: () => (/* reexport */ SchemaNumber),
|
|
932
|
-
LL: () => (/* reexport */ hasPrimitiveElements),
|
|
1085
|
+
LL: () => (/* reexport */ propertyKind/* .hasPrimitiveElements */.L),
|
|
933
1086
|
IB: () => (/* reexport */ SchemaTracked),
|
|
934
1087
|
L$: () => (/* reexport */ rehydrateSchemaFromJsonSchema),
|
|
935
1088
|
CW: () => (/* reexport */ SchemaSerialize),
|
|
@@ -945,10 +1098,11 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
945
1098
|
w_: () => (/* reexport */ SchemaBoolean),
|
|
946
1099
|
Od: () => (/* reexport */ extractTypeInfo),
|
|
947
1100
|
r5: () => (/* reexport */ SchemaComputed),
|
|
948
|
-
|
|
1101
|
+
TH: () => (/* reexport */ storageDates/* .getStorageDateReviver */.T),
|
|
949
1102
|
XM: () => (/* reexport */ SchemaString),
|
|
950
1103
|
Cg: () => (/* reexport */ SchemaFile),
|
|
951
1104
|
FR: () => (/* reexport */ SchemaBase),
|
|
1105
|
+
UX: () => (/* reexport */ propertyInfoToJsonSchema),
|
|
952
1106
|
s: () => (/* reexport */ s),
|
|
953
1107
|
yV: () => (/* reexport */ SchemaTag),
|
|
954
1108
|
ge: () => (/* reexport */ SchemaSearchable),
|
|
@@ -1765,12 +1919,6 @@ class SchemaComputed extends SchemaBase {
|
|
|
1765
1919
|
;// CONCATENATED MODULE: ./src/schema/PropertyInfo.ts
|
|
1766
1920
|
|
|
1767
1921
|
|
|
1768
|
-
const SUPPORTED_DESERIALIZATION_TYPES = new Set([
|
|
1769
|
-
types/* .SchemaTypes.Boolean */.L.Boolean,
|
|
1770
|
-
types/* .SchemaTypes.Date */.L.Date,
|
|
1771
|
-
types/* .SchemaTypes.Number */.L.Number,
|
|
1772
|
-
types/* .SchemaTypes.String */.L.String
|
|
1773
|
-
]);
|
|
1774
1922
|
/**
|
|
1775
1923
|
* Represents metadata and utilities for a property in a schema, including its type, name, parent, children, and serialization details.
|
|
1776
1924
|
*/ class PropertyInfo {
|
|
@@ -1890,9 +2038,6 @@ const SUPPORTED_DESERIALIZATION_TYPES = new Set([
|
|
|
1890
2038
|
get isRenamed() {
|
|
1891
2039
|
return !!this.from;
|
|
1892
2040
|
}
|
|
1893
|
-
get supportsDeserialization() {
|
|
1894
|
-
return this.valueDeserializer != null || SUPPORTED_DESERIALIZATION_TYPES.has(this.type);
|
|
1895
|
-
}
|
|
1896
2041
|
_getPropertyChain() {
|
|
1897
2042
|
if (this._propertyChainCache) {
|
|
1898
2043
|
return this._propertyChainCache;
|
|
@@ -2145,7 +2290,7 @@ const SUPPORTED_DESERIALIZATION_TYPES = new Set([
|
|
|
2145
2290
|
if (this.type === types/* .SchemaTypes.Boolean */.L.Boolean) {
|
|
2146
2291
|
return Boolean(value);
|
|
2147
2292
|
}
|
|
2148
|
-
|
|
2293
|
+
return value;
|
|
2149
2294
|
}
|
|
2150
2295
|
}
|
|
2151
2296
|
|
|
@@ -2172,78 +2317,9 @@ class SlotPath {
|
|
|
2172
2317
|
|
|
2173
2318
|
// EXTERNAL MODULE: ./src/errors/SchemaError.ts
|
|
2174
2319
|
var SchemaError = __webpack_require__(131);
|
|
2175
|
-
;// CONCATENATED MODULE: ./src/codegen/utils.ts
|
|
2176
|
-
/**
|
|
2177
|
-
* Counts non-overlapping occurrences of a term in text.
|
|
2178
|
-
*
|
|
2179
|
-
* Behavior:
|
|
2180
|
-
* - Case-sensitive matching
|
|
2181
|
-
* - If the search term is composed entirely of word characters (A–Z, a–z, 0–9, _),
|
|
2182
|
-
* enforce whole-word boundaries so "red" does not match inside "redder".
|
|
2183
|
-
* - If the search term contains any non-word character (e.g. "=>", "()", "::"),
|
|
2184
|
-
* match anywhere without boundary checks (useful for symbols).
|
|
2185
|
-
* - Non-overlapping matches (after a hit, advances by term length)
|
|
2186
|
-
* - Optimized single-character fast path; otherwise uses indexOf loop
|
|
2187
|
-
*
|
|
2188
|
-
* Examples:
|
|
2189
|
-
* - countWordOccurance("red redder red", "red") => 2
|
|
2190
|
-
* - countWordOccurance("()=>{}", "=>") => 1
|
|
2191
|
-
* - countWordOccurance("aaaa", "aa") => 2 (non-overlapping)
|
|
2192
|
-
*
|
|
2193
|
-
* @param text The source text to scan
|
|
2194
|
-
* @param word The term to match (must be non-empty)
|
|
2195
|
-
* @returns The number of occurrences found
|
|
2196
|
-
*/ const countWordOccurance = (text, word)=>{
|
|
2197
|
-
const wl = word.length;
|
|
2198
|
-
const tl = text.length;
|
|
2199
|
-
if (wl === 0 || wl > tl) return 0;
|
|
2200
|
-
// Fast path for single-character words
|
|
2201
|
-
if (wl === 1) {
|
|
2202
|
-
let c = 0;
|
|
2203
|
-
const code = word.charCodeAt(0);
|
|
2204
|
-
for(let i = 0; i < tl; i++)if (text.charCodeAt(i) === code) c++;
|
|
2205
|
-
return c;
|
|
2206
|
-
}
|
|
2207
|
-
let count = 0;
|
|
2208
|
-
let i = 0;
|
|
2209
|
-
function isWordCharCode(c) {
|
|
2210
|
-
return c >= 48 && c <= 57 // 0-9
|
|
2211
|
-
|| c >= 65 && c <= 90 // A-Z
|
|
2212
|
-
|| c >= 97 && c <= 122 // a-z
|
|
2213
|
-
|| c === 95; // _
|
|
2214
|
-
}
|
|
2215
|
-
// Decide whether to enforce word boundaries based on the search term
|
|
2216
|
-
let enforceWordBoundaries = true;
|
|
2217
|
-
for(let k = 0; k < wl; k++){
|
|
2218
|
-
const cc = word.charCodeAt(k);
|
|
2219
|
-
if (!isWordCharCode(cc)) {
|
|
2220
|
-
enforceWordBoundaries = false;
|
|
2221
|
-
break;
|
|
2222
|
-
}
|
|
2223
|
-
}
|
|
2224
|
-
while(true){
|
|
2225
|
-
i = text.indexOf(word, i);
|
|
2226
|
-
if (i === -1) break;
|
|
2227
|
-
if (enforceWordBoundaries) {
|
|
2228
|
-
const left = i - 1;
|
|
2229
|
-
const right = i + wl;
|
|
2230
|
-
const leftOk = left < 0 || !isWordCharCode(text.charCodeAt(left));
|
|
2231
|
-
const rightOk = right >= tl || !isWordCharCode(text.charCodeAt(right));
|
|
2232
|
-
if (leftOk && rightOk) count++;
|
|
2233
|
-
} else {
|
|
2234
|
-
// No boundary enforcement for symbol-containing terms
|
|
2235
|
-
count++;
|
|
2236
|
-
}
|
|
2237
|
-
i += wl; // non-overlapping word matches
|
|
2238
|
-
}
|
|
2239
|
-
return count;
|
|
2240
|
-
};
|
|
2241
|
-
|
|
2242
2320
|
;// CONCATENATED MODULE: ./src/codegen/handlers/types.ts
|
|
2243
2321
|
|
|
2244
2322
|
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
2323
|
/**
|
|
2248
2324
|
* Terminal link for chains that apply only to a subset of properties (keys,
|
|
2249
2325
|
* identities). Returning the builder marks every other property as
|
|
@@ -2419,34 +2495,16 @@ class PropertyInfoHandler {
|
|
|
2419
2495
|
}
|
|
2420
2496
|
enriched.property(`${property.name}: ${entitySelectorPath}`);
|
|
2421
2497
|
}
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
const index = stringifiedFunction.indexOf("=>");
|
|
2433
|
-
body = stringifiedFunction.slice(index + 2, stringifiedFunction.length);
|
|
2434
|
-
}
|
|
2435
|
-
if (body.startsWith("{") === true && body.endsWith("}")) {
|
|
2436
|
-
// Remove brackets, wrapping function will have them
|
|
2437
|
-
builder.appendBody(body.slice(1, body.length - 1));
|
|
2438
|
-
return {
|
|
2439
|
-
builder,
|
|
2440
|
-
parameters
|
|
2441
|
-
};
|
|
2442
|
-
}
|
|
2443
|
-
builder.appendBody(`return ${body};`);
|
|
2444
|
-
return {
|
|
2445
|
-
builder,
|
|
2446
|
-
parameters
|
|
2447
|
-
};
|
|
2448
|
-
}
|
|
2449
|
-
throw new Error("Only arrow functions are allowed in the schema definition: function () {} ---> () => {}");
|
|
2498
|
+
/**
|
|
2499
|
+
* Binds a function the schema author supplied (a default, a computed, a serializer) into
|
|
2500
|
+
* the generated code and returns the expression that calls it with `args`.
|
|
2501
|
+
*
|
|
2502
|
+
* The function is passed in by value rather than pasted in as source text. Pasted source
|
|
2503
|
+
* loses the scope it was written in, so a default that called an imported helper threw, and
|
|
2504
|
+
* it had to be parsed back apart, which only worked for arrows: a bundler that lowers arrows
|
|
2505
|
+
* to `function` expressions, or renames what they refer to, broke every schema (#46).
|
|
2506
|
+
*/ emitBoundCall(target, fn, args) {
|
|
2507
|
+
return `${target.bind(fn)}(${args.join(", ")})`;
|
|
2450
2508
|
}
|
|
2451
2509
|
}
|
|
2452
2510
|
|
|
@@ -2606,28 +2664,21 @@ class EnrichmentPrimitiveHandler extends PropertyInfoHandler {
|
|
|
2606
2664
|
class EnrichmentFunctionHandler extends PropertyInfoHandler {
|
|
2607
2665
|
handle(property, builder) {
|
|
2608
2666
|
if (property.functionBody != null && property.type === types/* .SchemaTypes.Function */.L.Function) {
|
|
2609
|
-
const
|
|
2667
|
+
const factory = builder.get("factory");
|
|
2668
|
+
const args = [
|
|
2610
2669
|
"enriched",
|
|
2611
2670
|
"collectionName"
|
|
2612
2671
|
];
|
|
2613
2672
|
if (property.injected != null) {
|
|
2614
|
-
|
|
2615
|
-
const parameter = factory.createParameter(property.injected);
|
|
2616
|
-
factory.parameters(parameter);
|
|
2617
|
-
parameterNames.push(parameter.name);
|
|
2673
|
+
args.push(factory.bind(property.injected));
|
|
2618
2674
|
}
|
|
2619
|
-
const declarationsSlot = builder.get("factory.function.declarations");
|
|
2620
|
-
// Unwrap the functions to removing currying
|
|
2621
|
-
const defaultFunctionWithParameters = this.toNamedFunction(property.functionBody.toString(), declarationsSlot);
|
|
2622
|
-
defaultFunctionWithParameters.builder.parameters(...parameterNames.map((w, i)=>({
|
|
2623
|
-
name: defaultFunctionWithParameters.parameters[i],
|
|
2624
|
-
callName: w
|
|
2625
|
-
})));
|
|
2626
2675
|
const slot = builder.get("factory.function.assignment");
|
|
2627
2676
|
const enrichedAssignmentPath = property.getAssignmentPath({
|
|
2628
2677
|
parent: "enriched"
|
|
2629
2678
|
});
|
|
2630
|
-
|
|
2679
|
+
// The definition is curried: calling it with the entity returns the function the
|
|
2680
|
+
// property holds
|
|
2681
|
+
slot.assign(enrichedAssignmentPath).value(this.emitBoundCall(factory, property.functionBody, args));
|
|
2631
2682
|
return builder;
|
|
2632
2683
|
}
|
|
2633
2684
|
return super.handle(property, builder);
|
|
@@ -2682,34 +2733,17 @@ class EnrichmentDefaultFunctionHandler extends PropertyInfoHandler {
|
|
|
2682
2733
|
handle(property, builder) {
|
|
2683
2734
|
if (property.defaultValue != null && typeof property.defaultValue === "function") {
|
|
2684
2735
|
this.setEnrichedProperty(property, builder);
|
|
2685
|
-
|
|
2686
|
-
|
|
2687
|
-
|
|
2688
|
-
|
|
2689
|
-
|
|
2690
|
-
|
|
2691
|
-
}
|
|
2692
|
-
const parameter = factory.createParameter(property.injected);
|
|
2693
|
-
factory.parameters(parameter);
|
|
2694
|
-
const defaultFunctionWithParameters = this.toNamedFunction(property.defaultValue.toString(), declarationsSlot);
|
|
2695
|
-
// This is ok, defaults can only inject one parameter anyways
|
|
2696
|
-
defaultFunctionWithParameters.builder.parameters(...defaultFunctionWithParameters.parameters.map((w)=>({
|
|
2697
|
-
name: w,
|
|
2698
|
-
callName: parameter.name
|
|
2699
|
-
})));
|
|
2700
|
-
const ifsSlot = builder.get("factory.function.ifs");
|
|
2701
|
-
const enrichedAssignmentPath = property.getAssignmentPath({
|
|
2702
|
-
parent: "enriched"
|
|
2703
|
-
});
|
|
2704
|
-
ifsSlot.if(`${enrichedAssignmentPath} == null`).appendBody(`${enrichedAssignmentPath} = ${defaultFunctionWithParameters.builder.toCallable()}`);
|
|
2705
|
-
return builder;
|
|
2706
|
-
}
|
|
2707
|
-
const defaultFunction = this.toNamedFunction(property.defaultValue.toString(), declarationsSlot);
|
|
2736
|
+
const factory = builder.get("factory");
|
|
2737
|
+
// Defaults take at most one argument: the injected value, when there is one
|
|
2738
|
+
const args = property.injected != null ? [
|
|
2739
|
+
factory.bind(property.injected)
|
|
2740
|
+
] : [];
|
|
2741
|
+
const call = this.emitBoundCall(factory, property.defaultValue, args);
|
|
2708
2742
|
const ifsSlot = builder.get("factory.function.ifs");
|
|
2709
2743
|
const enrichedAssignmentPath = property.getAssignmentPath({
|
|
2710
2744
|
parent: "enriched"
|
|
2711
2745
|
});
|
|
2712
|
-
ifsSlot.if(`${enrichedAssignmentPath} == null`).appendBody(`${enrichedAssignmentPath} = ${
|
|
2746
|
+
ifsSlot.if(`${enrichedAssignmentPath} == null`).appendBody(`${enrichedAssignmentPath} = ${call}`);
|
|
2713
2747
|
return builder;
|
|
2714
2748
|
}
|
|
2715
2749
|
return super.handle(property, builder);
|
|
@@ -2722,22 +2756,15 @@ class EnrichmentDefaultFunctionHandler extends PropertyInfoHandler {
|
|
|
2722
2756
|
class EnrichmentComputedValueHandler extends PropertyInfoHandler {
|
|
2723
2757
|
handle(property, builder) {
|
|
2724
2758
|
if (property.functionBody != null && property.type === types/* .SchemaTypes.Computed */.L.Computed) {
|
|
2725
|
-
const
|
|
2759
|
+
const factory = builder.get("factory");
|
|
2760
|
+
const args = [
|
|
2726
2761
|
"enriched",
|
|
2727
2762
|
"collectionName"
|
|
2728
2763
|
];
|
|
2729
2764
|
if (property.injected != null) {
|
|
2730
|
-
|
|
2731
|
-
const parameter = factory.createParameter(property.injected);
|
|
2732
|
-
factory.parameters(parameter);
|
|
2733
|
-
parameterNames.push(parameter.name);
|
|
2765
|
+
args.push(factory.bind(property.injected));
|
|
2734
2766
|
}
|
|
2735
|
-
const
|
|
2736
|
-
const defaultFunctionWithParameters = this.toNamedFunction(property.functionBody.toString(), declarationsSlot);
|
|
2737
|
-
defaultFunctionWithParameters.builder.parameters(...parameterNames.map((w, i)=>({
|
|
2738
|
-
name: defaultFunctionWithParameters.parameters[i],
|
|
2739
|
-
callName: w
|
|
2740
|
-
})));
|
|
2767
|
+
const call = this.emitBoundCall(factory, property.functionBody, args);
|
|
2741
2768
|
// Compute-once semantics for computed keys/identities: an existing value is
|
|
2742
2769
|
// carried into the enriched literal and never recomputed — a key must stay
|
|
2743
2770
|
// stable once assigned (content-hash ids would otherwise churn as the
|
|
@@ -2750,44 +2777,15 @@ class EnrichmentComputedValueHandler extends PropertyInfoHandler {
|
|
|
2750
2777
|
const enrichedAssignmentPath = property.getAssignmentPath({
|
|
2751
2778
|
parent: "enriched"
|
|
2752
2779
|
});
|
|
2753
|
-
ifsSlot.if(`${enrichedAssignmentPath} == null`).appendBody(`${enrichedAssignmentPath} = ${
|
|
2780
|
+
ifsSlot.if(`${enrichedAssignmentPath} == null`).appendBody(`${enrichedAssignmentPath} = ${call}`);
|
|
2754
2781
|
return builder;
|
|
2755
2782
|
}
|
|
2756
2783
|
return super.handle(property, builder);
|
|
2757
2784
|
}
|
|
2758
2785
|
}
|
|
2759
2786
|
|
|
2760
|
-
|
|
2761
|
-
|
|
2762
|
-
/**
|
|
2763
|
-
* Types whose runtime value is a JS array.
|
|
2764
|
-
*
|
|
2765
|
-
* `Array` and `Vector` are the same thing to every layer that copies, compares, hashes or
|
|
2766
|
-
* freezes a value — a vector is a list of numbers and nothing more. They differ only where a
|
|
2767
|
-
* backend chooses storage, which is the one place that should ask for `SchemaTypes.Vector` by
|
|
2768
|
-
* name.
|
|
2769
|
-
*
|
|
2770
|
-
* This exists so adding a third array-shaped type is one edit rather than a hunt through
|
|
2771
|
-
* twelve handlers. Missing one of those is silent in the worst way: a vector that clones by
|
|
2772
|
-
* reference is shared with the change tracker's copy, so overwriting an embedding produces no
|
|
2773
|
-
* diff and the save reports nothing to do.
|
|
2774
|
-
*/ const ARRAY_VALUED_TYPES = new Set([
|
|
2775
|
-
types/* .SchemaTypes.Array */.L.Array,
|
|
2776
|
-
types/* .SchemaTypes.Vector */.L.Vector
|
|
2777
|
-
]);
|
|
2778
|
-
/** True when the property's value is a JS array and needs value rather than reference semantics. */ const isArrayValued = (type)=>ARRAY_VALUED_TYPES.has(type);
|
|
2779
|
-
/**
|
|
2780
|
-
* True when the property's elements are primitives, so a spread is a sufficient copy.
|
|
2781
|
-
*
|
|
2782
|
-
* A vector is always numbers, so it never needs the per-element deep copy an array of objects
|
|
2783
|
-
* or dates does.
|
|
2784
|
-
*/ const PRIMITIVE_ELEMENT_TYPES = new Set([
|
|
2785
|
-
types/* .SchemaTypes.String */.L.String,
|
|
2786
|
-
types/* .SchemaTypes.Number */.L.Number,
|
|
2787
|
-
types/* .SchemaTypes.Boolean */.L.Boolean
|
|
2788
|
-
]);
|
|
2789
|
-
const hasPrimitiveElements = (type, elementType)=>type === types/* .SchemaTypes.Vector */.L.Vector || PRIMITIVE_ELEMENT_TYPES.has(elementType);
|
|
2790
|
-
|
|
2787
|
+
// EXTERNAL MODULE: ./src/schema/utils/propertyKind.ts
|
|
2788
|
+
var propertyKind = __webpack_require__(575);
|
|
2791
2789
|
;// CONCATENATED MODULE: ./src/codegen/handlers/enrichment/EnrichmentArrayHandler.ts
|
|
2792
2790
|
|
|
2793
2791
|
|
|
@@ -2797,7 +2795,7 @@ const hasPrimitiveElements = (type, elementType)=>type === types/* .SchemaTypes.
|
|
|
2797
2795
|
* mark the root entity dirty instead of being silently lost on save.
|
|
2798
2796
|
*/ class EnrichmentArrayHandler extends PropertyInfoHandler {
|
|
2799
2797
|
handle(property, builder) {
|
|
2800
|
-
if (isArrayValued(property.type)) {
|
|
2798
|
+
if ((0,propertyKind/* .isArrayValued */.l)(property.type)) {
|
|
2801
2799
|
// Place the property in the enriched literal like any other leaf
|
|
2802
2800
|
this.setEnrichedProperty(property, builder);
|
|
2803
2801
|
const enrichedPath = property.getAssignmentPath({
|
|
@@ -2839,13 +2837,10 @@ class MergeDefaultFunctionHandler extends PropertyInfoHandler {
|
|
|
2839
2837
|
// we are changing merge to be more like enrich so we can handle injections
|
|
2840
2838
|
// we may need to change more. Need to move towards factories
|
|
2841
2839
|
if (property.defaultValue != null && typeof property.defaultValue === "function") {
|
|
2842
|
-
const
|
|
2843
|
-
|
|
2844
|
-
|
|
2845
|
-
|
|
2846
|
-
factory.parameters(parameter);
|
|
2847
|
-
defaultFunctionParameters.push(parameter.name);
|
|
2848
|
-
}
|
|
2840
|
+
const factory = builder.get("factory");
|
|
2841
|
+
const args = property.injected != null ? [
|
|
2842
|
+
factory.bind(property.injected)
|
|
2843
|
+
] : [];
|
|
2849
2844
|
// A defaulted property still merges from the source; the default only fills
|
|
2850
2845
|
// the gap when neither side has a value
|
|
2851
2846
|
this.emitMergeCopy(property, builder, {
|
|
@@ -2861,15 +2856,9 @@ class MergeDefaultFunctionHandler extends PropertyInfoHandler {
|
|
|
2861
2856
|
const assignmentPath = property.getAssignmentPath({
|
|
2862
2857
|
parent: "destination"
|
|
2863
2858
|
});
|
|
2864
|
-
const declarationsSlot = builder.get("factory.function.header");
|
|
2865
|
-
const defaultFunctionWithParameters = this.toNamedFunction(property.defaultValue.toString(), declarationsSlot);
|
|
2866
|
-
defaultFunctionWithParameters.builder.parameters(...defaultFunctionParameters.map((w, i)=>({
|
|
2867
|
-
name: defaultFunctionWithParameters.parameters[i],
|
|
2868
|
-
callName: w
|
|
2869
|
-
})));
|
|
2870
2859
|
const defaultIf = ifsSlot.if(`${selectorPath} == null`);
|
|
2871
2860
|
this.emitDestinationAncestorGuards(property, defaultIf);
|
|
2872
|
-
defaultIf.appendBody(`${assignmentPath} = ${
|
|
2861
|
+
defaultIf.appendBody(`${assignmentPath} = ${this.emitBoundCall(factory, property.defaultValue, args)}`);
|
|
2873
2862
|
return builder;
|
|
2874
2863
|
}
|
|
2875
2864
|
return super.handle(property, builder);
|
|
@@ -2910,28 +2899,20 @@ class MergePrimitiveHandler extends PropertyInfoHandler {
|
|
|
2910
2899
|
class MergeComputedValueHandler extends PropertyInfoHandler {
|
|
2911
2900
|
handle(property, builder) {
|
|
2912
2901
|
if (property.functionBody != null && property.type === types/* .SchemaTypes.Computed */.L.Computed) {
|
|
2913
|
-
const
|
|
2902
|
+
const factory = builder.get("factory");
|
|
2903
|
+
const args = [
|
|
2914
2904
|
"source",
|
|
2915
2905
|
"collectionName"
|
|
2916
2906
|
];
|
|
2917
2907
|
if (property.injected != null) {
|
|
2918
|
-
|
|
2919
|
-
const parameter = factory.createParameter(property.injected);
|
|
2920
|
-
factory.parameters(parameter);
|
|
2921
|
-
parameterNames.push(parameter.name);
|
|
2908
|
+
args.push(factory.bind(property.injected));
|
|
2922
2909
|
}
|
|
2923
|
-
const declarationsSlot = builder.get("factory.function.header");
|
|
2924
|
-
const defaultFunctionWithParameters = this.toNamedFunction(property.functionBody.toString(), declarationsSlot);
|
|
2925
|
-
defaultFunctionWithParameters.builder.parameters(...parameterNames.map((w, i)=>({
|
|
2926
|
-
name: defaultFunctionWithParameters.parameters[i],
|
|
2927
|
-
callName: w
|
|
2928
|
-
})));
|
|
2929
2910
|
const slot = builder.get("factory.function.assignments");
|
|
2930
2911
|
const enrichedAssignmentPath = property.getAssignmentPath({
|
|
2931
2912
|
parent: "destination"
|
|
2932
2913
|
});
|
|
2933
2914
|
// We want to recompute the value always in case there are changes
|
|
2934
|
-
slot.assign(enrichedAssignmentPath).value(
|
|
2915
|
+
slot.assign(enrichedAssignmentPath).value(this.emitBoundCall(factory, property.functionBody, args));
|
|
2935
2916
|
return builder;
|
|
2936
2917
|
}
|
|
2937
2918
|
return super.handle(property, builder);
|
|
@@ -3004,7 +2985,7 @@ class MergeFunctionHandler extends PropertyInfoHandler {
|
|
|
3004
2985
|
* reference is adopted as-is — same as the primitive copy this replaces.
|
|
3005
2986
|
*/ class MergeArrayHandler extends PropertyInfoHandler {
|
|
3006
2987
|
handle(property, builder) {
|
|
3007
|
-
if (isArrayValued(property.type)) {
|
|
2988
|
+
if ((0,propertyKind/* .isArrayValued */.l)(property.type)) {
|
|
3008
2989
|
const selectorPath = property.getSelectrorPath({
|
|
3009
2990
|
parent: "source",
|
|
3010
2991
|
assignmentType: "FORCE_NULLABLE_OR_OPTIONAL"
|
|
@@ -3341,7 +3322,7 @@ class CloneArrayHandler extends PropertyInfoHandler {
|
|
|
3341
3322
|
super(), this.useFromPropertyName = useFromPropertyName;
|
|
3342
3323
|
}
|
|
3343
3324
|
handle(property, builder) {
|
|
3344
|
-
if (isArrayValued(property.type)) {
|
|
3325
|
+
if ((0,propertyKind/* .isArrayValued */.l)(property.type)) {
|
|
3345
3326
|
// Arrays are leaf properties — they have no child PropertyInfos, so the
|
|
3346
3327
|
// copy must happen here for every array, including nullable/optional ones.
|
|
3347
3328
|
// The `!== undefined` guard below covers absent values; an explicit null is copied as
|
|
@@ -3367,7 +3348,7 @@ class CloneArrayHandler extends PropertyInfoHandler {
|
|
|
3367
3348
|
// across merges), and a Proxy cannot pass a structured-clone boundary.
|
|
3368
3349
|
const elementType = property.innerSchema?.type;
|
|
3369
3350
|
let copyExpression;
|
|
3370
|
-
if (hasPrimitiveElements(property.type, elementType)) {
|
|
3351
|
+
if ((0,propertyKind/* .hasPrimitiveElements */.L)(property.type, elementType)) {
|
|
3371
3352
|
copyExpression = `[...${entitySelectorPath}]`;
|
|
3372
3353
|
} else if (elementType === types/* .SchemaTypes.Date */.L.Date) {
|
|
3373
3354
|
copyExpression = `${entitySelectorPath}.map(function (v) { return v == null ? v : new Date(v); })`;
|
|
@@ -3486,7 +3467,7 @@ class CloneObjectHandler extends PropertyInfoHandler {
|
|
|
3486
3467
|
// Anything that copies by assignment. An array-valued property must not land here:
|
|
3487
3468
|
// assigning the reference shares it with the source, which is the whole point of
|
|
3488
3469
|
// CloneArrayHandler.
|
|
3489
|
-
if (property.type != types/* .SchemaTypes.Object */.L.Object && isArrayValued(property.type) === false) {
|
|
3470
|
+
if (property.type != types/* .SchemaTypes.Object */.L.Object && (0,propertyKind/* .isArrayValued */.l)(property.type) === false) {
|
|
3490
3471
|
const slot = builder.get("if");
|
|
3491
3472
|
const useFromPropertyName = this.useFromPropertyName;
|
|
3492
3473
|
const entitySelectorPath = property.getSelectrorPath({
|
|
@@ -3549,7 +3530,7 @@ class CloneHandlerBuilder {
|
|
|
3549
3530
|
|
|
3550
3531
|
class CompareArrayHandler extends PropertyInfoHandler {
|
|
3551
3532
|
handle(property, builder) {
|
|
3552
|
-
if (isArrayValued(property.type)) {
|
|
3533
|
+
if ((0,propertyKind/* .isArrayValued */.l)(property.type)) {
|
|
3553
3534
|
let compare = builder.getOrDefault("result.variable.compare");
|
|
3554
3535
|
const leftCompare = property.getSelectrorPath({
|
|
3555
3536
|
parent: "a"
|
|
@@ -3844,7 +3825,6 @@ class DeserializeDeserializerHandler extends PropertyInfoHandler {
|
|
|
3844
3825
|
handle(property, builder) {
|
|
3845
3826
|
if (property.valueDeserializer != null) {
|
|
3846
3827
|
let objectBuilder = builder.getOrDefault("result.variable.object");
|
|
3847
|
-
const assignmentBuilder = builder.getOrDefault("functions");
|
|
3848
3828
|
// Read the incoming record by `from` (storage) name
|
|
3849
3829
|
const entitySelectorPath = property.getSelectrorPath({
|
|
3850
3830
|
parent: "unserialized",
|
|
@@ -3857,18 +3837,16 @@ class DeserializeDeserializerHandler extends PropertyInfoHandler {
|
|
|
3857
3837
|
name: "object"
|
|
3858
3838
|
});
|
|
3859
3839
|
}
|
|
3860
|
-
const
|
|
3861
|
-
|
|
3862
|
-
|
|
3863
|
-
callName: entitySelectorPath
|
|
3864
|
-
})));
|
|
3840
|
+
const call = this.emitBoundCall(builder, property.valueDeserializer, [
|
|
3841
|
+
entitySelectorPath
|
|
3842
|
+
]);
|
|
3865
3843
|
if (property.parent == null) {
|
|
3866
|
-
objectBuilder.property(`${property.name}: ${
|
|
3844
|
+
objectBuilder.property(`${property.name}: ${call}`);
|
|
3867
3845
|
return builder;
|
|
3868
3846
|
}
|
|
3869
3847
|
const slotPath = new SlotPath(...property.getParentPathArray());
|
|
3870
3848
|
objectBuilder = objectBuilder.get(slotPath.get());
|
|
3871
|
-
objectBuilder.property(`${property.name}: ${
|
|
3849
|
+
objectBuilder.property(`${property.name}: ${call}`);
|
|
3872
3850
|
return builder;
|
|
3873
3851
|
}
|
|
3874
3852
|
return super.handle(property, builder);
|
|
@@ -3894,7 +3872,7 @@ class DeserializeDeserializerHandler extends PropertyInfoHandler {
|
|
|
3894
3872
|
return `[...${selector}]`;
|
|
3895
3873
|
}
|
|
3896
3874
|
handle(property, builder) {
|
|
3897
|
-
if (isArrayValued(property.type)) {
|
|
3875
|
+
if ((0,propertyKind/* .isArrayValued */.l)(property.type)) {
|
|
3898
3876
|
const slotPath = new SlotPath("result.variable.object");
|
|
3899
3877
|
// Create the result object when this is the first property iterated —
|
|
3900
3878
|
// handler output cannot depend on schema property order
|
|
@@ -4135,7 +4113,7 @@ class HashComputedValueHandler extends PropertyInfoHandler {
|
|
|
4135
4113
|
* objects would collapse every value to "[object Object]" and collide.
|
|
4136
4114
|
*/ class HashArrayHandler extends PropertyInfoHandler {
|
|
4137
4115
|
handle(property, builder) {
|
|
4138
|
-
if (isArrayValued(property.type)) {
|
|
4116
|
+
if ((0,propertyKind/* .isArrayValued */.l)(property.type)) {
|
|
4139
4117
|
let stringBuilder = builder.getOrDefault("hash-object-return.variable.string");
|
|
4140
4118
|
const entitySelectorPath = property.getSelectrorPath({
|
|
4141
4119
|
parent: "entity"
|
|
@@ -4300,7 +4278,7 @@ class EnableChangeTrackingObjectHandler extends PropertyInfoHandler {
|
|
|
4300
4278
|
* mark the root entity dirty instead of being silently lost on save.
|
|
4301
4279
|
*/ class EnableChangeTrackingArrayHandler extends PropertyInfoHandler {
|
|
4302
4280
|
handle(property, builder) {
|
|
4303
|
-
if (isArrayValued(property.type)) {
|
|
4281
|
+
if ((0,propertyKind/* .isArrayValued */.l)(property.type)) {
|
|
4304
4282
|
const assignmentSlot = builder.get("assignment");
|
|
4305
4283
|
const childSelectorPath = property.getSelectrorPath({
|
|
4306
4284
|
parent: "entity"
|
|
@@ -4377,7 +4355,7 @@ class FreezeObjectHandler extends PropertyInfoHandler {
|
|
|
4377
4355
|
|
|
4378
4356
|
class FreezeArrayHandler extends PropertyInfoHandler {
|
|
4379
4357
|
handle(property, builder) {
|
|
4380
|
-
if (isArrayValued(property.type)) {
|
|
4358
|
+
if ((0,propertyKind/* .isArrayValued */.l)(property.type)) {
|
|
4381
4359
|
const assignmentSlot = builder.get("assignment");
|
|
4382
4360
|
const childSelectorPath = property.getSelectrorPath({
|
|
4383
4361
|
parent: "entity"
|
|
@@ -4513,7 +4491,6 @@ class SerializeSerializerHandler extends PropertyInfoHandler {
|
|
|
4513
4491
|
handle(property, builder) {
|
|
4514
4492
|
if (property.valueSerializer != null) {
|
|
4515
4493
|
const slot = builder.getOrDefault("if");
|
|
4516
|
-
const assignmentBuilder = builder.getOrDefault("functions");
|
|
4517
4494
|
// Serialize maps in-memory shape -> storage shape: read the entity by
|
|
4518
4495
|
// property name, write the result by `from` (storage) name
|
|
4519
4496
|
const entitySelectorPath = property.getSelectrorPath({
|
|
@@ -4523,17 +4500,15 @@ class SerializeSerializerHandler extends PropertyInfoHandler {
|
|
|
4523
4500
|
parent: "result",
|
|
4524
4501
|
useFromPropertyName: true
|
|
4525
4502
|
});
|
|
4526
|
-
const
|
|
4527
|
-
|
|
4528
|
-
|
|
4529
|
-
callName: entitySelectorPath
|
|
4530
|
-
})));
|
|
4503
|
+
const call = this.emitBoundCall(builder, property.valueSerializer, [
|
|
4504
|
+
entitySelectorPath
|
|
4505
|
+
]);
|
|
4531
4506
|
if (property.parent == null) {
|
|
4532
|
-
slot.if(`Object.hasOwn(entity, "${property.name}")`).appendBody(`${resultSelectorPath} = ${
|
|
4507
|
+
slot.if(`Object.hasOwn(entity, "${property.name}")`).appendBody(`${resultSelectorPath} = ${call}`);
|
|
4533
4508
|
return builder;
|
|
4534
4509
|
}
|
|
4535
4510
|
// Nested serializer: same pattern as SerializeValueHandler — if block for parent existence, then assign via serializer
|
|
4536
|
-
this.emitSerializeNestedAssignment(property, slot,
|
|
4511
|
+
this.emitSerializeNestedAssignment(property, slot, call);
|
|
4537
4512
|
return builder;
|
|
4538
4513
|
}
|
|
4539
4514
|
return super.handle(property, builder);
|
|
@@ -4592,7 +4567,7 @@ class SerializeComputedHandler extends PropertyInfoHandler {
|
|
|
4592
4567
|
return `[...${selector}]`;
|
|
4593
4568
|
}
|
|
4594
4569
|
handle(property, builder) {
|
|
4595
|
-
if (isArrayValued(property.type)) {
|
|
4570
|
+
if ((0,propertyKind/* .isArrayValued */.l)(property.type)) {
|
|
4596
4571
|
const slot = builder.get("if");
|
|
4597
4572
|
// Serialize maps in-memory shape -> storage shape: read the entity by
|
|
4598
4573
|
// property name, write the result by `from` (storage) name
|
|
@@ -5496,8 +5471,8 @@ const arrayConverter = (property, context)=>{
|
|
|
5496
5471
|
// Create the function using new Function()
|
|
5497
5472
|
// If no parameters, call with just the body; otherwise spread the params
|
|
5498
5473
|
const fn = params.length > 0 ? new Function(...params, functionBody) : new Function(functionBody);
|
|
5499
|
-
// Wrap it so toString() returns the original arrow function string
|
|
5500
|
-
//
|
|
5474
|
+
// Wrap it so toString() returns the original arrow function string, so
|
|
5475
|
+
// serializing the rehydrated schema writes the same functionSource again
|
|
5501
5476
|
recreatedFn = Object.assign(fn, {
|
|
5502
5477
|
toString: ()=>functionSource
|
|
5503
5478
|
});
|
|
@@ -5506,7 +5481,7 @@ const arrayConverter = (property, context)=>{
|
|
|
5506
5481
|
recreatedFn = ()=>{
|
|
5507
5482
|
throw new Error(`Cannot recreate computed property ${computedProp.name}: ${e instanceof Error ? e.message : 'unknown error'}`);
|
|
5508
5483
|
};
|
|
5509
|
-
//
|
|
5484
|
+
// Keep functionSource re-parseable if this schema is serialized again
|
|
5510
5485
|
Object.assign(recreatedFn, {
|
|
5511
5486
|
toString: ()=>`() => { throw new Error("Cannot recreate computed property ${computedProp.name}"); }`
|
|
5512
5487
|
});
|
|
@@ -5643,39 +5618,16 @@ class SetHandlerBuilder {
|
|
|
5643
5618
|
}
|
|
5644
5619
|
}
|
|
5645
5620
|
|
|
5646
|
-
;// CONCATENATED MODULE: ./src/schema/
|
|
5647
|
-
|
|
5648
|
-
|
|
5649
|
-
|
|
5650
|
-
|
|
5651
|
-
|
|
5652
|
-
|
|
5653
|
-
|
|
5654
|
-
|
|
5655
|
-
|
|
5656
|
-
|
|
5657
|
-
|
|
5658
|
-
|
|
5659
|
-
|
|
5660
|
-
|
|
5661
|
-
|
|
5662
|
-
|
|
5663
|
-
|
|
5664
|
-
|
|
5665
|
-
|
|
5666
|
-
|
|
5667
|
-
|
|
5668
|
-
|
|
5669
|
-
|
|
5670
|
-
|
|
5671
|
-
|
|
5672
|
-
|
|
5673
|
-
function assertPropertyHandled(generatorName, property, result) {
|
|
5674
|
-
if (result == null) {
|
|
5675
|
-
throw new Error(`Schema compilation failed: no '${generatorName}' code generator handles property '${property.getAssignmentPath()}' (type: ${property.type}). Add a handler for this property shape or mark it not applicable in the ${generatorName} chain.`);
|
|
5676
|
-
}
|
|
5677
|
-
}
|
|
5678
|
-
function createChangeTracker() {
|
|
5621
|
+
;// CONCATENATED MODULE: ./src/schema/changeTracker.ts
|
|
5622
|
+
/**
|
|
5623
|
+
* Builds the proxy factory that change-tracks an entity.
|
|
5624
|
+
*
|
|
5625
|
+
* Generated schema code receives the result as a bound value — a parameter of the generated
|
|
5626
|
+
* factory — and never refers to this module by name. Name references do not survive a minifier,
|
|
5627
|
+
* which renames the declaration but cannot see inside generated source text (#40, #46). The
|
|
5628
|
+
* returned function holds no per-entity state, so one per compiled schema is shared by every
|
|
5629
|
+
* entity it tracks.
|
|
5630
|
+
*/ function createChangeTracker() {
|
|
5679
5631
|
const DIRTY_ENTITY_MARKER = "isDirty";
|
|
5680
5632
|
const CHANGES_ENTITY_KEY = "changes";
|
|
5681
5633
|
const ORIGINAL_ENTITY_KEY = "original";
|
|
@@ -5774,6 +5726,40 @@ function createChangeTracker() {
|
|
|
5774
5726
|
return new Proxy(entity, proxyHandler);
|
|
5775
5727
|
};
|
|
5776
5728
|
}
|
|
5729
|
+
|
|
5730
|
+
;// CONCATENATED MODULE: ./src/schema/SchemaDefinition.ts
|
|
5731
|
+
|
|
5732
|
+
|
|
5733
|
+
|
|
5734
|
+
|
|
5735
|
+
|
|
5736
|
+
|
|
5737
|
+
|
|
5738
|
+
|
|
5739
|
+
|
|
5740
|
+
|
|
5741
|
+
|
|
5742
|
+
|
|
5743
|
+
|
|
5744
|
+
|
|
5745
|
+
|
|
5746
|
+
|
|
5747
|
+
|
|
5748
|
+
|
|
5749
|
+
|
|
5750
|
+
|
|
5751
|
+
|
|
5752
|
+
|
|
5753
|
+
|
|
5754
|
+
|
|
5755
|
+
|
|
5756
|
+
|
|
5757
|
+
|
|
5758
|
+
function assertPropertyHandled(generatorName, property, result) {
|
|
5759
|
+
if (result == null) {
|
|
5760
|
+
throw new Error(`Schema compilation failed: no '${generatorName}' code generator handles property '${property.getAssignmentPath()}' (type: ${property.type}). Add a handler for this property shape or mark it not applicable in the ${generatorName} chain.`);
|
|
5761
|
+
}
|
|
5762
|
+
}
|
|
5777
5763
|
class SchemaDefinition extends SchemaBase {
|
|
5778
5764
|
instance;
|
|
5779
5765
|
type = types/* .SchemaTypes.Definition */.L.Definition;
|
|
@@ -5824,10 +5810,22 @@ class SchemaDefinition extends SchemaBase {
|
|
|
5824
5810
|
throw e;
|
|
5825
5811
|
}
|
|
5826
5812
|
}
|
|
5827
|
-
|
|
5813
|
+
/**
|
|
5814
|
+
* Compiles `builder` into a function taking `fnArgs`.
|
|
5815
|
+
*
|
|
5816
|
+
* A builder with bindings is compiled one level out: an outer function whose parameters are
|
|
5817
|
+
* the bindings, called once here with their values, returns the function that is kept. The
|
|
5818
|
+
* bound values become closure variables of that function, so the per-call cost is a context
|
|
5819
|
+
* read rather than anything resolved by name.
|
|
5820
|
+
*/ createFunction(builder, ...fnArgs) {
|
|
5828
5821
|
const body = builder.toString();
|
|
5822
|
+
const bindings = builder.getBindings();
|
|
5829
5823
|
try {
|
|
5830
|
-
|
|
5824
|
+
if (bindings.length === 0) {
|
|
5825
|
+
return Function(...fnArgs, body);
|
|
5826
|
+
}
|
|
5827
|
+
const outer = Function(...bindings.map((w)=>w.name), `return function(${fnArgs.join(", ")}) {\n${body}\n}`);
|
|
5828
|
+
return outer(...bindings.map((w)=>w.value));
|
|
5831
5829
|
} catch (e) {
|
|
5832
5830
|
logger/* .logger.error */.vF.error(`Error compiling schema function. Function Body: ${body}`);
|
|
5833
5831
|
throw e;
|
|
@@ -5960,9 +5958,11 @@ class SchemaDefinition extends SchemaBase {
|
|
|
5960
5958
|
const serializeHandler = serializeHandlerBuilder.build();
|
|
5961
5959
|
const compareIdsHandler = compareIdsHandlerBuilder.build();
|
|
5962
5960
|
const setHandlerHanlder = setHandlerBuilder.build();
|
|
5961
|
+
// Handed to the generated functions as a value, never embedded as source and called
|
|
5962
|
+
// by name — a minifier renames the declaration and breaks every schema (#40).
|
|
5963
|
+
const changeTracker = createChangeTracker();
|
|
5963
5964
|
const changeTrackingCodeBuilder = new blocks/* .CodeBuilder */.Nl();
|
|
5964
|
-
changeTrackingCodeBuilder.
|
|
5965
|
-
changeTrackingCodeBuilder.slot("declarations").variable("enableChangeTracking").value('createChangeTracker()');
|
|
5965
|
+
changeTrackingCodeBuilder.bind(changeTracker, "enableChangeTracking");
|
|
5966
5966
|
// Nested proxies are installed by assigning through already-proxied parents;
|
|
5967
5967
|
// pause tracking during setup so those writes don't register as changes
|
|
5968
5968
|
changeTrackingCodeBuilder.slot("pause").raw('\tconst hadTracking = entity.__tracking__ != null;\n\tif (!hadTracking) { Object.defineProperty(entity, "__tracking__", { value: { changes: {}, isDirty: false, original: {}, isPaused: false }, configurable: true, writable: true, enumerable: false }); }\n\tconst wasPaused = entity.__tracking__.isPaused;\n\tentity.__tracking__.isPaused = true;');
|
|
@@ -5991,9 +5991,10 @@ class SchemaDefinition extends SchemaBase {
|
|
|
5991
5991
|
}).parameters({
|
|
5992
5992
|
name: "collectionName",
|
|
5993
5993
|
value: this.collectionName
|
|
5994
|
+
}, {
|
|
5995
|
+
name: "changeTracker",
|
|
5996
|
+
value: changeTracker
|
|
5994
5997
|
});
|
|
5995
|
-
enricherFunctionRoot.slot("changeTracker").raw(`${createChangeTracker.toString()}`);
|
|
5996
|
-
enricherFunctionRoot.slot("changeTrackerFunction").raw(`\tconst changeTracker = createChangeTracker();`);
|
|
5997
5998
|
const enricherFunctionBody = enricherFunctionRoot.function(undefined, {
|
|
5998
5999
|
name: "function"
|
|
5999
6000
|
}).parameters("entity", "changeTrackingType").return();
|
|
@@ -6228,6 +6229,8 @@ class SchemaDefinition extends SchemaBase {
|
|
|
6228
6229
|
enricherFunctionBody.get("append").insert(deserializeCodeBuilder.get("result"));
|
|
6229
6230
|
enricherFunctionBody.get("append").insert(deserializeCodeBuilder.get("if"));
|
|
6230
6231
|
enricherFunctionRoot.replace("function", new blocks/* .FunctionBuilder */.kF(undefined).parameters("unserialized", "changeTrackingType").return());
|
|
6232
|
+
// The deserialize slots moved in above call the deserializers bound on their own builder
|
|
6233
|
+
enricherFunctionRoot.parameters(...deserializeCodeBuilder.getBindings());
|
|
6231
6234
|
const postProcessGenerator = this.createReturnFunction(enricherCodeBuilder);
|
|
6232
6235
|
const postProcessParams = enricherFunctionRoot.getParameters();
|
|
6233
6236
|
// Combine prepare and serialize
|
|
@@ -6236,6 +6239,10 @@ class SchemaDefinition extends SchemaBase {
|
|
|
6236
6239
|
preprocessCodeBuilder.get("main").insert(serializeCodeBuilder.get("assignments"));
|
|
6237
6240
|
preprocessCodeBuilder.get("main").insert(serializeCodeBuilder.get("functions"));
|
|
6238
6241
|
preprocessCodeBuilder.get("main").insert(serializeCodeBuilder.get("if"));
|
|
6242
|
+
// Likewise the serialize slots call the serializers bound on the serialize builder
|
|
6243
|
+
for (const binding of serializeCodeBuilder.getBindings()){
|
|
6244
|
+
preprocessCodeBuilder.bind(binding.value, binding.name);
|
|
6245
|
+
}
|
|
6239
6246
|
const getIdsFunction = this.createFunction(idSelectorCodeBuilder, "entity");
|
|
6240
6247
|
const getHashTypeFunction = this.createFunction(hashTypeCodeBuilder, "entity");
|
|
6241
6248
|
const prepareFunction = this.createFunction(prepareCodeBuilder, "entity");
|
|
@@ -6877,6 +6884,8 @@ const s = {
|
|
|
6877
6884
|
|
|
6878
6885
|
|
|
6879
6886
|
|
|
6887
|
+
// EXTERNAL MODULE: ./src/schema/utils/storageDates.ts
|
|
6888
|
+
var storageDates = __webpack_require__(894);
|
|
6880
6889
|
;// CONCATENATED MODULE: ./src/schema/index.ts
|
|
6881
6890
|
|
|
6882
6891
|
|
|
@@ -6889,6 +6898,7 @@ const s = {
|
|
|
6889
6898
|
|
|
6890
6899
|
|
|
6891
6900
|
|
|
6901
|
+
|
|
6892
6902
|
})();
|
|
6893
6903
|
|
|
6894
6904
|
var __webpack_exports__HashType = __webpack_exports__.$H;
|
|
@@ -6925,12 +6935,13 @@ var __webpack_exports__SchemaVector = __webpack_exports__.TF;
|
|
|
6925
6935
|
var __webpack_exports__compiledSchemaToJsonSchema = __webpack_exports__.VG;
|
|
6926
6936
|
var __webpack_exports__createStandardJsonSchemaProps = __webpack_exports__.hM;
|
|
6927
6937
|
var __webpack_exports__extractTypeInfo = __webpack_exports__.Od;
|
|
6938
|
+
var __webpack_exports__getStorageDateReviver = __webpack_exports__.TH;
|
|
6928
6939
|
var __webpack_exports__hasPrimitiveElements = __webpack_exports__.LL;
|
|
6929
6940
|
var __webpack_exports__isArrayValued = __webpack_exports__.ly;
|
|
6930
6941
|
var __webpack_exports__propertyInfoToJsonSchema = __webpack_exports__.UX;
|
|
6931
6942
|
var __webpack_exports__rehydrateSchemaFromJsonSchema = __webpack_exports__.L$;
|
|
6932
6943
|
var __webpack_exports__rehydrateSchemaFromJsonString = __webpack_exports__.Dk;
|
|
6933
6944
|
var __webpack_exports__s = __webpack_exports__.s;
|
|
6934
|
-
export { __webpack_exports__HashType as HashType, __webpack_exports__PropertyInfo as PropertyInfo, __webpack_exports__SchemaArray as SchemaArray, __webpack_exports__SchemaBase as SchemaBase, __webpack_exports__SchemaBoolean as SchemaBoolean, __webpack_exports__SchemaComputed as SchemaComputed, __webpack_exports__SchemaDate as SchemaDate, __webpack_exports__SchemaDefault as SchemaDefault, __webpack_exports__SchemaDefinition as SchemaDefinition, __webpack_exports__SchemaDeserialize as SchemaDeserialize, __webpack_exports__SchemaDistinct as SchemaDistinct, __webpack_exports__SchemaFile as SchemaFile, __webpack_exports__SchemaForeignKey as SchemaForeignKey, __webpack_exports__SchemaFrom as SchemaFrom, __webpack_exports__SchemaFunction as SchemaFunction, __webpack_exports__SchemaIdentity as SchemaIdentity, __webpack_exports__SchemaIndex as SchemaIndex, __webpack_exports__SchemaKey as SchemaKey, __webpack_exports__SchemaNullable as SchemaNullable, __webpack_exports__SchemaNumber as SchemaNumber, __webpack_exports__SchemaObject as SchemaObject, __webpack_exports__SchemaOptional as SchemaOptional, __webpack_exports__SchemaReadonly as SchemaReadonly, __webpack_exports__SchemaSearchable as SchemaSearchable, __webpack_exports__SchemaSerialize as SchemaSerialize, __webpack_exports__SchemaString as SchemaString, __webpack_exports__SchemaTag as SchemaTag, __webpack_exports__SchemaTracked as SchemaTracked, __webpack_exports__SchemaTransform as SchemaTransform, __webpack_exports__SchemaTypes as SchemaTypes, __webpack_exports__SchemaVector as SchemaVector, __webpack_exports__compiledSchemaToJsonSchema as compiledSchemaToJsonSchema, __webpack_exports__createStandardJsonSchemaProps as createStandardJsonSchemaProps, __webpack_exports__extractTypeInfo as extractTypeInfo, __webpack_exports__hasPrimitiveElements as hasPrimitiveElements, __webpack_exports__isArrayValued as isArrayValued, __webpack_exports__propertyInfoToJsonSchema as propertyInfoToJsonSchema, __webpack_exports__rehydrateSchemaFromJsonSchema as rehydrateSchemaFromJsonSchema, __webpack_exports__rehydrateSchemaFromJsonString as rehydrateSchemaFromJsonString, __webpack_exports__s as s };
|
|
6945
|
+
export { __webpack_exports__HashType as HashType, __webpack_exports__PropertyInfo as PropertyInfo, __webpack_exports__SchemaArray as SchemaArray, __webpack_exports__SchemaBase as SchemaBase, __webpack_exports__SchemaBoolean as SchemaBoolean, __webpack_exports__SchemaComputed as SchemaComputed, __webpack_exports__SchemaDate as SchemaDate, __webpack_exports__SchemaDefault as SchemaDefault, __webpack_exports__SchemaDefinition as SchemaDefinition, __webpack_exports__SchemaDeserialize as SchemaDeserialize, __webpack_exports__SchemaDistinct as SchemaDistinct, __webpack_exports__SchemaFile as SchemaFile, __webpack_exports__SchemaForeignKey as SchemaForeignKey, __webpack_exports__SchemaFrom as SchemaFrom, __webpack_exports__SchemaFunction as SchemaFunction, __webpack_exports__SchemaIdentity as SchemaIdentity, __webpack_exports__SchemaIndex as SchemaIndex, __webpack_exports__SchemaKey as SchemaKey, __webpack_exports__SchemaNullable as SchemaNullable, __webpack_exports__SchemaNumber as SchemaNumber, __webpack_exports__SchemaObject as SchemaObject, __webpack_exports__SchemaOptional as SchemaOptional, __webpack_exports__SchemaReadonly as SchemaReadonly, __webpack_exports__SchemaSearchable as SchemaSearchable, __webpack_exports__SchemaSerialize as SchemaSerialize, __webpack_exports__SchemaString as SchemaString, __webpack_exports__SchemaTag as SchemaTag, __webpack_exports__SchemaTracked as SchemaTracked, __webpack_exports__SchemaTransform as SchemaTransform, __webpack_exports__SchemaTypes as SchemaTypes, __webpack_exports__SchemaVector as SchemaVector, __webpack_exports__compiledSchemaToJsonSchema as compiledSchemaToJsonSchema, __webpack_exports__createStandardJsonSchemaProps as createStandardJsonSchemaProps, __webpack_exports__extractTypeInfo as extractTypeInfo, __webpack_exports__getStorageDateReviver as getStorageDateReviver, __webpack_exports__hasPrimitiveElements as hasPrimitiveElements, __webpack_exports__isArrayValued as isArrayValued, __webpack_exports__propertyInfoToJsonSchema as propertyInfoToJsonSchema, __webpack_exports__rehydrateSchemaFromJsonSchema as rehydrateSchemaFromJsonSchema, __webpack_exports__rehydrateSchemaFromJsonString as rehydrateSchemaFromJsonString, __webpack_exports__s as s };
|
|
6935
6946
|
|
|
6936
6947
|
//# sourceMappingURL=index.js.map
|