Compare commits

..
Author SHA1 Message Date
Dominik Sokal e7dbe4ee71 upgrade @expo/plugin-warn-if-update-available 2022-05-12 10:40:24 +02:00
Dominik Sokal 34ecd38304 Update dependencies (#1095)
* update outdated deps

* [eas-cli] regenerate GraphQL code

* [eas-cli] fix tests

* [scripts] upgrade deps

* [eas-cli] fix lint warnings

* update CHANGELOG.md
2022-05-11 11:20:22 +02:00
47 changed files with 1819 additions and 3358 deletions

No files matched your search

+2
View File
@@ -12,6 +12,8 @@ This is the log of notable changes to EAS CLI and related packages.
### 🧹 Chores
- Update dependencies. ([#1095](https://github.com/expo/eas-cli/pull/1095) by [@dsokal](https://github.com/dsokal))
## [0.52.0](https://github.com/expo/eas-cli/releases/tag/v0.52.0) - 2022-04-26
### 🎉 New features
+10 -10
View File
@@ -17,19 +17,19 @@
"clean": "lerna run clean && rm -rf node_modules coverage"
},
"devDependencies": {
"@types/jest": "27.4.1",
"@types/node": "16.7.8",
"eslint": "8.12.0",
"eslint-config-universe": "10.0.0",
"@types/jest": "27.5.0",
"@types/node": "17.0.32",
"eslint": "8.15.0",
"eslint-config-universe": "11.0.0",
"eslint-plugin-async-protect": "1.1.0",
"eslint-plugin-node": "11.1.0",
"jest": "27.5.1",
"jest-watch-typeahead": "1.0.0",
"jest": "28.1.0",
"jest-watch-typeahead": "1.1.0",
"lerna": "4.0.0",
"oclif": "2.6.3",
"prettier": "2.6.1",
"ts-jest": "27.1.4",
"typescript": "4.6.3"
"oclif": "3.0.1",
"prettier": "2.6.2",
"ts-jest": "28.0.2",
"typescript": "4.6.4"
},
"volta": {
"node": "16.10.0",
@@ -1,7 +0,0 @@
{
"extends": "@tsconfig/node16/tsconfig.json",
"compilerOptions": {
"jsx": "react-jsx",
"strict": true
}
}
+1 -1
View File
@@ -1,5 +1,5 @@
overwrite: true
schema: 'http://localhost:3000/graphql'
schema: 'https://staging-api.expo.dev/graphql'
documents:
- 'src/graphql/**/!(*.d).{ts,tsx}'
- 'src/credentials/ios/api/graphql/**/!(*.d).{ts,tsx}'
+462 -340
View File
File diff suppressed because it is too large. Load diff
+29 -40
View File
@@ -10,31 +10,29 @@
"dependencies": {
"@expo/apple-utils": "0.0.0-alpha.31",
"@expo/code-signing-certificates": "0.0.2",
"@expo/config": "6.0.21",
"@expo/config-plugins": "4.1.2",
"@expo/config-types": "44.0.0",
"@expo/eas-build-job": "0.2.71",
"@expo/config": "6.0.23",
"@expo/config-plugins": "4.1.4",
"@expo/config-types": "45.0.0",
"@expo/eas-build-job": "0.2.72",
"@expo/eas-json": "0.52.0",
"@expo/json-file": "8.2.34",
"@expo/json-file": "8.2.36",
"@expo/multipart-body-parser": "1.1.0",
"@expo/package-manager": "0.0.50",
"@expo/pkcs12": "0.0.7",
"@expo/plist": "0.0.17",
"@expo/plugin-warn-if-update-available": "2.1.0",
"@expo/prebuild-config": "3.1.2",
"@expo/pkcs12": "0.0.8",
"@expo/plist": "0.0.18",
"@expo/plugin-warn-if-update-available": "2.2.0",
"@expo/prebuild-config": "3.1.6",
"@expo/results": "1.0.0",
"@expo/rudder-sdk-node": "1.1.1",
"@expo/spawn-async": "1.6.0",
"@expo/timeago.js": "1.0.0",
"@oclif/core": "1.6.4",
"@oclif/plugin-autocomplete": "1.2.0",
"@oclif/core": "1.8.1",
"@oclif/plugin-autocomplete": "1.3.0",
"@oclif/plugin-help": "5.1.12",
"@urql/core": "2.4.3",
"@urql/exchange-retry": "0.3.2",
"adm-zip": "0.5.9",
"@urql/core": "2.4.4",
"@urql/exchange-retry": "0.3.3",
"chalk": "4.1.2",
"cli-progress": "3.10.0",
"cli-table3": "0.6.1",
"cli-progress": "3.11.0",
"cli-table3": "0.6.2",
"dateformat": "4.6.3",
"env-paths": "2.2.0",
"envinfo": "7.8.1",
@@ -42,23 +40,21 @@
"fast-glob": "3.2.11",
"figures": "3.2.0",
"form-data": "4.0.0",
"fs-extra": "10.0.1",
"fs-extra": "10.1.0",
"getenv": "1.0.0",
"got": "^11.1.4",
"gradle-to-js": "2.0.0",
"graphql": "16.3.0",
"gradle-to-js": "2.0.1",
"graphql": "16.5.0",
"graphql-tag": "2.12.6",
"https-proxy-agent": "5.0.0",
"https-proxy-agent": "5.0.1",
"ignore": "5.2.0",
"indent-string": "4.0.0",
"jks-js": "1.0.2",
"js-yaml": "^3.13.1",
"joi": "17.6.0",
"keychain": "1.3.0",
"log-symbols": "4.1.0",
"mime": "3.0.0",
"minimatch": "3.0.5",
"nanoid": "3.3.2",
"minimatch": "5.0.1",
"nanoid": "3.3.4",
"node-fetch": "2.6.7",
"node-forge": "1.3.1",
"nullthrows": "1.1.1",
@@ -66,45 +62,38 @@
"pkg-dir": "4.2.0",
"prompts": "2.4.2",
"qrcode-terminal": "0.12.0",
"pnp-webpack-plugin": "1.7.0",
"react-dev-utils": "12.0.0",
"resolve-from": "5.0.0",
"semver": "7.3.5",
"semver": "7.3.7",
"slash": "3.0.0",
"strip-ansi": "6.0.0",
"tar": "6.1.11",
"terminal-link": "2.1.1",
"ts-loader": "^9.2.8",
"tslib": "2.3.1",
"tslib": "2.4.0",
"turndown": "7.1.1",
"untildify": "4.0.0",
"uuid": "8.3.2",
"webpack": "5.72.0",
"wrap-ansi": "7.0.0"
},
"devDependencies": {
"@graphql-codegen/cli": "2.6.2",
"@graphql-codegen/introspection": "2.1.1",
"@graphql-codegen/typescript": "2.4.8",
"@graphql-codegen/typescript-operations": "2.3.5",
"@graphql-codegen/typescript": "2.4.11",
"@graphql-codegen/typescript-operations": "2.4.0",
"@types/cli-progress": "3.9.2",
"@types/adm-zip": "0.4.34",
"@types/dateformat": "3.0.1",
"@types/envinfo": "7.8.1",
"@types/fs-extra": "9.0.13",
"@types/getenv": "^1.0.0",
"@types/js-yaml": "^3.12.2",
"@types/mime": "2.0.3",
"@types/node-fetch": "^2.5.7",
"@types/node-forge": "1.0.1",
"@types/node-forge": "1.0.2",
"@types/prompts": "2.0.14",
"@types/semver": "7.3.9",
"@types/tar": "6.1.1",
"@types/tough-cookie": "4.0.1",
"@types/tough-cookie": "4.0.2",
"@types/uuid": "8.3.4",
"@types/webpack": "5.28.0",
"@types/wrap-ansi": "3.0.0",
"axios": "0.26.1",
"axios": "0.27.2",
"eslint-plugin-graphql": "4.0.0",
"form-data": "4.0.0",
"memfs": "3.4.1",
@@ -112,7 +101,7 @@
"nock": "13.2.4",
"tempy": "0.7.0",
"ts-deepmerge": "2.0.1",
"typescript": "4.6.3"
"typescript": "4.6.4"
},
"engines": {
"node": ">=12.0.0"
@@ -105,7 +105,7 @@ export async function maybeResolveVersionsAsync(
appBuildVersion:
resolveConfigValue(buildGradle, 'versionCode', parsedGradleCommand?.flavor) ?? '1',
};
} catch (err: any) {
} catch {
return {};
}
} else {
@@ -1,4 +1,3 @@
import admzip from 'adm-zip';
import chalk from 'chalk';
import fs from 'fs-extra';
import path from 'path';
@@ -123,63 +122,6 @@ export async function makeProjectTarballAsync(): Promise<{ path: string; size: n
return { size, path: tarPath };
}
export async function makeZipAsync(pathToZip: string): Promise<{ path: string; size: number }> {
const spinner = ora('Compressing project files');
await fs.mkdirp(getTmpDirectory());
const shallowClonePath = path.join(getTmpDirectory(), `${uuidv4()}-shallow-clone`);
try {
process.chdir(pathToZip);
await getVcsClient().makeShallowCopyAsync(shallowClonePath);
process.chdir('..');
const zipPath = path.join(getTmpDirectory(), `${uuidv4()}.zip`);
// If the compression takes longer then a second, show the spinner.
// This can happen when the user has a lot of resources or doesn't ignore their CocoaPods.
// A basic project on a Mac can compress in roughly ~40ms.
// A fairly complex project without CocoaPods ignored can take up to 30s.
const timer = setTimeout(
() => {
spinner.start();
},
Log.isDebug ? 1 : 1000
);
// TODO: Possibly warn after more time about unoptimized assets.
const compressTimerLabel = 'makeProjectZipAsync';
startTimer(compressTimerLabel);
const zip = new admzip();
zip.addLocalFolder(shallowClonePath);
await zipAsync(zip, zipPath);
clearTimeout(timer);
const { size } = await fs.stat(zipPath);
const duration = endTimer(compressTimerLabel);
if (spinner.isSpinning) {
const prettyTime = formatMilliseconds(duration);
spinner.succeed(
`Compressed project files ${chalk.dim(`${prettyTime} (${formatBytes(size)})`)}`
);
}
return { size, path: zipPath };
} catch (err) {
if (spinner.isSpinning) {
spinner.fail();
}
throw err;
} finally {
await fs.remove(shallowClonePath);
}
}
async function zipAsync(zip: admzip, targetFileName?: string): Promise<void> {
return new Promise((resolve, reject) => {
zip.writeZip(targetFileName, (error: Error | null) => (error ? reject(error) : resolve()));
});
}
enum ShouldCommitChanges {
Yes,
ShowDiffFirst,
@@ -107,7 +107,7 @@ describe(EasCommand.name, () => {
await TestEasCommand.run().then(() => {
throw new Error('foo');
});
} catch (error) {}
} catch {}
expect(flushAsync).toHaveBeenCalled();
});
@@ -104,7 +104,7 @@ async function selectBuildToCancelAsync(
async function ensureBuildExistsAsync(buildId: string): Promise<void> {
try {
await BuildQuery.byIdAsync(buildId);
} catch (err) {
} catch {
throw new Error(`Couldn't find a build matching the id ${buildId}`);
}
}
@@ -102,7 +102,7 @@ export default class BuildInspect extends EasCommand {
if (!flags.verbose) {
Log.log(chalk.green('Build successful'));
}
} catch (err) {
} catch {
if (!flags.verbose) {
Log.error('Build failed');
Log.error(`Re-run this command with ${chalk.bold('--verbose')} flag to see the logs`);
@@ -45,7 +45,7 @@ export function getBranchMapping(branchMappingString?: string): {
let branchMapping: BranchMapping;
try {
branchMapping = JSON.parse(branchMappingString);
} catch (e) {
} catch {
throw new Error(`Could not parse branchMapping string into a JSON: "${branchMappingString}"`);
}
assert(branchMapping, 'Branch Mapping must be defined.');
@@ -1,151 +0,0 @@
import { getConfig } from '@expo/config';
import spawnAsync, { SpawnOptions, SpawnResult } from '@expo/spawn-async';
import admzip from 'adm-zip';
import fs from 'fs';
import fsPromise from 'fs/promises';
import got from 'got';
import fetch from 'node-fetch';
import path from 'path';
import { pipeline } from 'stream/promises';
import { makeZipAsync } from '../../build/utils/repository';
import EasCommand from '../../commandUtils/EasCommand';
import { bundleFunctionsAsync, prepareFunctionEntriesAsync } from '../../functions/webpack';
import { FunctionMutation } from '../../graphql/mutations/FunctionMutation';
import { PresignedPost } from '../../graphql/mutations/UploadSessionMutation';
import Log from '../../log';
import { ora } from '../../ora';
import {
findProjectRootAsync,
getProjectAccountName,
getProjectIdAsync,
} from '../../project/projectUtils';
import { uploadWithPresignedPostAsync } from '../../uploads';
import { ensureLoggedInAsync } from '../../user/actions';
import { expoCommandAsync } from '../../utils/expoCli';
import { sleepAsync } from '../../utils/promise';
export default class FunctionsCreate extends EasCommand {
static description = 'create a function';
async runAsync(): Promise<void> {
const projectDir = await findProjectRootAsync();
const { exp } = getConfig(projectDir, { skipSDKVersionRequirement: true });
const projectId = await getProjectIdAsync(exp);
const downloadSpinner = ora('Downloading functions template...').start();
const functionsTemplateUrl =
'https://github.com/quinlanj/functions-entry-point/archive/refs/heads/main.zip';
const functionsBuild = 'functions-build';
const functionsBuildZip = `${functionsBuild}.zip`;
const originalUnzippedDirectory = 'functions-entry-point-main';
// ensure empty build directory
await fsPromise.rm(path.join(projectDir, functionsBuild), { force: true, recursive: true });
// download and unzip the functions template
const downloadStream = got.stream(functionsTemplateUrl);
await pipeline(downloadStream, fs.createWriteStream(path.join(projectDir, functionsBuildZip)));
const zip = new admzip(functionsBuildZip);
zip.extractAllTo(/*target path*/ path.join(projectDir), /*overwrite*/ true);
// rename to desired dir, remove zip
await Promise.all([
fsPromise.rename(
path.join(projectDir, originalUnzippedDirectory),
path.join(projectDir, functionsBuild)
),
fsPromise.rm(path.join(projectDir, functionsBuildZip)),
]);
downloadSpinner.succeed('Downloaded functions template');
const permissionSpinner = ora('Modifying permissions...').start();
const promises = [];
for (const file of await fsPromise.readdir(path.join(projectDir, functionsBuild, 'scripts'))) {
promises.push(fsPromise.chmod(path.join(projectDir, functionsBuild, 'scripts', file), 0o777));
}
await Promise.all(promises);
permissionSpinner.succeed('Modified permissions');
const gitSpinner = ora('Initializing inner git...').start();
process.chdir(path.join(projectDir, functionsBuild));
const { status, stderr } = await spawnAsync('git', ['init']);
if (status !== 0) {
throw new Error('Failed to initialize git: ' + stderr);
}
process.chdir('..');
gitSpinner.succeed('Initialized inner git');
Log.log('Bundling functions...');
const functionDirectory = path.join(projectDir, 'functions');
const functionEntries = await prepareFunctionEntriesAsync(functionDirectory);
const outputDirectory = path.join(projectDir, functionsBuild, 'functions');
await bundleFunctionsAsync(projectDir, functionEntries, outputDirectory);
Log.log('Successfully bundled functions...');
Log.log('Doing web build...');
const accountName = getProjectAccountName(exp, await ensureLoggedInAsync());
const functionName = `${accountName}-${exp.slug}`; // TODO: set up a Cloudflare enterprise domain so we don't have to do this
const region = 'us-east1';
const cloudFunctionProject = 'eas-functions';
const publicUrl = `https://${region}-${cloudFunctionProject}.cloudfunctions.net/${functionName}`;
const webOutputDirectory = path.join(projectDir, functionsBuild, 'web-build');
await expoCommandAsync(projectDir, ['build:web'], {
env: { WEBPACK_BUILD_OUTPUT_PATH: webOutputDirectory, WEB_PUBLIC_URL: publicUrl },
});
Log.log('Finished web build...');
const { path: compressedProjectPath } = await makeZipAsync(
path.join(projectDir, functionsBuild)
);
const uploadSpinner = ora('Uploading project...').start();
let bucketKey;
try {
const specification = await FunctionMutation.uploadAsync(projectId);
const presignedPost: PresignedPost = JSON.parse(specification);
await uploadWithPresignedPostAsync(compressedProjectPath, presignedPost);
bucketKey = presignedPost.fields.key;
uploadSpinner.succeed(`Successfully uploaded project to bucket: ${bucketKey}`);
} catch (err) {
uploadSpinner.fail('Failed to upload project');
throw err;
}
const spinner = ora('Creating a function...').start();
try {
const success = await FunctionMutation.createAsync(bucketKey, projectId);
spinner.succeed(`Successfully created function: ${success}`);
} catch (err) {
spinner.fail('Failed to create a function');
throw err;
}
Log.log('Streaming build logs....');
const logsPrinted = new Set<string>();
let sawLastLog = false;
while (true) {
const { status, logUrls } = await FunctionMutation.getStatusAsync(projectId);
Log.log(`Function status: ${status}`);
const logsUrlsToPrint = logUrls.filter(url => !logsPrinted.has(url)).sort();
const logResponses = await Promise.all(logsUrlsToPrint.map(url => fetch(url)));
const logBodies = await Promise.all(logResponses.map(body => body.text()));
const logPayloads = logBodies.map(body => JSON.parse(body)).map(body => body.textPayload);
logPayloads.forEach(response => Log.log(response));
logsUrlsToPrint.forEach(logUrl => logsPrinted.add(logUrl));
if (!sawLastLog) {
sawLastLog = logPayloads.some(log => log === 'DONE');
}
if (sawLastLog && status === 'ACTIVE') {
Log.log(`🎉🎉🎉 Hooray! Your function is complete!`);
Log.log(`🎉🎉🎉 Your web-app is available at: ${publicUrl}`);
for (const submodule of Object.keys(functionEntries)) {
Log.log(`🎉🎉🎉 ${submodule} is available at: ${publicUrl}/functions/${submodule}`);
}
break;
} else if (status !== 'ACTIVE' && status !== 'DEPLOY_IN_PROGRESS') {
Log.log(`🤔 Uh oh...your function is ${status}`);
break;
}
await sleepAsync(6000);
}
}
}
@@ -1,25 +0,0 @@
import path from 'path';
import EasCommand from '../../commandUtils/EasCommand';
import { installNodeDependenciesAsync } from '../../functions/CreateApp';
import { YarnPackageManager } from '../../functions/PackageManager';
import Log from '../../log';
import { ora } from '../../ora';
import { findProjectRootAsync } from '../../project/projectUtils';
export default class FunctionsCreate extends EasCommand {
static description = 'start a function';
async runAsync(): Promise<void> {
const projectDir = await findProjectRootAsync();
const functionsBuild = 'functions-build';
const installSpinner = ora('Installing dependencies...').start();
await installNodeDependenciesAsync(path.join(projectDir, functionsBuild), 'yarn');
installSpinner.succeed('Modified permissions');
Log.log('serving up the function...');
const yarn = new YarnPackageManager({ cwd: path.join(projectDir, functionsBuild) });
await yarn.runAsync('dev');
}
}
@@ -20,7 +20,7 @@ function fileIsServiceAccountKey(keyJsonPath: string): boolean {
try {
readAndValidateServiceAccountKey(keyJsonPath);
return true;
} catch (err: any) {
} catch {
return false;
}
}
@@ -24,7 +24,7 @@ export async function keytoolCommandExistsAsync(): Promise<boolean> {
try {
await spawnAsync('keytool');
return true;
} catch (error) {
} catch {
return false;
}
}
@@ -24,7 +24,7 @@ function isPKCSKeystore(keystore: Keystore): boolean {
try {
parsePKCS12(keystore.keystore, keystore.keystorePassword);
return true;
} catch (e) {
} catch {
return false;
}
}
@@ -33,7 +33,7 @@ function isJKSKeystore(keystore: Keystore): boolean {
try {
jks.parseJks(Buffer.from(keystore.keystore, 'base64'), keystore.keystorePassword);
return true;
} catch (e) {
} catch {
return false;
}
}
+1 -1
View File
@@ -50,7 +50,7 @@ export class CredentialsContext {
): ExpoConfig | null {
try {
return getExpoConfig(projectDir, { env });
} catch (error) {
} catch {
// ignore error, context might be created outside of expo project
return null;
}
@@ -114,7 +114,7 @@ export async function readRawAsync(
try {
const credentialsJSONContents = await fs.readFile(credentialsJsonFilePath, 'utf8');
return JSON.parse(credentialsJSONContents);
} catch (err) {
} catch {
throw new Error(
`credentials.json must exist in the project root directory and contain a valid JSON`
);
@@ -15,7 +15,7 @@ describe(getCertData, () => {
});
});
describe(forge.pkcs12.pkcs12FromAsn1, () => {
describe('forge.pkcs12.pkcs12FromAsn1', () => {
describe('when using p12 created from keychain', () => {
it('throws if empty string is passed', async () => {
const p12Der = forge.util.decode64(testDistributionCertificateEmptyPasswordBase64);
@@ -31,7 +31,7 @@ export function parse(dataBase64: string): PlistObject {
const buffer = Buffer.from(dataBase64, 'base64');
const profile = buffer.toString('utf8');
return plist.parse(profile) as PlistObject;
} catch (error) {
} catch {
throw new Error('Provisioning profile is malformed');
}
}
@@ -75,7 +75,7 @@ function validateProvisioningProfileWithoutApple(
Log.warn('Provisioning Profile has expired.');
return false;
}
} catch (error) {
} catch {
Log.warn('Provisioning Profile is malformed.');
return false;
}
@@ -1,41 +0,0 @@
import * as PackageManager from '@expo/package-manager';
import fs from 'fs/promises';
import yaml from 'js-yaml';
import * as path from 'path';
import semver from 'semver';
import Log from '../log';
export async function installNodeDependenciesAsync(
projectRoot: string,
packageManager: 'yarn' | 'npm'
): Promise<void> {
const options = { cwd: projectRoot };
if (packageManager === 'yarn') {
const yarn = new PackageManager.YarnPackageManager(options);
const version = await yarn.versionAsync();
const nodeLinker = await yarn.getConfigAsync('nodeLinker');
if (semver.satisfies(version, '>=2.0.0-rc.24') && nodeLinker !== 'node-modules') {
const yarnRc = path.join(projectRoot, '.yarnrc.yml');
let yamlString = '';
try {
yamlString = await fs.readFile(yarnRc, 'utf8');
} catch (error: any) {
if (error.code !== 'ENOENT') {
throw error;
}
}
const config: any = yamlString ? yaml.safeLoad(yamlString) : {};
config.nodeLinker = 'node-modules';
Log.warn(
`Yarn v${version} detected, enabling experimental Yarn v2 support using the node-modules plugin.`
);
Log.log(`Writing ${yarnRc}...`);
await fs.writeFile(yarnRc, yaml.safeDump(config));
}
await yarn.installAsync();
} else {
await new PackageManager.NpmPackageManager(options).installAsync();
}
}
@@ -1,66 +0,0 @@
import spawnAsync, { SpawnOptions, SpawnResult } from '@expo/spawn-async';
import { Transform } from 'stream';
import Log from '../log';
function ansiRegex({ onlyFirst = false } = {}): RegExp {
const pattern = [
'[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)',
'(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~]))',
].join('|');
return new RegExp(pattern, onlyFirst ? undefined : 'g');
}
const ansi = `(?:${ansiRegex().source})*`;
const yarnPeerDependencyWarningPattern = new RegExp(
`${ansi}warning${ansi} "[^"]+" has (?:unmet|incorrect) peer dependency "[^"]+"\\.\n`,
'g'
);
class YarnStderrTransform extends Transform {
_transform(
chunk: Buffer,
_encoding: string,
callback: (error?: Error | null, data?: any) => void
): void {
this.push(chunk.toString().replace(yarnPeerDependencyWarningPattern, ''));
callback();
}
}
export class YarnPackageManager {
options: SpawnOptions;
constructor({ cwd, silent }: { cwd: string; silent?: boolean }) {
this.options = {
env: {
...process.env,
},
cwd,
...(silent
? { ignoreStdio: true }
: {
stdio: ['inherit', 'inherit', 'pipe'],
}),
};
}
async runAsync(command: string): Promise<void> {
await this.runPrivateAsync([command]);
}
// Private
private async runPrivateAsync(args: string[]): Promise<SpawnResult> {
if (!this.options.ignoreStdio) {
Log.log(`> yarn ${args.join(' ')}`);
}
// Have spawnAsync consume stdio but we don't actually do anything with it if it's ignored
const promise = spawnAsync('yarnpkg', args, { ...this.options, ignoreStdio: false });
if (promise.child.stderr && !this.options.ignoreStdio) {
promise.child.stderr.pipe(new YarnStderrTransform()).pipe(process.stderr);
}
return promise;
}
}
@@ -1,123 +0,0 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
'use strict';
const friendlySyntaxErrorLabel = 'Syntax error:';
function isLikelyASyntaxError(message: string | string[]): boolean {
return message.indexOf(friendlySyntaxErrorLabel) !== -1;
}
// Cleans up webpack error messages.
function formatMessage(message: any): any {
let lines = [];
if (typeof message === 'string') {
lines = message.split('\n');
} else if ('message' in message) {
lines = message['message'].split('\n');
} else if (Array.isArray(message)) {
message.forEach(message => {
if ('message' in message) {
lines = message['message'].split('\n');
}
});
}
// Strip webpack-added headers off errors/warnings
// https://github.com/webpack/webpack/blob/master/lib/ModuleError.js
lines = lines.filter((line: string) => !/Module [A-z ]+\(from/.test(line));
// Transform parsing error into syntax error
// TODO: move this to our ESLint formatter?
lines = lines.map((line: string) => {
const parsingError = /Line (\d+):(?:(\d+):)?\s*Parsing error: (.+)$/.exec(line);
if (!parsingError) {
return line;
}
const [, errorLine, errorColumn, errorMessage] = parsingError;
return `${friendlySyntaxErrorLabel} ${errorMessage} (${errorLine}:${errorColumn})`;
});
message = lines.join('\n');
// Smoosh syntax errors (commonly found in CSS)
message = message.replace(
/SyntaxError\s+\((\d+):(\d+)\)\s*(.+?)\n/g,
`${friendlySyntaxErrorLabel} $3 ($1:$2)\n`
);
// Clean up export errors
message = message.replace(
/^.*export '(.+?)' was not found in '(.+?)'.*$/gm,
`Attempted import error: '$1' is not exported from '$2'.`
);
message = message.replace(
/^.*export 'default' \(imported as '(.+?)'\) was not found in '(.+?)'.*$/gm,
`Attempted import error: '$2' does not contain a default export (imported as '$1').`
);
message = message.replace(
/^.*export '(.+?)' \(imported as '(.+?)'\) was not found in '(.+?)'.*$/gm,
`Attempted import error: '$1' is not exported from '$3' (imported as '$2').`
);
lines = message.split('\n');
// Remove leading newline
if (lines.length > 2 && lines[1].trim() === '') {
lines.splice(1, 1);
}
// Clean up file name
lines[0] = lines[0].replace(/^(.*) \d+:\d+-\d+$/, '$1');
// Cleans up verbose "module not found" messages for files and packages.
if (lines[1] && lines[1].indexOf('Module not found: ') === 0) {
lines = [
lines[0],
lines[1]
.replace('Error: ', '')
.replace('Module not found: Cannot find file:', 'Cannot find file:'),
];
}
// Add helpful message for users trying to use Sass for the first time
if (lines[1] && lines[1].match(/Cannot find module.+sass/)) {
lines[1] = 'To import Sass files, you first need to install sass.\n';
lines[1] += 'Run `npm install sass` or `yarn add sass` inside your workspace.';
}
message = lines.join('\n');
// Internal stacks are generally useless so we strip them... with the
// exception of stacks containing `webpack:` because they're normally
// from user code generated by webpack. For more information see
// https://github.com/facebook/create-react-app/pull/1050
message = message.replace(/^\s*at\s((?!webpack:).)*:\d+:\d+[\s)]*(\n|$)/gm, ''); // at ... ...:x:y
message = message.replace(/^\s*at\s<anonymous>(\n|$)/gm, ''); // at <anonymous>
lines = message.split('\n');
// Remove duplicated newlines
lines = lines.filter(
(line: string, index: number, arr: string[]) =>
index === 0 || line.trim() !== '' || line.trim() !== arr[index - 1].trim()
);
// Reassemble the message
message = lines.join('\n');
return message.trim();
}
export function formatWebpackMessages(json: any): {
errors: any[];
warnings: any[];
} {
const formattedErrors = json.errors.map(formatMessage);
const formattedWarnings = json.warnings.map(formatMessage);
const result = { errors: formattedErrors, warnings: formattedWarnings };
if (result.errors.some(isLikelyASyntaxError)) {
// If there are any syntax errors, show just them.
result.errors = result.errors.filter(isLikelyASyntaxError);
}
return result;
}
-132
View File
@@ -1,132 +0,0 @@
import chalk from 'chalk';
import fs from 'fs/promises';
import path from 'path';
import PnpWebpackPlugin from 'pnp-webpack-plugin';
import { Compiler, Configuration, EntryObject, webpack } from 'webpack';
import Log from '../log';
import { formatWebpackMessages } from './formatWebpackMessages';
async function getWebpackFunctionConfigurationAsync(
projectDir: string,
entry: EntryObject,
outputPath: string
): Promise<Configuration> {
const webpackConfig = {
entry,
target: 'node',
mode: 'development' as 'development',
// Disable file info logs.
//stats: 'none',
// https://webpack.js.org/configuration/other-options/#bail
// Fail out on the first error instead of tolerating it.
bail: true,
module: {
rules: [
{
test: /\.tsx?$/,
use: {
loader: require.resolve('ts-loader'),
options: {
configFile: require.resolve('../../functions.tsconfig.webpack.json'),
context: projectDir,
},
},
exclude: /node_modules/,
},
],
},
resolve: {
plugins: [PnpWebpackPlugin],
extensions: ['.tsx', '.ts', '.js'],
},
resolveLoader: {
plugins: [PnpWebpackPlugin.moduleLoader(module)],
},
output: {
filename: '[name].js',
path: outputPath,
library: {
type: 'commonjs',
},
},
};
return webpackConfig;
}
async function compileWebAppAsync(compiler: Compiler): Promise<any> {
// We generate the stats.json file in the webpack-config
const { warnings } = await new Promise((resolve, reject) =>
compiler.run((error, stats) => {
let messages;
if (error) {
if (!error.message) {
return reject(error);
}
messages = formatWebpackMessages({
errors: [error.message],
warnings: [],
_showErrors: true,
_showWarnings: true,
});
} else {
messages = formatWebpackMessages(
stats?.toJson({ all: false, warnings: true, errors: true })
);
}
if (messages.errors.length) {
// Only keep the first error. Others are often indicative
// of the same problem, but confuse the reader with noise.
if (messages.errors.length > 1) {
messages.errors.length = 1;
}
return reject(messages.errors.join('\n\n'));
}
resolve({
warnings: messages.warnings,
});
})
);
return { warnings };
}
export async function bundleFunctionsAsync(
projectDir: string,
entry: EntryObject,
outputPath: string
): Promise<void> {
const config = await getWebpackFunctionConfigurationAsync(projectDir, entry, outputPath);
const compiler = webpack(config);
try {
const { warnings } = await compileWebAppAsync(compiler);
if (warnings.length) {
Log.warn(chalk.yellow('Compiled with warnings.\n'));
Log.warn(warnings.join('\n\n'));
} else {
Log.log(chalk.green('Compiled successfully.\n'));
}
} catch (error) {
Log.error(chalk.red('Failed to compile.\n'));
Log.error(error);
throw error;
}
}
export async function prepareFunctionEntriesAsync(functionsPath: string): Promise<EntryObject> {
const files = await fs.readdir(functionsPath);
if (files.length === 0) {
throw new Error(`No functions found in ${functionsPath}`);
}
const entries = {} as EntryObject;
for (const file of files) {
const filenameNoExtension = path.parse(file).name;
entries[filenameNoExtension] = path.join(functionsPath, file);
}
return entries;
}
+63 -86
View File
@@ -94,7 +94,7 @@ export type Account = {
apps: Array<App>;
/** @deprecated Build packs are no longer supported */
availableBuilds?: Maybe<Scalars['Int']>;
/** Billing information */
/** Billing information. Only visible to members with the ADMIN or OWNER role. */
billing?: Maybe<Billing>;
billingPeriod: BillingPeriod;
/** Build Jobs associated with this account */
@@ -338,7 +338,9 @@ export type AccountMutationRenameArgs = {
export type AccountMutationRequestRefundArgs = {
accountID: Scalars['ID'];
chargeIdentifier: Scalars['ID'];
chargeID: Scalars['ID'];
description?: InputMaybe<Scalars['String']>;
reason?: InputMaybe<Scalars['String']>;
};
@@ -393,12 +395,25 @@ export type AccountQueryByNameArgs = {
export type AccountUsageMetric = {
__typename?: 'AccountUsageMetric';
metric: EasServiceMetric;
id: Scalars['ID'];
metricType: UsageMetricType;
serviceMetric: EasServiceMetric;
timestamp: Scalars['DateTime'];
value: Scalars['Float'];
};
export type AccountUsageMetricAndCost = {
__typename?: 'AccountUsageMetricAndCost';
id: Scalars['ID'];
/** The limit, in units, allowed by this plan */
limit: Scalars['Float'];
metricType: UsageMetricType;
serviceMetric: EasServiceMetric;
/** Total cost of this particular metric, in cents */
totalCost: Scalars['Float'];
value: Scalars['Float'];
};
export type AccountUsageMetrics = {
__typename?: 'AccountUsageMetrics';
byBillingPeriod: UsageMetricTotal;
@@ -413,7 +428,7 @@ export type AccountUsageMetricsByBillingPeriodArgs = {
export type AccountUsageMetricsMetricsForServiceMetricArgs = {
granularity: UsageMetricsGranularity;
metric: EasServiceMetric;
serviceMetric: EasServiceMetric;
timespan: UsageMetricsTimespan;
};
@@ -1008,15 +1023,20 @@ export type AppDataInput = {
export type AppIcon = {
__typename?: 'AppIcon';
/** Nullable color palette of the app icon. If null, color palette couldn't be retrieved from external service (imgix) */
/** @deprecated No longer supported */
colorPalette?: Maybe<Scalars['JSON']>;
originalUrl: Scalars['String'];
primaryColor?: Maybe<Scalars['String']>;
url: Scalars['String'];
};
export type AppInfoInput = {
displayName?: InputMaybe<Scalars['String']>;
};
export type AppInput = {
accountId: Scalars['ID'];
appInfo?: InputMaybe<AppInfoInput>;
privacy: AppPrivacy;
projectName: Scalars['String'];
};
@@ -1027,6 +1047,8 @@ export type AppMutation = {
createApp: App;
/** @deprecated No longer supported */
grantAccess?: Maybe<App>;
/** Set display info for app */
setAppInfo: App;
/** Require api token to send push notifs for experience */
setPushSecurityEnabled: App;
};
@@ -1043,6 +1065,12 @@ export type AppMutationGrantAccessArgs = {
};
export type AppMutationSetAppInfoArgs = {
appId: Scalars['ID'];
appInfo: AppInfoInput;
};
export type AppMutationSetPushSecurityEnabledArgs = {
appId: Scalars['ID'];
pushSecurityEnabled: Scalars['Boolean'];
@@ -1911,6 +1939,13 @@ export type CodeSigningInfoInput = {
sig: Scalars['String'];
};
export type Concurrencies = {
__typename?: 'Concurrencies';
android: Scalars['Int'];
ios: Scalars['Int'];
total: Scalars['Int'];
};
export type CreateAccessTokenInput = {
actorID: Scalars['ID'];
note?: InputMaybe<Scalars['String']>;
@@ -1926,6 +1961,7 @@ export type CreateAccessTokenResponse = {
export type CreateAndroidSubmissionInput = {
appId: Scalars['ID'];
archiveUrl?: InputMaybe<Scalars['String']>;
config: AndroidSubmissionConfigInput;
submittedBuildId?: InputMaybe<Scalars['ID']>;
};
@@ -1943,17 +1979,11 @@ export type CreateEnvironmentSecretInput = {
export type CreateIosSubmissionInput = {
appId: Scalars['ID'];
archiveUrl?: InputMaybe<Scalars['String']>;
config: IosSubmissionConfigInput;
submittedBuildId?: InputMaybe<Scalars['ID']>;
};
export type CreateSubmissionInput = {
appId: Scalars['ID'];
config: Scalars['JSONObject'];
platform: AppPlatform;
submittedBuildId?: InputMaybe<Scalars['ID']>;
};
export type CreateSubmissionResult = {
__typename?: 'CreateSubmissionResult';
/** Created submission */
@@ -2025,11 +2055,6 @@ export type DeleteWebhookResult = {
id: Scalars['ID'];
};
export type DeployFunctionResult = {
__typename?: 'DeployFunctionResult';
success: Scalars['Boolean'];
};
/** Represents a Deployment - a set of Builds with the same Runtime Version and Channel */
export type Deployment = {
__typename?: 'Deployment';
@@ -2068,7 +2093,10 @@ export enum EasBuildDeprecationInfoType {
}
export enum EasServiceMetric {
ManifestRequests = 'MANIFEST_REQUESTS'
AssetsRequests = 'ASSETS_REQUESTS',
BandwidthUsage = 'BANDWIDTH_USAGE',
ManifestRequests = 'MANIFEST_REQUESTS',
UniqueUsers = 'UNIQUE_USERS'
}
export type EditUpdateBranchInput = {
@@ -2160,40 +2188,6 @@ export enum Feature {
Teams = 'TEAMS'
}
export type FunctionMutation = {
__typename?: 'FunctionMutation';
createFunction: DeployFunctionResult;
getFunctionStatus: FunctionStatusResult;
getSignedFunctionUploadSpecification: GetFunctionUploadUrlResult;
};
export type FunctionMutationCreateFunctionArgs = {
appId: Scalars['String'];
bucketKey: Scalars['String'];
};
export type FunctionMutationGetFunctionStatusArgs = {
appId: Scalars['String'];
};
export type FunctionMutationGetSignedFunctionUploadSpecificationArgs = {
appId: Scalars['String'];
};
export type FunctionStatusResult = {
__typename?: 'FunctionStatusResult';
logUrls: Array<Scalars['String']>;
status: Scalars['String'];
};
export type GetFunctionUploadUrlResult = {
__typename?: 'GetFunctionUploadUrlResult';
specification: Scalars['String'];
};
export type GetSignedAssetUploadSpecificationsResult = {
__typename?: 'GetSignedAssetUploadSpecificationsResult';
specifications: Array<Scalars['String']>;
@@ -2911,7 +2905,6 @@ export type RootMutation = {
emailSubscription: EmailSubscriptionMutation;
/** Mutations that create and delete EnvironmentSecrets */
environmentSecret: EnvironmentSecretMutation;
function: FunctionMutation;
/** Mutations that modify a Google Service Account Key */
googleServiceAccountKey: GoogleServiceAccountKeyMutation;
/** Mutations that modify the build credentials for an iOS app */
@@ -3154,6 +3147,8 @@ export type Submission = ActivityTimelineProjectActivity & {
actor?: Maybe<Actor>;
androidConfig?: Maybe<AndroidSubmissionConfig>;
app: App;
archiveUrl?: Maybe<Scalars['String']>;
canRetry: Scalars['Boolean'];
cancelingActor?: Maybe<Actor>;
createdAt: Scalars['DateTime'];
error?: Maybe<SubmissionError>;
@@ -3161,6 +3156,7 @@ export type Submission = ActivityTimelineProjectActivity & {
initiatingActor?: Maybe<Actor>;
iosConfig?: Maybe<IosSubmissionConfig>;
logsUrl?: Maybe<Scalars['String']>;
parentSubmission?: Maybe<Submission>;
platform: AppPlatform;
status: SubmissionStatus;
submittedBuild?: Maybe<Build>;
@@ -3205,16 +3201,13 @@ export type SubmissionMutation = {
createAndroidSubmission: CreateSubmissionResult;
/** Create an iOS EAS Submit submission */
createIosSubmission: CreateSubmissionResult;
/**
* Create an EAS Submit submission
* @deprecated Use createIosSubmission / createAndroidSubmission instead
*/
createSubmission: CreateSubmissionResult;
/** Retry an EAS Submit submission */
retrySubmission: CreateSubmissionResult;
};
export type SubmissionMutationCancelSubmissionArgs = {
submissionId?: InputMaybe<Scalars['ID']>;
submissionId: Scalars['ID'];
};
@@ -3228,8 +3221,8 @@ export type SubmissionMutationCreateIosSubmissionArgs = {
};
export type SubmissionMutationCreateSubmissionArgs = {
input: CreateSubmissionInput;
export type SubmissionMutationRetrySubmissionArgs = {
parentSubmissionId: Scalars['ID'];
};
export type SubmissionQuery = {
@@ -3256,6 +3249,7 @@ export type SubscriptionDetails = {
__typename?: 'SubscriptionDetails';
addons: Array<AddonDetails>;
cancelledAt?: Maybe<Scalars['DateTime']>;
concurrencies?: Maybe<Concurrencies>;
endedAt?: Maybe<Scalars['DateTime']>;
id: Scalars['ID'];
isDowngrading?: Maybe<Scalars['Boolean']>;
@@ -3444,12 +3438,17 @@ export enum UploadSessionType {
export type UsageMetricTotal = {
__typename?: 'UsageMetricTotal';
billingPeriod: BillingPeriod;
metrics: Array<AccountUsageMetric>;
total: Scalars['Float'];
id: Scalars['ID'];
overageMetrics: Array<AccountUsageMetricAndCost>;
planMetrics: Array<AccountUsageMetricAndCost>;
/** Total cost of overages, in cents */
totalCost: Scalars['Float'];
};
export enum UsageMetricType {
Request = 'REQUEST'
Bandwidth = 'BANDWIDTH',
Request = 'REQUEST',
User = 'USER'
}
export enum UsageMetricsGranularity {
@@ -4344,28 +4343,6 @@ export type DeleteEnvironmentSecretMutationVariables = Exact<{
export type DeleteEnvironmentSecretMutation = { __typename?: 'RootMutation', environmentSecret: { __typename?: 'EnvironmentSecretMutation', deleteEnvironmentSecret: { __typename?: 'DeleteEnvironmentSecretResult', id: string } } };
export type GetSignedUploadFunctionMutationVariables = Exact<{
appId: Scalars['String'];
}>;
export type GetSignedUploadFunctionMutation = { __typename?: 'RootMutation', function: { __typename?: 'FunctionMutation', getSignedFunctionUploadSpecification: { __typename?: 'GetFunctionUploadUrlResult', specification: string } } };
export type CreateFunctionMutationVariables = Exact<{
bucketKey: Scalars['String'];
appId: Scalars['String'];
}>;
export type CreateFunctionMutation = { __typename?: 'RootMutation', function: { __typename?: 'FunctionMutation', createFunction: { __typename?: 'DeployFunctionResult', success: boolean } } };
export type GetFunctionStatusMutationVariables = Exact<{
appId: Scalars['String'];
}>;
export type GetFunctionStatusMutation = { __typename?: 'RootMutation', function: { __typename?: 'FunctionMutation', getFunctionStatus: { __typename?: 'FunctionStatusResult', status: string, logUrls: Array<string> } } };
export type CreateKeystoreGenerationUrlMutationVariables = Exact<{ [key: string]: never; }>;
@@ -1,79 +0,0 @@
import gql from 'graphql-tag';
import { graphqlClient, withErrorHandlingAsync } from '../client';
import {
CreateFunctionMutation,
CreateFunctionMutationVariables,
GetFunctionStatusMutation,
GetFunctionStatusMutationVariables,
GetSignedUploadFunctionMutation,
GetSignedUploadFunctionMutationVariables,
} from '../generated';
export const FunctionMutation = {
async uploadAsync(appId: string): Promise<string> {
const data = await withErrorHandlingAsync(
graphqlClient
.mutation<GetSignedUploadFunctionMutation, GetSignedUploadFunctionMutationVariables>(
gql`
mutation GetSignedUploadFunctionMutation($appId: String!) {
function {
getSignedFunctionUploadSpecification(appId: $appId) {
specification
}
}
}
`,
{
appId,
}
)
.toPromise()
);
return data.function.getSignedFunctionUploadSpecification.specification;
},
async createAsync(bucketKey: string, appId: string): Promise<boolean> {
const data = await withErrorHandlingAsync(
graphqlClient
.mutation<CreateFunctionMutation, CreateFunctionMutationVariables>(
gql`
mutation CreateFunctionMutation($bucketKey: String!, $appId: String!) {
function {
createFunction(bucketKey: $bucketKey, appId: $appId) {
success
}
}
}
`,
{
bucketKey,
appId,
}
)
.toPromise()
);
return data.function.createFunction.success;
},
async getStatusAsync(appId: string): Promise<{ status: string; logUrls: string[] }> {
const data = await withErrorHandlingAsync(
graphqlClient
.mutation<GetFunctionStatusMutation, GetFunctionStatusMutationVariables>(
gql`
mutation GetFunctionStatusMutation($appId: String!) {
function {
getFunctionStatus(appId: $appId) {
status
logUrls
}
}
}
`,
{
appId,
}
)
.toPromise()
);
return data.function.getFunctionStatus;
},
};
@@ -412,9 +412,9 @@ describe(uploadAssetsAsync, () => {
return { specifications: ['{}', '{}', '{}'] };
});
beforeEach(() => {
jest.useFakeTimers();
});
// beforeEach(() => {
// jest.useFakeTimers();
// });
it('throws an error if the upload exceeds TIMEOUT_LIMIT', async () => {
jest.spyOn(PublishQuery, 'getAssetMetadataAsync').mockImplementation(async () => {
const status = AssetMetadataStatus.DoesNotExist;
@@ -28,7 +28,7 @@ export async function ensureApplicationIdIsDefinedForManagedProjectAsync(
return await getApplicationIdAsync(projectDir, exp, {
moduleName: gradleUtils.DEFAULT_MODULE_NAME,
});
} catch (err) {
} catch {
return await configureApplicationIdAsync(projectDir, exp);
}
}
@@ -23,7 +23,7 @@ export async function ensureBundleIdentifierIsDefinedForManagedProjectAsync(
try {
return await getBundleIdentifierAsync(projectDir, exp);
} catch (err) {
} catch {
return await configureBundleIdentifierAsync(projectDir, exp);
}
}
+1 -1
View File
@@ -482,7 +482,7 @@ function validateUrl(url: string): boolean {
? protocols.map(x => `${x.toLowerCase()}:`).includes(parsed.protocol)
: false
: true;
} catch (err) {
} catch {
return false;
}
}
+1 -1
View File
@@ -8,7 +8,7 @@ export async function isExistingFileAsync(filePath: string): Promise<boolean> {
try {
const stats = await fs.stat(filePath);
return stats.isFile();
} catch (e) {
} catch {
return false;
}
}
+1 -1
View File
@@ -53,7 +53,7 @@ function parseLogs(logs: string): LogLine[] {
let parsedLine;
try {
parsedLine = JSON.parse(line);
} catch (error) {
} catch {
continue;
}
let level: LogLine['level'];
@@ -35,7 +35,7 @@ export async function readReleaseChannelSafelyAsync(projectDir: string): Promise
androidManifest,
AndroidConfig.Updates.Config.RELEASE_CHANNEL
);
} catch (err) {
} catch {
return null;
}
}
@@ -51,7 +51,7 @@ export async function readChannelSafelyAsync(projectDir: string): Promise<string
return null;
}
return JSON.parse(stringifiedRequestHeaders)['expo-channel-name'] ?? null;
} catch (err) {
} catch {
return null;
}
}
@@ -42,7 +42,7 @@ export async function readReleaseChannelSafelyAsync(projectDir: string): Promise
try {
const expoPlist = await readExpoPlistAsync(projectDir);
return expoPlist[IOSConfig.Updates.Config.RELEASE_CHANNEL] ?? null;
} catch (err) {
} catch {
return null;
}
}
@@ -52,7 +52,7 @@ export async function readChannelSafelyAsync(projectDir: string): Promise<string
const expoPlist = await readExpoPlistAsync(projectDir);
const updatesRequestHeaders = expoPlist['EXUpdatesRequestHeaders'];
return updatesRequestHeaders['expo-channel-name'] ?? null;
} catch (err) {
} catch {
return null;
}
}
+1 -1
View File
@@ -62,7 +62,7 @@ export async function ensureLoggedInAsync({ nonInteractive = false } = {}): Prom
let user: Actor | undefined;
try {
user = await getUserAsync();
} catch (_) {}
} catch {}
if (!user) {
Log.warn('An Expo user account is required to proceed.');
+1 -5
View File
@@ -7,15 +7,11 @@ import Log from '../log';
export async function expoCommandAsync(
projectDir: string,
args: string[],
{ silent = false, env }: { silent?: boolean; env?: { [key: string]: string } } = {}
{ silent = false }: { silent?: boolean } = {}
): Promise<void> {
const expoCliPath = resolveFrom(projectDir, 'expo/bin/cli.js');
const spawnPromise = spawnAsync(expoCliPath, args, {
stdio: ['inherit', 'pipe', 'pipe'], // inherit stdin so user can install a missing expo-cli from inside this command
env: {
...process.env,
...env,
},
});
const {
child: { stdout, stderr },
+5 -5
View File
@@ -143,7 +143,7 @@ export default class GitClient extends Client {
public async getCommitHashAsync(): Promise<string | undefined> {
try {
return (await spawnAsync('git', ['rev-parse', 'HEAD'])).stdout.trim();
} catch (err) {
} catch {
return undefined;
}
}
@@ -155,7 +155,7 @@ export default class GitClient extends Client {
public async getBranchNameAsync(): Promise<string | null> {
try {
return (await spawnAsync('git', ['rev-parse', '--abbrev-ref', 'HEAD'])).stdout.trim();
} catch (e) {
} catch {
return null;
}
}
@@ -163,7 +163,7 @@ export default class GitClient extends Client {
public async getLastCommitMessageAsync(): Promise<string | null> {
try {
return (await spawnAsync('git', ['--no-pager', 'log', '-1', '--pretty=%B'])).stdout.trim();
} catch (e) {
} catch {
return null;
}
}
@@ -187,7 +187,7 @@ export default class GitClient extends Client {
try {
await spawnAsync('git', ['check-ignore', '-q', filePath]);
return true;
} catch (e) {
} catch {
return false;
}
}
@@ -284,7 +284,7 @@ export async function isGitCaseSensitiveAsync(): Promise<boolean | undefined> {
} else {
return true;
}
} catch (e) {
} catch {
return undefined;
}
}
+1 -1
View File
@@ -16,7 +16,7 @@ export async function doesGitRepoExistAsync(): Promise<boolean> {
try {
await spawnAsync('git', ['rev-parse', '--git-dir']);
return true;
} catch (err) {
} catch {
return false;
}
}
+3 -4
View File
@@ -78,12 +78,11 @@ export async function makeShallowCopyAsync(src: string, dst: string): Promise<vo
const ignore = new Ignore(src);
await ignore.initIgnoreAsync();
await fs.copy(src, dst, {
filter: (_srcFilePath: string) => {
return true; // TODO: handle ignored build folder
/* if (srcFilePath === src) {
filter: (srcFilePath: string) => {
if (srcFilePath === src) {
return true;
}
return !ignore.ignores(path.relative(src, srcFilePath)); */
return !ignore.ignores(path.relative(src, srcFilePath));
},
});
}
+1 -1
View File
@@ -78,7 +78,7 @@ export function validateURL(url: string): boolean {
// eslint-disable-next-line no-new
new URL(url);
return true;
} catch (err) {
} catch {
return false;
}
}
+6 -6
View File
@@ -5,20 +5,20 @@
"author": "Expo <[email protected]>",
"bugs": "https://github.com/expo/eas-cli/issues",
"dependencies": {
"@expo/eas-build-job": "0.2.71",
"@expo/json-file": "8.2.34",
"@expo/eas-build-job": "0.2.72",
"@expo/json-file": "8.2.36",
"chalk": "4.1.2",
"env-string": "1.0.1",
"fs-extra": "10.0.1",
"fs-extra": "10.1.0",
"joi": "17.6.0",
"log-symbols": "4.1.0",
"semver": "7.3.5",
"tslib": "2.3.1"
"semver": "7.3.7",
"tslib": "2.4.0"
},
"devDependencies": {
"@types/fs-extra": "9.0.13",
"memfs": "3.4.1",
"typescript": "4.6.3"
"typescript": "4.6.4"
},
"engines": {
"node": ">=12.0.0"
+8 -8
View File
@@ -14,20 +14,20 @@
},
"dependencies": {
"dateformat": "4.5.1",
"fs-extra": "10.0.0",
"fs-extra": "10.1.0",
"lodash": "4.17.21",
"marked": "3.0.4",
"nullthrows": "1.1.1",
"semver": "7.3.5",
"tslib": "2.3.1"
"semver": "7.3.7",
"tslib": "2.4.0"
},
"devDependencies": {
"@types/dateformat": "3.0.1",
"@types/fs-extra": "9.0.13",
"@types/lodash": "4.14.175",
"@types/node": "16.7.8",
"@types/semver": "7.3.8",
"ts-node": "10.2.1",
"typescript": "4.5.2"
"@types/lodash": "4.14.182",
"@types/node": "17.0.32",
"@types/semver": "7.3.9",
"ts-node": "10.7.0",
"typescript": "4.6.4"
}
}
+43 -37
View File
@@ -7,10 +7,10 @@
resolved "https://registry.yarnpkg.com/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz#33bf4b7b39c178821606f669bbc447a6a629786b"
integrity sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==
"@cspotcode/source-map-support@0.6.1":
version "0.6.1"
resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.6.1.tgz#118511f316e2e87ee4294761868e254d3da47960"
integrity sha512-DX3Z+T5dt1ockmPdobJS/FAsQPW4V4SrWEhD2iYQT2Cb2tQsiMnYxrcUH9By/Z3B+v0S5LMBkQtV/XOBbpLEOg==
"@cspotcode/source-map-support@0.7.0":
version "0.7.0"
resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz#4789840aa859e46d2f3173727ab707c66bf344f5"
integrity sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA==
dependencies:
"@cspotcode/source-map-consumer" "0.8.0"
@@ -46,25 +46,25 @@
dependencies:
"@types/node" "*"
"@types/[email protected]75":
version "4.14.175"
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.175.tgz#b78dfa959192b01fae0ad90e166478769b215f45"
integrity sha512-XmdEOrKQ8a1Y/yxQFOMbC47G/V2VDO1GvMRnl4O75M4GW/abC5tnfzadQYkqEveqRM1dEJGFFegfPNA2vvx2iw==
"@types/[email protected]82":
version "4.14.182"
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.182.tgz#05301a4d5e62963227eaafe0ce04dd77c54ea5c2"
integrity sha512-/THyiqyQAP9AfARo4pF+aCGcyiQ94tX/Is2I7HofNRqoYLgN1PBoOWu2/zTA5zMxzP5EFutMtWtGAFRKUe961Q==
"@types/node@*":
version "16.10.3"
resolved "https://registry.yarnpkg.com/@types/node/-/node-16.10.3.tgz#7a8f2838603ea314d1d22bb3171d899e15c57bd5"
integrity sha512-ho3Ruq+fFnBrZhUYI46n/bV2GjwzSkwuT4dTf0GkuNFmnb8nq4ny2z9JEVemFi6bdEJanHLlYfy9c6FN9B9McQ==
"@types/node@16.7.8":
version "16.7.8"
resolved "https://registry.yarnpkg.com/@types/node/-/node-16.7.8.tgz#2448be5f24fe6b77114632b6350fcd219334651e"
integrity sha512-8upnoQU0OPzbIkm+ZMM0zCeFCkw2s3mS0IWdx0+AAaWqm4fkBb0UJp8Edl7FVKRamYbpJC/aVsHpKWBIbiC7Zg==
"@types/node@17.0.32":
version "17.0.32"
resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.32.tgz#51d59d7a90ef2d0ae961791e0900cad2393a0149"
integrity sha512-eAIcfAvhf/BkHcf4pkLJ7ECpBAhh9kcxRBpip9cTiO+hf+aJrsxYxBeS6OXvOd9WqNAJmavXVpZvY1rBjNsXmw==
"@types/[email protected].8":
version "7.3.8"
resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.3.8.tgz#508a27995498d7586dcecd77c25e289bfaf90c59"
integrity sha512-D/2EJvAlCEtYFEYmmlGwbGXuK886HzyCc3nZX/tkFTQdEU8jZDAgiv08P162yB17y4ZXZoq7yFAnW4GDBb9Now==
"@types/[email protected].9":
version "7.3.9"
resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.3.9.tgz#152c6c20a7688c30b967ec1841d31ace569863fc"
integrity sha512-L/TMpyURfBkf+o/526Zb6kd/tchUP3iBDEPjqjb+U2MAJhVRxxrmr2fwpe08E7QsV7YLcpq0tUaQ9O9x97ZIxQ==
acorn-walk@^8.1.1:
version "8.2.0"
@@ -96,10 +96,10 @@ diff@^4.0.1:
resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d"
integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==
fs-extra@10.0.0:
version "10.0.0"
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.0.0.tgz#9ff61b655dde53fb34a82df84bb214ce802e17c1"
integrity sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ==
fs-extra@10.1.0:
version "10.1.0"
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.1.0.tgz#02873cfbc4084dde127eaa5f9905eef2325d1abf"
integrity sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==
dependencies:
graceful-fs "^4.2.0"
jsonfile "^6.0.1"
@@ -146,19 +146,19 @@ [email protected]:
resolved "https://registry.yarnpkg.com/nullthrows/-/nullthrows-1.1.1.tgz#7818258843856ae971eae4208ad7d7eb19a431b1"
integrity sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw==
[email protected].5:
version "7.3.5"
resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7"
integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==
[email protected].7:
version "7.3.7"
resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f"
integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==
dependencies:
lru-cache "^6.0.0"
ts-node@10.2.1:
version "10.2.1"
resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.2.1.tgz#4cc93bea0a7aba2179497e65bb08ddfc198b3ab5"
integrity sha512-hCnyOyuGmD5wHleOQX6NIjJtYVIO8bPP8F2acWkB4W06wdlkgyvJtubO/I9NkI88hCFECbsEgoLc0VNkYmcSfw==
ts-node@10.7.0:
version "10.7.0"
resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.7.0.tgz#35d503d0fab3e2baa672a0e94f4b40653c2463f5"
integrity sha512-TbIGS4xgJoX2i3do417KSaep1uRAW/Lu+WAL2doDHC0D6ummjirVOXU5/7aiZotbQ5p1Zp9tP7U6cYhA0O7M8A==
dependencies:
"@cspotcode/source-map-support" "0.6.1"
"@cspotcode/source-map-support" "0.7.0"
"@tsconfig/node10" "^1.0.7"
"@tsconfig/node12" "^1.0.7"
"@tsconfig/node14" "^1.0.0"
@@ -169,23 +169,29 @@ [email protected]:
create-require "^1.1.0"
diff "^4.0.1"
make-error "^1.1.1"
v8-compile-cache-lib "^3.0.0"
yn "3.1.1"
tslib@2.3.1:
version "2.3.1"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.1.tgz#e8a335add5ceae51aa261d32a490158ef042ef01"
integrity sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==
tslib@2.4.0:
version "2.4.0"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3"
integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==
typescript@4.5.2:
version "4.5.2"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.5.2.tgz#8ac1fba9f52256fdb06fb89e4122fa6a346c2998"
integrity sha512-5BlMof9H1yGt0P8/WF+wPNw6GfctgGjXp5hkblpyT+8rkASSmkUKMXrxR0Xg8ThVCi/JnHQiKXeBaEwCeQwMFw==
typescript@4.6.4:
version "4.6.4"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.6.4.tgz#caa78bbc3a59e6a5c510d35703f6a09877ce45e9"
integrity sha512-9ia/jWHIEbo49HfjrLGfKbZSuWo9iTMwXO+Ca3pRsSpbsMbc7/IU8NKdCZVRRBafVPGnoJeFL76ZOAA84I9fEg==
universalify@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717"
integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==
v8-compile-cache-lib@^3.0.0:
version "3.0.1"
resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf"
integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==
yallist@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"
-5
View File
@@ -1,5 +0,0 @@
declare module 'pnp-webpack-plugin' {
function apply(resolver: any /* EnhancedResolve.Resolver */): void;
function moduleLoader(module: NodeModule): any;
function forkTsCheckerOptions(config: any): any;
}
Generated
+1157 -2100
View File
File diff suppressed because it is too large. Load diff