diff --git a/packages/cli/docs/cli.md b/packages/cli/docs/cli.md index 68c49785a..ebc7ae180 100644 --- a/packages/cli/docs/cli.md +++ b/packages/cli/docs/cli.md @@ -225,6 +225,7 @@ resources convert and relate to different actions. * `key-value pairs...` | The key-value pairs to set. Keys are case-insensitive. Each pair should be space separated and pairs should be separated by an `=`. For example: `A=123 B=456` **Flags** +* `-f, --force` | Force the update of environment variables regardless if the app version is production or not. Use with caution. * `-d, --debug` | Show extra debugging output. **Examples** @@ -242,6 +243,7 @@ resources convert and relate to different actions. * `keys...` | The keys to unset. Keys are case-insensitive. **Flags** +* `-f, --force` | Force the update of environment variables regardless if the app version is production or not. Use with caution. * `-d, --debug` | Show extra debugging output. **Examples** diff --git a/packages/cli/src/oclif/commands/env/set.js b/packages/cli/src/oclif/commands/env/set.js index 9eb677988..d49111026 100644 --- a/packages/cli/src/oclif/commands/env/set.js +++ b/packages/cli/src/oclif/commands/env/set.js @@ -1,4 +1,4 @@ -const { Args } = require('@oclif/core'); +const { Args, Flags } = require('@oclif/core'); const { cyan } = require('colors/safe'); const { omit } = require('lodash'); @@ -45,21 +45,30 @@ class SetEnvCommand extends BaseCommand { } const url = `/apps/${app.id}/versions/${version}/multi-environment`; + const requestOptions = { + body: payload, + method: 'POST', + }; + + if (this.flags.force) { + requestOptions.extraHeaders = { + 'X-Force-Env-Var-Update': 'true', + }; + } try { - // currently, this returns nothing - await callAPI( - url, - { - body: payload, - method: 'POST', - }, - true, - ); + await callAPI(url, requestOptions, true); this.log(successMessage(version)); this.logJSON(payload); } catch (e) { + if (e.statusCode === 409) { + this.error( + `App version ${version} is the production version. Are you sure you want to set potentially live environment variables?` + + ` If so, run this command again with the --force flag.`, + ); + } + // comes back as json: { errors: [ 'The following keys failed to update: 3QER, 4WER' ] }, const failedKeys = e.json.errors[0].split('update: ')[1].split(', '); const successfulResult = omit(payload, failedKeys); @@ -85,7 +94,15 @@ SetEnvCommand.args = { 'The key-value pairs to set. Keys are case-insensitive. Each pair should be space separated and pairs should be separated by an `=`. For example: `A=123 B=456`', }), }; -SetEnvCommand.flags = buildFlags(); +SetEnvCommand.flags = buildFlags({ + commandFlags: { + force: Flags.boolean({ + char: 'f', + description: + 'Force the update of environment variables regardless if the app version is production or not. Use with caution.', + }), + }, +}); SetEnvCommand.description = `Set environment variables for a version.`; SetEnvCommand.examples = [`zapier env:set 1.2.3 SECRET=12345 OTHER=4321`]; SetEnvCommand.strict = false; diff --git a/packages/cli/src/oclif/commands/env/unset.js b/packages/cli/src/oclif/commands/env/unset.js index cc70a655d..5fd09eeb8 100644 --- a/packages/cli/src/oclif/commands/env/unset.js +++ b/packages/cli/src/oclif/commands/env/unset.js @@ -1,4 +1,4 @@ -const { Args } = require('@oclif/core'); +const { Args, Flags } = require('@oclif/core'); const { cyan } = require('colors/safe'); const BaseCommand = require('../../ZapierBaseCommand'); @@ -42,13 +42,29 @@ class UnsetEnvCommand extends BaseCommand { } const url = `/apps/${app.id}/versions/${version}/multi-environment`; - - // currently, this returns nothing - // also, no need to cath errors here, since invalid keys don't get tripped over if the env var didn't exist in the first place - await callAPI(url, { + const requestOptions = { body: payload, method: 'POST', - }); + }; + + if (this.flags.force) { + requestOptions.extraHeaders = { + 'X-Force-Env-Var-Update': 'true', + }; + } + + try { + await callAPI(url, requestOptions); + } catch (e) { + if (e.statusCode === 409) { + this.error( + `App version ${version} is the production version. Are you sure you want to unset potentially live environment variables?` + + ` If so, run this command again with the --force flag.`, + ); + } else { + throw e; + } + } this.log(successMessage(version)); this.logJSON(keysToUnset); @@ -64,7 +80,15 @@ UnsetEnvCommand.args = { description: 'The keys to unset. Keys are case-insensitive.', }), }; -UnsetEnvCommand.flags = buildFlags(); +UnsetEnvCommand.flags = buildFlags({ + commandFlags: { + force: Flags.boolean({ + char: 'f', + description: + 'Force the update of environment variables regardless if the app version is production or not. Use with caution.', + }), + }, +}); UnsetEnvCommand.description = `Unset environment variables for a version.`; UnsetEnvCommand.examples = [`zapier env:unset 1.2.3 SECRET OTHER`]; UnsetEnvCommand.strict = false; diff --git a/packages/cli/src/utils/api.js b/packages/cli/src/utils/api.js index a0691b52f..2ca52d9ec 100644 --- a/packages/cli/src/utils/api.js +++ b/packages/cli/src/utils/api.js @@ -68,6 +68,7 @@ const callAPI = async ( method: options.method || 'GET', body: options.body ? JSON.stringify(options.body) : null, headers: { + ...options.extraHeaders, // extra headers first so they don't override defaults Accept: 'application/json', 'Content-Type': 'application/json; charset=utf-8', 'User-Agent': `${constants.PACKAGE_NAME}/${constants.PACKAGE_VERSION}`,