eas-cli 2.5.1 → 2.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +89 -49
- package/build/branch/queries.js +3 -22
- package/build/build/queries.d.ts +11 -1
- package/build/build/queries.js +39 -1
- package/build/channel/queries.js +5 -8
- package/build/channel/utils.js +22 -22
- package/build/commandUtils/context/LoggedInContextField.d.ts +3 -0
- package/build/commandUtils/context/LoggedInContextField.js +9 -1
- package/build/commandUtils/context/MaybeLoggedInContextField.d.ts +3 -0
- package/build/commandUtils/context/MaybeLoggedInContextField.js +9 -1
- package/build/commandUtils/context/contextUtils/createGraphqlClient.d.ts +2 -2
- package/build/commandUtils/gating/FeatureGateEnvOverrides.d.ts +7 -0
- package/build/commandUtils/gating/FeatureGateEnvOverrides.js +35 -0
- package/build/commandUtils/gating/FeatureGateKey.d.ts +4 -0
- package/build/commandUtils/gating/FeatureGateKey.js +11 -0
- package/build/commandUtils/gating/FeatureGateTestOverrides.d.ts +5 -0
- package/build/commandUtils/gating/FeatureGateTestOverrides.js +17 -0
- package/build/commandUtils/gating/FeatureGating.d.ts +16 -0
- package/build/commandUtils/gating/FeatureGating.js +55 -0
- package/build/commandUtils/pagination.d.ts +4 -3
- package/build/commands/branch/list.d.ts +1 -1
- package/build/commands/branch/view.d.ts +1 -1
- package/build/commands/build/configure.d.ts +1 -1
- package/build/commands/build/index.d.ts +2 -2
- package/build/commands/build/list.d.ts +4 -4
- package/build/commands/build/list.js +2 -15
- package/build/commands/build/run.d.ts +21 -0
- package/build/commands/build/run.js +149 -0
- package/build/commands/build/version/set.d.ts +1 -1
- package/build/commands/build/version/sync.d.ts +1 -1
- package/build/commands/channel/list.d.ts +1 -1
- package/build/commands/channel/view.d.ts +1 -1
- package/build/commands/config.d.ts +1 -1
- package/build/commands/credentials.d.ts +1 -1
- package/build/commands/device/list.d.ts +1 -1
- package/build/commands/metadata/lint.d.ts +12 -0
- package/build/commands/metadata/lint.js +72 -0
- package/build/commands/metadata/pull.js +20 -9
- package/build/commands/metadata/push.js +20 -9
- package/build/commands/secret/create.d.ts +1 -1
- package/build/commands/secret/list.js +12 -17
- package/build/commands/submit.d.ts +1 -1
- package/build/commands/update/configure.js +2 -0
- package/build/commands/update/list.d.ts +1 -1
- package/build/commands/webhook/create.d.ts +1 -1
- package/build/commands/webhook/list.d.ts +1 -1
- package/build/commands/webhook/update.d.ts +1 -1
- package/build/devices/actions/create/inputMethod.js +2 -15
- package/build/devices/utils/formatDevice.d.ts +2 -0
- package/build/devices/utils/formatDevice.js +32 -7
- package/build/env.d.ts +8 -0
- package/build/env.js +8 -0
- package/build/graphql/generated.d.ts +74 -6
- package/build/graphql/generated.js +10 -2
- package/build/graphql/mutations/KeystoreGenerationUrlMutation.js +1 -1
- package/build/graphql/queries/UserQuery.js +2 -2
- package/build/graphql/types/Build.js +1 -0
- package/build/metadata/apple/rules/index.d.ts +1 -0
- package/build/metadata/apple/rules/index.js +6 -0
- package/build/metadata/apple/rules/infoKeywordLength.d.ts +6 -0
- package/build/metadata/apple/rules/infoKeywordLength.js +35 -0
- package/build/metadata/apple/rules/infoRestrictedWords.d.ts +6 -0
- package/build/metadata/apple/rules/infoRestrictedWords.js +57 -0
- package/build/metadata/apple/tasks/index.d.ts +1 -2
- package/build/metadata/apple/tasks/index.js +1 -1
- package/build/metadata/auth.d.ts +21 -0
- package/build/metadata/auth.js +33 -0
- package/build/metadata/config/issue.d.ts +21 -0
- package/build/metadata/config/issue.js +9 -0
- package/build/metadata/config/resolve.d.ts +27 -0
- package/build/metadata/{config.js → config/resolve.js} +24 -25
- package/build/metadata/config/schema.d.ts +7 -0
- package/build/metadata/config/schema.js +2 -0
- package/build/metadata/config/validate.d.ts +3 -0
- package/build/metadata/config/validate.js +47 -0
- package/build/metadata/download.d.ts +11 -2
- package/build/metadata/download.js +14 -9
- package/build/metadata/errors.d.ts +3 -3
- package/build/metadata/errors.js +3 -1
- package/build/metadata/upload.d.ts +11 -2
- package/build/metadata/upload.js +16 -11
- package/build/metadata/utils/ajv.d.ts +10 -0
- package/build/metadata/utils/ajv.js +30 -0
- package/build/metadata/utils/telemetry.js +6 -6
- package/build/run/android/run.d.ts +1 -0
- package/build/run/android/run.js +9 -0
- package/build/run/ios/run.d.ts +1 -0
- package/build/run/ios/run.js +31 -0
- package/build/run/ios/simctl.d.ts +2 -0
- package/build/run/ios/simctl.js +8 -0
- package/build/run/ios/simulator.d.ts +21 -0
- package/build/run/ios/simulator.js +161 -0
- package/build/run/ios/systemRequirements.d.ts +1 -0
- package/build/run/ios/systemRequirements.js +82 -0
- package/build/run/ios/xcode.d.ts +4 -0
- package/build/run/ios/xcode.js +41 -0
- package/build/run/ios/xcrun.d.ts +4 -0
- package/build/run/ios/xcrun.js +68 -0
- package/build/run/run.d.ts +8 -0
- package/build/run/run.js +15 -0
- package/build/submit/utils/summary.d.ts +1 -1
- package/build/update/queries.js +30 -39
- package/build/update/utils.d.ts +8 -1
- package/build/update/utils.js +35 -1
- package/build/utils/buildDistribution.d.ts +3 -0
- package/build/utils/buildDistribution.js +20 -0
- package/build/utils/download.d.ts +2 -0
- package/build/utils/download.js +114 -0
- package/build/utils/expodash/filter.d.ts +2 -0
- package/build/utils/expodash/filter.js +8 -0
- package/build/utils/formatFields.d.ts +3 -2
- package/oclif.manifest.json +1 -1
- package/package.json +32 -30
- package/schema/metadata-0.json +1 -1
- package/build/metadata/config.d.ts +0 -41
- package/build/metadata/context.d.ts +0 -50
- package/build/metadata/context.js +0 -47
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.createAppleWriter = exports.createAppleReader = exports.
|
|
3
|
+
exports.createAppleWriter = exports.createAppleReader = exports.loadConfigAsync = exports.getStaticConfigFilePath = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
|
-
const ajv_1 = tslib_1.__importDefault(require("ajv"));
|
|
6
5
|
const assert_1 = tslib_1.__importDefault(require("assert"));
|
|
7
6
|
const fs_extra_1 = tslib_1.__importDefault(require("fs-extra"));
|
|
8
7
|
const path_1 = tslib_1.__importDefault(require("path"));
|
|
9
|
-
const reader_1 = require("
|
|
10
|
-
const writer_1 = require("
|
|
11
|
-
const errors_1 = require("
|
|
8
|
+
const reader_1 = require("../apple/config/reader");
|
|
9
|
+
const writer_1 = require("../apple/config/writer");
|
|
10
|
+
const errors_1 = require("../errors");
|
|
11
|
+
const validate_1 = require("./validate");
|
|
12
12
|
/**
|
|
13
13
|
* Resolve the dynamic config from the user.
|
|
14
14
|
* It supports methods, async methods, or objects (json).
|
|
@@ -19,12 +19,23 @@ async function resolveDynamicConfigAsync(configFile) {
|
|
|
19
19
|
? await userConfigOrFunction()
|
|
20
20
|
: userConfigOrFunction;
|
|
21
21
|
}
|
|
22
|
+
/**
|
|
23
|
+
* Resolve the prefered store config file name from the submit profile.
|
|
24
|
+
* This is relative to the project directory, and uses `store.config.json` by default.
|
|
25
|
+
*/
|
|
26
|
+
function resolveConfigFilePath(profile) {
|
|
27
|
+
var _a;
|
|
28
|
+
if ('metadataPath' in profile) {
|
|
29
|
+
return (_a = profile.metadataPath) !== null && _a !== void 0 ? _a : 'store.config.json';
|
|
30
|
+
}
|
|
31
|
+
return 'store.config.json';
|
|
32
|
+
}
|
|
22
33
|
/**
|
|
23
34
|
* Get the static configuration file path, based on the metadata context.
|
|
24
35
|
* This uses any custom name provided, but swaps out the extension for `.json`.
|
|
25
36
|
*/
|
|
26
|
-
function getStaticConfigFilePath({ projectDir,
|
|
27
|
-
const configFile = path_1.default.join(projectDir,
|
|
37
|
+
function getStaticConfigFilePath({ projectDir, profile, }) {
|
|
38
|
+
const configFile = path_1.default.join(projectDir, resolveConfigFilePath(profile));
|
|
28
39
|
const configExtension = path_1.default.extname(configFile);
|
|
29
40
|
return path_1.default.join(projectDir, `${path_1.default.basename(configFile, configExtension)}.json`);
|
|
30
41
|
}
|
|
@@ -35,37 +46,25 @@ exports.getStaticConfigFilePath = getStaticConfigFilePath;
|
|
|
35
46
|
* It throws MetadataValidationErrors when the file doesn't exist, or contains errors.
|
|
36
47
|
* The user is prompted to try anyway when errors are found.
|
|
37
48
|
*/
|
|
38
|
-
async function loadConfigAsync({ projectDir,
|
|
39
|
-
const configFile = path_1.default.join(projectDir,
|
|
49
|
+
async function loadConfigAsync({ projectDir, profile, skipValidation = false, }) {
|
|
50
|
+
const configFile = path_1.default.join(projectDir, resolveConfigFilePath(profile));
|
|
40
51
|
if (!(await fs_extra_1.default.pathExists(configFile))) {
|
|
41
52
|
throw new errors_1.MetadataValidationError(`Metadata store config file not found: "${configFile}"`);
|
|
42
53
|
}
|
|
43
54
|
const configData = await resolveDynamicConfigAsync(configFile);
|
|
44
55
|
if (!skipValidation) {
|
|
45
|
-
const
|
|
46
|
-
if (
|
|
47
|
-
throw new errors_1.MetadataValidationError(`Metadata store config errors found`,
|
|
56
|
+
const issues = (0, validate_1.validateConfig)(configData);
|
|
57
|
+
if (issues.length > 0) {
|
|
58
|
+
throw new errors_1.MetadataValidationError(`Metadata store config errors found`, issues);
|
|
48
59
|
}
|
|
49
60
|
}
|
|
50
61
|
return configData;
|
|
51
62
|
}
|
|
52
63
|
exports.loadConfigAsync = loadConfigAsync;
|
|
53
|
-
/**
|
|
54
|
-
* Run the JSON Schema validation to normalize defaults and flag early config errors.
|
|
55
|
-
* This includes validating the known store limitations for every configurable property.
|
|
56
|
-
*/
|
|
57
|
-
function validateConfig(config) {
|
|
58
|
-
const validator = new ajv_1.default({ allErrors: true, useDefaults: true })
|
|
59
|
-
.addMetaSchema(require('ajv/lib/refs/json-schema-draft-06.json'))
|
|
60
|
-
.compile(require('../../schema/metadata-0.json'));
|
|
61
|
-
const valid = validator(config);
|
|
62
|
-
return { valid, errors: validator.errors || [] };
|
|
63
|
-
}
|
|
64
|
-
exports.validateConfig = validateConfig;
|
|
65
64
|
/** Create a versioned deserializer to fetch App Store data from the store configuration. */
|
|
66
65
|
function createAppleReader(config) {
|
|
67
66
|
(0, assert_1.default)(config.configVersion === 0, 'Unsupported store configuration version');
|
|
68
|
-
(0, assert_1.default)(config.apple, 'No apple configuration found');
|
|
67
|
+
(0, assert_1.default)(config.apple !== undefined, 'No apple configuration found');
|
|
69
68
|
return new reader_1.AppleConfigReader(config.apple);
|
|
70
69
|
}
|
|
71
70
|
exports.createAppleReader = createAppleReader;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.validateConfig = void 0;
|
|
4
|
+
const rules_1 = require("../apple/rules");
|
|
5
|
+
const ajv_1 = require("../utils/ajv");
|
|
6
|
+
const issue_1 = require("./issue");
|
|
7
|
+
const metadataSchema = require('../../../schema/metadata-0.json');
|
|
8
|
+
/** Validate the user-provided validation for issues */
|
|
9
|
+
function validateConfig(config) {
|
|
10
|
+
var _a;
|
|
11
|
+
const validator = (0, ajv_1.createValidator)().compile(metadataSchema);
|
|
12
|
+
validator(config);
|
|
13
|
+
const issues = (0, ajv_1.getReadableErrors)((_a = validator.errors) !== null && _a !== void 0 ? _a : []).map(error => {
|
|
14
|
+
var _a, _b;
|
|
15
|
+
const path = error.path === '$' ? [] : error.path.substring(2).split('.');
|
|
16
|
+
const id = (_b = (_a = error.original) === null || _a === void 0 ? void 0 : _a.keyword) !== null && _b !== void 0 ? _b : 'unknown';
|
|
17
|
+
return {
|
|
18
|
+
id: `json-schema.${id}`,
|
|
19
|
+
path,
|
|
20
|
+
severity: issue_1.IssueSeverity.error,
|
|
21
|
+
message: error.message,
|
|
22
|
+
};
|
|
23
|
+
});
|
|
24
|
+
try {
|
|
25
|
+
issues.push(...validateRules(rules_1.appleRules, config));
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
// When the rules are failing, the json schema validation errors explain the issue
|
|
29
|
+
// TODO(cedric): optionally add debugging logging for these types of errors
|
|
30
|
+
}
|
|
31
|
+
return issues;
|
|
32
|
+
}
|
|
33
|
+
exports.validateConfig = validateConfig;
|
|
34
|
+
/** Validate the set of rules against the parsed metadata config */
|
|
35
|
+
function validateRules(rules, config) {
|
|
36
|
+
const issues = [];
|
|
37
|
+
for (const rule of rules) {
|
|
38
|
+
const result = rule.validate(config);
|
|
39
|
+
if (Array.isArray(result)) {
|
|
40
|
+
issues.push(...result);
|
|
41
|
+
}
|
|
42
|
+
else if (result) {
|
|
43
|
+
issues.push(result);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return issues;
|
|
47
|
+
}
|
|
@@ -1,6 +1,15 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ExpoConfig } from '@expo/config-types';
|
|
2
|
+
import { SubmitProfile } from '@expo/eas-json';
|
|
3
|
+
import { Analytics } from '../analytics/AnalyticsManager';
|
|
4
|
+
import { CredentialsContext } from '../credentials/context';
|
|
2
5
|
/**
|
|
3
6
|
* Generate a local store configuration from the stores.
|
|
4
7
|
* Note, only App Store is supported at this time.
|
|
5
8
|
*/
|
|
6
|
-
export declare function downloadMetadataAsync(
|
|
9
|
+
export declare function downloadMetadataAsync({ projectDir, profile, exp, analytics, credentialsCtx, }: {
|
|
10
|
+
projectDir: string;
|
|
11
|
+
profile: SubmitProfile;
|
|
12
|
+
exp: ExpoConfig;
|
|
13
|
+
analytics: Analytics;
|
|
14
|
+
credentialsCtx: CredentialsContext;
|
|
15
|
+
}): Promise<string>;
|
|
@@ -8,19 +8,19 @@ const AnalyticsManager_1 = require("../analytics/AnalyticsManager");
|
|
|
8
8
|
const log_1 = tslib_1.__importDefault(require("../log"));
|
|
9
9
|
const prompts_1 = require("../prompts");
|
|
10
10
|
const tasks_1 = require("./apple/tasks");
|
|
11
|
-
const
|
|
12
|
-
const
|
|
11
|
+
const auth_1 = require("./auth");
|
|
12
|
+
const resolve_1 = require("./config/resolve");
|
|
13
13
|
const errors_1 = require("./errors");
|
|
14
14
|
const telemetry_1 = require("./utils/telemetry");
|
|
15
15
|
/**
|
|
16
16
|
* Generate a local store configuration from the stores.
|
|
17
17
|
* Note, only App Store is supported at this time.
|
|
18
18
|
*/
|
|
19
|
-
async function downloadMetadataAsync(
|
|
20
|
-
const filePath = (0,
|
|
19
|
+
async function downloadMetadataAsync({ projectDir, profile, exp, analytics, credentialsCtx, }) {
|
|
20
|
+
const filePath = (0, resolve_1.getStaticConfigFilePath)({ projectDir, profile });
|
|
21
21
|
const fileExists = await fs_extra_1.default.pathExists(filePath);
|
|
22
22
|
if (fileExists) {
|
|
23
|
-
const filePathRelative = path_1.default.relative(
|
|
23
|
+
const filePathRelative = path_1.default.relative(projectDir, filePath);
|
|
24
24
|
const overwrite = await (0, prompts_1.confirmAsync)({
|
|
25
25
|
message: `Do you want to overwrite the existing "${filePathRelative}"?`,
|
|
26
26
|
});
|
|
@@ -28,13 +28,18 @@ async function downloadMetadataAsync(metadataCtx) {
|
|
|
28
28
|
throw new errors_1.MetadataValidationError(`Store config already exists at "${filePath}"`);
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
|
-
const { app, auth } = await (0,
|
|
32
|
-
|
|
31
|
+
const { app, auth } = await (0, auth_1.getAppStoreAuthAsync)({
|
|
32
|
+
exp,
|
|
33
|
+
credentialsCtx,
|
|
34
|
+
projectDir,
|
|
35
|
+
profile,
|
|
36
|
+
});
|
|
37
|
+
const { unsubscribeTelemetry, executionId } = (0, telemetry_1.subscribeTelemetry)(analytics, AnalyticsManager_1.MetadataEvent.APPLE_METADATA_DOWNLOAD, { app, auth });
|
|
33
38
|
log_1.default.addNewLineIfNone();
|
|
34
39
|
log_1.default.log('Downloading App Store config...');
|
|
35
40
|
const errors = [];
|
|
36
|
-
const config = (0,
|
|
37
|
-
const tasks = (0, tasks_1.createAppleTasks)(
|
|
41
|
+
const config = (0, resolve_1.createAppleWriter)();
|
|
42
|
+
const tasks = (0, tasks_1.createAppleTasks)();
|
|
38
43
|
const taskCtx = { app };
|
|
39
44
|
for (const task of tasks) {
|
|
40
45
|
try {
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { Issue } from './config/issue';
|
|
2
2
|
/**
|
|
3
3
|
* Before syncing data to the ASC API, we need to validate the metadata config.
|
|
4
4
|
* This error represents unrecoverable issues before syncing that data,
|
|
5
5
|
* and should contain useful information for the user to solve before trying again.
|
|
6
6
|
*/
|
|
7
7
|
export declare class MetadataValidationError extends Error {
|
|
8
|
-
readonly errors:
|
|
9
|
-
constructor(message?: string, errors?:
|
|
8
|
+
readonly errors: Issue[];
|
|
9
|
+
constructor(message?: string, errors?: Issue[]);
|
|
10
10
|
}
|
|
11
11
|
/**
|
|
12
12
|
* If a single entity failed to update, we don't block the other entities from uploading.
|
package/build/metadata/errors.js
CHANGED
|
@@ -54,7 +54,9 @@ function logMetadataValidationError(error) {
|
|
|
54
54
|
log_1.default.error(chalk_1.default.bold(error.message));
|
|
55
55
|
if (((_a = error.errors) === null || _a === void 0 ? void 0 : _a.length) > 0) {
|
|
56
56
|
// TODO(cedric): group errors by property to make multiple errors for same property more readable
|
|
57
|
-
|
|
57
|
+
for (const err of error.errors) {
|
|
58
|
+
log_1.default.log(` - ${chalk_1.default.bold(`$.${err.path.join('.')}`)} ${err.message}`);
|
|
59
|
+
}
|
|
58
60
|
}
|
|
59
61
|
}
|
|
60
62
|
exports.logMetadataValidationError = logMetadataValidationError;
|
|
@@ -1,8 +1,17 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ExpoConfig } from '@expo/config-types';
|
|
2
|
+
import { SubmitProfile } from '@expo/eas-json';
|
|
3
|
+
import { Analytics } from '../analytics/AnalyticsManager';
|
|
4
|
+
import { CredentialsContext } from '../credentials/context';
|
|
2
5
|
/**
|
|
3
6
|
* Sync a local store configuration with the stores.
|
|
4
7
|
* Note, only App Store is supported at this time.
|
|
5
8
|
*/
|
|
6
|
-
export declare function uploadMetadataAsync(
|
|
9
|
+
export declare function uploadMetadataAsync({ projectDir, profile, exp, analytics, credentialsCtx, }: {
|
|
10
|
+
projectDir: string;
|
|
11
|
+
profile: SubmitProfile;
|
|
12
|
+
exp: ExpoConfig;
|
|
13
|
+
analytics: Analytics;
|
|
14
|
+
credentialsCtx: CredentialsContext;
|
|
15
|
+
}): Promise<{
|
|
7
16
|
appleLink: string;
|
|
8
17
|
}>;
|
package/build/metadata/upload.js
CHANGED
|
@@ -6,24 +6,29 @@ const AnalyticsManager_1 = require("../analytics/AnalyticsManager");
|
|
|
6
6
|
const log_1 = tslib_1.__importDefault(require("../log"));
|
|
7
7
|
const prompts_1 = require("../prompts");
|
|
8
8
|
const tasks_1 = require("./apple/tasks");
|
|
9
|
-
const
|
|
10
|
-
const
|
|
9
|
+
const auth_1 = require("./auth");
|
|
10
|
+
const resolve_1 = require("./config/resolve");
|
|
11
11
|
const errors_1 = require("./errors");
|
|
12
12
|
const telemetry_1 = require("./utils/telemetry");
|
|
13
13
|
/**
|
|
14
14
|
* Sync a local store configuration with the stores.
|
|
15
15
|
* Note, only App Store is supported at this time.
|
|
16
16
|
*/
|
|
17
|
-
async function uploadMetadataAsync(
|
|
17
|
+
async function uploadMetadataAsync({ projectDir, profile, exp, analytics, credentialsCtx, }) {
|
|
18
18
|
var _a;
|
|
19
|
-
const storeConfig = await loadConfigWithValidationPromptAsync(
|
|
20
|
-
const { app, auth } = await (0,
|
|
21
|
-
|
|
19
|
+
const storeConfig = await loadConfigWithValidationPromptAsync(projectDir, profile);
|
|
20
|
+
const { app, auth } = await (0, auth_1.getAppStoreAuthAsync)({
|
|
21
|
+
exp,
|
|
22
|
+
credentialsCtx,
|
|
23
|
+
projectDir,
|
|
24
|
+
profile,
|
|
25
|
+
});
|
|
26
|
+
const { unsubscribeTelemetry, executionId } = (0, telemetry_1.subscribeTelemetry)(analytics, AnalyticsManager_1.MetadataEvent.APPLE_METADATA_UPLOAD, { app, auth });
|
|
22
27
|
log_1.default.addNewLineIfNone();
|
|
23
28
|
log_1.default.log('Uploading App Store configuration...');
|
|
24
29
|
const errors = [];
|
|
25
|
-
const config = (0,
|
|
26
|
-
const tasks = (0, tasks_1.createAppleTasks)(
|
|
30
|
+
const config = (0, resolve_1.createAppleReader)(storeConfig);
|
|
31
|
+
const tasks = (0, tasks_1.createAppleTasks)({
|
|
27
32
|
// We need to resolve a different version as soon as possible.
|
|
28
33
|
// This version is the parent model of all changes we are going to push.
|
|
29
34
|
version: (_a = config.getVersion()) === null || _a === void 0 ? void 0 : _a.versionString,
|
|
@@ -52,9 +57,9 @@ async function uploadMetadataAsync(metadataCtx) {
|
|
|
52
57
|
return { appleLink: `https://appstoreconnect.apple.com/apps/${app.id}/appstore` };
|
|
53
58
|
}
|
|
54
59
|
exports.uploadMetadataAsync = uploadMetadataAsync;
|
|
55
|
-
async function loadConfigWithValidationPromptAsync(
|
|
60
|
+
async function loadConfigWithValidationPromptAsync(projectDir, profile) {
|
|
56
61
|
try {
|
|
57
|
-
return await (0,
|
|
62
|
+
return await (0, resolve_1.loadConfigAsync)({ projectDir, profile });
|
|
58
63
|
}
|
|
59
64
|
catch (error) {
|
|
60
65
|
if (error instanceof errors_1.MetadataValidationError) {
|
|
@@ -62,7 +67,7 @@ async function loadConfigWithValidationPromptAsync(metadataCtx) {
|
|
|
62
67
|
log_1.default.newLine();
|
|
63
68
|
log_1.default.warn('Without further updates, the current store configuration can fail to be synchronized with the App Store or pass App Store review.');
|
|
64
69
|
if (await (0, prompts_1.confirmAsync)({ message: 'Do you still want to push the store configuration?' })) {
|
|
65
|
-
return await (0,
|
|
70
|
+
return await (0, resolve_1.loadConfigAsync)({ projectDir, profile, skipValidation: true });
|
|
66
71
|
}
|
|
67
72
|
}
|
|
68
73
|
throw error;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { HumanError } from '@segment/ajv-human-errors';
|
|
2
|
+
import Ajv, { ErrorObject } from 'ajv';
|
|
3
|
+
/**
|
|
4
|
+
* Create a new AJV validator using the JSON Schema 06 draft.
|
|
5
|
+
* It also adds the additional formats from the `ajv-formats` package.
|
|
6
|
+
*
|
|
7
|
+
* @see https://github.com/ajv-validator/ajv-formats
|
|
8
|
+
*/
|
|
9
|
+
export declare function createValidator(): Ajv;
|
|
10
|
+
export declare function getReadableErrors(errors?: ErrorObject[]): HumanError[];
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getReadableErrors = exports.createValidator = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const ajv_human_errors_1 = require("@segment/ajv-human-errors");
|
|
6
|
+
const ajv_1 = tslib_1.__importDefault(require("ajv"));
|
|
7
|
+
const ajv_formats_1 = tslib_1.__importDefault(require("ajv-formats"));
|
|
8
|
+
const jsonSchema = require('ajv/lib/refs/json-schema-draft-06.json');
|
|
9
|
+
/**
|
|
10
|
+
* Create a new AJV validator using the JSON Schema 06 draft.
|
|
11
|
+
* It also adds the additional formats from the `ajv-formats` package.
|
|
12
|
+
*
|
|
13
|
+
* @see https://github.com/ajv-validator/ajv-formats
|
|
14
|
+
*/
|
|
15
|
+
function createValidator() {
|
|
16
|
+
const validator = new ajv_1.default({
|
|
17
|
+
strict: false,
|
|
18
|
+
verbose: true,
|
|
19
|
+
allErrors: true, // Required for `ajv-human-errors`
|
|
20
|
+
});
|
|
21
|
+
return (0, ajv_formats_1.default)(validator).addMetaSchema(jsonSchema);
|
|
22
|
+
}
|
|
23
|
+
exports.createValidator = createValidator;
|
|
24
|
+
function getReadableErrors(errors = []) {
|
|
25
|
+
if (errors.length === 0) {
|
|
26
|
+
return [];
|
|
27
|
+
}
|
|
28
|
+
return new ajv_human_errors_1.AggregateAjvError(errors).toJSON();
|
|
29
|
+
}
|
|
30
|
+
exports.getReadableErrors = getReadableErrors;
|
|
@@ -24,18 +24,18 @@ function subscribeTelemetry(analytics, event, options) {
|
|
|
24
24
|
});
|
|
25
25
|
return response;
|
|
26
26
|
}, (error) => {
|
|
27
|
-
var _a, _b, _c;
|
|
27
|
+
var _a, _b, _c, _d, _e;
|
|
28
28
|
analytics.logEvent(event, {
|
|
29
29
|
executionId,
|
|
30
30
|
type: 'response',
|
|
31
31
|
phase: 'rejected',
|
|
32
32
|
method: error.request.method.toUpperCase(),
|
|
33
|
-
url: scrubber(error.config.url),
|
|
33
|
+
url: scrubber((_a = error.config) === null || _a === void 0 ? void 0 : _a.url),
|
|
34
34
|
error: scrubber(error.message),
|
|
35
|
-
status: String((
|
|
36
|
-
statusText: scrubber((
|
|
37
|
-
input: scrubber(error.config.data),
|
|
38
|
-
output: scrubber((
|
|
35
|
+
status: String((_b = error.response) === null || _b === void 0 ? void 0 : _b.status),
|
|
36
|
+
statusText: scrubber((_c = error.response) === null || _c === void 0 ? void 0 : _c.statusText),
|
|
37
|
+
input: scrubber((_d = error.config) === null || _d === void 0 ? void 0 : _d.data),
|
|
38
|
+
output: scrubber((_e = error.response) === null || _e === void 0 ? void 0 : _e.data),
|
|
39
39
|
});
|
|
40
40
|
throw error;
|
|
41
41
|
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function runAppOnAndroidEmulatorAsync(_appPath: string): Promise<void>;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.runAppOnAndroidEmulatorAsync = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const log_1 = tslib_1.__importDefault(require("../../log"));
|
|
6
|
+
async function runAppOnAndroidEmulatorAsync(_appPath) {
|
|
7
|
+
log_1.default.error('Not implemented!');
|
|
8
|
+
}
|
|
9
|
+
exports.runAppOnAndroidEmulatorAsync = runAppOnAndroidEmulatorAsync;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function runAppOnIosSimulatorAsync(appPath: string): Promise<void>;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.runAppOnIosSimulatorAsync = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const spawn_async_1 = tslib_1.__importDefault(require("@expo/spawn-async"));
|
|
6
|
+
const path_1 = tslib_1.__importDefault(require("path"));
|
|
7
|
+
const simulator = tslib_1.__importStar(require("./simulator"));
|
|
8
|
+
const systemRequirements_1 = require("./systemRequirements");
|
|
9
|
+
async function runAppOnIosSimulatorAsync(appPath) {
|
|
10
|
+
await (0, systemRequirements_1.validateSystemRequirementsAsync)();
|
|
11
|
+
const selectedSimulator = await simulator.selectSimulatorAsync();
|
|
12
|
+
await simulator.ensureSimulatorBootedAsync(selectedSimulator);
|
|
13
|
+
await simulator.ensureSimulatorAppOpenedAsync(selectedSimulator.udid);
|
|
14
|
+
const bundleIdentifier = await getAppBundleIdentifierAsync(appPath);
|
|
15
|
+
await simulator.installAppAsync(selectedSimulator.udid, appPath);
|
|
16
|
+
await simulator.launchAppAsync(selectedSimulator.udid, bundleIdentifier);
|
|
17
|
+
}
|
|
18
|
+
exports.runAppOnIosSimulatorAsync = runAppOnIosSimulatorAsync;
|
|
19
|
+
async function getAppBundleIdentifierAsync(appPath) {
|
|
20
|
+
const { stdout, stderr } = await (0, spawn_async_1.default)('xcrun', [
|
|
21
|
+
'plutil',
|
|
22
|
+
'-extract',
|
|
23
|
+
'CFBundleIdentifier',
|
|
24
|
+
'raw',
|
|
25
|
+
path_1.default.join(appPath, 'Info.plist'),
|
|
26
|
+
]);
|
|
27
|
+
if (!stdout) {
|
|
28
|
+
throw new Error(`Could not read app bundle identifier from ${path_1.default.join(appPath, 'Info.plist')}: ${stderr}`);
|
|
29
|
+
}
|
|
30
|
+
return stdout.trim();
|
|
31
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.simctlAsync = void 0;
|
|
4
|
+
const xcrun_1 = require("./xcrun");
|
|
5
|
+
async function simctlAsync(args, options) {
|
|
6
|
+
return (0, xcrun_1.xcrunAsync)(['simctl', ...args], options);
|
|
7
|
+
}
|
|
8
|
+
exports.simctlAsync = simctlAsync;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
interface IosSimulator {
|
|
2
|
+
runtime: string;
|
|
3
|
+
osVersion: string;
|
|
4
|
+
windowName: string;
|
|
5
|
+
osType: 'iOS';
|
|
6
|
+
state: 'Booted' | 'Shutdown';
|
|
7
|
+
isAvailable: boolean;
|
|
8
|
+
name: string;
|
|
9
|
+
udid: string;
|
|
10
|
+
lastBootedAt?: Date;
|
|
11
|
+
}
|
|
12
|
+
export declare function selectSimulatorAsync(): Promise<IosSimulator>;
|
|
13
|
+
export declare function getFirstBootedIosSimulatorAsync(): Promise<IosSimulator | undefined>;
|
|
14
|
+
export declare function getAvaliableIosSimulatorsListAsync(query?: string): Promise<IosSimulator[]>;
|
|
15
|
+
export declare function ensureSimulatorBootedAsync(simulator: IosSimulator): Promise<void>;
|
|
16
|
+
export declare function openSimulatorAppAsync(simulatorUdid: string): Promise<void>;
|
|
17
|
+
export declare function launchAppAsync(simulatorUdid: string, bundleIdentifier: string): Promise<void>;
|
|
18
|
+
export declare function ensureSimulatorAppOpenedAsync(simulatorUuid: string): Promise<void>;
|
|
19
|
+
export declare function installAppAsync(deviceId: string, filePath: string): Promise<void>;
|
|
20
|
+
export declare function getSimulatorAppIdAsync(): Promise<string | undefined>;
|
|
21
|
+
export {};
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getSimulatorAppIdAsync = exports.installAppAsync = exports.ensureSimulatorAppOpenedAsync = exports.launchAppAsync = exports.openSimulatorAppAsync = exports.ensureSimulatorBootedAsync = exports.getAvaliableIosSimulatorsListAsync = exports.getFirstBootedIosSimulatorAsync = exports.selectSimulatorAsync = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const osascript = tslib_1.__importStar(require("@expo/osascript"));
|
|
6
|
+
const spawn_async_1 = tslib_1.__importDefault(require("@expo/spawn-async"));
|
|
7
|
+
const log_1 = tslib_1.__importDefault(require("../../log"));
|
|
8
|
+
const prompts_1 = require("../../prompts");
|
|
9
|
+
const promise_1 = require("../../utils/promise");
|
|
10
|
+
const simctl_1 = require("./simctl");
|
|
11
|
+
async function selectSimulatorAsync() {
|
|
12
|
+
const bootedSimulator = await getFirstBootedIosSimulatorAsync();
|
|
13
|
+
if (bootedSimulator) {
|
|
14
|
+
return bootedSimulator;
|
|
15
|
+
}
|
|
16
|
+
const simulators = await getAvaliableIosSimulatorsListAsync();
|
|
17
|
+
log_1.default.newLine();
|
|
18
|
+
const { selectedSimulator } = await (0, prompts_1.promptAsync)({
|
|
19
|
+
type: 'select',
|
|
20
|
+
message: `Select a simulator to run your app on`,
|
|
21
|
+
name: 'selectedSimulator',
|
|
22
|
+
choices: simulators.map(simulator => ({
|
|
23
|
+
title: `ios ${simulator.osVersion} ${simulator.name}`,
|
|
24
|
+
value: simulator,
|
|
25
|
+
})),
|
|
26
|
+
});
|
|
27
|
+
return selectedSimulator;
|
|
28
|
+
}
|
|
29
|
+
exports.selectSimulatorAsync = selectSimulatorAsync;
|
|
30
|
+
async function getFirstBootedIosSimulatorAsync() {
|
|
31
|
+
const bootedSimulators = await getAvaliableIosSimulatorsListAsync('booted');
|
|
32
|
+
if (bootedSimulators.length > 0) {
|
|
33
|
+
return bootedSimulators[0];
|
|
34
|
+
}
|
|
35
|
+
return undefined;
|
|
36
|
+
}
|
|
37
|
+
exports.getFirstBootedIosSimulatorAsync = getFirstBootedIosSimulatorAsync;
|
|
38
|
+
async function getAvaliableIosSimulatorsListAsync(query) {
|
|
39
|
+
const { stdout } = query
|
|
40
|
+
? await (0, simctl_1.simctlAsync)(['list', 'devices', '--json', query])
|
|
41
|
+
: await (0, simctl_1.simctlAsync)(['list', 'devices', '--json']);
|
|
42
|
+
const info = parseSimControlJsonResults(stdout);
|
|
43
|
+
const iosSimulators = [];
|
|
44
|
+
for (const runtime of Object.keys(info.devices)) {
|
|
45
|
+
// Given a string like 'com.apple.CoreSimulator.SimRuntime.tvOS-13-4'
|
|
46
|
+
const runtimeSuffix = runtime.split('com.apple.CoreSimulator.SimRuntime.').pop();
|
|
47
|
+
if (!runtimeSuffix) {
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
// Create an array [tvOS, 13, 4]
|
|
51
|
+
const [osType, ...osVersionComponents] = runtimeSuffix.split('-');
|
|
52
|
+
if (osType === 'iOS') {
|
|
53
|
+
// Join the end components [13, 4] -> '13.4'
|
|
54
|
+
const osVersion = osVersionComponents.join('.');
|
|
55
|
+
const sims = info.devices[runtime];
|
|
56
|
+
for (const device of sims) {
|
|
57
|
+
if (device.isAvailable) {
|
|
58
|
+
iosSimulators.push({
|
|
59
|
+
...device,
|
|
60
|
+
runtime,
|
|
61
|
+
osVersion,
|
|
62
|
+
windowName: `${device.name} (${osVersion})`,
|
|
63
|
+
osType: 'iOS',
|
|
64
|
+
state: device.state,
|
|
65
|
+
lastBootedAt: device.lastBootedAt ? new Date(device.lastBootedAt) : undefined,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return iosSimulators;
|
|
72
|
+
}
|
|
73
|
+
exports.getAvaliableIosSimulatorsListAsync = getAvaliableIosSimulatorsListAsync;
|
|
74
|
+
function parseSimControlJsonResults(input) {
|
|
75
|
+
try {
|
|
76
|
+
return JSON.parse(input);
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
// Nov 15, 2020: Observed this can happen when opening the simulator and the simulator prompts the user to update the xcode command line tools.
|
|
80
|
+
// Unexpected token I in JSON at position 0
|
|
81
|
+
if (error.message.includes('Unexpected token')) {
|
|
82
|
+
log_1.default.error(`Apple's simctl returned malformed JSON:\n${input}`);
|
|
83
|
+
}
|
|
84
|
+
throw error;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
async function ensureSimulatorBootedAsync(simulator) {
|
|
88
|
+
if (simulator.state === 'Booted') {
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
await (0, simctl_1.simctlAsync)(['boot', simulator.udid]);
|
|
92
|
+
}
|
|
93
|
+
exports.ensureSimulatorBootedAsync = ensureSimulatorBootedAsync;
|
|
94
|
+
async function openSimulatorAppAsync(simulatorUdid) {
|
|
95
|
+
const args = ['-a', 'Simulator'];
|
|
96
|
+
if (simulatorUdid) {
|
|
97
|
+
// This has no effect if the app is already running.
|
|
98
|
+
args.push('--args', '-CurrentDeviceUDID', simulatorUdid);
|
|
99
|
+
}
|
|
100
|
+
await (0, spawn_async_1.default)('open', args);
|
|
101
|
+
}
|
|
102
|
+
exports.openSimulatorAppAsync = openSimulatorAppAsync;
|
|
103
|
+
async function launchAppAsync(simulatorUdid, bundleIdentifier) {
|
|
104
|
+
log_1.default.newLine();
|
|
105
|
+
log_1.default.log('Launching your app...');
|
|
106
|
+
await (0, simctl_1.simctlAsync)(['launch', simulatorUdid, bundleIdentifier]);
|
|
107
|
+
log_1.default.succeed('Successfully launched your app!');
|
|
108
|
+
}
|
|
109
|
+
exports.launchAppAsync = launchAppAsync;
|
|
110
|
+
// I think the app can be open while no simulators are booted.
|
|
111
|
+
async function waitForSimulatorAppToStartAsync(maxWaitTimeMs, intervalMs) {
|
|
112
|
+
log_1.default.newLine();
|
|
113
|
+
log_1.default.log('Waiting for Simulator app to start...');
|
|
114
|
+
const startTime = Date.now();
|
|
115
|
+
while (Date.now() - startTime < maxWaitTimeMs) {
|
|
116
|
+
if (await isSimulatorAppRunningAsync()) {
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
await (0, promise_1.sleepAsync)(Math.min(intervalMs, Math.max(maxWaitTimeMs - (Date.now() - startTime), 0)));
|
|
120
|
+
}
|
|
121
|
+
throw new Error('Timed out waiting for the iOS simulator to start.');
|
|
122
|
+
}
|
|
123
|
+
async function isSimulatorAppRunningAsync() {
|
|
124
|
+
try {
|
|
125
|
+
const result = await osascript.execAsync('tell app "System Events" to count processes whose name is "Simulator"');
|
|
126
|
+
if (result.trim() === '0') {
|
|
127
|
+
return false;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
catch (error) {
|
|
131
|
+
if (error.message.includes('Application isn’t running')) {
|
|
132
|
+
return false;
|
|
133
|
+
}
|
|
134
|
+
throw error;
|
|
135
|
+
}
|
|
136
|
+
return true;
|
|
137
|
+
}
|
|
138
|
+
async function ensureSimulatorAppOpenedAsync(simulatorUuid) {
|
|
139
|
+
if (await isSimulatorAppRunningAsync()) {
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
await openSimulatorAppAsync(simulatorUuid);
|
|
143
|
+
await waitForSimulatorAppToStartAsync(60 * 1000, 1000);
|
|
144
|
+
}
|
|
145
|
+
exports.ensureSimulatorAppOpenedAsync = ensureSimulatorAppOpenedAsync;
|
|
146
|
+
async function installAppAsync(deviceId, filePath) {
|
|
147
|
+
log_1.default.newLine();
|
|
148
|
+
log_1.default.log('Installing your app on the simulator...');
|
|
149
|
+
await (0, simctl_1.simctlAsync)(['install', deviceId, filePath]);
|
|
150
|
+
log_1.default.succeed('Successfully installed your app on the simulator!');
|
|
151
|
+
}
|
|
152
|
+
exports.installAppAsync = installAppAsync;
|
|
153
|
+
async function getSimulatorAppIdAsync() {
|
|
154
|
+
try {
|
|
155
|
+
return (await osascript.execAsync('id of app "Simulator"')).trim();
|
|
156
|
+
}
|
|
157
|
+
catch {
|
|
158
|
+
return undefined;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
exports.getSimulatorAppIdAsync = getSimulatorAppIdAsync;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function validateSystemRequirementsAsync(): Promise<void>;
|