Skip to content

Commit 4808462

Browse files
authored
New: Add hard-limit for framework major version (fixes #142) (#169)
1 parent 8da3fbf commit 4808462

3 files changed

Lines changed: 61 additions & 6 deletions

File tree

adapt-authoring.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
{
22
"documentation": {
33
"enable": true
4+
},
5+
"framework": {
6+
"targetVersion": 5
47
}
58
}

errors/errors.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,5 +126,14 @@
126126
},
127127
"description": "Plugin is missing a dependency",
128128
"statusCode": 500
129+
},
130+
"FW_VERSION_NOT_ALLOWED": {
131+
"data": {
132+
"version": "The version that is not allowed",
133+
"targetMajorVersion": "The allowed major version number",
134+
"allowedRange": "The allowed semver range"
135+
},
136+
"description": "Framework version is outside the allowed major version",
137+
"statusCode": 400
129138
}
130139
}

lib/AdaptFrameworkModule.js

Lines changed: 49 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,13 @@ class AdaptFrameworkModule extends AbstractModule {
7070
*/
7171
this.contentMigrations = []
7272

73+
const meta = await readJson(path.resolve(this.rootDir, 'adapt-authoring.json'))
74+
/**
75+
* The major version of the Adapt framework this module is designed to work with
76+
* @type {Number}
77+
*/
78+
this._targetFrameworkVersion = meta.framework?.targetVersion
79+
7380
this.app.waitForModule('content').then(content => {
7481
content.accessCheckHook.tap(this.checkContentAccess.bind(this))
7582
})
@@ -103,6 +110,36 @@ class AdaptFrameworkModule extends AbstractModule {
103110
return this._version
104111
}
105112

113+
/**
114+
* The major version of the Adapt framework this module is designed to work with
115+
* @type {Number|undefined}
116+
*/
117+
get targetFrameworkVersion () {
118+
return this._targetFrameworkVersion
119+
}
120+
121+
/**
122+
* Returns a semver range string constrained to the target major version, or undefined if no target is set
123+
* @type {String|undefined}
124+
*/
125+
get targetVersionRange () {
126+
if (this._targetFrameworkVersion === undefined) return undefined
127+
return `>=${this._targetFrameworkVersion}.0.0 <${this._targetFrameworkVersion + 1}.0.0`
128+
}
129+
130+
/**
131+
* Checks whether the given version is compatible with the configured target major version
132+
* @param {string} version Semver version string to check
133+
* @throws If the version's major does not match the target major version
134+
*/
135+
checkVersionCompatibility (version) {
136+
if (this._targetFrameworkVersion === undefined) return
137+
const major = semver.major(version)
138+
if (major !== this._targetFrameworkVersion) {
139+
throw this.app.errors.FW_VERSION_NOT_ALLOWED.setData({ version, targetMajorVersion: this._targetFrameworkVersion, allowedRange: this.targetVersionRange })
140+
}
141+
}
142+
106143
/**
107144
* Installs a local copy of the Adapt framework
108145
* @return {Promise}
@@ -121,10 +158,13 @@ class AdaptFrameworkModule extends AbstractModule {
121158
} catch (e) {
122159
// package is missing, an install is required
123160
}
124-
await this.runCliCommand('installFramework', { version })
161+
if (version) {
162+
this.checkVersionCompatibility(version)
163+
}
164+
await this.runCliCommand('installFramework', { version: version ?? this.targetVersionRange })
125165
} catch (e) {
126166
this.log('error', `failed to install framework, ${e.message}`)
127-
throw this.app.errors.FW_INSTALL_FAILED.setData({ reason: e.message })
167+
throw e.statusCode ? e : this.app.errors.FW_INSTALL_FAILED.setData({ reason: e.message })
128168
}
129169
this.log('verbose', 'INSTALL hook invoke')
130170
await this.postInstallHook.invoke()
@@ -136,7 +176,7 @@ class AdaptFrameworkModule extends AbstractModule {
136176
*/
137177
async getLatestVersion () {
138178
try {
139-
return semver.clean(await this.runCliCommand('getLatestFrameworkVersion'))
179+
return semver.clean(await this.runCliCommand('getLatestFrameworkVersion', { version: this.targetVersionRange }))
140180
} catch (e) {
141181
this.log('error', `failed to retrieve framework update data, ${e.message}`)
142182
throw this.app.errors.FW_LATEST_VERSION_FAILED.setData({ reason: e.message })
@@ -167,11 +207,14 @@ class AdaptFrameworkModule extends AbstractModule {
167207
*/
168208
async updateFramework (version) {
169209
try {
170-
await this.runCliCommand('updateFramework', { version })
210+
if (version) {
211+
this.checkVersionCompatibility(version)
212+
}
213+
await this.runCliCommand('updateFramework', { version: version ?? this.targetVersionRange })
171214
this._version = await this.runCliCommand('getCurrentFrameworkVersion')
172215
} catch (e) {
173216
this.log('error', `failed to update framework, ${e.message}`)
174-
throw this.app.errors.FW_UPDATE_FAILED.setData({ reason: e.message })
217+
throw e.statusCode ? e : this.app.errors.FW_UPDATE_FAILED.setData({ reason: e.message })
175218
}
176219
this.postUpdateHook.invoke()
177220
}
@@ -181,7 +224,7 @@ class AdaptFrameworkModule extends AbstractModule {
181224
*/
182225
async logStatus () {
183226
const current = this.version
184-
const latest = await this.runCliCommand('getLatestFrameworkVersion')
227+
const latest = await this.getLatestVersion()
185228

186229
this.log('info', `local adapt_framework v${current} installed`)
187230
if (semver.lt(current, latest)) {

0 commit comments

Comments
 (0)