esa-cli 1.0.3-beta.4 → 1.0.4-beta.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/dist/commands/commit/index.js +11 -1
- package/dist/commands/common/utils.js +10 -5
- package/dist/commands/deploy/index.js +5 -1
- package/dist/commands/dev/ew2/devEntry.js +2 -4
- package/dist/commands/dev/ew2/mock/cache.js +9 -6
- package/dist/commands/dev/ew2/mock/kv.js +2 -0
- package/dist/commands/init/helper.js +2 -2
- package/dist/commands/utils.js +58 -0
- package/dist/docs/Commands_en.md +6 -0
- package/dist/docs/Commands_zh_CN.md +6 -0
- package/dist/i18n/locales.json +12 -0
- package/dist/index.js +1 -1
- package/dist/libs/api.js +3 -1
- package/dist/libs/apiService.js +5 -2
- package/dist/libs/constants.js +13 -0
- package/dist/libs/logger.js +0 -3
- package/dist/utils/command.js +22 -21
- package/package.json +1 -1
|
@@ -13,6 +13,7 @@ import chalk from 'chalk';
|
|
|
13
13
|
import t from '../../i18n/index.js';
|
|
14
14
|
import logger from '../../libs/logger.js';
|
|
15
15
|
import promptParameter from '../../utils/prompt.js';
|
|
16
|
+
import { checkAndCleanupVersions } from '../utils.js';
|
|
16
17
|
import { validateAndInitializeProject, generateCodeVersion } from '../common/utils.js';
|
|
17
18
|
const commit = {
|
|
18
19
|
command: 'commit [entry]',
|
|
@@ -44,6 +45,10 @@ const commit = {
|
|
|
44
45
|
describe: 'Bundle with esbuild (use --no-bundle to skip)',
|
|
45
46
|
type: 'boolean',
|
|
46
47
|
default: true
|
|
48
|
+
})
|
|
49
|
+
.option('version-limit', {
|
|
50
|
+
describe: t('commit_option_version_limit').d('Maximum number of versions to keep. Oldest unreleased versions will be deleted if exceeded.'),
|
|
51
|
+
type: 'number'
|
|
47
52
|
});
|
|
48
53
|
},
|
|
49
54
|
handler: (argv) => __awaiter(void 0, void 0, void 0, function* () {
|
|
@@ -59,7 +64,12 @@ export function handleCommit(argv) {
|
|
|
59
64
|
const projectInfo = yield validateAndInitializeProject(argv === null || argv === void 0 ? void 0 : argv.name);
|
|
60
65
|
if (!projectInfo)
|
|
61
66
|
return;
|
|
62
|
-
const { projectName } = projectInfo;
|
|
67
|
+
const { projectName, projectConfig } = projectInfo;
|
|
68
|
+
// Cleanup old versions if limit is specified
|
|
69
|
+
const limit = argv['version-limit'] || (projectConfig === null || projectConfig === void 0 ? void 0 : projectConfig.versionLimit);
|
|
70
|
+
if (limit) {
|
|
71
|
+
yield checkAndCleanupVersions(projectName, limit, true);
|
|
72
|
+
}
|
|
63
73
|
let description;
|
|
64
74
|
if (argv.description) {
|
|
65
75
|
description = argv.description;
|
|
@@ -15,7 +15,7 @@ import { ensureRoutineExists } from '../../utils/checkIsRoutineCreated.js';
|
|
|
15
15
|
import compress from '../../utils/compress.js';
|
|
16
16
|
import { getProjectConfig } from '../../utils/fileUtils/index.js';
|
|
17
17
|
import sleep from '../../utils/sleep.js';
|
|
18
|
-
import { checkIsLoginSuccess } from '../utils.js';
|
|
18
|
+
import { checkAndCleanupVersions, checkIsLoginSuccess } from '../utils.js';
|
|
19
19
|
function normalizeNotFoundStrategy(value) {
|
|
20
20
|
if (!value)
|
|
21
21
|
return undefined;
|
|
@@ -260,21 +260,26 @@ export function deployToEnvironments(name, codeVersion, env) {
|
|
|
260
260
|
* 结合了压缩、提交和部署的完整流程
|
|
261
261
|
*/
|
|
262
262
|
export function commitAndDeployVersion(projectName_1, scriptEntry_1, assets_1) {
|
|
263
|
-
return __awaiter(this, arguments, void 0, function* (projectName, scriptEntry, assets, description = '', projectPath, env = 'production', minify = false, version, noBundle = false) {
|
|
263
|
+
return __awaiter(this, arguments, void 0, function* (projectName, scriptEntry, assets, description = '', projectPath, env = 'production', minify = false, version, noBundle = false, versionLimit) {
|
|
264
264
|
var _a, _b, _c;
|
|
265
265
|
const projectInfo = yield validateAndInitializeProject(projectName, projectPath);
|
|
266
266
|
if (!projectInfo) {
|
|
267
267
|
return false;
|
|
268
268
|
}
|
|
269
|
-
const { projectConfig } = projectInfo;
|
|
269
|
+
const { projectConfig, projectName: resolvedProjectName } = projectInfo;
|
|
270
|
+
// Cleanup old versions if limit is specified
|
|
271
|
+
const limit = versionLimit || (projectConfig === null || projectConfig === void 0 ? void 0 : projectConfig.versionLimit);
|
|
272
|
+
if (limit) {
|
|
273
|
+
yield checkAndCleanupVersions(resolvedProjectName, limit, !version);
|
|
274
|
+
}
|
|
270
275
|
// 2) Use existing version or generate a new one
|
|
271
276
|
if (version) {
|
|
272
277
|
logger.startSubStep(`Using existing version ${version}`);
|
|
273
|
-
const deployed = yield deployToEnvironments(
|
|
278
|
+
const deployed = yield deployToEnvironments(resolvedProjectName, version, env);
|
|
274
279
|
logger.endSubStep(deployed ? 'Deploy finished' : 'Deploy failed');
|
|
275
280
|
return deployed;
|
|
276
281
|
}
|
|
277
|
-
const res = yield generateCodeVersion(
|
|
282
|
+
const res = yield generateCodeVersion(resolvedProjectName, description, scriptEntry || (projectConfig === null || projectConfig === void 0 ? void 0 : projectConfig.entry), assets || ((_a = projectConfig === null || projectConfig === void 0 ? void 0 : projectConfig.assets) === null || _a === void 0 ? void 0 : _a.directory), minify || (projectConfig === null || projectConfig === void 0 ? void 0 : projectConfig.minify), projectPath, noBundle);
|
|
278
283
|
const isCommitSuccess = res === null || res === void 0 ? void 0 : res.isSuccess;
|
|
279
284
|
if (!isCommitSuccess) {
|
|
280
285
|
logger.endSubStep('Generate version failed');
|
|
@@ -61,6 +61,10 @@ const deploy = {
|
|
|
61
61
|
.option('versions', {
|
|
62
62
|
describe: 'Deploy two versions with percentages, format: v1:80,v2:20 or repeat --versions v1:80 --versions v2:20',
|
|
63
63
|
type: 'array'
|
|
64
|
+
})
|
|
65
|
+
.option('version-limit', {
|
|
66
|
+
describe: t('deploy_option_version_limit').d('Maximum number of versions to keep. Oldest unreleased versions will be deleted if exceeded.'),
|
|
67
|
+
type: 'number'
|
|
64
68
|
});
|
|
65
69
|
},
|
|
66
70
|
describe: `🚀 ${t('deploy_describe').d('Deploy your project')}`,
|
|
@@ -82,7 +86,7 @@ export function handleDeploy(argv) {
|
|
|
82
86
|
outro(ok ? 'Deploy finished' : 'Deploy failed');
|
|
83
87
|
exit(ok ? 0 : 1);
|
|
84
88
|
}
|
|
85
|
-
const success = yield commitAndDeployVersion(argv.name || undefined, entry, assets, argv.description || '', getRoot(), argv.environment || 'all', argv.minify, argv.version, (argv.bundle === false));
|
|
89
|
+
const success = yield commitAndDeployVersion(argv.name || undefined, entry, assets, argv.description || '', getRoot(), argv.environment || 'all', argv.minify, argv.version, (argv.bundle === false), argv['version-limit']);
|
|
86
90
|
outro(success ? 'Deploy finished' : 'Deploy failed');
|
|
87
91
|
if (success) {
|
|
88
92
|
const projectConfig = getProjectConfig(getRoot());
|
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
import worker from '$userPath';
|
|
2
1
|
import Cache from './mock/cache.js';
|
|
3
2
|
import mockKV from './mock/kv.js';
|
|
3
|
+
import worker from '$userPath';
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
globalThis.mockCache = mock_cache;
|
|
5
|
+
Cache.port = $userPort;
|
|
7
6
|
mockKV.port = $userPort;
|
|
8
|
-
globalThis.mockKV = mockKV;
|
|
9
7
|
|
|
10
8
|
export default worker;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
class MockCache {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
}
|
|
2
|
+
static port = 0;
|
|
3
|
+
|
|
4
|
+
constructor() {}
|
|
5
5
|
|
|
6
6
|
async put(reqOrUrl, response) {
|
|
7
7
|
if (arguments.length < 2) {
|
|
@@ -30,7 +30,7 @@ class MockCache {
|
|
|
30
30
|
|
|
31
31
|
const key = this.normalizeKey(reqOrUrl);
|
|
32
32
|
const fetchRes = await fetch(
|
|
33
|
-
`http://localhost:${
|
|
33
|
+
`http://localhost:${MockCache.port}/mock_cache/put`,
|
|
34
34
|
{
|
|
35
35
|
method: 'POST',
|
|
36
36
|
headers: { 'Content-Type': 'application/json' },
|
|
@@ -58,7 +58,7 @@ class MockCache {
|
|
|
58
58
|
async get(reqOrUrl) {
|
|
59
59
|
const key = this.normalizeKey(reqOrUrl);
|
|
60
60
|
const fetchRes = await fetch(
|
|
61
|
-
`http://localhost:${
|
|
61
|
+
`http://localhost:${MockCache.port}/mock_cache/get`,
|
|
62
62
|
{
|
|
63
63
|
method: 'POST',
|
|
64
64
|
headers: { 'Content-Type': 'application/json' },
|
|
@@ -85,7 +85,7 @@ class MockCache {
|
|
|
85
85
|
async delete(reqOrUrl) {
|
|
86
86
|
const key = this.normalizeKey(reqOrUrl);
|
|
87
87
|
const fetchRes = await fetch(
|
|
88
|
-
`http://localhost:${
|
|
88
|
+
`http://localhost:${MockCache.port}/mock_cache/delete`,
|
|
89
89
|
{
|
|
90
90
|
method: 'POST',
|
|
91
91
|
headers: { 'Content-Type': 'application/json' },
|
|
@@ -113,4 +113,7 @@ class MockCache {
|
|
|
113
113
|
}
|
|
114
114
|
}
|
|
115
115
|
|
|
116
|
+
var mock_cache = new MockCache();
|
|
117
|
+
globalThis.mockCache = mock_cache;
|
|
118
|
+
|
|
116
119
|
export default MockCache;
|
|
@@ -17,7 +17,7 @@ import Haikunator from 'haikunator';
|
|
|
17
17
|
import t from '../../i18n/index.js';
|
|
18
18
|
import logger from '../../libs/logger.js';
|
|
19
19
|
import Template from '../../libs/templates/index.js';
|
|
20
|
-
import { execCommand } from '../../utils/command.js';
|
|
20
|
+
import { execCommand, execWithLoginShell } from '../../utils/command.js';
|
|
21
21
|
import { getDirName } from '../../utils/fileUtils/base.js';
|
|
22
22
|
import { generateConfigFile, getCliConfig, getProjectConfig, getTemplatesConfig, templateHubPath, updateProjectConfigFile } from '../../utils/fileUtils/index.js';
|
|
23
23
|
import promptParameter from '../../utils/prompt.js';
|
|
@@ -382,7 +382,7 @@ export const createProject = (initParams) => __awaiter(void 0, void 0, void 0, f
|
|
|
382
382
|
const templateFlag = ((_a = frameworkConfig.language) === null || _a === void 0 ? void 0 : _a[initParams.language || 'typescript']) || '';
|
|
383
383
|
const extraParams = frameworkConfig.params || '';
|
|
384
384
|
const full = `${command} ${initParams.name} ${templateFlag} ${extraParams}`.trim();
|
|
385
|
-
const res = yield
|
|
385
|
+
const res = yield execWithLoginShell(full, {
|
|
386
386
|
interactive: true,
|
|
387
387
|
startText: `Starting to execute framework command ${chalk.gray(full)}`,
|
|
388
388
|
doneText: `Framework command executed ${chalk.gray(full)}`
|
package/dist/commands/utils.js
CHANGED
|
@@ -153,3 +153,61 @@ export const getRoutineCodeVersions = (projectName) => __awaiter(void 0, void 0,
|
|
|
153
153
|
const productionVersions = ((_m = (_l = (_k = (_j = (_h = routineDetail === null || routineDetail === void 0 ? void 0 : routineDetail.data) === null || _h === void 0 ? void 0 : _h.Envs) === null || _j === void 0 ? void 0 : _j.find((item) => item.Env === 'production')) === null || _k === void 0 ? void 0 : _k.CodeDeploy) === null || _l === void 0 ? void 0 : _l.CodeVersions) === null || _m === void 0 ? void 0 : _m.map((item) => item.CodeVersion)) || [];
|
|
154
154
|
return { allVersions, stagingVersions, productionVersions };
|
|
155
155
|
});
|
|
156
|
+
/**
|
|
157
|
+
* Check the total number of versions and delete the oldest unreleased ones if they exceed the limit.
|
|
158
|
+
* @param projectName Name of the project
|
|
159
|
+
* @param limit The maximum number of versions to keep
|
|
160
|
+
* @param isCreatingNewVersion Whether a new version will be created after cleanup
|
|
161
|
+
*/
|
|
162
|
+
export function checkAndCleanupVersions(projectName_1, limit_1) {
|
|
163
|
+
return __awaiter(this, arguments, void 0, function* (projectName, limit, isCreatingNewVersion = true) {
|
|
164
|
+
if (limit <= 0)
|
|
165
|
+
return;
|
|
166
|
+
const { allVersions, stagingVersions, productionVersions } = yield getRoutineCodeVersions(projectName);
|
|
167
|
+
const currentCount = allVersions.length;
|
|
168
|
+
const targetCount = isCreatingNewVersion ? limit - 1 : limit;
|
|
169
|
+
if (currentCount <= targetCount) {
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
const deployedVersions = new Set([...stagingVersions, ...productionVersions]);
|
|
173
|
+
// Filter versions that are not currently deployed
|
|
174
|
+
const undeployedVersions = allVersions.filter((v) => v.codeVersion && !deployedVersions.has(v.codeVersion));
|
|
175
|
+
// Sort by createTime (oldest first)
|
|
176
|
+
undeployedVersions.sort((a, b) => {
|
|
177
|
+
const timeA = a.createTime ? new Date(a.createTime).getTime() : 0;
|
|
178
|
+
const timeB = b.createTime ? new Date(b.createTime).getTime() : 0;
|
|
179
|
+
return timeA - timeB;
|
|
180
|
+
});
|
|
181
|
+
const numToDelete = currentCount - targetCount;
|
|
182
|
+
const toDelete = undeployedVersions.slice(0, numToDelete);
|
|
183
|
+
if (toDelete.length > 0) {
|
|
184
|
+
logger.info(t('cleanup_versions_start', {
|
|
185
|
+
count: toDelete.length.toString(),
|
|
186
|
+
limit: limit.toString()
|
|
187
|
+
}).d(`Cleaning up ${toDelete.length} oldest unreleased versions (limit: ${limit})...`));
|
|
188
|
+
const server = yield ApiService.getInstance();
|
|
189
|
+
for (const version of toDelete) {
|
|
190
|
+
if (!version.codeVersion)
|
|
191
|
+
continue;
|
|
192
|
+
try {
|
|
193
|
+
const res = yield server.deleteRoutineCodeVersion({
|
|
194
|
+
Name: projectName,
|
|
195
|
+
CodeVersion: version.codeVersion
|
|
196
|
+
});
|
|
197
|
+
if ((res === null || res === void 0 ? void 0 : res.Status) === 'OK') {
|
|
198
|
+
logger.success(t('deployments_delete_success').d('Delete success') +
|
|
199
|
+
`: ${version.codeVersion}`);
|
|
200
|
+
}
|
|
201
|
+
else {
|
|
202
|
+
logger.warn(t('deployments_delete_failed').d('Delete failed') +
|
|
203
|
+
`: ${version.codeVersion}`);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
catch (error) {
|
|
207
|
+
logger.warn(t('deployments_delete_failed').d('Delete failed') +
|
|
208
|
+
`: ${version.codeVersion}`);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
});
|
|
213
|
+
}
|
package/dist/docs/Commands_en.md
CHANGED
|
@@ -143,6 +143,9 @@ Description for Functions & Pages/version (skip interactive input)
|
|
|
143
143
|
**--name, -n** _optional_
|
|
144
144
|
Functions & Pages name
|
|
145
145
|
|
|
146
|
+
**--version-limit** _optional_
|
|
147
|
+
Maximum number of versions to keep. Oldest unreleased versions (not in staging or production) will be deleted if exceeded.
|
|
148
|
+
|
|
146
149
|
---
|
|
147
150
|
|
|
148
151
|
## deploy
|
|
@@ -174,6 +177,9 @@ Description of the version
|
|
|
174
177
|
**--minify, -m** _optional_
|
|
175
178
|
Whether to minify the code
|
|
176
179
|
|
|
180
|
+
**--version-limit** _optional_
|
|
181
|
+
Maximum number of versions to keep. Oldest unreleased versions (not in staging or production) will be deleted if exceeded.
|
|
182
|
+
|
|
177
183
|
---
|
|
178
184
|
|
|
179
185
|
## deployments
|
|
@@ -155,6 +155,9 @@ esa-cli commit [<ENTRY>] [OPTIONS]
|
|
|
155
155
|
**--name, -n** _可选_
|
|
156
156
|
**函数和Pages名称**
|
|
157
157
|
|
|
158
|
+
**--version-limit** _可选_
|
|
159
|
+
**保持的最大版本数量。如果超过此限制,将删除最旧的未发布版本(不处于仿真环境或线上环境的版本)。**
|
|
160
|
+
|
|
158
161
|
---
|
|
159
162
|
|
|
160
163
|
## deploy
|
|
@@ -186,6 +189,9 @@ esa-cli deploy [<ENTRY>] [OPTIONS]
|
|
|
186
189
|
**--minify, -m** _可选_
|
|
187
190
|
**是否压缩代码**
|
|
188
191
|
|
|
192
|
+
**--version-limit** _可选_
|
|
193
|
+
**保持的最大版本数量。如果超过此限制,将删除最旧的未发布版本(不处于仿真环境或线上环境的版本)。**
|
|
194
|
+
|
|
189
195
|
---
|
|
190
196
|
|
|
191
197
|
## deployments
|
package/dist/i18n/locales.json
CHANGED
|
@@ -1322,5 +1322,17 @@
|
|
|
1322
1322
|
"login_get_credentials_from_environment_variables": {
|
|
1323
1323
|
"en": "Get credentials from environment variables",
|
|
1324
1324
|
"zh_CN": ""
|
|
1325
|
+
},
|
|
1326
|
+
"commit_option_version_limit": {
|
|
1327
|
+
"en": "Maximum number of versions to keep. Oldest unreleased versions will be deleted if exceeded.",
|
|
1328
|
+
"zh_CN": "保留的最大版本数量。如果超过此限制,最旧的未发布版本将被删除。"
|
|
1329
|
+
},
|
|
1330
|
+
"deploy_option_version_limit": {
|
|
1331
|
+
"en": "Maximum number of versions to keep. Oldest unreleased versions will be deleted if exceeded.",
|
|
1332
|
+
"zh_CN": "保留的最大版本数量。如果超过此限制,最旧的未发布版本将被删除。"
|
|
1333
|
+
},
|
|
1334
|
+
"cleanup_versions_start": {
|
|
1335
|
+
"en": "Cleaning up ${toDelete.length} oldest unreleased versions (limit: ${limit})...",
|
|
1336
|
+
"zh_CN": "正在清理 ${count} 个最旧的未发布版本(限制数量:${limit})..."
|
|
1325
1337
|
}
|
|
1326
1338
|
}
|
package/dist/index.js
CHANGED
|
@@ -10,7 +10,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
10
10
|
import chalk from 'chalk';
|
|
11
11
|
import yargs from 'yargs';
|
|
12
12
|
import { hideBin } from 'yargs/helpers';
|
|
13
|
-
import logger from './libs/logger.js';
|
|
14
13
|
import commit from './commands/commit/index.js';
|
|
15
14
|
import config from './commands/config.js';
|
|
16
15
|
import deploy from './commands/deploy/index.js';
|
|
@@ -25,6 +24,7 @@ import routeCommand from './commands/route/index.js';
|
|
|
25
24
|
import routine from './commands/routine/index.js';
|
|
26
25
|
import site from './commands/site/index.js';
|
|
27
26
|
import t from './i18n/index.js';
|
|
27
|
+
import logger from './libs/logger.js';
|
|
28
28
|
import { handleCheckVersion, checkCLIVersion } from './utils/checkVersion.js';
|
|
29
29
|
import { getCliConfig } from './utils/fileUtils/index.js';
|
|
30
30
|
const main = () => __awaiter(void 0, void 0, void 0, function* () {
|
package/dist/libs/api.js
CHANGED
|
@@ -11,6 +11,7 @@ import ESA, * as $ESA from '@alicloud/esa20240910';
|
|
|
11
11
|
import * as $OpenApi from '@alicloud/openapi-client';
|
|
12
12
|
import * as $Util from '@alicloud/tea-util';
|
|
13
13
|
import { getApiConfig } from '../utils/fileUtils/index.js';
|
|
14
|
+
import { CLI_USER_AGENT } from './constants.js';
|
|
14
15
|
import logger from './logger.js';
|
|
15
16
|
class Client {
|
|
16
17
|
constructor() {
|
|
@@ -77,7 +78,8 @@ class Client {
|
|
|
77
78
|
const apiConfig = new $OpenApi.Config({
|
|
78
79
|
accessKeyId: (_a = config.auth) === null || _a === void 0 ? void 0 : _a.accessKeyId,
|
|
79
80
|
accessKeySecret: (_b = config.auth) === null || _b === void 0 ? void 0 : _b.accessKeySecret,
|
|
80
|
-
endpoint: config.endpoint
|
|
81
|
+
endpoint: config.endpoint,
|
|
82
|
+
userAgent: CLI_USER_AGENT
|
|
81
83
|
});
|
|
82
84
|
return new ESA.default(apiConfig);
|
|
83
85
|
}
|
package/dist/libs/apiService.js
CHANGED
|
@@ -12,6 +12,7 @@ import FormData from 'form-data';
|
|
|
12
12
|
import fetch from 'node-fetch';
|
|
13
13
|
import t from '../i18n/index.js';
|
|
14
14
|
import { getApiConfig } from '../utils/fileUtils/index.js';
|
|
15
|
+
import { CLI_USER_AGENT } from './constants.js';
|
|
15
16
|
import { Environment } from './interface.js';
|
|
16
17
|
export class ApiService {
|
|
17
18
|
constructor(cliConfig) {
|
|
@@ -19,7 +20,8 @@ export class ApiService {
|
|
|
19
20
|
let apiConfig = new $OpenApi.Config({
|
|
20
21
|
accessKeyId: (_a = cliConfig.auth) === null || _a === void 0 ? void 0 : _a.accessKeyId,
|
|
21
22
|
accessKeySecret: (_b = cliConfig.auth) === null || _b === void 0 ? void 0 : _b.accessKeySecret,
|
|
22
|
-
endpoint: cliConfig.endpoint
|
|
23
|
+
endpoint: cliConfig.endpoint,
|
|
24
|
+
userAgent: CLI_USER_AGENT
|
|
23
25
|
});
|
|
24
26
|
this.client = new $OpenApi.default.default(apiConfig);
|
|
25
27
|
}
|
|
@@ -37,7 +39,8 @@ export class ApiService {
|
|
|
37
39
|
let apiConfig = new $OpenApi.Config({
|
|
38
40
|
accessKeyId: (_a = newConfig.auth) === null || _a === void 0 ? void 0 : _a.accessKeyId,
|
|
39
41
|
accessKeySecret: (_b = newConfig.auth) === null || _b === void 0 ? void 0 : _b.accessKeySecret,
|
|
40
|
-
endpoint: newConfig.endpoint
|
|
42
|
+
endpoint: newConfig.endpoint,
|
|
43
|
+
userAgent: CLI_USER_AGENT
|
|
41
44
|
});
|
|
42
45
|
this.client = new $OpenApi.default.default(apiConfig);
|
|
43
46
|
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { createRequire } from 'module';
|
|
2
|
+
const require = createRequire(import.meta.url);
|
|
3
|
+
const packageJson = require('../../package.json');
|
|
4
|
+
/**
|
|
5
|
+
* CLI User-Agent string for API requests
|
|
6
|
+
* Format: esa-cli/{version}
|
|
7
|
+
* This helps identify requests originating from the CLI
|
|
8
|
+
*/
|
|
9
|
+
export const CLI_USER_AGENT = `esa-cli/${packageJson.version}`;
|
|
10
|
+
/**
|
|
11
|
+
* CLI version from package.json
|
|
12
|
+
*/
|
|
13
|
+
export const CLI_VERSION = packageJson.version;
|
package/dist/libs/logger.js
CHANGED
package/dist/utils/command.js
CHANGED
|
@@ -7,15 +7,16 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
7
7
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
|
+
import { spawn } from 'child_process';
|
|
11
|
+
import { platform } from 'os';
|
|
10
12
|
import { cancel, spinner } from '@clack/prompts';
|
|
11
13
|
import chalk from 'chalk';
|
|
12
|
-
|
|
13
|
-
import logger from '../libs/logger.js';
|
|
14
|
+
export const isWindows = platform() === 'win32';
|
|
14
15
|
/**
|
|
15
16
|
* Execute a shell command with rich options (spinner, capture, env, cwd).
|
|
16
17
|
*/
|
|
17
18
|
export const execCommand = (command_1, ...args_1) => __awaiter(void 0, [command_1, ...args_1], void 0, function* (command, options = {}) {
|
|
18
|
-
const { startText, doneText, silent = false, captureOutput = false, useSpinner = true, realtimeOutput = false, interactive = false, env, cwd, transformOutput, fallbackOutput, errorMessage,
|
|
19
|
+
const { startText, doneText, silent = false, captureOutput = false, useSpinner = true, realtimeOutput = false, interactive = false, env, cwd, transformOutput, fallbackOutput, errorMessage, shell = false } = options;
|
|
19
20
|
// Determine stdio mode based on options
|
|
20
21
|
// If realtimeOutput is true, we need to pipe to capture and display output in real-time
|
|
21
22
|
// If spinner is used without realtimeOutput, pipe to avoid TTY contention
|
|
@@ -56,7 +57,7 @@ export const execCommand = (command_1, ...args_1) => __awaiter(void 0, [command_
|
|
|
56
57
|
stdio,
|
|
57
58
|
cwd,
|
|
58
59
|
env: Object.assign(Object.assign({}, process.env), env),
|
|
59
|
-
shell
|
|
60
|
+
shell
|
|
60
61
|
});
|
|
61
62
|
if (stdio === 'pipe') {
|
|
62
63
|
(_a = child.stdout) === null || _a === void 0 ? void 0 : _a.on('data', (chunk) => {
|
|
@@ -141,27 +142,27 @@ export const execCommand = (command_1, ...args_1) => __awaiter(void 0, [command_
|
|
|
141
142
|
if (stderr)
|
|
142
143
|
process.stderr.write(stderr);
|
|
143
144
|
}
|
|
144
|
-
if (debug) {
|
|
145
|
-
console.error(chalk.red('\n--- DEBUG INFO ---'));
|
|
146
|
-
console.error(chalk.red(`Command: ${command.join(' ')}`));
|
|
147
|
-
if (cwd)
|
|
148
|
-
console.error(chalk.red(`CWD: ${cwd}`));
|
|
149
|
-
if (stdout)
|
|
150
|
-
console.error(chalk.red(`Stdout:\n${stdout}`));
|
|
151
|
-
if (stderr)
|
|
152
|
-
console.error(chalk.red(`Stderr:\n${stderr}`));
|
|
153
|
-
if (e instanceof Error && e.stack) {
|
|
154
|
-
console.error(chalk.red(`Stack:\n${e.stack}`));
|
|
155
|
-
}
|
|
156
|
-
else if (e && typeof e === 'object') {
|
|
157
|
-
console.error(chalk.red(`Error Object:\n${JSON.stringify(e, null, 2)}`));
|
|
158
|
-
}
|
|
159
|
-
console.error(chalk.red('------------------\n'));
|
|
160
|
-
}
|
|
161
145
|
if (errorMessage) {
|
|
162
146
|
cancel(errorMessage);
|
|
163
147
|
}
|
|
164
148
|
return { success: false, stdout, stderr };
|
|
165
149
|
}
|
|
166
150
|
});
|
|
151
|
+
/**
|
|
152
|
+
* Execute a command with login shell on Unix (to load ~/.profile, ~/.zshrc etc.)
|
|
153
|
+
* On Windows, directly execute the command since login shell is not typically needed.
|
|
154
|
+
*
|
|
155
|
+
* @param commandStr - The full command string to execute
|
|
156
|
+
* @param options - ExecCommandOptions
|
|
157
|
+
*/
|
|
158
|
+
export const execWithLoginShell = (commandStr_1, ...args_1) => __awaiter(void 0, [commandStr_1, ...args_1], void 0, function* (commandStr, options = {}) {
|
|
159
|
+
if (isWindows) {
|
|
160
|
+
// Windows: use cmd /c to execute the command
|
|
161
|
+
return execCommand(['cmd', '/c', commandStr], options);
|
|
162
|
+
}
|
|
163
|
+
else {
|
|
164
|
+
// Unix: use login shell to ensure PATH is properly set (nvm, fnm, etc.)
|
|
165
|
+
return execCommand(['sh', '-lc', commandStr], options);
|
|
166
|
+
}
|
|
167
|
+
});
|
|
167
168
|
export default execCommand;
|