adapt-authoring-contentplugin 1.6.0 → 1.7.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.
|
@@ -10,7 +10,8 @@ permissions:
|
|
|
10
10
|
issues: write
|
|
11
11
|
pull-requests: write
|
|
12
12
|
id-token: write
|
|
13
|
+
packages: write
|
|
13
14
|
|
|
14
15
|
jobs:
|
|
15
16
|
release:
|
|
16
|
-
uses: adaptlearning/semantic-release-config/.github/workflows/release.yml@master
|
|
17
|
+
uses: adaptlearning/semantic-release-config/.github/workflows/release.yml@master
|
|
@@ -24,8 +24,10 @@ class ContentPluginModule extends AbstractApiModule {
|
|
|
24
24
|
/** @ignore */ this.root = 'contentplugins'
|
|
25
25
|
/** @ignore */ this.schemaName = 'contentplugin'
|
|
26
26
|
/**
|
|
27
|
-
*
|
|
28
|
-
*
|
|
27
|
+
* Maps plugin name to a map of schema $anchor → file path. The file path
|
|
28
|
+
* lets us re-register schemas after JsonSchemaModule resets the registry
|
|
29
|
+
* on app ready (it only re-registers schemas owned by app.dependencies).
|
|
30
|
+
* @type {Object<string, Object<string, string>>}
|
|
29
31
|
*/
|
|
30
32
|
this.pluginSchemas = {}
|
|
31
33
|
/**
|
|
@@ -45,7 +47,7 @@ class ContentPluginModule extends AbstractApiModule {
|
|
|
45
47
|
if (!process.env.ADAPT_ALLOW_PRERELEASE) {
|
|
46
48
|
process.env.ADAPT_ALLOW_PRERELEASE = 'true'
|
|
47
49
|
}
|
|
48
|
-
const [framework,
|
|
50
|
+
const [framework, jsonschema, mongodb] = await this.app.waitForModule('adaptframework', 'jsonschema', 'mongodb')
|
|
49
51
|
|
|
50
52
|
await mongodb.setIndex(this.collectionName, 'name', { unique: true })
|
|
51
53
|
await mongodb.setIndex(this.collectionName, 'displayName', { unique: true })
|
|
@@ -56,14 +58,20 @@ class ContentPluginModule extends AbstractApiModule {
|
|
|
56
58
|
*/
|
|
57
59
|
this.framework = framework
|
|
58
60
|
|
|
61
|
+
// JsonSchemaModule resets the registry at app ready and only re-registers
|
|
62
|
+
// schemas from app.dependencies — plugin schemas would otherwise be lost.
|
|
63
|
+
jsonschema.registerSchemasHook.tap(() => this.reregisterPluginSchemas())
|
|
64
|
+
|
|
59
65
|
try {
|
|
60
66
|
await this.initPlugins()
|
|
61
67
|
} catch (e) {
|
|
62
68
|
this.log('error', e)
|
|
63
69
|
}
|
|
64
|
-
content.preInsertHook.tap((...args) => addDefaultPlugins(this, ...args))
|
|
65
70
|
this.framework.postInstallHook.tap(this.syncPluginData.bind(this))
|
|
66
71
|
this.framework.postUpdateHook.tap(this.syncPluginData.bind(this))
|
|
72
|
+
this.app.waitForModule('content').then(content => {
|
|
73
|
+
content.preInsertHook.tap((...args) => addDefaultPlugins(this, ...args))
|
|
74
|
+
})
|
|
67
75
|
}
|
|
68
76
|
|
|
69
77
|
/** @override */
|
|
@@ -112,8 +120,8 @@ class ContentPluginModule extends AbstractApiModule {
|
|
|
112
120
|
const pluginData = await this.findOne({ _id })
|
|
113
121
|
// unregister any schemas
|
|
114
122
|
const jsonschema = await this.app.waitForModule('jsonschema')
|
|
115
|
-
const schemas = this.pluginSchemas[pluginData.name] ??
|
|
116
|
-
schemas.forEach(s => jsonschema.deregisterSchema(s))
|
|
123
|
+
const schemas = this.pluginSchemas[pluginData.name] ?? {}
|
|
124
|
+
Object.keys(schemas).forEach(s => jsonschema.deregisterSchema(s))
|
|
117
125
|
delete this.pluginSchemas[pluginData.name]
|
|
118
126
|
|
|
119
127
|
await this.framework.runCliCommand('uninstallPlugins', { plugins: [pluginData.name] })
|
|
@@ -211,9 +219,9 @@ class ContentPluginModule extends AbstractApiModule {
|
|
|
211
219
|
const jsonschema = await this.app.waitForModule('jsonschema')
|
|
212
220
|
return Promise.all(pluginInfo.map(async plugin => {
|
|
213
221
|
const name = plugin.name
|
|
214
|
-
const
|
|
215
|
-
if (
|
|
216
|
-
Object.
|
|
222
|
+
const existing = this.pluginSchemas[name]
|
|
223
|
+
if (existing) {
|
|
224
|
+
Object.keys(existing).forEach(s => jsonschema.deregisterSchema(s))
|
|
217
225
|
delete this.pluginSchemas[name]
|
|
218
226
|
}
|
|
219
227
|
const schemaPaths = await plugin.getSchemaPaths()
|
|
@@ -221,15 +229,31 @@ class ContentPluginModule extends AbstractApiModule {
|
|
|
221
229
|
const schema = await this.readJson(schemaPath)
|
|
222
230
|
const source = schema?.$patch?.source?.$ref
|
|
223
231
|
if (source) {
|
|
224
|
-
if (!this.pluginSchemas[name]) this.pluginSchemas[name] =
|
|
225
|
-
|
|
226
|
-
this.pluginSchemas[name].push(schema.$anchor)
|
|
232
|
+
if (!this.pluginSchemas[name]) this.pluginSchemas[name] = {}
|
|
233
|
+
this.pluginSchemas[name][schema.$anchor] = schemaPath
|
|
227
234
|
}
|
|
228
235
|
return jsonschema.registerSchema(schemaPath, { replace: true })
|
|
229
236
|
}))
|
|
230
237
|
}))
|
|
231
238
|
}
|
|
232
239
|
|
|
240
|
+
/**
|
|
241
|
+
* Re-registers tracked plugin schemas (called via JsonSchemaModule.registerSchemasHook)
|
|
242
|
+
* @return {Promise}
|
|
243
|
+
*/
|
|
244
|
+
async reregisterPluginSchemas () {
|
|
245
|
+
const jsonschema = await this.app.waitForModule('jsonschema')
|
|
246
|
+
for (const schemas of Object.values(this.pluginSchemas)) {
|
|
247
|
+
for (const schemaPath of Object.values(schemas)) {
|
|
248
|
+
try {
|
|
249
|
+
jsonschema.registerSchema(schemaPath, { replace: true })
|
|
250
|
+
} catch (e) {
|
|
251
|
+
this.log('warn', `failed to re-register plugin schema ${schemaPath}`, e)
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
|
|
233
257
|
/**
|
|
234
258
|
* Returns whether a schema is registered by a plugin
|
|
235
259
|
* @param {String} schemaName Name of the schema to check
|
|
@@ -237,17 +261,17 @@ class ContentPluginModule extends AbstractApiModule {
|
|
|
237
261
|
*/
|
|
238
262
|
isPluginSchema (schemaName) {
|
|
239
263
|
for (const p in this.pluginSchemas) {
|
|
240
|
-
if (this.pluginSchemas[p]
|
|
264
|
+
if (schemaName in this.pluginSchemas[p]) return true
|
|
241
265
|
}
|
|
242
266
|
}
|
|
243
267
|
|
|
244
268
|
/**
|
|
245
269
|
* Returns all schemas registered by a plugin
|
|
246
270
|
* @param {String} pluginName Plugin name
|
|
247
|
-
* @return {Array} List of the plugin's registered
|
|
271
|
+
* @return {Array} List of the plugin's registered schema $anchors
|
|
248
272
|
*/
|
|
249
273
|
getPluginSchemas (pluginName) {
|
|
250
|
-
return this.pluginSchemas[pluginName] ??
|
|
274
|
+
return Object.keys(this.pluginSchemas[pluginName] ?? {})
|
|
251
275
|
}
|
|
252
276
|
|
|
253
277
|
/**
|
|
@@ -391,9 +415,20 @@ class ContentPluginModule extends AbstractApiModule {
|
|
|
391
415
|
*/
|
|
392
416
|
async updatePlugin (_id) {
|
|
393
417
|
const [{ name }] = await this.find({ _id })
|
|
418
|
+
const { readFrameworkPluginVersions } = await import('adapt-authoring-adaptframework')
|
|
419
|
+
const fromPlugins = await readFrameworkPluginVersions(this.framework.path)
|
|
394
420
|
const [pluginData] = await this.framework.runCliCommand('updatePlugins', { plugins: [name] })
|
|
395
421
|
const p = await this.update({ name }, pluginData._sourceInfo)
|
|
396
422
|
await this.processPluginSchemas(pluginData)
|
|
423
|
+
const toPlugins = await readFrameworkPluginVersions(this.framework.path)
|
|
424
|
+
const courses = await this.getPluginUses(_id)
|
|
425
|
+
if (courses.length) {
|
|
426
|
+
await this.framework.migrateCourses({
|
|
427
|
+
fromPlugins,
|
|
428
|
+
toPlugins,
|
|
429
|
+
courseIds: courses.map(c => c._id)
|
|
430
|
+
})
|
|
431
|
+
}
|
|
397
432
|
this.log('info', `successfully updated plugin ${p.name}@${p.version}`)
|
|
398
433
|
return p
|
|
399
434
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "adapt-authoring-contentplugin",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.7.0",
|
|
4
4
|
"description": "Module for managing framework plugins",
|
|
5
5
|
"homepage": "https://github.com/adapt-security/adapt-authoring-contentplugin",
|
|
6
6
|
"repository": "github:adapt-security/adapt-authoring-contentplugin",
|