UNPKG

eas-cli

Version:
187 lines (186 loc) 10.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const tslib_1 = require("tslib"); const core_1 = require("@oclif/core"); const assert_1 = tslib_1.__importDefault(require("assert")); const chalk_1 = tslib_1.__importDefault(require("chalk")); const fs_extra_1 = tslib_1.__importDefault(require("fs-extra")); const path_1 = tslib_1.__importDefault(require("path")); const EasCommand_1 = tslib_1.__importDefault(require("../../commandUtils/EasCommand")); const flags_1 = require("../../commandUtils/flags"); const EnvironmentSecretMutation_1 = require("../../graphql/mutations/EnvironmentSecretMutation"); const EnvironmentSecretsQuery_1 = require("../../graphql/queries/EnvironmentSecretsQuery"); const EnvironmentSecret_1 = require("../../graphql/types/EnvironmentSecret"); const log_1 = tslib_1.__importDefault(require("../../log")); const projectUtils_1 = require("../../project/projectUtils"); const prompts_1 = require("../../prompts"); class EnvironmentSecretCreate extends EasCommand_1.default { static description = 'create an environment secret on the current project or owner account'; static hidden = true; static flags = { scope: core_1.Flags.enum({ description: 'Scope for the secret', options: [EnvironmentSecretsQuery_1.EnvironmentSecretScope.ACCOUNT, EnvironmentSecretsQuery_1.EnvironmentSecretScope.PROJECT], default: EnvironmentSecretsQuery_1.EnvironmentSecretScope.PROJECT, }), name: core_1.Flags.string({ description: 'Name of the secret', }), value: core_1.Flags.string({ description: 'Text value or path to a file to store in the secret', }), type: core_1.Flags.enum({ description: 'The type of secret', options: [EnvironmentSecret_1.SecretType.STRING, EnvironmentSecret_1.SecretType.FILE], }), force: core_1.Flags.boolean({ description: 'Delete and recreate existing secrets', default: false, }), ...flags_1.EASNonInteractiveFlag, }; static contextDefinition = { ...this.ContextOptions.ProjectId, ...this.ContextOptions.LoggedIn, }; async runAsync() { log_1.default.warn('This command is deprecated. Use eas env:create instead.'); log_1.default.newLine(); let { flags: { name, value: secretValue, scope, force, type: secretType, 'non-interactive': nonInteractive, }, } = await this.parse(EnvironmentSecretCreate); const { projectId, loggedIn: { graphqlClient }, } = await this.getContextAsync(EnvironmentSecretCreate, { nonInteractive, }); const projectDisplayName = await (0, projectUtils_1.getDisplayNameForProjectIdAsync)(graphqlClient, projectId); const ownerAccount = await (0, projectUtils_1.getOwnerAccountForProjectIdAsync)(graphqlClient, projectId); if (!scope) { const validationMessage = 'Secret scope may not be empty.'; if (nonInteractive) { throw new Error(validationMessage); } ({ scope } = await (0, prompts_1.promptAsync)({ type: 'select', name: 'scope', message: 'Where should this secret be used:', choices: [ { title: 'Account-wide', value: EnvironmentSecretsQuery_1.EnvironmentSecretScope.ACCOUNT }, { title: 'Project-specific', value: EnvironmentSecretsQuery_1.EnvironmentSecretScope.PROJECT }, ], validate: value => (value ? true : validationMessage), })); } if (!name) { const validationMessage = 'Secret name may not be empty.'; if (nonInteractive) { throw new Error(validationMessage); } ({ name } = await (0, prompts_1.promptAsync)({ type: 'text', name: 'name', message: `Secret name:`, validate: value => { if (!value) { return validationMessage; } // this validation regex here is just to shorten the feedback loop // the source of truth is in www's EnvironmentSecretValidator class if (!value.match(/^\w+$/)) { return 'Names may contain only letters, numbers, and underscores.'; } return true; }, })); if (!name) { throw new Error(validationMessage); } } if (!secretType) { if (nonInteractive) { throw new Error('Secret type may not be empty in non-interactive mode'); } secretType = await (0, prompts_1.selectAsync)('Select secret type', [ { title: 'string', value: EnvironmentSecret_1.SecretType.STRING, }, { title: 'file', value: EnvironmentSecret_1.SecretType.FILE, }, ]); } if (!secretValue) { const validationMessage = 'Secret value may not be empty.'; if (nonInteractive) { throw new Error(validationMessage); } ({ secretValue } = await (0, prompts_1.promptAsync)({ type: 'text', name: 'secretValue', message: secretType === EnvironmentSecret_1.SecretType.STRING ? 'Secret value:' : 'Local file path:', // eslint-disable-next-line async-protect/async-suffix validate: async (secretValue) => { if (!secretValue) { return validationMessage; } if (secretType === EnvironmentSecret_1.SecretType.FILE) { const secretFilePath = path_1.default.resolve(secretValue); if (!(await fs_extra_1.default.pathExists(secretFilePath))) { return `File "${secretValue}" does not exist.`; } } return true; }, })); } (0, assert_1.default)(secretValue); let secretFilePath; if (secretType === EnvironmentSecret_1.SecretType.FILE) { secretFilePath = path_1.default.resolve(secretValue); if (!(await fs_extra_1.default.pathExists(secretFilePath))) { throw new Error(`File "${secretValue}" does not exist`); } secretValue = await fs_extra_1.default.readFile(secretFilePath, 'base64'); } if (scope === EnvironmentSecretsQuery_1.EnvironmentSecretScope.PROJECT) { if (force) { const { appSecrets: existingSecrets } = await EnvironmentSecretsQuery_1.EnvironmentSecretsQuery.byAppIdAsync(graphqlClient, projectId); const existingSecret = existingSecrets.find(secret => secret.name === name); if (existingSecret) { await EnvironmentSecretMutation_1.EnvironmentSecretMutation.deleteAsync(graphqlClient, existingSecret.id); log_1.default.withTick(`Deleting existing secret ${chalk_1.default.bold(name)} on project ${chalk_1.default.bold(projectDisplayName)}.`); } } const secret = await EnvironmentSecretMutation_1.EnvironmentSecretMutation.createForAppAsync(graphqlClient, { name, value: secretValue, type: EnvironmentSecret_1.SecretTypeToEnvironmentSecretType[secretType] }, projectId); if (!secret) { throw new Error(`Could not create secret with name ${name} on project with id ${projectId}`); } if (secretType === EnvironmentSecret_1.SecretType.STRING) { log_1.default.withTick(`Created a new secret ${chalk_1.default.bold(name)} with value ${chalk_1.default.bold(secretValue)} on project ${chalk_1.default.bold(projectDisplayName)}.`); } else { log_1.default.withTick(`Created a new secret ${chalk_1.default.bold(name)} from file ${chalk_1.default.bold(secretFilePath)} on project ${chalk_1.default.bold(projectDisplayName)}.`); } } else if (scope === EnvironmentSecretsQuery_1.EnvironmentSecretScope.ACCOUNT) { if (force) { const { accountSecrets: existingSecrets } = await EnvironmentSecretsQuery_1.EnvironmentSecretsQuery.byAppIdAsync(graphqlClient, projectId); const existingSecret = existingSecrets.find(secret => secret.name === name); if (existingSecret) { await EnvironmentSecretMutation_1.EnvironmentSecretMutation.deleteAsync(graphqlClient, existingSecret.id); log_1.default.withTick(`Deleting existing secret ${chalk_1.default.bold(name)} on account ${chalk_1.default.bold(ownerAccount.name)}.`); } } const secret = await EnvironmentSecretMutation_1.EnvironmentSecretMutation.createForAccountAsync(graphqlClient, { name, value: secretValue, type: EnvironmentSecret_1.SecretTypeToEnvironmentSecretType[secretType] }, ownerAccount.id); if (!secret) { throw new Error(`Could not create secret with name ${name} on account with id ${ownerAccount.id}`); } if (secretType === EnvironmentSecret_1.SecretType.STRING) { log_1.default.withTick(`Created a new secret ${chalk_1.default.bold(name)} with value ${chalk_1.default.bold(secretValue)} on account ${chalk_1.default.bold(ownerAccount.name)}.`); } else { log_1.default.withTick(`Created a new secret ${chalk_1.default.bold(name)} from file ${chalk_1.default.bold(secretFilePath)} on account ${chalk_1.default.bold(ownerAccount.name)}.`); } } } } exports.default = EnvironmentSecretCreate;