diff --git a/lib/launcher.js b/lib/launcher.js index 2d0824e..a6ec980 100644 --- a/lib/launcher.js +++ b/lib/launcher.js @@ -62,6 +62,14 @@ class Launcher { debug(`Updating package.json: ${this.files.packageJSON}`) const packageData = JSON.parse(JSON.stringify(packageJSONTemplate)) packageData.dependencies = JSON.parse(JSON.stringify(this.snapshot.modules)) + // if we are working in a development env and the project nodes src is available in the right place, + // then use the development version of the project nodes + if (packageData.dependencies?.['@flowfuse/nr-project-nodes'] && process.env.NODE_ENV === 'development') { + const devPath = path.join(__dirname, '..', '..', 'nr-project-nodes') + if (existsSync(devPath)) { + packageData.dependencies['@flowfuse/nr-project-nodes'] = `file:${devPath}` + } + } packageData.version = `0.0.0-${this.snapshot.id}` packageData.name = this.snapshot.env.FF_PROJECT_NAME if (this.snapshot.name && this.snapshot.description) { @@ -165,12 +173,19 @@ class Launcher { if (this.config.brokerUsername) { // Parse the teamID out of the brokerUsername teamID = this.config.brokerUsername.split(':')[1] + // Determine if projectLink is enabled (default to true if not set in settings for backwards compatibility) + const enabled = !!(this.settings?.features ? this.settings.features.projectComms : true) projectLink = { + featureEnabled: enabled, + // always include the token to permit project enumeration in the project nodes. + // This permits the node to be usable/discoverable but no comms will + // be possible due to the feature being disabled and the broker url/user/pass being empty. + // The project nodes will inform the user of the need to enable or upgrade. token: this.config.token, broker: { - url: this.config.brokerURL, - username: this.config.brokerUsername, - password: this.config.brokerPassword + url: enabled ? this.config.brokerURL : '', + username: enabled ? this.config.brokerUsername : '', + password: enabled ? this.config.brokerPassword : '' } } } @@ -214,7 +229,8 @@ class Launcher { } // if licensed, add shared library config - if (this.config.licensed) { + const libraryEnabled = this.settings?.features ? this.settings.features['shared-library'] : false + if (libraryEnabled && this.config.licensed) { settings.nodesDir = [ path.join(__dirname, 'plugins', 'node_modules', '@flowforge', 'flowforge-library-plugin') ] diff --git a/test/unit/lib/launcher_spec.js b/test/unit/lib/launcher_spec.js index 7688b6f..fad73c9 100644 --- a/test/unit/lib/launcher_spec.js +++ b/test/unit/lib/launcher_spec.js @@ -93,11 +93,39 @@ describe('Launcher', function () { settings.flowforge.should.have.property('projectID', 'PROJECTID') settings.flowforge.should.have.property('projectLink') settings.flowforge.should.have.property('teamID', 'TEAMID') + // by default, since the feature flag is not set, it should be true. + // This is for backwards compatibility where a Node-RED instance has the nodes in their flows + // but the feature flag is not present in the settings. + settings.flowforge.projectLink.should.have.property('featureEnabled', true) settings.flowforge.projectLink.should.have.property('broker') settings.flowforge.projectLink.broker.should.have.property('url', 'BURL') settings.flowforge.projectLink.broker.should.have.property('username', 'BUSER:TEAMID:deviceid') settings.flowforge.projectLink.broker.should.have.property('password', 'BPASS') }) + it('Write Settings - with broker and feature flag `projectComms` false', async function () { + const launcher = newLauncher({ + config: { + ...config, + brokerURL: 'BURL', + brokerUsername: 'BUSER:TEAMID:deviceid', + brokerPassword: 'BPASS' + } + }, null, 'PROJECTID', setup.snapshot, { features: { projectComms: false } }) + await launcher.writeSettings() + const setFile = await fs.readFile(path.join(config.dir, 'project', 'settings.json')) + const settings = JSON.parse(setFile) + settings.should.have.property('port', 1880) + settings.should.have.property('credentialSecret', 'secret') + settings.should.have.property('flowforge') + settings.flowforge.should.have.property('projectID', 'PROJECTID') + settings.flowforge.should.have.property('projectLink') + settings.flowforge.should.have.property('teamID', 'TEAMID') + settings.flowforge.projectLink.should.have.property('featureEnabled', false) // explicitly disabled + settings.flowforge.projectLink.should.have.property('broker') + settings.flowforge.projectLink.broker.should.have.property('url', '') // should be set to empty string + settings.flowforge.projectLink.broker.should.have.property('username', '') // should be set to empty string + settings.flowforge.projectLink.broker.should.have.property('password', '') // should be set to empty string + }) it('Write package.json', async function () { const launcher = newLauncher({ config }, null, 'projectId', setup.snapshot)