json-fs-query 0.1.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +41 -6
- package/browser/jsonFsQuery.js +28271 -0
- package/browser/jsonFsQuery.min.js +1 -0
- package/dist/data/introspect/create.js +6 -4
- package/dist/data/introspect/create.min.js +1 -1
- package/dist/data/introspect/drop.js +2 -2
- package/dist/data/introspect/drop.min.js +1 -1
- package/dist/data/introspect/policies/hasDependents.d.ts +13 -0
- package/dist/data/introspect/policies/hasDependents.js +52 -0
- package/dist/data/introspect/policies/hasDependents.min.js +1 -0
- package/dist/data/introspect/policies/keyGenerate.js +1 -1
- package/dist/data/introspect/policies/keyGenerate.min.js +1 -1
- package/dist/data/introspect/policies/keyUnique.d.ts +9 -1
- package/dist/data/introspect/policies/keyUnique.js +19 -9
- package/dist/data/introspect/policies/keyUnique.min.js +1 -1
- package/dist/data/queries/deleteEntity.js +36 -15
- package/dist/data/queries/deleteEntity.min.js +1 -1
- package/dist/data/queries/groupBy.js +22 -22
- package/dist/data/queries/groupBy.min.js +1 -1
- package/dist/data/queries/insertEntity.js +14 -12
- package/dist/data/queries/insertEntity.min.js +1 -1
- package/dist/data/queries/readEntity.js +1 -1
- package/dist/data/queries/readEntity.min.js +1 -1
- package/dist/data/queries/updateEntity.js +68 -42
- package/dist/data/queries/updateEntity.min.js +1 -1
- package/dist/data/queries/where.js +1 -1
- package/dist/data/queries/where.min.js +1 -1
- package/dist/data/utilities/computeKeyValue.d.ts +13 -0
- package/dist/data/utilities/computeKeyValue.js +26 -0
- package/dist/data/utilities/computeKeyValue.min.js +1 -0
- package/dist/data/utilities/config.d.ts +28 -0
- package/dist/data/utilities/config.js +45 -0
- package/dist/data/utilities/config.min.js +1 -0
- package/dist/data/utilities/deregisterRecord.js +2 -2
- package/dist/data/utilities/deregisterRecord.min.js +1 -1
- package/dist/data/utilities/getConditionIndexedList.js +1 -1
- package/dist/data/utilities/getConditionIndexedList.min.js +1 -1
- package/dist/data/utilities/getJoinIndexedList.js +2 -2
- package/dist/data/utilities/getJoinIndexedList.min.js +1 -1
- package/dist/data/utilities/getMatchingIndexes.js +2 -2
- package/dist/data/utilities/getMatchingIndexes.min.js +1 -1
- package/dist/data/utilities/matchIndexedJoins.js +2 -2
- package/dist/data/utilities/matchIndexedJoins.min.js +1 -1
- package/dist/data/utilities/reconcileJoin.js +26 -26
- package/dist/data/utilities/reconcileJoin.min.js +1 -1
- package/dist/data/utilities/reconcileJoins.js +26 -27
- package/dist/data/utilities/reconcileJoins.min.js +1 -1
- package/dist/data/utilities/registerRecord.js +2 -2
- package/dist/data/utilities/registerRecord.min.js +1 -1
- package/dist/data/utilities/removeFromIndex.js +2 -2
- package/dist/data/utilities/removeFromIndex.min.js +1 -1
- package/dist/data/utilities/restrictIndexedList.js +45 -45
- package/dist/data/utilities/restrictIndexedList.min.js +1 -1
- package/dist/data/utilities/retrieveFile.js +3 -3
- package/dist/data/utilities/retrieveFile.min.js +1 -1
- package/dist/data/utilities/retrieveIndexes.js +1 -1
- package/dist/data/utilities/retrieveIndexes.min.js +1 -1
- package/dist/data/utilities/updateIndex.js +2 -2
- package/dist/data/utilities/updateIndex.min.js +1 -1
- package/dist/data/utilities/useJoinClause.js +4 -4
- package/dist/data/utilities/useJoinClause.min.js +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +7 -0
- package/dist/index.min.js +1 -1
- package/package.json +11 -4
- package/.browserslistrc +0 -1
- package/.nvmrc +0 -1
- package/MAIN.md +0 -15
- package/babel.config.js +0 -3
- package/build-tools.config.json +0 -30
- package/gulpfile.mjs +0 -15
- package/src/data/introspect/create.test.js +0 -67
- package/src/data/introspect/create.ts +0 -29
- package/src/data/introspect/definitions/field.test.js +0 -23
- package/src/data/introspect/definitions/field.ts +0 -48
- package/src/data/introspect/definitions/key.test.js +0 -100
- package/src/data/introspect/definitions/key.ts +0 -64
- package/src/data/introspect/definitions/keyReference.test.js +0 -8
- package/src/data/introspect/definitions/keyReference.ts +0 -23
- package/src/data/introspect/definitions/record.ts +0 -42
- package/src/data/introspect/describe.test.js +0 -36
- package/src/data/introspect/describe.ts +0 -9
- package/src/data/introspect/drop.test.js +0 -77
- package/src/data/introspect/drop.ts +0 -20
- package/src/data/introspect/index.ts +0 -8
- package/src/data/introspect/policies/foreignKeyExists.test.js +0 -44
- package/src/data/introspect/policies/foreignKeyExists.ts +0 -15
- package/src/data/introspect/policies/keyGenerate.ts +0 -11
- package/src/data/introspect/policies/keyUnique.ts +0 -11
- package/src/data/introspect/policies/typeCheck.test.js +0 -84
- package/src/data/introspect/policies/typeCheck.ts +0 -49
- package/src/data/introspect/policies/typeEnum.ts +0 -6
- package/src/data/introspect/policies/useDefault.ts +0 -6
- package/src/data/queries/deleteEntity.test.js +0 -86
- package/src/data/queries/deleteEntity.ts +0 -56
- package/src/data/queries/groupBy.test.js +0 -135
- package/src/data/queries/groupBy.ts +0 -16
- package/src/data/queries/insertEntity.test.js +0 -156
- package/src/data/queries/insertEntity.ts +0 -113
- package/src/data/queries/joinEntity.test.js +0 -109
- package/src/data/queries/joinEntity.ts +0 -20
- package/src/data/queries/mergeJoins.test.js +0 -174
- package/src/data/queries/mergeJoins.ts +0 -13
- package/src/data/queries/parser.test.js +0 -343
- package/src/data/queries/parser.ts +0 -24
- package/src/data/queries/query.test.js +0 -233
- package/src/data/queries/query.ts +0 -12
- package/src/data/queries/readEntity.test.js +0 -85
- package/src/data/queries/readEntity.ts +0 -8
- package/src/data/queries/sortBy.test.js +0 -131
- package/src/data/queries/sortBy.ts +0 -18
- package/src/data/queries/updateEntity.test.js +0 -228
- package/src/data/queries/updateEntity.ts +0 -162
- package/src/data/queries/where.test.js +0 -129
- package/src/data/queries/where.ts +0 -54
- package/src/data/utilities/deregisterRecord.test.js +0 -26
- package/src/data/utilities/deregisterRecord.ts +0 -24
- package/src/data/utilities/getConditionIndexedList.ts +0 -43
- package/src/data/utilities/getJoinIndexedList.ts +0 -53
- package/src/data/utilities/getMatchingIndexes.ts +0 -21
- package/src/data/utilities/matchIndexedJoins.ts +0 -45
- package/src/data/utilities/mergeJoin.test.js +0 -102
- package/src/data/utilities/mergeJoin.ts +0 -28
- package/src/data/utilities/parsers/findCommand.ts +0 -25
- package/src/data/utilities/parsers/findConditions.test.js +0 -38
- package/src/data/utilities/parsers/findConditions.ts +0 -32
- package/src/data/utilities/parsers/findGroupBy.ts +0 -20
- package/src/data/utilities/parsers/findInsertValues.test.js +0 -26
- package/src/data/utilities/parsers/findInsertValues.ts +0 -32
- package/src/data/utilities/parsers/findJoinClauses.ts +0 -29
- package/src/data/utilities/parsers/findJoinEntity.ts +0 -20
- package/src/data/utilities/parsers/findLimit.ts +0 -20
- package/src/data/utilities/parsers/findMergeJoins.ts +0 -27
- package/src/data/utilities/parsers/findOffset.ts +0 -20
- package/src/data/utilities/parsers/findSelects.ts +0 -31
- package/src/data/utilities/parsers/findSortClauses.ts +0 -31
- package/src/data/utilities/parsers/findUpdateValues.test.js +0 -37
- package/src/data/utilities/parsers/findUpdateValues.ts +0 -32
- package/src/data/utilities/parsers/isEntityProperty.ts +0 -1
- package/src/data/utilities/parsers/parseLiteralValue.test.js +0 -41
- package/src/data/utilities/parsers/parseLiteralValue.ts +0 -29
- package/src/data/utilities/parsers/parseQuery.ts +0 -73
- package/src/data/utilities/parsers/removeFromQuery.ts +0 -1
- package/src/data/utilities/parsers/splitEntityProperty.test.js +0 -8
- package/src/data/utilities/parsers/splitEntityProperty.ts +0 -17
- package/src/data/utilities/parsers/splitQueries.test.js +0 -33
- package/src/data/utilities/parsers/splitQueries.ts +0 -4
- package/src/data/utilities/reconcileJoin.test.js +0 -38
- package/src/data/utilities/reconcileJoin.ts +0 -23
- package/src/data/utilities/reconcileJoins.test.js +0 -160
- package/src/data/utilities/reconcileJoins.ts +0 -15
- package/src/data/utilities/registerRecord.test.js +0 -44
- package/src/data/utilities/registerRecord.ts +0 -44
- package/src/data/utilities/removeFromIndex.test.js +0 -44
- package/src/data/utilities/removeFromIndex.ts +0 -34
- package/src/data/utilities/restrictIndexedList.ts +0 -38
- package/src/data/utilities/retrieveFile.test.js +0 -49
- package/src/data/utilities/retrieveFile.ts +0 -19
- package/src/data/utilities/retrieveIndexes.ts +0 -17
- package/src/data/utilities/retrieveRecord.ts +0 -3
- package/src/data/utilities/retrieveRecords.test.js +0 -223
- package/src/data/utilities/retrieveRecords.ts +0 -16
- package/src/data/utilities/runQuery.test.js +0 -88
- package/src/data/utilities/runQuery.ts +0 -75
- package/src/data/utilities/updateIndex.test.js +0 -44
- package/src/data/utilities/updateIndex.ts +0 -45
- package/src/data/utilities/useJoinClause.test.js +0 -94
- package/src/data/utilities/useJoinClause.ts +0 -44
- package/src/global.d.ts +0 -1
- package/src/index.test.js +0 -52
- package/src/index.ts +0 -17
- package/test-data/__RECORDS.json +0 -32
- package/test-data/__indexes/exercise_muscle/fk_exercise_id.json +0 -14
- package/test-data/__indexes/exercise_muscle/fk_muscle_id.json +0 -14
- package/test-data/__indexes/exercise_muscle/pk__id.json +0 -14
- package/test-data/__indexes/exercises/pk__id.json +0 -14
- package/test-data/__indexes/muscles/pk__id.json +0 -58
- package/test-data/__indexes/workouts/fk_exercise_id.json +0 -23
- package/test-data/__indexes/workouts/index_date.json +0 -18
- package/test-data/__indexes/workouts/pk__id.json +0 -26
- package/test-data/copyDatabase.ts +0 -64
- package/test-data/exercise_muscle/bench_press_pectorals.json +0 -6
- package/test-data/exercise_muscle/deadlift_hamstrings.json +0 -6
- package/test-data/exercise_muscle/squat_quadriceps.json +0 -6
- package/test-data/exercise_muscle.json +0 -69
- package/test-data/exercises/bench_press.json +0 -5
- package/test-data/exercises/deadlift.json +0 -5
- package/test-data/exercises/squat.json +0 -5
- package/test-data/exercises.json +0 -34
- package/test-data/muscles/abdominal.json +0 -6
- package/test-data/muscles/biceps.json +0 -6
- package/test-data/muscles/calves.json +0 -6
- package/test-data/muscles/deltoids.json +0 -6
- package/test-data/muscles/erector_spinae.json +0 -6
- package/test-data/muscles/forearms.json +0 -6
- package/test-data/muscles/gluteus_maximus.json +0 -6
- package/test-data/muscles/hamstrings.json +0 -6
- package/test-data/muscles/latissimus_dorsi.json +0 -6
- package/test-data/muscles/obliques.json +0 -6
- package/test-data/muscles/pectorals.json +0 -6
- package/test-data/muscles/quadriceps.json +0 -6
- package/test-data/muscles/trapezius.json +0 -6
- package/test-data/muscles/triceps.json +0 -6
- package/test-data/muscles.json +0 -50
- package/test-data/workouts/2024-06-02-001.json +0 -10
- package/test-data/workouts/2024-06-02-002.json +0 -10
- package/test-data/workouts/2024-06-02-003.json +0 -10
- package/test-data/workouts/2024-06-05-001.json +0 -10
- package/test-data/workouts/2024-06-05-002.json +0 -10
- package/test-data/workouts/2024-06-05-003.json +0 -10
- package/test-data/workouts.json +0 -84
- package/tsconfig.json +0 -15
|
@@ -7,67 +7,69 @@ exports.updateEntity = void 0
|
|
|
7
7
|
require('core-js/modules/es.json.stringify.js')
|
|
8
8
|
require('core-js/modules/esnext.iterator.constructor.js')
|
|
9
9
|
require('core-js/modules/esnext.iterator.find.js')
|
|
10
|
+
require('core-js/modules/esnext.iterator.map.js')
|
|
11
|
+
require('core-js/modules/esnext.iterator.some.js')
|
|
10
12
|
const _retrieveRecord = require('../utilities/retrieveRecord')
|
|
11
13
|
const _retrieveFile = require('../utilities/retrieveFile')
|
|
12
14
|
const _updateIndex = require('../utilities/updateIndex')
|
|
13
15
|
const _removeFromIndex = require('../utilities/removeFromIndex')
|
|
16
|
+
const _computeKeyValue = require('../utilities/computeKeyValue')
|
|
14
17
|
const _keyUnique = require('../introspect/policies/keyUnique')
|
|
15
18
|
const _typeCheck = require('../introspect/policies/typeCheck')
|
|
16
19
|
const _foreignKeyExists = require('../introspect/policies/foreignKeyExists')
|
|
20
|
+
const _hasDependents = require('../introspect/policies/hasDependents')
|
|
17
21
|
const _splitEntityProperty = require('../utilities/parsers/splitEntityProperty')
|
|
18
|
-
const
|
|
22
|
+
const _config = require('../utilities/config')
|
|
19
23
|
const {
|
|
20
24
|
writeFile
|
|
21
25
|
} = require('fs/promises')
|
|
22
26
|
/**
|
|
23
27
|
* Same reasoning as deleteEntity: a record object carries no memory of which entry file it came
|
|
24
|
-
* from, so re-scan entries[] and match by the record's own primary key value
|
|
28
|
+
* from, so re-scan entries[] and match by the record's own primary key value(s) - a single field,
|
|
29
|
+
* or a composite of several for a multi-field primary key.
|
|
25
30
|
* @param record
|
|
26
|
-
* @param
|
|
31
|
+
* @param primaryKey
|
|
27
32
|
* @param primaryValue
|
|
28
33
|
*/
|
|
29
|
-
const findEntryFile = async (record,
|
|
34
|
+
const findEntryFile = async (record, primaryKey, primaryValue) => {
|
|
30
35
|
for (const fileName of record.entries) {
|
|
31
36
|
const data = await (0, _retrieveFile.retrieveFile)(`${record.path}/${fileName}`)
|
|
32
|
-
if (data
|
|
37
|
+
if ((0, _computeKeyValue.computeKeyValue)(primaryKey.fields, data) == primaryValue) {
|
|
33
38
|
return fileName
|
|
34
39
|
}
|
|
35
40
|
}
|
|
36
41
|
return null
|
|
37
42
|
}
|
|
38
43
|
/**
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
44
|
+
* True if the update actually changes at least one of this key's fields - a key none of whose
|
|
45
|
+
* fields appear in newValues, or whose given values are all unchanged, doesn't need re-checking.
|
|
46
|
+
* @param key
|
|
47
|
+
* @param oldData
|
|
48
|
+
* @param newValues
|
|
49
|
+
*/
|
|
50
|
+
const keyFieldsChanged = (key, oldData, newValues) => key.fields.some(field => Object.prototype.hasOwnProperty.call(newValues, field) && newValues[field] != oldData[field])
|
|
51
|
+
/**
|
|
52
|
+
* Only check uniqueness for a primary/unique key (single-field, or composite) whose value is
|
|
53
|
+
* actually changing - checking an unchanged value would find the record's own existing entry and
|
|
54
|
+
* wrongly report it as a duplicate of itself.
|
|
42
55
|
* @param entity
|
|
43
56
|
* @param record
|
|
44
57
|
* @param oldData
|
|
58
|
+
* @param newData
|
|
45
59
|
* @param newValues
|
|
46
60
|
*/
|
|
47
|
-
const assertUniqueForUpdate = async (entity, record, oldData, newValues) => {
|
|
61
|
+
const assertUniqueForUpdate = async (entity, record, oldData, newData, newValues) => {
|
|
48
62
|
for (const key of record.keys) {
|
|
49
|
-
if (key.type !== 'primary' && key.type !== 'unique' || key
|
|
63
|
+
if (key.type !== 'primary' && key.type !== 'unique' || !keyFieldsChanged(key, oldData, newValues)) {
|
|
50
64
|
continue
|
|
51
65
|
}
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
continue
|
|
55
|
-
}
|
|
56
|
-
const isUnique = await (0, _keyUnique.keyUnique)(entity, key.fields, newValues[field])
|
|
66
|
+
const checkKeys = key.fields.map(field => newData[field])
|
|
67
|
+
const isUnique = await (0, _keyUnique.keyUnique)(entity, key.fields, checkKeys)
|
|
57
68
|
if (!isUnique) {
|
|
58
|
-
throw new Error(`Duplicate value for ${key.type} key "${
|
|
69
|
+
throw new Error(`Duplicate value for ${key.type} key "${key.fields.join(', ')}" on ${entity}`)
|
|
59
70
|
}
|
|
60
71
|
}
|
|
61
72
|
}
|
|
62
|
-
/**
|
|
63
|
-
* Move a single-field key's index entry from the old value to the new one wherever the update
|
|
64
|
-
* actually changed that field.
|
|
65
|
-
* @param record
|
|
66
|
-
* @param oldData
|
|
67
|
-
* @param newData
|
|
68
|
-
* @param newValues
|
|
69
|
-
* @param fileName
|
|
70
|
-
*/
|
|
71
73
|
/**
|
|
72
74
|
* Same "only if it actually changed" scoping as assertUniqueForUpdate: re-checking an unchanged
|
|
73
75
|
* foreign key value would re-validate a reference this update never touches, which could fail an
|
|
@@ -83,7 +85,7 @@ const assertForeignKeysForUpdate = async (entity, record, oldData, newValues) =>
|
|
|
83
85
|
continue
|
|
84
86
|
}
|
|
85
87
|
const field = key.fields[0]
|
|
86
|
-
if (!
|
|
88
|
+
if (!Object.prototype.hasOwnProperty.call(newValues, field) || newValues[field] == oldData[field]) {
|
|
87
89
|
continue
|
|
88
90
|
}
|
|
89
91
|
const {
|
|
@@ -96,17 +98,41 @@ const assertForeignKeysForUpdate = async (entity, record, oldData, newValues) =>
|
|
|
96
98
|
}
|
|
97
99
|
}
|
|
98
100
|
}
|
|
101
|
+
/**
|
|
102
|
+
* RESTRICT: reject an update that would change a single-field primary key's value while another
|
|
103
|
+
* entity's foreign key still points at the old one - that reference would otherwise be left
|
|
104
|
+
* dangling, since the row itself isn't gone, just re-keyed. Only meaningful for a single-field
|
|
105
|
+
* primary key, matching foreign key support's own single-field-only scope.
|
|
106
|
+
* @param entity
|
|
107
|
+
* @param primaryKey
|
|
108
|
+
* @param oldData
|
|
109
|
+
* @param newValues
|
|
110
|
+
*/
|
|
111
|
+
const assertNoDependentsForUpdate = async (entity, primaryKey, oldData, newValues) => {
|
|
112
|
+
if (!(0, _config.getSetting)('enforceForeignKeys', true) || primaryKey.fields.length !== 1 || !keyFieldsChanged(primaryKey, oldData, newValues)) {
|
|
113
|
+
return
|
|
114
|
+
}
|
|
115
|
+
const property = primaryKey.fields[0]
|
|
116
|
+
if (await (0, _hasDependents.hasDependents)(entity, property, oldData[property])) {
|
|
117
|
+
throw new Error(`Cannot update "${entity}" where "${property}" = ${oldData[property]} - other records still reference it`)
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Move a key's index entry (single-field, or a composite for a multi-field key) from the old
|
|
122
|
+
* value to the new one wherever the update actually changed one of its fields.
|
|
123
|
+
* @param record
|
|
124
|
+
* @param oldData
|
|
125
|
+
* @param newData
|
|
126
|
+
* @param newValues
|
|
127
|
+
* @param fileName
|
|
128
|
+
*/
|
|
99
129
|
const reconcileIndexes = async (record, oldData, newData, newValues, fileName) => {
|
|
100
130
|
for (const key of record.keys) {
|
|
101
|
-
if (key
|
|
102
|
-
continue
|
|
103
|
-
}
|
|
104
|
-
const field = key.fields[0]
|
|
105
|
-
if (!newValues.hasOwnProperty(field) || newValues[field] == oldData[field]) {
|
|
131
|
+
if (!keyFieldsChanged(key, oldData, newValues)) {
|
|
106
132
|
continue
|
|
107
133
|
}
|
|
108
|
-
await (0, _removeFromIndex.removeFromIndex)(record.path, key, oldData
|
|
109
|
-
await (0, _updateIndex.updateIndex)(record.path, key, newData
|
|
134
|
+
await (0, _removeFromIndex.removeFromIndex)(record.path, key, (0, _computeKeyValue.computeKeyValue)(key.fields, oldData), fileName)
|
|
135
|
+
await (0, _updateIndex.updateIndex)(record.path, key, (0, _computeKeyValue.computeKeyValue)(key.fields, newData), fileName)
|
|
110
136
|
}
|
|
111
137
|
}
|
|
112
138
|
const assertRequiredFields = (entity, record, newData) => {
|
|
@@ -127,32 +153,32 @@ const assertRequiredFields = (entity, record, newData) => {
|
|
|
127
153
|
const applyFieldTypes = (record, values) => {
|
|
128
154
|
const typedValues = Object.assign({}, values)
|
|
129
155
|
for (const field of record.definition) {
|
|
130
|
-
if (
|
|
156
|
+
if (Object.prototype.hasOwnProperty.call(typedValues, field.name)) {
|
|
131
157
|
typedValues[field.name] = (0, _typeCheck.typeCheck)(field.type, typedValues[field.name])
|
|
132
158
|
}
|
|
133
159
|
}
|
|
134
160
|
return typedValues
|
|
135
161
|
}
|
|
136
162
|
const updateEntity = async (entity = '', values = {}, dataSet = {}) => {
|
|
137
|
-
const databasePath =
|
|
163
|
+
const databasePath = (0, _config.getSetting)('databasePath', 'database/')
|
|
138
164
|
const record = await (0, _retrieveRecord.retrieveRecord)(entity)
|
|
139
|
-
const primaryKey = record.keys.find(key => key.type === 'primary'
|
|
165
|
+
const primaryKey = record.keys.find(key => key.type === 'primary')
|
|
140
166
|
if (!primaryKey) {
|
|
141
|
-
throw new Error(`Cannot update "${entity}" without a
|
|
167
|
+
throw new Error(`Cannot update "${entity}" without a primary key`)
|
|
142
168
|
}
|
|
143
|
-
const primaryField = primaryKey.fields[0]
|
|
144
169
|
const typedValues = applyFieldTypes(record, values)
|
|
145
170
|
const toUpdate = dataSet[entity] || []
|
|
146
171
|
const updatedRows = []
|
|
147
172
|
for (const row of toUpdate) {
|
|
148
|
-
const fileName = await findEntryFile(record,
|
|
173
|
+
const fileName = await findEntryFile(record, primaryKey, (0, _computeKeyValue.computeKeyValue)(primaryKey.fields, row))
|
|
149
174
|
if (!fileName) {
|
|
150
|
-
throw new Error(`Could not find entry for ${entity} where "${
|
|
175
|
+
throw new Error(`Could not find entry for ${entity} where "${primaryKey.fields.join(', ')}" = ${(0, _computeKeyValue.computeKeyValue)(primaryKey.fields, row)}`)
|
|
151
176
|
}
|
|
152
177
|
const oldData = await (0, _retrieveFile.retrieveFile)(`${record.path}/${fileName}`)
|
|
153
|
-
await assertUniqueForUpdate(entity, record, oldData, typedValues)
|
|
154
|
-
await assertForeignKeysForUpdate(entity, record, oldData, typedValues)
|
|
155
178
|
const newData = Object.assign({}, oldData, typedValues)
|
|
179
|
+
await assertUniqueForUpdate(entity, record, oldData, newData, typedValues)
|
|
180
|
+
await assertForeignKeysForUpdate(entity, record, oldData, typedValues)
|
|
181
|
+
await assertNoDependentsForUpdate(entity, primaryKey, oldData, typedValues)
|
|
156
182
|
assertRequiredFields(entity, record, newData)
|
|
157
183
|
await reconcileIndexes(record, oldData, newData, typedValues, fileName)
|
|
158
184
|
await writeFile(`${databasePath}${record.path}/${fileName}`, JSON.stringify(newData, null, 2))
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.updateEntity=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");var _retrieveRecord=require("../utilities/retrieveRecord"),_retrieveFile=require("../utilities/retrieveFile"),_updateIndex=require("../utilities/updateIndex"),_removeFromIndex=require("../utilities/removeFromIndex"),_keyUnique=require("../introspect/policies/keyUnique"),_typeCheck=require("../introspect/policies/typeCheck"),_foreignKeyExists=require("../introspect/policies/foreignKeyExists"),_splitEntityProperty=require("../utilities/parsers/splitEntityProperty")
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.updateEntity=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.iterator.some.js");var _retrieveRecord=require("../utilities/retrieveRecord"),_retrieveFile=require("../utilities/retrieveFile"),_updateIndex=require("../utilities/updateIndex"),_removeFromIndex=require("../utilities/removeFromIndex"),_computeKeyValue=require("../utilities/computeKeyValue"),_keyUnique=require("../introspect/policies/keyUnique"),_typeCheck=require("../introspect/policies/typeCheck"),_foreignKeyExists=require("../introspect/policies/foreignKeyExists"),_hasDependents=require("../introspect/policies/hasDependents"),_splitEntityProperty=require("../utilities/parsers/splitEntityProperty"),_config=require("../utilities/config");const{writeFile:writeFile}=require("fs/promises"),findEntryFile=async(e,t,r)=>{for(const i of e.entries){const s=await(0,_retrieveFile.retrieveFile)(`${e.path}/${i}`);if((0,_computeKeyValue.computeKeyValue)(t.fields,s)==r)return i}return null},keyFieldsChanged=(e,t,r)=>e.fields.some((e=>Object.prototype.hasOwnProperty.call(r,e)&&r[e]!=t[e])),assertUniqueForUpdate=async(e,t,r,i,s)=>{for(const o of t.keys){if("primary"!==o.type&&"unique"!==o.type||!keyFieldsChanged(o,r,s))continue;const t=o.fields.map((e=>i[e]));if(!await(0,_keyUnique.keyUnique)(e,o.fields,t))throw new Error(`Duplicate value for ${o.type} key "${o.fields.join(", ")}" on ${e}`)}},assertForeignKeysForUpdate=async(e,t,r,i)=>{for(const s of t.keys){if("foreign"!==s.type||1!==s.fields.length||!s.references||1!==s.references.length)continue;const t=s.fields[0];if(!Object.prototype.hasOwnProperty.call(i,t)||i[t]==r[t])continue;const{entity:o,property:n}=(0,_splitEntityProperty.splitEntityProperty)(s.references[0].fields[0]);if(!await(0,_foreignKeyExists.foreignKeyExists)(o,n,i[t]))throw new Error(`Foreign key "${t}" on ${e} references a nonexistent ${o}.${n} = ${i[t]}`)}},assertNoDependentsForUpdate=async(e,t,r,i)=>{if(!(0,_config.getSetting)("enforceForeignKeys",!0)||1!==t.fields.length||!keyFieldsChanged(t,r,i))return;const s=t.fields[0];if(await(0,_hasDependents.hasDependents)(e,s,r[s]))throw new Error(`Cannot update "${e}" where "${s}" = ${r[s]} - other records still reference it`)},reconcileIndexes=async(e,t,r,i,s)=>{for(const o of e.keys)keyFieldsChanged(o,t,i)&&(await(0,_removeFromIndex.removeFromIndex)(e.path,o,(0,_computeKeyValue.computeKeyValue)(o.fields,t),s),await(0,_updateIndex.updateIndex)(e.path,o,(0,_computeKeyValue.computeKeyValue)(o.fields,r),s))},assertRequiredFields=(e,t,r)=>{for(const i of t.definition)if(!i.optional&&void 0===r[i.name])throw new Error(`Missing required field "${i.name}" for ${e}`)},applyFieldTypes=(e,t)=>{const r=Object.assign({},t);for(const t of e.definition)Object.prototype.hasOwnProperty.call(r,t.name)&&(r[t.name]=(0,_typeCheck.typeCheck)(t.type,r[t.name]));return r},updateEntity=async(e="",t={},r={})=>{const i=(0,_config.getSetting)("databasePath","database/"),s=await(0,_retrieveRecord.retrieveRecord)(e),o=s.keys.find((e=>"primary"===e.type));if(!o)throw new Error(`Cannot update "${e}" without a primary key`);const n=applyFieldTypes(s,t),a=r[e]||[],p=[];for(const t of a){const r=await findEntryFile(s,o,(0,_computeKeyValue.computeKeyValue)(o.fields,t));if(!r)throw new Error(`Could not find entry for ${e} where "${o.fields.join(", ")}" = ${(0,_computeKeyValue.computeKeyValue)(o.fields,t)}`);const a=await(0,_retrieveFile.retrieveFile)(`${s.path}/${r}`),u=Object.assign({},a,n);await assertUniqueForUpdate(e,s,a,u,n),await assertForeignKeysForUpdate(e,s,a,n),await assertNoDependentsForUpdate(e,o,a,n),assertRequiredFields(e,s,u),await reconcileIndexes(s,a,u,n,r),await writeFile(`${i}${s.path}/${r}`,JSON.stringify(u,null,2)),p.push(u)}return r[e]=p,r};exports.updateEntity=updateEntity;
|
|
@@ -15,7 +15,7 @@ const likeMatch = (dataValue, pattern) => {
|
|
|
15
15
|
return new RegExp(`^${regexPattern}$`, 'i').test(dataValue)
|
|
16
16
|
}
|
|
17
17
|
const makeCondition = (data, property, comparator, value) => {
|
|
18
|
-
if (!
|
|
18
|
+
if (!Object.prototype.hasOwnProperty.call(data, property)) {
|
|
19
19
|
return false
|
|
20
20
|
}
|
|
21
21
|
const dataValue = data[property]
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.where=void 0,require("core-js/modules/es.array.includes.js"),require("core-js/modules/esnext.iterator.constructor.js"),require("core-js/modules/esnext.iterator.filter.js");const likeMatch=(e,r)=>{if("string"!=typeof e||"string"!=typeof r)return!1;const t=r.replace(/[.*+?^${}()|[\]\\]/g,"\\$&").replace(/%/g,".*").replace(/_/g,".");return new RegExp(`^${t}$`,"i").test(e)},makeCondition=(e,r,t,s)=>{if(!
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.where=void 0,require("core-js/modules/es.array.includes.js"),require("core-js/modules/esnext.iterator.constructor.js"),require("core-js/modules/esnext.iterator.filter.js");const likeMatch=(e,r)=>{if("string"!=typeof e||"string"!=typeof r)return!1;const t=r.replace(/[.*+?^${}()|[\]\\]/g,"\\$&").replace(/%/g,".*").replace(/_/g,".");return new RegExp(`^${t}$`,"i").test(e)},makeCondition=(e,r,t,s)=>{if(!Object.prototype.hasOwnProperty.call(e,r))return!1;const n=e[r];switch(t){case"=":return n==s;case"!=":case"<>":return n!=s;case">":return n>s;case">=":return n>=s;case"<":return n<s;case"<=":return n<=s;case"in":return Array.isArray(s)&&s.includes(n);case"between":return Array.isArray(s)&&2===s.length&&n>=s[0]&&n<=s[1];case"like":return likeMatch(n,s)}return!1},where=(e=[],{property:r="",joinEntity:t,comparator:s="=",value:n=null}={})=>e.filter((e=>makeCondition(e,t?`${t}.${r}`:r,s,n)));exports.where=where;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { fieldName } from '../introspect/definitions/field';
|
|
2
|
+
/**
|
|
3
|
+
* The value a key (of any field count) indexes and checks uniqueness by. A single-field key uses
|
|
4
|
+
* the field's own raw value directly - this is the pre-existing, already-shipped index file
|
|
5
|
+
* format (e.g. a plain "2024-06-02" or 1), and stays exactly as it was for backward compatibility
|
|
6
|
+
* with real fixture data. A multi-field key has no single value to use, so its fields' values are
|
|
7
|
+
* combined into one deterministic composite (a JSON array), in the same field order as key.fields
|
|
8
|
+
* - two records only share a composite value if every field matches.
|
|
9
|
+
* @param fields
|
|
10
|
+
* @param values
|
|
11
|
+
*/
|
|
12
|
+
export declare const computeKeyValue: (fields: fieldName[], values: Object) => any;
|
|
13
|
+
//# sourceMappingURL=computeKeyValue.d.ts.map
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', {
|
|
4
|
+
value: true
|
|
5
|
+
})
|
|
6
|
+
exports.computeKeyValue = 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.map.js')
|
|
10
|
+
/**
|
|
11
|
+
* The value a key (of any field count) indexes and checks uniqueness by. A single-field key uses
|
|
12
|
+
* the field's own raw value directly - this is the pre-existing, already-shipped index file
|
|
13
|
+
* format (e.g. a plain "2024-06-02" or 1), and stays exactly as it was for backward compatibility
|
|
14
|
+
* with real fixture data. A multi-field key has no single value to use, so its fields' values are
|
|
15
|
+
* combined into one deterministic composite (a JSON array), in the same field order as key.fields
|
|
16
|
+
* - two records only share a composite value if every field matches.
|
|
17
|
+
* @param fields
|
|
18
|
+
* @param values
|
|
19
|
+
*/
|
|
20
|
+
const computeKeyValue = (fields, values) => {
|
|
21
|
+
if (fields.length === 1) {
|
|
22
|
+
return values[fields[0]]
|
|
23
|
+
}
|
|
24
|
+
return JSON.stringify(fields.map(field => values[field]))
|
|
25
|
+
}
|
|
26
|
+
exports.computeKeyValue = computeKeyValue
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.computeKeyValue=void 0,require("core-js/modules/es.json.stringify.js"),require("core-js/modules/esnext.iterator.constructor.js"),require("core-js/modules/esnext.iterator.map.js");const computeKeyValue=(e,r)=>1===e.length?r[e[0]]:JSON.stringify(e.map((e=>r[e])));exports.computeKeyValue=computeKeyValue;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export type RuntimeSettings = {
|
|
2
|
+
databasePath: string;
|
|
3
|
+
relativePath: string;
|
|
4
|
+
enforceForeignKeys: boolean;
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* Set where this package's data lives: databasePath (a filesystem path, used in Node) and/or
|
|
8
|
+
* relativePath (a URL prefix prepended to databasePath, used when reading over fetch() in a
|
|
9
|
+
* browser). Call this once before using create()/drop()/query() - a fresh consumer has no other
|
|
10
|
+
* way to point this package at their own data directory.
|
|
11
|
+
*
|
|
12
|
+
* enforceForeignKeys (default true) controls whether deleteEntity/updateEntity block an operation
|
|
13
|
+
* that would leave another record's foreign key pointing at a value that no longer exists -
|
|
14
|
+
* mirroring MySQL's own foreign_key_checks setting, which is also toggleable rather than always
|
|
15
|
+
* on, since strict enforcement isn't always what every consumer wants.
|
|
16
|
+
* @param newSettings
|
|
17
|
+
*/
|
|
18
|
+
export declare const configure: (newSettings: Partial<RuntimeSettings>) => void;
|
|
19
|
+
/**
|
|
20
|
+
* Read one runtime setting, falling back to the given default if it was never configured. This is
|
|
21
|
+
* the package's own lightweight replacement for reading settings via js-build-tools/gulp.config -
|
|
22
|
+
* that module is a dev-time build tool, not something a published package should require at
|
|
23
|
+
* runtime, and it isn't available at all once a consumer installs this package on its own.
|
|
24
|
+
* @param key
|
|
25
|
+
* @param defaultValue
|
|
26
|
+
*/
|
|
27
|
+
export declare const getSetting: <K extends keyof RuntimeSettings>(key: K, defaultValue: RuntimeSettings[K]) => RuntimeSettings[K];
|
|
28
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', {
|
|
4
|
+
value: true
|
|
5
|
+
})
|
|
6
|
+
exports.getSetting = exports.configure = void 0
|
|
7
|
+
const defaults = {
|
|
8
|
+
databasePath: 'database/',
|
|
9
|
+
relativePath: '',
|
|
10
|
+
enforceForeignKeys: true
|
|
11
|
+
}
|
|
12
|
+
let settings = {
|
|
13
|
+
...defaults
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Set where this package's data lives: databasePath (a filesystem path, used in Node) and/or
|
|
17
|
+
* relativePath (a URL prefix prepended to databasePath, used when reading over fetch() in a
|
|
18
|
+
* browser). Call this once before using create()/drop()/query() - a fresh consumer has no other
|
|
19
|
+
* way to point this package at their own data directory.
|
|
20
|
+
*
|
|
21
|
+
* enforceForeignKeys (default true) controls whether deleteEntity/updateEntity block an operation
|
|
22
|
+
* that would leave another record's foreign key pointing at a value that no longer exists -
|
|
23
|
+
* mirroring MySQL's own foreign_key_checks setting, which is also toggleable rather than always
|
|
24
|
+
* on, since strict enforcement isn't always what every consumer wants.
|
|
25
|
+
* @param newSettings
|
|
26
|
+
*/
|
|
27
|
+
const configure = newSettings => {
|
|
28
|
+
settings = {
|
|
29
|
+
...settings,
|
|
30
|
+
...newSettings
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Read one runtime setting, falling back to the given default if it was never configured. This is
|
|
35
|
+
* the package's own lightweight replacement for reading settings via js-build-tools/gulp.config -
|
|
36
|
+
* that module is a dev-time build tool, not something a published package should require at
|
|
37
|
+
* runtime, and it isn't available at all once a consumer installs this package on its own.
|
|
38
|
+
* @param key
|
|
39
|
+
* @param defaultValue
|
|
40
|
+
*/
|
|
41
|
+
exports.configure = configure
|
|
42
|
+
const getSetting = (key, defaultValue) => {
|
|
43
|
+
return typeof settings[key] !== 'undefined' ? settings[key] : defaultValue
|
|
44
|
+
}
|
|
45
|
+
exports.getSetting = getSetting
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.getSetting=exports.configure=void 0;const defaults={databasePath:"database/",relativePath:"",enforceForeignKeys:!0};let settings={...defaults};const configure=t=>{settings={...settings,...t}};exports.configure=configure;const getSetting=(t,e)=>void 0!==settings[t]?settings[t]:e;exports.getSetting=getSetting;
|
|
@@ -7,7 +7,7 @@ exports.deregisterRecord = void 0
|
|
|
7
7
|
require('core-js/modules/es.json.stringify.js')
|
|
8
8
|
require('core-js/modules/esnext.iterator.constructor.js')
|
|
9
9
|
require('core-js/modules/esnext.iterator.filter.js')
|
|
10
|
-
const
|
|
10
|
+
const _config = require('./config')
|
|
11
11
|
const {
|
|
12
12
|
readFile,
|
|
13
13
|
writeFile
|
|
@@ -18,7 +18,7 @@ const {
|
|
|
18
18
|
* @param recordName
|
|
19
19
|
*/
|
|
20
20
|
const deregisterRecord = async recordName => {
|
|
21
|
-
const databasePath =
|
|
21
|
+
const databasePath = (0, _config.getSetting)('databasePath', 'database/')
|
|
22
22
|
const registryPath = `${databasePath}__RECORDS.json`
|
|
23
23
|
let registry
|
|
24
24
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.deregisterRecord=void 0,require("core-js/modules/es.json.stringify.js"),require("core-js/modules/esnext.iterator.constructor.js"),require("core-js/modules/esnext.iterator.filter.js");
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.deregisterRecord=void 0,require("core-js/modules/es.json.stringify.js"),require("core-js/modules/esnext.iterator.constructor.js"),require("core-js/modules/esnext.iterator.filter.js");var _config=require("./config");const{readFile:readFile,writeFile:writeFile}=require("fs/promises"),deregisterRecord=async e=>{const r=`${(0,_config.getSetting)("databasePath","database/")}__RECORDS.json`;let t;try{t=JSON.parse(await readFile(r,"utf8"))}catch(e){return null}const s=`${e}.json`;return t.entries=t.entries.filter((e=>e!==s)),await writeFile(r,JSON.stringify(t,null,2)),t};exports.deregisterRecord=deregisterRecord;
|
|
@@ -20,7 +20,7 @@ const getConditionIndexedList = async (parsed, recordData, dataSet) => {
|
|
|
20
20
|
entity = entityProperty.entity
|
|
21
21
|
property = entityProperty.property
|
|
22
22
|
}
|
|
23
|
-
if (!
|
|
23
|
+
if (!Object.prototype.hasOwnProperty.call(recordData, entity)) {
|
|
24
24
|
recordData[entity] = await (0, _retrieveRecord.retrieveRecord)(entity)
|
|
25
25
|
}
|
|
26
26
|
const indexed = {}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.getConditionIndexedList=void 0;var _isEntityProperty=require("./parsers/isEntityProperty"),_splitEntityProperty=require("./parsers/splitEntityProperty"),_retrieveRecord=require("./retrieveRecord"),_where=require("../queries/where"),_retrieveFile=require("./retrieveFile"),_getMatchingIndexes=require("./getMatchingIndexes");const getConditionIndexedList=async(e,t,r)=>{let i=[];for(let o of e.conditions){let n=e.entity,s=o.property;if((0,_isEntityProperty.isEntityProperty)(s)){const e=(0,_splitEntityProperty.splitEntityProperty)(s);n=e.entity,s=e.property}
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.getConditionIndexedList=void 0;var _isEntityProperty=require("./parsers/isEntityProperty"),_splitEntityProperty=require("./parsers/splitEntityProperty"),_retrieveRecord=require("./retrieveRecord"),_where=require("../queries/where"),_retrieveFile=require("./retrieveFile"),_getMatchingIndexes=require("./getMatchingIndexes");const getConditionIndexedList=async(e,t,r)=>{let i=[];for(let o of e.conditions){let n=e.entity,s=o.property;if((0,_isEntityProperty.isEntityProperty)(s)){const e=(0,_splitEntityProperty.splitEntityProperty)(s);n=e.entity,s=e.property}Object.prototype.hasOwnProperty.call(t,n)||(t[n]=await(0,_retrieveRecord.retrieveRecord)(n));const p={},d=async(e,t,r,i,o,n)=>{const s=(0,_where.where)(n[e][t],{property:"value",comparator:i.comparator,value:i.value});for(let t of s)for(let r of t.record)o[e].push(await(0,_retrieveFile.retrieveFile)(`${e}/${r}`))};await(0,_getMatchingIndexes.getMatchingIndexes)(n,s,t,o,r,p,d)||i.push(o)}return e.conditions=i,e};exports.getConditionIndexedList=getConditionIndexedList;
|
|
@@ -34,10 +34,10 @@ const getJoinIndexedList = async (parsed, recordData, dataSets) => {
|
|
|
34
34
|
property: propertyB
|
|
35
35
|
} = (0, _splitEntityProperty.splitEntityProperty)(joinClause.propertyB)
|
|
36
36
|
// Get the record for the entities A and B, store on the recordData
|
|
37
|
-
if (!
|
|
37
|
+
if (!Object.prototype.hasOwnProperty.call(recordData, entityA)) {
|
|
38
38
|
recordData[entityA] = await (0, _retrieveRecord.retrieveRecord)(entityA)
|
|
39
39
|
}
|
|
40
|
-
if (!
|
|
40
|
+
if (!Object.prototype.hasOwnProperty.call(recordData, entityB)) {
|
|
41
41
|
recordData[entityB] = await (0, _retrieveRecord.retrieveRecord)(entityB)
|
|
42
42
|
}
|
|
43
43
|
indexedClone = (0, _restrictIndexedList.restrictIndexedList)(joinClause, filterJoins, indexedClone)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.getJoinIndexedList=void 0;var _siFunciona=_interopRequireDefault(require("si-funciona")),_splitEntityProperty=require("./parsers/splitEntityProperty"),_retrieveRecord=require("./retrieveRecord"),_getMatchingIndexes=require("./getMatchingIndexes"),_matchIndexedJoins=require("./matchIndexedJoins"),_restrictIndexedList=require("./restrictIndexedList");function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}const getJoinIndexedList=async(e,t,r)=>{let i=[];const n={};let
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.getJoinIndexedList=void 0;var _siFunciona=_interopRequireDefault(require("si-funciona")),_splitEntityProperty=require("./parsers/splitEntityProperty"),_retrieveRecord=require("./retrieveRecord"),_getMatchingIndexes=require("./getMatchingIndexes"),_matchIndexedJoins=require("./matchIndexedJoins"),_restrictIndexedList=require("./restrictIndexedList");function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}const getJoinIndexedList=async(e,t,r)=>{let i=[];const n={};let o=!0;const s=e.entity,c=e.joinEntity,d=e.joinClauses;for(const e in r[s]){const a=r[s][e];let p={};p[s]=[_siFunciona.default.cloneObject(a)];for(let e of d){let c=_siFunciona.default.cloneObject(n);const{entity:d,property:a}=(0,_splitEntityProperty.splitEntityProperty)(e.propertyA),{entity:l,property:u}=(0,_splitEntityProperty.splitEntityProperty)(e.propertyB);Object.prototype.hasOwnProperty.call(t,d)||(t[d]=await(0,_retrieveRecord.retrieveRecord)(d)),Object.prototype.hasOwnProperty.call(t,l)||(t[l]=await(0,_retrieveRecord.retrieveRecord)(l)),c=(0,_restrictIndexedList.restrictIndexedList)(e,p,c);const y=(0,_matchIndexedJoins.matchIndexedJoins)(s,c,r),_=await(0,_getMatchingIndexes.getMatchingIndexes)(d,a,t,e,p,n),x=await(0,_getMatchingIndexes.getMatchingIndexes)(l,u,t,e,p,n,y);!(_||x)&&o&&(i.push(e),o=!1)}r[s][e][c]=p[c]}return e.joinClauses=i,e};exports.getJoinIndexedList=getJoinIndexedList;
|
|
@@ -11,10 +11,10 @@ const getMatchingIndexes = async (entity, property, recordData, clause, dataSet,
|
|
|
11
11
|
for (const key of recordData[entity].keys) {
|
|
12
12
|
if (key.fields.includes(property)) {
|
|
13
13
|
dataSet[entity] = []
|
|
14
|
-
if (!
|
|
14
|
+
if (!Object.prototype.hasOwnProperty.call(indexed, entity)) {
|
|
15
15
|
indexed[entity] = {}
|
|
16
16
|
}
|
|
17
|
-
if (!indexed[entity]
|
|
17
|
+
if (!Object.prototype.hasOwnProperty.call(indexed[entity], property)) {
|
|
18
18
|
indexed[entity][property] = (await (0, _retrieveIndexes.retrieveIndexes)(entity, [property], recordData))[property]
|
|
19
19
|
}
|
|
20
20
|
if (typeof cb === 'function') {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.getMatchingIndexes=void 0,require("core-js/modules/es.array.includes.js");var _retrieveIndexes=require("./retrieveIndexes");const getMatchingIndexes=async(e,r,
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.getMatchingIndexes=void 0,require("core-js/modules/es.array.includes.js");var _retrieveIndexes=require("./retrieveIndexes");const getMatchingIndexes=async(e,t,r,s,n,i,o=null)=>{let a=!1;for(let c of r[e].keys)c.fields.includes(t)&&(n[e]=[],Object.prototype.hasOwnProperty.call(i,e)||(i[e]={}),Object.prototype.hasOwnProperty.call(i[e],t)||(i[e][t]=(await(0,_retrieveIndexes.retrieveIndexes)(e,[t],r))[t]),"function"==typeof o&&await o(e,t,r,s,n,i),a=!0);return a};exports.getMatchingIndexes=getMatchingIndexes;
|
|
@@ -32,7 +32,7 @@ const matchIndexedJoins = (entity, indexedClone, dataSets) => async (focusEntity
|
|
|
32
32
|
propertySecond: propertyA
|
|
33
33
|
}]
|
|
34
34
|
for (const checkProp of properties) {
|
|
35
|
-
if (!
|
|
35
|
+
if (!Object.prototype.hasOwnProperty.call(indexedClone, checkProp.entitySecond)) {
|
|
36
36
|
indexedClone[checkProp.entitySecond] = _siFunciona.default.cloneObject(indexed[checkProp.entitySecond])
|
|
37
37
|
}
|
|
38
38
|
const matchedRecords = indexedClone[checkProp.entitySecond][checkProp.propertySecond].reduce((dataA, dataB) => _siFunciona.default.mergeArrays(dataA, (0, _where.where)(indexedClone[checkProp.entityFirst][checkProp.propertyFirst], {
|
|
@@ -41,7 +41,7 @@ const matchIndexedJoins = (entity, indexedClone, dataSets) => async (focusEntity
|
|
|
41
41
|
value: dataB.value
|
|
42
42
|
})), [])
|
|
43
43
|
const skipPush = checkProp.entityFirst === entity
|
|
44
|
-
if (!
|
|
44
|
+
if (!Object.prototype.hasOwnProperty.call(dataSets, checkProp.entityFirst)) {
|
|
45
45
|
dataSets[checkProp.entityFirst] = []
|
|
46
46
|
}
|
|
47
47
|
for (const matchedRecord of matchedRecords) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.matchIndexedJoins=void 0,require("core-js/modules/esnext.iterator.constructor.js"),require("core-js/modules/esnext.iterator.reduce.js");var _siFunciona=_interopRequireDefault(require("si-funciona")),_where=require("../queries/where"),_retrieveFile=require("./retrieveFile"),_splitEntityProperty=require("./parsers/splitEntityProperty");function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}const matchIndexedJoins=(e,t,r)=>async(i,o,n,s,p,y)=>{const{entity:c,property:u}=(0,_splitEntityProperty.splitEntityProperty)(s.propertyA),{entity:a,property:
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.matchIndexedJoins=void 0,require("core-js/modules/esnext.iterator.constructor.js"),require("core-js/modules/esnext.iterator.reduce.js");var _siFunciona=_interopRequireDefault(require("si-funciona")),_where=require("../queries/where"),_retrieveFile=require("./retrieveFile"),_splitEntityProperty=require("./parsers/splitEntityProperty");function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}const matchIndexedJoins=(e,t,r)=>async(i,o,n,s,p,y)=>{const{entity:c,property:u}=(0,_splitEntityProperty.splitEntityProperty)(s.propertyA),{entity:a,property:l}=(0,_splitEntityProperty.splitEntityProperty)(s.propertyB),d=[{entityFirst:c,propertyFirst:u,entitySecond:a,propertySecond:l},{entityFirst:a,propertyFirst:l,entitySecond:c,propertySecond:u}];for(let i of d){Object.prototype.hasOwnProperty.call(t,i.entitySecond)||(t[i.entitySecond]=_siFunciona.default.cloneObject(y[i.entitySecond]));const o=t[i.entitySecond][i.propertySecond].reduce(((e,r)=>_siFunciona.default.mergeArrays(e,(0,_where.where)(t[i.entityFirst][i.propertyFirst],{property:"value",comparator:s.comparator,value:r.value}))),[]);let n=i.entityFirst===e;Object.prototype.hasOwnProperty.call(r,i.entityFirst)||(r[i.entityFirst]=[]);for(let e of o)for(let t of e.record){let e=t;"string"==typeof t&&(e=await(0,_retrieveFile.retrieveFile)(`${i.entityFirst}/${t}`)),n||r[i.entityFirst].push(e),p[i.entityFirst].push(e)}}};exports.matchIndexedJoins=matchIndexedJoins;
|
|
@@ -1,26 +1,26 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, '__esModule', {
|
|
4
|
-
value: true
|
|
5
|
-
})
|
|
6
|
-
exports.reconcileJoin = void 0
|
|
7
|
-
require('core-js/modules/esnext.iterator.constructor.js')
|
|
8
|
-
require('core-js/modules/esnext.iterator.for-each.js')
|
|
9
|
-
const _where = require('../queries/where')
|
|
10
|
-
const reconcileJoin = (dataSet, entityName, entityKey, joinEntity, joinProp) => {
|
|
11
|
-
const entity = dataSet[entityName][entityKey]
|
|
12
|
-
if (
|
|
13
|
-
entity[joinEntity].forEach((mergedEntity, k) => {
|
|
14
|
-
const matchedEntity = (0, _where.where)(dataSet[joinEntity], {
|
|
15
|
-
property: joinProp,
|
|
16
|
-
comparator: '=',
|
|
17
|
-
value: mergedEntity[joinProp]
|
|
18
|
-
})
|
|
19
|
-
if (matchedEntity.length) {
|
|
20
|
-
dataSet[entityName][entityKey][joinEntity][k] = matchedEntity[0]
|
|
21
|
-
}
|
|
22
|
-
})
|
|
23
|
-
}
|
|
24
|
-
return dataSet
|
|
25
|
-
}
|
|
26
|
-
exports.reconcileJoin = reconcileJoin
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', {
|
|
4
|
+
value: true
|
|
5
|
+
})
|
|
6
|
+
exports.reconcileJoin = void 0
|
|
7
|
+
require('core-js/modules/esnext.iterator.constructor.js')
|
|
8
|
+
require('core-js/modules/esnext.iterator.for-each.js')
|
|
9
|
+
const _where = require('../queries/where')
|
|
10
|
+
const reconcileJoin = (dataSet, entityName, entityKey, joinEntity, joinProp) => {
|
|
11
|
+
const entity = dataSet[entityName][entityKey]
|
|
12
|
+
if (Object.prototype.hasOwnProperty.call(entity, joinEntity) && Array.isArray(entity[joinEntity])) {
|
|
13
|
+
entity[joinEntity].forEach((mergedEntity, k) => {
|
|
14
|
+
const matchedEntity = (0, _where.where)(dataSet[joinEntity], {
|
|
15
|
+
property: joinProp,
|
|
16
|
+
comparator: '=',
|
|
17
|
+
value: mergedEntity[joinProp]
|
|
18
|
+
})
|
|
19
|
+
if (matchedEntity.length) {
|
|
20
|
+
dataSet[entityName][entityKey][joinEntity][k] = matchedEntity[0]
|
|
21
|
+
}
|
|
22
|
+
})
|
|
23
|
+
}
|
|
24
|
+
return dataSet
|
|
25
|
+
}
|
|
26
|
+
exports.reconcileJoin = reconcileJoin
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.reconcileJoin=void 0,require("core-js/modules/esnext.iterator.constructor.js"),require("core-js/modules/esnext.iterator.for-each.js");var _where=require("../queries/where");const reconcileJoin=(e,r,o,t,
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.reconcileJoin=void 0,require("core-js/modules/esnext.iterator.constructor.js"),require("core-js/modules/esnext.iterator.for-each.js");var _where=require("../queries/where");const reconcileJoin=(e,r,o,t,c)=>{const s=e[r][o];return Object.prototype.hasOwnProperty.call(s,t)&&Array.isArray(s[t])&&s[t].forEach(((s,i)=>{const n=(0,_where.where)(e[t],{property:c,comparator:"=",value:s[c]});n.length&&(e[r][o][t][i]=n[0])})),e};exports.reconcileJoin=reconcileJoin;
|
|
@@ -1,27 +1,26 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, '__esModule', {
|
|
4
|
-
value: true
|
|
5
|
-
})
|
|
6
|
-
exports.reconcileJoins = void 0
|
|
7
|
-
const _splitEntityProperty = require('./parsers/splitEntityProperty')
|
|
8
|
-
const _reconcileJoin = require('./reconcileJoin')
|
|
9
|
-
const reconcileJoins = (propertyA, propertyB, dataSet) => {
|
|
10
|
-
const {
|
|
11
|
-
entity: entityA,
|
|
12
|
-
property: propA
|
|
13
|
-
} = (0, _splitEntityProperty.splitEntityProperty)(propertyA)
|
|
14
|
-
const {
|
|
15
|
-
entity: entityB,
|
|
16
|
-
property: propB
|
|
17
|
-
} = (0, _splitEntityProperty.splitEntityProperty)(propertyB)
|
|
18
|
-
for (const entityName in dataSet) {
|
|
19
|
-
for (const entityKey in dataSet[entityName]) {
|
|
20
|
-
|
|
21
|
-
dataSet = (0, _reconcileJoin.reconcileJoin)(dataSet, entityName, entityKey,
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
exports.reconcileJoins = reconcileJoins
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', {
|
|
4
|
+
value: true
|
|
5
|
+
})
|
|
6
|
+
exports.reconcileJoins = void 0
|
|
7
|
+
const _splitEntityProperty = require('./parsers/splitEntityProperty')
|
|
8
|
+
const _reconcileJoin = require('./reconcileJoin')
|
|
9
|
+
const reconcileJoins = (propertyA, propertyB, dataSet) => {
|
|
10
|
+
const {
|
|
11
|
+
entity: entityA,
|
|
12
|
+
property: propA
|
|
13
|
+
} = (0, _splitEntityProperty.splitEntityProperty)(propertyA)
|
|
14
|
+
const {
|
|
15
|
+
entity: entityB,
|
|
16
|
+
property: propB
|
|
17
|
+
} = (0, _splitEntityProperty.splitEntityProperty)(propertyB)
|
|
18
|
+
for (const entityName in dataSet) {
|
|
19
|
+
for (const entityKey in dataSet[entityName]) {
|
|
20
|
+
dataSet = (0, _reconcileJoin.reconcileJoin)(dataSet, entityName, entityKey, entityA, propA)
|
|
21
|
+
dataSet = (0, _reconcileJoin.reconcileJoin)(dataSet, entityName, entityKey, entityB, propB)
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return dataSet
|
|
25
|
+
}
|
|
26
|
+
exports.reconcileJoins = reconcileJoins
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.reconcileJoins=void 0;var _splitEntityProperty=require("./parsers/splitEntityProperty"),_reconcileJoin=require("./reconcileJoin");const reconcileJoins=(e,r,t)=>{const{entity:i,property:o}=(0,_splitEntityProperty.splitEntityProperty)(e),{entity:n,property:c}=(0,_splitEntityProperty.splitEntityProperty)(r);for(let e in t)for(let r in t[e])
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.reconcileJoins=void 0;var _splitEntityProperty=require("./parsers/splitEntityProperty"),_reconcileJoin=require("./reconcileJoin");const reconcileJoins=(e,r,t)=>{const{entity:i,property:o}=(0,_splitEntityProperty.splitEntityProperty)(e),{entity:n,property:c}=(0,_splitEntityProperty.splitEntityProperty)(r);for(let e in t)for(let r in t[e])t=(0,_reconcileJoin.reconcileJoin)(t,e,r,i,o),t=(0,_reconcileJoin.reconcileJoin)(t,e,r,n,c);return t};exports.reconcileJoins=reconcileJoins;
|
|
@@ -6,7 +6,7 @@ Object.defineProperty(exports, '__esModule', {
|
|
|
6
6
|
exports.registerRecord = void 0
|
|
7
7
|
require('core-js/modules/es.array.includes.js')
|
|
8
8
|
require('core-js/modules/es.json.stringify.js')
|
|
9
|
-
const
|
|
9
|
+
const _config = require('./config')
|
|
10
10
|
const {
|
|
11
11
|
readFile,
|
|
12
12
|
writeFile
|
|
@@ -49,7 +49,7 @@ const defaultRegistry = () => ({
|
|
|
49
49
|
* @param recordName
|
|
50
50
|
*/
|
|
51
51
|
const registerRecord = async recordName => {
|
|
52
|
-
const databasePath =
|
|
52
|
+
const databasePath = (0, _config.getSetting)('databasePath', 'database/')
|
|
53
53
|
const registryPath = `${databasePath}__RECORDS.json`
|
|
54
54
|
let registry
|
|
55
55
|
try {
|