diff --git a/packages/expo-cli/src/accounts.ts b/packages/expo-cli/src/accounts.ts index 1d68d22f68..25bb83379f 100644 --- a/packages/expo-cli/src/accounts.ts +++ b/packages/expo-cli/src/accounts.ts @@ -6,8 +6,8 @@ import invariant from 'invariant'; import CommandError from './CommandError'; import log from './log'; -import prompt, { Question } from './prompt'; import promptNew, { confirmAsync, Question as NewQuestion, selectAsync } from './prompts'; +import { nonEmptyInput } from './validators'; UserManager.initialize(); @@ -42,27 +42,27 @@ export async function loginOrRegisterAsync(): Promise { ); } - const question: Question = { - type: 'list', + const question: NewQuestion = { + type: 'select', name: 'action', message: 'How would you like to authenticate?', choices: [ { - name: 'Make a new Expo account', + title: 'Make a new Expo account', value: 'register', }, { - name: 'Log in with an existing Expo account', + title: 'Log in with an existing Expo account', value: 'existingUser', }, { - name: 'Cancel', + title: 'Cancel', value: 'cancel', }, ], }; - const { action } = await prompt(question); + const { action } = await promptNew(question); if (action === 'register') { return register(); @@ -212,7 +212,7 @@ async function _promptForBackupOTPAsync( * OTP (or backup code) and also give the user a way to cancel and move to case 3 below. * 3. User doesn't have a primary device or doesn't have access to their primary device. In this case * we should show a picker of the SMS devices that they can have an OTP code sent to, and when - * the user picks one we show a prompt for the sent OTP. + * the user picks one we show a prompt() for the sent OTP. */ export async function _retryUsernamePasswordAuthWithOTPAsync( username: string, @@ -268,18 +268,14 @@ async function _usernamePasswordAuth( password?: string, otp?: string ): Promise { - const questions: Question[] = []; + const questions: NewQuestion[] = []; if (!username) { questions.push({ - type: 'input', + type: 'text', name: 'username', message: 'Username/Email Address:', - validate(val: string) { - if (val.trim() === '') { - return false; - } - return true; - }, + format: val => val.trim(), + validate: nonEmptyInput, }); } @@ -288,16 +284,12 @@ async function _usernamePasswordAuth( type: 'password', name: 'password', message: 'Password:', - validate(val: string) { - if (val.trim() === '') { - return false; - } - return true; - }, + format: val => val.trim(), + validate: nonEmptyInput, }); } - const answers = await prompt(questions); + const answers = await promptNew(questions); const data = { username: username || answers.username, @@ -336,36 +328,26 @@ Just a few questions: ` ); - const questions: Question[] = [ + const questions: NewQuestion[] = [ { - type: 'input', + type: 'text', name: 'email', message: 'E-mail:', - filter: val => val.trim(), - validate(val) { - if (val.trim() === '') { - return false; - } - return true; - }, + format: val => val.trim(), + validate: nonEmptyInput, }, { - type: 'input', + type: 'text', name: 'username', message: 'Username:', - filter: val => val.trim(), - validate(val) { - if (val.trim() === '') { - return false; - } - return true; - }, + format: val => val.trim(), + validate: nonEmptyInput, }, { type: 'password', name: 'password', message: 'Password:', - filter: val => val.trim(), + format: val => val.trim(), validate(val) { if (val.trim() === '') { return 'Please create a password'; @@ -377,6 +359,7 @@ Just a few questions: type: 'password', name: 'passwordRepeat', message: 'Confirm Password:', + format: val => val.trim(), validate(val, answers) { if (val.trim() === '') { return false; @@ -388,7 +371,7 @@ Just a few questions: }, }, ]; - const answers = await prompt(questions); + const answers = await promptNew(questions); const registeredUser = await UserManager.registerAsync(answers as RegistrationData); log('\nThanks for signing up!'); return registeredUser; diff --git a/packages/expo-cli/src/appleApi/authenticate.ts b/packages/expo-cli/src/appleApi/authenticate.ts index 0c3bf11a10..ac001dbcac 100644 --- a/packages/expo-cli/src/appleApi/authenticate.ts +++ b/packages/expo-cli/src/appleApi/authenticate.ts @@ -4,7 +4,7 @@ import wordwrap from 'wordwrap'; import { learnMore } from '../commands/utils/TerminalLink'; import log from '../log'; -import prompt from '../prompt'; +import prompt from '../prompts'; import { nonEmptyInput } from '../validators'; import { runAction, travelingFastlane } from './fastlane'; import * as Keychain from './keychain'; @@ -133,12 +133,12 @@ async function _promptForAppleId({ const { appleId: promptAppleId } = await prompt( { - type: 'input', + type: 'text', name: 'appleId', message: `Apple ID:`, validate: nonEmptyInput, - default: lastAppleId ?? undefined, - ...(previousAppleId && { default: previousAppleId }), + initial: lastAppleId ?? undefined, + ...(previousAppleId && { initial: previousAppleId }), }, { nonInteractiveHelp: 'Pass your Apple ID using the --apple-id flag.', @@ -205,12 +205,12 @@ async function _chooseTeam(teams: FastlaneTeam[], userProvidedTeamId?: string): } else { log(`You have ${teams.length} teams associated with your account`); const choices = teams.map((team, i) => ({ - name: `${i + 1}) ${team.teamId} "${team.name}" (${team.type})`, + title: `${i + 1}) ${team.teamId} "${team.name}" (${team.type})`, value: team, })); const { team } = await prompt( { - type: 'list', + type: 'select', name: 'team', message: 'Which team would you like to use?', choices, diff --git a/packages/expo-cli/src/askUser.ts b/packages/expo-cli/src/askUser.ts index 054c15a29d..742cb4e6e0 100644 --- a/packages/expo-cli/src/askUser.ts +++ b/packages/expo-cli/src/askUser.ts @@ -1,7 +1,7 @@ import { UserSettings } from '@expo/xdl'; import log from './log'; -import prompt from './prompt'; +import prompt from './prompts'; async function askForSendToAsync(): Promise { const cachedValue = await UserSettings.getAsync('sendTo', null); @@ -9,10 +9,10 @@ async function askForSendToAsync(): Promise { const answers = await prompt( [ { - type: 'input', + type: 'text', name: 'sendTo', message: `Your email address ${cachedValue ? ' (space to not send anything)' : ''}:`, - default: cachedValue ?? undefined, + initial: cachedValue ?? undefined, }, ], { nonInteractiveHelp: 'Please specify email address with --send-to.' } diff --git a/packages/expo-cli/src/commands/client/index.ts b/packages/expo-cli/src/commands/client/index.ts index 40c27c5b80..e12f12db54 100644 --- a/packages/expo-cli/src/commands/client/index.ts +++ b/packages/expo-cli/src/commands/client/index.ts @@ -18,8 +18,7 @@ import { CreateOrReuseProvisioningProfileAdhoc } from '../../credentials/views/I import { SetupIosDist } from '../../credentials/views/SetupIosDist'; import { SetupIosPush } from '../../credentials/views/SetupIosPush'; import log from '../../log'; -import prompt from '../../prompt'; -import { confirmAsync } from '../../prompts'; +import prompt, { confirmAsync } from '../../prompts'; import urlOpts from '../../urlOpts'; import * as ClientUpgradeUtils from '../utils/ClientUpgradeUtils'; import { createClientBuildRequest, getExperienceName, isAllowedToBuild } from './clientBuildApi'; @@ -211,10 +210,11 @@ export default function (program: Command) { email = user.email; } else { ({ email } = await prompt({ + type: 'text', name: 'email', message: 'Please enter an email address to notify, when the build is completed:', - default: context?.user?.email, - filter: value => value.trim(), + initial: context?.user?.email, + format: value => value.trim(), validate: (value: string) => /.+@.+/.test(value) ? true : "That doesn't look like a valid email.", })); diff --git a/packages/expo-cli/src/commands/eject/ConfigValidation.ts b/packages/expo-cli/src/commands/eject/ConfigValidation.ts index 2d03b221b3..aad2d19030 100644 --- a/packages/expo-cli/src/commands/eject/ConfigValidation.ts +++ b/packages/expo-cli/src/commands/eject/ConfigValidation.ts @@ -3,8 +3,7 @@ import { UserManager } from '@expo/xdl'; import got from 'got'; import log from '../../log'; -import prompt from '../../prompt'; -import { confirmAsync } from '../../prompts'; +import prompt, { confirmAsync } from '../../prompts'; import { learnMore } from '../utils/TerminalLink'; import { isUrlAvailableAsync } from '../utils/url'; @@ -133,15 +132,14 @@ export async function getOrPromptForBundleIdentifier(projectRoot: string): Promi // prompt a better error message, recommend a default value, and help the user // validate their custom bundle ID upfront. const { bundleIdentifier } = await prompt( - [ - { - name: 'bundleIdentifier', - default: recommendedBundleId, - // The Apple helps people know this isn't an EAS feature. - message: `What would you like your iOS bundle identifier to be?`, - validate: validateBundleId, - }, - ], + { + type: 'text', + name: 'bundleIdentifier', + initial: recommendedBundleId, + // The Apple helps people know this isn't an EAS feature. + message: `What would you like your iOS bundle identifier to be?`, + validate: validateBundleId, + }, { nonInteractiveHelp: noBundleIdMessage, } @@ -220,14 +218,13 @@ export async function getOrPromptForPackage(projectRoot: string): Promise val !== '', + type: 'text', + validate: nonEmptyInput, }); return androidPackage; } else { diff --git a/packages/expo-cli/src/commands/upload/submission-service/android/ServiceAccountSource.ts b/packages/expo-cli/src/commands/upload/submission-service/android/ServiceAccountSource.ts index 2337e04f17..8d01ffb26e 100644 --- a/packages/expo-cli/src/commands/upload/submission-service/android/ServiceAccountSource.ts +++ b/packages/expo-cli/src/commands/upload/submission-service/android/ServiceAccountSource.ts @@ -1,5 +1,5 @@ import log from '../../../../log'; -import prompt from '../../../../prompt'; +import prompt from '../../../../prompts'; import { existingFile } from '../../../../validators'; import { learnMore } from '../../../utils/TerminalLink'; @@ -62,8 +62,8 @@ async function askForServiceAccountPathAsync(): Promise { const { filePath } = await prompt({ name: 'filePath', message: 'Path to Google Service Account file:', - default: 'api-0000000000000000000-111111-aaaaaabbbbbb.json', - type: 'input', + initial: 'api-0000000000000000000-111111-aaaaaabbbbbb.json', + type: 'text', validate: async (path: string): Promise => { if (!(await existingFile(path, false))) { return `File ${path} doesn't exist.`; diff --git a/packages/expo-cli/src/commands/upload/submission-service/android/__tests__/ServiceAccountSource-test.ts b/packages/expo-cli/src/commands/upload/submission-service/android/__tests__/ServiceAccountSource-test.ts index bcb273a01e..0aa9583aa5 100644 --- a/packages/expo-cli/src/commands/upload/submission-service/android/__tests__/ServiceAccountSource-test.ts +++ b/packages/expo-cli/src/commands/upload/submission-service/android/__tests__/ServiceAccountSource-test.ts @@ -1,6 +1,6 @@ import { vol } from 'memfs'; -import prompt from '../../../../../prompt'; +import prompt from '../../../../../prompts'; import { getServiceAccountAsync, ServiceAccountSource, @@ -8,7 +8,7 @@ import { } from '../ServiceAccountSource'; jest.mock('fs'); -jest.mock('../../../../../prompt'); +jest.mock('../../../../../prompts'); describe(getServiceAccountAsync, () => { beforeAll(() => { diff --git a/packages/expo-cli/src/commands/upload/submission-service/archive-source/ArchiveFileSource.ts b/packages/expo-cli/src/commands/upload/submission-service/archive-source/ArchiveFileSource.ts index 75b984ffe8..e98dfa2a3a 100644 --- a/packages/expo-cli/src/commands/upload/submission-service/archive-source/ArchiveFileSource.ts +++ b/packages/expo-cli/src/commands/upload/submission-service/archive-source/ArchiveFileSource.ts @@ -3,7 +3,7 @@ import { StandaloneBuild } from '@expo/xdl'; import validator from 'validator'; import log from '../../../../log'; -import prompt from '../../../../prompt'; +import prompt from '../../../../prompts'; import { existingFile } from '../../../../validators'; import { getAppConfig } from '../utils/config'; import { @@ -170,20 +170,20 @@ async function handleBuildIdSourceAsync(source: ArchiveFileBuildIdSource): Promi async function handlePromptSourceAsync(source: ArchiveFilePromptSource): Promise { const { sourceType: sourceTypeRaw } = await prompt({ name: 'sourceType', - type: 'list', + type: 'select', message: 'What would you like to submit?', choices: [ - { name: 'I have a url to the app archive', value: ArchiveFileSourceType.url }, + { title: 'I have a url to the app archive', value: ArchiveFileSourceType.url }, { - name: "I'd like to upload the app archive from my computer", + title: "I'd like to upload the app archive from my computer", value: ArchiveFileSourceType.path, }, { - name: 'The latest build from Expo servers', + title: 'The latest build from Expo servers', value: ArchiveFileSourceType.latest, }, { - name: 'A build identified by a build id', + title: 'A build identified by a build id', value: ArchiveFileSourceType.buildId, }, ], @@ -234,8 +234,8 @@ async function askForArchiveUrlAsync(): Promise { const { url } = await prompt({ name: 'url', message: 'URL:', - default: defaultArchiveUrl, - type: 'input', + initial: defaultArchiveUrl, + type: 'text', validate: (url: string): string | boolean => { if (url === defaultArchiveUrl) { return 'That was just an example URL, meant to show you the format that we expect for the response.'; @@ -254,8 +254,8 @@ async function askForArchivePathAsync(): Promise { const { path } = await prompt({ name: 'path', message: 'Path to the app archive file (aab or apk):', - default: defaultArchivePath, - type: 'input', + initial: defaultArchivePath, + type: 'text', validate: async (path: string): Promise => { if (path === defaultArchivePath) { return 'That was just an example path, meant to show you the format that we expect for the response.'; @@ -273,7 +273,7 @@ async function askForBuildIdAsync(): Promise { const { id } = await prompt({ name: 'id', message: 'Build ID:', - type: 'input', + type: 'text', validate: (val: string): string | boolean => { if (!validator.isUUID(val)) { return `${val} is not a valid id`; diff --git a/packages/expo-cli/src/commands/upload/submission-service/archive-source/ArchiveTypeSource.ts b/packages/expo-cli/src/commands/upload/submission-service/archive-source/ArchiveTypeSource.ts index 20dc95d809..eff8629277 100644 --- a/packages/expo-cli/src/commands/upload/submission-service/archive-source/ArchiveTypeSource.ts +++ b/packages/expo-cli/src/commands/upload/submission-service/archive-source/ArchiveTypeSource.ts @@ -1,5 +1,5 @@ import log from '../../../../log'; -import prompt from '../../../../prompt'; +import prompt from '../../../../prompts'; import { ArchiveType } from '../android/AndroidSubmissionConfig'; enum ArchiveTypeSourceType { @@ -83,11 +83,11 @@ async function handlePromptSourceAsync( const inferredArchiveType = inferArchiveTypeFromLocation(location); const { archiveType: archiveTypeRaw } = await prompt({ name: 'archiveType', - type: 'list', + type: 'select', message: "What's the archive type?", choices: [ - { name: 'APK', value: ArchiveType.apk }, - { name: 'AAB', value: ArchiveType.aab }, + { title: 'APK', value: ArchiveType.apk }, + { title: 'AAB', value: ArchiveType.aab }, ], ...(inferredArchiveType && { default: inferredArchiveType }), }); diff --git a/packages/expo-cli/src/commands/utils/ClientUpgradeUtils.ts b/packages/expo-cli/src/commands/utils/ClientUpgradeUtils.ts index fac386d034..eba398fd50 100644 --- a/packages/expo-cli/src/commands/utils/ClientUpgradeUtils.ts +++ b/packages/expo-cli/src/commands/utils/ClientUpgradeUtils.ts @@ -2,7 +2,7 @@ import * as ConfigUtils from '@expo/config'; import { Versions } from '@expo/xdl'; import chalk from 'chalk'; -import prompt from '../../prompt'; +import prompt from '../../prompts'; import { findProjectRootAsync } from './ProjectUtils'; export async function getExpoSdkConfig(path: string) { @@ -89,10 +89,10 @@ interface InstallClientOptions { export async function askClientToInstall(options: InstallClientOptions): Promise { const answer = await prompt({ - type: 'list', + type: 'select', name: 'targetClient', message: 'Choose an SDK version to install the client for:', - pageSize: 20, + optionsPerPage: 20, choices: options.clients.map(client => { const clientVersion = `- client ${client.clientVersion || 'version unknown'}`; const clientLabels = [ @@ -106,7 +106,7 @@ export async function askClientToInstall(options: InstallClientOptions): Promise return { value: client, - name: `${chalk.bold(client.sdkVersionString)} ${chalk.gray(clientMessage)}`, + title: `${chalk.bold(client.sdkVersionString)} ${chalk.gray(clientMessage)}`, }; }), }); diff --git a/packages/expo-cli/src/credentials/views/AndroidCredentials.ts b/packages/expo-cli/src/credentials/views/AndroidCredentials.ts index 78703d3dd2..2a4eafce35 100644 --- a/packages/expo-cli/src/credentials/views/AndroidCredentials.ts +++ b/packages/expo-cli/src/credentials/views/AndroidCredentials.ts @@ -1,7 +1,7 @@ import isEmpty from 'lodash/isEmpty'; import log from '../../log'; -import prompt from '../../prompt'; +import prompt from '../../prompts'; import { displayAndroidAppCredentials } from '../actions/list'; import { Context, IView } from '../context'; import { DownloadKeystore, RemoveKeystore, UpdateKeystore } from './AndroidKeystore'; @@ -21,25 +21,23 @@ class ExperienceView implements IView { log.newLine(); } - const { action } = await prompt([ - { - type: 'list', - name: 'action', - message: 'What do you want to do?', - choices: [ - { value: 'update-keystore', name: 'Update upload Keystore' }, - { value: 'remove-keystore', name: 'Remove keystore' }, - { value: 'update-fcm-key', name: 'Update FCM Api Key' }, - { value: 'fetch-keystore', name: 'Download Keystore from the Expo servers' }, - // { value: 'fetch-public-cert', name: 'Extract public cert from Keystore' }, - // { - // value: 'fetch-private-signing-key', - // name: - // 'Extract private signing key (required when migration to App Signing by Google Play)', - // }, - ], - }, - ]); + const { action } = await prompt({ + type: 'select', + name: 'action', + message: 'What do you want to do?', + choices: [ + { value: 'update-keystore', title: 'Update upload Keystore' }, + { value: 'remove-keystore', title: 'Remove keystore' }, + { value: 'update-fcm-key', title: 'Update FCM Api Key' }, + { value: 'fetch-keystore', title: 'Download Keystore from the Expo servers' }, + // { value: 'fetch-public-cert', title: 'Extract public cert from Keystore' }, + // { + // value: 'fetch-private-signing-key', + // title: + // 'Extract private signing key (required when migration to App Signing by Google Play)', + // }, + ], + }); return this.handleAction(ctx, action); } diff --git a/packages/expo-cli/src/credentials/views/AndroidPushCredentials.ts b/packages/expo-cli/src/credentials/views/AndroidPushCredentials.ts index 28e5d84c57..4a73188911 100644 --- a/packages/expo-cli/src/credentials/views/AndroidPushCredentials.ts +++ b/packages/expo-cli/src/credentials/views/AndroidPushCredentials.ts @@ -2,7 +2,7 @@ import chalk from 'chalk'; import CommandError from '../../CommandError'; import log from '../../log'; -import prompt from '../../prompt'; +import prompt from '../../prompts'; import { Context, IView } from '../context'; export class UpdateFcmKey implements IView { @@ -16,14 +16,12 @@ export class UpdateFcmKey implements IView { ); } - const { fcmApiKey } = await prompt([ - { - type: 'input', - name: 'fcmApiKey', - message: 'FCM Api Key', - validate: value => value.length > 0 || "FCM Api Key can't be empty", - }, - ]); + const { fcmApiKey } = await prompt({ + type: 'text', + name: 'fcmApiKey', + message: 'FCM Api Key', + validate: (value: string) => value.length > 0 || "FCM Api Key can't be empty", + }); await ctx.android.updateFcmKey(this.experienceName, fcmApiKey); log(chalk.green('Updated successfully')); diff --git a/packages/expo-cli/src/credentials/views/IosDistCert.ts b/packages/expo-cli/src/credentials/views/IosDistCert.ts index fd7ee7f223..54941e2424 100644 --- a/packages/expo-cli/src/credentials/views/IosDistCert.ts +++ b/packages/expo-cli/src/credentials/views/IosDistCert.ts @@ -8,8 +8,7 @@ import terminalLink from 'terminal-link'; import CommandError from '../../CommandError'; import { DistCert, DistCertInfo, DistCertManager, isDistCert } from '../../appleApi'; import log from '../../log'; -import prompt, { Question } from '../../prompt'; -import { confirmAsync } from '../../prompts'; +import prompt, { confirmAsync, Question } from '../../prompts'; import { displayIosUserCredentials } from '../actions/list'; import { askForUserProvided, CredentialSchema } from '../actions/promptForCredentials'; import { AppLookupParams, getAppLookupParams } from '../api/IosApi'; @@ -259,18 +258,18 @@ export class CreateOrReuseDistributionCert implements IView { async _createOrReuse(ctx: Context): Promise { const choices = [ { - name: '[Choose existing certificate] (Recommended)', + title: '[Choose existing certificate] (Recommended)', value: 'CHOOSE_EXISTING', }, - { name: '[Add a new certificate]', value: 'GENERATE' }, + { title: '[Add a new certificate]', value: 'GENERATE' }, ]; const question: Question = { - type: 'list', + type: 'select', name: 'action', message: 'Select an iOS distribution certificate to use for code signing:', choices, - pageSize: Infinity, + optionsPerPage: 20, }; const { action } = await prompt(question); @@ -344,11 +343,11 @@ async function selectDistCertFromList( } const question: Question = { - type: 'list', + type: 'select', name: 'credentialsIndex', message: 'Select certificate from the list.', choices: distCerts.map((entry, index) => ({ - name: formatDistCert(entry, iosCredentials, getValidityStatus(entry, validDistCerts)), + title: formatDistCert(entry, iosCredentials, getValidityStatus(entry, validDistCerts)), value: index, })), }; @@ -460,14 +459,14 @@ async function generateDistCert(ctx: Context, accountName: string): Promise ({ value: index, - name: formatDistCertFromApple(cert, credentials), + title: formatDistCertFromApple(cert, credentials), })), - pageSize: Infinity, }, ]); diff --git a/packages/expo-cli/src/credentials/views/IosProvisioningProfile.ts b/packages/expo-cli/src/credentials/views/IosProvisioningProfile.ts index fc5c25446c..b18db9fdef 100644 --- a/packages/expo-cli/src/credentials/views/IosProvisioningProfile.ts +++ b/packages/expo-cli/src/credentials/views/IosProvisioningProfile.ts @@ -14,8 +14,7 @@ import { ProvisioningProfileManager, } from '../../appleApi'; import log from '../../log'; -import prompt, { Question } from '../../prompt'; -import { confirmAsync } from '../../prompts'; +import prompt, { confirmAsync, Question } from '../../prompts'; import { displayIosAppCredentials } from '../actions/list'; import { askForUserProvided } from '../actions/promptForCredentials'; import { AppLookupParams, getAppLookupParams } from '../api/IosApi'; @@ -184,18 +183,18 @@ export class CreateOrReuseProvisioningProfile implements IView { async _createOrReuse(ctx: Context): Promise { const choices = [ { - name: '[Choose existing provisioning profile] (Recommended)', + title: '[Choose existing provisioning profile] (Recommended)', value: 'CHOOSE_EXISTING', }, - { name: '[Add a new provisioning profile]', value: 'GENERATE' }, + { title: '[Add a new provisioning profile]', value: 'GENERATE' }, ]; const question: Question = { - type: 'list', + type: 'select', name: 'action', message: 'Select a Provisioning Profile:', choices, - pageSize: Infinity, + optionsPerPage: 20, }; const { action } = await prompt(question); @@ -224,11 +223,11 @@ async function selectProfileFromApple( } const question: Question = { - type: 'list', + type: 'select', name: 'credentialsIndex', message: 'Select Provisioning Profile from the list.', choices: profiles.map((entry, index) => ({ - name: formatProvisioningProfileFromApple(entry), + title: formatProvisioningProfileFromApple(entry), value: index, })), }; @@ -254,11 +253,11 @@ async function selectProfileFromExpo( }; const question: Question = { - type: 'list', + type: 'select', name: 'credentialsIndex', message: 'Select Provisioning Profile from the list.', choices: profiles.map((entry, index) => ({ - name: getName(entry), + title: getName(entry), value: index, })), }; diff --git a/packages/expo-cli/src/credentials/views/IosPushCredentials.ts b/packages/expo-cli/src/credentials/views/IosPushCredentials.ts index 3afbe5224e..2b8159de6f 100644 --- a/packages/expo-cli/src/credentials/views/IosPushCredentials.ts +++ b/packages/expo-cli/src/credentials/views/IosPushCredentials.ts @@ -6,8 +6,7 @@ import terminalLink from 'terminal-link'; import CommandError from '../../CommandError'; import { isPushKey, PushKey, PushKeyInfo, PushKeyManager } from '../../appleApi'; import log from '../../log'; -import prompt, { Question } from '../../prompt'; -import { confirmAsync } from '../../prompts'; +import prompt, { confirmAsync, Question } from '../../prompts'; import { displayIosUserCredentials } from '../actions/list'; import { askForUserProvided, CredentialSchema } from '../actions/promptForCredentials'; import { AppLookupParams, getAppLookupParams } from '../api/IosApi'; @@ -283,18 +282,17 @@ export class CreateOrReusePushKey implements IView { async _createOrReuse(ctx: Context): Promise { const choices = [ { - name: '[Choose existing push key] (Recommended)', + title: '[Choose existing push key] (Recommended)', value: 'CHOOSE_EXISTING', }, - { name: '[Add a new push key]', value: 'GENERATE' }, + { title: '[Add a new push key]', value: 'GENERATE' }, ]; const question: Question = { - type: 'list', + type: 'select', name: 'action', message: 'Select an iOS push key to use for push notifications:', choices, - pageSize: Infinity, }; const { action } = await prompt(question); @@ -388,11 +386,11 @@ async function selectPushCredFromList( }; const question: Question = { - type: 'list', + type: 'select', name: 'credentialsIndex', message: 'Select credentials from list', choices: pushCredentials.map((entry, index) => ({ - name: getName(entry), + title: getName(entry), value: index, })), }; @@ -503,14 +501,14 @@ async function generatePushKey(ctx: Context, accountName: string): Promise ({ value: index, - name: formatPushKeyFromApple(key, credentials), + title: formatPushKeyFromApple(key, credentials), })), - pageSize: Infinity, + optionsPerPage: 20, }, ]); diff --git a/packages/expo-cli/src/credentials/views/Select.ts b/packages/expo-cli/src/credentials/views/Select.ts index 70f7ecf09a..26306bc547 100644 --- a/packages/expo-cli/src/credentials/views/Select.ts +++ b/packages/expo-cli/src/credentials/views/Select.ts @@ -1,7 +1,6 @@ import invariant from 'invariant'; -import prompt, { ChoiceType, Question } from '../../prompt'; -import { confirmAsync } from '../../prompts'; +import prompts, { confirmAsync } from '../../prompts'; import { displayAndroidCredentials, displayIosCredentials } from '../actions/list'; import { AppLookupParams } from '../api/IosApi'; import { Context, IView } from '../context'; @@ -13,15 +12,13 @@ import * as iosPushView from './IosPushCredentials'; export class SelectPlatform implements IView { async open(ctx: Context): Promise { - const { platform } = await prompt([ - { - type: 'list', - name: 'platform', - message: 'Select platform', - pageSize: Infinity, - choices: ['ios', 'android'], - }, - ]); + const { platform } = await prompts({ + type: 'select', + name: 'platform', + message: 'Select platform', + choices: ['ios', 'android'].map(value => ({ value, title: value })), + optionsPerPage: 20, + }); const view = platform === 'ios' ? new SelectIosExperience() : new SelectAndroidExperience(); CredentialsManager.get().changeMainView(view); return view; @@ -36,16 +33,15 @@ export class SelectIosExperience implements IView { await displayIosCredentials(iosCredentials); - const projectSpecificActions: ChoiceType[] = ctx.hasProjectContext + const projectSpecificActions: { value: string; title: string }[] = ctx.hasProjectContext ? [ - prompt.separator('---- Current project actions ----'), { value: 'use-existing-push-ios', - name: 'Use existing Push Notifications Key in current project', + title: 'Use existing Push Notifications Key in current project', }, { value: 'use-existing-dist-ios', - name: 'Use existing Distribution Certificate in current project', + title: 'Use existing Distribution Certificate in current project', }, // { // value: 'current-remove-push-ios', @@ -59,28 +55,25 @@ export class SelectIosExperience implements IView { // value: 'current-remove-app-ios', // name: 'Remove all credentials for current project', // }, - prompt.separator('---- Account level actions ----'), ] : []; - const question: Question = { - type: 'list', + const { action } = await prompts({ + type: 'select', name: 'action', message: 'What do you want to do?', choices: [ ...projectSpecificActions, - { value: 'remove-provisioning-profile', name: 'Remove Provisioning Profile' }, - { value: 'create-ios-push', name: 'Add new Push Notifications Key' }, - { value: 'remove-ios-push', name: 'Remove Push Notification credentials' }, - { value: 'update-ios-push', name: 'Update Push Notifications Key' }, - { value: 'create-ios-dist', name: 'Add new Distribution Certificate' }, - { value: 'remove-ios-dist', name: 'Remove Distribution Certificate' }, - { value: 'update-ios-dist', name: 'Update Distribution Certificate' }, + { value: 'remove-provisioning-profile', title: 'Remove Provisioning Profile' }, + { value: 'create-ios-push', title: 'Add new Push Notifications Key' }, + { value: 'remove-ios-push', title: 'Remove Push Notification credentials' }, + { value: 'update-ios-push', title: 'Update Push Notifications Key' }, + { value: 'create-ios-dist', title: 'Add new Distribution Certificate' }, + { value: 'remove-ios-dist', title: 'Remove Distribution Certificate' }, + { value: 'update-ios-dist', title: 'Update Distribution Certificate' }, ], - pageSize: Infinity, - }; - - const { action } = await prompt(question); + optionsPerPage: 20, + }); return this.handleAction(ctx, accountName, action); } @@ -148,17 +141,16 @@ export class SelectAndroidExperience implements IView { const credentials = await ctx.android.fetchAll(); await displayAndroidCredentials(Object.values(credentials)); - const question: Question = { - type: 'list', + const { experienceName } = await prompts({ + type: 'select', name: 'experienceName', message: 'Select application', choices: Object.values(credentials).map(cred => ({ - name: cred.experienceName, + title: cred.experienceName, value: cred.experienceName, })), - pageSize: Infinity, - }; - const { experienceName } = await prompt(question); + optionsPerPage: 20, + }); return new androidView.ExperienceView(experienceName); } @@ -186,17 +178,15 @@ export class DoQuit implements IQuit { export class AskQuit implements IQuit { async runAsync(mainpage: IView): Promise { - const { selected } = await prompt([ - { - type: 'list', - name: 'selected', - message: 'Do you want to quit Credential Manager', - choices: [ - { value: 'exit', name: 'Quit Credential Manager' }, - { value: 'mainpage', name: 'Go back to experience overview.' }, - ], - }, - ]); + const { selected } = await prompts({ + type: 'select', + name: 'selected', + message: 'Do you want to quit Credential Manager', + choices: [ + { value: 'exit', title: 'Quit Credential Manager' }, + { value: 'mainpage', title: 'Go back to experience overview.' }, + ], + }); if (selected === 'exit') { process.exit(0); } diff --git a/packages/expo-cli/src/prompts.ts b/packages/expo-cli/src/prompts.ts index bbf0e13a9f..524067ef2a 100644 --- a/packages/expo-cli/src/prompts.ts +++ b/packages/expo-cli/src/prompts.ts @@ -1,9 +1,13 @@ import program from 'commander'; -import prompts, { Choice, Options, PromptType, PromptObject as Question } from 'prompts'; +import prompts, { Choice, Options, PromptObject, PromptType } from 'prompts'; import CommandError, { AbortCommandError } from './CommandError'; -export { PromptType, Question }; +export type Question = PromptObject & { + optionsPerPage?: number; +}; + +export { PromptType }; type PromptOptions = { nonInteractiveHelp?: string } & Options;