adapt-authoring-api 3.2.2 → 3.3.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/lib/AbstractApiModule.js
CHANGED
|
@@ -658,7 +658,7 @@ class AbstractApiModule extends AbstractModule {
|
|
|
658
658
|
if (results.length > 1) {
|
|
659
659
|
throw this.app.errors.TOO_MANY_RESULTS.setData({ actual: results.length, expected: 1, query })
|
|
660
660
|
}
|
|
661
|
-
if (options.strict !== false && !results.length) {
|
|
661
|
+
if ((options.throwOnMissing ?? options.strict) !== false && !results.length) {
|
|
662
662
|
throw this.app.errors.NOT_FOUND.setData({ id: query, type: options.schemaName })
|
|
663
663
|
}
|
|
664
664
|
return results[0] ?? null
|
|
@@ -726,7 +726,9 @@ class AbstractApiModule extends AbstractModule {
|
|
|
726
726
|
|
|
727
727
|
const updatedDocs = await mongodb.updateMany(options.collectionName, query, formattedData, mongoOptions)
|
|
728
728
|
|
|
729
|
-
if (options.invokePostHook !== false)
|
|
729
|
+
if (options.invokePostHook !== false) {
|
|
730
|
+
await Promise.all(originalDocs.map((original, i) => this.postUpdateHook.invoke(original, updatedDocs[i])))
|
|
731
|
+
}
|
|
730
732
|
return updatedDocs
|
|
731
733
|
}
|
|
732
734
|
|
|
@@ -770,6 +772,8 @@ class AbstractApiModule extends AbstractModule {
|
|
|
770
772
|
|
|
771
773
|
const mongodb = await this.app.waitForModule('mongodb')
|
|
772
774
|
const toDelete = await mongodb.find(options.collectionName, query)
|
|
775
|
+
|
|
776
|
+
if (options.invokePreHook !== false) await Promise.all(toDelete.map(d => this.preDeleteHook.invoke(d, options, mongoOptions)))
|
|
773
777
|
await mongodb.deleteMany(options.collectionName, query, mongoOptions)
|
|
774
778
|
|
|
775
779
|
if (options.invokePostHook !== false) await Promise.all(toDelete.map(d => this.postDeleteHook.invoke(d)))
|
package/lib/typedefs.js
CHANGED
|
@@ -49,6 +49,8 @@
|
|
|
49
49
|
* @typedef {Object} FindOptions
|
|
50
50
|
* @property {String} schemaName Name of the schema to validate against
|
|
51
51
|
* @property {String} collectionName DB collection to insert document into
|
|
52
|
+
* @property {Boolean} throwOnMissing Whether to throw a NOT_FOUND error when no results are found (default: true)
|
|
53
|
+
* @property {Boolean} [strict] @deprecated Use throwOnMissing instead
|
|
52
54
|
*/
|
|
53
55
|
/**
|
|
54
56
|
* @memberof api
|
package/package.json
CHANGED
|
@@ -142,6 +142,56 @@ describe('AbstractApiModule', () => {
|
|
|
142
142
|
})
|
|
143
143
|
})
|
|
144
144
|
|
|
145
|
+
describe('#findOne()', () => {
|
|
146
|
+
function createFindOneInstance (findResults) {
|
|
147
|
+
const notFoundError = { setData: () => { const e = new Error('NOT_FOUND'); e.code = 'NOT_FOUND'; return e } }
|
|
148
|
+
const tooManyResultsError = { setData: () => { const e = new Error('TOO_MANY_RESULTS'); e.code = 'TOO_MANY_RESULTS'; return e } }
|
|
149
|
+
const instance = Object.create(AbstractApiModule.prototype)
|
|
150
|
+
instance.find = async () => findResults
|
|
151
|
+
instance.app = { errors: { NOT_FOUND: notFoundError, TOO_MANY_RESULTS: tooManyResultsError } }
|
|
152
|
+
return instance
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
it('should throw NOT_FOUND when no results and throwOnMissing is not set', async () => {
|
|
156
|
+
const instance = createFindOneInstance([])
|
|
157
|
+
await assert.rejects(() => instance.findOne({}), /NOT_FOUND/)
|
|
158
|
+
})
|
|
159
|
+
|
|
160
|
+
it('should throw NOT_FOUND when no results and throwOnMissing is true', async () => {
|
|
161
|
+
const instance = createFindOneInstance([])
|
|
162
|
+
await assert.rejects(() => instance.findOne({}, { throwOnMissing: true }), /NOT_FOUND/)
|
|
163
|
+
})
|
|
164
|
+
|
|
165
|
+
it('should return null when no results and throwOnMissing is false', async () => {
|
|
166
|
+
const instance = createFindOneInstance([])
|
|
167
|
+
const result = await instance.findOne({}, { throwOnMissing: false })
|
|
168
|
+
assert.equal(result, null)
|
|
169
|
+
})
|
|
170
|
+
|
|
171
|
+
it('should return null when no results and strict is false (backward compat)', async () => {
|
|
172
|
+
const instance = createFindOneInstance([])
|
|
173
|
+
const result = await instance.findOne({}, { strict: false })
|
|
174
|
+
assert.equal(result, null)
|
|
175
|
+
})
|
|
176
|
+
|
|
177
|
+
it('should prefer throwOnMissing over strict when both are set', async () => {
|
|
178
|
+
const instance = createFindOneInstance([])
|
|
179
|
+
await assert.rejects(() => instance.findOne({}, { throwOnMissing: true, strict: false }), /NOT_FOUND/)
|
|
180
|
+
})
|
|
181
|
+
|
|
182
|
+
it('should return the single result when found', async () => {
|
|
183
|
+
const doc = { _id: '1', name: 'test' }
|
|
184
|
+
const instance = createFindOneInstance([doc])
|
|
185
|
+
const result = await instance.findOne({})
|
|
186
|
+
assert.deepEqual(result, doc)
|
|
187
|
+
})
|
|
188
|
+
|
|
189
|
+
it('should throw TOO_MANY_RESULTS when more than one result is returned', async () => {
|
|
190
|
+
const instance = createFindOneInstance([{ _id: '1' }, { _id: '2' }])
|
|
191
|
+
await assert.rejects(() => instance.findOne({}), /TOO_MANY_RESULTS/)
|
|
192
|
+
})
|
|
193
|
+
})
|
|
194
|
+
|
|
145
195
|
describe('default-routes.json', () => {
|
|
146
196
|
it('should define an array of route objects', () => {
|
|
147
197
|
assert.ok(Array.isArray(defaultRoutes.routes))
|