Compare commits

...
93 changed files with 2308 additions and 3305 deletions

No files matched your search

+1 -1
View File
@@ -26,7 +26,7 @@
"jest": "29.7.0",
"jest-watch-typeahead": "2.2.2",
"lerna": "9.0.3",
"oclif": "^3.9.0",
"oclif": "^4.22.85",
"oxfmt": "0.28.0",
"oxlint": "1.43.0",
"oxlint-tsgolint": "0.11.1",
+6 -13
View File
@@ -1,17 +1,10 @@
#!/usr/bin/env node
const oclif = require('@oclif/core');
const path = require('path');
(async () => {
const oclif = require('@oclif/core');
const project = path.join(__dirname, '..', 'tsconfig.json');
// Keep dev entrypoint failures verbose for local debugging.
oclif.settings.debug = true;
// In dev mode -> use ts-node and dev plugins
process.env.NODE_ENV = 'development';
require('ts-node').register({ project });
// In dev mode, always show stack traces
oclif.settings.disableJsonFlag = true
// Start the CLI
oclif.run().then(oclif.flush).catch(oclif.Errors.handle);
await oclif.execute({ development: true, dir: __dirname });
})();
+4 -4
View File
@@ -1,6 +1,6 @@
#!/usr/bin/env node
require('@oclif/core')
.run()
.then(require('@oclif/core/flush'))
.catch(require('@oclif/core/handle'));
(async () => {
const oclif = require('@oclif/core');
await oclif.execute({ dir: __dirname });
})();
+2 -2
View File
@@ -65,8 +65,8 @@
"@expo/spawn-async": "1.7.2",
"@expo/steps": "18.0.2",
"@expo/timeago.js": "1.0.0",
"@oclif/core": "^1.26.2",
"@oclif/plugin-autocomplete": "^2.3.10",
"@oclif/core": "^4.8.3",
"@oclif/plugin-autocomplete": "^3.2.40",
"@segment/ajv-human-errors": "^2.1.2",
"@urql/core": "4.0.11",
"@urql/exchange-retry": "1.2.0",
@@ -133,11 +133,21 @@ export function mockTestCommand<T extends Command>(
argv: string[],
ctx: any
): T {
const cmd = new commandConstructor(argv, new Config({ root: __dirname }));
const config = getMockOclifConfig(__dirname);
const cmd = new commandConstructor(argv, config);
(cmd as any).getContextAsync = jest.fn(() => ctx);
return cmd;
}
export function getMockOclifConfig(root = __dirname): Config {
const config = new Config({ root });
config.runHook = async () => ({
failures: [],
successes: [],
});
return config;
}
export class NoErrorThrownError extends Error {}
export const getErrorAsync = async <TError = any>(
@@ -1,5 +1,5 @@
import { Platform, Workflow } from '@expo/eas-build-job';
import { ExitError } from '@oclif/core/lib/errors';
import { Errors } from '@oclif/core';
import path from 'path';
import { instance, mock, when } from 'ts-mockito';
@@ -8,6 +8,8 @@ import { validatePNGsForManagedProjectAsync } from '../validate';
const fixturesPath = path.join(__dirname, 'fixtures');
const { ExitError } = Errors;
describe(validatePNGsForManagedProjectAsync, () => {
it('does not validate PNGs for generic projects', async () => {
const ctxMock = mock<CommonContext<Platform.ANDROID>>();
@@ -42,7 +42,7 @@ beforeEach(() => {
jest.mocked(createAnalyticsAsync).mockResolvedValue(analytics);
});
const createTestEasCommand = (): typeof EasCommand => {
const createTestEasCommand = (): any => {
class TestEasCommand extends EasCommand {
async runAsync(): Promise<void> {}
}
+9 -9
View File
@@ -28,28 +28,28 @@ export const EASMultiEnvironmentFlag = {
};
export const EASVariableFormatFlag = {
format: Flags.enum({
format: Flags.option({
description: 'Output format',
options: ['long', 'short'],
options: ['long', 'short'] as const,
default: 'short',
}),
})(),
};
export const EASVariableVisibilityFlag = {
visibility: Flags.enum<'plaintext' | 'sensitive' | 'secret'>({
visibility: Flags.option({
description: 'Visibility of the variable',
options: ['plaintext', 'sensitive', 'secret'],
}),
options: ['plaintext', 'sensitive', 'secret'] as const,
})(),
};
export type EASEnvironmentVariableScopeFlagValue = 'project' | 'account';
export const EASEnvironmentVariableScopeFlag = {
scope: Flags.enum<EASEnvironmentVariableScopeFlagValue>({
scope: Flags.option({
description: 'Scope for the variable',
options: ['project', 'account'],
options: ['project', 'account'] as const,
default: 'project',
}),
})(),
};
export const EASNonInteractiveFlag = {
@@ -1,5 +1,4 @@
import { Flags } from '@oclif/core';
import { OptionFlag } from '@oclif/core/lib/interfaces';
import { Flags, Interfaces } from '@oclif/core';
import { EasNonInteractiveAndJsonFlags } from './flags';
@@ -38,18 +37,18 @@ export const getLimitFlagWithCustomValues = ({
}: {
defaultTo: number;
limit: number;
}): OptionFlag<number | undefined> =>
}): Interfaces.OptionFlag<number | undefined> =>
Flags.integer({
description: `The number of items to fetch each query. Defaults to ${defaultTo} and is capped at ${limit}.`,
// eslint-disable-next-line async-protect/async-suffix
parse: async input => parseFlagInputStringAsInteger(input, 'limit', 1, limit),
parse: async (input: string) => parseFlagInputStringAsInteger(input, 'limit', 1, limit),
});
export const EasPaginatedQueryFlags = {
offset: Flags.integer({
description: 'Start queries from specified index. Use for paginating results. Defaults to 0.',
// eslint-disable-next-line async-protect/async-suffix
parse: async input =>
parse: async (input: string) =>
parseFlagInputStringAsInteger(input, 'offset', 0, Number.MAX_SAFE_INTEGER),
}),
limit: getLimitFlagWithCustomValues({ defaultTo: 50, limit: 100 }),
@@ -1,3 +1,4 @@
import { Args } from '@oclif/core';
import chalk from 'chalk';
import EasCommand from '../../commandUtils/EasCommand';
@@ -201,13 +202,12 @@ function displayUsage(data: UsageDisplayData, usageData: AccountFullUsageData):
export default class AccountUsage extends EasCommand {
static override description = 'view account usage and billing for the current cycle';
static override args = [
{
name: 'ACCOUNT_NAME',
static override args = {
ACCOUNT_NAME: Args.string({
description:
'Account name to view usage for. If not provided, the account will be selected interactively (or defaults to the only account if there is just one)',
},
];
}),
};
static override flags = {
...EasJsonOnlyFlag,
+6 -1
View File
@@ -1,3 +1,4 @@
import { Args } from '@oclif/core';
import { getAnalyticsEnabledAsync, setAnalyticsEnabledAsync } from '../analytics/AnalyticsManager';
import EasCommand from '../commandUtils/EasCommand';
import Log from '../log';
@@ -5,7 +6,11 @@ import Log from '../log';
export default class AnalyticsView extends EasCommand {
static override description = 'display or change analytics settings';
static override args = [{ name: 'STATUS', options: ['on', 'off'] }];
static override args = {
STATUS: Args.string({
options: ['on', 'off'] as const,
}),
};
async runAsync(): Promise<void> {
const { STATUS: status } = (await this.parse(AnalyticsView)).args;
@@ -1,3 +1,4 @@
import { Args } from '@oclif/core';
import chalk from 'chalk';
import { createUpdateBranchOnAppAsync } from '../../branch/queries';
@@ -12,13 +13,12 @@ import { enableJsonOutput, printJsonOnlyOutput } from '../../utils/json';
export default class BranchCreate extends EasCommand {
static override description = 'create a branch';
static override args = [
{
name: 'name',
static override args = {
name: Args.string({
required: false,
description: 'Name of the branch to create',
},
];
}),
};
static override flags = {
...EasNonInteractiveAndJsonFlags,
@@ -61,6 +61,9 @@ export default class BranchCreate extends EasCommand {
initial: (await getDefaultBranchNameAsync(vcsClient)) ?? undefined,
validate: value => (value ? true : validationMessage),
}));
if (!name) {
throw new Error(validationMessage);
}
}
const newBranch = await createUpdateBranchOnAppAsync(graphqlClient, { appId: projectId, name });
@@ -1,3 +1,4 @@
import { Args } from '@oclif/core';
import chalk from 'chalk';
import gql from 'graphql-tag';
@@ -54,13 +55,12 @@ export default class BranchDelete extends EasCommand {
...this.ContextOptions.LoggedIn,
};
static override args = [
{
name: 'name',
static override args = {
name: Args.string({
required: false,
description: 'Name of the branch to delete',
},
];
}),
};
static override flags = {
...EasNonInteractiveAndJsonFlags,
+5 -5
View File
@@ -1,3 +1,4 @@
import { Args } from '@oclif/core';
import { selectBranchOnAppAsync } from '../../branch/queries';
import EasCommand from '../../commandUtils/EasCommand';
import { EasNonInteractiveAndJsonFlags } from '../../commandUtils/flags';
@@ -12,13 +13,12 @@ import { enableJsonOutput } from '../../utils/json';
export default class BranchView extends EasCommand {
static override description = 'view a branch';
static override args = [
{
name: 'name',
static override args = {
name: Args.string({
required: false,
description: 'Name of the branch to view',
},
];
}),
};
static override flags = {
...EasPaginatedQueryFlags,
@@ -1,4 +1,4 @@
import { Flags } from '@oclif/core';
import { Args, Flags } from '@oclif/core';
import gql from 'graphql-tag';
import EasCommand from '../../commandUtils/EasCommand';
@@ -93,15 +93,17 @@ export async function selectBuildToCancelAsync(
export default class BuildCancel extends EasCommand {
static override description = 'cancel a build';
static override args = [{ name: 'BUILD_ID' }];
static override args = {
BUILD_ID: Args.string({}),
};
static override flags = {
...EASNonInteractiveFlag,
platform: Flags.enum({
platform: Flags.option({
char: 'p',
description: 'Filter builds by the platform if build ID is not provided',
options: Object.values(RequestedPlatform),
}),
})(),
profile: Flags.string({
char: 'e',
description: 'Filter builds by build profile if build ID is not provided',
@@ -140,7 +142,7 @@ export default class BuildCancel extends EasCommand {
await ensureBuildExistsAsync(graphqlClient, buildIdFromArg);
}
let buildId: string | null = buildIdFromArg;
let buildId: string | null = buildIdFromArg ?? null;
if (!buildId) {
if (nonInteractive) {
throw new Error('Build ID must be provided in non-interactive mode');
@@ -19,11 +19,11 @@ export default class BuildConfigure extends EasCommand {
static override description = 'configure the project to support EAS Build';
static override flags = {
platform: Flags.enum({
platform: Flags.option({
description: 'Platform to configure',
char: 'p',
options: ['android', 'ios', 'all'],
}),
options: ['android', 'ios', 'all'] as const,
})(),
};
static override contextDefinition = {
@@ -1,4 +1,4 @@
import { Flags } from '@oclif/core';
import { Args, Flags } from '@oclif/core';
import gql from 'graphql-tag';
import EasCommand from '../../commandUtils/EasCommand';
@@ -79,14 +79,16 @@ export async function selectBuildToDeleteAsync(
export default class BuildDelete extends EasCommand {
static override description = 'delete a build';
static override args = [{ name: 'BUILD_ID' }];
static override args = {
BUILD_ID: Args.string({}),
};
static override flags = {
...EASNonInteractiveFlag,
platform: Flags.enum({
platform: Flags.option({
char: 'p',
description: 'Filter builds by the platform if build ID is not provided',
options: Object.values(RequestedPlatform),
}),
})(),
profile: Flags.string({
char: 'e',
description: 'Filter builds by build profile if build ID is not provided',
@@ -121,7 +123,7 @@ export default class BuildDelete extends EasCommand {
await ensureBuildExistsAsync(graphqlClient, buildIdFromArg);
}
let buildId: string | null = buildIdFromArg;
let buildId: string | null = buildIdFromArg ?? null;
if (!buildId) {
if (nonInteractive) {
throw new Error('Build ID must be provided in non-interactive mode');
+3 -3
View File
@@ -34,10 +34,10 @@ export default class BuildDev extends EasCommand {
'run dev client simulator/emulator build with matching fingerprint or create a new one';
static override flags = {
platform: Flags.enum<Platform.IOS | Platform.ANDROID>({
platform: Flags.option({
char: 'p',
options: [Platform.IOS, Platform.ANDROID],
}),
options: [Platform.IOS, Platform.ANDROID] as const,
})(),
profile: Flags.string({
char: 'e',
description: `Name of the build profile from eas.json. It must be a profile allowing to create emulator/simulator internal distribution dev client builds. The "${DEFAULT_EAS_BUILD_RUN_PROFILE_NAME}" build profile will be selected by default.`,
@@ -23,10 +23,10 @@ export default class Download extends EasCommand {
description: 'Fingerprint hash of the build to download',
required: true,
}),
platform: Flags.enum<Platform.IOS | Platform.ANDROID>({
platform: Flags.option({
char: 'p',
options: [Platform.IOS, Platform.ANDROID],
}),
options: [Platform.IOS, Platform.ANDROID] as const,
})(),
'dev-client': Flags.boolean({
description: 'Filter only dev-client builds.',
allowNo: true,
+7 -7
View File
@@ -45,10 +45,10 @@ export default class Build extends EasCommand {
static override description = 'start a build';
static override flags = {
platform: Flags.enum({
platform: Flags.option({
char: 'p',
options: ['android', 'ios', 'all'],
}),
options: ['android', 'ios', 'all'] as const,
})(),
'skip-credentials-check': Flags.boolean({
default: false,
hidden: true,
@@ -96,7 +96,7 @@ export default class Build extends EasCommand {
description:
'Specify the "What to Test" information for the build in TestFlight (iOS-only). To be used with the `auto-submit` flag',
}),
'resource-class': Flags.enum({
'resource-class': Flags.option({
options: Object.values(ResourceClass),
hidden: true,
deprecated: {
@@ -105,15 +105,15 @@ export default class Build extends EasCommand {
),
},
description: 'The instance type that will be used to run this build [experimental]',
}),
})(),
message: Flags.string({
char: 'm',
description: 'A short message describing the build',
}),
'build-logger-level': Flags.enum({
'build-logger-level': Flags.option({
description: 'The level of logs to output during the build process. Defaults to "info".',
options: Object.values(LoggerLevel),
}),
})(),
'freeze-credentials': Flags.boolean({
default: false,
description: 'Prevent the build from updating credentials in non-interactive mode',
@@ -28,23 +28,23 @@ export default class BuildInspect extends EasCommand {
'inspect the state of the project at specific build stages, useful for troubleshooting';
static override flags = {
platform: Flags.enum({
platform: Flags.option({
char: 'p',
options: [RequestedPlatform.Android, RequestedPlatform.Ios],
options: [RequestedPlatform.Android, RequestedPlatform.Ios] as const,
required: true,
}),
})(),
profile: Flags.string({
char: 'e',
description:
'Name of the build profile from eas.json. Defaults to "production" if defined in eas.json.',
helpValue: 'PROFILE_NAME',
}),
stage: Flags.enum({
stage: Flags.option({
char: 's',
description: STAGE_DESCRIPTION,
options: [InspectStage.ARCHIVE, InspectStage.PRE_BUILD, InspectStage.POST_BUILD],
options: [InspectStage.ARCHIVE, InspectStage.PRE_BUILD, InspectStage.POST_BUILD] as const,
required: true,
}),
})(),
output: Flags.string({
char: 'o',
description: 'Output directory.',
@@ -18,11 +18,11 @@ export default class BuildInternal extends EasCommand {
static override hidden = true;
static override flags = {
platform: Flags.enum({
platform: Flags.option({
char: 'p',
options: ['android', 'ios'],
options: ['android', 'ios'] as const,
required: true,
}),
})(),
profile: Flags.string({
char: 'e',
description:
+6 -6
View File
@@ -20,18 +20,18 @@ export default class BuildList extends EasCommand {
static override description = 'list all builds for your project';
static override flags = {
platform: Flags.enum({
platform: Flags.option({
options: Object.values(RequestedPlatform),
char: 'p',
}),
status: Flags.enum({
})(),
status: Flags.option({
options: Object.values(BuildStatus),
description: 'Filter only builds with the specified status',
}),
distribution: Flags.enum({
})(),
distribution: Flags.option({
options: Object.values(BuildDistributionType),
description: 'Filter only builds with the specified distribution type',
}),
})(),
channel: Flags.string(),
'app-version': Flags.string({
aliases: ['appVersion'],
@@ -66,10 +66,10 @@ export default class BuildResign extends EasCommand {
static override description = 're-sign a build archive';
static override flags = {
platform: Flags.enum({
platform: Flags.option({
char: 'p',
options: ['android', 'ios'],
}),
options: ['android', 'ios'] as const,
})(),
'target-profile': Flags.string({
char: 'e',
description:
+3 -3
View File
@@ -62,10 +62,10 @@ export default class Run extends EasCommand {
description: 'ID of the simulator/emulator build to run',
exclusive: ['latest, path, url'],
}),
platform: Flags.enum({
platform: Flags.option({
char: 'p',
options: ['android', 'ios'],
}),
options: ['android', 'ios'] as const,
})(),
profile: Flags.string({
char: 'e',
description:
@@ -22,10 +22,10 @@ export default class BuildVersionGetView extends EasCommand {
public static override description = 'get the latest version from EAS servers';
public static override flags = {
platform: Flags.enum({
platform: Flags.option({
char: 'p',
options: ['android', 'ios', 'all'],
}),
options: ['android', 'ios', 'all'] as const,
})(),
profile: Flags.string({
char: 'e',
description:
@@ -26,10 +26,10 @@ export default class BuildVersionSetView extends EasCommand {
static override description = 'update version of an app';
static override flags = {
platform: Flags.enum({
platform: Flags.option({
char: 'p',
options: ['android', 'ios'],
}),
options: ['android', 'ios'] as const,
})(),
profile: Flags.string({
char: 'e',
description:
@@ -45,10 +45,10 @@ export default class BuildVersionSyncView extends EasCommand {
'update a version in native code with a value stored on EAS servers';
public static override flags = {
platform: Flags.enum({
platform: Flags.option({
char: 'p',
options: ['android', 'ios', 'all'],
}),
options: ['android', 'ios', 'all'] as const,
})(),
profile: Flags.string({
char: 'e',
description:
+4 -1
View File
@@ -1,3 +1,4 @@
import { Args } from '@oclif/core';
import { formatGraphQLBuild } from '../../build/utils/formatBuild';
import EasCommand from '../../commandUtils/EasCommand';
import { EasJsonOnlyFlag } from '../../commandUtils/flags';
@@ -11,7 +12,9 @@ import { enableJsonOutput, printJsonOnlyOutput } from '../../utils/json';
export default class BuildView extends EasCommand {
static override description = 'view a build for your project';
static override args = [{ name: 'BUILD_ID' }];
static override args = {
BUILD_ID: Args.string({}),
};
static override flags = {
...EasJsonOnlyFlag,
@@ -1,3 +1,4 @@
import { Args } from '@oclif/core';
import chalk from 'chalk';
import { createAndLinkChannelAsync } from '../../channel/queries';
@@ -10,13 +11,12 @@ import { enableJsonOutput } from '../../utils/json';
export default class ChannelCreate extends EasCommand {
static override description = 'create a channel';
static override args = [
{
name: 'name',
static override args = {
name: Args.string({
required: false,
description: 'Name of the channel to create',
},
];
}),
};
static override flags = {
...EasNonInteractiveAndJsonFlags,
@@ -53,6 +53,9 @@ export default class ChannelCreate extends EasCommand {
message: 'Provide a channel name:',
validate: value => (value ? true : validationMessage),
}));
if (!channelName) {
throw new Error(validationMessage);
}
}
await createAndLinkChannelAsync(graphqlClient, {
@@ -1,3 +1,4 @@
import { Args } from '@oclif/core';
import { scheduleChannelDeletionAsync } from '../../channel/delete';
import { selectChannelOnAppAsync } from '../../channel/queries';
import EasCommand from '../../commandUtils/EasCommand';
@@ -11,13 +12,12 @@ import { pollForBackgroundJobReceiptAsync } from '../../utils/pollForBackgroundJ
export default class ChannelDelete extends EasCommand {
static override description = 'Delete a channel';
static override args = [
{
name: 'name',
static override args = {
name: Args.string({
required: false,
description: 'Name of the channel to delete',
},
];
}),
};
static override flags = {
...EasNonInteractiveAndJsonFlags,
};
@@ -1,4 +1,4 @@
import { Flags } from '@oclif/core';
import { Args, Flags } from '@oclif/core';
import chalk from 'chalk';
import { print } from 'graphql';
import gql from 'graphql-tag';
@@ -58,13 +58,12 @@ export async function updateChannelBranchMappingAsync(
export default class ChannelEdit extends EasCommand {
static override description = 'point a channel at a new branch';
static override args = [
{
name: 'name',
static override args = {
name: Args.string({
required: false,
description: 'Name of the channel to edit',
},
];
}),
};
static override flags = {
branch: Flags.string({
@@ -1,4 +1,4 @@
import { Flags } from '@oclif/core';
import { Args, Flags } from '@oclif/core';
import chalk from 'chalk';
import { print } from 'graphql';
import gql from 'graphql-tag';
@@ -50,13 +50,12 @@ export async function pauseUpdateChannelAsync(
export default class ChannelPause extends EasCommand {
static override description = 'pause a channel to stop it from sending updates';
static override args = [
{
name: 'name',
static override args = {
name: Args.string({
required: false,
description: 'Name of the channel to edit',
},
];
}),
};
static override flags = {
branch: Flags.string({
@@ -1,4 +1,4 @@
import { Flags } from '@oclif/core';
import { Args, Flags } from '@oclif/core';
import chalk from 'chalk';
import { print } from 'graphql';
import gql from 'graphql-tag';
@@ -50,13 +50,12 @@ export async function resumeUpdateChannelAsync(
export default class ChannelResume extends EasCommand {
static override description = 'resume a channel to start sending updates';
static override args = [
{
name: 'name',
static override args = {
name: Args.string({
required: false,
description: 'Name of the channel to edit',
},
];
}),
};
static override flags = {
branch: Flags.string({
@@ -1,4 +1,4 @@
import { Flags } from '@oclif/core';
import { Args, Flags } from '@oclif/core';
import EasCommand from '../../commandUtils/EasCommand';
import { EasNonInteractiveAndJsonFlags } from '../../commandUtils/flags';
@@ -49,15 +49,14 @@ type ChannelRolloutArgsAndFlags = {
export default class ChannelRollout extends EasCommand {
static override description = 'Roll a new branch out on a channel incrementally.';
static override args = [
{
name: 'channel',
static override args = {
channel: Args.string({
description: 'channel on which the rollout should be done',
},
];
}),
};
static override flags = {
action: Flags.enum({
action: Flags.option({
description: 'Rollout action to perform',
options: Object.values(ActionRawFlagValue),
required: false,
@@ -97,17 +96,17 @@ export default class ChannelRollout extends EasCommand {
],
},
],
}),
})(),
percent: Flags.integer({
description:
'Percent of users to send to the new branch. Use with --action=edit or --action=create',
required: false,
}),
outcome: Flags.enum({
outcome: Flags.option({
description: 'End outcome of rollout. Use with --action=end',
options: Object.values(EndOutcome),
required: false,
}),
})(),
branch: Flags.string({
description: 'Branch to roll out. Use with --action=create',
required: false,
@@ -1,3 +1,4 @@
import { Args } from '@oclif/core';
import assert from 'assert';
import {
@@ -12,13 +13,12 @@ import { enableJsonOutput } from '../../utils/json';
export default class ChannelView extends EasCommand {
static override description = 'view a channel';
static override args = [
{
name: 'name',
static override args = {
name: Args.string({
required: false,
description: 'Name of the channel to view',
},
];
}),
};
static override flags = {
...EasNonInteractiveAndJsonFlags,
+1 -1
View File
@@ -17,7 +17,7 @@ export default class Config extends EasCommand {
static override description = 'display project configuration (app.json + eas.json)';
static override flags = {
platform: Flags.enum<Platform>({ char: 'p', options: [Platform.ANDROID, Platform.IOS] }),
platform: Flags.option({ char: 'p', options: [Platform.ANDROID, Platform.IOS] as const })(),
profile: Flags.string({
char: 'e',
description:
@@ -10,10 +10,10 @@ export default class InitializeBuildCredentials extends EasCommand {
static override description = 'Set up credentials for building your project.';
static override flags = {
platform: Flags.enum({
platform: Flags.option({
char: 'p',
options: [Platform.ANDROID, Platform.IOS],
}),
options: [Platform.ANDROID, Platform.IOS] as const,
})(),
profile: Flags.string({
char: 'e',
description: 'The name of the build profile in eas.json.',
@@ -7,7 +7,7 @@ export default class Credentials extends EasCommand {
static override description = 'manage credentials';
static override flags = {
platform: Flags.enum({ char: 'p', options: ['android', 'ios'] }),
platform: Flags.option({ char: 'p', options: ['android', 'ios'] as const })(),
};
static override contextDefinition = {
@@ -1,3 +1,4 @@
import { Args } from '@oclif/core';
import chalk from 'chalk';
import EasCommand from '../../../commandUtils/EasCommand';
@@ -22,7 +23,9 @@ export default class WorkerAliasDelete extends EasCommand {
static override aliases = ['worker:alias:delete'];
static override state = 'preview';
static override args = [{ name: 'ALIAS_NAME' }];
static override args = {
ALIAS_NAME: Args.string({}),
};
static override flags = {
...EasNonInteractiveAndJsonFlags,
};
@@ -1,3 +1,4 @@
import { Args } from '@oclif/core';
import chalk from 'chalk';
import EasCommand from '../../commandUtils/EasCommand';
@@ -23,7 +24,9 @@ export default class WorkerDelete extends EasCommand {
static override aliases = ['worker:delete'];
static override state = 'preview';
static override args = [{ name: 'DEPLOYMENT_ID' }];
static override args = {
DEPLOYMENT_ID: Args.string({}),
};
static override flags = {
...EasNonInteractiveAndJsonFlags,
};
+4 -1
View File
@@ -1,3 +1,4 @@
import { Args } from '@oclif/core';
import EasCommand from '../../commandUtils/EasCommand';
import { AppleDeviceQuery } from '../../credentials/ios/api/graphql/queries/AppleDeviceQuery';
import formatDevice from '../../devices/utils/formatDevice';
@@ -8,7 +9,9 @@ import { getOwnerAccountForProjectIdAsync } from '../../project/projectUtils';
export default class DeviceView extends EasCommand {
static override description = 'view a device for your project';
static override args = [{ name: 'UDID' }];
static override args = {
UDID: Args.string({}),
};
static override contextDefinition = {
...this.ContextOptions.ProjectId,
@@ -1,6 +1,4 @@
import { Config } from '@oclif/core';
import { getMockAppFragment } from '../../../__tests__/commands/utils';
import { getMockAppFragment, getMockOclifConfig } from '../../../__tests__/commands/utils';
import { DefaultEnvironment } from '../../../build/utils/environment';
import { ExpoGraphqlClient } from '../../../commandUtils/context/contextUtils/createGraphqlClient';
import { testProjectId } from '../../../credentials/__tests__/fixtures-constants';
@@ -28,7 +26,7 @@ jest.mock('../../../utils/prompts');
describe(EnvCreate, () => {
const graphqlClient = {} as any as ExpoGraphqlClient;
const mockConfig = {} as unknown as Config;
const mockConfig = getMockOclifConfig();
const variableId = 'testId';
const testAccountId = 'test-account-id';
@@ -1,5 +1,4 @@
import { Config } from '@oclif/core';
import { getMockOclifConfig } from '../../../__tests__/commands/utils';
import { DefaultEnvironment } from '../../../build/utils/environment';
import {
EnvironmentSecretType,
@@ -21,7 +20,7 @@ describe(EnvDelete, () => {
const projectId = 'test-project-id';
const variableId = '1';
const graphqlClient = {};
const mockConfig = {} as unknown as Config;
const mockConfig = getMockOclifConfig();
const mockContext = {
privateProjectConfig: { projectId },
loggedIn: { graphqlClient },
@@ -1,5 +1,4 @@
import { Config } from '@oclif/core';
import { getMockOclifConfig } from '../../../__tests__/commands/utils';
import { DefaultEnvironment } from '../../../build/utils/environment';
import { ExpoGraphqlClient } from '../../../commandUtils/context/contextUtils/createGraphqlClient';
import { testProjectId } from '../../../credentials/__tests__/fixtures-constants';
@@ -17,7 +16,7 @@ jest.mock('../../../log');
describe(EnvExec, () => {
const graphqlClient = {} as any as ExpoGraphqlClient;
const mockConfig = {} as unknown as Config;
const mockConfig = getMockOclifConfig();
const mockEnvironmentVariables = [
{
+2 -3
View File
@@ -1,5 +1,4 @@
import { Config } from '@oclif/core';
import { getMockOclifConfig } from '../../../__tests__/commands/utils';
import { DefaultEnvironment } from '../../../build/utils/environment';
import { ExpoGraphqlClient } from '../../../commandUtils/context/contextUtils/createGraphqlClient';
import { testProjectId } from '../../../credentials/__tests__/fixtures-constants';
@@ -21,7 +20,7 @@ jest.mock('../../../utils/prompts');
describe(EnvGet, () => {
const graphqlClient = {} as any as ExpoGraphqlClient;
const mockConfig = {} as unknown as Config;
const mockConfig = getMockOclifConfig();
const mockVariables: EnvironmentVariableFragment[] = [
{
id: 'var1',
@@ -1,6 +1,4 @@
import { Config } from '@oclif/core';
import { getMockAppFragment } from '../../../__tests__/commands/utils';
import { getMockAppFragment, getMockOclifConfig } from '../../../__tests__/commands/utils';
import { DefaultEnvironment } from '../../../build/utils/environment';
import { ExpoGraphqlClient } from '../../../commandUtils/context/contextUtils/createGraphqlClient';
import { testProjectId } from '../../../credentials/__tests__/fixtures-constants';
@@ -48,7 +46,7 @@ const mockVariables: EnvironmentVariableFragment[] = [
describe(EnvList, () => {
const graphqlClient = {} as any as ExpoGraphqlClient;
const mockConfig = {} as unknown as Config;
const mockConfig = getMockOclifConfig();
beforeEach(() => {
jest.clearAllMocks();
@@ -1,7 +1,7 @@
import { Config } from '@oclif/core';
import * as fs from 'fs-extra';
import path from 'path';
import { getMockOclifConfig } from '../../../__tests__/commands/utils';
import { DefaultEnvironment } from '../../../build/utils/environment';
import { ExpoGraphqlClient } from '../../../commandUtils/context/contextUtils/createGraphqlClient';
import { testProjectId } from '../../../credentials/__tests__/fixtures-constants';
@@ -25,7 +25,7 @@ jest.mock('../../../log');
describe(EnvPull, () => {
const graphqlClient = {} as any as ExpoGraphqlClient;
const mockConfig = {} as unknown as Config;
const mockConfig = getMockOclifConfig();
const testProjectDir = '/test/project';
const testTargetPath = '.env.local';
@@ -1,6 +1,6 @@
import { Config } from '@oclif/core';
import * as fs from 'fs-extra';
import { getMockOclifConfig } from '../../../__tests__/commands/utils';
import { DefaultEnvironment } from '../../../build/utils/environment';
import { ExpoGraphqlClient } from '../../../commandUtils/context/contextUtils/createGraphqlClient';
import { testProjectId } from '../../../credentials/__tests__/fixtures-constants';
@@ -23,7 +23,7 @@ jest.mock('../../../prompts');
describe(EnvPush, () => {
const graphqlClient = {} as any as ExpoGraphqlClient;
const mockConfig = {} as unknown as Config;
const mockConfig = getMockOclifConfig();
const testProjectDir = '/test/project';
const testEnvPath = '.env.test';
@@ -1,8 +1,7 @@
import { Config } from '@oclif/core';
import chalk from 'chalk';
import * as fs from 'fs-extra';
import { getMockAppFragment } from '../../../__tests__/commands/utils';
import { getMockAppFragment, getMockOclifConfig } from '../../../__tests__/commands/utils';
import { DefaultEnvironment } from '../../../build/utils/environment';
import {
EnvironmentSecretType,
@@ -33,7 +32,7 @@ describe(EnvUpdate, () => {
const projectId = 'test-project-id';
const variableId = '1';
const graphqlClient = {};
const mockConfig = {} as unknown as Config;
const mockConfig = getMockOclifConfig();
const mockContext = {
privateProjectConfig: { projectId },
loggedIn: { graphqlClient },
+8 -9
View File
@@ -1,4 +1,4 @@
import { Flags } from '@oclif/core';
import { Args, Flags } from '@oclif/core';
import chalk from 'chalk';
import fs from 'fs-extra';
import path from 'path';
@@ -59,14 +59,13 @@ interface CreateFlags {
export default class EnvCreate extends EasCommand {
static override description = 'create an environment variable for the current project or account';
static override args = [
{
name: 'environment',
static override args = {
environment: Args.string({
description:
"Environment to create the variable in. Default environments are 'production', 'preview', and 'development'.",
required: false,
},
];
}),
};
static override flags = {
name: Flags.string({
@@ -79,10 +78,10 @@ export default class EnvCreate extends EasCommand {
description: 'Overwrite existing variable',
default: false,
}),
type: Flags.enum<'string' | 'file'>({
type: Flags.option({
description: 'The type of variable',
options: ['string', 'file'],
}),
options: ['string', 'file'] as const,
})(),
...EASVariableVisibilityFlag,
...EASEnvironmentVariableScopeFlag,
...EASMultiEnvironmentFlag,
+5 -6
View File
@@ -1,4 +1,4 @@
import { Flags } from '@oclif/core';
import { Args, Flags } from '@oclif/core';
import assert from 'assert';
import chalk from 'chalk';
@@ -45,14 +45,13 @@ export default class EnvDelete extends EasCommand {
...EASNonInteractiveFlag,
};
static override args = [
{
name: 'environment',
static override args = {
environment: Args.string({
description:
"Current environment of the variable to delete. Default environments are 'production', 'preview', and 'development'.",
required: false,
},
];
}),
};
static override contextDefinition = {
...this.ContextOptions.ProjectId,
+7 -8
View File
@@ -1,3 +1,4 @@
import { Args } from '@oclif/core';
import spawnAsync from '@expo/spawn-async';
import chalk from 'chalk';
@@ -37,19 +38,17 @@ export default class EnvExec extends EasCommand {
...EASNonInteractiveFlag,
};
static override args = [
{
name: 'environment',
static override args = {
environment: Args.string({
required: true,
description:
"Environment to execute the command in. Default environments are 'production', 'preview', and 'development'.",
},
{
name: 'bash_command',
}),
bash_command: Args.string({
required: true,
description: 'bash command to execute with the environment variables from the environment',
},
];
}),
};
private isNonInteractive: boolean = false;
+5 -6
View File
@@ -1,4 +1,4 @@
import { Flags } from '@oclif/core';
import { Args, Flags } from '@oclif/core';
import chalk from 'chalk';
import EasCommand from '../../commandUtils/EasCommand';
@@ -44,14 +44,13 @@ export default class EnvGet extends EasCommand {
...this.ContextOptions.LoggedIn,
};
static override args = [
{
name: 'environment',
static override args = {
environment: Args.string({
description:
"Current environment of the variable. Default environments are 'production', 'preview', and 'development'.",
required: false,
},
];
}),
};
static override flags = {
'variable-name': Flags.string({
+5 -6
View File
@@ -1,4 +1,4 @@
import { Flags } from '@oclif/core';
import { Args, Flags } from '@oclif/core';
import chalk from 'chalk';
import EasCommand from '../../commandUtils/EasCommand';
@@ -106,14 +106,13 @@ export default class EnvList extends EasCommand {
...EASEnvironmentVariableScopeFlag,
};
static override args = [
{
name: 'environment',
static override args = {
environment: Args.string({
description:
"Environment to list the variables from. Default environments are 'production', 'preview', and 'development'.",
required: false,
},
];
}),
};
async runAsync(): Promise<void> {
const { args, flags } = await this.parse(EnvList);
+5 -6
View File
@@ -1,4 +1,4 @@
import { Flags } from '@oclif/core';
import { Args, Flags } from '@oclif/core';
import dotenv from 'dotenv';
import * as fs from 'fs-extra';
import path from 'path';
@@ -24,14 +24,13 @@ export default class EnvPull extends EasCommand {
...this.ContextOptions.ProjectDir,
};
static override args = [
{
name: 'environment',
static override args = {
environment: Args.string({
description:
"Environment to pull variables from. Default environments are 'production', 'preview', and 'development'.",
required: false,
},
];
}),
};
static override flags = {
...EASNonInteractiveFlag,
+6 -7
View File
@@ -1,4 +1,4 @@
import { Flags } from '@oclif/core';
import { Args, Flags } from '@oclif/core';
import dotenv from 'dotenv';
import fs from 'fs-extra';
import path from 'path';
@@ -38,14 +38,13 @@ export default class EnvPush extends EasCommand {
}),
};
static override args = [
{
name: 'environment',
static override args = {
environment: Args.string({
description:
"Environment to push variables to. Default environments are 'production', 'preview', and 'development'.",
required: false,
},
];
}),
};
async runAsync(): Promise<void> {
const { args, flags } = await this.parse(EnvPush);
@@ -214,7 +213,7 @@ export default class EnvPush extends EasCommand {
environment: string[] | undefined;
force: boolean;
},
{ environment }: Record<string, string>
{ environment }: { environment?: string }
): { environment?: string[]; path: string; force: boolean } {
const environments = flags.environment ?? (environment ? [environment] : undefined);
+8 -9
View File
@@ -1,4 +1,4 @@
import { Flags } from '@oclif/core';
import { Args, Flags } from '@oclif/core';
import assert from 'assert';
import chalk from 'chalk';
import fs from 'fs-extra';
@@ -79,24 +79,23 @@ export default class EnvUpdate extends EasCommand {
value: Flags.string({
description: 'New value or the variable',
}),
type: Flags.enum<'string' | 'file'>({
type: Flags.option({
description: 'The type of variable',
options: ['string', 'file'],
}),
options: ['string', 'file'] as const,
})(),
...EASVariableVisibilityFlag,
...EASEnvironmentVariableScopeFlag,
...EASMultiEnvironmentFlag,
...EASNonInteractiveFlag,
};
static override args = [
{
name: 'environment',
static override args = {
environment: Args.string({
description:
"Current environment of the variable to update. Default environments are 'production', 'preview', and 'development'.",
required: false,
},
];
}),
};
static override contextDefinition = {
...this.ContextOptions.ProjectId,
@@ -1,4 +1,4 @@
import { Flags } from '@oclif/core';
import { Args, Flags } from '@oclif/core';
import openBrowserAsync from 'better-opn';
import chalk from 'chalk';
@@ -68,19 +68,17 @@ export default class FingerprintCompare extends EasCommand {
'$ eas fingerprint:compare <FINGERPRINT-HASH> --update-id <UPDATE-ID> \t # Compare fingerprint from update against provided fingerprint',
];
static override args = [
{
name: 'hash1',
static override args = {
hash1: Args.string({
description:
"If provided alone, HASH1 is compared against the current project's fingerprint.",
required: false,
},
{
name: 'hash2',
}),
hash2: Args.string({
description: 'If two hashes are provided, HASH1 is compared against HASH2.',
required: false,
},
];
}),
};
static override flags = {
'build-id': Flags.string({
@@ -155,8 +153,8 @@ export default class FingerprintCompare extends EasCommand {
);
const { fingerprint: firstFingerprint, origin: firstFingerprintOrigin } = firstFingerprintInfo;
const isFirstFingerprintSpecifiedByFlagOrArg = hash1 || buildId1 || updateId1;
const isSecondFingerprintSpecifiedByFlagOrArg = hash2 || buildId2 || updateId2;
const isFirstFingerprintSpecifiedByFlagOrArg = Boolean(hash1 || buildId1 || updateId1);
const isSecondFingerprintSpecifiedByFlagOrArg = Boolean(hash2 || buildId2 || updateId2);
const secondFingerprintInfo = await getFingerprintInfoAsync(
graphqlClient,
projectDir,
@@ -287,7 +285,7 @@ async function getFingerprintInfoAsync(
}: {
buildId?: string;
updateId?: string;
hash: string;
hash?: string;
useProjectFingerprint?: boolean;
environmentForProjectFingerprint?: string;
nonInteractive: boolean;
@@ -34,10 +34,10 @@ export default class FingerprintGenerate extends EasCommand {
];
static override flags = {
platform: Flags.enum({
platform: Flags.option({
char: 'p',
options: ['android', 'ios'],
}),
options: ['android', 'ios'] as const,
})(),
...EASEnvironmentFlag,
environment: Flags.string({
...EasEnvironmentFlagParameters,
@@ -3,6 +3,7 @@ import chalk from 'chalk';
import { vol } from 'memfs';
import { instance, mock } from 'ts-mockito';
import { getMockOclifConfig } from '../../../__tests__/commands/utils';
import LoggedInContextField from '../../../commandUtils/context/LoggedInContextField';
import ProjectDirContextField from '../../../commandUtils/context/ProjectDirContextField';
import { ExpoGraphqlClient } from '../../../commandUtils/context/contextUtils/createGraphqlClient';
@@ -97,7 +98,7 @@ function mockTestProject(options: {
jest.mocked(isExpoInstalled).mockReturnValue(true);
}
const commandOptions = { root: '/test-project' } as any;
const commandOptions = getMockOclifConfig('/test-project');
beforeEach(() => {
jest.resetAllMocks();
@@ -166,9 +167,10 @@ describe(ProjectInit.name, () => {
});
it('does not prompt to overwrite when different', async () => {
await new ProjectInit(['--id', '12345', '--force'], {
root: '/test-project',
} as any).run();
await new ProjectInit(
['--id', '12345', '--force'],
getMockOclifConfig('/test-project')
).run();
expect(saveProjectIdToAppConfigAsync).toHaveBeenCalledWith('/test-project', '12345');
expect(confirmAsync).not.toHaveBeenCalled();
});
@@ -177,9 +179,10 @@ describe(ProjectInit.name, () => {
describe('non-interactive', () => {
it('aborts when different', async () => {
await expect(
new ProjectInit(['--id', '12345', '--non-interactive'], {
root: '/test-project',
} as any).run()
new ProjectInit(
['--id', '12345', '--non-interactive'],
getMockOclifConfig('/test-project')
).run()
).rejects.toThrowError(
`Project is already linked to a different ID: ${chalk.bold(
'1234'
+8 -9
View File
@@ -1,4 +1,4 @@
import { Flags } from '@oclif/core';
import { Args, Flags } from '@oclif/core';
import chalk from 'chalk';
import nullthrows from 'nullthrows';
@@ -132,21 +132,20 @@ export default class New extends EasCommand {
static override description =
'Create a new project configured with Expo Application Services (EAS)';
static override args = [
{
name: 'path',
static override args = {
path: Args.string({
description: 'Path to create the project (defaults to current directory)',
required: false,
},
];
}),
};
static override flags = {
'package-manager': Flags.enum<PackageManager>({
'package-manager': Flags.option({
char: 'p',
description: 'Package manager to use for installing dependencies',
options: [...PACKAGE_MANAGERS],
options: [...PACKAGE_MANAGERS] as const,
default: 'npm',
}),
})(),
};
static override contextDefinition = {
@@ -1,3 +1,4 @@
import { Args } from '@oclif/core';
import { ExpoConfig } from '@expo/config';
import { Platform } from '@expo/eas-build-job';
import { AppVersionSource, EasJson } from '@expo/eas-json';
@@ -45,7 +46,9 @@ export default class Onboarding extends EasCommand {
static override flags = {};
static override args = [{ name: 'TARGET_PROJECT_DIRECTORY' }];
static override args = {
TARGET_PROJECT_DIRECTORY: Args.string({}),
};
static override contextDefinition = {
...this.ContextOptions.LoggedIn,
@@ -28,21 +28,21 @@ export default class EnvironmentSecretCreate extends EasCommand {
static override hidden = true;
static override flags = {
scope: Flags.enum({
scope: Flags.option({
description: 'Scope for the secret',
options: [EnvironmentSecretScope.ACCOUNT, EnvironmentSecretScope.PROJECT],
options: [EnvironmentSecretScope.ACCOUNT, EnvironmentSecretScope.PROJECT] as const,
default: EnvironmentSecretScope.PROJECT,
}),
})(),
name: Flags.string({
description: 'Name of the secret',
}),
value: Flags.string({
description: 'Text value or path to a file to store in the secret',
}),
type: Flags.enum({
type: Flags.option({
description: 'The type of secret',
options: [SecretType.STRING, SecretType.FILE],
}),
options: [SecretType.STRING, SecretType.FILE] as const,
})(),
force: Flags.boolean({
description: 'Delete and recreate existing secrets',
default: false,
@@ -171,6 +171,7 @@ export default class EnvironmentSecretCreate extends EasCommand {
}
assert(secretValue);
const environmentSecretType = SecretTypeToEnvironmentSecretType[secretType as SecretType];
let secretFilePath: string | undefined;
if (secretType === SecretType.FILE) {
@@ -201,7 +202,7 @@ export default class EnvironmentSecretCreate extends EasCommand {
const secret = await EnvironmentSecretMutation.createForAppAsync(
graphqlClient,
{ name, value: secretValue, type: SecretTypeToEnvironmentSecretType[secretType] },
{ name, value: secretValue, type: environmentSecretType },
projectId
);
if (!secret) {
@@ -244,7 +245,7 @@ export default class EnvironmentSecretCreate extends EasCommand {
const secret = await EnvironmentSecretMutation.createForAccountAsync(
graphqlClient,
{ name, value: secretValue, type: SecretTypeToEnvironmentSecretType[secretType] },
{ name, value: secretValue, type: environmentSecretType },
ownerAccount.id
);
+3 -3
View File
@@ -27,11 +27,11 @@ export default class EnvironmentSecretPush extends EasCommand {
static override hidden = true;
static override flags = {
scope: Flags.enum({
scope: Flags.option({
description: 'Scope for the secrets',
options: [EnvironmentSecretScope.ACCOUNT, EnvironmentSecretScope.PROJECT],
options: [EnvironmentSecretScope.ACCOUNT, EnvironmentSecretScope.PROJECT] as const,
default: EnvironmentSecretScope.PROJECT,
}),
})(),
'env-file': Flags.string({
description: 'Env file with secrets',
}),
+3 -3
View File
@@ -55,10 +55,10 @@ export default class Submit extends EasCommand {
static override aliases = ['build:submit'];
static override flags = {
platform: Flags.enum({
platform: Flags.option({
char: 'p',
options: ['android', 'ios', 'all'],
}),
options: ['android', 'ios', 'all'] as const,
})(),
profile: Flags.string({
char: 'e',
description:
@@ -29,10 +29,10 @@ export default class SubmitInternal extends EasCommand {
static override hidden = true;
static override flags = {
platform: Flags.enum<Platform>({
options: [Platform.ANDROID, Platform.IOS],
platform: Flags.option({
options: [Platform.ANDROID, Platform.IOS] as const,
required: true,
}),
})(),
profile: Flags.string({
description:
'Name of the submit profile from eas.json. Defaults to "production" if defined in eas.json.',
@@ -5,6 +5,7 @@ import nullthrows from 'nullthrows';
import path from 'path';
import { instance, mock } from 'ts-mockito';
import { getMockOclifConfig } from '../../../__tests__/commands/utils';
import UpdatePublish, { preprocessSourceMapsArg } from '..';
import { ensureBranchExistsAsync } from '../../../branch/queries';
import {
@@ -26,7 +27,7 @@ import { getBranchFromChannelNameAndCreateAndLinkIfNotExistsAsync } from '../../
import { resolveVcsClient } from '../../../vcs';
const projectRoot = '/test-project';
const commandOptions = { root: projectRoot } as any;
const commandOptions = getMockOclifConfig(projectRoot);
const updateStub: UpdateFragment = {
id: 'update-1234',
group: 'group-1234',
@@ -2,6 +2,7 @@ import { AppJSONConfig, ExpoConfig, PackageJSONConfig, getConfig } from '@expo/c
import { DirectoryJSON, vol } from 'memfs';
import { instance, mock } from 'ts-mockito';
import { getMockOclifConfig } from '../../../__tests__/commands/utils';
import LoggedInContextField from '../../../commandUtils/context/LoggedInContextField';
import { PrivateProjectConfigContextField } from '../../../commandUtils/context/PrivateProjectConfigContextField';
import { ExpoGraphqlClient } from '../../../commandUtils/context/contextUtils/createGraphqlClient';
@@ -23,7 +24,7 @@ import {
import UpdateRepublish from '../republish';
const projectRoot = '/test-project';
const commandOptions = { root: projectRoot } as any;
const commandOptions = getMockOclifConfig(projectRoot);
const updateStub: UpdateFragment = {
id: 'update-1234',
group: 'group-1234',
@@ -4,6 +4,7 @@ import nullthrows from 'nullthrows';
import path from 'path';
import { instance, mock } from 'ts-mockito';
import { getMockOclifConfig } from '../../../__tests__/commands/utils';
import { ensureBranchExistsAsync } from '../../../branch/queries';
import {
DynamicPrivateProjectConfigContextField,
@@ -23,7 +24,7 @@ import { resolveVcsClient } from '../../../vcs';
import UpdateRollBackToEmbedded from '../roll-back-to-embedded';
const projectRoot = '/test-project';
const commandOptions = { root: projectRoot } as any;
const commandOptions = getMockOclifConfig(projectRoot);
const updateStub: UpdateFragment = {
id: 'update-1234',
group: 'group-1234',
@@ -16,12 +16,12 @@ export default class UpdateConfigure extends EasCommand {
static override description = 'configure the project to support EAS Update';
static override flags = {
platform: Flags.enum<RequestedPlatform>({
platform: Flags.option({
description: 'Platform to configure',
char: 'p',
options: Object.values(RequestedPlatform),
default: RequestedPlatform.All,
}),
})(),
...EasUpdateEnvironmentFlag,
...EASNonInteractiveFlag,
};
@@ -1,3 +1,4 @@
import { Args } from '@oclif/core';
import chalk from 'chalk';
import EasCommand from '../../commandUtils/EasCommand';
@@ -11,13 +12,12 @@ import { pollForBackgroundJobReceiptAsync } from '../../utils/pollForBackgroundJ
export default class UpdateDelete extends EasCommand {
static override description = 'delete all the updates in an update group';
static override args = [
{
name: 'groupId',
static override args = {
groupId: Args.string({
required: true,
description: 'The ID of an update group to delete.',
},
];
}),
};
static override flags = {
...EasNonInteractiveAndJsonFlags,
+5 -6
View File
@@ -1,4 +1,4 @@
import { Flags } from '@oclif/core';
import { Args, Flags } from '@oclif/core';
import assert from 'assert';
import chalk from 'chalk';
@@ -20,12 +20,11 @@ import { enableJsonOutput, printJsonOnlyOutput } from '../../utils/json';
export default class UpdateEdit extends EasCommand {
static override description = 'edit all the updates in an update group';
static override args = [
{
name: 'groupId',
static override args = {
groupId: Args.string({
description: 'The ID of an update group to edit.',
},
];
}),
};
static override flags = {
'rollout-percentage': Flags.integer({
@@ -179,12 +179,12 @@ export default class UpdatePublish extends EasCommand {
min: 0,
max: 100,
}),
platform: Flags.enum<RequestedPlatform>({
platform: Flags.option({
char: 'p',
options: Object.values(RequestedPlatform), // TODO: Add web when it's fully supported
default: RequestedPlatform.All,
required: false,
}),
})(),
auto: Flags.boolean({
description:
'Use the current git branch and commit message for the EAS branch and update message',
+2 -2
View File
@@ -29,11 +29,11 @@ export default class UpdateList extends EasCommand {
exclusive: ['branch'],
default: false,
}),
platform: Flags.enum<RequestedPlatform>({
platform: Flags.option({
options: Object.values(RequestedPlatform),
char: 'p',
description: 'Filter updates by platform',
}),
})(),
'runtime-version': Flags.string({
description: 'Filter updates by runtime version',
}),
@@ -76,12 +76,12 @@ export default class UpdateRepublish extends EasCommand {
description: 'Short message describing the republished update group',
required: false,
}),
platform: Flags.enum({
platform: Flags.option({
char: 'p',
options: [...defaultRepublishPlatforms, 'all'],
options: [...defaultRepublishPlatforms, 'all'] as const,
default: 'all',
required: false,
}),
})(),
'private-key-path': Flags.string({
description: `File containing the PEM-encoded private key corresponding to the certificate in expo-updates' configuration. Defaults to a file named "private-key.pem" in the certificate's directory. Only relevant if you are using code signing: https://docs.expo.dev/eas-update/code-signing/`,
required: false,
@@ -63,16 +63,16 @@ export default class UpdateRollBackToEmbedded extends EasCommand {
description: 'A short message describing the rollback to embedded update',
required: false,
}),
platform: Flags.enum({
platform: Flags.option({
char: 'p',
options: [
// TODO: Add web when it's fully supported
...defaultPublishPlatforms,
'all',
],
] as const,
default: 'all',
required: false,
}),
})(),
'private-key-path': Flags.string({
description: `File containing the PEM-encoded private key corresponding to the certificate in expo-updates' configuration. Defaults to a file named "private-key.pem" in the certificate's directory. Only relevant if you are using code signing: https://docs.expo.dev/eas-update/code-signing/`,
required: false,
+5 -5
View File
@@ -1,3 +1,4 @@
import { Args } from '@oclif/core';
import chalk from 'chalk';
import EasCommand from '../../commandUtils/EasCommand';
@@ -14,13 +15,12 @@ import { enableJsonOutput, printJsonOnlyOutput } from '../../utils/json';
export default class UpdateView extends EasCommand {
static override description = 'update group details';
static override args = [
{
name: 'groupId',
static override args = {
groupId: Args.string({
required: true,
description: 'The ID of an update group.',
},
];
}),
};
static override flags = {
...EasJsonOnlyFlag,
+3 -3
View File
@@ -35,10 +35,10 @@ export default class BuildUpload extends EasCommand {
static override description = 'upload a local build and generate a sharable link';
static override flags = {
platform: Flags.enum<Platform.IOS | Platform.ANDROID>({
platform: Flags.option({
char: 'p',
options: [Platform.IOS, Platform.ANDROID],
}),
options: [Platform.IOS, Platform.ANDROID] as const,
})(),
'build-path': Flags.string({
description: 'Path for the local build',
}),
@@ -11,10 +11,10 @@ export default class WebhookCreate extends EasCommand {
static override description = 'create a webhook';
static override flags = {
event: Flags.enum({
event: Flags.option({
description: 'Event type that triggers the webhook',
options: [WebhookType.Build, WebhookType.Submit],
}),
options: [WebhookType.Build, WebhookType.Submit] as const,
})(),
url: Flags.string({
description: 'Webhook URL',
}),
@@ -1,3 +1,4 @@
import { Args } from '@oclif/core';
import assert from 'assert';
import chalk from 'chalk';
import nullthrows from 'nullthrows';
@@ -16,13 +17,12 @@ import { formatWebhook } from '../../webhooks/formatWebhook';
export default class WebhookDelete extends EasCommand {
static override description = 'delete a webhook';
static override args = [
{
name: 'ID',
static override args = {
ID: Args.string({
required: false,
description: 'ID of the webhook to delete',
},
];
}),
};
static override flags = {
...EASNonInteractiveFlag,
@@ -45,8 +45,9 @@ export default class WebhookDelete extends EasCommand {
nonInteractive,
});
let webhook: WebhookFragment | undefined =
webhookId && (await WebhookQuery.byIdAsync(graphqlClient, webhookId));
let webhook: WebhookFragment | undefined = webhookId
? await WebhookQuery.byIdAsync(graphqlClient, webhookId)
: undefined;
if (!webhookId) {
const webhooks = await fetchWebhooksByAppIdAsync(graphqlClient, projectId);
if (webhooks.length === 0) {
@@ -15,10 +15,10 @@ export default class WebhookList extends EasCommand {
static override description = 'list webhooks';
static override flags = {
event: Flags.enum({
event: Flags.option({
description: 'Event type that triggers the webhook',
options: [WebhookType.Build, WebhookType.Submit],
}),
options: [WebhookType.Build, WebhookType.Submit] as const,
})(),
...EasJsonOnlyFlag,
};
@@ -17,10 +17,10 @@ export default class WebhookUpdate extends EasCommand {
description: 'Webhook ID',
required: true,
}),
event: Flags.enum({
event: Flags.option({
description: 'Event type that triggers the webhook',
options: [WebhookType.Build, WebhookType.Submit],
}),
options: [WebhookType.Build, WebhookType.Submit] as const,
})(),
url: Flags.string({
description: 'Webhook URL',
}),
@@ -1,3 +1,4 @@
import { Args } from '@oclif/core';
import EasCommand from '../../commandUtils/EasCommand';
import { WebhookQuery } from '../../graphql/queries/WebhookQuery';
import Log from '../../log';
@@ -7,13 +8,12 @@ import { formatWebhook } from '../../webhooks/formatWebhook';
export default class WebhookView extends EasCommand {
static override description = 'view a webhook';
static override args = [
{
name: 'ID',
static override args = {
ID: Args.string({
required: true,
description: 'ID of the webhook to view',
},
];
}),
};
static override contextDefinition = {
...this.ContextOptions.LoggedIn,
@@ -27,7 +27,7 @@ export default class WorkflowRunCancel extends EasCommand {
const workflowRunIds: Set<string> = new Set();
// Custom parsing of argv
const tokens: string[] = [...argv];
const tokens = [...argv] as string[];
while (tokens.length > 0) {
const token = tokens.shift();
if (token === '--non-interactive') {
@@ -1,4 +1,4 @@
import { Flags } from '@oclif/core';
import { Args, Flags } from '@oclif/core';
import chalk from 'chalk';
import fs from 'fs/promises';
import fsExtra from 'fs-extra';
@@ -29,13 +29,12 @@ import { WorkflowFile } from '../../utils/workflowFile';
export class WorkflowCreate extends EasCommand {
static override description = 'create a new workflow configuration YAML file';
static override args = [
{
name: 'name',
static override args = {
name: Args.string({
description: 'Name of the workflow file (must end with .yml or .yaml)',
required: false,
},
];
}),
};
static override flags = {
'skip-validation': Flags.boolean({
@@ -1,4 +1,4 @@
import { Flags } from '@oclif/core';
import { Args, Flags } from '@oclif/core';
import EasCommand from '../../commandUtils/EasCommand';
import { EASNonInteractiveFlag, EasJsonOnlyFlag } from '../../commandUtils/flags';
@@ -38,9 +38,11 @@ export default class WorkflowLogView extends EasCommand {
}),
};
static override args = [
{ name: 'id', description: 'ID of the workflow run or workflow job to view logs for' },
];
static override args = {
id: Args.string({
description: 'ID of the workflow run or workflow job to view logs for',
}),
};
static override contextDefinition = {
...this.ContextOptions.ProjectId,
@@ -41,7 +41,7 @@
*/
import spawnAsync from '@expo/spawn-async';
import { Flags } from '@oclif/core';
import { Args, Flags } from '@oclif/core';
import { CombinedError } from '@urql/core';
import chalk from 'chalk';
import { boolish } from 'getenv';
@@ -82,7 +82,12 @@ export default class WorkflowRun extends EasCommand {
static override description =
'run an EAS workflow. The entire local project directory will be packaged and uploaded to EAS servers for the workflow run, unless the --ref flag is used.';
static override args = [{ name: 'file', description: 'Path to the workflow file to run' }];
static override args = {
file: Args.string({
description: 'Path to the workflow file to run',
required: true,
}),
};
static override flags = {
...EASNonInteractiveFlag,
@@ -21,11 +21,11 @@ export default class WorkflowRunList extends EasCommand {
'If present, the query will only return runs for the specified workflow file name',
required: false,
}),
status: Flags.enum({
status: Flags.option({
description: 'If present, filter the returned runs to select those with the specified status',
required: false,
options: Object.values(WorkflowRunStatus),
}),
})(),
...EasJsonOnlyFlag,
limit: getLimitFlagWithCustomValues({ defaultTo: 10, limit: 100 }),
};
@@ -10,7 +10,7 @@
*
*/
import { Flags } from '@oclif/core';
import { Args, Flags } from '@oclif/core';
import { boolish } from 'getenv';
import { getWorkflowRunUrl } from '../../build/utils/url';
@@ -34,12 +34,11 @@ export default class WorkflowStatus extends EasCommand {
static override description =
'show the status of an existing workflow run. If no run ID is provided, you will be prompted to select from recent workflow runs for the current project.';
static override args = [
{
name: 'WORKFLOW_RUN_ID',
static override args = {
WORKFLOW_RUN_ID: Args.string({
description: 'A workflow run ID.',
},
];
}),
};
static override flags = {
...EASNonInteractiveFlag,
@@ -104,6 +103,9 @@ export default class WorkflowStatus extends EasCommand {
choices: runs.map(run => choiceFromWorkflowRun(run)),
});
workflowRunId = answers.selectedRun;
if (!workflowRunId) {
throw new Error('No workflow run selected');
}
}
Log.addNewLineIfNone();
@@ -1,3 +1,4 @@
import { Args } from '@oclif/core';
import EasCommand from '../../commandUtils/EasCommand';
import { EASNonInteractiveFlag } from '../../commandUtils/flags';
import {
@@ -11,13 +12,12 @@ import { WorkflowFile } from '../../utils/workflowFile';
export class WorkflowValidate extends EasCommand {
static override description = 'validate a workflow configuration yaml file';
static override args = [
{
name: 'path',
static override args = {
path: Args.string({
description: 'Path to the workflow configuration YAML file (must end with .yml or .yaml)',
required: true,
},
];
}),
};
static override flags = {
...EASNonInteractiveFlag,
@@ -1,3 +1,4 @@
import { Args } from '@oclif/core';
import chalk from 'chalk';
import { formatGraphQLBuildArtifacts } from '../../build/utils/formatBuild';
@@ -65,7 +66,11 @@ export default class WorkflowView extends EasCommand {
...EASNonInteractiveFlag,
};
static override args = [{ name: 'id', description: 'ID of the workflow run to view' }];
static override args = {
id: Args.string({
description: 'ID of the workflow run to view',
}),
};
static override contextDefinition = {
...this.ContextOptions.ProjectId,
Generated
+1899 -2927
View File
File diff suppressed because it is too large. Load diff