json-fs-query 1.0.6 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/browser/jsonFsQuery.js +518 -361
  2. package/browser/jsonFsQuery.min.js +1 -1
  3. package/dist/data/introspect/policies/foreignKeyExists.js +28 -24
  4. package/dist/data/introspect/policies/foreignKeyExists.min.js +1 -1
  5. package/dist/data/introspect/policies/hasDependents.js +53 -51
  6. package/dist/data/introspect/policies/hasDependents.min.js +1 -1
  7. package/dist/data/introspect/policies/keyUnique.js +34 -30
  8. package/dist/data/introspect/policies/keyUnique.min.js +1 -1
  9. package/dist/data/queries/deleteEntity.js +100 -99
  10. package/dist/data/queries/deleteEntity.min.js +1 -1
  11. package/dist/data/queries/insertEntity.js +117 -116
  12. package/dist/data/queries/insertEntity.min.js +1 -1
  13. package/dist/data/queries/sortBy.js +27 -24
  14. package/dist/data/queries/updateEntity.js +193 -189
  15. package/dist/data/queries/updateEntity.min.js +1 -1
  16. package/dist/data/queries/where.d.ts +7 -6
  17. package/dist/data/queries/where.js +67 -55
  18. package/dist/data/queries/where.min.js +1 -1
  19. package/dist/data/utilities/compareAs.d.ts +20 -0
  20. package/dist/data/utilities/compareAs.js +58 -0
  21. package/dist/data/utilities/compareAs.min.js +1 -0
  22. package/dist/data/utilities/fieldType.d.ts +16 -0
  23. package/dist/data/utilities/fieldType.js +23 -0
  24. package/dist/data/utilities/fieldType.min.js +1 -0
  25. package/dist/data/utilities/getConditionIndexedList.js +47 -46
  26. package/dist/data/utilities/getConditionIndexedList.min.js +1 -1
  27. package/dist/data/utilities/matchIndexedJoins.js +62 -60
  28. package/dist/data/utilities/matchIndexedJoins.min.js +1 -1
  29. package/dist/data/utilities/mergeJoin.js +47 -43
  30. package/dist/data/utilities/mergeJoin.min.js +1 -1
  31. package/dist/data/utilities/parsers/findConditions.d.ts +15 -14
  32. package/dist/data/utilities/removeFromIndex.d.ts +14 -13
  33. package/dist/data/utilities/removeFromIndex.js +45 -43
  34. package/dist/data/utilities/removeFromIndex.min.js +1 -1
  35. package/dist/data/utilities/runQuery.js +112 -86
  36. package/dist/data/utilities/runQuery.min.js +1 -1
  37. package/dist/data/utilities/updateIndex.d.ts +17 -16
  38. package/dist/data/utilities/updateIndex.js +57 -55
  39. package/dist/data/utilities/updateIndex.min.js +1 -1
  40. package/dist/data/utilities/useJoinClause.js +56 -50
  41. package/dist/data/utilities/useJoinClause.min.js +1 -1
  42. package/package.json +6 -1
