esa-cli 0.0.2-beta.20 → 0.0.2-beta.21
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 +1 -6
- package/dist/commands/common/utils.js +87 -84
- package/dist/commands/deploy/index.js +0 -1
- package/dist/commands/deployments/delete.js +2 -2
- package/dist/commands/deployments/index.js +1 -1
- package/dist/commands/dev/ew2/devPack.js +9 -9
- package/dist/commands/dev/ew2/kvService.js +20 -1
- package/dist/commands/dev/ew2/mock/kv.js +3 -3
- package/dist/commands/dev/ew2/server.js +2 -1
- package/dist/commands/dev/index.js +1 -1
- package/dist/commands/dev/mockWorker/devPack.js +3 -3
- package/dist/commands/domain/add.js +1 -1
- package/dist/commands/domain/index.js +1 -1
- package/dist/commands/init/helper.js +9 -7
- package/dist/commands/init/template.jsonc +1 -1
- package/dist/commands/logout.js +1 -1
- package/dist/commands/route/add.js +54 -21
- package/dist/commands/route/helper.js +10 -9
- package/dist/commands/route/index.js +1 -1
- package/dist/commands/routine/index.js +1 -1
- package/dist/commands/routine/list.js +20 -38
- package/dist/commands/site/index.js +1 -1
- package/dist/commands/utils.js +4 -4
- package/dist/components/filterSelector.js +1 -1
- package/dist/i18n/locales.json +4 -36
- package/dist/libs/apiService.js +6 -7
- package/dist/libs/logger.js +4 -4
- package/dist/utils/checkIsRoutineCreated.js +1 -1
- package/dist/utils/compress.js +5 -5
- package/dist/utils/download.js +2 -2
- package/dist/utils/fileUtils/index.js +18 -69
- package/package.json +2 -1
- package/dist/components/routeBuilder.js +0 -68
|
@@ -16,7 +16,7 @@ import promptParameter from '../../utils/prompt.js';
|
|
|
16
16
|
import { validateAndInitializeProject, generateCodeVersion } from '../common/utils.js';
|
|
17
17
|
const commit = {
|
|
18
18
|
command: 'commit [entry]',
|
|
19
|
-
describe:
|
|
19
|
+
describe: `📦 ${t('commit_describe').d('Commit your code, save as a new version')}`,
|
|
20
20
|
builder: (yargs) => {
|
|
21
21
|
return yargs
|
|
22
22
|
.option('minify', {
|
|
@@ -69,11 +69,6 @@ export function handleCommit(argv) {
|
|
|
69
69
|
}
|
|
70
70
|
logger.startSubStep('Generating code version');
|
|
71
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);
|
|
76
|
-
}
|
|
77
72
|
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
73
|
if (!codeVersion) {
|
|
79
74
|
logger.endSubStep('Missing CodeVersion in response');
|
|
@@ -120,97 +120,100 @@ export function generateCodeVersion(projectName_1, description_1, entry_1, asset
|
|
|
120
120
|
return __awaiter(this, arguments, void 0, function* (projectName, description, entry, assets, minify = false, projectPath) {
|
|
121
121
|
var _a;
|
|
122
122
|
const { zip, sourceList, dynamicSources } = yield compress(entry, assets, minify, projectPath);
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
const
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
const
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
node.children.
|
|
123
|
+
try {
|
|
124
|
+
// Pretty print upload directory tree
|
|
125
|
+
const buildTree = (paths, decorateTopLevel) => {
|
|
126
|
+
const root = { children: new Map(), isFile: false };
|
|
127
|
+
const sorted = [...paths].sort((a, b) => a.localeCompare(b));
|
|
128
|
+
for (const p of sorted) {
|
|
129
|
+
const parts = p.split('/').filter(Boolean);
|
|
130
|
+
let node = root;
|
|
131
|
+
for (let i = 0; i < parts.length; i++) {
|
|
132
|
+
const part = parts[i];
|
|
133
|
+
if (!node.children.has(part)) {
|
|
134
|
+
node.children.set(part, { children: new Map(), isFile: false });
|
|
135
|
+
}
|
|
136
|
+
const child = node.children.get(part);
|
|
137
|
+
if (i === parts.length - 1)
|
|
138
|
+
child.isFile = true;
|
|
139
|
+
node = child;
|
|
134
140
|
}
|
|
135
|
-
const child = node.children.get(part);
|
|
136
|
-
if (i === parts.length - 1)
|
|
137
|
-
child.isFile = true;
|
|
138
|
-
node = child;
|
|
139
141
|
}
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
}
|
|
142
|
+
const lines = [];
|
|
143
|
+
const render = (node, prefix, depth) => {
|
|
144
|
+
const entries = [...node.children.entries()];
|
|
145
|
+
entries.forEach(([_name, _child], idx) => {
|
|
146
|
+
const isLast = idx === entries.length - 1;
|
|
147
|
+
const connector = isLast ? '└ ' : '├ ';
|
|
148
|
+
const nextPrefix = prefix + (isLast ? ' ' : '│ ');
|
|
149
|
+
const displayName = depth === 0 ? decorateTopLevel(_name) : _name;
|
|
150
|
+
lines.push(prefix + connector + displayName);
|
|
151
|
+
render(_child, nextPrefix, depth + 1);
|
|
152
|
+
});
|
|
153
|
+
};
|
|
154
|
+
render(root, '', 0);
|
|
155
|
+
return lines.length ? lines : ['-'];
|
|
152
156
|
};
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
.
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
157
|
+
const header = chalk.hex('#22c55e')('UPLOAD') + ' Files to be uploaded (source paths)';
|
|
158
|
+
logger.block();
|
|
159
|
+
logger.log(header);
|
|
160
|
+
const dynamicSet = new Set(dynamicSources);
|
|
161
|
+
const LIMIT = 300;
|
|
162
|
+
const staticPaths = sourceList
|
|
163
|
+
.filter((p) => !dynamicSet.has(p))
|
|
164
|
+
.sort((a, b) => a.localeCompare(b));
|
|
165
|
+
const dynamicPaths = sourceList
|
|
166
|
+
.filter((p) => dynamicSet.has(p))
|
|
167
|
+
.sort((a, b) => a.localeCompare(b));
|
|
168
|
+
let omitted = 0;
|
|
169
|
+
let shownStatic = staticPaths;
|
|
170
|
+
if (staticPaths.length > LIMIT) {
|
|
171
|
+
shownStatic = staticPaths.slice(0, LIMIT);
|
|
172
|
+
omitted = staticPaths.length - LIMIT;
|
|
173
|
+
}
|
|
174
|
+
// Compute top-level markers based on whether a top-level bucket contains dynamic/static files
|
|
175
|
+
const topLevelStats = new Map();
|
|
176
|
+
const addStat = (p, isDynamic) => {
|
|
177
|
+
const top = p.split('/')[0] || p;
|
|
178
|
+
const stat = topLevelStats.get(top) || {
|
|
179
|
+
hasDynamic: false,
|
|
180
|
+
hasStatic: false
|
|
181
|
+
};
|
|
182
|
+
if (isDynamic)
|
|
183
|
+
stat.hasDynamic = true;
|
|
184
|
+
else
|
|
185
|
+
stat.hasStatic = true;
|
|
186
|
+
topLevelStats.set(top, stat);
|
|
180
187
|
};
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
188
|
+
dynamicPaths.forEach((p) => addStat(p, true));
|
|
189
|
+
shownStatic.forEach((p) => addStat(p, false));
|
|
190
|
+
const dynamicMarker = chalk.bold.yellowBright(' (dynamic)');
|
|
191
|
+
const staticMarker = chalk.bold.greenBright(' (static)');
|
|
192
|
+
const decorateTopLevel = (name) => {
|
|
193
|
+
const stat = topLevelStats.get(name);
|
|
194
|
+
if (!stat)
|
|
195
|
+
return name;
|
|
196
|
+
if (stat.hasDynamic && stat.hasStatic) {
|
|
197
|
+
return `${name}${dynamicMarker}${staticMarker}`;
|
|
198
|
+
}
|
|
199
|
+
if (stat.hasDynamic)
|
|
200
|
+
return `${name}${dynamicMarker}`;
|
|
201
|
+
if (stat.hasStatic)
|
|
202
|
+
return `${name}${staticMarker}`;
|
|
194
203
|
return name;
|
|
195
|
-
|
|
196
|
-
|
|
204
|
+
};
|
|
205
|
+
const combined = [...dynamicPaths, ...shownStatic];
|
|
206
|
+
const treeLines = buildTree(combined, decorateTopLevel);
|
|
207
|
+
for (const line of treeLines) {
|
|
208
|
+
logger.log(line);
|
|
197
209
|
}
|
|
198
|
-
if (
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
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);
|
|
210
|
+
if (omitted > 0) {
|
|
211
|
+
const note = chalk.gray(`仅展示前 ${LIMIT} 个静态文件,已省略 ${omitted} 个`);
|
|
212
|
+
logger.log(note);
|
|
213
|
+
}
|
|
214
|
+
logger.block();
|
|
212
215
|
}
|
|
213
|
-
|
|
216
|
+
catch (_b) { }
|
|
214
217
|
const projectConfig = getProjectConfig(projectPath);
|
|
215
218
|
const notFoundStrategy = normalizeNotFoundStrategy((_a = projectConfig === null || projectConfig === void 0 ? void 0 : projectConfig.assets) === null || _a === void 0 ? void 0 : _a.notFoundStrategy);
|
|
216
219
|
logger.startSubStep('Generating code version');
|
|
@@ -52,7 +52,7 @@ export function handleDeleteDeployments(argv) {
|
|
|
52
52
|
const isInteractive = argv.i;
|
|
53
53
|
if (isInteractive) {
|
|
54
54
|
const { allVersions, stagingVersions, productionVersions } = yield getRoutineCodeVersions(projectConfig.name);
|
|
55
|
-
//
|
|
55
|
+
// 显示正在部署的版本信息
|
|
56
56
|
if (stagingVersions.length > 0 || productionVersions.length > 0) {
|
|
57
57
|
logger.log(chalk.yellow('⚠️ Currently deploying versions:'));
|
|
58
58
|
if (stagingVersions.length > 0) {
|
|
@@ -64,7 +64,7 @@ export function handleDeleteDeployments(argv) {
|
|
|
64
64
|
logger.log('');
|
|
65
65
|
}
|
|
66
66
|
logger.log(t('delete_deployments_table_title').d(' Version ID Description'));
|
|
67
|
-
//
|
|
67
|
+
// 过滤掉正在部署的版本
|
|
68
68
|
const selectList = allVersions
|
|
69
69
|
.filter((item) => {
|
|
70
70
|
var _a, _b;
|
|
@@ -4,7 +4,7 @@ import deploymentsList from './list.js';
|
|
|
4
4
|
let yargsIns;
|
|
5
5
|
const deploymentsCommand = {
|
|
6
6
|
command: 'deployments [script]',
|
|
7
|
-
describe:
|
|
7
|
+
describe: `📜 ${t('deployments_describe').d('Manage your deployments')}`,
|
|
8
8
|
builder: (yargs) => {
|
|
9
9
|
yargsIns = yargs;
|
|
10
10
|
return yargs
|
|
@@ -16,7 +16,7 @@ import { getRoot, getDirName } from '../../../utils/fileUtils/base.js';
|
|
|
16
16
|
import { getDevConf } from '../../../utils/fileUtils/index.js';
|
|
17
17
|
import { EW2Path } from '../../../utils/installEw2.js';
|
|
18
18
|
import devBuild from '../build.js';
|
|
19
|
-
//
|
|
19
|
+
// 生成可用的Ew2端口
|
|
20
20
|
const generateEw2Port = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
21
21
|
let ew2port = 3322;
|
|
22
22
|
let portAvailable = yield checkPort(ew2port);
|
|
@@ -60,7 +60,7 @@ conf_path = "${erConfPath}"
|
|
|
60
60
|
fs.promises.writeFile(erConfPath, erConf)
|
|
61
61
|
]);
|
|
62
62
|
};
|
|
63
|
-
//
|
|
63
|
+
// 生成入口文件
|
|
64
64
|
const generateEntry = (id, projectEntry, userRoot, port) => __awaiter(void 0, void 0, void 0, function* () {
|
|
65
65
|
const __dirname = getDirName(import.meta.url);
|
|
66
66
|
const devDir = path.resolve(userRoot, '.dev');
|
|
@@ -85,20 +85,20 @@ const generateEntry = (id, projectEntry, userRoot, port) => __awaiter(void 0, vo
|
|
|
85
85
|
.replace(/'\$userPath'/g, `'${projectEntry.replace(/\\/g, '/')}'`)
|
|
86
86
|
.replace(/\$userPort/g, `${port}`));
|
|
87
87
|
});
|
|
88
|
-
//
|
|
88
|
+
// 前期准备
|
|
89
89
|
const prepare = (configPath, entry, port, localUpstream, userRoot) => __awaiter(void 0, void 0, void 0, function* () {
|
|
90
90
|
const options = {};
|
|
91
91
|
const currentOptions = { entry, port, localUpstream };
|
|
92
|
-
//
|
|
92
|
+
// 支持同时跑多个 worker
|
|
93
93
|
const id = new Date().getTime().toString();
|
|
94
94
|
// @ts-ignore
|
|
95
95
|
global.id = id;
|
|
96
|
-
//
|
|
96
|
+
// 生成入口文件
|
|
97
97
|
yield generateEntry(id, entry, userRoot, port);
|
|
98
|
-
//
|
|
98
|
+
// 生成 Ew2 配置
|
|
99
99
|
const ew2port = yield generateEw2Port();
|
|
100
100
|
yield writeEw2config(id, ew2port, userRoot);
|
|
101
|
-
//
|
|
101
|
+
// 给每一次 dev 的配置项,在一个文件中通过 id 区分
|
|
102
102
|
if (fs.existsSync(configPath)) {
|
|
103
103
|
const currentConfig = fs
|
|
104
104
|
.readFileSync(configPath, 'utf-8')
|
|
@@ -106,7 +106,7 @@ const prepare = (configPath, entry, port, localUpstream, userRoot) => __awaiter(
|
|
|
106
106
|
const currentConfigObj = JSON.parse(currentConfig);
|
|
107
107
|
const currentIds = Object.keys(currentConfigObj);
|
|
108
108
|
if (currentIds[0] && /^\d+$/.test(currentIds[0])) {
|
|
109
|
-
//
|
|
109
|
+
// 删除没有用到的入口
|
|
110
110
|
for (let currentId of currentIds) {
|
|
111
111
|
const unused = yield checkPort(currentConfigObj[currentId].port);
|
|
112
112
|
if (unused) {
|
|
@@ -155,7 +155,7 @@ const devPack = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
|
155
155
|
}
|
|
156
156
|
else {
|
|
157
157
|
logger.notInProject();
|
|
158
|
-
process.exit(
|
|
158
|
+
process.exit(0);
|
|
159
159
|
}
|
|
160
160
|
return prepare(path.resolve(userRoot, '.dev/devConfig.js'), projectEntry, port, localUpstream, userRoot)
|
|
161
161
|
.then(() => {
|
|
@@ -1,5 +1,24 @@
|
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import fs from 'fs';
|
|
3
|
+
import { getRoot } from '../../../utils/fileUtils/base.js';
|
|
4
|
+
import t from '../../../i18n/index.js';
|
|
1
5
|
class EdgeKV {
|
|
2
|
-
constructor() {
|
|
6
|
+
constructor() {
|
|
7
|
+
const root = getRoot();
|
|
8
|
+
const kvPath = path.join(root, 'kv.json');
|
|
9
|
+
if (fs.existsSync(kvPath)) {
|
|
10
|
+
try {
|
|
11
|
+
const kvJson = fs.readFileSync(kvPath, 'utf8');
|
|
12
|
+
const kvJsonObj = JSON.parse(kvJson);
|
|
13
|
+
Object.keys(kvJsonObj).forEach((namespace) => {
|
|
14
|
+
EdgeKV.store.set(namespace, new Map(Object.entries(kvJsonObj[namespace])));
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
catch (err) {
|
|
18
|
+
console.log(t('kv_parse_failed').d('kv.json parse failed, use empty local kv store.'));
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
3
22
|
get(key, namespace) {
|
|
4
23
|
const store = EdgeKV.store.get(namespace);
|
|
5
24
|
if (!store || !store.has(key)) {
|
|
@@ -103,7 +103,7 @@ class EdgeKV {
|
|
|
103
103
|
headers: { 'Content-Type': 'application/json' }
|
|
104
104
|
}
|
|
105
105
|
);
|
|
106
|
-
//
|
|
106
|
+
// 判断是否存在key
|
|
107
107
|
let isGetFailed = false;
|
|
108
108
|
fetchRes.headers.forEach((v, k) => {
|
|
109
109
|
if (k === 'kv-get-empty') {
|
|
@@ -134,10 +134,10 @@ class EdgeKV {
|
|
|
134
134
|
);
|
|
135
135
|
}
|
|
136
136
|
case 'stream':
|
|
137
|
-
const
|
|
137
|
+
const value = await fetchRes.text();
|
|
138
138
|
return new ReadableStream({
|
|
139
139
|
start(controller) {
|
|
140
|
-
controller.enqueue(new TextEncoder().encode(
|
|
140
|
+
controller.enqueue(new TextEncoder().encode(value));
|
|
141
141
|
controller.close();
|
|
142
142
|
}
|
|
143
143
|
});
|
|
@@ -187,7 +187,7 @@ class Ew2Server {
|
|
|
187
187
|
agent: new HttpProxyAgent(`http://127.0.0.1:${ew2Port}`)
|
|
188
188
|
});
|
|
189
189
|
const workerHeaders = Object.fromEntries(workerRes.headers.entries());
|
|
190
|
-
//
|
|
190
|
+
// 解决 gzip 兼容性问题,防止net::ERR_CONTENT_DECODING_FAILED
|
|
191
191
|
workerHeaders['content-encoding'] = 'identity';
|
|
192
192
|
if (workerRes.body) {
|
|
193
193
|
res.writeHead(workerRes.status, workerHeaders);
|
|
@@ -236,6 +236,7 @@ class Ew2Server {
|
|
|
236
236
|
const key = url.searchParams.get('key');
|
|
237
237
|
const namespace = url.searchParams.get('namespace');
|
|
238
238
|
const body = yield this.parseKVBody(req);
|
|
239
|
+
console.log(body);
|
|
239
240
|
if (!key || !namespace) {
|
|
240
241
|
return {
|
|
241
242
|
success: false
|
|
@@ -40,12 +40,12 @@ const generateEntry = (id, projectEntry, userRoot) => __awaiter(void 0, void 0,
|
|
|
40
40
|
const prepare = (configPath, entry, port, localUpstream, userRoot) => __awaiter(void 0, void 0, void 0, function* () {
|
|
41
41
|
const options = {};
|
|
42
42
|
const currentOptions = { entry, port, localUpstream };
|
|
43
|
-
//
|
|
43
|
+
// 支持同时跑多个 deno
|
|
44
44
|
const id = new Date().getTime().toString();
|
|
45
45
|
// @ts-ignore
|
|
46
46
|
global.id = id;
|
|
47
47
|
yield generateEntry(id, entry, userRoot);
|
|
48
|
-
//
|
|
48
|
+
// 给每一次 dev 的配置项,在一个文件中通过 id 区分
|
|
49
49
|
if (fs.existsSync(configPath)) {
|
|
50
50
|
const currentConfig = fs
|
|
51
51
|
.readFileSync(configPath, 'utf-8')
|
|
@@ -101,7 +101,7 @@ const devPack = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
|
101
101
|
}
|
|
102
102
|
else {
|
|
103
103
|
logger.notInProject();
|
|
104
|
-
process.exit(
|
|
104
|
+
process.exit(0);
|
|
105
105
|
}
|
|
106
106
|
return prepare(path.resolve(userRoot, '.dev/devConfig.js'), projectEntry, port, localUpstream, userRoot)
|
|
107
107
|
.then(() => {
|
|
@@ -14,7 +14,7 @@ import { getProjectConfig } from '../../utils/fileUtils/index.js';
|
|
|
14
14
|
import { bindRoutineWithDomain, checkDirectory, checkIsLoginSuccess, validDomain, validName } from '../utils.js';
|
|
15
15
|
const addDomain = {
|
|
16
16
|
command: 'add <domain>',
|
|
17
|
-
describe:
|
|
17
|
+
describe: `🔗 ${t('domain_add_describe').d('Bind a domain to a routine')}`,
|
|
18
18
|
builder: (yargs) => {
|
|
19
19
|
return yargs
|
|
20
20
|
.positional('domain', {
|
|
@@ -5,7 +5,7 @@ import listDomain from './list.js';
|
|
|
5
5
|
let yargsIns;
|
|
6
6
|
const domainCommand = {
|
|
7
7
|
command: 'domain [script]',
|
|
8
|
-
describe:
|
|
8
|
+
describe: `🔗 ${t('domain_describe').d('Manage the domain names bound to your routine')}`,
|
|
9
9
|
builder: (yargs) => {
|
|
10
10
|
yargsIns = yargs;
|
|
11
11
|
return yargs
|
|
@@ -100,7 +100,7 @@ export function checkAndUpdatePackage(packageName) {
|
|
|
100
100
|
const spinner = logger.ora;
|
|
101
101
|
spinner.text = t('checking_template_update').d('Checking esa-template updates...');
|
|
102
102
|
spinner.start();
|
|
103
|
-
//
|
|
103
|
+
// 获取当前安装的版本
|
|
104
104
|
const __dirname = getDirName(import.meta.url);
|
|
105
105
|
const packageJsonPath = path.join(__dirname, '../../../');
|
|
106
106
|
let versionInfo;
|
|
@@ -124,7 +124,7 @@ export function checkAndUpdatePackage(packageName) {
|
|
|
124
124
|
}
|
|
125
125
|
const match = versionInfo.match(new RegExp(`(${packageName})@([0-9.]+)`));
|
|
126
126
|
const currentVersion = match ? match[2] : '';
|
|
127
|
-
//
|
|
127
|
+
// 获取最新版本
|
|
128
128
|
const latestVersion = execSync(`npm view ${packageName} version`, {
|
|
129
129
|
cwd: packageJsonPath
|
|
130
130
|
})
|
|
@@ -173,10 +173,11 @@ export function checkAndUpdatePackage(packageName) {
|
|
|
173
173
|
});
|
|
174
174
|
}
|
|
175
175
|
export const getFrameworkConfig = (framework) => {
|
|
176
|
-
//
|
|
176
|
+
// 从init目录读取template.jsonc
|
|
177
177
|
const templatePath = path.join(getDirName(import.meta.url), 'template.jsonc');
|
|
178
178
|
const jsonc = fs.readFileSync(templatePath, 'utf-8');
|
|
179
179
|
const json = JSON.parse(jsonc);
|
|
180
|
+
console.log(json);
|
|
180
181
|
return json[framework];
|
|
181
182
|
};
|
|
182
183
|
/**
|
|
@@ -184,7 +185,7 @@ export const getFrameworkConfig = (framework) => {
|
|
|
184
185
|
* @returns 框架全部配置
|
|
185
186
|
*/
|
|
186
187
|
export const getAllFrameworkConfig = () => {
|
|
187
|
-
//
|
|
188
|
+
// 从init目录读取template.jsonc
|
|
188
189
|
const templatePath = path.join(getDirName(import.meta.url), 'template.jsonc');
|
|
189
190
|
const jsonc = fs.readFileSync(templatePath, 'utf-8');
|
|
190
191
|
const json = JSON.parse(jsonc);
|
|
@@ -231,7 +232,7 @@ export function getInitParamsFromArgv(argv) {
|
|
|
231
232
|
params.deploy = Boolean(a.deploy);
|
|
232
233
|
return params;
|
|
233
234
|
}
|
|
234
|
-
//
|
|
235
|
+
// 配置项目名称
|
|
235
236
|
export const configProjectName = (initParams) => __awaiter(void 0, void 0, void 0, function* () {
|
|
236
237
|
if (initParams.name) {
|
|
237
238
|
log.step(`Project name configured ${initParams.name}`);
|
|
@@ -592,7 +593,7 @@ export const initGit = (initParams) => __awaiter(void 0, void 0, void 0, functio
|
|
|
592
593
|
export function getGitVersion() {
|
|
593
594
|
return __awaiter(this, void 0, void 0, function* () {
|
|
594
595
|
try {
|
|
595
|
-
|
|
596
|
+
const stdout = yield execCommand(['git', '--version'], {
|
|
596
597
|
useSpinner: false,
|
|
597
598
|
silent: true,
|
|
598
599
|
captureOutput: true
|
|
@@ -608,7 +609,7 @@ export function getGitVersion() {
|
|
|
608
609
|
}
|
|
609
610
|
export function isGitInstalled() {
|
|
610
611
|
return __awaiter(this, void 0, void 0, function* () {
|
|
611
|
-
return (yield getGitVersion()) !==
|
|
612
|
+
return (yield getGitVersion()) !== null;
|
|
612
613
|
});
|
|
613
614
|
}
|
|
614
615
|
/**
|
|
@@ -684,6 +685,7 @@ function ensureGitignore(projectRoot, assetsDirectory) {
|
|
|
684
685
|
? `${existingContent.replace(/\n$/, '')}\n${toAppend.join('\n')}\n`
|
|
685
686
|
: `${toAppend.join('\n')}\n`;
|
|
686
687
|
fs.writeFileSync(gitignorePath, newContent, 'utf-8');
|
|
688
|
+
logger.log('Updated .gitignore');
|
|
687
689
|
}
|
|
688
690
|
catch (_a) {
|
|
689
691
|
// Do not fail init due to .gitignore issues
|
package/dist/commands/logout.js
CHANGED
|
@@ -12,7 +12,7 @@ import logger from '../libs/logger.js';
|
|
|
12
12
|
import { getCliConfig, updateCliConfigFile } from '../utils/fileUtils/index.js';
|
|
13
13
|
const logout = {
|
|
14
14
|
command: 'logout',
|
|
15
|
-
describe:
|
|
15
|
+
describe: `🚪 ${t('logout_describe').d('Logout')}`,
|
|
16
16
|
builder: (yargs) => {
|
|
17
17
|
return yargs;
|
|
18
18
|
},
|
|
@@ -14,11 +14,10 @@ import logger from '../../libs/logger.js';
|
|
|
14
14
|
import { validRoutine } from '../../utils/checkIsRoutineCreated.js';
|
|
15
15
|
import { getProjectConfig } from '../../utils/fileUtils/index.js';
|
|
16
16
|
import { checkDirectory, checkIsLoginSuccess } from '../utils.js';
|
|
17
|
-
import { routeBuilder } from '../../components/routeBuilder.js';
|
|
18
17
|
import { transferRouteToRuleString } from './helper.js';
|
|
19
18
|
const addRoute = {
|
|
20
|
-
command: 'add',
|
|
21
|
-
describe:
|
|
19
|
+
command: 'add [route] [site]',
|
|
20
|
+
describe: `🚄 ${t('route_add_describe').d('Bind a Route to a routine')}`,
|
|
22
21
|
builder: (yargs) => {
|
|
23
22
|
return yargs
|
|
24
23
|
.option('route', {
|
|
@@ -79,6 +78,7 @@ export function handlerAddRoute(argv) {
|
|
|
79
78
|
name: i.SiteName,
|
|
80
79
|
value: i.SiteId
|
|
81
80
|
}));
|
|
81
|
+
// 获取路由名称,支持直接通过参数传入
|
|
82
82
|
let routeName = argv.alias;
|
|
83
83
|
if (!routeName) {
|
|
84
84
|
const response = yield inquirer.prompt([
|
|
@@ -99,18 +99,35 @@ export function handlerAddRoute(argv) {
|
|
|
99
99
|
let siteName = argv.site;
|
|
100
100
|
let siteId;
|
|
101
101
|
if (!siteName) {
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
102
|
+
if (argv._.length > 2) {
|
|
103
|
+
siteName = argv._[2];
|
|
104
|
+
}
|
|
105
|
+
// 如果仍未提供站点名称,则提示选择
|
|
106
|
+
if (!siteName) {
|
|
107
|
+
const response = yield inquirer.prompt([
|
|
108
|
+
{
|
|
109
|
+
type: 'list',
|
|
110
|
+
name: 'routeSite',
|
|
111
|
+
message: t('create_route_site').d('Select a site that is active in your account:'),
|
|
112
|
+
choices: siteList
|
|
113
|
+
}
|
|
114
|
+
]);
|
|
115
|
+
siteId = response.routeSite;
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
// 根据站点名称查找对应的站点ID
|
|
119
|
+
const matchedSite = siteList.find((site) => site.name === siteName);
|
|
120
|
+
if (matchedSite) {
|
|
121
|
+
siteId = matchedSite.value;
|
|
108
122
|
}
|
|
109
|
-
|
|
110
|
-
|
|
123
|
+
else {
|
|
124
|
+
logger.error(t('site_not_found').d(`Site "${siteName}" not found in your account`));
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
111
128
|
}
|
|
112
129
|
else {
|
|
113
|
-
//
|
|
130
|
+
// 根据站点名称查找对应的站点ID
|
|
114
131
|
const matchedSite = siteList.find((site) => site.name === siteName);
|
|
115
132
|
if (matchedSite) {
|
|
116
133
|
siteId = matchedSite.value;
|
|
@@ -120,24 +137,40 @@ export function handlerAddRoute(argv) {
|
|
|
120
137
|
return;
|
|
121
138
|
}
|
|
122
139
|
}
|
|
140
|
+
// 获取路由值,支持直接通过参数传入
|
|
123
141
|
let inputRoute = argv.route;
|
|
124
142
|
if (!inputRoute) {
|
|
125
|
-
//
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
if (!
|
|
131
|
-
|
|
132
|
-
|
|
143
|
+
// 如果参数中提供了路由值,使用它
|
|
144
|
+
if (argv._.length > 1) {
|
|
145
|
+
inputRoute = argv._[1];
|
|
146
|
+
}
|
|
147
|
+
// 如果仍未提供路由值,则提示输入
|
|
148
|
+
if (!inputRoute) {
|
|
149
|
+
const response = yield inquirer.prompt([
|
|
150
|
+
{
|
|
151
|
+
type: 'input',
|
|
152
|
+
name: 'inputRoute',
|
|
153
|
+
message: t('create_route_route').d('Enter a Route (e.g., example.com/*):'),
|
|
154
|
+
validate: (input) => {
|
|
155
|
+
if (!input) {
|
|
156
|
+
return t('route_input_required').d('Route is required');
|
|
157
|
+
}
|
|
158
|
+
if (!input.includes('*') && !input.includes('/')) {
|
|
159
|
+
return t('route_format_invalid').d('Route format is invalid. Please include wildcard (*) or path (/)');
|
|
160
|
+
}
|
|
161
|
+
return true;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
]);
|
|
165
|
+
inputRoute = response.inputRoute;
|
|
133
166
|
}
|
|
134
|
-
inputRoute = builtRoute;
|
|
135
167
|
}
|
|
136
168
|
const rule = transferRouteToRuleString(inputRoute);
|
|
137
169
|
if (!rule) {
|
|
138
170
|
logger.error(t('route_format_invalid').d('Invalid route format'));
|
|
139
171
|
return;
|
|
140
172
|
}
|
|
173
|
+
// 获取站点名称用于显示
|
|
141
174
|
const selectedSite = siteList.find((site) => site.value === siteId);
|
|
142
175
|
const displaySiteName = selectedSite ? selectedSite.name : siteName;
|
|
143
176
|
const req = {
|