esa-cli 0.0.2-beta.2 → 0.0.2-beta.20
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 +48 -115
- package/dist/commands/commit/prodBuild.js +2 -3
- package/dist/commands/common/constant.js +0 -19
- package/dist/commands/common/utils.js +416 -0
- package/dist/commands/config.js +1 -1
- package/dist/commands/deploy/helper.js +51 -72
- package/dist/commands/deploy/index.js +50 -188
- package/dist/commands/deployments/delete.js +32 -22
- package/dist/commands/deployments/index.js +2 -2
- package/dist/commands/deployments/list.js +22 -38
- package/dist/commands/dev/build.js +3 -3
- package/dist/commands/dev/doProcess.js +5 -5
- package/dist/commands/dev/ew2/cacheService.js +33 -0
- package/dist/commands/dev/ew2/devEntry.js +2 -1
- package/dist/commands/dev/ew2/devPack.js +39 -43
- package/dist/commands/dev/ew2/kvService.js +27 -0
- package/dist/commands/dev/ew2/mock/cache.js +99 -15
- package/dist/commands/dev/ew2/mock/kv.js +142 -21
- package/dist/commands/dev/ew2/server.js +165 -29
- package/dist/commands/dev/index.js +17 -17
- package/dist/commands/dev/mockWorker/devPack.js +35 -24
- package/dist/commands/dev/mockWorker/server.js +7 -6
- package/dist/commands/domain/add.js +2 -2
- package/dist/commands/domain/delete.js +7 -7
- package/dist/commands/domain/index.js +2 -2
- package/dist/commands/domain/list.js +10 -10
- package/dist/commands/init/helper.js +759 -0
- package/dist/commands/init/index.js +88 -220
- package/dist/commands/init/snippets/nextjs/next.config.mjs +6 -0
- package/dist/commands/init/snippets/nextjs/next.config.ts +7 -0
- package/dist/commands/init/snippets/react-router/react-router.config.ts +7 -0
- package/dist/commands/init/template.jsonc +84 -0
- package/dist/commands/init/types.js +1 -0
- package/dist/commands/lang.js +2 -2
- package/dist/commands/login/index.js +74 -34
- package/dist/commands/logout.js +5 -5
- package/dist/commands/route/add.js +105 -49
- package/dist/commands/route/delete.js +33 -27
- package/dist/commands/route/helper.js +123 -0
- package/dist/commands/route/index.js +2 -2
- package/dist/commands/route/list.js +56 -17
- package/dist/commands/routine/delete.js +2 -2
- package/dist/commands/routine/index.js +2 -2
- package/dist/commands/routine/list.js +43 -37
- package/dist/commands/site/index.js +1 -1
- package/dist/commands/site/list.js +6 -7
- package/dist/commands/utils.js +59 -23
- package/dist/components/descriptionInput.js +1 -1
- package/dist/components/filterSelector.js +1 -1
- package/dist/components/mutiLevelSelect.js +43 -55
- package/dist/components/mutiSelectTable.js +1 -1
- package/dist/components/routeBuilder.js +68 -0
- package/dist/components/selectInput.js +2 -3
- package/dist/components/selectItem.js +1 -1
- package/dist/docs/Commands_en.md +142 -131
- package/dist/docs/Commands_zh_CN.md +139 -127
- package/dist/i18n/index.js +2 -2
- package/dist/i18n/locales.json +435 -23
- package/dist/index.js +27 -20
- package/dist/libs/api.js +32 -9
- package/dist/libs/apiService.js +267 -88
- package/dist/libs/git/index.js +86 -9
- package/dist/libs/interface.js +0 -1
- package/dist/libs/logger.js +162 -10
- package/dist/libs/service.js +2 -2
- package/dist/libs/templates/index.js +3 -2
- package/dist/utils/checkAssetsExist.js +80 -0
- package/dist/utils/checkDevPort.js +3 -17
- package/dist/utils/checkEntryFileExist.js +10 -0
- package/dist/utils/checkIsRoutineCreated.js +28 -27
- package/dist/utils/checkVersion.js +119 -1
- package/dist/utils/command.js +149 -0
- package/dist/utils/compress.js +136 -0
- package/dist/utils/download.js +182 -0
- package/dist/utils/fileMd5.js +1 -1
- package/dist/utils/fileUtils/base.js +1 -1
- package/dist/utils/fileUtils/index.js +136 -44
- package/dist/utils/installDeno.js +8 -8
- package/dist/utils/installEw2.js +7 -7
- package/dist/utils/openInBrowser.js +1 -1
- package/dist/utils/prompt.js +97 -0
- package/package.json +19 -12
|
@@ -7,15 +7,13 @@ 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 { getProjectConfig, readEdgeRoutineFile } from '../../utils/fileUtils/index.js';
|
|
11
|
-
import { checkDirectory, checkIsLoginSuccess } from '../utils.js';
|
|
12
|
-
import { displaySelectSpec } from '../deploy/index.js';
|
|
13
|
-
import { descriptionInput } from '../../components/descriptionInput.js';
|
|
14
|
-
import { ApiService } from '../../libs/apiService.js';
|
|
15
|
-
import prodBuild from './prodBuild.js';
|
|
16
|
-
import logger from '../../libs/logger.js';
|
|
17
|
-
import t from '../../i18n/index.js';
|
|
18
10
|
import { exit } from 'process';
|
|
11
|
+
import { intro, outro } from '@clack/prompts';
|
|
12
|
+
import chalk from 'chalk';
|
|
13
|
+
import t from '../../i18n/index.js';
|
|
14
|
+
import logger from '../../libs/logger.js';
|
|
15
|
+
import promptParameter from '../../utils/prompt.js';
|
|
16
|
+
import { validateAndInitializeProject, generateCodeVersion } from '../common/utils.js';
|
|
19
17
|
const commit = {
|
|
20
18
|
command: 'commit [entry]',
|
|
21
19
|
describe: `📥 ${t('commit_describe').d('Commit your code, save as a new version')}`,
|
|
@@ -27,126 +25,61 @@ const commit = {
|
|
|
27
25
|
type: 'boolean',
|
|
28
26
|
default: false
|
|
29
27
|
})
|
|
30
|
-
.
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
28
|
+
.option('assets', {
|
|
29
|
+
alias: 'a',
|
|
30
|
+
describe: t('commit_option_assets').d('Assets directory'),
|
|
31
|
+
type: 'string'
|
|
32
|
+
})
|
|
33
|
+
.option('description', {
|
|
34
|
+
alias: 'd',
|
|
35
|
+
describe: t('commit_option_description').d('Description for the routine/version (skip interactive input)'),
|
|
36
|
+
type: 'string'
|
|
37
|
+
})
|
|
38
|
+
.option('name', {
|
|
39
|
+
alias: 'n',
|
|
40
|
+
describe: t('commit_option_name').d('Edge Routine name'),
|
|
41
|
+
type: 'string'
|
|
34
42
|
});
|
|
35
43
|
},
|
|
36
44
|
handler: (argv) => __awaiter(void 0, void 0, void 0, function* () {
|
|
37
|
-
handleCommit(argv);
|
|
45
|
+
yield handleCommit(argv);
|
|
46
|
+
exit();
|
|
38
47
|
})
|
|
39
48
|
};
|
|
40
49
|
export default commit;
|
|
41
50
|
export function handleCommit(argv) {
|
|
42
51
|
return __awaiter(this, void 0, void 0, function* () {
|
|
43
|
-
var _a, _b
|
|
44
|
-
|
|
52
|
+
var _a, _b;
|
|
53
|
+
intro(`Commit an application with ESA`);
|
|
54
|
+
const projectInfo = yield validateAndInitializeProject(argv === null || argv === void 0 ? void 0 : argv.name);
|
|
55
|
+
if (!projectInfo)
|
|
45
56
|
return;
|
|
46
|
-
const
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
return;
|
|
51
|
-
yield prodBuild(!!argv.minify, argv === null || argv === void 0 ? void 0 : argv.entry);
|
|
52
|
-
try {
|
|
53
|
-
const server = yield ApiService.getInstance();
|
|
54
|
-
const req = { Name: projectConfig.name };
|
|
55
|
-
const response = yield server.getRoutine(req, false);
|
|
56
|
-
let specName = (_a = response === null || response === void 0 ? void 0 : response.data.Envs[0].SpecName) !== null && _a !== void 0 ? _a : '50ms';
|
|
57
|
-
let action = 'Creating';
|
|
58
|
-
let description;
|
|
59
|
-
if (!response) {
|
|
60
|
-
logger.log(`🙅 ${t('commit_er_not_exist').d('No routine found, creating a new one')}`);
|
|
61
|
-
description = yield descriptionInput(`🖊️ ${t('commit_er_description').d('Enter a description for the routine')}:`, false);
|
|
62
|
-
const specList = ((_c = (_b = (yield server.ListRoutineOptionalSpecs())) === null || _b === void 0 ? void 0 : _b.data.Specs) !== null && _c !== void 0 ? _c : []).reduce((acc, item) => {
|
|
63
|
-
if (item.IsAvailable) {
|
|
64
|
-
acc.push(item.SpecName);
|
|
65
|
-
}
|
|
66
|
-
return acc;
|
|
67
|
-
}, []);
|
|
68
|
-
specName = yield displaySelectSpec(specList);
|
|
69
|
-
}
|
|
70
|
-
else {
|
|
71
|
-
logger.log(`🔄 ${t('commit_er_exist').d('Routine exists, updating the code')}`);
|
|
72
|
-
description = yield descriptionInput(`🖊️ ${t('commit_version_description').d('Enter a description for the version')}:`, false);
|
|
73
|
-
action = 'Updating';
|
|
74
|
-
}
|
|
75
|
-
const code = readEdgeRoutineFile() || '';
|
|
76
|
-
const edgeRoutine = {
|
|
77
|
-
name: projectConfig.name,
|
|
78
|
-
code,
|
|
79
|
-
description,
|
|
80
|
-
specName
|
|
81
|
-
};
|
|
82
|
-
if (action === 'Creating') {
|
|
83
|
-
yield createEdgeRoutine(edgeRoutine);
|
|
84
|
-
}
|
|
85
|
-
else {
|
|
86
|
-
if (!(yield uploadEdgeRoutineCode(edgeRoutine)))
|
|
87
|
-
return;
|
|
88
|
-
yield releaseOfficialVersion(edgeRoutine);
|
|
89
|
-
}
|
|
90
|
-
exit(0);
|
|
91
|
-
}
|
|
92
|
-
catch (error) {
|
|
93
|
-
logger.error(`${t('common_error_occurred').d('An error occurred:')} ${error}`);
|
|
94
|
-
}
|
|
95
|
-
});
|
|
96
|
-
}
|
|
97
|
-
export function createEdgeRoutine(edgeRoutine) {
|
|
98
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
99
|
-
try {
|
|
100
|
-
const server = yield ApiService.getInstance();
|
|
101
|
-
const res = yield server.createRoutine(edgeRoutine);
|
|
102
|
-
const createResult = (res === null || res === void 0 ? void 0 : res.data.Status) === 'OK';
|
|
103
|
-
if (!createResult) {
|
|
104
|
-
logger.error(t('commit_create_er_fail').d('An error occurred while trying to create a routine'));
|
|
105
|
-
return false;
|
|
106
|
-
}
|
|
107
|
-
logger.success(t('commit_create_er_success').d('Routine created successfully.'));
|
|
108
|
-
return yield uploadEdgeRoutineCode(edgeRoutine);
|
|
57
|
+
const { projectName } = projectInfo;
|
|
58
|
+
let description;
|
|
59
|
+
if (argv.description) {
|
|
60
|
+
description = argv.description;
|
|
109
61
|
}
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
118
|
-
try {
|
|
119
|
-
const server = yield ApiService.getInstance();
|
|
120
|
-
const uploadResult = yield server.getRoutineStagingCodeUploadInfo(edgeRoutine);
|
|
121
|
-
if (!uploadResult) {
|
|
122
|
-
logger.error(t('commit_upload_fail').d('An error occurred while trying to upload your code'));
|
|
123
|
-
process.exit(0);
|
|
124
|
-
}
|
|
125
|
-
logger.success(t('commit_upload_success').d('Code uploaded successfully.'));
|
|
126
|
-
return true;
|
|
127
|
-
}
|
|
128
|
-
catch (error) {
|
|
129
|
-
logger.error(`${t('common_error_occurred').d('An error occurred:')} ${error}`);
|
|
130
|
-
process.exit(0);
|
|
62
|
+
else {
|
|
63
|
+
description = (yield promptParameter({
|
|
64
|
+
type: 'text',
|
|
65
|
+
question: t('commit_version_description').d('Enter a description for the version'),
|
|
66
|
+
label: 'Description',
|
|
67
|
+
defaultValue: ''
|
|
68
|
+
}));
|
|
131
69
|
}
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
Name: edgeRoutine.name,
|
|
139
|
-
CodeDescription: (_a = edgeRoutine.description) !== null && _a !== void 0 ? _a : ''
|
|
140
|
-
};
|
|
141
|
-
const server = yield ApiService.getInstance();
|
|
142
|
-
const commitResult = yield server.commitRoutineStagingCode(param);
|
|
143
|
-
if (commitResult) {
|
|
144
|
-
logger.success(t('commit_success').d('Code version committed successfully.'));
|
|
145
|
-
return true;
|
|
70
|
+
logger.startSubStep('Generating code version');
|
|
71
|
+
const res = yield generateCodeVersion(projectName, description, argv === null || argv === void 0 ? void 0 : argv.entry, argv === null || argv === void 0 ? void 0 : argv.assets, argv === null || argv === void 0 ? void 0 : argv.minify);
|
|
72
|
+
const { isSuccess } = res || {};
|
|
73
|
+
if (!isSuccess) {
|
|
74
|
+
logger.endSubStep('Generate version failed');
|
|
75
|
+
exit(1);
|
|
146
76
|
}
|
|
147
|
-
|
|
148
|
-
|
|
77
|
+
const codeVersion = (_b = (_a = res === null || res === void 0 ? void 0 : res.res) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.CodeVersion;
|
|
78
|
+
if (!codeVersion) {
|
|
79
|
+
logger.endSubStep('Missing CodeVersion in response');
|
|
149
80
|
return false;
|
|
150
81
|
}
|
|
82
|
+
logger.endSubStep(`Version generated: ${codeVersion}`);
|
|
83
|
+
outro(`Code version ${chalk.bold(codeVersion)} generated successfully`);
|
|
151
84
|
});
|
|
152
85
|
}
|
|
@@ -7,15 +7,14 @@ 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 fs from 'fs';
|
|
11
|
+
import path from 'path';
|
|
10
12
|
import esbuild from 'esbuild';
|
|
11
13
|
import { lessLoader } from 'esbuild-plugin-less';
|
|
12
|
-
import path from 'path';
|
|
13
|
-
import fs from 'fs';
|
|
14
14
|
import { getRoot } from '../../utils/fileUtils/base.js';
|
|
15
15
|
import { NODE_EXTERNALS } from '../common/constant.js';
|
|
16
16
|
const userRoot = getRoot();
|
|
17
17
|
const entry = path.resolve(userRoot, 'src/index.js');
|
|
18
|
-
const outfile = path.resolve(userRoot, '.dev/pub.js');
|
|
19
18
|
export default function () {
|
|
20
19
|
return __awaiter(this, arguments, void 0, function* (minify = false, customEntry, outputPath) {
|
|
21
20
|
const entryPoint = customEntry
|
|
@@ -1,23 +1,4 @@
|
|
|
1
1
|
import t from '../../i18n/index.js';
|
|
2
|
-
export const SUMMARIES_LIST = [
|
|
3
|
-
{
|
|
4
|
-
title: t('summery_cd').d('Enter your routine project folder'),
|
|
5
|
-
command: '💡 cd [Your Routine Name]'
|
|
6
|
-
},
|
|
7
|
-
{
|
|
8
|
-
title: t('summery_dev').d('Start a local development server for your project'),
|
|
9
|
-
command: '💡 esa dev'
|
|
10
|
-
},
|
|
11
|
-
{
|
|
12
|
-
title: t('summery_commit').d('Save a new version of code'),
|
|
13
|
-
command: '💡 esa commit'
|
|
14
|
-
},
|
|
15
|
-
// Use Deploy or Release?
|
|
16
|
-
{
|
|
17
|
-
title: t('summery_deploy').d('Deploy your project to different environments'),
|
|
18
|
-
command: '💡 esa deploy'
|
|
19
|
-
}
|
|
20
|
-
];
|
|
21
2
|
export const getSummary = (routineName) => {
|
|
22
3
|
return [
|
|
23
4
|
{
|
|
@@ -0,0 +1,416 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import chalk from 'chalk';
|
|
11
|
+
import t from '../../i18n/index.js';
|
|
12
|
+
import { ApiService } from '../../libs/apiService.js';
|
|
13
|
+
import logger from '../../libs/logger.js';
|
|
14
|
+
import { ensureRoutineExists } from '../../utils/checkIsRoutineCreated.js';
|
|
15
|
+
import compress from '../../utils/compress.js';
|
|
16
|
+
import { getProjectConfig } from '../../utils/fileUtils/index.js';
|
|
17
|
+
import sleep from '../../utils/sleep.js';
|
|
18
|
+
import { checkIsLoginSuccess } from '../utils.js';
|
|
19
|
+
function normalizeNotFoundStrategy(value) {
|
|
20
|
+
if (!value)
|
|
21
|
+
return undefined;
|
|
22
|
+
const lower = value.toLowerCase();
|
|
23
|
+
if (lower === 'singlepageapplication') {
|
|
24
|
+
return 'SinglePageApplication';
|
|
25
|
+
}
|
|
26
|
+
return value;
|
|
27
|
+
}
|
|
28
|
+
export function commitRoutineWithAssets(requestParams, zipBuffer) {
|
|
29
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
30
|
+
try {
|
|
31
|
+
const server = yield ApiService.getInstance();
|
|
32
|
+
const apiResult = yield server.CreateRoutineWithAssetsCodeVersion(requestParams);
|
|
33
|
+
if (!apiResult || !apiResult.data.OssPostConfig) {
|
|
34
|
+
return {
|
|
35
|
+
isSuccess: false,
|
|
36
|
+
res: null
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
const ossConfig = apiResult.data.OssPostConfig;
|
|
40
|
+
if (!ossConfig.OSSAccessKeyId ||
|
|
41
|
+
!ossConfig.Signature ||
|
|
42
|
+
!ossConfig.Url ||
|
|
43
|
+
!ossConfig.Key ||
|
|
44
|
+
!ossConfig.Policy) {
|
|
45
|
+
console.error('Missing required OSS configuration fields');
|
|
46
|
+
return {
|
|
47
|
+
isSuccess: false,
|
|
48
|
+
res: null
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
let uploadSuccess = false;
|
|
52
|
+
for (let i = 0; i < 3; i++) {
|
|
53
|
+
uploadSuccess = yield server.uploadToOss({
|
|
54
|
+
OSSAccessKeyId: ossConfig.OSSAccessKeyId,
|
|
55
|
+
Signature: ossConfig.Signature,
|
|
56
|
+
Url: ossConfig.Url,
|
|
57
|
+
Key: ossConfig.Key,
|
|
58
|
+
Policy: ossConfig.Policy,
|
|
59
|
+
XOssSecurityToken: ossConfig.XOssSecurityToken || ''
|
|
60
|
+
}, zipBuffer);
|
|
61
|
+
if (uploadSuccess) {
|
|
62
|
+
break;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return {
|
|
66
|
+
isSuccess: uploadSuccess,
|
|
67
|
+
res: apiResult
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
console.error('Error in createRoutineWithAssetsCodeVersion:', error);
|
|
72
|
+
return {
|
|
73
|
+
isSuccess: false,
|
|
74
|
+
res: null
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* 通用的项目验证和初始化函数
|
|
81
|
+
* 包含目录检查、项目配置获取、登录检查、routine存在性检查
|
|
82
|
+
*/
|
|
83
|
+
export function validateAndInitializeProject(name, projectPath) {
|
|
84
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
85
|
+
const projectConfig = getProjectConfig(projectPath);
|
|
86
|
+
// allow missing config, derive name from cwd when not provided
|
|
87
|
+
const projectName = name ||
|
|
88
|
+
(projectConfig === null || projectConfig === void 0 ? void 0 : projectConfig.name) ||
|
|
89
|
+
process.cwd().split(/[\\/]/).pop();
|
|
90
|
+
if (!projectName) {
|
|
91
|
+
logger.notInProject();
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
logger.startSubStep('Checking login status');
|
|
95
|
+
const isSuccess = yield checkIsLoginSuccess();
|
|
96
|
+
if (!isSuccess) {
|
|
97
|
+
logger.endSubStep('You are not logged in');
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
100
|
+
logger.endSubStep('Logged in');
|
|
101
|
+
yield ensureRoutineExists(projectName);
|
|
102
|
+
return { projectConfig: projectConfig || null, projectName };
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* 通用的routine详情获取函数
|
|
107
|
+
*/
|
|
108
|
+
export function getRoutineDetails(projectName) {
|
|
109
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
110
|
+
const server = yield ApiService.getInstance();
|
|
111
|
+
const req = { Name: projectName };
|
|
112
|
+
return yield server.getRoutine(req, false);
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* 通用的代码压缩和提交函数
|
|
117
|
+
* 支持assets和普通代码两种模式
|
|
118
|
+
*/
|
|
119
|
+
export function generateCodeVersion(projectName_1, description_1, entry_1, assets_1) {
|
|
120
|
+
return __awaiter(this, arguments, void 0, function* (projectName, description, entry, assets, minify = false, projectPath) {
|
|
121
|
+
var _a;
|
|
122
|
+
const { zip, sourceList, dynamicSources } = yield compress(entry, assets, minify, projectPath);
|
|
123
|
+
// Pretty print upload directory tree
|
|
124
|
+
const buildTree = (paths, decorateTopLevel) => {
|
|
125
|
+
const root = { children: new Map(), isFile: false };
|
|
126
|
+
const sorted = [...paths].sort((a, b) => a.localeCompare(b));
|
|
127
|
+
for (const p of sorted) {
|
|
128
|
+
const parts = p.split('/').filter(Boolean);
|
|
129
|
+
let node = root;
|
|
130
|
+
for (let i = 0; i < parts.length; i++) {
|
|
131
|
+
const part = parts[i];
|
|
132
|
+
if (!node.children.has(part)) {
|
|
133
|
+
node.children.set(part, { children: new Map(), isFile: false });
|
|
134
|
+
}
|
|
135
|
+
const child = node.children.get(part);
|
|
136
|
+
if (i === parts.length - 1)
|
|
137
|
+
child.isFile = true;
|
|
138
|
+
node = child;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
const lines = [];
|
|
142
|
+
const render = (node, prefix, depth) => {
|
|
143
|
+
const entries = [...node.children.entries()];
|
|
144
|
+
entries.forEach(([_name, _child], idx) => {
|
|
145
|
+
const isLast = idx === entries.length - 1;
|
|
146
|
+
const connector = isLast ? '└ ' : '├ ';
|
|
147
|
+
const nextPrefix = prefix + (isLast ? ' ' : '│ ');
|
|
148
|
+
const displayName = depth === 0 ? decorateTopLevel(_name) : _name;
|
|
149
|
+
lines.push(prefix + connector + displayName);
|
|
150
|
+
render(_child, nextPrefix, depth + 1);
|
|
151
|
+
});
|
|
152
|
+
};
|
|
153
|
+
render(root, '', 0);
|
|
154
|
+
return lines.length ? lines : ['-'];
|
|
155
|
+
};
|
|
156
|
+
const header = chalk.hex('#22c55e')('UPLOAD') + ' Files to be uploaded (source paths)';
|
|
157
|
+
logger.block();
|
|
158
|
+
logger.log(header);
|
|
159
|
+
const dynamicSet = new Set(dynamicSources);
|
|
160
|
+
const LIMIT = 300;
|
|
161
|
+
const staticPaths = sourceList
|
|
162
|
+
.filter((p) => !dynamicSet.has(p))
|
|
163
|
+
.sort((a, b) => a.localeCompare(b));
|
|
164
|
+
const dynamicPaths = sourceList
|
|
165
|
+
.filter((p) => dynamicSet.has(p))
|
|
166
|
+
.sort((a, b) => a.localeCompare(b));
|
|
167
|
+
let omitted = 0;
|
|
168
|
+
let shownStatic = staticPaths;
|
|
169
|
+
if (staticPaths.length > LIMIT) {
|
|
170
|
+
shownStatic = staticPaths.slice(0, LIMIT);
|
|
171
|
+
omitted = staticPaths.length - LIMIT;
|
|
172
|
+
}
|
|
173
|
+
// Compute top-level markers based on whether a top-level bucket contains dynamic/static files
|
|
174
|
+
const topLevelStats = new Map();
|
|
175
|
+
const addStat = (p, isDynamic) => {
|
|
176
|
+
const top = p.split('/')[0] || p;
|
|
177
|
+
const stat = topLevelStats.get(top) || {
|
|
178
|
+
hasDynamic: false,
|
|
179
|
+
hasStatic: false
|
|
180
|
+
};
|
|
181
|
+
if (isDynamic)
|
|
182
|
+
stat.hasDynamic = true;
|
|
183
|
+
else
|
|
184
|
+
stat.hasStatic = true;
|
|
185
|
+
topLevelStats.set(top, stat);
|
|
186
|
+
};
|
|
187
|
+
dynamicPaths.forEach((p) => addStat(p, true));
|
|
188
|
+
shownStatic.forEach((p) => addStat(p, false));
|
|
189
|
+
const dynamicMarker = chalk.bold.yellowBright(' (dynamic)');
|
|
190
|
+
const staticMarker = chalk.bold.greenBright(' (static)');
|
|
191
|
+
const decorateTopLevel = (name) => {
|
|
192
|
+
const stat = topLevelStats.get(name);
|
|
193
|
+
if (!stat)
|
|
194
|
+
return name;
|
|
195
|
+
if (stat.hasDynamic && stat.hasStatic) {
|
|
196
|
+
return `${name}${dynamicMarker}${staticMarker}`;
|
|
197
|
+
}
|
|
198
|
+
if (stat.hasDynamic)
|
|
199
|
+
return `${name}${dynamicMarker}`;
|
|
200
|
+
if (stat.hasStatic)
|
|
201
|
+
return `${name}${staticMarker}`;
|
|
202
|
+
return name;
|
|
203
|
+
};
|
|
204
|
+
const combined = [...dynamicPaths, ...shownStatic];
|
|
205
|
+
const treeLines = buildTree(combined, decorateTopLevel);
|
|
206
|
+
for (const line of treeLines) {
|
|
207
|
+
logger.log(line);
|
|
208
|
+
}
|
|
209
|
+
if (omitted > 0) {
|
|
210
|
+
const note = chalk.gray(`Only show the first ${LIMIT} static files, omitted ${omitted} files`);
|
|
211
|
+
logger.log(note);
|
|
212
|
+
}
|
|
213
|
+
logger.block();
|
|
214
|
+
const projectConfig = getProjectConfig(projectPath);
|
|
215
|
+
const notFoundStrategy = normalizeNotFoundStrategy((_a = projectConfig === null || projectConfig === void 0 ? void 0 : projectConfig.assets) === null || _a === void 0 ? void 0 : _a.notFoundStrategy);
|
|
216
|
+
logger.startSubStep('Generating code version');
|
|
217
|
+
const requestParams = {
|
|
218
|
+
Name: projectName,
|
|
219
|
+
CodeDescription: description,
|
|
220
|
+
ExtraInfo: JSON.stringify({ Source: 'CLI' })
|
|
221
|
+
};
|
|
222
|
+
if (notFoundStrategy) {
|
|
223
|
+
requestParams.ConfOptions = {
|
|
224
|
+
NotFoundStrategy: notFoundStrategy
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
const res = yield commitRoutineWithAssets(requestParams, zip === null || zip === void 0 ? void 0 : zip.toBuffer());
|
|
228
|
+
if (res === null || res === void 0 ? void 0 : res.isSuccess) {
|
|
229
|
+
return {
|
|
230
|
+
isSuccess: true,
|
|
231
|
+
res: res === null || res === void 0 ? void 0 : res.res
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
else {
|
|
235
|
+
return {
|
|
236
|
+
isSuccess: false,
|
|
237
|
+
res: null
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* 根据 env 在一个或多个环境部署
|
|
244
|
+
*/
|
|
245
|
+
export function deployToEnvironments(name, codeVersion, env) {
|
|
246
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
247
|
+
if (env === 'all') {
|
|
248
|
+
const isStagingSuccess = yield deployCodeVersion(name, codeVersion, 'staging');
|
|
249
|
+
const isProdSuccess = yield deployCodeVersion(name, codeVersion, 'production');
|
|
250
|
+
return isStagingSuccess && isProdSuccess;
|
|
251
|
+
}
|
|
252
|
+
return yield deployCodeVersion(name, codeVersion, env);
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* 通用的快速部署函数
|
|
257
|
+
* 结合了压缩、提交和部署的完整流程
|
|
258
|
+
*/
|
|
259
|
+
export function commitAndDeployVersion(projectName_1, scriptEntry_1, assets_1) {
|
|
260
|
+
return __awaiter(this, arguments, void 0, function* (projectName, scriptEntry, assets, description = '', projectPath, env = 'production', minify = false, version) {
|
|
261
|
+
var _a, _b, _c;
|
|
262
|
+
const projectInfo = yield validateAndInitializeProject(projectName, projectPath);
|
|
263
|
+
if (!projectInfo) {
|
|
264
|
+
return false;
|
|
265
|
+
}
|
|
266
|
+
const { projectConfig } = projectInfo;
|
|
267
|
+
// 2) Use existing version or generate a new one
|
|
268
|
+
if (version) {
|
|
269
|
+
logger.startSubStep(`Using existing version ${version}`);
|
|
270
|
+
const deployed = yield deployToEnvironments(projectInfo.projectName, version, env);
|
|
271
|
+
logger.endSubStep(deployed ? 'Deploy finished' : 'Deploy failed');
|
|
272
|
+
return deployed;
|
|
273
|
+
}
|
|
274
|
+
const res = yield generateCodeVersion(projectInfo.projectName, 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);
|
|
275
|
+
const isCommitSuccess = res === null || res === void 0 ? void 0 : res.isSuccess;
|
|
276
|
+
if (!isCommitSuccess) {
|
|
277
|
+
logger.endSubStep('Generate version failed');
|
|
278
|
+
return false;
|
|
279
|
+
}
|
|
280
|
+
const codeVersion = (_c = (_b = res === null || res === void 0 ? void 0 : res.res) === null || _b === void 0 ? void 0 : _b.data) === null || _c === void 0 ? void 0 : _c.CodeVersion;
|
|
281
|
+
if (!codeVersion) {
|
|
282
|
+
logger.endSubStep('Missing CodeVersion in response');
|
|
283
|
+
return false;
|
|
284
|
+
}
|
|
285
|
+
logger.endSubStep(`Version generated: ${codeVersion}`);
|
|
286
|
+
// 3) Deploy to specified environment(s)
|
|
287
|
+
const deployed = yield deployToEnvironments(projectInfo.projectName, codeVersion, env);
|
|
288
|
+
return deployed;
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* 通用的版本部署函数
|
|
293
|
+
*/
|
|
294
|
+
export function deployCodeVersion(name, codeVersion, environment) {
|
|
295
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
296
|
+
const server = yield ApiService.getInstance();
|
|
297
|
+
// Ensure the committed code version is ready before deploying
|
|
298
|
+
const isReady = yield waitForCodeVersionReady(name, codeVersion, environment);
|
|
299
|
+
if (!isReady) {
|
|
300
|
+
logger.error('The code version is not ready for deployment.');
|
|
301
|
+
return false;
|
|
302
|
+
}
|
|
303
|
+
const res = yield server.createRoutineCodeDeployment({
|
|
304
|
+
Name: name,
|
|
305
|
+
CodeVersions: [{ Percentage: 100, CodeVersion: codeVersion }],
|
|
306
|
+
Strategy: 'percentage',
|
|
307
|
+
Env: environment
|
|
308
|
+
});
|
|
309
|
+
if (res) {
|
|
310
|
+
return true;
|
|
311
|
+
}
|
|
312
|
+
else {
|
|
313
|
+
return false;
|
|
314
|
+
}
|
|
315
|
+
});
|
|
316
|
+
}
|
|
317
|
+
/**
|
|
318
|
+
* Poll routine code version status until it becomes ready
|
|
319
|
+
*/
|
|
320
|
+
export function waitForCodeVersionReady(name_1, codeVersion_1, env_1) {
|
|
321
|
+
return __awaiter(this, arguments, void 0, function* (name, codeVersion, env, timeoutMs = 5 * 60 * 1000, intervalMs = 1000) {
|
|
322
|
+
var _a, _b;
|
|
323
|
+
if (!name || !codeVersion) {
|
|
324
|
+
return false;
|
|
325
|
+
}
|
|
326
|
+
const server = yield ApiService.getInstance();
|
|
327
|
+
const start = Date.now();
|
|
328
|
+
logger.startSubStep(`Waiting for code version ${codeVersion} to be ready...`);
|
|
329
|
+
while (Date.now() - start < timeoutMs) {
|
|
330
|
+
try {
|
|
331
|
+
const info = yield server.getRoutineCodeVersionInfo({
|
|
332
|
+
Name: name,
|
|
333
|
+
CodeVersion: codeVersion
|
|
334
|
+
});
|
|
335
|
+
const status = (_b = (_a = info === null || info === void 0 ? void 0 : info.data) === null || _a === void 0 ? void 0 : _a.Status) === null || _b === void 0 ? void 0 : _b.toLowerCase();
|
|
336
|
+
if (status === 'init') {
|
|
337
|
+
yield sleep(intervalMs);
|
|
338
|
+
continue;
|
|
339
|
+
}
|
|
340
|
+
else if (status === 'available') {
|
|
341
|
+
logger.endSubStep(`Code version ${chalk.cyan(codeVersion)} is deployed to ${env}.`);
|
|
342
|
+
return true;
|
|
343
|
+
}
|
|
344
|
+
else {
|
|
345
|
+
logger.error(`Code version ${chalk.cyan(codeVersion)} build ${status}.`);
|
|
346
|
+
return false;
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
catch (e) {
|
|
350
|
+
// swallow and retry until timeout
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
logger.error(`⏰ Waiting for code version ${chalk.cyan(codeVersion)} timed out.`);
|
|
354
|
+
return false;
|
|
355
|
+
});
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* 通用的部署成功显示函数
|
|
359
|
+
* 显示部署成功信息、访问链接和后续操作指南
|
|
360
|
+
*/
|
|
361
|
+
export function displayDeploySuccess(projectName_1) {
|
|
362
|
+
return __awaiter(this, arguments, void 0, function* (projectName, showDomainGuide = true, showRouteGuide = true) {
|
|
363
|
+
var _a;
|
|
364
|
+
const service = yield ApiService.getInstance();
|
|
365
|
+
const res = yield service.getRoutine({ Name: projectName });
|
|
366
|
+
const defaultUrl = (_a = res === null || res === void 0 ? void 0 : res.data) === null || _a === void 0 ? void 0 : _a.DefaultRelatedRecord;
|
|
367
|
+
const visitUrl = defaultUrl ? 'https://' + defaultUrl : '';
|
|
368
|
+
const accent = chalk.hex('#7C3AED');
|
|
369
|
+
const label = chalk.hex('#22c55e');
|
|
370
|
+
const subtle = chalk.gray;
|
|
371
|
+
const title = `${chalk.bold('🚀 ')}${chalk.bold(t('init_deploy_success').d('Deploy Success'))}`;
|
|
372
|
+
const lineUrl = `${label('URL')} ${visitUrl ? chalk.yellowBright(visitUrl) : subtle('-')}`;
|
|
373
|
+
const lineProject = `${label('APP')} ${chalk.cyan(projectName || '-')}`;
|
|
374
|
+
const lineCd = projectName
|
|
375
|
+
? `${label('TIP')} ${t('deploy_success_cd').d('Enter project directory')}: ${chalk.green(`cd ${projectName}`)}`
|
|
376
|
+
: '';
|
|
377
|
+
const guides = [];
|
|
378
|
+
if (showDomainGuide) {
|
|
379
|
+
guides.push(`${label('TIP')} ${t('deploy_success_guide').d('Add a custom domain')}: ${chalk.green('esa domain add <DOMAIN>')}`);
|
|
380
|
+
}
|
|
381
|
+
if (showRouteGuide) {
|
|
382
|
+
guides.push(`${label('TIP')} ${t('deploy_success_guide_2').d('Add routes for a site')}: ${chalk.green('esa route add -r <ROUTE> -s <SITE>')}`);
|
|
383
|
+
}
|
|
384
|
+
const tip = `${subtle(t('deploy_url_warn').d('The domain may take some time to take effect, please try again later.'))}`;
|
|
385
|
+
const lines = [
|
|
386
|
+
accent(title),
|
|
387
|
+
'',
|
|
388
|
+
lineProject,
|
|
389
|
+
lineUrl,
|
|
390
|
+
lineCd ? '' : '',
|
|
391
|
+
lineCd || '',
|
|
392
|
+
guides.length ? '' : '',
|
|
393
|
+
...guides,
|
|
394
|
+
guides.length ? '' : '',
|
|
395
|
+
tip
|
|
396
|
+
];
|
|
397
|
+
const stripAnsi = (s) => s.replace(/\x1B\[[0-?]*[ -\/]*[@-~]/g, '');
|
|
398
|
+
const contentWidth = Math.max(...lines.map((l) => stripAnsi(l).length));
|
|
399
|
+
const borderColor = chalk.hex('#00D4FF').bold;
|
|
400
|
+
const top = `${borderColor('╔')}${borderColor('═'.repeat(contentWidth + 2))}${borderColor('╗')}`;
|
|
401
|
+
const bottom = `${borderColor('╚')}${borderColor('═'.repeat(contentWidth + 2))}${borderColor('╝')}`;
|
|
402
|
+
const boxLines = [
|
|
403
|
+
top,
|
|
404
|
+
...lines.map((l) => {
|
|
405
|
+
const pad = ' '.repeat(contentWidth - stripAnsi(l).length);
|
|
406
|
+
const left = borderColor('║');
|
|
407
|
+
const right = borderColor('║');
|
|
408
|
+
return `${left} ${l}${pad} ${right}`;
|
|
409
|
+
}),
|
|
410
|
+
bottom
|
|
411
|
+
];
|
|
412
|
+
logger.block();
|
|
413
|
+
boxLines.forEach((l) => logger.log(l));
|
|
414
|
+
logger.block();
|
|
415
|
+
});
|
|
416
|
+
}
|
package/dist/commands/config.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
2
|
import spawn from 'cross-spawn';
|
|
3
|
-
import { projectConfigPath, cliConfigPath } from '../utils/fileUtils/index.js';
|
|
4
3
|
import t from '../i18n/index.js';
|
|
5
4
|
import logger from '../libs/logger.js';
|
|
5
|
+
import { projectConfigPath, cliConfigPath } from '../utils/fileUtils/index.js';
|
|
6
6
|
const editConfigFile = (configPath) => {
|
|
7
7
|
const editor = process.env.EDITOR || 'vi';
|
|
8
8
|
spawn(editor, [configPath], {
|