eas-cli
Version:
EAS command line tool
187 lines (186 loc) • 10.1 kB
JavaScript
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;
;