eoas 1.0.2 → 1.0.3
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/dist/commands/generate-certs.d.ts +8 -0
- package/dist/commands/generate-certs.js +90 -0
- package/dist/commands/init.d.ts +8 -0
- package/dist/commands/init.js +113 -0
- package/dist/commands/publish.d.ts +18 -0
- package/dist/commands/publish.js +249 -0
- package/dist/lib/assets.d.ts +19 -0
- package/dist/lib/assets.js +90 -0
- package/dist/lib/auth.d.ts +6 -0
- package/dist/lib/auth.js +57 -0
- package/dist/lib/expoConfig.d.ts +23 -0
- package/dist/lib/expoConfig.js +198 -0
- package/dist/lib/log.d.ts +40 -0
- package/dist/lib/log.js +101 -0
- package/dist/lib/ora.d.ts +9 -0
- package/dist/lib/ora.js +103 -0
- package/dist/lib/package.d.ts +1 -0
- package/dist/lib/package.js +9 -0
- package/dist/lib/prompts.d.ts +13 -0
- package/dist/lib/prompts.js +68 -0
- package/dist/lib/repo.d.ts +6 -0
- package/dist/lib/repo.js +48 -0
- package/dist/lib/runtimeVersion.d.ts +42 -0
- package/dist/lib/runtimeVersion.js +116 -0
- package/dist/lib/utils.d.ts +1 -0
- package/dist/lib/utils.js +7 -0
- package/dist/lib/vcs/clients/git.d.ts +31 -0
- package/dist/lib/vcs/clients/git.js +322 -0
- package/dist/lib/vcs/clients/gitNoCommit.d.ts +8 -0
- package/dist/lib/vcs/clients/gitNoCommit.js +42 -0
- package/dist/lib/vcs/clients/noVcs.d.ts +7 -0
- package/dist/lib/vcs/clients/noVcs.js +22 -0
- package/dist/lib/vcs/git.d.ts +13 -0
- package/dist/lib/vcs/git.js +60 -0
- package/dist/lib/vcs/index.d.ts +2 -0
- package/dist/lib/vcs/index.js +26 -0
- package/dist/lib/vcs/local.d.ts +19 -0
- package/dist/lib/vcs/local.js +85 -0
- package/dist/lib/vcs/vcs.d.ts +25 -0
- package/dist/lib/vcs/vcs.js +61 -0
- package/dist/lib/workflow.d.ts +4 -0
- package/dist/lib/workflow.js +40 -0
- package/package.json +6 -2
- package/.eslintignore +0 -1
- package/.eslintrc.js +0 -73
- package/.prettierrc +0 -9
- package/src/commands/generate-certs.ts +0 -95
- package/src/commands/init.ts +0 -117
- package/src/commands/publish.ts +0 -277
- package/src/index.d.ts +0 -7
- package/src/lib/assets.ts +0 -118
- package/src/lib/auth.ts +0 -67
- package/src/lib/expoConfig.ts +0 -265
- package/src/lib/log.ts +0 -122
- package/src/lib/ora.ts +0 -113
- package/src/lib/package.ts +0 -6
- package/src/lib/prompts.ts +0 -97
- package/src/lib/repo.ts +0 -62
- package/src/lib/runtimeVersion.ts +0 -177
- package/src/lib/utils.ts +0 -3
- package/src/lib/vcs/README.md +0 -1
- package/src/lib/vcs/clients/git.ts +0 -390
- package/src/lib/vcs/clients/gitNoCommit.ts +0 -45
- package/src/lib/vcs/clients/noVcs.ts +0 -23
- package/src/lib/vcs/git.ts +0 -68
- package/src/lib/vcs/index.ts +0 -25
- package/src/lib/vcs/local.ts +0 -88
- package/src/lib/vcs/vcs.ts +0 -90
- package/src/lib/workflow.ts +0 -47
- package/tsconfig.json +0 -17
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { ExpoConfig } from '@expo/config';
|
|
2
|
+
import { Env } from '@expo/eas-build-job';
|
|
3
|
+
export declare enum RequestedPlatform {
|
|
4
|
+
Android = "android",
|
|
5
|
+
Ios = "ios",
|
|
6
|
+
All = "all"
|
|
7
|
+
}
|
|
8
|
+
export type PublicExpoConfig = Omit<ExpoConfig, '_internal' | 'hooks' | 'ios' | 'android' | 'updates'> & {
|
|
9
|
+
ios?: Omit<ExpoConfig['ios'], 'config'>;
|
|
10
|
+
android?: Omit<ExpoConfig['android'], 'config'>;
|
|
11
|
+
updates?: Omit<ExpoConfig['updates'], 'codeSigningCertificate' | 'codeSigningMetadata'>;
|
|
12
|
+
};
|
|
13
|
+
export interface ExpoConfigOptions {
|
|
14
|
+
env?: Env;
|
|
15
|
+
skipSDKVersionRequirement?: boolean;
|
|
16
|
+
skipPlugins?: boolean;
|
|
17
|
+
}
|
|
18
|
+
export declare function getPrivateExpoConfigAsync(projectDir: string, opts?: ExpoConfigOptions): Promise<ExpoConfig>;
|
|
19
|
+
export declare function ensureExpoConfigExists(projectDir: string): void;
|
|
20
|
+
export declare function isUsingStaticExpoConfig(projectDir: string): boolean;
|
|
21
|
+
export declare function getPublicExpoConfigAsync(projectDir: string, opts?: ExpoConfigOptions): Promise<PublicExpoConfig>;
|
|
22
|
+
export declare function getExpoConfigUpdateUrl(config: ExpoConfig): string | undefined;
|
|
23
|
+
export declare function createOrModifyExpoConfigAsync(projectDir: string, exp: Partial<ExpoConfig>): Promise<void>;
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createOrModifyExpoConfigAsync = exports.getExpoConfigUpdateUrl = exports.getPublicExpoConfigAsync = exports.isUsingStaticExpoConfig = exports.ensureExpoConfigExists = exports.getPrivateExpoConfigAsync = exports.RequestedPlatform = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
// This file is copied from eas-cli[https://github.com/expo/eas-cli] to ensure consistent user experience across the CLI.
|
|
6
|
+
const config_1 = require("@expo/config");
|
|
7
|
+
const spawn_async_1 = tslib_1.__importDefault(require("@expo/spawn-async"));
|
|
8
|
+
const fs_extra_1 = tslib_1.__importDefault(require("fs-extra"));
|
|
9
|
+
const joi_1 = tslib_1.__importDefault(require("joi"));
|
|
10
|
+
const jscodeshift_1 = tslib_1.__importDefault(require("jscodeshift"));
|
|
11
|
+
const path_1 = tslib_1.__importDefault(require("path"));
|
|
12
|
+
const log_1 = tslib_1.__importDefault(require("./log"));
|
|
13
|
+
const package_1 = require("./package");
|
|
14
|
+
var RequestedPlatform;
|
|
15
|
+
(function (RequestedPlatform) {
|
|
16
|
+
RequestedPlatform["Android"] = "android";
|
|
17
|
+
RequestedPlatform["Ios"] = "ios";
|
|
18
|
+
RequestedPlatform["All"] = "all";
|
|
19
|
+
})(RequestedPlatform || (exports.RequestedPlatform = RequestedPlatform = {}));
|
|
20
|
+
let wasExpoConfigWarnPrinted = false;
|
|
21
|
+
async function getExpoConfigInternalAsync(projectDir, opts = {}) {
|
|
22
|
+
const originalProcessEnv = process.env;
|
|
23
|
+
try {
|
|
24
|
+
process.env = {
|
|
25
|
+
...process.env,
|
|
26
|
+
...opts.env,
|
|
27
|
+
};
|
|
28
|
+
let exp;
|
|
29
|
+
if ((0, package_1.isExpoInstalled)(projectDir)) {
|
|
30
|
+
try {
|
|
31
|
+
const { stdout } = await (0, spawn_async_1.default)('npx', ['expo', 'config', '--json', ...(opts.isPublicConfig ? ['--type', 'public'] : [])], {
|
|
32
|
+
cwd: projectDir,
|
|
33
|
+
env: {
|
|
34
|
+
...process.env,
|
|
35
|
+
...opts.env,
|
|
36
|
+
EXPO_NO_DOTENV: '1',
|
|
37
|
+
},
|
|
38
|
+
});
|
|
39
|
+
exp = JSON.parse(stdout);
|
|
40
|
+
}
|
|
41
|
+
catch (err) {
|
|
42
|
+
if (!wasExpoConfigWarnPrinted) {
|
|
43
|
+
log_1.default.warn(`Failed to read the app config from the project using "npx expo config" command: ${err.message}.`);
|
|
44
|
+
log_1.default.warn('Falling back to the version of "@expo/config" shipped with the EAS CLI.');
|
|
45
|
+
wasExpoConfigWarnPrinted = true;
|
|
46
|
+
}
|
|
47
|
+
exp = (0, config_1.getConfig)(projectDir, {
|
|
48
|
+
skipSDKVersionRequirement: true,
|
|
49
|
+
...(opts.isPublicConfig ? { isPublicConfig: true } : {}),
|
|
50
|
+
...(opts.skipPlugins ? { skipPlugins: true } : {}),
|
|
51
|
+
}).exp;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
exp = (0, config_1.getConfig)(projectDir, {
|
|
56
|
+
skipSDKVersionRequirement: true,
|
|
57
|
+
...(opts.isPublicConfig ? { isPublicConfig: true } : {}),
|
|
58
|
+
...(opts.skipPlugins ? { skipPlugins: true } : {}),
|
|
59
|
+
}).exp;
|
|
60
|
+
}
|
|
61
|
+
const { error } = MinimalAppConfigSchema.validate(exp, {
|
|
62
|
+
allowUnknown: true,
|
|
63
|
+
abortEarly: true,
|
|
64
|
+
});
|
|
65
|
+
if (error) {
|
|
66
|
+
throw new Error(`Invalid app config.\n${error.message}`);
|
|
67
|
+
}
|
|
68
|
+
return exp;
|
|
69
|
+
}
|
|
70
|
+
finally {
|
|
71
|
+
process.env = originalProcessEnv;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
const MinimalAppConfigSchema = joi_1.default.object({
|
|
75
|
+
slug: joi_1.default.string().required(),
|
|
76
|
+
name: joi_1.default.string().required(),
|
|
77
|
+
version: joi_1.default.string(),
|
|
78
|
+
android: joi_1.default.object({
|
|
79
|
+
versionCode: joi_1.default.number().integer(),
|
|
80
|
+
}),
|
|
81
|
+
ios: joi_1.default.object({
|
|
82
|
+
buildNumber: joi_1.default.string(),
|
|
83
|
+
}),
|
|
84
|
+
});
|
|
85
|
+
async function getPrivateExpoConfigAsync(projectDir, opts = {}) {
|
|
86
|
+
ensureExpoConfigExists(projectDir);
|
|
87
|
+
return await getExpoConfigInternalAsync(projectDir, { ...opts, isPublicConfig: false });
|
|
88
|
+
}
|
|
89
|
+
exports.getPrivateExpoConfigAsync = getPrivateExpoConfigAsync;
|
|
90
|
+
function ensureExpoConfigExists(projectDir) {
|
|
91
|
+
const paths = (0, config_1.getConfigFilePaths)(projectDir);
|
|
92
|
+
if (!paths?.staticConfigPath && !paths?.dynamicConfigPath) {
|
|
93
|
+
// eslint-disable-next-line node/no-sync
|
|
94
|
+
fs_extra_1.default.writeFileSync(path_1.default.join(projectDir, 'app.json'), JSON.stringify({ expo: {} }, null, 2));
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
exports.ensureExpoConfigExists = ensureExpoConfigExists;
|
|
98
|
+
function isUsingStaticExpoConfig(projectDir) {
|
|
99
|
+
const paths = (0, config_1.getConfigFilePaths)(projectDir);
|
|
100
|
+
return !!(paths.staticConfigPath?.endsWith('app.json') && !paths.dynamicConfigPath);
|
|
101
|
+
}
|
|
102
|
+
exports.isUsingStaticExpoConfig = isUsingStaticExpoConfig;
|
|
103
|
+
async function getPublicExpoConfigAsync(projectDir, opts = {}) {
|
|
104
|
+
ensureExpoConfigExists(projectDir);
|
|
105
|
+
return await getExpoConfigInternalAsync(projectDir, { ...opts, isPublicConfig: true });
|
|
106
|
+
}
|
|
107
|
+
exports.getPublicExpoConfigAsync = getPublicExpoConfigAsync;
|
|
108
|
+
function getExpoConfigUpdateUrl(config) {
|
|
109
|
+
return config.updates?.url;
|
|
110
|
+
}
|
|
111
|
+
exports.getExpoConfigUpdateUrl = getExpoConfigUpdateUrl;
|
|
112
|
+
async function createOrModifyExpoConfigAsync(projectDir, exp) {
|
|
113
|
+
try {
|
|
114
|
+
ensureExpoConfigExists(projectDir);
|
|
115
|
+
const configPathJS = path_1.default.join(projectDir, 'app.config.js');
|
|
116
|
+
const configPathTS = path_1.default.join(projectDir, 'app.config.ts');
|
|
117
|
+
// eslint-disable-next-line node/no-sync
|
|
118
|
+
const hasJsConfig = fs_extra_1.default.existsSync(configPathJS);
|
|
119
|
+
if (isUsingStaticExpoConfig(projectDir)) {
|
|
120
|
+
log_1.default.withInfo('You are using a static app config. We will create a dynamic config file for you.');
|
|
121
|
+
const newConfigContent = `export default ({ config }) => ({
|
|
122
|
+
...config,
|
|
123
|
+
...${stringifyWithEnv(exp)}
|
|
124
|
+
});`;
|
|
125
|
+
// eslint-disable-next-line node/no-sync
|
|
126
|
+
fs_extra_1.default.writeFileSync(configPathJS, newConfigContent);
|
|
127
|
+
}
|
|
128
|
+
else if (hasJsConfig) {
|
|
129
|
+
// eslint-disable-next-line node/no-sync
|
|
130
|
+
const existingCode = fs_extra_1.default.readFileSync(configPathJS, 'utf8');
|
|
131
|
+
const j = jscodeshift_1.default;
|
|
132
|
+
const ast = j(existingCode);
|
|
133
|
+
ast.find(j.ArrowFunctionExpression).forEach(path => {
|
|
134
|
+
if (path.value.body &&
|
|
135
|
+
j.BlockStatement.check(path.value.body) &&
|
|
136
|
+
path.value.body.body.length > 0) {
|
|
137
|
+
const returnStatement = path.value.body.body.find(node => j.ReturnStatement.check(node));
|
|
138
|
+
if (returnStatement &&
|
|
139
|
+
j.ReturnStatement.check(returnStatement) &&
|
|
140
|
+
returnStatement.argument) {
|
|
141
|
+
const configObject = returnStatement.argument;
|
|
142
|
+
if (j.ObjectExpression.check(configObject)) {
|
|
143
|
+
updateObjectExpression(j, configObject, exp);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
const updatedCode = ast.toSource({
|
|
149
|
+
quote: 'auto',
|
|
150
|
+
trailingComma: true,
|
|
151
|
+
reuseWhitespace: true,
|
|
152
|
+
});
|
|
153
|
+
// eslint-disable-next-line node/no-sync
|
|
154
|
+
fs_extra_1.default.writeFileSync(configPathJS, updatedCode);
|
|
155
|
+
}
|
|
156
|
+
else if (configPathTS) {
|
|
157
|
+
log_1.default.warn('TypeScript support is not yet implemented.');
|
|
158
|
+
throw new Error('TypeScript support is not yet implemented.');
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
catch (e) {
|
|
162
|
+
log_1.default.withInfo('An error occurred while updating the Expo config. Please update it manually.');
|
|
163
|
+
log_1.default.newLine();
|
|
164
|
+
log_1.default.warn('Please modify your app.config.ts file manually by adding the following code:');
|
|
165
|
+
log_1.default.newLine();
|
|
166
|
+
log_1.default.withInfo(`${stringifyWithEnv(exp)}`);
|
|
167
|
+
log_1.default.newLine();
|
|
168
|
+
throw e;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
exports.createOrModifyExpoConfigAsync = createOrModifyExpoConfigAsync;
|
|
172
|
+
function updateObjectExpression(j, configObject, updates) {
|
|
173
|
+
Object.entries(updates).forEach(([key, value]) => {
|
|
174
|
+
const existingProperty = configObject.properties.find(prop => {
|
|
175
|
+
return (prop.type === 'Property' &&
|
|
176
|
+
((prop.key.type === 'Identifier' && prop.key.name === key) ||
|
|
177
|
+
(prop.key.type === 'StringLiteral' && prop.key.value === key)));
|
|
178
|
+
});
|
|
179
|
+
if (existingProperty) {
|
|
180
|
+
configObject.properties = configObject.properties.filter(prop => prop !== existingProperty);
|
|
181
|
+
}
|
|
182
|
+
const newProperty = j.objectProperty(j.identifier(key), createValueNode(j, value));
|
|
183
|
+
configObject.properties.push(newProperty);
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
function createValueNode(j, value) {
|
|
187
|
+
if (typeof value === 'string' && value.startsWith('process.env.')) {
|
|
188
|
+
return j.memberExpression(j.memberExpression(j.identifier('process'), j.identifier('env')), j.identifier(value.split('.')[2]));
|
|
189
|
+
}
|
|
190
|
+
if (typeof value === 'object' && value !== null) {
|
|
191
|
+
return j.objectExpression(Object.entries(value).map(([key, val]) => j.objectProperty(j.stringLiteral(key), createValueNode(j, val)) // Force stringLiteral pour garder les guillemets
|
|
192
|
+
));
|
|
193
|
+
}
|
|
194
|
+
return j.literal(value);
|
|
195
|
+
}
|
|
196
|
+
function stringifyWithEnv(obj) {
|
|
197
|
+
return JSON.stringify(obj, null, 2).replace(/"process\.env\.(\w+)"/g, 'process.env.$1');
|
|
198
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
export default class Log {
|
|
2
|
+
static readonly isDebug: boolean;
|
|
3
|
+
static log(...args: any[]): void;
|
|
4
|
+
static newLine(): void;
|
|
5
|
+
static addNewLineIfNone(): void;
|
|
6
|
+
static error(...args: any[]): void;
|
|
7
|
+
static warn(...args: any[]): void;
|
|
8
|
+
static debug(...args: any[]): void;
|
|
9
|
+
static gray(...args: any[]): void;
|
|
10
|
+
static warnDeprecatedFlag(flag: string, message: string): void;
|
|
11
|
+
static fail(message: string): void;
|
|
12
|
+
static succeed(message: string): void;
|
|
13
|
+
static withTick(...args: any[]): void;
|
|
14
|
+
static withInfo(...args: any[]): void;
|
|
15
|
+
private static consoleLog;
|
|
16
|
+
private static withTextColor;
|
|
17
|
+
private static isLastLineNewLine;
|
|
18
|
+
private static updateIsLastLineNewLine;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Prints a link for given URL, using text if provided, otherwise text is just the URL.
|
|
22
|
+
* Format links as dim (unless disabled) and with an underline.
|
|
23
|
+
*
|
|
24
|
+
* @example https://expo.dev
|
|
25
|
+
*/
|
|
26
|
+
export declare function link(url: string, { text, fallback, dim }?: {
|
|
27
|
+
text?: string;
|
|
28
|
+
dim?: boolean;
|
|
29
|
+
fallback?: string;
|
|
30
|
+
}): string;
|
|
31
|
+
/**
|
|
32
|
+
* Provide a consistent "Learn more" link experience.
|
|
33
|
+
* Format links as dim (unless disabled) with an underline.
|
|
34
|
+
*
|
|
35
|
+
* @example Learn more: https://expo.dev
|
|
36
|
+
*/
|
|
37
|
+
export declare function learnMore(url: string, { learnMoreMessage: maybeLearnMoreMessage, dim, }?: {
|
|
38
|
+
learnMoreMessage?: string;
|
|
39
|
+
dim?: boolean;
|
|
40
|
+
}): string;
|
package/dist/lib/log.js
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.learnMore = exports.link = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
// This file is copied from eas-cli[https://github.com/expo/eas-cli] to ensure consistent user experience across the CLI.
|
|
6
|
+
const chalk_1 = tslib_1.__importDefault(require("chalk"));
|
|
7
|
+
const figures_1 = tslib_1.__importDefault(require("figures"));
|
|
8
|
+
const getenv_1 = require("getenv");
|
|
9
|
+
const log_symbols_1 = tslib_1.__importDefault(require("log-symbols"));
|
|
10
|
+
const terminal_link_1 = tslib_1.__importDefault(require("terminal-link"));
|
|
11
|
+
class Log {
|
|
12
|
+
static isDebug = (0, getenv_1.boolish)('DEBUG', false);
|
|
13
|
+
static log(...args) {
|
|
14
|
+
Log.consoleLog(...args);
|
|
15
|
+
}
|
|
16
|
+
static newLine() {
|
|
17
|
+
Log.consoleLog();
|
|
18
|
+
}
|
|
19
|
+
static addNewLineIfNone() {
|
|
20
|
+
if (!Log.isLastLineNewLine) {
|
|
21
|
+
Log.newLine();
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
static error(...args) {
|
|
25
|
+
Log.consoleLog(...Log.withTextColor(args, chalk_1.default.red));
|
|
26
|
+
}
|
|
27
|
+
static warn(...args) {
|
|
28
|
+
Log.consoleLog(...Log.withTextColor(args, chalk_1.default.yellow));
|
|
29
|
+
}
|
|
30
|
+
static debug(...args) {
|
|
31
|
+
if (Log.isDebug) {
|
|
32
|
+
Log.consoleLog(...args);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
static gray(...args) {
|
|
36
|
+
Log.consoleLog(...Log.withTextColor(args, chalk_1.default.gray));
|
|
37
|
+
}
|
|
38
|
+
static warnDeprecatedFlag(flag, message) {
|
|
39
|
+
Log.warn(`› ${chalk_1.default.bold('--' + flag)} flag is deprecated. ${message}`);
|
|
40
|
+
}
|
|
41
|
+
static fail(message) {
|
|
42
|
+
Log.log(`${chalk_1.default.red(log_symbols_1.default.error)} ${message}`);
|
|
43
|
+
}
|
|
44
|
+
static succeed(message) {
|
|
45
|
+
Log.log(`${chalk_1.default.green(log_symbols_1.default.success)} ${message}`);
|
|
46
|
+
}
|
|
47
|
+
static withTick(...args) {
|
|
48
|
+
Log.consoleLog(chalk_1.default.green(figures_1.default.tick), ...args);
|
|
49
|
+
}
|
|
50
|
+
static withInfo(...args) {
|
|
51
|
+
Log.consoleLog(chalk_1.default.green(figures_1.default.info), ...args);
|
|
52
|
+
}
|
|
53
|
+
static consoleLog(...args) {
|
|
54
|
+
Log.updateIsLastLineNewLine(args);
|
|
55
|
+
// eslint-disable-next-line no-console
|
|
56
|
+
console.log(...args);
|
|
57
|
+
}
|
|
58
|
+
static withTextColor(args, chalkColor) {
|
|
59
|
+
return args.map(arg => chalkColor(arg));
|
|
60
|
+
}
|
|
61
|
+
static isLastLineNewLine = false;
|
|
62
|
+
static updateIsLastLineNewLine(args) {
|
|
63
|
+
if (args.length === 0) {
|
|
64
|
+
Log.isLastLineNewLine = true;
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
const lastArg = args[args.length - 1];
|
|
68
|
+
if (typeof lastArg === 'string' && (lastArg === '' || lastArg.match(/[\r\n]$/))) {
|
|
69
|
+
Log.isLastLineNewLine = true;
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
Log.isLastLineNewLine = false;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
exports.default = Log;
|
|
78
|
+
/**
|
|
79
|
+
* Prints a link for given URL, using text if provided, otherwise text is just the URL.
|
|
80
|
+
* Format links as dim (unless disabled) and with an underline.
|
|
81
|
+
*
|
|
82
|
+
* @example https://expo.dev
|
|
83
|
+
*/
|
|
84
|
+
function link(url, { text = url, fallback, dim = true } = {}) {
|
|
85
|
+
// Links can be disabled via env variables https://github.com/jamestalmage/supports-hyperlinks/blob/master/index.js
|
|
86
|
+
const output = (0, terminal_link_1.default)(text, url, {
|
|
87
|
+
fallback: () => fallback ?? (text === url ? chalk_1.default.underline(url) : `${text}: ${chalk_1.default.underline(url)}`),
|
|
88
|
+
});
|
|
89
|
+
return dim ? chalk_1.default.dim(output) : output;
|
|
90
|
+
}
|
|
91
|
+
exports.link = link;
|
|
92
|
+
/**
|
|
93
|
+
* Provide a consistent "Learn more" link experience.
|
|
94
|
+
* Format links as dim (unless disabled) with an underline.
|
|
95
|
+
*
|
|
96
|
+
* @example Learn more: https://expo.dev
|
|
97
|
+
*/
|
|
98
|
+
function learnMore(url, { learnMoreMessage: maybeLearnMoreMessage, dim = true, } = {}) {
|
|
99
|
+
return link(url, { text: maybeLearnMoreMessage ?? 'Learn more', dim });
|
|
100
|
+
}
|
|
101
|
+
exports.learnMore = learnMore;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Options, Ora } from 'ora';
|
|
2
|
+
export { Ora, Options };
|
|
3
|
+
/**
|
|
4
|
+
* A custom ora spinner that sends the stream to stdout in CI, or non-TTY, instead of stderr (the default).
|
|
5
|
+
*
|
|
6
|
+
* @param options
|
|
7
|
+
* @returns
|
|
8
|
+
*/
|
|
9
|
+
export declare function ora(options?: Options | string): Ora;
|
package/dist/lib/ora.js
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ora = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
// This file is copied from eas-cli[https://github.com/expo/eas-cli] to ensure consistent user experience across the CLI.
|
|
6
|
+
const getenv_1 = require("getenv");
|
|
7
|
+
// eslint-disable-next-line
|
|
8
|
+
const ora_1 = tslib_1.__importDefault(require("ora"));
|
|
9
|
+
const log_1 = tslib_1.__importDefault(require("./log"));
|
|
10
|
+
// eslint-disable-next-line no-console
|
|
11
|
+
const logReal = console.log;
|
|
12
|
+
// eslint-disable-next-line no-console
|
|
13
|
+
const infoReal = console.info;
|
|
14
|
+
// eslint-disable-next-line no-console
|
|
15
|
+
const warnReal = console.warn;
|
|
16
|
+
// eslint-disable-next-line no-console
|
|
17
|
+
const errorReal = console.error;
|
|
18
|
+
const isCi = (0, getenv_1.boolish)('CI', false);
|
|
19
|
+
/**
|
|
20
|
+
* A custom ora spinner that sends the stream to stdout in CI, or non-TTY, instead of stderr (the default).
|
|
21
|
+
*
|
|
22
|
+
* @param options
|
|
23
|
+
* @returns
|
|
24
|
+
*/
|
|
25
|
+
function ora(options) {
|
|
26
|
+
const inputOptions = typeof options === 'string' ? { text: options } : options ?? {};
|
|
27
|
+
const disabled = log_1.default.isDebug || !process.stdin.isTTY || isCi;
|
|
28
|
+
const spinner = (0, ora_1.default)({
|
|
29
|
+
// Ensure our non-interactive mode emulates CI mode.
|
|
30
|
+
isEnabled: !disabled,
|
|
31
|
+
// In non-interactive mode, send the stream to stdout so it prevents looking like an error.
|
|
32
|
+
stream: disabled ? process.stdout : process.stderr,
|
|
33
|
+
...inputOptions,
|
|
34
|
+
});
|
|
35
|
+
const oraStart = spinner.start.bind(spinner);
|
|
36
|
+
const oraStop = spinner.stop.bind(spinner);
|
|
37
|
+
const oraStopAndPersist = spinner.stopAndPersist.bind(spinner);
|
|
38
|
+
const logWrap = (method, args) => {
|
|
39
|
+
oraStop();
|
|
40
|
+
method(...args);
|
|
41
|
+
spinner.start();
|
|
42
|
+
};
|
|
43
|
+
const wrapNativeLogs = () => {
|
|
44
|
+
// eslint-disable-next-line no-console
|
|
45
|
+
console.log = (...args) => {
|
|
46
|
+
logWrap(logReal, args);
|
|
47
|
+
};
|
|
48
|
+
// eslint-disable-next-line no-console
|
|
49
|
+
console.info = (...args) => {
|
|
50
|
+
logWrap(infoReal, args);
|
|
51
|
+
};
|
|
52
|
+
// eslint-disable-next-line no-console
|
|
53
|
+
console.warn = (...args) => {
|
|
54
|
+
logWrap(warnReal, args);
|
|
55
|
+
};
|
|
56
|
+
// eslint-disable-next-line no-console
|
|
57
|
+
console.error = (...args) => {
|
|
58
|
+
logWrap(errorReal, args);
|
|
59
|
+
};
|
|
60
|
+
};
|
|
61
|
+
const resetNativeLogs = () => {
|
|
62
|
+
// eslint-disable-next-line no-console
|
|
63
|
+
console.log = logReal;
|
|
64
|
+
// eslint-disable-next-line no-console
|
|
65
|
+
console.info = infoReal;
|
|
66
|
+
// eslint-disable-next-line no-console
|
|
67
|
+
console.warn = warnReal;
|
|
68
|
+
// eslint-disable-next-line no-console
|
|
69
|
+
console.error = errorReal;
|
|
70
|
+
};
|
|
71
|
+
spinner.start = (text) => {
|
|
72
|
+
// wrapNativeLogs wraps calls to console so they always:
|
|
73
|
+
// 1. stop the spinner
|
|
74
|
+
// 2. log the message
|
|
75
|
+
// 3. start the spinner again
|
|
76
|
+
// Every restart of the spinner causes the spinner message to be logged again
|
|
77
|
+
// which makes logs look like
|
|
78
|
+
//
|
|
79
|
+
// - Exporting...
|
|
80
|
+
// [expo-cli] Starting Metro Bundler
|
|
81
|
+
// - Exporting...
|
|
82
|
+
// [expo-cli] Android Bundling complete 3492ms
|
|
83
|
+
// - Exporting...
|
|
84
|
+
//
|
|
85
|
+
// Skipping wrapping native logs removes the repeated interleaved "Exporting..." messages.
|
|
86
|
+
if (!disabled) {
|
|
87
|
+
wrapNativeLogs();
|
|
88
|
+
}
|
|
89
|
+
return oraStart(text);
|
|
90
|
+
};
|
|
91
|
+
spinner.stopAndPersist = (options) => {
|
|
92
|
+
const result = oraStopAndPersist(options);
|
|
93
|
+
resetNativeLogs();
|
|
94
|
+
return result;
|
|
95
|
+
};
|
|
96
|
+
spinner.stop = () => {
|
|
97
|
+
const result = oraStop();
|
|
98
|
+
resetNativeLogs();
|
|
99
|
+
return result;
|
|
100
|
+
};
|
|
101
|
+
return spinner;
|
|
102
|
+
}
|
|
103
|
+
exports.ora = ora;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function isExpoInstalled(projectDir: string): boolean;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isExpoInstalled = void 0;
|
|
4
|
+
const config_1 = require("@expo/config");
|
|
5
|
+
function isExpoInstalled(projectDir) {
|
|
6
|
+
const packageJson = (0, config_1.getPackageJson)(projectDir);
|
|
7
|
+
return !!(packageJson.dependencies && 'expo' in packageJson.dependencies);
|
|
8
|
+
}
|
|
9
|
+
exports.isExpoInstalled = isExpoInstalled;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import prompts, { Answers, Choice, Options } from 'prompts';
|
|
2
|
+
export interface ExpoChoice<T> extends Choice {
|
|
3
|
+
value: T;
|
|
4
|
+
}
|
|
5
|
+
export declare function promptAsync<T extends string = string>(questions: prompts.PromptObject<T> | prompts.PromptObject<T>[], options?: Options): Promise<Answers<T>>;
|
|
6
|
+
export declare function confirmAsync(question: prompts.PromptObject<any>, options?: Options): Promise<boolean>;
|
|
7
|
+
export declare function selectAsync<T>(message: string, choices: ExpoChoice<T>[], config?: {
|
|
8
|
+
options?: Options;
|
|
9
|
+
initial?: T;
|
|
10
|
+
warningMessageForDisabledEntries?: string;
|
|
11
|
+
}): Promise<T>;
|
|
12
|
+
export declare function toggleConfirmAsync(questions: prompts.PromptObject<any>, options?: Options): Promise<boolean>;
|
|
13
|
+
export declare function pressAnyKeyToContinueAsync(): Promise<void>;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.pressAnyKeyToContinueAsync = exports.toggleConfirmAsync = exports.selectAsync = exports.confirmAsync = exports.promptAsync = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
// This file is copied from eas-cli[https://github.com/expo/eas-cli] to ensure consistent user experience across the CLI.
|
|
6
|
+
const os_1 = require("os");
|
|
7
|
+
const prompts_1 = tslib_1.__importDefault(require("prompts"));
|
|
8
|
+
async function promptAsync(questions, options = {}) {
|
|
9
|
+
if (!process.stdin.isTTY) {
|
|
10
|
+
const message = Array.isArray(questions) ? questions[0]?.message : questions.message;
|
|
11
|
+
throw new Error(`Input is required, but stdin is not readable. Failed to display prompt: ${message}`);
|
|
12
|
+
}
|
|
13
|
+
return await (0, prompts_1.default)(questions, {
|
|
14
|
+
onCancel() {
|
|
15
|
+
process.exit(os_1.constants.signals.SIGINT + 128); // Exit code 130 used when process is interrupted with ctrl+c.
|
|
16
|
+
},
|
|
17
|
+
...options,
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
exports.promptAsync = promptAsync;
|
|
21
|
+
async function confirmAsync(question, options) {
|
|
22
|
+
const { value } = await promptAsync({
|
|
23
|
+
initial: true,
|
|
24
|
+
...question,
|
|
25
|
+
name: 'value',
|
|
26
|
+
type: 'confirm',
|
|
27
|
+
}, options);
|
|
28
|
+
return value;
|
|
29
|
+
}
|
|
30
|
+
exports.confirmAsync = confirmAsync;
|
|
31
|
+
async function selectAsync(message, choices, config) {
|
|
32
|
+
const initial = config?.initial ? choices.findIndex(({ value }) => value === config.initial) : 0;
|
|
33
|
+
const { value } = await promptAsync({
|
|
34
|
+
message,
|
|
35
|
+
choices,
|
|
36
|
+
initial,
|
|
37
|
+
name: 'value',
|
|
38
|
+
type: 'select',
|
|
39
|
+
warn: config?.warningMessageForDisabledEntries,
|
|
40
|
+
}, config?.options ?? {});
|
|
41
|
+
return value ?? null;
|
|
42
|
+
}
|
|
43
|
+
exports.selectAsync = selectAsync;
|
|
44
|
+
async function toggleConfirmAsync(questions, options) {
|
|
45
|
+
const { value } = await promptAsync({
|
|
46
|
+
active: 'yes',
|
|
47
|
+
inactive: 'no',
|
|
48
|
+
...questions,
|
|
49
|
+
name: 'value',
|
|
50
|
+
type: 'toggle',
|
|
51
|
+
}, options);
|
|
52
|
+
return value ?? null;
|
|
53
|
+
}
|
|
54
|
+
exports.toggleConfirmAsync = toggleConfirmAsync;
|
|
55
|
+
async function pressAnyKeyToContinueAsync() {
|
|
56
|
+
process.stdin.setRawMode(true);
|
|
57
|
+
process.stdin.resume();
|
|
58
|
+
process.stdin.setEncoding('utf8');
|
|
59
|
+
await new Promise(res => {
|
|
60
|
+
process.stdin.on('data', key => {
|
|
61
|
+
if (String(key) === '\u0003') {
|
|
62
|
+
process.exit(os_1.constants.signals.SIGINT + 128); // ctrl-c
|
|
63
|
+
}
|
|
64
|
+
res();
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
exports.pressAnyKeyToContinueAsync = pressAnyKeyToContinueAsync;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { Client } from './vcs/vcs';
|
|
2
|
+
export declare function commitPromptAsync(vcsClient: Client, { initialCommitMessage, commitAllFiles, }?: {
|
|
3
|
+
initialCommitMessage?: string;
|
|
4
|
+
commitAllFiles?: boolean;
|
|
5
|
+
}): Promise<void>;
|
|
6
|
+
export declare function ensureRepoIsCleanAsync(vcsClient: Client, nonInteractive?: boolean): Promise<void>;
|
package/dist/lib/repo.js
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ensureRepoIsCleanAsync = exports.commitPromptAsync = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
// This file is copied from eas-cli[https://github.com/expo/eas-cli] to ensure consistent user experience across the CLI.
|
|
6
|
+
const chalk_1 = tslib_1.__importDefault(require("chalk"));
|
|
7
|
+
const log_1 = tslib_1.__importDefault(require("./log"));
|
|
8
|
+
const prompts_1 = require("./prompts");
|
|
9
|
+
async function commitPromptAsync(vcsClient, { initialCommitMessage, commitAllFiles, } = {}) {
|
|
10
|
+
const { message } = await (0, prompts_1.promptAsync)({
|
|
11
|
+
type: 'text',
|
|
12
|
+
name: 'message',
|
|
13
|
+
message: 'Commit message:',
|
|
14
|
+
initial: initialCommitMessage,
|
|
15
|
+
validate: (input) => input !== '',
|
|
16
|
+
});
|
|
17
|
+
await vcsClient.commitAsync({
|
|
18
|
+
commitAllFiles,
|
|
19
|
+
commitMessage: message,
|
|
20
|
+
nonInteractive: false,
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
exports.commitPromptAsync = commitPromptAsync;
|
|
24
|
+
async function ensureRepoIsCleanAsync(vcsClient, nonInteractive = false) {
|
|
25
|
+
if (!(await vcsClient.isCommitRequiredAsync())) {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
log_1.default.addNewLineIfNone();
|
|
29
|
+
log_1.default.warn(`${chalk_1.default.bold('Warning!')} Your repository working tree is dirty.`);
|
|
30
|
+
log_1.default.log(`This operation needs to be run on a clean working tree. ${chalk_1.default.bold('Commit all your changes before proceeding')}.`);
|
|
31
|
+
if (nonInteractive) {
|
|
32
|
+
log_1.default.log('The following files need to be committed:');
|
|
33
|
+
await vcsClient.showChangedFilesAsync();
|
|
34
|
+
throw new Error('Commit all changes. Aborting...');
|
|
35
|
+
}
|
|
36
|
+
const answer = await (0, prompts_1.confirmAsync)({
|
|
37
|
+
message: `Commit changes to git?`,
|
|
38
|
+
type: 'confirm',
|
|
39
|
+
name: 'confirm git commit',
|
|
40
|
+
});
|
|
41
|
+
if (answer) {
|
|
42
|
+
await commitPromptAsync(vcsClient, { commitAllFiles: true });
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
throw new Error('Commit all changes. Aborting...');
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
exports.ensureRepoIsCleanAsync = ensureRepoIsCleanAsync;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { ExpoConfig } from '@expo/config';
|
|
2
|
+
import { Env, Workflow } from '@expo/eas-build-job';
|
|
3
|
+
export declare class ExpoUpdatesCLIModuleNotFoundError extends Error {
|
|
4
|
+
}
|
|
5
|
+
export declare class ExpoUpdatesCLIInvalidCommandError extends Error {
|
|
6
|
+
}
|
|
7
|
+
export declare class ExpoUpdatesCLICommandFailedError extends Error {
|
|
8
|
+
}
|
|
9
|
+
export declare function expoUpdatesCommandAsync(projectDir: string, args: string[], options: {
|
|
10
|
+
env: Env | undefined;
|
|
11
|
+
cwd?: string;
|
|
12
|
+
}): Promise<string>;
|
|
13
|
+
export declare function isModernExpoUpdatesCLIWithRuntimeVersionCommandSupportedAsync(projectDir: string): Promise<boolean>;
|
|
14
|
+
export declare function resolveRuntimeVersionUsingCLIAsync({ platform, workflow, projectDir, env, cwd, }: {
|
|
15
|
+
platform: 'ios' | 'android';
|
|
16
|
+
workflow: Workflow;
|
|
17
|
+
projectDir: string;
|
|
18
|
+
env: Env | undefined;
|
|
19
|
+
cwd?: string;
|
|
20
|
+
}): Promise<{
|
|
21
|
+
runtimeVersion: string | null;
|
|
22
|
+
expoUpdatesRuntimeFingerprint: {
|
|
23
|
+
fingerprintSources: object[];
|
|
24
|
+
isDebugFingerprintSource: boolean;
|
|
25
|
+
} | null;
|
|
26
|
+
expoUpdatesRuntimeFingerprintHash: string | null;
|
|
27
|
+
}>;
|
|
28
|
+
export declare function resolveRuntimeVersionAsync({ exp, platform, workflow, projectDir, env, cwd, }: {
|
|
29
|
+
exp: ExpoConfig;
|
|
30
|
+
platform: 'ios' | 'android';
|
|
31
|
+
workflow: Workflow;
|
|
32
|
+
projectDir: string;
|
|
33
|
+
env: Env | undefined;
|
|
34
|
+
cwd?: string;
|
|
35
|
+
}): Promise<{
|
|
36
|
+
runtimeVersion: string | null;
|
|
37
|
+
expoUpdatesRuntimeFingerprint: {
|
|
38
|
+
fingerprintSources: object[];
|
|
39
|
+
isDebugFingerprintSource: boolean;
|
|
40
|
+
} | null;
|
|
41
|
+
expoUpdatesRuntimeFingerprintHash: string | null;
|
|
42
|
+
} | null>;
|