@rljson/rljson 0.0.22 → 0.0.24
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 +2 -2
- package/dist/content/cake.d.ts +2 -2
- package/dist/content/collection.d.ts +2 -2
- package/dist/content/table-cfg.d.ts +8 -12
- package/dist/example.d.ts +1 -1
- package/dist/rljson-indexed.d.ts +1 -1
- package/dist/rljson.d.ts +4 -4
- package/dist/rljson.js +170 -125
- package/dist/src/example.ts +15 -31
- package/dist/typedefs.d.ts +9 -3
- package/dist/validate/base-validator.d.ts +7 -5
- package/package.json +1 -1
package/dist/content/buffet.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Json } from '@rljson/json';
|
|
2
2
|
import { RljsonTable } from '../rljson.ts';
|
|
3
|
-
import { ItemId, Ref,
|
|
3
|
+
import { ItemId, Ref, TableKey } from '../typedefs.ts';
|
|
4
4
|
/**
|
|
5
5
|
* A buffet id is a name or id of a buffet
|
|
6
6
|
*/
|
|
@@ -17,7 +17,7 @@ export interface Buffet extends Json {
|
|
|
17
17
|
/**
|
|
18
18
|
* The table the item is taken from
|
|
19
19
|
*/
|
|
20
|
-
table:
|
|
20
|
+
table: TableKey;
|
|
21
21
|
/**
|
|
22
22
|
* The hash of the item in the able
|
|
23
23
|
*/
|
package/dist/content/cake.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Json } from '@rljson/json';
|
|
2
2
|
import { RljsonTable } from '../rljson.ts';
|
|
3
|
-
import { ItemId,
|
|
3
|
+
import { ItemId, TableKey } from '../typedefs.ts';
|
|
4
4
|
import { CollectionRef } from './collection.ts';
|
|
5
5
|
import { IdSetRef } from './id-set.ts';
|
|
6
6
|
/**
|
|
@@ -22,7 +22,7 @@ export interface Cake extends Json {
|
|
|
22
22
|
/**
|
|
23
23
|
* The table containing the item collections defining the layers
|
|
24
24
|
*/
|
|
25
|
-
collections:
|
|
25
|
+
collections: TableKey;
|
|
26
26
|
/**
|
|
27
27
|
* Assigns a collection to each layer of the cake.
|
|
28
28
|
*/
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Json } from '@rljson/json';
|
|
2
2
|
import { RljsonTable } from '../rljson.ts';
|
|
3
|
-
import { ItemId, Ref,
|
|
3
|
+
import { ItemId, Ref, TableKey } from '../typedefs.ts';
|
|
4
4
|
import { IdSetRef } from './id-set.ts';
|
|
5
5
|
import { PropertiesRef } from './properties.ts';
|
|
6
6
|
/**
|
|
@@ -24,7 +24,7 @@ export interface Collection extends Json {
|
|
|
24
24
|
* The table containing the properties that are assigned to the items
|
|
25
25
|
* with the assign property below
|
|
26
26
|
*/
|
|
27
|
-
properties:
|
|
27
|
+
properties: TableKey;
|
|
28
28
|
/**
|
|
29
29
|
* Assign properties to each item of the collection.
|
|
30
30
|
*/
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Json, JsonKey, JsonValueType } from '@rljson/json';
|
|
2
2
|
import { RljsonTable } from '../rljson.ts';
|
|
3
|
-
import { Ref } from '../typedefs.ts';
|
|
3
|
+
import { ColumnKey, ContentType, Ref, TableKey } from '../typedefs.ts';
|
|
4
4
|
/**
|
|
5
5
|
* A ColumnsRef is a hash pointing to columns metadata
|
|
6
6
|
*/
|
|
@@ -10,17 +10,9 @@ export type TableCfgRef = Ref;
|
|
|
10
10
|
*/
|
|
11
11
|
export interface ColumnCfg extends Json {
|
|
12
12
|
/**
|
|
13
|
-
* The
|
|
13
|
+
* The key of the column used in data
|
|
14
14
|
*/
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Average number of characters in the column
|
|
18
|
-
*/
|
|
19
|
-
avgChars?: number;
|
|
20
|
-
/**
|
|
21
|
-
* Maximum number of characters in the column
|
|
22
|
-
*/
|
|
23
|
-
maxChars?: number;
|
|
15
|
+
key: ColumnKey;
|
|
24
16
|
/**
|
|
25
17
|
* The type of the column
|
|
26
18
|
*/
|
|
@@ -33,11 +25,15 @@ export interface TableCfg extends Json {
|
|
|
33
25
|
/**
|
|
34
26
|
* Technical lower camel case json identifier of the table
|
|
35
27
|
*/
|
|
36
|
-
|
|
28
|
+
key: TableKey;
|
|
37
29
|
/**
|
|
38
30
|
* A short description of the table
|
|
39
31
|
*/
|
|
40
32
|
columns: Record<JsonKey, ColumnCfg>;
|
|
33
|
+
/**
|
|
34
|
+
* The content type of the table
|
|
35
|
+
*/
|
|
36
|
+
type: ContentType;
|
|
41
37
|
}
|
|
42
38
|
/**
|
|
43
39
|
* A table containing columns
|
package/dist/example.d.ts
CHANGED
package/dist/rljson-indexed.d.ts
CHANGED
package/dist/rljson.d.ts
CHANGED
|
@@ -5,16 +5,16 @@ import { CollectionsTable } from './content/collection.ts';
|
|
|
5
5
|
import { IdSetsTable } from './content/id-set.ts';
|
|
6
6
|
import { PropertiesTable } from './content/properties.ts';
|
|
7
7
|
import { TableCfgRef, TablesCfgTable } from './content/table-cfg.ts';
|
|
8
|
-
import { ContentType, Ref,
|
|
8
|
+
import { ContentType, Ref, TableKey } from './typedefs.ts';
|
|
9
9
|
export declare const reservedFieldNames: string[];
|
|
10
|
-
export declare const
|
|
10
|
+
export declare const reservedTableKeys: string[];
|
|
11
11
|
/**
|
|
12
12
|
* One of the supported Rljson table types
|
|
13
13
|
*/
|
|
14
14
|
export type TableType = BuffetsTable | PropertiesTable<any> | CollectionsTable | IdSetsTable | CakesTable;
|
|
15
15
|
/** The rljson data format */
|
|
16
16
|
export interface Rljson extends Json {
|
|
17
|
-
[tableId:
|
|
17
|
+
[tableId: TableKey]: TableType;
|
|
18
18
|
}
|
|
19
19
|
/**
|
|
20
20
|
* Rljson set with private fields
|
|
@@ -58,4 +58,4 @@ export interface RljsonTable<Data extends Json, Type extends ContentType> extend
|
|
|
58
58
|
* @param rljson - The Rljson object to iterate
|
|
59
59
|
* @param callback - The callback to call for each table
|
|
60
60
|
*/
|
|
61
|
-
export declare const iterateTables: (rljson: Rljson, callback: (
|
|
61
|
+
export declare const iterateTables: (rljson: Rljson, callback: (tableKey: string, table: TableType) => void) => void;
|
package/dist/rljson.js
CHANGED
|
@@ -157,72 +157,56 @@ __publicField(_Example, "ok", {
|
|
|
157
157
|
};
|
|
158
158
|
},
|
|
159
159
|
singleRow: () => {
|
|
160
|
-
const tableCfgs = {
|
|
160
|
+
const tableCfgs = hip({
|
|
161
161
|
_hash: "",
|
|
162
162
|
_type: "properties",
|
|
163
163
|
_data: [
|
|
164
164
|
{
|
|
165
|
-
_hash: "
|
|
166
|
-
|
|
167
|
-
|
|
165
|
+
_hash: "",
|
|
166
|
+
key: "table",
|
|
167
|
+
type: "properties",
|
|
168
168
|
columns: {
|
|
169
169
|
int: {
|
|
170
|
-
|
|
171
|
-
type: "number"
|
|
172
|
-
name: "Integer",
|
|
173
|
-
nameShort: "Int"
|
|
170
|
+
key: "int",
|
|
171
|
+
type: "number"
|
|
174
172
|
},
|
|
175
173
|
double: {
|
|
176
|
-
|
|
177
|
-
type: "number"
|
|
178
|
-
name: "Double",
|
|
179
|
-
nameShort: "Dbl"
|
|
174
|
+
key: "double",
|
|
175
|
+
type: "number"
|
|
180
176
|
},
|
|
181
177
|
string: {
|
|
182
|
-
|
|
183
|
-
type: "string"
|
|
184
|
-
name: "String",
|
|
185
|
-
nameShort: "Str"
|
|
178
|
+
key: "string",
|
|
179
|
+
type: "string"
|
|
186
180
|
},
|
|
187
181
|
boolean: {
|
|
188
|
-
|
|
189
|
-
type: "boolean"
|
|
190
|
-
name: "Boolean",
|
|
191
|
-
nameShort: "Bool"
|
|
182
|
+
key: "boolean",
|
|
183
|
+
type: "boolean"
|
|
192
184
|
},
|
|
193
185
|
null: {
|
|
194
|
-
|
|
195
|
-
type: "null"
|
|
196
|
-
name: "null",
|
|
197
|
-
nameShort: "null"
|
|
186
|
+
key: "null",
|
|
187
|
+
type: "null"
|
|
198
188
|
},
|
|
199
189
|
jsonArray: {
|
|
200
|
-
|
|
201
|
-
type: "jsonArray"
|
|
202
|
-
name: "Json Array",
|
|
203
|
-
nameShort: "Jarray"
|
|
190
|
+
key: "jsonArray",
|
|
191
|
+
type: "jsonArray"
|
|
204
192
|
},
|
|
205
193
|
json: {
|
|
206
|
-
|
|
207
|
-
type: "json"
|
|
208
|
-
name: "Json",
|
|
209
|
-
nameShort: "Json"
|
|
194
|
+
key: "json",
|
|
195
|
+
type: "json"
|
|
210
196
|
},
|
|
211
197
|
jsonValue: {
|
|
212
|
-
|
|
213
|
-
type: "jsonValue"
|
|
214
|
-
name: "Json Value",
|
|
215
|
-
nameShort: "Jval"
|
|
198
|
+
key: "jsonValue",
|
|
199
|
+
type: "jsonValue"
|
|
216
200
|
}
|
|
217
201
|
}
|
|
218
202
|
}
|
|
219
203
|
]
|
|
220
|
-
};
|
|
204
|
+
});
|
|
221
205
|
const result = {
|
|
222
206
|
tableCfgs,
|
|
223
207
|
table: {
|
|
224
208
|
_type: "properties",
|
|
225
|
-
_tableCfg:
|
|
209
|
+
_tableCfg: tableCfgs._data[0]._hash,
|
|
226
210
|
_data: [exampleJsonObject()],
|
|
227
211
|
_hash: ""
|
|
228
212
|
}
|
|
@@ -357,7 +341,7 @@ __publicField(_Example, "ok", {
|
|
|
357
341
|
});
|
|
358
342
|
__publicField(_Example, "broken", {
|
|
359
343
|
base: {
|
|
360
|
-
|
|
344
|
+
brokenTableKey: () => {
|
|
361
345
|
return {
|
|
362
346
|
brok$en: {
|
|
363
347
|
_type: "properties",
|
|
@@ -518,23 +502,30 @@ const rljsonIndexed = (rljson) => {
|
|
|
518
502
|
};
|
|
519
503
|
// @license
|
|
520
504
|
const reservedFieldNames = ["_type", "_data"];
|
|
521
|
-
const
|
|
505
|
+
const reservedTableKeys = ["_hash", "idSets", "tableCfgs"];
|
|
522
506
|
const exampleRljson = () => Example.ok.singleRow();
|
|
523
507
|
const iterateTables = (rljson, callback) => {
|
|
524
|
-
for (const
|
|
525
|
-
const value = rljson[
|
|
508
|
+
for (const tableKey in rljson) {
|
|
509
|
+
const value = rljson[tableKey];
|
|
526
510
|
if (typeof value !== "object" || !Array.isArray(value._data)) {
|
|
527
511
|
continue;
|
|
528
512
|
}
|
|
529
|
-
callback(
|
|
513
|
+
callback(tableKey, rljson[tableKey]);
|
|
530
514
|
}
|
|
531
515
|
};
|
|
532
516
|
// @license
|
|
517
|
+
const contentTypes = [
|
|
518
|
+
"buffets",
|
|
519
|
+
"cakes",
|
|
520
|
+
"collections",
|
|
521
|
+
"idSets",
|
|
522
|
+
"properties"
|
|
523
|
+
];
|
|
533
524
|
const exampleTypedefs = () => {
|
|
534
525
|
return {
|
|
535
526
|
ref: "ref",
|
|
536
527
|
itemId: "itemId",
|
|
537
|
-
|
|
528
|
+
tableKey: "tableKey",
|
|
538
529
|
contentType: "collections"
|
|
539
530
|
};
|
|
540
531
|
};
|
|
@@ -559,10 +550,10 @@ class _BaseValidator {
|
|
|
559
550
|
// ######################
|
|
560
551
|
// Private
|
|
561
552
|
// ######################
|
|
562
|
-
__publicField(this, "
|
|
553
|
+
__publicField(this, "tableKeys");
|
|
563
554
|
__publicField(this, "rljsonIndexed");
|
|
564
555
|
this.rljson = rljson;
|
|
565
|
-
this.
|
|
556
|
+
this.tableKeys = Object.keys(this.rljson).filter(
|
|
566
557
|
(table) => !table.startsWith("_")
|
|
567
558
|
);
|
|
568
559
|
this.rljsonIndexed = rljsonIndexed(rljson);
|
|
@@ -574,17 +565,19 @@ class _BaseValidator {
|
|
|
574
565
|
const steps = [
|
|
575
566
|
// Base checks
|
|
576
567
|
() => this._writeAndValidHashes(),
|
|
577
|
-
() => this.
|
|
578
|
-
() => this.
|
|
568
|
+
() => this._tableKeysNotLowerCamelCase(),
|
|
569
|
+
() => this._tableKeysDoNotEndWithRef(),
|
|
579
570
|
() => this._columnNamesNotLowerCamelCase(),
|
|
580
571
|
() => this._dataNotFound(),
|
|
581
572
|
() => this._dataHasWrongType(),
|
|
573
|
+
() => this._invalidTableTypes(),
|
|
582
574
|
// Check table cfg
|
|
583
|
-
() => this.
|
|
584
|
-
() => this.
|
|
575
|
+
() => this._tableCfgsReferencedTableKeyNotFound(),
|
|
576
|
+
() => this._tableCfgsHaveWrongType(),
|
|
585
577
|
() => this._tableCfgNotFound(),
|
|
586
578
|
() => this._missingColumnConfigs(),
|
|
587
579
|
() => this._dataDoesNotMatchColumnConfig(),
|
|
580
|
+
() => this._tableTypesDoNotMatch(),
|
|
588
581
|
// Check references
|
|
589
582
|
() => this._refsNotFound(),
|
|
590
583
|
// Check collections
|
|
@@ -606,32 +599,32 @@ class _BaseValidator {
|
|
|
606
599
|
this.errors.hasErrors = this.hasErrors;
|
|
607
600
|
return this.errors;
|
|
608
601
|
}
|
|
609
|
-
|
|
610
|
-
const
|
|
611
|
-
for (const
|
|
612
|
-
if (!BaseValidator.isValidFieldName(
|
|
613
|
-
|
|
602
|
+
_tableKeysNotLowerCamelCase() {
|
|
603
|
+
const invalidTableKeys = [];
|
|
604
|
+
for (const tableKey of this.tableKeys) {
|
|
605
|
+
if (!BaseValidator.isValidFieldName(tableKey)) {
|
|
606
|
+
invalidTableKeys.push(tableKey);
|
|
614
607
|
}
|
|
615
608
|
}
|
|
616
|
-
if (
|
|
617
|
-
this.errors.
|
|
609
|
+
if (invalidTableKeys.length > 0) {
|
|
610
|
+
this.errors.tableKeysNotLowerCamelCase = {
|
|
618
611
|
error: "Table names must be lower camel case",
|
|
619
|
-
|
|
612
|
+
invalidTableKeys
|
|
620
613
|
};
|
|
621
614
|
}
|
|
622
615
|
}
|
|
623
616
|
// ...........................................................................
|
|
624
|
-
|
|
625
|
-
const
|
|
626
|
-
for (const
|
|
627
|
-
if (
|
|
628
|
-
|
|
617
|
+
_tableKeysDoNotEndWithRef() {
|
|
618
|
+
const invalidTableKeys = [];
|
|
619
|
+
for (const tableKey of this.tableKeys) {
|
|
620
|
+
if (tableKey.endsWith("Ref")) {
|
|
621
|
+
invalidTableKeys.push(tableKey);
|
|
629
622
|
}
|
|
630
623
|
}
|
|
631
|
-
if (
|
|
632
|
-
this.errors.
|
|
624
|
+
if (invalidTableKeys.length > 0) {
|
|
625
|
+
this.errors.tableKeysDoNotEndWithRef = {
|
|
633
626
|
error: 'Table names must not end with "Ref"',
|
|
634
|
-
|
|
627
|
+
invalidTableKeys
|
|
635
628
|
};
|
|
636
629
|
}
|
|
637
630
|
}
|
|
@@ -639,8 +632,8 @@ class _BaseValidator {
|
|
|
639
632
|
_columnNamesNotLowerCamelCase() {
|
|
640
633
|
const invalidColumnNames = {};
|
|
641
634
|
let hadErrors = false;
|
|
642
|
-
for (const
|
|
643
|
-
const table = this.rljson[
|
|
635
|
+
for (const tableKey of this.tableKeys) {
|
|
636
|
+
const table = this.rljson[tableKey];
|
|
644
637
|
if (!table._data || !Array.isArray(table._data)) {
|
|
645
638
|
continue;
|
|
646
639
|
}
|
|
@@ -650,8 +643,8 @@ class _BaseValidator {
|
|
|
650
643
|
continue;
|
|
651
644
|
}
|
|
652
645
|
if (!BaseValidator.isValidFieldName(columnName)) {
|
|
653
|
-
invalidColumnNames[
|
|
654
|
-
invalidColumnNames[
|
|
646
|
+
invalidColumnNames[tableKey] ?? (invalidColumnNames[tableKey] = []);
|
|
647
|
+
invalidColumnNames[tableKey].push(columnName);
|
|
655
648
|
hadErrors = true;
|
|
656
649
|
}
|
|
657
650
|
}
|
|
@@ -689,7 +682,7 @@ class _BaseValidator {
|
|
|
689
682
|
_dataNotFound() {
|
|
690
683
|
const rljson = this.rljson;
|
|
691
684
|
const tablesWithMissingData = [];
|
|
692
|
-
for (const table of this.
|
|
685
|
+
for (const table of this.tableKeys) {
|
|
693
686
|
const tableData = rljson[table];
|
|
694
687
|
const items = tableData["_data"];
|
|
695
688
|
if (items == null) {
|
|
@@ -704,30 +697,30 @@ class _BaseValidator {
|
|
|
704
697
|
}
|
|
705
698
|
}
|
|
706
699
|
// ...........................................................................
|
|
707
|
-
|
|
700
|
+
_tableCfgsReferencedTableKeyNotFound() {
|
|
708
701
|
const tableCfgs = this.rljson.tableCfgs;
|
|
709
702
|
if (!tableCfgs) {
|
|
710
703
|
return;
|
|
711
704
|
}
|
|
712
705
|
const brokenCfgs = [];
|
|
713
706
|
for (const item of tableCfgs._data) {
|
|
714
|
-
const table = this.rljson[item.
|
|
707
|
+
const table = this.rljson[item.key];
|
|
715
708
|
if (!table) {
|
|
716
709
|
brokenCfgs.push({
|
|
717
710
|
brokenTableCfg: item._hash,
|
|
718
|
-
|
|
711
|
+
tableKeyNotFound: item.key
|
|
719
712
|
});
|
|
720
713
|
}
|
|
721
714
|
}
|
|
722
715
|
if (brokenCfgs.length > 0) {
|
|
723
|
-
this.errors.
|
|
716
|
+
this.errors.tableCfgsReferencedTableKeyNotFound = {
|
|
724
717
|
error: "Tables referenced in tableCfgs not found",
|
|
725
718
|
brokenCfgs
|
|
726
719
|
};
|
|
727
720
|
}
|
|
728
721
|
}
|
|
729
722
|
// ...........................................................................
|
|
730
|
-
|
|
723
|
+
_tableCfgsHaveWrongType() {
|
|
731
724
|
const tableCfgs = this.rljson.tableCfgs;
|
|
732
725
|
if (!tableCfgs) {
|
|
733
726
|
return;
|
|
@@ -749,7 +742,7 @@ class _BaseValidator {
|
|
|
749
742
|
}
|
|
750
743
|
}
|
|
751
744
|
if (brokenCfgs.length > 0) {
|
|
752
|
-
this.errors.
|
|
745
|
+
this.errors.columnsHaveWrongType = {
|
|
753
746
|
error: "Some of the columns have invalid types. Valid types are: " + jsonValueTypes.join(", "),
|
|
754
747
|
brokenCfgs
|
|
755
748
|
};
|
|
@@ -759,7 +752,7 @@ class _BaseValidator {
|
|
|
759
752
|
_tableCfgNotFound() {
|
|
760
753
|
const tableCfgs = this.rljsonIndexed.tableCfgs;
|
|
761
754
|
const tableCfgNotFound = [];
|
|
762
|
-
iterateTables(this.rljson, (
|
|
755
|
+
iterateTables(this.rljson, (tableKey, table) => {
|
|
763
756
|
const tableCfgRef = table._tableCfg;
|
|
764
757
|
if (!tableCfgRef) {
|
|
765
758
|
return;
|
|
@@ -767,7 +760,7 @@ class _BaseValidator {
|
|
|
767
760
|
const tableCfgData = tableCfgs._data[tableCfgRef];
|
|
768
761
|
if (!tableCfgData) {
|
|
769
762
|
tableCfgNotFound.push({
|
|
770
|
-
tableWithBrokenTableCfgRef:
|
|
763
|
+
tableWithBrokenTableCfgRef: tableKey,
|
|
771
764
|
brokenTableCfgRef: tableCfgRef
|
|
772
765
|
});
|
|
773
766
|
return;
|
|
@@ -784,7 +777,7 @@ class _BaseValidator {
|
|
|
784
777
|
_missingColumnConfigs() {
|
|
785
778
|
const tableCfgs = this.rljsonIndexed.tableCfgs;
|
|
786
779
|
const missingColumnConfigs = [];
|
|
787
|
-
iterateTables(this.rljson, (
|
|
780
|
+
iterateTables(this.rljson, (tableKey, table) => {
|
|
788
781
|
const tableCfgRef = table._tableCfg;
|
|
789
782
|
if (!tableCfgRef) {
|
|
790
783
|
return;
|
|
@@ -805,7 +798,7 @@ class _BaseValidator {
|
|
|
805
798
|
tableCfg: tableCfgRef,
|
|
806
799
|
row: row._hash,
|
|
807
800
|
column: columnKey,
|
|
808
|
-
table:
|
|
801
|
+
table: tableKey
|
|
809
802
|
});
|
|
810
803
|
}
|
|
811
804
|
processedColumnKeys.push(columnKey);
|
|
@@ -823,7 +816,7 @@ class _BaseValidator {
|
|
|
823
816
|
_dataDoesNotMatchColumnConfig() {
|
|
824
817
|
const tableCfgs = this.rljsonIndexed.tableCfgs;
|
|
825
818
|
const brokenValues = [];
|
|
826
|
-
iterateTables(this.rljson, (
|
|
819
|
+
iterateTables(this.rljson, (tableKey, table) => {
|
|
827
820
|
const tableCfgRef = table._tableCfg;
|
|
828
821
|
if (!tableCfgRef) {
|
|
829
822
|
return;
|
|
@@ -843,7 +836,7 @@ class _BaseValidator {
|
|
|
843
836
|
const typeShould = columnConfig.type;
|
|
844
837
|
if (!jsonValueMatchesType(value, typeShould)) {
|
|
845
838
|
brokenValues.push({
|
|
846
|
-
table:
|
|
839
|
+
table: tableKey,
|
|
847
840
|
row: row._hash,
|
|
848
841
|
column: columnKey,
|
|
849
842
|
tableCfg: tableCfgRef
|
|
@@ -860,14 +853,43 @@ class _BaseValidator {
|
|
|
860
853
|
}
|
|
861
854
|
}
|
|
862
855
|
// ...........................................................................
|
|
856
|
+
_tableTypesDoNotMatch() {
|
|
857
|
+
const rljson = this.rljson;
|
|
858
|
+
const tablesWithTypeMissmatch = [];
|
|
859
|
+
for (const tableKey of this.tableKeys) {
|
|
860
|
+
const table = rljson[tableKey];
|
|
861
|
+
const cfgRef = table._tableCfg;
|
|
862
|
+
if (!cfgRef) {
|
|
863
|
+
continue;
|
|
864
|
+
}
|
|
865
|
+
const cfg = this.rljsonIndexed.tableCfgs._data[cfgRef];
|
|
866
|
+
const typeShould = cfg.type;
|
|
867
|
+
const typeIs = table._type;
|
|
868
|
+
if (typeShould !== typeIs) {
|
|
869
|
+
tablesWithTypeMissmatch.push({
|
|
870
|
+
table: tableKey,
|
|
871
|
+
typeInTable: typeIs,
|
|
872
|
+
typeInConfig: typeShould,
|
|
873
|
+
tableCfg: cfgRef
|
|
874
|
+
});
|
|
875
|
+
}
|
|
876
|
+
}
|
|
877
|
+
if (tablesWithTypeMissmatch.length > 0) {
|
|
878
|
+
this.errors.tableTypesDoNotMatch = {
|
|
879
|
+
error: "Table types do not match table config",
|
|
880
|
+
tables: tablesWithTypeMissmatch
|
|
881
|
+
};
|
|
882
|
+
}
|
|
883
|
+
}
|
|
884
|
+
// ...........................................................................
|
|
863
885
|
_dataHasWrongType() {
|
|
864
886
|
const rljson = this.rljson;
|
|
865
887
|
const tablesWithWrongType = [];
|
|
866
|
-
for (const
|
|
867
|
-
const tableData = rljson[
|
|
888
|
+
for (const tableKey of this.tableKeys) {
|
|
889
|
+
const tableData = rljson[tableKey];
|
|
868
890
|
const items = tableData["_data"];
|
|
869
891
|
if (!Array.isArray(items)) {
|
|
870
|
-
tablesWithWrongType.push(
|
|
892
|
+
tablesWithWrongType.push(tableKey);
|
|
871
893
|
}
|
|
872
894
|
}
|
|
873
895
|
if (tablesWithWrongType.length > 0) {
|
|
@@ -877,37 +899,59 @@ class _BaseValidator {
|
|
|
877
899
|
};
|
|
878
900
|
}
|
|
879
901
|
}
|
|
902
|
+
// ...........................................................................
|
|
903
|
+
_invalidTableTypes() {
|
|
904
|
+
const rljson = this.rljson;
|
|
905
|
+
const tablesWithWrongType = [];
|
|
906
|
+
for (const tableKey of this.tableKeys) {
|
|
907
|
+
const table = rljson[tableKey];
|
|
908
|
+
const type = table._type;
|
|
909
|
+
if (contentTypes.indexOf(type) === -1) {
|
|
910
|
+
tablesWithWrongType.push({
|
|
911
|
+
table: tableKey,
|
|
912
|
+
type,
|
|
913
|
+
allowedTypes: contentTypes.join(" | ")
|
|
914
|
+
});
|
|
915
|
+
}
|
|
916
|
+
}
|
|
917
|
+
if (tablesWithWrongType.length > 0) {
|
|
918
|
+
this.errors.invalidTableTypes = {
|
|
919
|
+
error: "Tables with invalid types",
|
|
920
|
+
tables: tablesWithWrongType
|
|
921
|
+
};
|
|
922
|
+
}
|
|
923
|
+
}
|
|
880
924
|
_refsNotFound() {
|
|
881
925
|
const missingRefs = [];
|
|
882
|
-
iterateTables(this.rljson, (
|
|
926
|
+
iterateTables(this.rljson, (tableKey, table) => {
|
|
883
927
|
const tableData = table._data;
|
|
884
928
|
for (const item of tableData) {
|
|
885
929
|
for (const key of Object.keys(item)) {
|
|
886
930
|
if (key.endsWith("Ref")) {
|
|
887
931
|
const targetItemHash = item[key];
|
|
888
|
-
const
|
|
932
|
+
const targetTableKey = key.substring(0, key.length - 3);
|
|
889
933
|
const itemHash = item._hash;
|
|
890
|
-
if (this.
|
|
934
|
+
if (this.tableKeys.indexOf(targetTableKey) === -1) {
|
|
891
935
|
missingRefs.push({
|
|
892
|
-
error: `Target table "${
|
|
893
|
-
sourceTable:
|
|
936
|
+
error: `Target table "${targetTableKey}" not found.`,
|
|
937
|
+
sourceTable: tableKey,
|
|
894
938
|
sourceKey: key,
|
|
895
939
|
sourceItemHash: itemHash,
|
|
896
940
|
targetItemHash,
|
|
897
|
-
targetTable:
|
|
941
|
+
targetTable: targetTableKey
|
|
898
942
|
});
|
|
899
943
|
continue;
|
|
900
944
|
}
|
|
901
|
-
const targetTableIndexed = this.rljsonIndexed[
|
|
945
|
+
const targetTableIndexed = this.rljsonIndexed[targetTableKey];
|
|
902
946
|
const referencedItem = targetTableIndexed._data[targetItemHash];
|
|
903
947
|
if (referencedItem === void 0) {
|
|
904
948
|
missingRefs.push({
|
|
905
|
-
sourceTable:
|
|
949
|
+
sourceTable: tableKey,
|
|
906
950
|
sourceItemHash: itemHash,
|
|
907
951
|
sourceKey: key,
|
|
908
952
|
targetItemHash,
|
|
909
|
-
targetTable:
|
|
910
|
-
error: `Table "${
|
|
953
|
+
targetTable: targetTableKey,
|
|
954
|
+
error: `Table "${targetTableKey}" has no item with hash "${targetItemHash}"`
|
|
911
955
|
});
|
|
912
956
|
}
|
|
913
957
|
}
|
|
@@ -923,11 +967,11 @@ class _BaseValidator {
|
|
|
923
967
|
}
|
|
924
968
|
_collectionBasesNotFound() {
|
|
925
969
|
const brokenCollections = [];
|
|
926
|
-
iterateTables(this.rljson, (
|
|
970
|
+
iterateTables(this.rljson, (tableKey, table) => {
|
|
927
971
|
if (table._type !== "collections") {
|
|
928
972
|
return;
|
|
929
973
|
}
|
|
930
|
-
const collectionsIndexed = this.rljsonIndexed[
|
|
974
|
+
const collectionsIndexed = this.rljsonIndexed[tableKey];
|
|
931
975
|
const collectionsTable = table;
|
|
932
976
|
for (const collection of collectionsTable._data) {
|
|
933
977
|
const baseRef = collection.base;
|
|
@@ -937,7 +981,7 @@ class _BaseValidator {
|
|
|
937
981
|
const baseCollection = collectionsIndexed._data[baseRef];
|
|
938
982
|
if (!baseCollection) {
|
|
939
983
|
brokenCollections.push({
|
|
940
|
-
collectionsTable:
|
|
984
|
+
collectionsTable: tableKey,
|
|
941
985
|
brokenCollection: collection._hash,
|
|
942
986
|
missingBaseCollection: baseRef
|
|
943
987
|
});
|
|
@@ -953,7 +997,7 @@ class _BaseValidator {
|
|
|
953
997
|
}
|
|
954
998
|
_collectionIdSetsExist() {
|
|
955
999
|
const brokenCollections = [];
|
|
956
|
-
iterateTables(this.rljson, (
|
|
1000
|
+
iterateTables(this.rljson, (tableKey, table) => {
|
|
957
1001
|
if (table._type !== "collections") {
|
|
958
1002
|
return;
|
|
959
1003
|
}
|
|
@@ -967,7 +1011,7 @@ class _BaseValidator {
|
|
|
967
1011
|
const idSet = idSets._data[idSetRef];
|
|
968
1012
|
if (!idSet) {
|
|
969
1013
|
brokenCollections.push({
|
|
970
|
-
collectionsTable:
|
|
1014
|
+
collectionsTable: tableKey,
|
|
971
1015
|
collectionHash: collection._hash,
|
|
972
1016
|
missingIdSet: idSetRef
|
|
973
1017
|
});
|
|
@@ -984,19 +1028,19 @@ class _BaseValidator {
|
|
|
984
1028
|
_collectionPropertyAssignmentsNotFound() {
|
|
985
1029
|
const missingPropertyTables = [];
|
|
986
1030
|
const brokenAssignments = [];
|
|
987
|
-
iterateTables(this.rljson, (
|
|
1031
|
+
iterateTables(this.rljson, (tableKey, table) => {
|
|
988
1032
|
if (table._type !== "collections") {
|
|
989
1033
|
return;
|
|
990
1034
|
}
|
|
991
1035
|
const collectionsTable = table;
|
|
992
1036
|
for (const collection of collectionsTable._data) {
|
|
993
|
-
const
|
|
994
|
-
const propertiesTable = this.rljsonIndexed[
|
|
1037
|
+
const propertyTableKey = collection.properties;
|
|
1038
|
+
const propertiesTable = this.rljsonIndexed[propertyTableKey];
|
|
995
1039
|
if (!propertiesTable) {
|
|
996
1040
|
missingPropertyTables.push({
|
|
997
1041
|
brokenCollection: collection._hash,
|
|
998
|
-
collectionsTable:
|
|
999
|
-
missingPropertyTable:
|
|
1042
|
+
collectionsTable: tableKey,
|
|
1043
|
+
missingPropertyTable: propertyTableKey
|
|
1000
1044
|
});
|
|
1001
1045
|
continue;
|
|
1002
1046
|
}
|
|
@@ -1008,9 +1052,9 @@ class _BaseValidator {
|
|
|
1008
1052
|
const propertyHash = assignments[itemId];
|
|
1009
1053
|
if (!propertiesTable._data[propertyHash]) {
|
|
1010
1054
|
brokenAssignments.push({
|
|
1011
|
-
collectionsTable:
|
|
1055
|
+
collectionsTable: tableKey,
|
|
1012
1056
|
brokenCollection: collection._hash,
|
|
1013
|
-
referencedPropertyTable:
|
|
1057
|
+
referencedPropertyTable: propertyTableKey,
|
|
1014
1058
|
brokenAssignment: itemId,
|
|
1015
1059
|
missingProperty: propertyHash
|
|
1016
1060
|
});
|
|
@@ -1033,7 +1077,7 @@ class _BaseValidator {
|
|
|
1033
1077
|
}
|
|
1034
1078
|
_cakeIdSetsNotFound() {
|
|
1035
1079
|
const brokenCakes = [];
|
|
1036
|
-
iterateTables(this.rljson, (
|
|
1080
|
+
iterateTables(this.rljson, (tableKey, table) => {
|
|
1037
1081
|
if (table._type !== "cakes") {
|
|
1038
1082
|
return;
|
|
1039
1083
|
}
|
|
@@ -1047,7 +1091,7 @@ class _BaseValidator {
|
|
|
1047
1091
|
const idSet = idSets._data[idSetRef];
|
|
1048
1092
|
if (!idSet) {
|
|
1049
1093
|
brokenCakes.push({
|
|
1050
|
-
cakeTable:
|
|
1094
|
+
cakeTable: tableKey,
|
|
1051
1095
|
brokenCake: cake._hash,
|
|
1052
1096
|
missingIdSet: idSetRef
|
|
1053
1097
|
});
|
|
@@ -1064,19 +1108,19 @@ class _BaseValidator {
|
|
|
1064
1108
|
_cakeCollectionTablesNotFound() {
|
|
1065
1109
|
const missingCollectionTables = [];
|
|
1066
1110
|
const missingLayerCollections = [];
|
|
1067
|
-
iterateTables(this.rljson, (
|
|
1111
|
+
iterateTables(this.rljson, (tableKey, table) => {
|
|
1068
1112
|
if (table._type !== "cakes") {
|
|
1069
1113
|
return;
|
|
1070
1114
|
}
|
|
1071
1115
|
const cakesTable = table;
|
|
1072
1116
|
for (const cake of cakesTable._data) {
|
|
1073
|
-
const
|
|
1074
|
-
const collectionsTable = this.rljsonIndexed[
|
|
1117
|
+
const collectionsTableKey = cake.collections;
|
|
1118
|
+
const collectionsTable = this.rljsonIndexed[collectionsTableKey];
|
|
1075
1119
|
if (!collectionsTable) {
|
|
1076
1120
|
missingCollectionTables.push({
|
|
1077
|
-
cakeTable:
|
|
1121
|
+
cakeTable: tableKey,
|
|
1078
1122
|
brokenCake: cake._hash,
|
|
1079
|
-
missingCollectionsTable:
|
|
1123
|
+
missingCollectionsTable: collectionsTableKey
|
|
1080
1124
|
});
|
|
1081
1125
|
continue;
|
|
1082
1126
|
}
|
|
@@ -1088,10 +1132,10 @@ class _BaseValidator {
|
|
|
1088
1132
|
const collection = collectionsTable._data[collectionRef];
|
|
1089
1133
|
if (!collection) {
|
|
1090
1134
|
missingLayerCollections.push({
|
|
1091
|
-
cakeTable:
|
|
1135
|
+
cakeTable: tableKey,
|
|
1092
1136
|
brokenCake: cake._hash,
|
|
1093
1137
|
brokenLayerName: layer,
|
|
1094
|
-
collectionsTable:
|
|
1138
|
+
collectionsTable: collectionsTableKey,
|
|
1095
1139
|
missingCollection: collectionRef
|
|
1096
1140
|
});
|
|
1097
1141
|
}
|
|
@@ -1114,20 +1158,20 @@ class _BaseValidator {
|
|
|
1114
1158
|
_buffetReferencedTableNotFound() {
|
|
1115
1159
|
const missingTables = [];
|
|
1116
1160
|
const missingItems = [];
|
|
1117
|
-
iterateTables(this.rljson, (
|
|
1161
|
+
iterateTables(this.rljson, (tableKey, table) => {
|
|
1118
1162
|
if (table._type !== "buffets") {
|
|
1119
1163
|
return;
|
|
1120
1164
|
}
|
|
1121
1165
|
const buffetsTable = table;
|
|
1122
1166
|
for (const buffet of buffetsTable._data) {
|
|
1123
1167
|
for (const item of buffet.items) {
|
|
1124
|
-
const
|
|
1125
|
-
const itemTable = this.rljsonIndexed[
|
|
1168
|
+
const itemTableKey = item.table;
|
|
1169
|
+
const itemTable = this.rljsonIndexed[itemTableKey];
|
|
1126
1170
|
if (!itemTable) {
|
|
1127
1171
|
missingTables.push({
|
|
1128
|
-
buffetTable:
|
|
1172
|
+
buffetTable: tableKey,
|
|
1129
1173
|
brokenBuffet: buffet._hash,
|
|
1130
|
-
missingItemTable:
|
|
1174
|
+
missingItemTable: itemTableKey
|
|
1131
1175
|
});
|
|
1132
1176
|
continue;
|
|
1133
1177
|
}
|
|
@@ -1135,9 +1179,9 @@ class _BaseValidator {
|
|
|
1135
1179
|
const referencedItem = itemTable._data[ref];
|
|
1136
1180
|
if (!referencedItem) {
|
|
1137
1181
|
missingItems.push({
|
|
1138
|
-
buffetTable:
|
|
1182
|
+
buffetTable: tableKey,
|
|
1139
1183
|
brokenBuffet: buffet._hash,
|
|
1140
|
-
itemTable:
|
|
1184
|
+
itemTable: itemTableKey,
|
|
1141
1185
|
missingItem: ref
|
|
1142
1186
|
});
|
|
1143
1187
|
}
|
|
@@ -1201,6 +1245,7 @@ export {
|
|
|
1201
1245
|
Example,
|
|
1202
1246
|
Validate,
|
|
1203
1247
|
bakeryExample,
|
|
1248
|
+
contentTypes,
|
|
1204
1249
|
exampleBuffetsTable,
|
|
1205
1250
|
exampleCakesTable,
|
|
1206
1251
|
exampleCollectionsTable,
|
|
@@ -1212,6 +1257,6 @@ export {
|
|
|
1212
1257
|
isValidFieldName,
|
|
1213
1258
|
iterateTables,
|
|
1214
1259
|
reservedFieldNames,
|
|
1215
|
-
|
|
1260
|
+
reservedTableKeys,
|
|
1216
1261
|
rljsonIndexed
|
|
1217
1262
|
};
|
package/dist/src/example.ts
CHANGED
|
@@ -34,73 +34,57 @@ export class Example {
|
|
|
34
34
|
},
|
|
35
35
|
|
|
36
36
|
singleRow: (): Rljson => {
|
|
37
|
-
const tableCfgs: TablesCfgTable = {
|
|
37
|
+
const tableCfgs: TablesCfgTable = hip({
|
|
38
38
|
_hash: '',
|
|
39
39
|
_type: 'properties',
|
|
40
40
|
_data: [
|
|
41
41
|
{
|
|
42
|
-
_hash: '
|
|
43
|
-
|
|
44
|
-
|
|
42
|
+
_hash: '',
|
|
43
|
+
key: 'table',
|
|
44
|
+
type: 'properties',
|
|
45
45
|
columns: {
|
|
46
46
|
int: {
|
|
47
|
-
|
|
47
|
+
key: 'int',
|
|
48
48
|
type: 'number',
|
|
49
|
-
name: 'Integer',
|
|
50
|
-
nameShort: 'Int',
|
|
51
49
|
},
|
|
52
50
|
double: {
|
|
53
|
-
|
|
51
|
+
key: 'double',
|
|
54
52
|
type: 'number',
|
|
55
|
-
name: 'Double',
|
|
56
|
-
nameShort: 'Dbl',
|
|
57
53
|
},
|
|
58
54
|
string: {
|
|
59
|
-
|
|
55
|
+
key: 'string',
|
|
60
56
|
type: 'string',
|
|
61
|
-
name: 'String',
|
|
62
|
-
nameShort: 'Str',
|
|
63
57
|
},
|
|
64
58
|
boolean: {
|
|
65
|
-
|
|
59
|
+
key: 'boolean',
|
|
66
60
|
type: 'boolean',
|
|
67
|
-
name: 'Boolean',
|
|
68
|
-
nameShort: 'Bool',
|
|
69
61
|
},
|
|
70
62
|
null: {
|
|
71
|
-
|
|
63
|
+
key: 'null',
|
|
72
64
|
type: 'null',
|
|
73
|
-
name: 'null',
|
|
74
|
-
nameShort: 'null',
|
|
75
65
|
},
|
|
76
66
|
jsonArray: {
|
|
77
|
-
|
|
67
|
+
key: 'jsonArray',
|
|
78
68
|
type: 'jsonArray',
|
|
79
|
-
name: 'Json Array',
|
|
80
|
-
nameShort: 'Jarray',
|
|
81
69
|
},
|
|
82
70
|
json: {
|
|
83
|
-
|
|
71
|
+
key: 'json',
|
|
84
72
|
type: 'json',
|
|
85
|
-
name: 'Json',
|
|
86
|
-
nameShort: 'Json',
|
|
87
73
|
},
|
|
88
74
|
jsonValue: {
|
|
89
|
-
|
|
75
|
+
key: 'jsonValue',
|
|
90
76
|
type: 'jsonValue',
|
|
91
|
-
name: 'Json Value',
|
|
92
|
-
nameShort: 'Jval',
|
|
93
77
|
},
|
|
94
78
|
},
|
|
95
79
|
},
|
|
96
80
|
],
|
|
97
|
-
};
|
|
81
|
+
});
|
|
98
82
|
|
|
99
83
|
const result: Rljson = {
|
|
100
84
|
tableCfgs: tableCfgs,
|
|
101
85
|
table: {
|
|
102
86
|
_type: 'properties',
|
|
103
|
-
_tableCfg:
|
|
87
|
+
_tableCfg: tableCfgs._data[0]._hash as string,
|
|
104
88
|
_data: [exampleJsonObject()],
|
|
105
89
|
_hash: '',
|
|
106
90
|
},
|
|
@@ -245,7 +229,7 @@ export class Example {
|
|
|
245
229
|
|
|
246
230
|
static readonly broken = {
|
|
247
231
|
base: {
|
|
248
|
-
|
|
232
|
+
brokenTableKey: () => {
|
|
249
233
|
return {
|
|
250
234
|
brok$en: {
|
|
251
235
|
_type: 'properties',
|
package/dist/typedefs.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { JsonKey } from '@rljson/json';
|
|
1
2
|
/**
|
|
2
3
|
* A ref is a hash that references to another element
|
|
3
4
|
*/
|
|
@@ -11,7 +12,11 @@ export type ItemId = string;
|
|
|
11
12
|
* A table id reference to a table. The table ids are used as keys in the top
|
|
12
13
|
* level structure of an Rljson data object.
|
|
13
14
|
*/
|
|
14
|
-
export type
|
|
15
|
+
export type TableKey = JsonKey;
|
|
16
|
+
/**
|
|
17
|
+
* A column key is a key that references a column in a table
|
|
18
|
+
*/
|
|
19
|
+
export type ColumnKey = JsonKey;
|
|
15
20
|
/**
|
|
16
21
|
* Types of tables that can be stored in an Rljson object
|
|
17
22
|
*
|
|
@@ -21,13 +26,14 @@ export type TableName = ItemId;
|
|
|
21
26
|
* - `ids` Tables containing item ids
|
|
22
27
|
* - `properties` Tables containing item properties
|
|
23
28
|
*/
|
|
24
|
-
export
|
|
29
|
+
export declare const contentTypes: readonly ["buffets", "cakes", "collections", "idSets", "properties"];
|
|
30
|
+
export type ContentType = (typeof contentTypes)[number];
|
|
25
31
|
/**
|
|
26
32
|
* An example object using the typedefs
|
|
27
33
|
*/
|
|
28
34
|
export declare const exampleTypedefs: () => {
|
|
29
35
|
ref: Ref;
|
|
30
36
|
itemId: ItemId;
|
|
31
|
-
|
|
37
|
+
tableKey: TableKey;
|
|
32
38
|
contentType: ContentType;
|
|
33
39
|
};
|
|
@@ -2,18 +2,20 @@ import { Json } from '@rljson/json';
|
|
|
2
2
|
import { Rljson } from '../rljson.ts';
|
|
3
3
|
import { Errors, Validator } from './validate.ts';
|
|
4
4
|
export interface BaseErrors extends Errors {
|
|
5
|
-
|
|
5
|
+
tableKeysNotLowerCamelCase?: Json;
|
|
6
6
|
columnNamesNotLowerCamelCase?: Json;
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
tableKeysDoNotStartWithANumber?: Json;
|
|
8
|
+
tableKeysDoNotEndWithRef?: Json;
|
|
9
9
|
hashesNotValid?: Json;
|
|
10
10
|
dataNotFound?: Json;
|
|
11
11
|
dataHasWrongType?: Json;
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
invalidTableTypes?: Json;
|
|
13
|
+
tableCfgsReferencedTableKeyNotFound?: Json;
|
|
14
|
+
columnsHaveWrongType?: Json;
|
|
14
15
|
tableCfgReferencedNotFound?: Json;
|
|
15
16
|
columnConfigNotFound?: Json;
|
|
16
17
|
dataDoesNotMatchColumnConfig?: Json;
|
|
18
|
+
tableTypesDoNotMatch?: Json;
|
|
17
19
|
refsNotFound?: Json;
|
|
18
20
|
collectionBasesNotFound?: Json;
|
|
19
21
|
collectionIdSetsNotFound?: Json;
|