eas-cli
Version:
EAS command line tool
160 lines (159 loc) • 6.95 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.selectWorkerDeploymentOnAppAsync = exports.assignWorkerDeploymentProductionAsync = exports.assignWorkerDeploymentAliasAsync = exports.assignDevDomainNameAsync = exports.getSignedDeploymentUrlAsync = void 0;
const tslib_1 = require("tslib");
const chalk_1 = tslib_1.__importDefault(require("chalk"));
const mutations_1 = require("./mutations");
const queries_1 = require("./queries");
const logs_1 = require("./utils/logs");
const log_1 = tslib_1.__importDefault(require("../log"));
const prompts_1 = require("../prompts");
const memoize_1 = require("../utils/expodash/memoize");
const relay_1 = require("../utils/relay");
async function getSignedDeploymentUrlAsync(graphqlClient, options) {
try {
return await mutations_1.DeploymentsMutation.createSignedDeploymentUrlAsync(graphqlClient, {
appId: options.appId,
deploymentIdentifier: options.deploymentIdentifier,
});
}
catch (error) {
const isMissingDevDomain = error?.graphQLErrors?.some(e => ['APP_NO_DEV_DOMAIN_NAME'].includes(e?.extensions?.errorCode));
// Throw unexpected errors eagerly
if (!isMissingDevDomain) {
throw error;
}
// Ensure the callback is invoked, containing cleanup logic for possible spinners
options.onSetupDevDomain?.();
// Assign the dev domain name by prompting the user
await assignDevDomainNameAsync({
graphqlClient,
appId: options.appId,
nonInteractive: options.nonInteractive,
});
// Retry creating the signed URL
return await getSignedDeploymentUrlAsync(graphqlClient, options);
}
}
exports.getSignedDeploymentUrlAsync = getSignedDeploymentUrlAsync;
const DEV_DOMAIN_INVALID_START_END_CHARACTERS = /^[^a-z0-9]+|[^a-z0-9-]+$/;
const DEV_DOMAIN_INVALID_REPLACEMENT_HYPHEN = /[^a-z0-9-]+/;
const DEV_DOMAIN_INVALID_MULTIPLE_HYPHENS = /(-{2,})/;
/**
* Format a dev domain name to match whats allowed on the backend.
* This is equal to our `DEV_DOMAIN_NAME_REGEX`, but implemented as a filtering function
* to help users find a valid name while typing.
*/
function formatDevDomainName(name = '') {
return name
.toLowerCase()
.replace(DEV_DOMAIN_INVALID_REPLACEMENT_HYPHEN, '-')
.replace(DEV_DOMAIN_INVALID_START_END_CHARACTERS, '')
.replace(DEV_DOMAIN_INVALID_MULTIPLE_HYPHENS, '-')
.trim();
}
async function promptDevDomainNameAsync(initialDevDomain) {
const rootDomain = `.${logs_1.EXPO_BASE_DOMAIN}.app`;
const memoizedFormatDevDomainName = (0, memoize_1.memoize)(formatDevDomainName);
const { name } = await (0, prompts_1.promptAsync)({
type: 'text',
name: 'name',
message: 'Choose a preview URL for your project:',
initial: initialDevDomain,
validate: (value) => {
if (!value) {
return 'You have to choose a preview URL for your project';
}
if (value.length < 3) {
return 'Preview URLs must be at least 3 characters long';
}
if (value.endsWith('-')) {
return 'Preview URLs cannot end with a hyphen (-)';
}
return true;
},
onState(state) {
const value = memoizedFormatDevDomainName(state.value);
if (value !== state.value) {
this.value = value;
}
},
onRender(kleur) {
this.cursorOffset = -rootDomain.length - 1;
if (this.done) {
// Remove the space for the cursor when the prompt is done
this.rendered = this.value + kleur.dim(`${rootDomain}`);
}
else if (this.placeholder) {
this.rendered = kleur.dim(`${this.initial} ${rootDomain}`);
}
else {
this.rendered = this.value + kleur.dim(` ${rootDomain}`);
}
},
});
// This should never happen due to the validation, if it does its an error
if (!name) {
throw new Error('No preview URL provided, aborting deployment.');
}
return name;
}
/**
* Assign a dev domain name to a project.
* - When running in interactive mode, it will prompt the user with a suggested domain name.
* - When running in non interactive mode, it will auto-assign the suggested domain name.
*/
async function assignDevDomainNameAsync({ graphqlClient, appId, nonInteractive, }) {
let devDomainName = await queries_1.DeploymentsQuery.getSuggestedDevDomainByAppIdAsync(graphqlClient, {
appId,
});
if (!nonInteractive) {
devDomainName = await promptDevDomainNameAsync(devDomainName);
}
try {
return await mutations_1.DeploymentsMutation.assignDevDomainNameAsync(graphqlClient, {
appId,
name: devDomainName,
});
}
catch (error) {
const isChosenNameTaken = error?.graphQLErrors?.some(e => ['DEV_DOMAIN_NAME_TAKEN'].includes(e?.extensions?.errorCode));
// Throw unexpected errors eagerly
if (!isChosenNameTaken) {
throw error;
}
if (!nonInteractive) {
log_1.default.error(`The preview URL "${devDomainName}" is already taken, choose a different URL.`);
}
return await assignDevDomainNameAsync({ graphqlClient, appId, nonInteractive });
}
}
exports.assignDevDomainNameAsync = assignDevDomainNameAsync;
async function assignWorkerDeploymentAliasAsync({ graphqlClient, appId, deploymentId, aliasName, }) {
return await mutations_1.DeploymentsMutation.assignAliasAsync(graphqlClient, {
appId,
deploymentId,
aliasName,
});
}
exports.assignWorkerDeploymentAliasAsync = assignWorkerDeploymentAliasAsync;
async function assignWorkerDeploymentProductionAsync({ graphqlClient, appId, deploymentId, }) {
return await mutations_1.DeploymentsMutation.assignAliasAsync(graphqlClient, {
appId,
deploymentId,
aliasName: null, // this will assign the deployment as production
});
}
exports.assignWorkerDeploymentProductionAsync = assignWorkerDeploymentProductionAsync;
async function selectWorkerDeploymentOnAppAsync({ graphqlClient, appId, selectTitle, pageSize, }) {
return await (0, relay_1.selectPaginatedAsync)({
pageSize: pageSize ?? 25,
printedType: selectTitle ?? 'worker deployment',
queryAsync: async (queryParams) => await queries_1.DeploymentsQuery.getAllDeploymentsPaginatedAsync(graphqlClient, {
...queryParams,
appId,
}),
getTitleAsync: async (deployment) => (0, chalk_1.default) `${deployment.deploymentIdentifier}{dim - created at: ${new Date(deployment.createdAt).toLocaleString()}}`,
});
}
exports.selectWorkerDeploymentOnAppAsync = selectWorkerDeploymentOnAppAsync;
;