@@ -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