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.
Files changed (212) hide show
  1. package/README.md +41 -6
  2. package/browser/jsonFsQuery.js +28271 -0
  3. package/browser/jsonFsQuery.min.js +1 -0
  4. package/dist/data/introspect/create.js +6 -4
  5. package/dist/data/introspect/create.min.js +1 -1
  6. package/dist/data/introspect/drop.js +2 -2
  7. package/dist/data/introspect/drop.min.js +1 -1
  8. package/dist/data/introspect/policies/hasDependents.d.ts +13 -0
  9. package/dist/data/introspect/policies/hasDependents.js +52 -0
  10. package/dist/data/introspect/policies/hasDependents.min.js +1 -0
  11. package/dist/data/introspect/policies/keyGenerate.js +1 -1
  12. package/dist/data/introspect/policies/keyGenerate.min.js +1 -1
  13. package/dist/data/introspect/policies/keyUnique.d.ts +9 -1
  14. package/dist/data/introspect/policies/keyUnique.js +19 -9
  15. package/dist/data/introspect/policies/keyUnique.min.js +1 -1
  16. package/dist/data/queries/deleteEntity.js +36 -15
  17. package/dist/data/queries/deleteEntity.min.js +1 -1
  18. package/dist/data/queries/groupBy.js +22 -22
  19. package/dist/data/queries/groupBy.min.js +1 -1
  20. package/dist/data/queries/insertEntity.js +14 -12
  21. package/dist/data/queries/insertEntity.min.js +1 -1
  22. package/dist/data/queries/readEntity.js +1 -1
  23. package/dist/data/queries/readEntity.min.js +1 -1
  24. package/dist/data/queries/updateEntity.js +68 -42
  25. package/dist/data/queries/updateEntity.min.js +1 -1
  26. package/dist/data/queries/where.js +1 -1
  27. package/dist/data/queries/where.min.js +1 -1
  28. package/dist/data/utilities/computeKeyValue.d.ts +13 -0
  29. package/dist/data/utilities/computeKeyValue.js +26 -0
  30. package/dist/data/utilities/computeKeyValue.min.js +1 -0
  31. package/dist/data/utilities/config.d.ts +28 -0
  32. package/dist/data/utilities/config.js +45 -0
  33. package/dist/data/utilities/config.min.js +1 -0
  34. package/dist/data/utilities/deregisterRecord.js +2 -2
  35. package/dist/data/utilities/deregisterRecord.min.js +1 -1
  36. package/dist/data/utilities/getConditionIndexedList.js +1 -1
  37. package/dist/data/utilities/getConditionIndexedList.min.js +1 -1
  38. package/dist/data/utilities/getJoinIndexedList.js +2 -2
  39. package/dist/data/utilities/getJoinIndexedList.min.js +1 -1
  40. package/dist/data/utilities/getMatchingIndexes.js +2 -2
  41. package/dist/data/utilities/getMatchingIndexes.min.js +1 -1
  42. package/dist/data/utilities/matchIndexedJoins.js +2 -2
  43. package/dist/data/utilities/matchIndexedJoins.min.js +1 -1
  44. package/dist/data/utilities/reconcileJoin.js +26 -26
  45. package/dist/data/utilities/reconcileJoin.min.js +1 -1
  46. package/dist/data/utilities/reconcileJoins.js +26 -27
  47. package/dist/data/utilities/reconcileJoins.min.js +1 -1
  48. package/dist/data/utilities/registerRecord.js +2 -2
  49. package/dist/data/utilities/registerRecord.min.js +1 -1
  50. package/dist/data/utilities/removeFromIndex.js +2 -2
  51. package/dist/data/utilities/removeFromIndex.min.js +1 -1
  52. package/dist/data/utilities/restrictIndexedList.js +45 -45
  53. package/dist/data/utilities/restrictIndexedList.min.js +1 -1
  54. package/dist/data/utilities/retrieveFile.js +3 -3
  55. package/dist/data/utilities/retrieveFile.min.js +1 -1
  56. package/dist/data/utilities/retrieveIndexes.js +1 -1
  57. package/dist/data/utilities/retrieveIndexes.min.js +1 -1
  58. package/dist/data/utilities/updateIndex.js +2 -2
  59. package/dist/data/utilities/updateIndex.min.js +1 -1
  60. package/dist/data/utilities/useJoinClause.js +4 -4
  61. package/dist/data/utilities/useJoinClause.min.js +1 -1
  62. package/dist/index.d.ts +1 -0
  63. package/dist/index.js +7 -0
  64. package/dist/index.min.js +1 -1
  65. package/package.json +11 -4
  66. package/.browserslistrc +0 -1
  67. package/.nvmrc +0 -1
  68. package/MAIN.md +0 -15
  69. package/babel.config.js +0 -3
  70. package/build-tools.config.json +0 -30
  71. package/gulpfile.mjs +0 -15
  72. package/src/data/introspect/create.test.js +0 -67
  73. package/src/data/introspect/create.ts +0 -29
  74. package/src/data/introspect/definitions/field.test.js +0 -23
  75. package/src/data/introspect/definitions/field.ts +0 -48
  76. package/src/data/introspect/definitions/key.test.js +0 -100
  77. package/src/data/introspect/definitions/key.ts +0 -64
  78. package/src/data/introspect/definitions/keyReference.test.js +0 -8
  79. package/src/data/introspect/definitions/keyReference.ts +0 -23
  80. package/src/data/introspect/definitions/record.ts +0 -42
  81. package/src/data/introspect/describe.test.js +0 -36
  82. package/src/data/introspect/describe.ts +0 -9
  83. package/src/data/introspect/drop.test.js +0 -77
  84. package/src/data/introspect/drop.ts +0 -20
  85. package/src/data/introspect/index.ts +0 -8
  86. package/src/data/introspect/policies/foreignKeyExists.test.js +0 -44
  87. package/src/data/introspect/policies/foreignKeyExists.ts +0 -15
  88. package/src/data/introspect/policies/keyGenerate.ts +0 -11
  89. package/src/data/introspect/policies/keyUnique.ts +0 -11
  90. package/src/data/introspect/policies/typeCheck.test.js +0 -84
  91. package/src/data/introspect/policies/typeCheck.ts +0 -49
  92. package/src/data/introspect/policies/typeEnum.ts +0 -6
  93. package/src/data/introspect/policies/useDefault.ts +0 -6
  94. package/src/data/queries/deleteEntity.test.js +0 -86
  95. package/src/data/queries/deleteEntity.ts +0 -56
  96. package/src/data/queries/groupBy.test.js +0 -135
  97. package/src/data/queries/groupBy.ts +0 -16
  98. package/src/data/queries/insertEntity.test.js +0 -156
  99. package/src/data/queries/insertEntity.ts +0 -113
  100. package/src/data/queries/joinEntity.test.js +0 -109
  101. package/src/data/queries/joinEntity.ts +0 -20
  102. package/src/data/queries/mergeJoins.test.js +0 -174
  103. package/src/data/queries/mergeJoins.ts +0 -13
  104. package/src/data/queries/parser.test.js +0 -343
  105. package/src/data/queries/parser.ts +0 -24
  106. package/src/data/queries/query.test.js +0 -233
  107. package/src/data/queries/query.ts +0 -12
  108. package/src/data/queries/readEntity.test.js +0 -85
  109. package/src/data/queries/readEntity.ts +0 -8
  110. package/src/data/queries/sortBy.test.js +0 -131
  111. package/src/data/queries/sortBy.ts +0 -18
  112. package/src/data/queries/updateEntity.test.js +0 -228
  113. package/src/data/queries/updateEntity.ts +0 -162
  114. package/src/data/queries/where.test.js +0 -129
  115. package/src/data/queries/where.ts +0 -54
  116. package/src/data/utilities/deregisterRecord.test.js +0 -26
  117. package/src/data/utilities/deregisterRecord.ts +0 -24
  118. package/src/data/utilities/getConditionIndexedList.ts +0 -43
  119. package/src/data/utilities/getJoinIndexedList.ts +0 -53
  120. package/src/data/utilities/getMatchingIndexes.ts +0 -21
  121. package/src/data/utilities/matchIndexedJoins.ts +0 -45
  122. package/src/data/utilities/mergeJoin.test.js +0 -102
  123. package/src/data/utilities/mergeJoin.ts +0 -28
  124. package/src/data/utilities/parsers/findCommand.ts +0 -25
  125. package/src/data/utilities/parsers/findConditions.test.js +0 -38
  126. package/src/data/utilities/parsers/findConditions.ts +0 -32
  127. package/src/data/utilities/parsers/findGroupBy.ts +0 -20
  128. package/src/data/utilities/parsers/findInsertValues.test.js +0 -26
  129. package/src/data/utilities/parsers/findInsertValues.ts +0 -32
  130. package/src/data/utilities/parsers/findJoinClauses.ts +0 -29
  131. package/src/data/utilities/parsers/findJoinEntity.ts +0 -20
  132. package/src/data/utilities/parsers/findLimit.ts +0 -20
  133. package/src/data/utilities/parsers/findMergeJoins.ts +0 -27
  134. package/src/data/utilities/parsers/findOffset.ts +0 -20
  135. package/src/data/utilities/parsers/findSelects.ts +0 -31
  136. package/src/data/utilities/parsers/findSortClauses.ts +0 -31
  137. package/src/data/utilities/parsers/findUpdateValues.test.js +0 -37
  138. package/src/data/utilities/parsers/findUpdateValues.ts +0 -32
  139. package/src/data/utilities/parsers/isEntityProperty.ts +0 -1
  140. package/src/data/utilities/parsers/parseLiteralValue.test.js +0 -41
  141. package/src/data/utilities/parsers/parseLiteralValue.ts +0 -29
  142. package/src/data/utilities/parsers/parseQuery.ts +0 -73
  143. package/src/data/utilities/parsers/removeFromQuery.ts +0 -1
  144. package/src/data/utilities/parsers/splitEntityProperty.test.js +0 -8
  145. package/src/data/utilities/parsers/splitEntityProperty.ts +0 -17
  146. package/src/data/utilities/parsers/splitQueries.test.js +0 -33
  147. package/src/data/utilities/parsers/splitQueries.ts +0 -4
  148. package/src/data/utilities/reconcileJoin.test.js +0 -38
  149. package/src/data/utilities/reconcileJoin.ts +0 -23
  150. package/src/data/utilities/reconcileJoins.test.js +0 -160
  151. package/src/data/utilities/reconcileJoins.ts +0 -15
  152. package/src/data/utilities/registerRecord.test.js +0 -44
  153. package/src/data/utilities/registerRecord.ts +0 -44
  154. package/src/data/utilities/removeFromIndex.test.js +0 -44
  155. package/src/data/utilities/removeFromIndex.ts +0 -34
  156. package/src/data/utilities/restrictIndexedList.ts +0 -38
  157. package/src/data/utilities/retrieveFile.test.js +0 -49
  158. package/src/data/utilities/retrieveFile.ts +0 -19
  159. package/src/data/utilities/retrieveIndexes.ts +0 -17
  160. package/src/data/utilities/retrieveRecord.ts +0 -3
  161. package/src/data/utilities/retrieveRecords.test.js +0 -223
  162. package/src/data/utilities/retrieveRecords.ts +0 -16
  163. package/src/data/utilities/runQuery.test.js +0 -88
  164. package/src/data/utilities/runQuery.ts +0 -75
  165. package/src/data/utilities/updateIndex.test.js +0 -44
  166. package/src/data/utilities/updateIndex.ts +0 -45
  167. package/src/data/utilities/useJoinClause.test.js +0 -94
  168. package/src/data/utilities/useJoinClause.ts +0 -44
  169. package/src/global.d.ts +0 -1
  170. package/src/index.test.js +0 -52
  171. package/src/index.ts +0 -17
  172. package/test-data/__RECORDS.json +0 -32
  173. package/test-data/__indexes/exercise_muscle/fk_exercise_id.json +0 -14
  174. package/test-data/__indexes/exercise_muscle/fk_muscle_id.json +0 -14
  175. package/test-data/__indexes/exercise_muscle/pk__id.json +0 -14
  176. package/test-data/__indexes/exercises/pk__id.json +0 -14
  177. package/test-data/__indexes/muscles/pk__id.json +0 -58
  178. package/test-data/__indexes/workouts/fk_exercise_id.json +0 -23
  179. package/test-data/__indexes/workouts/index_date.json +0 -18
  180. package/test-data/__indexes/workouts/pk__id.json +0 -26
  181. package/test-data/copyDatabase.ts +0 -64
  182. package/test-data/exercise_muscle/bench_press_pectorals.json +0 -6
  183. package/test-data/exercise_muscle/deadlift_hamstrings.json +0 -6
  184. package/test-data/exercise_muscle/squat_quadriceps.json +0 -6
  185. package/test-data/exercise_muscle.json +0 -69
  186. package/test-data/exercises/bench_press.json +0 -5
  187. package/test-data/exercises/deadlift.json +0 -5
  188. package/test-data/exercises/squat.json +0 -5
  189. package/test-data/exercises.json +0 -34
  190. package/test-data/muscles/abdominal.json +0 -6
  191. package/test-data/muscles/biceps.json +0 -6
  192. package/test-data/muscles/calves.json +0 -6
  193. package/test-data/muscles/deltoids.json +0 -6
  194. package/test-data/muscles/erector_spinae.json +0 -6
  195. package/test-data/muscles/forearms.json +0 -6
  196. package/test-data/muscles/gluteus_maximus.json +0 -6
  197. package/test-data/muscles/hamstrings.json +0 -6
  198. package/test-data/muscles/latissimus_dorsi.json +0 -6
  199. package/test-data/muscles/obliques.json +0 -6
  200. package/test-data/muscles/pectorals.json +0 -6
  201. package/test-data/muscles/quadriceps.json +0 -6
  202. package/test-data/muscles/trapezius.json +0 -6
  203. package/test-data/muscles/triceps.json +0 -6
  204. package/test-data/muscles.json +0 -50
  205. package/test-data/workouts/2024-06-02-001.json +0 -10
  206. package/test-data/workouts/2024-06-02-002.json +0 -10
  207. package/test-data/workouts/2024-06-02-003.json +0 -10
  208. package/test-data/workouts/2024-06-05-001.json +0 -10
  209. package/test-data/workouts/2024-06-05-002.json +0 -10
  210. package/test-data/workouts/2024-06-05-003.json +0 -10
  211. package/test-data/workouts.json +0 -84
  212. 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 gulpConfig = require('js-build-tools/gulp.config')
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 primaryField
31
+ * @param primaryKey
27
32
  * @param primaryValue