@@ -1,25 +1,29 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.foreignKeyExists = void 0;
7
- var _retrieveRecords = require("../../utilities/retrieveRecords");
8
- var _where = require("../../queries/where");
9
- /**
10
- * Check whether any record in the referenced entity has the given property set to the given
11
- * value - the mirror image of keyUnique(), which checks that no record already has a value.
12
- * @param entity
13
- * @param property
14
- * @param value
15
- */
16
- const foreignKeyExists = async (entity, property, value) => {
17
- const records = await (0, _retrieveRecords.retrieveRecords)(entity);
18
- const found = (0, _where.where)(records, {
19
- property,
20
- comparator: '=',
21
- value
22
- });
23
- return found.length > 0;
24
- };
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.foreignKeyExists = void 0;
7
+ var _retrieveRecords = require("../../utilities/retrieveRecords");
8
+ var _where = require("../../queries/where");
9
+ var _retrieveRecord = require("../../utilities/retrieveRecord");
10
+ var _fieldType = require("../../utilities/fieldType");
11
+ /**
12
+ * Check whether any record in the referenced entity has the given property set to the given
13
+ * value - the mirror image of keyUnique(), which checks that no record already has a value.
14
+ * @param entity
15
+ * @param property
16
+ * @param value
17
+ */
18
+ const foreignKeyExists = async (entity, property, value) => {
19
+ const records = await (0, _retrieveRecords.retrieveRecords)(entity);
20
+ const type = (0, _fieldType.fieldType)(await (0, _retrieveRecord.retrieveRecord)(entity), property);
21
+ const found = (0, _where.where)(records, {
22
+ property,
23
+ comparator: '=',
24
+ value,
25
+ type
26
+ });
27
+ return found.length > 0;
28
+ };
25
29
  exports.foreignKeyExists = foreignKeyExists;
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.foreignKeyExists=void 0;var _retrieveRecords=require("../../utilities/retrieveRecords"),_where=require("../../queries/where");const foreignKeyExists=async(e,r,t)=>{const s=await(0,_retrieveRecords.retrieveRecords)(e);return(0,_where.where)(s,{property:r,comparator:"=",value:t}).length>0};exports.foreignKeyExists=foreignKeyExists;
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.foreignKeyExists=void 0;var _retrieveRecords=require("../../utilities/retrieveRecords"),_where=require("../../queries/where"),_retrieveRecord=require("../../utilities/retrieveRecord"),_fieldType=require("../../utilities/fieldType");const foreignKeyExists=async(e,r,i)=>{const t=await(0,_retrieveRecords.retrieveRecords)(e),s=(0,_fieldType.fieldType)(await(0,_retrieveRecord.retrieveRecord)(e),r);return(0,_where.where)(t,{property:r,comparator:"=",value:i,type:s}).length>0};exports.foreignKeyExists=foreignKeyExists;
@@ -1,52 +1,54 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.hasDependents = void 0;
7
- var _describe = require("../describe");
8
- var _retrieveRecord = require("../../utilities/retrieveRecord");
9
- var _retrieveRecords = require("../../utilities/retrieveRecords");
10
- var _where = require("../../queries/where");
11
- var _splitEntityProperty = require("../../utilities/parsers/splitEntityProperty");
12
- /**
13
- * Check whether any other record, in any entity, still has a single-field foreign key pointing
14
- * at entity.property = value - the mirror image of foreignKeyExists(), which checks the opposite
15
- * direction (that a new/updated foreign key value points at something real). Used to RESTRICT a
16
- * delete or update that would otherwise leave a dangling reference behind. Scans every record in
17
- * the database via the __RECORDS registry, the same "no index needed, just look" approach as
18
- * keyUnique()/foreignKeyExists() - correctness over speed, matching this project's overall scale.
19
- * @param entity
20
- * @param property
21
- * @param value
22
- */
23
- const hasDependents = async (entity, property, value) => {
24
- const entityFiles = await (0, _describe.describe)();
25
- for (const entityFile of entityFiles) {
26
- const otherEntity = entityFile.replace(/\.json$/, '');
27
- const otherRecord = await (0, _retrieveRecord.retrieveRecord)(otherEntity);
28
- for (const key of otherRecord.keys) {
29
- if (key.type !== 'foreign' || key.fields.length !== 1 || !key.references || key.references.length !== 1) {
30
- continue;
31
- }
32
- const {
33
- entity: refEntity,
34
- property: refProperty
35
- } = (0, _splitEntityProperty.splitEntityProperty)(key.references[0].fields[0]);
36
- if (refEntity !== entity || refProperty !== property) {
37
- continue;
38
- }
39
- const records = await (0, _retrieveRecords.retrieveRecords)(otherEntity);
40
- const found = (0, _where.where)(records, {
41
- property: key.fields[0],
42
- comparator: '=',
43
- value
44
- });
45
- if (found.length) {
46
- return true;
47
- }
48
- }
49
- }
50
- return false;
51
- };
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.hasDependents = void 0;
7
+ var _describe = require("../describe");
8
+ var _retrieveRecord = require("../../utilities/retrieveRecord");
9
+ var _retrieveRecords = require("../../utilities/retrieveRecords");
10
+ var _where = require("../../queries/where");
11
+ var _fieldType = require("../../utilities/fieldType");
12
+ var _splitEntityProperty = require("../../utilities/parsers/splitEntityProperty");
13
+ /**
14
+ * Check whether any other record, in any entity, still has a single-field foreign key pointing
15
+ * at entity.property = value - the mirror image of foreignKeyExists(), which checks the opposite
16
+ * direction (that a new/updated foreign key value points at something real). Used to RESTRICT a
17
+ * delete or update that would otherwise leave a dangling reference behind. Scans every record in
18
+ * the database via the __RECORDS registry, the same "no index needed, just look" approach as
19
+ * keyUnique()/foreignKeyExists() - correctness over speed, matching this project's overall scale.
20
+ * @param entity
21
+ * @param property
22
+ * @param value
23
+ */
24
+ const hasDependents = async (entity, property, value) => {
25
+ const entityFiles = await (0, _describe.describe)();
26
+ for (const entityFile of entityFiles) {
27
+ const otherEntity = entityFile.replace(/\.json$/, '');
28
+ const otherRecord = await (0, _retrieveRecord.retrieveRecord)(otherEntity);
29
+ for (const key of otherRecord.keys) {
30
+ if (key.type !== 'foreign' || key.fields.length !== 1 || !key.references || key.references.length !== 1) {
31
+ continue;
32
+ }
33
+ const {
34
+ entity: refEntity,
35
+ property: refProperty
36
+ } = (0, _splitEntityProperty.splitEntityProperty)(key.references[0].fields[0]);
37
+ if (refEntity !== entity || refProperty !== property) {
38
+ continue;
39
+ }
40
+ const records = await (0, _retrieveRecords.retrieveRecords)(otherEntity);
41
+ const found = (0, _where.where)(records, {
42
+ property: key.fields[0],
43
+ comparator: '=',
44
+ value,
45
+ type: (0, _fieldType.fieldType)(otherRecord, key.fields[0])
46
+ });
47
+ if (found.length) {
48
+ return true;
49
+ }
50
+ }
51
+ }
52
+ return false;
53
+ };
52
54
  exports.hasDependents = hasDependents;
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.hasDependents=void 0;var _describe=require("../describe"),_retrieveRecord=require("../../utilities/retrieveRecord"),_retrieveRecords=require("../../utilities/retrieveRecords"),_where=require("../../queries/where"),_splitEntityProperty=require("../../utilities/parsers/splitEntityProperty");const hasDependents=async(e,r,t)=>{const i=await(0,_describe.describe)();for(const s of i){const i=s.replace(/\.json$/,""),o=await(0,_retrieveRecord.retrieveRecord)(i);for(const s of o.keys){if("foreign"!==s.type||1!==s.fields.length||!s.references||1!==s.references.length)continue;const{entity:o,property:n}=(0,_splitEntityProperty.splitEntityProperty)(s.references[0].fields[0]);if(o!==e||n!==r)continue;const c=await(0,_retrieveRecords.retrieveRecords)(i);if((0,_where.where)(c,{property:s.fields[0],comparator:"=",value:t}).length)return!0}}return!1};exports.hasDependents=hasDependents;
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.hasDependents=void 0;var _describe=require("../describe"),_retrieveRecord=require("../../utilities/retrieveRecord"),_retrieveRecords=require("../../utilities/retrieveRecords"),_where=require("../../queries/where"),_fieldType=require("../../utilities/fieldType"),_splitEntityProperty=require("../../utilities/parsers/splitEntityProperty");const hasDependents=async(e,r,t)=>{const i=await(0,_describe.describe)();for(const s of i){const i=s.replace(/\.json$/,""),o=await(0,_retrieveRecord.retrieveRecord)(i);for(const s of o.keys){if("foreign"!==s.type||1!==s.fields.length||!s.references||1!==s.references.length)continue;const{entity:n,property:c}=(0,_splitEntityProperty.splitEntityProperty)(s.references[0].fields[0]);if(n!==e||c!==r)continue;const p=await(0,_retrieveRecords.retrieveRecords)(i);if((0,_where.where)(p,{property:s.fields[0],comparator:"=",value:t,type:(0,_fieldType.fieldType)(o,s.fields[0])}).length)return!0}}return!1};exports.hasDependents=hasDependents;
@@ -1,31 +1,35 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.keyUnique = void 0;
7
- var _retrieveRecords = require("../../utilities/retrieveRecords");
8
- var _where = require("../../queries/where");
9
- /**
10
- * Check that no existing record already has this combination of values across all of the given
11
- * fields - a single field for a normal unique/primary key, or several for a composite one.
12
- * references and checkKeys are parallel arrays: references[i]'s value must equal checkKeys[i].
13
- * @param entity
14
- * @param references
15
- * @param checkKeys
16
- */
17
- const keyUnique = async (entity, references = [], checkKeys = []) => {
18
- if (!references.length || references.length !== checkKeys.length) {
19
- return false;
20
- }
21
- let records = await (0, _retrieveRecords.retrieveRecords)(entity);
22
- for (let i = 0; i < references.length; i++) {
23
- records = (0, _where.where)(records, {
24
- property: references[i],
25
- comparator: '=',
26
- value: checkKeys[i]
27
- });
28
- }
29
- return !records.length;
30
- };
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.keyUnique = void 0;
7
+ var _retrieveRecords = require("../../utilities/retrieveRecords");
8
+ var _where = require("../../queries/where");
9
+ var _retrieveRecord = require("../../utilities/retrieveRecord");
10
+ var _fieldType = require("../../utilities/fieldType");
11
+ /**
12
+ * Check that no existing record already has this combination of values across all of the given
13
+ * fields - a single field for a normal unique/primary key, or several for a composite one.
14
+ * references and checkKeys are parallel arrays: references[i]'s value must equal checkKeys[i].
15
+ * @param entity
16
+ * @param references
17
+ * @param checkKeys
18
+ */
19
+ const keyUnique = async (entity, references = [], checkKeys = []) => {
20
+ if (!references.length || references.length !== checkKeys.length) {
21
+ return false;
22
+ }
23
+ let records = await (0, _retrieveRecords.retrieveRecords)(entity);
24
+ const record = await (0, _retrieveRecord.retrieveRecord)(entity);
25
+ for (let i = 0; i < references.length; i++) {
26
+ records = (0, _where.where)(records, {
27
+ property: references[i],
28
+ comparator: '=',
29
+ value: checkKeys[i],
30
+ type: (0, _fieldType.fieldType)(record, references[i])
31
+ });
32
+ }
33
+ return !records.length;
34
+ };
31
35
  exports.keyUnique = keyUnique;
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.keyUnique=void 0;var _retrieveRecords=require("../../utilities/retrieveRecords"),_where=require("../../queries/where");const keyUnique=async(e,r=[],t=[])=>{if(!r.length||r.length!==t.length)return!1;let i=await(0,_retrieveRecords.retrieveRecords)(e);for(let e=0;e<r.length;e++)i=(0,_where.where)(i,{property:r[e],comparator:"=",value:t[e]});return!i.length};exports.keyUnique=keyUnique;
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.keyUnique=void 0;var _retrieveRecords=require("../../utilities/retrieveRecords"),_where=require("../../queries/where"),_retrieveRecord=require("../../utilities/retrieveRecord"),_fieldType=require("../../utilities/fieldType");const keyUnique=async(e,r=[],t=[])=>{if(!r.length||r.length!==t.length)return!1;let i=await(0,_retrieveRecords.retrieveRecords)(e);const o=await(0,_retrieveRecord.retrieveRecord)(e);for(let e=0;e<r.length;e++)i=(0,_where.where)(i,{property:r[e],comparator:"=",value:t[e],type:(0,_fieldType.fieldType)(o,r[e])});return!i.length};exports.keyUnique=keyUnique;
@@ -1,100 +1,101 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.deleteEntity = void 0;
7
- require("core-js/modules/es.json.stringify.js");
8
- require("core-js/modules/esnext.iterator.constructor.js");
9
- require("core-js/modules/esnext.iterator.find.js");
10
- require("core-js/modules/esnext.iterator.map.js");
11
- require("core-js/modules/esnext.set.add-all.js");
12
- require("core-js/modules/esnext.set.delete-all.js");
13
- require("core-js/modules/esnext.set.difference.js");
14
- require("core-js/modules/esnext.set.every.js");
15
- require("core-js/modules/esnext.set.filter.js");
16
- require("core-js/modules/esnext.set.find.js");
17
- require("core-js/modules/esnext.set.intersection.js");
18
- require("core-js/modules/esnext.set.is-disjoint-from.js");
19
- require("core-js/modules/esnext.set.is-subset-of.js");
20
- require("core-js/modules/esnext.set.is-superset-of.js");
21
- require("core-js/modules/esnext.set.join.js");
22
- require("core-js/modules/esnext.set.map.js");
23
- require("core-js/modules/esnext.set.reduce.js");
24
- require("core-js/modules/esnext.set.some.js");
25
- require("core-js/modules/esnext.set.symmetric-difference.js");
26
- require("core-js/modules/esnext.set.union.js");
27
- var _retrieveRecord = require("../utilities/retrieveRecord");
28
- var _retrieveFile = require("../utilities/retrieveFile");
29
- var _removeFromIndex = require("../utilities/removeFromIndex");
30
- var _computeKeyValue = require("../utilities/computeKeyValue");
31
- var _hasDependents = require("../introspect/policies/hasDependents");
32
- var _config = require("../utilities/config");
33
- const {
34
- rm,
35
- writeFile
36
- } = require('fs/promises');
37
- /**
38
- * RESTRICT: reject the whole delete (before removing anything) if any row being deleted is still
39
- * referenced by a single-field foreign key elsewhere. Only meaningful for a single-field primary
40
- * key, since foreign key support itself is single-field only - a composite primary key can't be
41
- * the target of one yet, so there's nothing to check.
42
- * @param entity
43
- * @param primaryKey
44
- * @param toDelete
45
- */
46
- const assertNoDependents = async (entity, primaryKey, toDelete) => {
47
- if (!(0, _config.getSetting)('enforceForeignKeys', true) || primaryKey.fields.length !== 1) {
48
- return;
49
- }
50
- const property = primaryKey.fields[0];
51
- for (const row of toDelete) {
52
- if (await (0, _hasDependents.hasDependents)(entity, property, row[property])) {
53
- throw new Error(`Cannot delete from "${entity}" where "${property}" = ${row[property]} - other records still reference it`);
54
- }
55
- }
56
- };
57
- /**
58
- * A record object carries no memory of which entry file it was read from, and files are not
59
- * guaranteed to be named after any field's value, so the only reliable way to find a record's
60
- * file is to re-scan every entry and match it by its primary key value(s) - a single field, or a
61
- * composite of several for a multi-field primary key.
62
- * @param entity
63
- * @param record
64
- * @param primaryKey
65
- * @param deletedValues
66
- */
67
- const removeMatchingEntries = async (entity, record, primaryKey, deletedValues) => {
68
- const databasePath = (0, _config.getSetting)('databasePath', 'database/');
69
- const remainingEntries = [];
70
- for (const fileName of record.entries) {
71
- const data = await (0, _retrieveFile.retrieveFile)(`${record.path}/${fileName}`);
72
- if (!deletedValues.has((0, _computeKeyValue.computeKeyValue)(primaryKey.fields, data))) {
73
- remainingEntries.push(fileName);
74
- continue;
75
- }
76
- await rm(`${databasePath}${record.path}/${fileName}`);
77
- for (const key of record.keys) {
78
- await (0, _removeFromIndex.removeFromIndex)(record.path, key, (0, _computeKeyValue.computeKeyValue)(key.fields, data), fileName);
79
- }
80
- }
81
- return remainingEntries;
82
- };
83
- const deleteEntity = async (entity = '', dataSet = {}) => {
84
- const databasePath = (0, _config.getSetting)('databasePath', 'database/');
85
- const record = await (0, _retrieveRecord.retrieveRecord)(entity);
86
- const primaryKey = record.keys.find(key => key.type === 'primary');
87
- if (!primaryKey) {
88
- throw new Error(`Cannot delete from "${entity}" without a primary key`);
89
- }
90
- const toDelete = dataSet[entity] || [];
91
- if (!toDelete.length) {
92
- return dataSet;
93
- }
94
- await assertNoDependents(entity, primaryKey, toDelete);
95
- const deletedValues = new Set(toDelete.map(row => (0, _computeKeyValue.computeKeyValue)(primaryKey.fields, row)));
96
- record.entries = await removeMatchingEntries(entity, record, primaryKey, deletedValues);
97
- await writeFile(`${databasePath}${record.path}.json`, JSON.stringify(record, null, 2));
98
- return dataSet;
99
- };
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.deleteEntity = void 0;
7
+ require("core-js/modules/es.json.stringify.js");
8
+ require("core-js/modules/esnext.iterator.constructor.js");
9
+ require("core-js/modules/esnext.iterator.find.js");
10
+ require("core-js/modules/esnext.iterator.map.js");
11
+ require("core-js/modules/esnext.set.add-all.js");
12
+ require("core-js/modules/esnext.set.delete-all.js");
13
+ require("core-js/modules/esnext.set.difference.js");
14
+ require("core-js/modules/esnext.set.every.js");
15
+ require("core-js/modules/esnext.set.filter.js");
16
+ require("core-js/modules/esnext.set.find.js");
17
+ require("core-js/modules/esnext.set.intersection.js");
18
+ require("core-js/modules/esnext.set.is-disjoint-from.js");
19
+ require("core-js/modules/esnext.set.is-subset-of.js");
20
+ require("core-js/modules/esnext.set.is-superset-of.js");
21
+ require("core-js/modules/esnext.set.join.js");
22
+ require("core-js/modules/esnext.set.map.js");
23
+ require("core-js/modules/esnext.set.reduce.js");
24
+ require("core-js/modules/esnext.set.some.js");
25
+ require("core-js/modules/esnext.set.symmetric-difference.js");
26
+ require("core-js/modules/esnext.set.union.js");
27
+ var _retrieveRecord = require("../utilities/retrieveRecord");
28
+ var _retrieveFile = require("../utilities/retrieveFile");
29
+ var _removeFromIndex = require("../utilities/removeFromIndex");
30
+ var _computeKeyValue = require("../utilities/computeKeyValue");
31
+ var _fieldType = require("../utilities/fieldType");
32
+ var _hasDependents = require("../introspect/policies/hasDependents");
33
+ var _config = require("../utilities/config");
34
+ const {
35
+ rm,
36
+ writeFile
37
+ } = require('fs/promises');
38
+ /**
39
+ * RESTRICT: reject the whole delete (before removing anything) if any row being deleted is still
40
+ * referenced by a single-field foreign key elsewhere. Only meaningful for a single-field primary
41
+ * key, since foreign key support itself is single-field only - a composite primary key can't be
42
+ * the target of one yet, so there's nothing to check.
43
+ * @param entity
44
+ * @param primaryKey
45
+ * @param toDelete
46
+ */
47
+ const assertNoDependents = async (entity, primaryKey, toDelete) => {
48
+ if (!(0, _config.getSetting)('enforceForeignKeys', true) || primaryKey.fields.length !== 1) {
49
+ return;
50
+ }
51
+ const property = primaryKey.fields[0];
52
+ for (const row of toDelete) {
53
+ if (await (0, _hasDependents.hasDependents)(entity, property, row[property])) {
54
+ throw new Error(`Cannot delete from "${entity}" where "${property}" = ${row[property]} - other records still reference it`);
55
+ }
56
+ }
57
+ };
58
+ /**
59
+ * A record object carries no memory of which entry file it was read from, and files are not
60
+ * guaranteed to be named after any field's value, so the only reliable way to find a record's
61
+ * file is to re-scan every entry and match it by its primary key value(s) - a single field, or a
62
+ * composite of several for a multi-field primary key.
63
+ * @param entity
64
+ * @param record
65
+ * @param primaryKey
66
+ * @param deletedValues
67
+ */
68
+ const removeMatchingEntries = async (entity, record, primaryKey, deletedValues) => {
69
+ const databasePath = (0, _config.getSetting)('databasePath', 'database/');
70
+ const remainingEntries = [];
71
+ for (const fileName of record.entries) {
72
+ const data = await (0, _retrieveFile.retrieveFile)(`${record.path}/${fileName}`);
73
+ if (!deletedValues.has((0, _computeKeyValue.computeKeyValue)(primaryKey.fields, data))) {
74
+ remainingEntries.push(fileName);
75
+ continue;
76
+ }
77
+ await rm(`${databasePath}${record.path}/${fileName}`);
78
+ for (const key of record.keys) {
79
+ await (0, _removeFromIndex.removeFromIndex)(record.path, key, (0, _computeKeyValue.computeKeyValue)(key.fields, data), fileName, (0, _fieldType.keyValueType)(record, key));
80
+ }
81
+ }
82
+ return remainingEntries;
83
+ };
84
+ const deleteEntity = async (entity = '', dataSet = {}) => {
85
+ const databasePath = (0, _config.getSetting)('databasePath', 'database/');
86
+ const record = await (0, _retrieveRecord.retrieveRecord)(entity);
87
+ const primaryKey = record.keys.find(key => key.type === 'primary');
88
+ if (!primaryKey) {
89
+ throw new Error(`Cannot delete from "${entity}" without a primary key`);
90
+ }
91
+ const toDelete = dataSet[entity] || [];
92
+ if (!toDelete.length) {
93
+ return dataSet;
94
+ }
95
+ await assertNoDependents(entity, primaryKey, toDelete);
96
+ const deletedValues = new Set(toDelete.map(row => (0, _computeKeyValue.computeKeyValue)(primaryKey.fields, row)));
97
+ record.entries = await removeMatchingEntries(entity, record, primaryKey, deletedValues);
98
+ await writeFile(`${databasePath}${record.path}.json`, JSON.stringify(record, null, 2));
99
+ return dataSet;
100
+ };
100
101
  exports.deleteEntity = deleteEntity;
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.deleteEntity=void 0,require("core-js/modules/es.json.stringify.js"),require("core-js/modules/esnext.iterator.constructor.js"),require("core-js/modules/esnext.iterator.find.js"),require("core-js/modules/esnext.iterator.map.js"),require("core-js/modules/esnext.set.add-all.js"),require("core-js/modules/esnext.set.delete-all.js"),require("core-js/modules/esnext.set.difference.js"),require("core-js/modules/esnext.set.every.js"),require("core-js/modules/esnext.set.filter.js"),require("core-js/modules/esnext.set.find.js"),require("core-js/modules/esnext.set.intersection.js"),require("core-js/modules/esnext.set.is-disjoint-from.js"),require("core-js/modules/esnext.set.is-subset-of.js"),require("core-js/modules/esnext.set.is-superset-of.js"),require("core-js/modules/esnext.set.join.js"),require("core-js/modules/esnext.set.map.js"),require("core-js/modules/esnext.set.reduce.js"),require("core-js/modules/esnext.set.some.js"),require("core-js/modules/esnext.set.symmetric-difference.js"),require("core-js/modules/esnext.set.union.js");var _retrieveRecord=require("../utilities/retrieveRecord"),_retrieveFile=require("../utilities/retrieveFile"),_removeFromIndex=require("../utilities/removeFromIndex"),_computeKeyValue=require("../utilities/computeKeyValue"),_hasDependents=require("../introspect/policies/hasDependents"),_config=require("../utilities/config");const{rm:rm,writeFile:writeFile}=require("fs/promises"),assertNoDependents=async(e,r,s)=>{if(!(0,_config.getSetting)("enforceForeignKeys",!0)||1!==r.fields.length)return;const t=r.fields[0];for(const r of s)if(await(0,_hasDependents.hasDependents)(e,t,r[t]))throw new Error(`Cannot delete from "${e}" where "${t}" = ${r[t]} - other records still reference it`)},removeMatchingEntries=async(e,r,s,t)=>{const i=(0,_config.getSetting)("databasePath","database/"),o=[];for(const e of r.entries){const n=await(0,_retrieveFile.retrieveFile)(`${r.path}/${e}`);if(t.has((0,_computeKeyValue.computeKeyValue)(s.fields,n))){await rm(`${i}${r.path}/${e}`);for(const s of r.keys)await(0,_removeFromIndex.removeFromIndex)(r.path,s,(0,_computeKeyValue.computeKeyValue)(s.fields,n),e)}else o.push(e)}return o},deleteEntity=async(e="",r={})=>{const s=(0,_config.getSetting)("databasePath","database/"),t=await(0,_retrieveRecord.retrieveRecord)(e),i=t.keys.find((e=>"primary"===e.type));if(!i)throw new Error(`Cannot delete from "${e}" without a primary key`);const o=r[e]||[];if(!o.length)return r;await assertNoDependents(e,i,o);const n=new Set(o.map((e=>(0,_computeKeyValue.computeKeyValue)(i.fields,e))));return t.entries=await removeMatchingEntries(0,t,i,n),await writeFile(`${s}${t.path}.json`,JSON.stringify(t,null,2)),r};exports.deleteEntity=deleteEntity;
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.deleteEntity=void 0,require("core-js/modules/es.json.stringify.js"),require("core-js/modules/esnext.iterator.constructor.js"),require("core-js/modules/esnext.iterator.find.js"),require("core-js/modules/esnext.iterator.map.js"),require("core-js/modules/esnext.set.add-all.js"),require("core-js/modules/esnext.set.delete-all.js"),require("core-js/modules/esnext.set.difference.js"),require("core-js/modules/esnext.set.every.js"),require("core-js/modules/esnext.set.filter.js"),require("core-js/modules/esnext.set.find.js"),require("core-js/modules/esnext.set.intersection.js"),require("core-js/modules/esnext.set.is-disjoint-from.js"),require("core-js/modules/esnext.set.is-subset-of.js"),require("core-js/modules/esnext.set.is-superset-of.js"),require("core-js/modules/esnext.set.join.js"),require("core-js/modules/esnext.set.map.js"),require("core-js/modules/esnext.set.reduce.js"),require("core-js/modules/esnext.set.some.js"),require("core-js/modules/esnext.set.symmetric-difference.js"),require("core-js/modules/esnext.set.union.js");var _retrieveRecord=require("../utilities/retrieveRecord"),_retrieveFile=require("../utilities/retrieveFile"),_removeFromIndex=require("../utilities/removeFromIndex"),_computeKeyValue=require("../utilities/computeKeyValue"),_fieldType=require("../utilities/fieldType"),_hasDependents=require("../introspect/policies/hasDependents"),_config=require("../utilities/config");const{rm:rm,writeFile:writeFile}=require("fs/promises"),assertNoDependents=async(e,r,s)=>{if(!(0,_config.getSetting)("enforceForeignKeys",!0)||1!==r.fields.length)return;const t=r.fields[0];for(const r of s)if(await(0,_hasDependents.hasDependents)(e,t,r[t]))throw new Error(`Cannot delete from "${e}" where "${t}" = ${r[t]} - other records still reference it`)},removeMatchingEntries=async(e,r,s,t)=>{const i=(0,_config.getSetting)("databasePath","database/"),o=[];for(const e of r.entries){const n=await(0,_retrieveFile.retrieveFile)(`${r.path}/${e}`);if(t.has((0,_computeKeyValue.computeKeyValue)(s.fields,n))){await rm(`${i}${r.path}/${e}`);for(const s of r.keys)await(0,_removeFromIndex.removeFromIndex)(r.path,s,(0,_computeKeyValue.computeKeyValue)(s.fields,n),e,(0,_fieldType.keyValueType)(r,s))}else o.push(e)}return o},deleteEntity=async(e="",r={})=>{const s=(0,_config.getSetting)("databasePath","database/"),t=await(0,_retrieveRecord.retrieveRecord)(e),i=t.keys.find((e=>"primary"===e.type));if(!i)throw new Error(`Cannot delete from "${e}" without a primary key`);const o=r[e]||[];if(!o.length)return r;await assertNoDependents(e,i,o);const n=new Set(o.map((e=>(0,_computeKeyValue.computeKeyValue)(i.fields,e))));return t.entries=await removeMatchingEntries(0,t,i,n),await writeFile(`${s}${t.path}.json`,JSON.stringify(t,null,2)),r};exports.deleteEntity=deleteEntity;