adapt-authoring-courseassets 1.4.2 → 1.4.4
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/.github/workflows/releases.yml +8 -22
- package/lib/courseassetsModule.js +44 -13
- package/package.json +3 -29
|
@@ -1,30 +1,16 @@
|
|
|
1
1
|
name: Release
|
|
2
|
+
|
|
2
3
|
on:
|
|
3
4
|
push:
|
|
4
5
|
branches:
|
|
5
6
|
- master
|
|
6
7
|
|
|
8
|
+
permissions:
|
|
9
|
+
contents: write
|
|
10
|
+
issues: write
|
|
11
|
+
pull-requests: write
|
|
12
|
+
id-token: write
|
|
13
|
+
|
|
7
14
|
jobs:
|
|
8
15
|
release:
|
|
9
|
-
|
|
10
|
-
runs-on: ubuntu-latest
|
|
11
|
-
permissions:
|
|
12
|
-
contents: write # to be able to publish a GitHub release
|
|
13
|
-
issues: write # to be able to comment on released issues
|
|
14
|
-
pull-requests: write # to be able to comment on released pull requests
|
|
15
|
-
id-token: write # to enable use of OIDC for trusted publishing and npm provenance
|
|
16
|
-
steps:
|
|
17
|
-
- name: Checkout
|
|
18
|
-
uses: actions/checkout@v4
|
|
19
|
-
with:
|
|
20
|
-
fetch-depth: 0
|
|
21
|
-
- name: Setup Node.js
|
|
22
|
-
uses: actions/setup-node@v4
|
|
23
|
-
with:
|
|
24
|
-
node-version: 'lts/*'
|
|
25
|
-
- name: Install dependencies
|
|
26
|
-
run: npm install
|
|
27
|
-
- name: Release
|
|
28
|
-
env:
|
|
29
|
-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
30
|
-
run: npx semantic-release
|
|
16
|
+
uses: adaptlearning/semantic-release-config/.github/workflows/release.yml@master
|
|
@@ -20,7 +20,7 @@ class CourseAssetsModule extends AbstractApiModule {
|
|
|
20
20
|
async init () {
|
|
21
21
|
await super.init()
|
|
22
22
|
|
|
23
|
-
const [assets, content] = await this.app.waitForModule('assets', 'content')
|
|
23
|
+
const [assets, content, mongodb] = await this.app.waitForModule('assets', 'content', 'mongodb')
|
|
24
24
|
/**
|
|
25
25
|
* Cached module instance for easy access
|
|
26
26
|
* @type {AssetsModule}
|
|
@@ -31,6 +31,10 @@ class CourseAssetsModule extends AbstractApiModule {
|
|
|
31
31
|
* @type {ContentModule}
|
|
32
32
|
*/
|
|
33
33
|
this.content = content
|
|
34
|
+
/** @ignore */
|
|
35
|
+
this.collection = mongodb.getCollection(this.collectionName)
|
|
36
|
+
/** @ignore */
|
|
37
|
+
this.pendingDeletes = { courseIds: new Set(), contentIds: new Set(), promise: null }
|
|
34
38
|
|
|
35
39
|
this.assets.preDeleteHook.tap(this.handleDeletedAsset.bind(this));
|
|
36
40
|
|
|
@@ -54,11 +58,16 @@ class CourseAssetsModule extends AbstractApiModule {
|
|
|
54
58
|
*/
|
|
55
59
|
async handleContentEvent (action, arg1, arg2) {
|
|
56
60
|
if (action === 'delete') {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
this.
|
|
61
|
-
}
|
|
61
|
+
const items = Array.isArray(arg1) ? arg1 : [arg1]
|
|
62
|
+
for (const c of items) {
|
|
63
|
+
if (c._type === 'course') this.pendingDeletes.courseIds.add(c._id.toString())
|
|
64
|
+
else this.pendingDeletes.contentIds.add(c._id.toString())
|
|
65
|
+
}
|
|
66
|
+
if (!this.pendingDeletes.promise) {
|
|
67
|
+
this.pendingDeletes.promise = new Promise(resolve => setImmediate(resolve))
|
|
68
|
+
.then(() => this.flushDeletes())
|
|
69
|
+
}
|
|
70
|
+
return this.pendingDeletes.promise
|
|
62
71
|
}
|
|
63
72
|
const type = arg1._type
|
|
64
73
|
const contentId = arg1._id.toString()
|
|
@@ -68,23 +77,45 @@ class CourseAssetsModule extends AbstractApiModule {
|
|
|
68
77
|
if (!contentId || !courseId) {
|
|
69
78
|
return
|
|
70
79
|
}
|
|
71
|
-
// delete any existing course assets for content
|
|
72
|
-
await this.deleteMany({ courseId, contentId })
|
|
73
|
-
|
|
74
80
|
const data = isModify ? arg2 : arg1
|
|
75
81
|
const schema = await this.content.getSchema(this.content.schemaName, data)
|
|
76
82
|
const ids = extractAssetIds(schema.built.properties, data)
|
|
77
83
|
|
|
84
|
+
if (isModify) {
|
|
85
|
+
const existing = await this.find({ courseId, contentId })
|
|
86
|
+
const existingIds = existing.map(r => r.assetId.toString()).sort()
|
|
87
|
+
if (ids.length === existingIds.length && ids.slice().sort().every((id, i) => id === existingIds[i])) {
|
|
88
|
+
return
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
// delete any existing course assets for content
|
|
92
|
+
await this.collection.deleteMany({ courseId, contentId })
|
|
93
|
+
|
|
78
94
|
if (!ids.length) {
|
|
79
95
|
return
|
|
80
96
|
}
|
|
81
|
-
await
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
97
|
+
const found = await this.assets.find({ _id: { $in: ids } })
|
|
98
|
+
const foundIds = new Set(found.map(a => a._id.toString()))
|
|
99
|
+
const validIds = ids.filter(id => foundIds.has(id))
|
|
100
|
+
|
|
101
|
+
if (validIds.length) {
|
|
102
|
+
const docs = validIds.map(assetId => ({ courseId, contentId, assetId }))
|
|
103
|
+
await this.collection.insertMany(docs)
|
|
104
|
+
}
|
|
85
105
|
this.log('debug', 'UPDATE', courseId, contentId)
|
|
86
106
|
}
|
|
87
107
|
|
|
108
|
+
async flushDeletes () {
|
|
109
|
+
const { courseIds, contentIds } = this.pendingDeletes
|
|
110
|
+
this.pendingDeletes = { courseIds: new Set(), contentIds: new Set(), promise: null }
|
|
111
|
+
|
|
112
|
+
const ops = []
|
|
113
|
+
if (courseIds.size) ops.push(this.collection.deleteMany({ courseId: { $in: [...courseIds] } }))
|
|
114
|
+
if (contentIds.size) ops.push(this.collection.deleteMany({ contentId: { $in: [...contentIds] } }))
|
|
115
|
+
await Promise.all(ops)
|
|
116
|
+
this.log('debug', 'DELETE', `${courseIds.size} courses, ${contentIds.size} content items`)
|
|
117
|
+
}
|
|
118
|
+
|
|
88
119
|
async handleDeletedAsset (asset) {
|
|
89
120
|
const results = await this.find({ assetId: asset._id })
|
|
90
121
|
if (!results.length) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "adapt-authoring-courseassets",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.4",
|
|
4
4
|
"description": "Module for managing course asset usage",
|
|
5
5
|
"homepage": "https://github.com/adapt-security/adapt-authoring-courseassets",
|
|
6
6
|
"license": "GPL-3.0",
|
|
@@ -16,37 +16,11 @@
|
|
|
16
16
|
"adapt-authoring-core": "^2.0.0"
|
|
17
17
|
},
|
|
18
18
|
"devDependencies": {
|
|
19
|
-
"@semantic-release
|
|
20
|
-
"conventional-changelog-eslint": "^6.0.0",
|
|
21
|
-
"semantic-release": "^25.0.2",
|
|
19
|
+
"@adaptlearning/semantic-release-config": "^1.0.0",
|
|
22
20
|
"standard": "^17.1.0"
|
|
23
21
|
},
|
|
24
22
|
"release": {
|
|
25
|
-
"
|
|
26
|
-
[
|
|
27
|
-
"@semantic-release/commit-analyzer",
|
|
28
|
-
{
|
|
29
|
-
"preset": "eslint"
|
|
30
|
-
}
|
|
31
|
-
],
|
|
32
|
-
[
|
|
33
|
-
"@semantic-release/release-notes-generator",
|
|
34
|
-
{
|
|
35
|
-
"preset": "eslint"
|
|
36
|
-
}
|
|
37
|
-
],
|
|
38
|
-
"@semantic-release/npm",
|
|
39
|
-
"@semantic-release/github",
|
|
40
|
-
[
|
|
41
|
-
"@semantic-release/git",
|
|
42
|
-
{
|
|
43
|
-
"assets": [
|
|
44
|
-
"package.json"
|
|
45
|
-
],
|
|
46
|
-
"message": "Chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"
|
|
47
|
-
}
|
|
48
|
-
]
|
|
49
|
-
]
|
|
23
|
+
"extends": "@adaptlearning/semantic-release-config"
|
|
50
24
|
},
|
|
51
25
|
"scripts": {
|
|
52
26
|
"test": "node --test 'tests/**/*.spec.js'"
|