UNPKG

eas-cli

Version:

EAS command line tool

166 lines (165 loc) 6.32 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.maybePromptForMissingInputsAsync = exports.parseWorkflowInputsFromYaml = exports.parseJsonInputs = exports.parseInputs = exports.WorkflowDispatchInputZ = void 0; const tslib_1 = require("tslib"); const YAML = tslib_1.__importStar(require("yaml")); const zod_1 = require("zod"); const environment_1 = require("../../build/utils/environment"); const types_1 = require("../../credentials/ios/types"); const log_1 = tslib_1.__importDefault(require("../../log")); const prompts_1 = require("../../prompts"); const inputExtraProperties = { description: types_1.stringLike.optional().describe('Description of the input'), required: types_1.booleanLike.default(false).optional().describe('Whether the input is required.'), }; // Adapted from the input definition on the server (https://github.com/expo/universe/pull/21950) exports.WorkflowDispatchInputZ = zod_1.z.discriminatedUnion('type', [ zod_1.z.object({ ...inputExtraProperties, type: zod_1.z.literal('string').default('string').optional(), default: types_1.stringLike.optional().describe('Default value for the input'), }), zod_1.z.object({ ...inputExtraProperties, type: zod_1.z.literal('boolean'), default: types_1.booleanLike.optional().describe('Default value for the input'), }), zod_1.z.object({ ...inputExtraProperties, type: zod_1.z.literal('number'), default: zod_1.z.number().optional().describe('Default value for the input'), }), zod_1.z.object({ ...inputExtraProperties, type: zod_1.z.literal('choice'), default: types_1.stringLike.optional().describe('Default value for the input'), options: zod_1.z.array(types_1.stringLike).min(1).describe('Options for choice type inputs'), }), zod_1.z.object({ ...inputExtraProperties, type: zod_1.z.literal('environment'), default: zod_1.z .enum(Object.values(environment_1.DefaultEnvironment)) .optional() .describe('Default value for the input'), }), ]); function parseInputs(inputFlags) { const inputs = {}; for (const inputFlag of inputFlags) { const equalIndex = inputFlag.indexOf('='); if (equalIndex === -1) { throw new Error(`Invalid input format: ${inputFlag}. Expected key=value format.`); } const key = inputFlag.substring(0, equalIndex); const value = inputFlag.substring(equalIndex + 1); if (!key) { throw new Error(`Invalid input format: ${inputFlag}. Key cannot be empty.`); } inputs[key] = value; } return inputs; } exports.parseInputs = parseInputs; function parseJsonInputs(jsonString) { try { const parsed = JSON.parse(jsonString); if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) { throw new Error('JSON input must be an object.'); } return parsed; } catch (error) { throw new Error(`Invalid JSON input.`, { cause: error }); } } exports.parseJsonInputs = parseJsonInputs; function parseWorkflowInputsFromYaml(yamlConfig) { try { const parsed = YAML.parse(yamlConfig); return zod_1.z .record(zod_1.z.string(), exports.WorkflowDispatchInputZ) .default({}) .parse(parsed?.on?.workflow_dispatch?.inputs); } catch (error) { log_1.default.warn('Failed to parse workflow inputs from YAML:', error); return {}; } } exports.parseWorkflowInputsFromYaml = parseWorkflowInputsFromYaml; async function maybePromptForMissingInputsAsync({ inputSpecs, inputs, }) { const requiredInputs = Object.entries(inputSpecs).filter(([_, spec]) => spec.required); const missingRequiredInputs = requiredInputs.filter(([key]) => inputs[key] === undefined); if (missingRequiredInputs.length === 0) { return inputs; } log_1.default.addNewLineIfNone(); log_1.default.log('Some required inputs are missing. Please provide them:'); const nextInputs = { ...inputs }; for (const [key, spec] of missingRequiredInputs) { const value = await promptForMissingInputAsync({ key, spec }); nextInputs[key] = value; } return nextInputs; } exports.maybePromptForMissingInputsAsync = maybePromptForMissingInputsAsync; async function promptForMissingInputAsync({ key, spec, }) { const message = spec.description ? `${key} (${spec.description})` : key; switch (spec.type) { case 'boolean': { const { value } = await (0, prompts_1.promptAsync)({ type: 'confirm', name: 'value', message, initial: spec.default, }); return value; } case 'number': { const { value } = await (0, prompts_1.promptAsync)({ type: 'number', name: 'value', message, initial: spec.default, validate: (val) => { if (isNaN(val)) { return 'Please enter a valid number'; } return true; }, }); return value; } case 'choice': { const { value } = await (0, prompts_1.promptAsync)({ type: 'select', name: 'value', message, choices: spec.options.map(option => ({ title: option, value: option, })), initial: spec.default, }); return value; } case 'string': case 'environment': default: { const { value } = await (0, prompts_1.promptAsync)({ type: 'text', name: 'value', message, initial: spec.default, validate: (val) => { if (spec.required && (!val || val.trim() === '')) { return 'This field is required'; } return true; }, }); return value; } } }