@rljson/rljson 0.0.65 → 0.0.67
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/content/table-cfg.d.ts +7 -0
- package/dist/example/bakery-example.d.ts +2 -2
- package/dist/example.d.ts +1 -4
- package/dist/index.d.ts +1 -1
- package/dist/insertHistory/insertHistory.d.ts +24 -0
- package/dist/rljson.d.ts +2 -2
- package/dist/rljson.js +599 -309
- package/dist/route/route.d.ts +76 -5
- package/dist/src/example.ts +379 -173
- package/dist/typedefs.d.ts +1 -1
- package/package.json +11 -11
- package/dist/history/history.d.ts +0 -24
package/dist/rljson.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { hip, hsh } from "@rljson/hash";
|
|
2
2
|
import { exampleJsonObject, jsonValueTypes, jsonValueMatchesType, jsonValueType } from "@rljson/json";
|
|
3
3
|
import { nanoid } from "nanoid";
|
|
4
|
-
// @license
|
|
5
4
|
class Route {
|
|
6
5
|
constructor(_segments) {
|
|
7
6
|
this._segments = _segments;
|
|
8
7
|
}
|
|
8
|
+
_propertyKey;
|
|
9
9
|
// .............................................................................
|
|
10
10
|
/**
|
|
11
11
|
* Creates a Route from a flat string representation.
|
|
@@ -17,7 +17,7 @@ class Route {
|
|
|
17
17
|
const segments = [];
|
|
18
18
|
for (const segmentFlat of segmentsFlat) {
|
|
19
19
|
const [tableKey, refFlat] = segmentFlat.split("@");
|
|
20
|
-
const ref = !!refFlat ? refFlat.split(":").length == 2 ? { [tableKey + "
|
|
20
|
+
const ref = !!refFlat ? refFlat.split(":").length == 2 ? { [tableKey + "InsertHistoryRef"]: refFlat } : { [tableKey + "Ref"]: refFlat } : {};
|
|
21
21
|
const segment = {
|
|
22
22
|
tableKey,
|
|
23
23
|
...ref
|
|
@@ -59,6 +59,78 @@ class Route {
|
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
61
|
// .............................................................................
|
|
62
|
+
/**
|
|
63
|
+
* Returns a new Route that is one level higher than the current route.
|
|
64
|
+
* If steps is provided, it returns a new Route that is 'steps' levels higher.
|
|
65
|
+
* @param steps - The number of levels to go higher (optional)
|
|
66
|
+
* @returns A new Route that is one level higher or 'steps' levels higher
|
|
67
|
+
*/
|
|
68
|
+
upper(steps) {
|
|
69
|
+
if (steps === void 0) {
|
|
70
|
+
return new Route(this._segments.slice(0, -1));
|
|
71
|
+
} else {
|
|
72
|
+
if (steps < 1) {
|
|
73
|
+
throw new Error("Steps must be greater than 0");
|
|
74
|
+
}
|
|
75
|
+
if (steps >= this._segments.length) {
|
|
76
|
+
throw new Error("Cannot go upper than the top level");
|
|
77
|
+
}
|
|
78
|
+
return new Route(this._segments.slice(0, -steps));
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
// .............................................................................
|
|
82
|
+
/**
|
|
83
|
+
* Returns a new Route with the property key set to the last segment's table key.
|
|
84
|
+
* If the property key is already set, it returns the current route.
|
|
85
|
+
* @returns A new Route with the property key set
|
|
86
|
+
*/
|
|
87
|
+
toRouteWithProperty() {
|
|
88
|
+
if (this.hasPropertyKey) return this;
|
|
89
|
+
const route = this.upper();
|
|
90
|
+
route.propertyKey = this.segment().tableKey;
|
|
91
|
+
return route;
|
|
92
|
+
}
|
|
93
|
+
// .............................................................................
|
|
94
|
+
/**
|
|
95
|
+
* Returns a new Route without the property key.
|
|
96
|
+
* If the property key is not set, it returns the current route.
|
|
97
|
+
* @returns A new Route without the property key
|
|
98
|
+
*/
|
|
99
|
+
toRouteWithoutProperty() {
|
|
100
|
+
if (!this.hasPropertyKey) return this;
|
|
101
|
+
const route = new Route(this._segments);
|
|
102
|
+
route.propertyKey = void 0;
|
|
103
|
+
return route;
|
|
104
|
+
}
|
|
105
|
+
// .............................................................................
|
|
106
|
+
/**
|
|
107
|
+
* Checks if the current route includes another route.
|
|
108
|
+
* A route includes another route if all segments of the other route
|
|
109
|
+
* are present in the current route in the same order.
|
|
110
|
+
* @param other - The other route to check
|
|
111
|
+
* @returns True if the current route includes the other route, false otherwise
|
|
112
|
+
*/
|
|
113
|
+
includes(other) {
|
|
114
|
+
if (other._segments.length < this._segments.length) {
|
|
115
|
+
return false;
|
|
116
|
+
}
|
|
117
|
+
for (let i = 0; i < this._segments.length; i++) {
|
|
118
|
+
const thisSegment = this._segments[i];
|
|
119
|
+
const otherSegment = other._segments[i];
|
|
120
|
+
if (thisSegment.tableKey !== otherSegment.tableKey) {
|
|
121
|
+
return false;
|
|
122
|
+
}
|
|
123
|
+
if (Route.segmentHasRef(thisSegment) && Route.segmentHasRef(otherSegment)) {
|
|
124
|
+
const thisRef = Route.segmentRef(thisSegment);
|
|
125
|
+
const otherRef = Route.segmentRef(otherSegment);
|
|
126
|
+
if (thisRef !== otherRef) {
|
|
127
|
+
return false;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
return true;
|
|
132
|
+
}
|
|
133
|
+
// .............................................................................
|
|
62
134
|
/**
|
|
63
135
|
* Checks if the current route is the root route.
|
|
64
136
|
* @returns True if the current route is the root route, false otherwise
|
|
@@ -72,6 +144,18 @@ class Route {
|
|
|
72
144
|
* @returns The flat string representation of the route (e.g. "/a/b/c")
|
|
73
145
|
*/
|
|
74
146
|
get flat() {
|
|
147
|
+
let flat = this.flatWithoutPropertyKey;
|
|
148
|
+
if (this.hasPropertyKey) {
|
|
149
|
+
flat += `/${this.propertyKey}`;
|
|
150
|
+
}
|
|
151
|
+
return flat;
|
|
152
|
+
}
|
|
153
|
+
// .............................................................................
|
|
154
|
+
/**
|
|
155
|
+
* Returns the flat string representation of the route without the property key.
|
|
156
|
+
* @returns The flat string representation of the route without the property key
|
|
157
|
+
*/
|
|
158
|
+
get flatWithoutPropertyKey() {
|
|
75
159
|
let flat = "";
|
|
76
160
|
for (const segment of this._segments) {
|
|
77
161
|
const tableKey = segment.tableKey;
|
|
@@ -81,6 +165,22 @@ class Route {
|
|
|
81
165
|
return flat;
|
|
82
166
|
}
|
|
83
167
|
// .............................................................................
|
|
168
|
+
/**
|
|
169
|
+
* Returns the flat string representation of the route without any references.
|
|
170
|
+
* @returns The flat string representation of the route without any references
|
|
171
|
+
*/
|
|
172
|
+
get flatWithoutRefs() {
|
|
173
|
+
let flat = "";
|
|
174
|
+
for (const segment of this._segments) {
|
|
175
|
+
const tableKey = segment.tableKey;
|
|
176
|
+
flat += `/${tableKey}`;
|
|
177
|
+
}
|
|
178
|
+
if (this.hasPropertyKey) {
|
|
179
|
+
flat += `/${this.propertyKey}`;
|
|
180
|
+
}
|
|
181
|
+
return flat;
|
|
182
|
+
}
|
|
183
|
+
// .............................................................................
|
|
84
184
|
/**
|
|
85
185
|
* Returns the segments of the route as an array of strings.
|
|
86
186
|
* @returns The segments of the route as an array of strings
|
|
@@ -121,6 +221,57 @@ class Route {
|
|
|
121
221
|
return this._segments.length > 0 && this._segments.every((s) => s.tableKey.length > 0);
|
|
122
222
|
}
|
|
123
223
|
// .............................................................................
|
|
224
|
+
/**
|
|
225
|
+
* Checks if the route has a property key.
|
|
226
|
+
* @returns True if the route has a property key, false otherwise
|
|
227
|
+
*/
|
|
228
|
+
get hasPropertyKey() {
|
|
229
|
+
return this._propertyKey !== void 0;
|
|
230
|
+
}
|
|
231
|
+
// .............................................................................
|
|
232
|
+
/**
|
|
233
|
+
* Returns the property key of the route if it exists.
|
|
234
|
+
* @returns The property key of the route or undefined if it doesn't exist
|
|
235
|
+
*/
|
|
236
|
+
get propertyKey() {
|
|
237
|
+
return this._propertyKey;
|
|
238
|
+
}
|
|
239
|
+
// .............................................................................
|
|
240
|
+
/**
|
|
241
|
+
* Sets the property key of the route.
|
|
242
|
+
* @param key - The property key to set
|
|
243
|
+
*/
|
|
244
|
+
set propertyKey(key) {
|
|
245
|
+
this._propertyKey = key;
|
|
246
|
+
}
|
|
247
|
+
// .............................................................................
|
|
248
|
+
/**
|
|
249
|
+
* Checks if two routes are equal.
|
|
250
|
+
* @param other - The other route to compare with
|
|
251
|
+
* @returns True if the routes are equal, false otherwise
|
|
252
|
+
*/
|
|
253
|
+
equals(other) {
|
|
254
|
+
return this.flat === other.flat;
|
|
255
|
+
}
|
|
256
|
+
// .............................................................................
|
|
257
|
+
/**
|
|
258
|
+
* Checks if two routes are equal without considering the property key.
|
|
259
|
+
* @param other - The other route to compare with
|
|
260
|
+
* @returns True if the routes are equal without considering the property key, false otherwise
|
|
261
|
+
*/
|
|
262
|
+
equalsWithoutPropertyKey(other) {
|
|
263
|
+
return this.flatWithoutPropertyKey === other.flatWithoutPropertyKey;
|
|
264
|
+
}
|
|
265
|
+
// .............................................................................
|
|
266
|
+
/**
|
|
267
|
+
* Checks if two routes are equal without considering the references.
|
|
268
|
+
* @param other - The other route to compare with
|
|
269
|
+
* @returns True if the routes are equal without considering the references, false otherwise
|
|
270
|
+
*/
|
|
271
|
+
equalsWithoutRefs(other) {
|
|
272
|
+
return this.flatWithoutRefs === other.flatWithoutRefs;
|
|
273
|
+
}
|
|
274
|
+
// .............................................................................
|
|
124
275
|
/**
|
|
125
276
|
* Returns the reference of a segment if it exists.
|
|
126
277
|
* @param segment - The segment to get the reference from
|
|
@@ -131,7 +282,6 @@ class Route {
|
|
|
131
282
|
const refKey = Object.keys(segment).find(
|
|
132
283
|
(k) => k.endsWith("Ref") && k !== "tableKey"
|
|
133
284
|
);
|
|
134
|
-
/* v8 ignore next -- @preserve */
|
|
135
285
|
if (refKey) {
|
|
136
286
|
return segment[refKey];
|
|
137
287
|
}
|
|
@@ -140,7 +290,7 @@ class Route {
|
|
|
140
290
|
}
|
|
141
291
|
// .............................................................................
|
|
142
292
|
/**
|
|
143
|
-
* Checks if a segment has any reference (either default or
|
|
293
|
+
* Checks if a segment has any reference (either default or insertHistory).
|
|
144
294
|
* @param segment - The segment to check
|
|
145
295
|
* @returns True if the segment has any reference, false otherwise
|
|
146
296
|
*/
|
|
@@ -149,24 +299,23 @@ class Route {
|
|
|
149
299
|
}
|
|
150
300
|
// .............................................................................
|
|
151
301
|
/**
|
|
152
|
-
* Checks if a segment has a default reference (i.e. not a
|
|
302
|
+
* Checks if a segment has a default reference (i.e. not a insertHistory reference).
|
|
153
303
|
* @param segment - The segment to check
|
|
154
304
|
* @returns True if the segment has a default reference, false otherwise
|
|
155
305
|
*/
|
|
156
306
|
static segmentHasDefaultRef(segment) {
|
|
157
|
-
return this.segmentHasRef(segment) && !this.
|
|
307
|
+
return this.segmentHasRef(segment) && !this.segmentHasInsertHistoryRef(segment);
|
|
158
308
|
}
|
|
159
309
|
// .............................................................................
|
|
160
310
|
/**
|
|
161
|
-
* Checks if a segment has a
|
|
311
|
+
* Checks if a segment has a insertHistory reference (i.e. an InsertHistoryRef).
|
|
162
312
|
* @param segment - The segment to check
|
|
163
|
-
* @returns True if the segment has a
|
|
313
|
+
* @returns True if the segment has a insertHistory reference, false otherwise
|
|
164
314
|
*/
|
|
165
|
-
static
|
|
166
|
-
return this.segmentHasRef(segment) && Object.keys(segment).some((k) => k.endsWith("
|
|
315
|
+
static segmentHasInsertHistoryRef(segment) {
|
|
316
|
+
return this.segmentHasRef(segment) && Object.keys(segment).some((k) => k.endsWith("InsertHistoryRef"));
|
|
167
317
|
}
|
|
168
318
|
}
|
|
169
|
-
// @license
|
|
170
319
|
const bakeryExample = () => {
|
|
171
320
|
const nutritionalValues = hip({
|
|
172
321
|
_type: "components",
|
|
@@ -294,8 +443,8 @@ const bakeryExample = () => {
|
|
|
294
443
|
}
|
|
295
444
|
]
|
|
296
445
|
});
|
|
297
|
-
const
|
|
298
|
-
_type: "
|
|
446
|
+
const ingredientsInsertHistory = hip({
|
|
447
|
+
_type: "insertHistory",
|
|
299
448
|
_data: [
|
|
300
449
|
{
|
|
301
450
|
timeId: "de72:1759123957292",
|
|
@@ -324,13 +473,11 @@ const bakeryExample = () => {
|
|
|
324
473
|
recipeIngredients,
|
|
325
474
|
ingredients,
|
|
326
475
|
nutritionalValues,
|
|
327
|
-
|
|
476
|
+
ingredientsInsertHistory
|
|
328
477
|
};
|
|
329
478
|
return result;
|
|
330
479
|
};
|
|
331
|
-
// @license
|
|
332
480
|
const exampleBuffetsTable = () => bakeryExample().buffets;
|
|
333
|
-
// @license
|
|
334
481
|
const createCakeTableCfg = (cakeKey) => ({
|
|
335
482
|
key: cakeKey,
|
|
336
483
|
type: "cakes",
|
|
@@ -356,9 +503,7 @@ const createCakeTableCfg = (cakeKey) => ({
|
|
|
356
503
|
isShared: true
|
|
357
504
|
});
|
|
358
505
|
const exampleCakesTable = () => bakeryExample().cakes;
|
|
359
|
-
// @license
|
|
360
506
|
const exampleComponentsTable = () => bakeryExample().nutritionalValues;
|
|
361
|
-
// @license
|
|
362
507
|
const createLayerTableCfg = (layerKey) => ({
|
|
363
508
|
key: layerKey,
|
|
364
509
|
type: "layers",
|
|
@@ -391,7 +536,6 @@ const createLayerTableCfg = (layerKey) => ({
|
|
|
391
536
|
isShared: true
|
|
392
537
|
});
|
|
393
538
|
const exampleLayersTable = () => bakeryExample().recipeLayers;
|
|
394
|
-
// @license
|
|
395
539
|
const exampleRevision = () => ({
|
|
396
540
|
table: "nutritionalValues",
|
|
397
541
|
id: "flour",
|
|
@@ -399,9 +543,7 @@ const exampleRevision = () => ({
|
|
|
399
543
|
successor: "IqeoWJjZQNlr-NVk2QT15B",
|
|
400
544
|
timestamp: 1743558427
|
|
401
545
|
});
|
|
402
|
-
// @license
|
|
403
546
|
const exampleSliceIdsTable = () => bakeryExample().slices;
|
|
404
|
-
// @license
|
|
405
547
|
class Example {
|
|
406
548
|
static ok = {
|
|
407
549
|
bakery: () => bakeryExample(),
|
|
@@ -535,26 +677,172 @@ class Example {
|
|
|
535
677
|
};
|
|
536
678
|
},
|
|
537
679
|
singleRef: () => {
|
|
680
|
+
const tableCfgs = hip({
|
|
681
|
+
_type: "tableCfgs",
|
|
682
|
+
_data: [
|
|
683
|
+
{
|
|
684
|
+
key: "tableA",
|
|
685
|
+
type: "components",
|
|
686
|
+
isHead: false,
|
|
687
|
+
isRoot: false,
|
|
688
|
+
isShared: true,
|
|
689
|
+
columns: [
|
|
690
|
+
{
|
|
691
|
+
key: "_hash",
|
|
692
|
+
type: "string",
|
|
693
|
+
titleLong: "Hash",
|
|
694
|
+
titleShort: "Hash"
|
|
695
|
+
},
|
|
696
|
+
{
|
|
697
|
+
key: "propertyA",
|
|
698
|
+
type: "string",
|
|
699
|
+
titleLong: "Key",
|
|
700
|
+
titleShort: "Key"
|
|
701
|
+
}
|
|
702
|
+
],
|
|
703
|
+
_hash: ""
|
|
704
|
+
},
|
|
705
|
+
{
|
|
706
|
+
key: "tableB",
|
|
707
|
+
type: "components",
|
|
708
|
+
isHead: false,
|
|
709
|
+
isRoot: false,
|
|
710
|
+
isShared: true,
|
|
711
|
+
columns: [
|
|
712
|
+
{
|
|
713
|
+
key: "_hash",
|
|
714
|
+
type: "string",
|
|
715
|
+
titleLong: "Hash",
|
|
716
|
+
titleShort: "Hash"
|
|
717
|
+
},
|
|
718
|
+
{
|
|
719
|
+
key: "propertyAFromTableA",
|
|
720
|
+
type: "string",
|
|
721
|
+
titleLong: "Table A Reference",
|
|
722
|
+
titleShort: "TableARef",
|
|
723
|
+
ref: {
|
|
724
|
+
tableKey: "tableA",
|
|
725
|
+
columnKey: "propertyA"
|
|
726
|
+
}
|
|
727
|
+
}
|
|
728
|
+
],
|
|
729
|
+
_hash: ""
|
|
730
|
+
}
|
|
731
|
+
]
|
|
732
|
+
});
|
|
733
|
+
const tableA = hip({
|
|
734
|
+
_type: "components",
|
|
735
|
+
_tableCfg: tableCfgs._data[0]._hash,
|
|
736
|
+
_data: [
|
|
737
|
+
{
|
|
738
|
+
propertyA: "a0"
|
|
739
|
+
},
|
|
740
|
+
{
|
|
741
|
+
propertyA: "a1"
|
|
742
|
+
}
|
|
743
|
+
],
|
|
744
|
+
_hash: ""
|
|
745
|
+
});
|
|
746
|
+
const tableB = hip({
|
|
747
|
+
_type: "components",
|
|
748
|
+
_tableCfg: tableCfgs._data[1]._hash,
|
|
749
|
+
_data: [
|
|
750
|
+
{
|
|
751
|
+
propertyAFromTableA: tableA._data[0]._hash
|
|
752
|
+
}
|
|
753
|
+
],
|
|
754
|
+
_hash: ""
|
|
755
|
+
});
|
|
538
756
|
return {
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
757
|
+
tableCfgs,
|
|
758
|
+
tableA,
|
|
759
|
+
tableB
|
|
760
|
+
};
|
|
761
|
+
},
|
|
762
|
+
multiRef: () => {
|
|
763
|
+
const tableCfgs = hip({
|
|
764
|
+
_type: "tableCfgs",
|
|
765
|
+
_data: [
|
|
766
|
+
{
|
|
767
|
+
key: "tableA",
|
|
768
|
+
type: "components",
|
|
769
|
+
isHead: false,
|
|
770
|
+
isRoot: false,
|
|
771
|
+
isShared: true,
|
|
772
|
+
columns: [
|
|
773
|
+
{
|
|
774
|
+
key: "_hash",
|
|
775
|
+
type: "string",
|
|
776
|
+
titleLong: "Hash",
|
|
777
|
+
titleShort: "Hash"
|
|
778
|
+
},
|
|
779
|
+
{
|
|
780
|
+
key: "propertyA",
|
|
781
|
+
type: "string",
|
|
782
|
+
titleLong: "Key",
|
|
783
|
+
titleShort: "Key"
|
|
784
|
+
}
|
|
785
|
+
],
|
|
786
|
+
_hash: ""
|
|
787
|
+
},
|
|
788
|
+
{
|
|
789
|
+
key: "tableB",
|
|
790
|
+
type: "components",
|
|
791
|
+
isHead: false,
|
|
792
|
+
isRoot: false,
|
|
793
|
+
isShared: true,
|
|
794
|
+
columns: [
|
|
795
|
+
{
|
|
796
|
+
key: "_hash",
|
|
797
|
+
type: "string",
|
|
798
|
+
titleLong: "Hash",
|
|
799
|
+
titleShort: "Hash"
|
|
800
|
+
},
|
|
801
|
+
{
|
|
802
|
+
key: "propertyAFromTableA",
|
|
803
|
+
type: "jsonValue",
|
|
804
|
+
titleLong: "Table A Reference",
|
|
805
|
+
titleShort: "TableARef",
|
|
806
|
+
ref: {
|
|
807
|
+
tableKey: "tableA",
|
|
808
|
+
columnKey: "propertyA"
|
|
809
|
+
}
|
|
810
|
+
}
|
|
811
|
+
],
|
|
812
|
+
_hash: ""
|
|
813
|
+
}
|
|
814
|
+
]
|
|
815
|
+
});
|
|
816
|
+
const tableA = hip({
|
|
817
|
+
_type: "components",
|
|
818
|
+
_tableCfg: tableCfgs._data[0]._hash,
|
|
819
|
+
_data: [
|
|
820
|
+
{
|
|
821
|
+
propertyA: "a0"
|
|
822
|
+
},
|
|
823
|
+
{
|
|
824
|
+
propertyA: "a1"
|
|
825
|
+
}
|
|
826
|
+
],
|
|
827
|
+
_hash: ""
|
|
828
|
+
});
|
|
829
|
+
const tableB = hip({
|
|
830
|
+
_type: "components",
|
|
831
|
+
_tableCfg: tableCfgs._data[1]._hash,
|
|
832
|
+
_data: [
|
|
833
|
+
{
|
|
834
|
+
propertyAFromTableA: [
|
|
835
|
+
tableA._data[0]._hash,
|
|
836
|
+
tableA._data[1]._hash
|
|
837
|
+
]
|
|
838
|
+
}
|
|
839
|
+
],
|
|
840
|
+
_hash: ""
|
|
841
|
+
});
|
|
842
|
+
return {
|
|
843
|
+
tableCfgs,
|
|
844
|
+
tableA,
|
|
845
|
+
tableB
|
|
558
846
|
};
|
|
559
847
|
},
|
|
560
848
|
singleSliceIdRef: () => {
|
|
@@ -597,89 +885,6 @@ class Example {
|
|
|
597
885
|
}
|
|
598
886
|
};
|
|
599
887
|
},
|
|
600
|
-
singleNamedRef: () => {
|
|
601
|
-
return {
|
|
602
|
-
tableA: {
|
|
603
|
-
_type: "components",
|
|
604
|
-
_data: [
|
|
605
|
-
{
|
|
606
|
-
keyA0: "a0"
|
|
607
|
-
},
|
|
608
|
-
{
|
|
609
|
-
keyA1: "a1"
|
|
610
|
-
}
|
|
611
|
-
]
|
|
612
|
-
},
|
|
613
|
-
tableB: {
|
|
614
|
-
_type: "components",
|
|
615
|
-
_data: [
|
|
616
|
-
{
|
|
617
|
-
namedRef: { component: "tableA", ref: "KFQrf4mEz0UPmUaFHwH4T6" }
|
|
618
|
-
}
|
|
619
|
-
]
|
|
620
|
-
}
|
|
621
|
-
};
|
|
622
|
-
},
|
|
623
|
-
multiRef: () => {
|
|
624
|
-
return {
|
|
625
|
-
tableA: {
|
|
626
|
-
_type: "components",
|
|
627
|
-
_data: [
|
|
628
|
-
{
|
|
629
|
-
keyA0: "a0"
|
|
630
|
-
},
|
|
631
|
-
{
|
|
632
|
-
keyA1: "a1"
|
|
633
|
-
}
|
|
634
|
-
]
|
|
635
|
-
},
|
|
636
|
-
tableB: {
|
|
637
|
-
_type: "components",
|
|
638
|
-
_data: [
|
|
639
|
-
{
|
|
640
|
-
tableARef: ["KFQrf4mEz0UPmUaFHwH4T6", "YPw-pxhqaUOWRFGramr4B1"]
|
|
641
|
-
}
|
|
642
|
-
]
|
|
643
|
-
}
|
|
644
|
-
};
|
|
645
|
-
},
|
|
646
|
-
multiMixedRef: () => {
|
|
647
|
-
return {
|
|
648
|
-
tableA: {
|
|
649
|
-
_type: "components",
|
|
650
|
-
_data: [
|
|
651
|
-
{
|
|
652
|
-
keyA0: "a0"
|
|
653
|
-
},
|
|
654
|
-
{
|
|
655
|
-
keyA1: "a1"
|
|
656
|
-
}
|
|
657
|
-
]
|
|
658
|
-
},
|
|
659
|
-
tableB: {
|
|
660
|
-
_type: "components",
|
|
661
|
-
_data: [
|
|
662
|
-
{
|
|
663
|
-
keyB0: "b0"
|
|
664
|
-
},
|
|
665
|
-
{
|
|
666
|
-
keyB1: "b1"
|
|
667
|
-
}
|
|
668
|
-
]
|
|
669
|
-
},
|
|
670
|
-
tableC: {
|
|
671
|
-
_type: "components",
|
|
672
|
-
_data: [
|
|
673
|
-
{
|
|
674
|
-
tableRef: [
|
|
675
|
-
{ component: "tableA", ref: "KFQrf4mEz0UPmUaFHwH4T6" },
|
|
676
|
-
{ component: "tableB", ref: "dXhIygNwNMVPEqFbsFJkn6" }
|
|
677
|
-
]
|
|
678
|
-
}
|
|
679
|
-
]
|
|
680
|
-
}
|
|
681
|
-
};
|
|
682
|
-
},
|
|
683
888
|
complete: () => {
|
|
684
889
|
const sliceIds = hip({
|
|
685
890
|
_type: "sliceIds",
|
|
@@ -777,87 +982,220 @@ class Example {
|
|
|
777
982
|
};
|
|
778
983
|
},
|
|
779
984
|
missingRef: () => {
|
|
985
|
+
const tableCfgs = hip({
|
|
986
|
+
_type: "tableCfgs",
|
|
987
|
+
_data: [
|
|
988
|
+
{
|
|
989
|
+
key: "tableA",
|
|
990
|
+
type: "components",
|
|
991
|
+
isHead: false,
|
|
992
|
+
isRoot: false,
|
|
993
|
+
isShared: true,
|
|
994
|
+
columns: [
|
|
995
|
+
{
|
|
996
|
+
key: "_hash",
|
|
997
|
+
type: "string",
|
|
998
|
+
titleLong: "Hash",
|
|
999
|
+
titleShort: "Hash"
|
|
1000
|
+
},
|
|
1001
|
+
{
|
|
1002
|
+
key: "propertyA",
|
|
1003
|
+
type: "string",
|
|
1004
|
+
titleLong: "Key",
|
|
1005
|
+
titleShort: "Key"
|
|
1006
|
+
}
|
|
1007
|
+
],
|
|
1008
|
+
_hash: ""
|
|
1009
|
+
},
|
|
1010
|
+
{
|
|
1011
|
+
key: "tableB",
|
|
1012
|
+
type: "components",
|
|
1013
|
+
isHead: false,
|
|
1014
|
+
isRoot: false,
|
|
1015
|
+
isShared: true,
|
|
1016
|
+
columns: [
|
|
1017
|
+
{
|
|
1018
|
+
key: "_hash",
|
|
1019
|
+
type: "string",
|
|
1020
|
+
titleLong: "Hash",
|
|
1021
|
+
titleShort: "Hash"
|
|
1022
|
+
},
|
|
1023
|
+
{
|
|
1024
|
+
key: "propertyAFromTableA",
|
|
1025
|
+
type: "jsonValue",
|
|
1026
|
+
titleLong: "Table A Reference",
|
|
1027
|
+
titleShort: "TableARef",
|
|
1028
|
+
ref: {
|
|
1029
|
+
tableKey: "tableA",
|
|
1030
|
+
columnKey: "propertyA"
|
|
1031
|
+
}
|
|
1032
|
+
}
|
|
1033
|
+
],
|
|
1034
|
+
_hash: ""
|
|
1035
|
+
}
|
|
1036
|
+
]
|
|
1037
|
+
});
|
|
1038
|
+
const tableA = hip({
|
|
1039
|
+
_type: "components",
|
|
1040
|
+
_tableCfg: tableCfgs._data[0]._hash,
|
|
1041
|
+
_data: [
|
|
1042
|
+
{
|
|
1043
|
+
propertyA: "a0"
|
|
1044
|
+
},
|
|
1045
|
+
{
|
|
1046
|
+
propertyA: "a1"
|
|
1047
|
+
}
|
|
1048
|
+
],
|
|
1049
|
+
_hash: ""
|
|
1050
|
+
});
|
|
1051
|
+
const tableB = hip({
|
|
1052
|
+
_type: "components",
|
|
1053
|
+
_tableCfg: tableCfgs._data[1]._hash,
|
|
1054
|
+
_data: [
|
|
1055
|
+
{
|
|
1056
|
+
propertyAFromTableA: "MISSINGREF"
|
|
1057
|
+
// Missing reference
|
|
1058
|
+
}
|
|
1059
|
+
],
|
|
1060
|
+
_hash: ""
|
|
1061
|
+
});
|
|
780
1062
|
return {
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
{
|
|
785
|
-
keyA0: "a0"
|
|
786
|
-
},
|
|
787
|
-
{
|
|
788
|
-
keyA1: "a1"
|
|
789
|
-
}
|
|
790
|
-
]
|
|
791
|
-
},
|
|
792
|
-
tableB: {
|
|
793
|
-
_type: "components",
|
|
794
|
-
_data: [
|
|
795
|
-
{
|
|
796
|
-
tableARef: "MISSINGREF"
|
|
797
|
-
// MISSINGREF does not exist in tableA
|
|
798
|
-
}
|
|
799
|
-
]
|
|
800
|
-
}
|
|
801
|
-
};
|
|
802
|
-
},
|
|
803
|
-
missingNamedRef: () => {
|
|
804
|
-
return {
|
|
805
|
-
tableA: {
|
|
806
|
-
_type: "components",
|
|
807
|
-
_data: [
|
|
808
|
-
{
|
|
809
|
-
keyA0: "a0"
|
|
810
|
-
},
|
|
811
|
-
{
|
|
812
|
-
keyA1: "a1"
|
|
813
|
-
}
|
|
814
|
-
]
|
|
815
|
-
},
|
|
816
|
-
tableB: {
|
|
817
|
-
_type: "components",
|
|
818
|
-
_data: [
|
|
819
|
-
{
|
|
820
|
-
namedRef: { component: "tableA", ref: "MISSINGREF" }
|
|
821
|
-
// MISSINGREF does not exist in tableA
|
|
822
|
-
}
|
|
823
|
-
]
|
|
824
|
-
}
|
|
1063
|
+
tableCfgs,
|
|
1064
|
+
tableA,
|
|
1065
|
+
tableB
|
|
825
1066
|
};
|
|
826
1067
|
},
|
|
827
1068
|
missingMultiRef: () => {
|
|
1069
|
+
const tableCfgs = hip({
|
|
1070
|
+
_type: "tableCfgs",
|
|
1071
|
+
_data: [
|
|
1072
|
+
{
|
|
1073
|
+
key: "tableA",
|
|
1074
|
+
type: "components",
|
|
1075
|
+
isHead: false,
|
|
1076
|
+
isRoot: false,
|
|
1077
|
+
isShared: true,
|
|
1078
|
+
columns: [
|
|
1079
|
+
{
|
|
1080
|
+
key: "_hash",
|
|
1081
|
+
type: "string",
|
|
1082
|
+
titleLong: "Hash",
|
|
1083
|
+
titleShort: "Hash"
|
|
1084
|
+
},
|
|
1085
|
+
{
|
|
1086
|
+
key: "propertyA",
|
|
1087
|
+
type: "string",
|
|
1088
|
+
titleLong: "Key",
|
|
1089
|
+
titleShort: "Key"
|
|
1090
|
+
}
|
|
1091
|
+
],
|
|
1092
|
+
_hash: ""
|
|
1093
|
+
},
|
|
1094
|
+
{
|
|
1095
|
+
key: "tableB",
|
|
1096
|
+
type: "components",
|
|
1097
|
+
isHead: false,
|
|
1098
|
+
isRoot: false,
|
|
1099
|
+
isShared: true,
|
|
1100
|
+
columns: [
|
|
1101
|
+
{
|
|
1102
|
+
key: "_hash",
|
|
1103
|
+
type: "string",
|
|
1104
|
+
titleLong: "Hash",
|
|
1105
|
+
titleShort: "Hash"
|
|
1106
|
+
},
|
|
1107
|
+
{
|
|
1108
|
+
key: "propertyAFromTableA",
|
|
1109
|
+
type: "jsonValue",
|
|
1110
|
+
titleLong: "Table A Reference",
|
|
1111
|
+
titleShort: "TableARef",
|
|
1112
|
+
ref: {
|
|
1113
|
+
tableKey: "tableA",
|
|
1114
|
+
columnKey: "propertyA"
|
|
1115
|
+
}
|
|
1116
|
+
}
|
|
1117
|
+
],
|
|
1118
|
+
_hash: ""
|
|
1119
|
+
}
|
|
1120
|
+
]
|
|
1121
|
+
});
|
|
1122
|
+
const tableA = hip({
|
|
1123
|
+
_type: "components",
|
|
1124
|
+
_tableCfg: tableCfgs._data[0]._hash,
|
|
1125
|
+
_data: [
|
|
1126
|
+
{
|
|
1127
|
+
propertyA: "a0"
|
|
1128
|
+
},
|
|
1129
|
+
{
|
|
1130
|
+
propertyA: "a1"
|
|
1131
|
+
}
|
|
1132
|
+
],
|
|
1133
|
+
_hash: ""
|
|
1134
|
+
});
|
|
1135
|
+
const tableB = hip({
|
|
1136
|
+
_type: "components",
|
|
1137
|
+
_tableCfg: tableCfgs._data[1]._hash,
|
|
1138
|
+
_data: [
|
|
1139
|
+
{
|
|
1140
|
+
propertyAFromTableA: [tableA._data[0]._hash, "MISSINGREF"]
|
|
1141
|
+
// Missing reference
|
|
1142
|
+
}
|
|
1143
|
+
],
|
|
1144
|
+
_hash: ""
|
|
1145
|
+
});
|
|
828
1146
|
return {
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
{
|
|
833
|
-
keyA0: "a0"
|
|
834
|
-
},
|
|
835
|
-
{
|
|
836
|
-
keyA1: "a1"
|
|
837
|
-
}
|
|
838
|
-
]
|
|
839
|
-
},
|
|
840
|
-
tableB: {
|
|
841
|
-
_type: "components",
|
|
842
|
-
_data: [
|
|
843
|
-
{
|
|
844
|
-
tableARef: ["KFQrf4mEz0UPmUaFHwH4T6", "MISSING"]
|
|
845
|
-
}
|
|
846
|
-
]
|
|
847
|
-
}
|
|
1147
|
+
tableCfgs,
|
|
1148
|
+
tableA,
|
|
1149
|
+
tableB
|
|
848
1150
|
};
|
|
849
1151
|
},
|
|
850
1152
|
missingReferencedTable: () => {
|
|
1153
|
+
const tableCfgs = hip({
|
|
1154
|
+
_type: "tableCfgs",
|
|
1155
|
+
_data: [
|
|
1156
|
+
{
|
|
1157
|
+
key: "tableB",
|
|
1158
|
+
type: "components",
|
|
1159
|
+
isHead: false,
|
|
1160
|
+
isRoot: false,
|
|
1161
|
+
isShared: true,
|
|
1162
|
+
columns: [
|
|
1163
|
+
{
|
|
1164
|
+
key: "_hash",
|
|
1165
|
+
type: "string",
|
|
1166
|
+
titleLong: "Hash",
|
|
1167
|
+
titleShort: "Hash"
|
|
1168
|
+
},
|
|
1169
|
+
{
|
|
1170
|
+
key: "propertyAFromTableA",
|
|
1171
|
+
type: "jsonValue",
|
|
1172
|
+
titleLong: "Table A Reference",
|
|
1173
|
+
titleShort: "TableARef",
|
|
1174
|
+
ref: {
|
|
1175
|
+
tableKey: "tableA",
|
|
1176
|
+
// Referenced table missing
|
|
1177
|
+
columnKey: "propertyA"
|
|
1178
|
+
}
|
|
1179
|
+
}
|
|
1180
|
+
],
|
|
1181
|
+
_hash: ""
|
|
1182
|
+
}
|
|
1183
|
+
]
|
|
1184
|
+
});
|
|
1185
|
+
const tableB = hip({
|
|
1186
|
+
_type: "components",
|
|
1187
|
+
_tableCfg: tableCfgs._data[0]._hash,
|
|
1188
|
+
_data: [
|
|
1189
|
+
{
|
|
1190
|
+
propertyAFromTableA: "MISSINGREF"
|
|
1191
|
+
// Missing reference
|
|
1192
|
+
}
|
|
1193
|
+
],
|
|
1194
|
+
_hash: ""
|
|
1195
|
+
});
|
|
851
1196
|
return {
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
_data: [
|
|
855
|
-
{
|
|
856
|
-
tableARef: "MISSINGREF"
|
|
857
|
-
// tableA is missing
|
|
858
|
-
}
|
|
859
|
-
]
|
|
860
|
-
}
|
|
1197
|
+
tableCfgs,
|
|
1198
|
+
tableB
|
|
861
1199
|
};
|
|
862
1200
|
},
|
|
863
1201
|
missingSliceId: () => {
|
|
@@ -992,7 +1330,6 @@ class Example {
|
|
|
992
1330
|
}
|
|
993
1331
|
};
|
|
994
1332
|
}
|
|
995
|
-
// @license
|
|
996
1333
|
const throwOnInvalidTableCfg = (tableCfg) => {
|
|
997
1334
|
if (tableCfg.columns.length < 2) {
|
|
998
1335
|
throw new Error(
|
|
@@ -1099,46 +1436,7 @@ const exampleTableCfg = (tableCfg = void 0) => {
|
|
|
1099
1436
|
isShared: false
|
|
1100
1437
|
};
|
|
1101
1438
|
};
|
|
1102
|
-
// @license
|
|
1103
|
-
const createHistoryTableCfg = (tableCfg) => ({
|
|
1104
|
-
key: `${tableCfg.key}History`,
|
|
1105
|
-
type: "history",
|
|
1106
|
-
columns: [
|
|
1107
|
-
{ key: "_hash", type: "string", titleLong: "Hash", titleShort: "Hash" },
|
|
1108
|
-
{
|
|
1109
|
-
key: "timeId",
|
|
1110
|
-
type: "string",
|
|
1111
|
-
titleLong: "Time ID",
|
|
1112
|
-
titleShort: "Time ID"
|
|
1113
|
-
},
|
|
1114
|
-
{
|
|
1115
|
-
key: `${tableCfg.key}Ref`,
|
|
1116
|
-
type: "string",
|
|
1117
|
-
titleLong: "Reference",
|
|
1118
|
-
titleShort: "Ref"
|
|
1119
|
-
},
|
|
1120
|
-
{ key: "route", type: "string", titleLong: "Route", titleShort: "Route" },
|
|
1121
|
-
{
|
|
1122
|
-
key: "origin",
|
|
1123
|
-
type: "string",
|
|
1124
|
-
titleLong: "Origin",
|
|
1125
|
-
titleShort: "Origin"
|
|
1126
|
-
},
|
|
1127
|
-
{
|
|
1128
|
-
key: "previous",
|
|
1129
|
-
type: "jsonArray",
|
|
1130
|
-
titleLong: "Previous",
|
|
1131
|
-
titleShort: "Previous"
|
|
1132
|
-
}
|
|
1133
|
-
],
|
|
1134
|
-
isHead: false,
|
|
1135
|
-
isRoot: false,
|
|
1136
|
-
isShared: false
|
|
1137
|
-
});
|
|
1138
|
-
const exampleHistoryTable = () => bakeryExample().ingredientsHistory;
|
|
1139
|
-
// @license
|
|
1140
1439
|
const objectDepth = (o) => Object(o) === o ? 1 + Math.max(-1, ...Object.values(o).map(objectDepth)) : 0;
|
|
1141
|
-
// @license
|
|
1142
1440
|
class InsertValidator {
|
|
1143
1441
|
constructor(_insert) {
|
|
1144
1442
|
this._insert = _insert;
|
|
@@ -1192,9 +1490,9 @@ class InsertValidator {
|
|
|
1192
1490
|
if (route.isValid) {
|
|
1193
1491
|
const routeDepth = route.segments.length;
|
|
1194
1492
|
const valueDepth = objectDepth(this._insert.value);
|
|
1195
|
-
if (routeDepth
|
|
1493
|
+
if (routeDepth > valueDepth) {
|
|
1196
1494
|
this.errors.dataRouteMismatch = {
|
|
1197
|
-
error: "Insert route depth does not match value depth. Route depth must
|
|
1495
|
+
error: "Insert route depth does not match value depth. Route depth must be lower than the depth of the value object.",
|
|
1198
1496
|
route: this._insert.route,
|
|
1199
1497
|
routeDepth,
|
|
1200
1498
|
valueDepth
|
|
@@ -1244,13 +1542,47 @@ class InsertValidator {
|
|
|
1244
1542
|
const validateInsert = (insert) => {
|
|
1245
1543
|
return InsertValidator.create(insert).validate();
|
|
1246
1544
|
};
|
|
1247
|
-
// @license
|
|
1248
1545
|
const exampleInsert = () => ({
|
|
1249
1546
|
route: "a/b/c",
|
|
1250
1547
|
command: "add",
|
|
1251
1548
|
value: { x: { y: { z: true } } }
|
|
1252
1549
|
});
|
|
1253
|
-
|
|
1550
|
+
const createInsertHistoryTableCfg = (tableCfg) => ({
|
|
1551
|
+
key: `${tableCfg.key}InsertHistory`,
|
|
1552
|
+
type: "insertHistory",
|
|
1553
|
+
columns: [
|
|
1554
|
+
{ key: "_hash", type: "string", titleLong: "Hash", titleShort: "Hash" },
|
|
1555
|
+
{
|
|
1556
|
+
key: "timeId",
|
|
1557
|
+
type: "string",
|
|
1558
|
+
titleLong: "Time ID",
|
|
1559
|
+
titleShort: "Time ID"
|
|
1560
|
+
},
|
|
1561
|
+
{
|
|
1562
|
+
key: `${tableCfg.key}Ref`,
|
|
1563
|
+
type: "string",
|
|
1564
|
+
titleLong: "Reference",
|
|
1565
|
+
titleShort: "Ref"
|
|
1566
|
+
},
|
|
1567
|
+
{ key: "route", type: "string", titleLong: "Route", titleShort: "Route" },
|
|
1568
|
+
{
|
|
1569
|
+
key: "origin",
|
|
1570
|
+
type: "string",
|
|
1571
|
+
titleLong: "Origin",
|
|
1572
|
+
titleShort: "Origin"
|
|
1573
|
+
},
|
|
1574
|
+
{
|
|
1575
|
+
key: "previous",
|
|
1576
|
+
type: "jsonArray",
|
|
1577
|
+
titleLong: "Previous",
|
|
1578
|
+
titleShort: "Previous"
|
|
1579
|
+
}
|
|
1580
|
+
],
|
|
1581
|
+
isHead: false,
|
|
1582
|
+
isRoot: false,
|
|
1583
|
+
isShared: false
|
|
1584
|
+
});
|
|
1585
|
+
const exampleInsertHistoryTable = () => bakeryExample().ingredientsInsertHistory;
|
|
1254
1586
|
const reservedFieldNames = ["_data"];
|
|
1255
1587
|
const reservedTableKeys = [
|
|
1256
1588
|
"_hash",
|
|
@@ -1290,7 +1622,6 @@ const iterateTables = async (rljson, callback) => {
|
|
|
1290
1622
|
throw errors;
|
|
1291
1623
|
}
|
|
1292
1624
|
};
|
|
1293
|
-
// @license
|
|
1294
1625
|
const removeDuplicates = (rljson) => {
|
|
1295
1626
|
const result = {};
|
|
1296
1627
|
for (const key in rljson) {
|
|
@@ -1304,7 +1635,6 @@ const removeDuplicates = (rljson) => {
|
|
|
1304
1635
|
}
|
|
1305
1636
|
return hip(result, { throwOnWrongHashes: false, updateExistingHashes: true });
|
|
1306
1637
|
};
|
|
1307
|
-
// @license
|
|
1308
1638
|
const timeId = () => {
|
|
1309
1639
|
return nanoid(4) + ":" + Date.now();
|
|
1310
1640
|
};
|
|
@@ -1314,7 +1644,6 @@ const isTimeId = (id) => {
|
|
|
1314
1644
|
if (isNaN(Number(parts[1]))) return false;
|
|
1315
1645
|
return parts[0].length === 4;
|
|
1316
1646
|
};
|
|
1317
|
-
// @license
|
|
1318
1647
|
const contentTypes = [
|
|
1319
1648
|
"buffets",
|
|
1320
1649
|
"cakes",
|
|
@@ -1323,7 +1652,7 @@ const contentTypes = [
|
|
|
1323
1652
|
"components",
|
|
1324
1653
|
"revisions",
|
|
1325
1654
|
"tableCfgs",
|
|
1326
|
-
"
|
|
1655
|
+
"insertHistory"
|
|
1327
1656
|
];
|
|
1328
1657
|
const exampleTypedefs = () => {
|
|
1329
1658
|
return {
|
|
@@ -1333,7 +1662,6 @@ const exampleTypedefs = () => {
|
|
|
1333
1662
|
contentType: "layers"
|
|
1334
1663
|
};
|
|
1335
1664
|
};
|
|
1336
|
-
// @license
|
|
1337
1665
|
const rljsonIndexed = (rljson) => {
|
|
1338
1666
|
const result = {};
|
|
1339
1667
|
for (const key in rljson) {
|
|
@@ -1356,7 +1684,6 @@ const rljsonIndexed = (rljson) => {
|
|
|
1356
1684
|
}
|
|
1357
1685
|
return result;
|
|
1358
1686
|
};
|
|
1359
|
-
// @license
|
|
1360
1687
|
class BaseValidator {
|
|
1361
1688
|
name = "base";
|
|
1362
1689
|
async validate(rljson) {
|
|
@@ -1400,7 +1727,6 @@ class _BaseValidator {
|
|
|
1400
1727
|
() => this._rootOrHeadTableHasNoIdColumn(),
|
|
1401
1728
|
// Check references
|
|
1402
1729
|
() => this._refsNotFound(),
|
|
1403
|
-
() => this._sliceIdRefsNotFound(),
|
|
1404
1730
|
// Check layers
|
|
1405
1731
|
() => this._layerBasesNotFound(),
|
|
1406
1732
|
() => this._layerSliceIdsTableNotFound(),
|
|
@@ -1769,36 +2095,44 @@ class _BaseValidator {
|
|
|
1769
2095
|
_refsNotFound() {
|
|
1770
2096
|
const missingRefs = [];
|
|
1771
2097
|
iterateTablesSync(this.rljson, (tableKey, table) => {
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
2098
|
+
if (tableKey === "tableCfgs") return;
|
|
2099
|
+
const tableCfgRef = table._tableCfg;
|
|
2100
|
+
if (!tableCfgRef) return;
|
|
2101
|
+
const tableCfg = this.rljsonIndexed.tableCfgs._data[tableCfgRef];
|
|
2102
|
+
if (!tableCfg) return;
|
|
2103
|
+
const tableRows = table._data;
|
|
2104
|
+
for (const row of tableRows) {
|
|
2105
|
+
for (const columnKey of Object.keys(row)) {
|
|
2106
|
+
if (columnKey.startsWith("_")) continue;
|
|
2107
|
+
const columnCfg = tableCfg.columns.find(
|
|
2108
|
+
(col) => col.key === columnKey
|
|
2109
|
+
);
|
|
2110
|
+
if (columnCfg === void 0) continue;
|
|
2111
|
+
if (columnCfg.ref && columnCfg.ref.tableKey) {
|
|
2112
|
+
const targetTableKey = columnCfg.ref.tableKey;
|
|
2113
|
+
const targetRefs = Array.isArray(row[columnKey]) ? row[columnKey] : [row[columnKey]];
|
|
2114
|
+
for (const targetRef of targetRefs) {
|
|
1781
2115
|
if (this.tableKeys.indexOf(targetTableKey) === -1) {
|
|
1782
2116
|
missingRefs.push({
|
|
1783
2117
|
error: `Target table "${targetTableKey}" not found.`,
|
|
1784
2118
|
sourceTable: tableKey,
|
|
1785
|
-
sourceKey:
|
|
1786
|
-
sourceItemHash:
|
|
1787
|
-
targetItemHash,
|
|
2119
|
+
sourceKey: columnKey,
|
|
2120
|
+
sourceItemHash: row._hash,
|
|
2121
|
+
targetItemHash: targetRef,
|
|
1788
2122
|
targetTable: targetTableKey
|
|
1789
2123
|
});
|
|
1790
2124
|
continue;
|
|
1791
2125
|
}
|
|
1792
2126
|
const targetTableIndexed = this.rljsonIndexed[targetTableKey];
|
|
1793
|
-
const referencedItem = targetTableIndexed._data[
|
|
2127
|
+
const referencedItem = targetTableIndexed._data[targetRef];
|
|
1794
2128
|
if (referencedItem === void 0) {
|
|
1795
2129
|
missingRefs.push({
|
|
1796
2130
|
sourceTable: tableKey,
|
|
1797
|
-
sourceItemHash:
|
|
1798
|
-
sourceKey:
|
|
1799
|
-
targetItemHash,
|
|
2131
|
+
sourceItemHash: row._hash,
|
|
2132
|
+
sourceKey: columnKey,
|
|
2133
|
+
targetItemHash: targetRef,
|
|
1800
2134
|
targetTable: targetTableKey,
|
|
1801
|
-
error: `Table "${targetTableKey}" has no item with hash "${
|
|
2135
|
+
error: `Table "${targetTableKey}" has no item with hash "${targetRef}"`
|
|
1802
2136
|
});
|
|
1803
2137
|
}
|
|
1804
2138
|
}
|
|
@@ -1814,49 +2148,6 @@ class _BaseValidator {
|
|
|
1814
2148
|
}
|
|
1815
2149
|
}
|
|
1816
2150
|
// ...........................................................................
|
|
1817
|
-
_sliceIdRefsNotFound() {
|
|
1818
|
-
const missingSliceIdRefs = [];
|
|
1819
|
-
iterateTablesSync(this.rljson, (tableKey, table) => {
|
|
1820
|
-
const tableData = table._data;
|
|
1821
|
-
for (const item of tableData) {
|
|
1822
|
-
for (const key of Object.keys(item)) {
|
|
1823
|
-
if (key.endsWith("SliceId")) {
|
|
1824
|
-
const targetSliceIds = Array.isArray(item[key]) ? item[key] : [item[key]];
|
|
1825
|
-
for (const targetSliceId of targetSliceIds) {
|
|
1826
|
-
if (this.tableKeys.indexOf(key) === -1) {
|
|
1827
|
-
missingSliceIdRefs.push({
|
|
1828
|
-
sourceTable: tableKey,
|
|
1829
|
-
targetSliceId,
|
|
1830
|
-
targetTable: key,
|
|
1831
|
-
error: `Target table "${targetSliceId}" not found.`
|
|
1832
|
-
});
|
|
1833
|
-
continue;
|
|
1834
|
-
}
|
|
1835
|
-
const targetSliceIdsTable = this.rljson[key];
|
|
1836
|
-
const targetSliceIds2 = targetSliceIdsTable._data.flatMap(
|
|
1837
|
-
(d) => [...d.add, ...d.remove ?? []]
|
|
1838
|
-
);
|
|
1839
|
-
if (targetSliceIds2.indexOf(targetSliceId) === -1) {
|
|
1840
|
-
missingSliceIdRefs.push({
|
|
1841
|
-
sourceTable: tableKey,
|
|
1842
|
-
targetSliceId,
|
|
1843
|
-
targetTable: key,
|
|
1844
|
-
error: `Table "${key}" has no sliceId "${targetSliceId}"`
|
|
1845
|
-
});
|
|
1846
|
-
}
|
|
1847
|
-
}
|
|
1848
|
-
}
|
|
1849
|
-
}
|
|
1850
|
-
}
|
|
1851
|
-
});
|
|
1852
|
-
if (missingSliceIdRefs.length > 0) {
|
|
1853
|
-
this.errors.refsNotFound = {
|
|
1854
|
-
error: "Broken references",
|
|
1855
|
-
missingRefs: missingSliceIdRefs
|
|
1856
|
-
};
|
|
1857
|
-
}
|
|
1858
|
-
}
|
|
1859
|
-
// ...........................................................................
|
|
1860
2151
|
_layerBasesNotFound() {
|
|
1861
2152
|
const brokenLayers = [];
|
|
1862
2153
|
iterateTablesSync(this.rljson, (tableKey, table) => {
|
|
@@ -2169,7 +2460,6 @@ class _BaseValidator {
|
|
|
2169
2460
|
}
|
|
2170
2461
|
}
|
|
2171
2462
|
const isValidFieldName = (fieldName) => BaseValidator.isValidFieldName(fieldName);
|
|
2172
|
-
// @license
|
|
2173
2463
|
class Validate {
|
|
2174
2464
|
addValidator(validator) {
|
|
2175
2465
|
this._validators.push(validator);
|
|
@@ -2214,13 +2504,13 @@ export {
|
|
|
2214
2504
|
bakeryExample,
|
|
2215
2505
|
contentTypes,
|
|
2216
2506
|
createCakeTableCfg,
|
|
2217
|
-
|
|
2507
|
+
createInsertHistoryTableCfg,
|
|
2218
2508
|
createLayerTableCfg,
|
|
2219
2509
|
exampleBuffetsTable,
|
|
2220
2510
|
exampleCakesTable,
|
|
2221
2511
|
exampleComponentsTable,
|
|
2222
|
-
exampleHistoryTable,
|
|
2223
2512
|
exampleInsert,
|
|
2513
|
+
exampleInsertHistoryTable,
|
|
2224
2514
|
exampleLayersTable,
|
|
2225
2515
|
exampleRevision,
|
|
2226
2516
|
exampleRljson,
|