adapt-authoring-api 3.4.0 → 3.6.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 +3 -6
- package/package.json +2 -2
- package/lib/DataCache.js +0 -45
- package/tests/DataCache.spec.js +0 -47
package/lib/AbstractApiModule.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import _ from 'lodash'
|
|
2
|
-
import { AbstractModule, Hook, stringifyValues } from 'adapt-authoring-core'
|
|
2
|
+
import { AbstractModule, DataCache, Hook, stringifyValues } from 'adapt-authoring-core'
|
|
3
3
|
import { argsFromReq, generateApiMetadata, httpMethodToDBFunction } from './utils.js'
|
|
4
|
-
import DataCache from './DataCache.js'
|
|
5
4
|
import { loadRouteConfig } from 'adapt-authoring-server'
|
|
6
5
|
/**
|
|
7
6
|
* Abstract module for creating APIs
|
|
@@ -328,11 +327,9 @@ class AbstractApiModule extends AbstractModule {
|
|
|
328
327
|
* @return {Promise} Resolves with the sanitised data
|
|
329
328
|
*/
|
|
330
329
|
async sanitise (schemaName, data, options) {
|
|
330
|
+
const schema = await this.getSchema(schemaName, data)
|
|
331
331
|
const isArray = Array.isArray(data)
|
|
332
|
-
const sanitised =
|
|
333
|
-
const schema = await this.getSchema(schemaName, d)
|
|
334
|
-
return schema.sanitise(d, options)
|
|
335
|
-
}))
|
|
332
|
+
const sanitised = (isArray ? data : [data]).map(d => schema.sanitise(d, options))
|
|
336
333
|
return isArray ? sanitised : sanitised[0]
|
|
337
334
|
}
|
|
338
335
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "adapt-authoring-api",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.6.0",
|
|
4
4
|
"description": "Abstract module for creating APIs",
|
|
5
5
|
"homepage": "https://github.com/adapt-security/adapt-authoring-api",
|
|
6
6
|
"license": "GPL-3.0",
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"test": "node --test 'tests/**/*.spec.js'"
|
|
12
12
|
},
|
|
13
13
|
"dependencies": {
|
|
14
|
-
"adapt-authoring-core": "^2.
|
|
14
|
+
"adapt-authoring-core": "^2.5.0",
|
|
15
15
|
"adapt-authoring-server": "^2.1.0",
|
|
16
16
|
"lodash": "^4.17.21"
|
|
17
17
|
},
|
package/lib/DataCache.js
DELETED
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import { App } from 'adapt-authoring-core'
|
|
2
|
-
/**
|
|
3
|
-
* Time-limited data cache
|
|
4
|
-
* @memberof api
|
|
5
|
-
*/
|
|
6
|
-
class DataCache {
|
|
7
|
-
/** @override */
|
|
8
|
-
constructor ({ enable, lifespan }) {
|
|
9
|
-
this.isEnabled = enable === true
|
|
10
|
-
this.lifespan = lifespan ?? App.instance.config.get('adapt-authoring-api.defaultCacheLifespan')
|
|
11
|
-
this.cache = {}
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Retrieve cached data, or run fresh query if no cache exists or cache is invalid
|
|
16
|
-
* @param {Object} query
|
|
17
|
-
* @param Object} options
|
|
18
|
-
* @param {Object} mongoOptions
|
|
19
|
-
* @returns {*} The cached data
|
|
20
|
-
*/
|
|
21
|
-
async get (query, options, mongoOptions) {
|
|
22
|
-
const key = JSON.stringify(query) + JSON.stringify(options) + JSON.stringify(mongoOptions)
|
|
23
|
-
this.prune()
|
|
24
|
-
if (this.isEnabled && this.cache[key]) {
|
|
25
|
-
return this.cache[key].data
|
|
26
|
-
}
|
|
27
|
-
const mongodb = await App.instance.waitForModule('mongodb')
|
|
28
|
-
const data = await mongodb.find(options.collectionName, query, mongoOptions)
|
|
29
|
-
this.cache[key] = { data, timestamp: Date.now() }
|
|
30
|
-
return data
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Removes invalid cache data
|
|
35
|
-
*/
|
|
36
|
-
prune () {
|
|
37
|
-
Object.keys(this.cache).forEach(k => {
|
|
38
|
-
if (Date.now() > (this.cache[k].timestamp + this.lifespan)) {
|
|
39
|
-
delete this.cache[k]
|
|
40
|
-
}
|
|
41
|
-
})
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
export default DataCache
|
package/tests/DataCache.spec.js
DELETED
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import { describe, it, before } from 'node:test'
|
|
2
|
-
import assert from 'node:assert/strict'
|
|
3
|
-
|
|
4
|
-
describe('DataCache', () => {
|
|
5
|
-
let DataCache
|
|
6
|
-
|
|
7
|
-
before(async () => {
|
|
8
|
-
// DataCache constructor references App.instance.config, so we need to
|
|
9
|
-
// dynamically import after ensuring no app instance is required for prune tests.
|
|
10
|
-
// We import the module directly and test what we can without the full app.
|
|
11
|
-
DataCache = (await import('../lib/DataCache.js')).default
|
|
12
|
-
})
|
|
13
|
-
|
|
14
|
-
describe('#prune()', () => {
|
|
15
|
-
it('should remove expired entries from the cache', () => {
|
|
16
|
-
const instance = Object.create(DataCache.prototype)
|
|
17
|
-
instance.lifespan = 100
|
|
18
|
-
instance.cache = {
|
|
19
|
-
expired: { data: [1], timestamp: Date.now() - 200 },
|
|
20
|
-
valid: { data: [2], timestamp: Date.now() }
|
|
21
|
-
}
|
|
22
|
-
instance.prune()
|
|
23
|
-
assert.equal(instance.cache.expired, undefined)
|
|
24
|
-
assert.ok(instance.cache.valid)
|
|
25
|
-
})
|
|
26
|
-
|
|
27
|
-
it('should keep entries that have not expired', () => {
|
|
28
|
-
const instance = Object.create(DataCache.prototype)
|
|
29
|
-
instance.lifespan = 10000
|
|
30
|
-
instance.cache = {
|
|
31
|
-
a: { data: [1], timestamp: Date.now() },
|
|
32
|
-
b: { data: [2], timestamp: Date.now() }
|
|
33
|
-
}
|
|
34
|
-
instance.prune()
|
|
35
|
-
assert.ok(instance.cache.a)
|
|
36
|
-
assert.ok(instance.cache.b)
|
|
37
|
-
})
|
|
38
|
-
|
|
39
|
-
it('should handle an empty cache', () => {
|
|
40
|
-
const instance = Object.create(DataCache.prototype)
|
|
41
|
-
instance.lifespan = 100
|
|
42
|
-
instance.cache = {}
|
|
43
|
-
instance.prune()
|
|
44
|
-
assert.deepEqual(instance.cache, {})
|
|
45
|
-
})
|
|
46
|
-
})
|
|
47
|
-
})
|