28
33
  */
29
- const findEntryFile = async (record, primaryField, primaryValue) => {
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[primaryField] == primaryValue) {
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
- * Only check uniqueness for a single-field primary/unique key whose value is actually changing -
40
- * checking an unchanged value would find the record's own existing entry and wrongly report it
41
- * as a duplicate of itself.
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.fields.length !== 1) {
63
+ if (key.type !== 'primary' && key.type !== 'unique' || !keyFieldsChanged(key, oldData, newValues)) {
50
64
  continue
51
65
  }
52
- const field = key.fields[0]
53
- if (!newValues.hasOwnProperty(field) || newValues[field] == oldData[field]) {
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 "${field}" on ${entity}`)
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 (!newValues.hasOwnProperty(field) || newValues[field] == oldData[field]) {
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.fields.length !== 1) {
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[field], fileName)
109
- await (0, _updateIndex.updateIndex)(record.path, key, newData[field], fileName)
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 (typedValues.hasOwnProperty(field.name)) {
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 = gulpConfig.get('databasePath', 'database/')
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' && key.fields.length === 1)
165
+ const primaryKey = record.keys.find(key => key.type === 'primary')
140
166
  if (!primaryKey) {
141
- throw new Error(`Cannot update "${entity}" without a single-field primary key`)
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, primaryField, row[primaryField])
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 "${primaryField}" = ${row[primaryField]}`)
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");const gulpConfig=require("js-build-tools/gulp.config"),{writeFile:writeFile}=require("fs/promises"),findEntryFile=async(e,t,r)=>{for(const i of e.entries){if((await(0,_retrieveFile.retrieveFile)(`${e.path}/${i}`))[t]==r)return i}return null},assertUniqueForUpdate=async(e,t,r,i)=>{for(const n of t.keys){if("primary"!==n.type&&"unique"!==n.type||1!==n.fields.length)continue;const t=n.fields[0];if(!i.hasOwnProperty(t)||i[t]==r[t])continue;if(!await(0,_keyUnique.keyUnique)(e,n.fields,i[t]))throw new Error(`Duplicate value for ${n.type} key "${t}" on ${e}`)}},assertForeignKeysForUpdate=async(e,t,r,i)=>{for(const n of t.keys){if("foreign"!==n.type||1!==n.fields.length||!n.references||1!==n.references.length)continue;const t=n.fields[0];if(!i.hasOwnProperty(t)||i[t]==r[t])continue;const{entity:s,property:o}=(0,_splitEntityProperty.splitEntityProperty)(n.references[0].fields[0]);if(!await(0,_foreignKeyExists.foreignKeyExists)(s,o,i[t]))throw new Error(`Foreign key "${t}" on ${e} references a nonexistent ${s}.${o} = ${i[t]}`)}},reconcileIndexes=async(e,t,r,i,n)=>{for(const s of e.keys){if(1!==s.fields.length)continue;const o=s.fields[0];i.hasOwnProperty(o)&&i[o]!=t[o]&&(await(0,_removeFromIndex.removeFromIndex)(e.path,s,t[o],n),await(0,_updateIndex.updateIndex)(e.path,s,r[o],n))}},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)r.hasOwnProperty(t.name)&&(r[t.name]=(0,_typeCheck.typeCheck)(t.type,r[t.name]));return r},updateEntity=async(e="",t={},r={})=>{const i=gulpConfig.get("databasePath","database/"),n=await(0,_retrieveRecord.retrieveRecord)(e),s=n.keys.find((e=>"primary"===e.type&&1===e.fields.length));if(!s)throw new Error(`Cannot update "${e}" without a single-field primary key`);const o=s.fields[0],a=applyFieldTypes(n,t),p=r[e]||[],l=[];for(const t of p){const r=await findEntryFile(n,o,t[o]);if(!r)throw new Error(`Could not find entry for ${e} where "${o}" = ${t[o]}`);const s=await(0,_retrieveFile.retrieveFile)(`${n.path}/${r}`);await assertUniqueForUpdate(e,n,s,a),await assertForeignKeysForUpdate(e,n,s,a);const p=Object.assign({},s,a);assertRequiredFields(e,n,p),await reconcileIndexes(n,s,p,a,r),await writeFile(`${i}${n.path}/${r}`,JSON.stringify(p,null,2)),l.push(p)}return r[e]=l,r};exports.updateEntity=updateEntity;
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 (!data.hasOwnProperty(property)) {
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(!e.hasOwnProperty(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;
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 gulpConfig = require('js-build-tools/gulp.config')
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 = gulpConfig.get('databasePath', 'database/')
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");const gulpConfig=require("js-build-tools/gulp.config"),{readFile:readFile,writeFile:writeFile}=require("fs/promises"),deregisterRecord=async e=>{const r=`${gulpConfig.get("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;
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 (!recordData.hasOwnProperty(entity)) {
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}t.hasOwnProperty(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;
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 (!recordData.hasOwnProperty(entityA)) {
37
+ if (!Object.prototype.hasOwnProperty.call(recordData, entityA)) {
38
38
  recordData[entityA] = await (0, _retrieveRecord.retrieveRecord)(entityA)
39
39
  }
40
- if (!recordData.hasOwnProperty(entityB)) {
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 s=!0;const o=e.entity,d=e.joinEntity,c=e.joinClauses;for(const e in r[o]){const a=r[o][e];let p={};p[o]=[_siFunciona.default.cloneObject(a)];for(let e of c){let d=_siFunciona.default.cloneObject(n);const{entity:c,property:a}=(0,_splitEntityProperty.splitEntityProperty)(e.propertyA),{entity:u,property:y}=(0,_splitEntityProperty.splitEntityProperty)(e.propertyB);t.hasOwnProperty(c)||(t[c]=await(0,_retrieveRecord.retrieveRecord)(c)),t.hasOwnProperty(u)||(t[u]=await(0,_retrieveRecord.retrieveRecord)(u)),d=(0,_restrictIndexedList.restrictIndexedList)(e,p,d);const l=(0,_matchIndexedJoins.matchIndexedJoins)(o,d,r),_=await(0,_getMatchingIndexes.getMatchingIndexes)(c,a,t,e,p,n),x=await(0,_getMatchingIndexes.getMatchingIndexes)(u,y,t,e,p,n,l);!(_||x)&&s&&(i.push(e),s=!1)}r[o][e][d]=p[d]}return e.joinClauses=i,e};exports.getJoinIndexedList=getJoinIndexedList;
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 (!indexed.hasOwnProperty(entity)) {
14
+ if (!Object.prototype.hasOwnProperty.call(indexed, entity)) {
15
15
  indexed[entity] = {}
16
16
  }
17
- if (!indexed[entity].hasOwnProperty(property)) {
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,t,s,n,i,a=null)=>{let d=!1;for(let o of t[e].keys)o.fields.includes(r)&&(n[e]=[],i.hasOwnProperty(e)||(i[e]={}),i[e].hasOwnProperty(r)||(i[e][r]=(await(0,_retrieveIndexes.retrieveIndexes)(e,[r],t))[r]),"function"==typeof a&&await a(e,r,t,s,n,i),d=!0);return d};exports.getMatchingIndexes=getMatchingIndexes;
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 (!indexedClone.hasOwnProperty(checkProp.entitySecond)) {
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 (!dataSets.hasOwnProperty(checkProp.entityFirst)) {
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:d}=(0,_splitEntityProperty.splitEntityProperty)(s.propertyB),l=[{entityFirst:c,propertyFirst:u,entitySecond:a,propertySecond:d},{entityFirst:a,propertyFirst:d,entitySecond:c,propertySecond:u}];for(let i of l){t.hasOwnProperty(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;r.hasOwnProperty(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
+ "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 (entity.hasOwnProperty(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
+ '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,s)=>{const c=e[r][o];return c.hasOwnProperty(t)&&Array.isArray(c[t])&&c[t].forEach(((c,i)=>{const n=(0,_where.where)(e[t],{property:s,comparator:"=",value:c[s]});n.length&&(e[r][o][t][i]=n[0])})),e};exports.reconcileJoin=reconcileJoin;
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
- const entity = dataSet[entityName][entityKey]
21
- dataSet = (0, _reconcileJoin.reconcileJoin)(dataSet, entityName, entityKey, entityA, propA)
22
- dataSet = (0, _reconcileJoin.reconcileJoin)(dataSet, entityName, entityKey, entityB, propB)
23
- }
24
- }
25
- return dataSet
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]){t[e][r];t=(0,_reconcileJoin.reconcileJoin)(t,e,r,i,o),t=(0,_reconcileJoin.reconcileJoin)(t,e,r,n,c)}return t};exports.reconcileJoins=reconcileJoins;
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 gulpConfig = require('js-build-tools/gulp.config')
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 = gulpConfig.get('databasePath', 'database/')
52
+ const databasePath = (0, _config.getSetting)('databasePath', 'database/')
53
53
  const registryPath = `${databasePath}__RECORDS.json`
54
54
  let registry
55
55
  try {