@rljson/rljson 0.0.33 → 0.0.34
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/buffet.d.ts +4 -0
- package/dist/content/cake.d.ts +4 -0
- package/dist/content/ingredients.d.ts +2 -3
- package/dist/content/revision.d.ts +37 -0
- package/dist/content/table-cfg.d.ts +24 -4
- package/dist/example.d.ts +1 -1
- package/dist/rljson.d.ts +2 -1
- package/dist/rljson.js +133 -28
- package/dist/src/example.ts +33 -17
- package/dist/typedefs.d.ts +7 -1
- package/dist/validate/base-validator.d.ts +2 -0
- package/package.json +10 -10
package/dist/content/buffet.d.ts
CHANGED
package/dist/content/cake.d.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import { Json } from '@rljson/json';
|
|
2
1
|
import { NutritionalValues } from '../example/bakery-example.ts';
|
|
3
2
|
import { RljsonTable } from '../rljson.ts';
|
|
4
|
-
import { Ref } from '../typedefs.ts';
|
|
3
|
+
import { JsonWithId, Ref } from '../typedefs.ts';
|
|
5
4
|
/**
|
|
6
5
|
* A reference to a ingredients row in a ingredients table
|
|
7
6
|
*/
|
|
@@ -9,7 +8,7 @@ export type IngredientsRef = Ref;
|
|
|
9
8
|
/**
|
|
10
9
|
* A table containing ingredients
|
|
11
10
|
*/
|
|
12
|
-
export type IngredientsTable<T extends
|
|
11
|
+
export type IngredientsTable<T extends JsonWithId> = RljsonTable<T, 'ingredients'>;
|
|
13
12
|
/**
|
|
14
13
|
* Provides an example ingredients table for test purposes
|
|
15
14
|
*/
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { Json } from '@rljson/json';
|
|
2
|
+
import { RljsonTable } from '../rljson.ts';
|
|
3
|
+
import { Ref, TableKey } from '../typedefs.ts';
|
|
4
|
+
/**
|
|
5
|
+
* Describes a revision of a row in a table
|
|
6
|
+
*/
|
|
7
|
+
export interface Revision extends Json {
|
|
8
|
+
/**
|
|
9
|
+
* The name of the table the revisione row belongs to
|
|
10
|
+
*/
|
|
11
|
+
table: TableKey;
|
|
12
|
+
/**
|
|
13
|
+
* The predecessor of the revision
|
|
14
|
+
*/
|
|
15
|
+
predecessor: Ref;
|
|
16
|
+
/**
|
|
17
|
+
* The successor of the revision
|
|
18
|
+
*/
|
|
19
|
+
successor: Ref;
|
|
20
|
+
/**
|
|
21
|
+
* The UTC timestamp of the revision
|
|
22
|
+
*/
|
|
23
|
+
timestamp: number;
|
|
24
|
+
/**
|
|
25
|
+
* The optional ID of the revisioned element.
|
|
26
|
+
* Can be used get all revisions of a specific ingredient.
|
|
27
|
+
*/
|
|
28
|
+
id?: string;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* A table containing revisions
|
|
32
|
+
*/
|
|
33
|
+
export type RevisionsTable = RljsonTable<Revision, 'ingredients'>;
|
|
34
|
+
/**
|
|
35
|
+
* Example revision object for test purposes
|
|
36
|
+
*/
|
|
37
|
+
export declare const exampleRevision: () => Revision;
|
|
@@ -9,10 +9,6 @@ export type TableCfgRef = Ref;
|
|
|
9
9
|
* A column configuration
|
|
10
10
|
*/
|
|
11
11
|
export interface ColumnCfg extends Json {
|
|
12
|
-
/**
|
|
13
|
-
* The key of the column used in data
|
|
14
|
-
*/
|
|
15
|
-
key: ColumnKey;
|
|
16
12
|
/**
|
|
17
13
|
* The type of the column
|
|
18
14
|
*/
|
|
@@ -43,6 +39,30 @@ export interface TableCfg extends Json {
|
|
|
43
39
|
* Needs to be increased when new columns are added.
|
|
44
40
|
*/
|
|
45
41
|
version: number;
|
|
42
|
+
/**
|
|
43
|
+
* Head tables serve as versioning entry points.
|
|
44
|
+
*
|
|
45
|
+
* - Head tables must contain an id column
|
|
46
|
+
* - Rows in an head table must contain a non-null id
|
|
47
|
+
* - Same row ids must refer to the same physical object
|
|
48
|
+
* - Head tables have no or only one parent table
|
|
49
|
+
*/
|
|
50
|
+
isHead: boolean;
|
|
51
|
+
/**
|
|
52
|
+
* Root tables are tables that have no parent table.
|
|
53
|
+
*
|
|
54
|
+
* - Root tables are also head tables
|
|
55
|
+
*/
|
|
56
|
+
isRoot: boolean;
|
|
57
|
+
/**
|
|
58
|
+
* Shared tables are tables that are used by multiple parents.
|
|
59
|
+
*
|
|
60
|
+
* - The don't need an id column
|
|
61
|
+
* - Same id can refer to different physical objects
|
|
62
|
+
* - Shared tables can have multiple parents
|
|
63
|
+
* - Shared tables can not be head or root tables
|
|
64
|
+
*/
|
|
65
|
+
isShared: boolean;
|
|
46
66
|
}
|
|
47
67
|
/**
|
|
48
68
|
* A table containing columns
|
package/dist/example.d.ts
CHANGED
package/dist/rljson.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { BuffetsTable } from './content/buffet.ts';
|
|
|
3
3
|
import { CakesTable } from './content/cake.ts';
|
|
4
4
|
import { IngredientsTable } from './content/ingredients.ts';
|
|
5
5
|
import { LayersTable } from './content/layer.ts';
|
|
6
|
+
import { RevisionsTable } from './content/revision.ts';
|
|
6
7
|
import { SliceIdsTable } from './content/slice-ids.ts';
|
|
7
8
|
import { TableCfgRef, TablesCfgTable } from './content/table-cfg.ts';
|
|
8
9
|
import { ContentType, Ref, TableKey } from './typedefs.ts';
|
|
@@ -11,7 +12,7 @@ export declare const reservedTableKeys: string[];
|
|
|
11
12
|
/**
|
|
12
13
|
* One of the supported Rljson table types
|
|
13
14
|
*/
|
|
14
|
-
export type TableType = BuffetsTable | IngredientsTable<any> | LayersTable | SliceIdsTable | CakesTable;
|
|
15
|
+
export type TableType = BuffetsTable | IngredientsTable<any> | LayersTable | SliceIdsTable | CakesTable | RevisionsTable;
|
|
15
16
|
/** The rljson data format */
|
|
16
17
|
export interface Rljson extends Json {
|
|
17
18
|
[tableId: TableKey]: TableType;
|
package/dist/rljson.js
CHANGED
|
@@ -9,11 +9,20 @@ const bakeryExample = () => {
|
|
|
9
9
|
_type: "ingredients",
|
|
10
10
|
_data: [
|
|
11
11
|
{
|
|
12
|
+
id: "flour",
|
|
12
13
|
energy: 364,
|
|
13
14
|
fat: 0.98,
|
|
14
15
|
protein: 10.33,
|
|
15
16
|
carbohydrates: 76.31,
|
|
16
17
|
_hash: ""
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
id: "flour",
|
|
21
|
+
energy: 364.1,
|
|
22
|
+
fat: 0.981,
|
|
23
|
+
protein: 10.331,
|
|
24
|
+
carbohydrates: 76.311,
|
|
25
|
+
_hash: ""
|
|
17
26
|
}
|
|
18
27
|
],
|
|
19
28
|
_hash: ""
|
|
@@ -22,7 +31,7 @@ const bakeryExample = () => {
|
|
|
22
31
|
_type: "ingredients",
|
|
23
32
|
_data: [
|
|
24
33
|
{
|
|
25
|
-
|
|
34
|
+
id: "flour",
|
|
26
35
|
amountUnit: "g",
|
|
27
36
|
nutritionalValuesRef: nutritionalValues._data[0]._hash,
|
|
28
37
|
_hash: ""
|
|
@@ -34,6 +43,7 @@ const bakeryExample = () => {
|
|
|
34
43
|
_type: "ingredients",
|
|
35
44
|
_data: [
|
|
36
45
|
{
|
|
46
|
+
id: "flour",
|
|
37
47
|
ingredientsRef: ingredients._data[0]._hash,
|
|
38
48
|
quantity: 500,
|
|
39
49
|
_hash: ""
|
|
@@ -45,6 +55,7 @@ const bakeryExample = () => {
|
|
|
45
55
|
_type: "layers",
|
|
46
56
|
_data: [
|
|
47
57
|
{
|
|
58
|
+
id: "tastyCake",
|
|
48
59
|
ingredientsTable: "recipeIngredients",
|
|
49
60
|
assign: {
|
|
50
61
|
flour: recipeIngredients._data[0]._hash
|
|
@@ -70,23 +81,21 @@ const bakeryExample = () => {
|
|
|
70
81
|
_data: [
|
|
71
82
|
{
|
|
72
83
|
add: ["slice0", "slice1"],
|
|
73
|
-
remove: []
|
|
74
|
-
_hash: ""
|
|
84
|
+
remove: []
|
|
75
85
|
}
|
|
76
|
-
]
|
|
77
|
-
_hash: ""
|
|
86
|
+
]
|
|
78
87
|
});
|
|
79
88
|
const cakes = hip({
|
|
80
89
|
_type: "cakes",
|
|
81
90
|
_data: [
|
|
82
91
|
{
|
|
92
|
+
id: "cake1",
|
|
83
93
|
sliceIdsTable: "slices",
|
|
84
94
|
sliceIds: slices._data[0]._hash,
|
|
85
95
|
layersTable: "layers",
|
|
86
96
|
layers: {
|
|
87
97
|
flour: layers._data[0]._hash
|
|
88
|
-
}
|
|
89
|
-
_hash: ""
|
|
98
|
+
}
|
|
90
99
|
}
|
|
91
100
|
]
|
|
92
101
|
});
|
|
@@ -94,6 +103,7 @@ const bakeryExample = () => {
|
|
|
94
103
|
_type: "buffets",
|
|
95
104
|
_data: [
|
|
96
105
|
{
|
|
106
|
+
id: "salesCounter",
|
|
97
107
|
items: [
|
|
98
108
|
{
|
|
99
109
|
table: "cakes",
|
|
@@ -156,37 +166,32 @@ __publicField(_Example, "ok", {
|
|
|
156
166
|
_hash: "",
|
|
157
167
|
key: "table",
|
|
158
168
|
type: "ingredients",
|
|
169
|
+
isHead: false,
|
|
170
|
+
isRoot: false,
|
|
171
|
+
isShared: true,
|
|
159
172
|
columns: {
|
|
160
173
|
int: {
|
|
161
|
-
key: "int",
|
|
162
174
|
type: "number"
|
|
163
175
|
},
|
|
164
176
|
double: {
|
|
165
|
-
key: "double",
|
|
166
177
|
type: "number"
|
|
167
178
|
},
|
|
168
179
|
string: {
|
|
169
|
-
key: "string",
|
|
170
180
|
type: "string"
|
|
171
181
|
},
|
|
172
182
|
boolean: {
|
|
173
|
-
key: "boolean",
|
|
174
183
|
type: "boolean"
|
|
175
184
|
},
|
|
176
185
|
null: {
|
|
177
|
-
key: "null",
|
|
178
186
|
type: "null"
|
|
179
187
|
},
|
|
180
188
|
jsonArray: {
|
|
181
|
-
key: "jsonArray",
|
|
182
189
|
type: "jsonArray"
|
|
183
190
|
},
|
|
184
191
|
json: {
|
|
185
|
-
key: "json",
|
|
186
192
|
type: "json"
|
|
187
193
|
},
|
|
188
194
|
jsonValue: {
|
|
189
|
-
key: "jsonValue",
|
|
190
195
|
type: "jsonValue"
|
|
191
196
|
}
|
|
192
197
|
}
|
|
@@ -399,7 +404,10 @@ __publicField(_Example, "broken", {
|
|
|
399
404
|
const result = _Example.ok.singleRow();
|
|
400
405
|
const tableCfg = result.tableCfgs._data[0];
|
|
401
406
|
tableCfg.columns["int"].type = "numberBroken";
|
|
402
|
-
return hip(result,
|
|
407
|
+
return hip(result, {
|
|
408
|
+
updateExistingHashes: true,
|
|
409
|
+
throwOnWrongHashes: false
|
|
410
|
+
});
|
|
403
411
|
}
|
|
404
412
|
},
|
|
405
413
|
layers: {
|
|
@@ -407,13 +415,19 @@ __publicField(_Example, "broken", {
|
|
|
407
415
|
const result = _Example.ok.complete();
|
|
408
416
|
const layer1 = result.layers._data[1];
|
|
409
417
|
layer1.base = "MISSING";
|
|
410
|
-
return hip(result,
|
|
418
|
+
return hip(result, {
|
|
419
|
+
updateExistingHashes: true,
|
|
420
|
+
throwOnWrongHashes: false
|
|
421
|
+
});
|
|
411
422
|
},
|
|
412
423
|
missingSliceIdSet: () => {
|
|
413
424
|
const result = _Example.ok.complete();
|
|
414
425
|
const layer1 = result.layers._data[1];
|
|
415
426
|
layer1.sliceIds = "MISSING1";
|
|
416
|
-
return hip(result,
|
|
427
|
+
return hip(result, {
|
|
428
|
+
updateExistingHashes: true,
|
|
429
|
+
throwOnWrongHashes: false
|
|
430
|
+
});
|
|
417
431
|
},
|
|
418
432
|
missingAssignedIngredientTable: () => {
|
|
419
433
|
const result = _Example.ok.complete();
|
|
@@ -423,27 +437,39 @@ __publicField(_Example, "broken", {
|
|
|
423
437
|
missingAssignedIngredient: () => {
|
|
424
438
|
const result = _Example.ok.complete();
|
|
425
439
|
result.ingredients._data.splice(1, 2);
|
|
426
|
-
return hip(result,
|
|
440
|
+
return hip(result, {
|
|
441
|
+
updateExistingHashes: true,
|
|
442
|
+
throwOnWrongHashes: false
|
|
443
|
+
});
|
|
427
444
|
}
|
|
428
445
|
},
|
|
429
446
|
cakes: {
|
|
430
447
|
missingSliceIdSet: () => {
|
|
431
448
|
const result = _Example.ok.complete();
|
|
432
449
|
result.cakes._data[0].sliceIds = "MISSING";
|
|
433
|
-
hip(result.cakes,
|
|
450
|
+
hip(result.cakes, {
|
|
451
|
+
updateExistingHashes: true,
|
|
452
|
+
throwOnWrongHashes: false
|
|
453
|
+
});
|
|
434
454
|
return result;
|
|
435
455
|
},
|
|
436
456
|
missingLayersTable: () => {
|
|
437
457
|
const result = _Example.ok.complete();
|
|
438
458
|
result.cakes._data[0].layersTable = "MISSING";
|
|
439
|
-
hip(result.cakes,
|
|
459
|
+
hip(result.cakes, {
|
|
460
|
+
updateExistingHashes: true,
|
|
461
|
+
throwOnWrongHashes: false
|
|
462
|
+
});
|
|
440
463
|
return result;
|
|
441
464
|
},
|
|
442
465
|
missingCakeLayer: () => {
|
|
443
466
|
const result = _Example.ok.complete();
|
|
444
467
|
result.cakes._data[0].layers["layer0"] = "MISSING0";
|
|
445
468
|
result.cakes._data[0].layers["layer1"] = "MISSING1";
|
|
446
|
-
hip(result.cakes,
|
|
469
|
+
hip(result.cakes, {
|
|
470
|
+
updateExistingHashes: true,
|
|
471
|
+
throwOnWrongHashes: false
|
|
472
|
+
});
|
|
447
473
|
return result;
|
|
448
474
|
}
|
|
449
475
|
},
|
|
@@ -453,7 +479,7 @@ __publicField(_Example, "broken", {
|
|
|
453
479
|
const buffet = result.buffets._data[0];
|
|
454
480
|
buffet.items[0].table = "MISSING0";
|
|
455
481
|
buffet.items[1].table = "MISSING1";
|
|
456
|
-
hip(result, true, false);
|
|
482
|
+
hip(result, { updateExistingHashes: true, throwOnWrongHashes: false });
|
|
457
483
|
return result;
|
|
458
484
|
},
|
|
459
485
|
missingItems: () => {
|
|
@@ -461,7 +487,7 @@ __publicField(_Example, "broken", {
|
|
|
461
487
|
const buffet = result.buffets._data[0];
|
|
462
488
|
buffet.items[0].ref = "MISSING0";
|
|
463
489
|
buffet.items[1].ref = "MISSING1";
|
|
464
|
-
hip(result, true, false);
|
|
490
|
+
hip(result, { updateExistingHashes: true, throwOnWrongHashes: false });
|
|
465
491
|
return result;
|
|
466
492
|
}
|
|
467
493
|
}
|
|
@@ -475,15 +501,16 @@ const exampleTableCfg = (tableCfg = void 0) => {
|
|
|
475
501
|
version: 1,
|
|
476
502
|
columns: (tableCfg == null ? void 0 : tableCfg.columns) ?? {
|
|
477
503
|
a: {
|
|
478
|
-
key: "a",
|
|
479
504
|
type: "string"
|
|
480
505
|
},
|
|
481
506
|
b: {
|
|
482
|
-
key: "b",
|
|
483
507
|
type: "number"
|
|
484
508
|
}
|
|
485
509
|
},
|
|
486
|
-
type: (tableCfg == null ? void 0 : tableCfg.type) ?? "ingredients"
|
|
510
|
+
type: (tableCfg == null ? void 0 : tableCfg.type) ?? "ingredients",
|
|
511
|
+
isHead: true,
|
|
512
|
+
isRoot: true,
|
|
513
|
+
isShared: false
|
|
487
514
|
};
|
|
488
515
|
};
|
|
489
516
|
// @license
|
|
@@ -511,7 +538,13 @@ const rljsonIndexed = (rljson) => {
|
|
|
511
538
|
};
|
|
512
539
|
// @license
|
|
513
540
|
const reservedFieldNames = ["_type", "_data"];
|
|
514
|
-
const reservedTableKeys = [
|
|
541
|
+
const reservedTableKeys = [
|
|
542
|
+
"_hash",
|
|
543
|
+
"sliceIds",
|
|
544
|
+
"tableCfgs",
|
|
545
|
+
"reverseRefs",
|
|
546
|
+
"revisions"
|
|
547
|
+
];
|
|
515
548
|
const exampleRljson = () => Example.ok.singleRow();
|
|
516
549
|
const iterateTables = (rljson, callback) => {
|
|
517
550
|
for (const tableKey in rljson) {
|
|
@@ -587,6 +620,8 @@ class _BaseValidator {
|
|
|
587
620
|
() => this._missingColumnConfigs(),
|
|
588
621
|
() => this._dataDoesNotMatchColumnConfig(),
|
|
589
622
|
() => this._tableTypesDoNotMatch(),
|
|
623
|
+
() => this._tableCfgHasRootHeadSharedError(),
|
|
624
|
+
() => this._rootOrHeadTableHasNoIdColumn(),
|
|
590
625
|
// Check references
|
|
591
626
|
() => this._refsNotFound(),
|
|
592
627
|
// Check layers
|
|
@@ -893,6 +928,76 @@ class _BaseValidator {
|
|
|
893
928
|
}
|
|
894
929
|
}
|
|
895
930
|
// ...........................................................................
|
|
931
|
+
_tableCfgHasRootHeadSharedError() {
|
|
932
|
+
const rljson = this.rljson;
|
|
933
|
+
const inconsistentTableCfgs = [];
|
|
934
|
+
for (const tableKey of this.tableKeys) {
|
|
935
|
+
const table = rljson[tableKey];
|
|
936
|
+
const cfgRef = table._tableCfg;
|
|
937
|
+
if (!cfgRef) {
|
|
938
|
+
continue;
|
|
939
|
+
}
|
|
940
|
+
const cfg = this.rljsonIndexed.tableCfgs._data[cfgRef];
|
|
941
|
+
const { isRoot, isHead, isShared } = cfg;
|
|
942
|
+
if (isShared && (isRoot || isHead)) {
|
|
943
|
+
inconsistentTableCfgs.push({
|
|
944
|
+
error: "Tables with isShared = true must have isRoot = false and isHead = false",
|
|
945
|
+
table: tableKey,
|
|
946
|
+
tableCfg: cfgRef
|
|
947
|
+
});
|
|
948
|
+
} else if (isRoot && !isHead) {
|
|
949
|
+
inconsistentTableCfgs.push({
|
|
950
|
+
error: "Tables with isRoot = true must also have isHead = true",
|
|
951
|
+
table: tableKey,
|
|
952
|
+
tableCfg: cfgRef
|
|
953
|
+
});
|
|
954
|
+
} else if (!isRoot && !isHead && !isShared) {
|
|
955
|
+
inconsistentTableCfgs.push({
|
|
956
|
+
error: "Tables must be either root, root+head or shared",
|
|
957
|
+
table: tableKey,
|
|
958
|
+
tableCfg: cfgRef
|
|
959
|
+
});
|
|
960
|
+
}
|
|
961
|
+
}
|
|
962
|
+
if (inconsistentTableCfgs.length > 0) {
|
|
963
|
+
this.errors.tableCfgHasRootHeadSharedError = {
|
|
964
|
+
error: "Table configs have inconsistent root/head/shared settings",
|
|
965
|
+
tables: inconsistentTableCfgs
|
|
966
|
+
};
|
|
967
|
+
}
|
|
968
|
+
}
|
|
969
|
+
// ...........................................................................
|
|
970
|
+
_rootOrHeadTableHasNoIdColumn() {
|
|
971
|
+
const rljson = this.rljson;
|
|
972
|
+
const rootOrHeadTablesWithoutIdColumns = [];
|
|
973
|
+
for (const tableKey of this.tableKeys) {
|
|
974
|
+
const table = rljson[tableKey];
|
|
975
|
+
const cfgRef = table._tableCfg;
|
|
976
|
+
if (!cfgRef) {
|
|
977
|
+
continue;
|
|
978
|
+
}
|
|
979
|
+
const cfg = this.rljsonIndexed.tableCfgs._data[cfgRef];
|
|
980
|
+
const isRootOrHeadTable = cfg.isRoot || cfg.isHead;
|
|
981
|
+
if (!isRootOrHeadTable) {
|
|
982
|
+
continue;
|
|
983
|
+
}
|
|
984
|
+
const columns = cfg.columns;
|
|
985
|
+
const idField = columns["id"];
|
|
986
|
+
if (!idField) {
|
|
987
|
+
rootOrHeadTablesWithoutIdColumns.push({
|
|
988
|
+
table: tableKey,
|
|
989
|
+
tableCfg: cfgRef
|
|
990
|
+
});
|
|
991
|
+
}
|
|
992
|
+
}
|
|
993
|
+
if (rootOrHeadTablesWithoutIdColumns.length > 0) {
|
|
994
|
+
this.errors.rootOrHeadTableHasNoIdColumn = {
|
|
995
|
+
error: "Root or head tables must have an id column",
|
|
996
|
+
tables: rootOrHeadTablesWithoutIdColumns
|
|
997
|
+
};
|
|
998
|
+
}
|
|
999
|
+
}
|
|
1000
|
+
// ...........................................................................
|
|
896
1001
|
_dataHasWrongType() {
|
|
897
1002
|
const rljson = this.rljson;
|
|
898
1003
|
const tablesWithWrongType = [];
|
package/dist/src/example.ts
CHANGED
|
@@ -49,37 +49,32 @@ export class Example {
|
|
|
49
49
|
_hash: '',
|
|
50
50
|
key: 'table',
|
|
51
51
|
type: 'ingredients',
|
|
52
|
+
isHead: false,
|
|
53
|
+
isRoot: false,
|
|
54
|
+
isShared: true,
|
|
52
55
|
columns: {
|
|
53
56
|
int: {
|
|
54
|
-
key: 'int',
|
|
55
57
|
type: 'number',
|
|
56
58
|
},
|
|
57
59
|
double: {
|
|
58
|
-
key: 'double',
|
|
59
60
|
type: 'number',
|
|
60
61
|
},
|
|
61
62
|
string: {
|
|
62
|
-
key: 'string',
|
|
63
63
|
type: 'string',
|
|
64
64
|
},
|
|
65
65
|
boolean: {
|
|
66
|
-
key: 'boolean',
|
|
67
66
|
type: 'boolean',
|
|
68
67
|
},
|
|
69
68
|
null: {
|
|
70
|
-
key: 'null',
|
|
71
69
|
type: 'null',
|
|
72
70
|
},
|
|
73
71
|
jsonArray: {
|
|
74
|
-
key: 'jsonArray',
|
|
75
72
|
type: 'jsonArray',
|
|
76
73
|
},
|
|
77
74
|
json: {
|
|
78
|
-
key: 'json',
|
|
79
75
|
type: 'json',
|
|
80
76
|
},
|
|
81
77
|
jsonValue: {
|
|
82
|
-
key: 'jsonValue',
|
|
83
78
|
type: 'jsonValue',
|
|
84
79
|
},
|
|
85
80
|
},
|
|
@@ -309,7 +304,10 @@ export class Example {
|
|
|
309
304
|
const result = Example.ok.singleRow();
|
|
310
305
|
const tableCfg = result.tableCfgs._data[0];
|
|
311
306
|
tableCfg.columns['int'].type = 'numberBroken'; // Break one of the types
|
|
312
|
-
return hip(result,
|
|
307
|
+
return hip(result, {
|
|
308
|
+
updateExistingHashes: true,
|
|
309
|
+
throwOnWrongHashes: false,
|
|
310
|
+
});
|
|
313
311
|
},
|
|
314
312
|
},
|
|
315
313
|
|
|
@@ -320,7 +318,10 @@ export class Example {
|
|
|
320
318
|
layer1.base = 'MISSING'; // Missing base
|
|
321
319
|
|
|
322
320
|
// Recalculate hashes
|
|
323
|
-
return hip(result,
|
|
321
|
+
return hip(result, {
|
|
322
|
+
updateExistingHashes: true,
|
|
323
|
+
throwOnWrongHashes: false,
|
|
324
|
+
});
|
|
324
325
|
},
|
|
325
326
|
|
|
326
327
|
missingSliceIdSet: (): Rljson => {
|
|
@@ -330,7 +331,10 @@ export class Example {
|
|
|
330
331
|
layer1.sliceIds = 'MISSING1';
|
|
331
332
|
|
|
332
333
|
// Recalculate hashes
|
|
333
|
-
return hip(result,
|
|
334
|
+
return hip(result, {
|
|
335
|
+
updateExistingHashes: true,
|
|
336
|
+
throwOnWrongHashes: false,
|
|
337
|
+
});
|
|
334
338
|
},
|
|
335
339
|
|
|
336
340
|
missingAssignedIngredientTable: (): Rljson => {
|
|
@@ -342,7 +346,10 @@ export class Example {
|
|
|
342
346
|
missingAssignedIngredient: (): Rljson => {
|
|
343
347
|
const result = Example.ok.complete();
|
|
344
348
|
result.ingredients._data.splice(1, 2); // Remove an ingredient that is assigned
|
|
345
|
-
return hip(result,
|
|
349
|
+
return hip(result, {
|
|
350
|
+
updateExistingHashes: true,
|
|
351
|
+
throwOnWrongHashes: false,
|
|
352
|
+
});
|
|
346
353
|
},
|
|
347
354
|
},
|
|
348
355
|
|
|
@@ -350,14 +357,20 @@ export class Example {
|
|
|
350
357
|
missingSliceIdSet: (): Rljson => {
|
|
351
358
|
const result = Example.ok.complete();
|
|
352
359
|
result.cakes._data[0].sliceIds = 'MISSING'; // Missing ID set
|
|
353
|
-
hip(result.cakes,
|
|
360
|
+
hip(result.cakes, {
|
|
361
|
+
updateExistingHashes: true,
|
|
362
|
+
throwOnWrongHashes: false,
|
|
363
|
+
});
|
|
354
364
|
return result;
|
|
355
365
|
},
|
|
356
366
|
|
|
357
367
|
missingLayersTable: (): Rljson => {
|
|
358
368
|
const result = Example.ok.complete();
|
|
359
369
|
result.cakes._data[0].layersTable = 'MISSING'; // Missing layers table
|
|
360
|
-
hip(result.cakes,
|
|
370
|
+
hip(result.cakes, {
|
|
371
|
+
updateExistingHashes: true,
|
|
372
|
+
throwOnWrongHashes: false,
|
|
373
|
+
});
|
|
361
374
|
return result;
|
|
362
375
|
},
|
|
363
376
|
|
|
@@ -365,7 +378,10 @@ export class Example {
|
|
|
365
378
|
const result = Example.ok.complete();
|
|
366
379
|
result.cakes._data[0].layers['layer0'] = 'MISSING0';
|
|
367
380
|
result.cakes._data[0].layers['layer1'] = 'MISSING1';
|
|
368
|
-
hip(result.cakes,
|
|
381
|
+
hip(result.cakes, {
|
|
382
|
+
updateExistingHashes: true,
|
|
383
|
+
throwOnWrongHashes: false,
|
|
384
|
+
});
|
|
369
385
|
return result;
|
|
370
386
|
},
|
|
371
387
|
},
|
|
@@ -376,7 +392,7 @@ export class Example {
|
|
|
376
392
|
const buffet = result.buffets._data[0];
|
|
377
393
|
buffet.items[0].table = 'MISSING0';
|
|
378
394
|
buffet.items[1].table = 'MISSING1';
|
|
379
|
-
hip(result, true, false);
|
|
395
|
+
hip(result, { updateExistingHashes: true, throwOnWrongHashes: false });
|
|
380
396
|
return result;
|
|
381
397
|
},
|
|
382
398
|
|
|
@@ -385,7 +401,7 @@ export class Example {
|
|
|
385
401
|
const buffet = result.buffets._data[0];
|
|
386
402
|
buffet.items[0].ref = 'MISSING0';
|
|
387
403
|
buffet.items[1].ref = 'MISSING1';
|
|
388
|
-
hip(result, true, false);
|
|
404
|
+
hip(result, { updateExistingHashes: true, throwOnWrongHashes: false });
|
|
389
405
|
return result;
|
|
390
406
|
},
|
|
391
407
|
},
|
package/dist/typedefs.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { JsonKey } from '@rljson/json';
|
|
1
|
+
import { Json, JsonKey } from '@rljson/json';
|
|
2
2
|
/**
|
|
3
3
|
* A ref is a hash that references to another element
|
|
4
4
|
*/
|
|
@@ -37,3 +37,9 @@ export declare const exampleTypedefs: () => {
|
|
|
37
37
|
tableKey: TableKey;
|
|
38
38
|
contentType: ContentType;
|
|
39
39
|
};
|
|
40
|
+
/**
|
|
41
|
+
* A json object with an optional id
|
|
42
|
+
*/
|
|
43
|
+
export type JsonWithId = Json & {
|
|
44
|
+
id?: string;
|
|
45
|
+
};
|
|
@@ -16,6 +16,8 @@ export interface BaseErrors extends Errors {
|
|
|
16
16
|
columnConfigNotFound?: Json;
|
|
17
17
|
dataDoesNotMatchColumnConfig?: Json;
|
|
18
18
|
tableTypesDoNotMatch?: Json;
|
|
19
|
+
rootOrHeadTableHasNoIdColumn?: Json;
|
|
20
|
+
tableCfgHasRootHeadSharedError?: Json;
|
|
19
21
|
refsNotFound?: Json;
|
|
20
22
|
layerBasesNotFound?: Json;
|
|
21
23
|
layerSliceIdsTableNotFound?: Json;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rljson/rljson",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.34",
|
|
4
4
|
"packageManager": "pnpm@10.6.3",
|
|
5
5
|
"description": "The RLJSON data format specification",
|
|
6
6
|
"homepage": "https://github.com/rljson/rljson",
|
|
@@ -29,10 +29,10 @@
|
|
|
29
29
|
"updateGoldens": "cross-env UPDATE_GOLDENS=true npm test"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
|
-
"@types/node": "^22.13.
|
|
33
|
-
"@typescript-eslint/eslint-plugin": "^8.
|
|
34
|
-
"@typescript-eslint/parser": "^8.
|
|
35
|
-
"@vitest/coverage-v8": "^3.
|
|
32
|
+
"@types/node": "^22.13.17",
|
|
33
|
+
"@typescript-eslint/eslint-plugin": "^8.29.0",
|
|
34
|
+
"@typescript-eslint/parser": "^8.29.0",
|
|
35
|
+
"@vitest/coverage-v8": "^3.1.1",
|
|
36
36
|
"cross-env": "^7.0.3",
|
|
37
37
|
"eslint": "^9.23.0",
|
|
38
38
|
"eslint-plugin-jsdoc": "^50.6.9",
|
|
@@ -41,16 +41,16 @@
|
|
|
41
41
|
"jsdoc": "^4.0.4",
|
|
42
42
|
"read-pkg": "^9.0.1",
|
|
43
43
|
"typescript": "~5.8.2",
|
|
44
|
-
"typescript-eslint": "^8.
|
|
45
|
-
"vite": "^6.2.
|
|
46
|
-
"vite-node": "^3.
|
|
44
|
+
"typescript-eslint": "^8.29.0",
|
|
45
|
+
"vite": "^6.2.4",
|
|
46
|
+
"vite-node": "^3.1.1",
|
|
47
47
|
"vite-plugin-dts": "^4.5.3",
|
|
48
48
|
"vite-tsconfig-paths": "^5.1.4",
|
|
49
|
-
"vitest": "^3.
|
|
49
|
+
"vitest": "^3.1.1",
|
|
50
50
|
"vitest-dom": "^0.1.1"
|
|
51
51
|
},
|
|
52
52
|
"dependencies": {
|
|
53
|
-
"@rljson/hash": "^0.0.
|
|
53
|
+
"@rljson/hash": "^0.0.13",
|
|
54
54
|
"@rljson/json": "^0.0.18"
|
|
55
55
|
},
|
|
56
56
|
"pnpm": {
|