diff --git a/lib/App/index.js b/lib/App/index.js index 7c3a5a3b..08f1251b 100644 --- a/lib/App/index.js +++ b/lib/App/index.js @@ -5,6 +5,7 @@ const { URLSearchParams } = require('url'); +const fs = require('fs'); const Ajv = require('ajv'); const semver = require('semver'); const tinycolor = require('tinycolor2'); @@ -116,6 +117,38 @@ class App { throw new Error('Invalid compatibility'); } + if (appJson.esm === true && semver.lt(semver.coerce(appJson.compatibility), '12.0.0')) { + throw new Error('ESM apps require a compatibility of at least >=12.0.0'); + } + + const checkMjs = async (path) => { + await fs.promises.access(path).then(() => { + if (semver.lt(semver.coerce(appJson.compatibility), '12.0.0')) { + throw new Error(`ESM apps require a compatibility of at least >=12.0.0. (${path})`); + } + }).catch(err => { + if (err.code !== 'ENOENT') { + throw err; + } + }); + }; + + const appFilePath = join(this._path, 'app.mjs'); + const apiFilePath = join(this._path, 'api.mjs'); + + await checkMjs(appFilePath); + await checkMjs(apiFilePath); + + if (Array.isArray(appJson.drivers)) { + for (const driver of appJson.drivers) { + const driverFilePath = join(this._path, 'drivers', driver.id, 'driver.mjs'); + const deviceFilePath = join(this._path, 'drivers', driver.id, 'device.mjs'); + + await checkMjs(driverFilePath); + await checkMjs(deviceFilePath); + } + } + // validate sdk v3 apps have compatibility of at least >=5.0.0 if (appJson.sdk === 3) { // lowest version that satisfies the compatibility