esa-cli 1.0.10 → 1.0.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +206 -22
- package/bin/enter.cjs +45 -12
- package/dist/bin/enter.cjs +45 -12
- package/dist/commands/commit/index.js +5 -4
- package/dist/commands/deployments/delete.js +1 -1
- package/dist/commands/deployments/list.js +1 -1
- package/dist/commands/dev/build.js +4 -1
- package/dist/commands/dev/doProcess.js +94 -36
- package/dist/commands/domain/add.js +1 -1
- package/dist/commands/domain/delete.js +2 -3
- package/dist/commands/domain/list.js +1 -1
- package/dist/commands/init/helper.js +12 -8
- package/dist/commands/init/index.js +3 -4
- package/dist/commands/login/index.js +9 -5
- package/dist/commands/logout.js +3 -3
- package/dist/commands/route/add.js +1 -1
- package/dist/commands/route/delete.js +1 -1
- package/dist/commands/route/list.js +1 -1
- package/dist/commands/routine/delete.js +1 -2
- package/dist/commands/routine/list.js +1 -1
- package/dist/commands/site/list.js +1 -1
- package/dist/commands/utils.js +9 -3
- package/dist/components/mutiSelectTable.js +16 -83
- package/dist/components/routeBuilder.js +30 -54
- package/dist/components/selectInput.js +27 -13
- package/dist/docs/Commands_en.md +14 -2
- package/dist/docs/Commands_zh_CN.md +11 -1
- package/dist/i18n/locales.json +1 -1
- package/dist/index.js +8 -3
- package/dist/libs/api.js +0 -8
- package/dist/libs/logger.js +7 -2
- package/dist/utils/fileMd5.js +13 -3
- package/dist/utils/fileUtils/base.js +14 -18
- package/dist/utils/fileUtils/index.js +20 -0
- package/package.json +18 -20
- package/zh_CN.md +2 -2
- package/dist/components/descriptionInput.js +0 -38
- package/dist/components/filterSelector.js +0 -132
- package/dist/components/selectItem.js +0 -6
- package/dist/components/yesNoPrompt.js +0 -9
package/README.md
CHANGED
|
@@ -1,6 +1,13 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Alibaba Cloud ESA CLI
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/esa-cli)
|
|
4
|
+
[](https://github.com/aliyun/alibabacloud-esa-cli/actions/workflows/main.yml)
|
|
5
|
+

|
|
6
|
+
[](https://www.typescriptlang.org)
|
|
7
|
+
|
|
8
|
+
ESA CLI is a command-line tool for building, developing, and deploying [Alibaba Cloud ESA](https://www.alibabacloud.com/help/en/edge-security-acceleration/esa/user-guide/what-is-er/) Functions & Pages projects.
|
|
9
|
+
|
|
10
|
+
It helps you create projects from templates, run Functions & Pages locally, package static assets and edge functions, publish code versions, deploy to staging or production, and manage domains, routes, and deployments from your terminal.
|
|
4
11
|
|
|
5
12
|
<p>
|
|
6
13
|
<a href="https://discord.gg/BxcRVEeh">
|
|
@@ -9,54 +16,231 @@ ESA CLI is a command-line tool for building with Alibaba Cloud ESA Functions and
|
|
|
9
16
|
<a href="https://discord.gg/SHYe5926" style="margin-left:8px;">
|
|
10
17
|
<img alt="Discord EN" src="https://img.shields.io/badge/Discord-English-5865F2?logo=discord&logoColor=white" />
|
|
11
18
|
</a>
|
|
12
|
-
|
|
19
|
+
</p>
|
|
20
|
+
|
|
21
|
+
[Get started](#getting-started) • [Configuration](#configuration) • [Commands](#commands) • [Development](#development) • [Resources](#resources)
|
|
13
22
|
|
|
14
|
-
##
|
|
23
|
+
## Features
|
|
15
24
|
|
|
16
|
-
|
|
25
|
+
- **Project scaffolding**: initialize React, Vue, Next.js static export, Astro, and React Router projects with ESA-ready configuration.
|
|
26
|
+
- **Local development**: run a local ESA-compatible server with automatic rebuilds, local upstream proxying, mock KV, and cache support.
|
|
27
|
+
- **Static + dynamic deployments**: deploy static Pages, edge functions, or hybrid Functions & Pages projects.
|
|
28
|
+
- **Versioned releases**: create code versions with `commit`, deploy existing versions, or split traffic between two versions by percentage.
|
|
29
|
+
- **Account operations**: login with AK/SK or STS credentials, list projects and sites, and manage custom domains and routes.
|
|
30
|
+
- **Bilingual CLI**: switch the CLI language between English and Simplified Chinese.
|
|
17
31
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
-
|
|
32
|
+
## Prerequisites
|
|
33
|
+
|
|
34
|
+
- Node.js 20 or newer is recommended. CI currently covers Node.js 18.x, 20.x, and 22.x.
|
|
35
|
+
- npm, pnpm, yarn, or Bun for installing the package.
|
|
36
|
+
- An Alibaba Cloud account with ESA Functions & Pages access.
|
|
37
|
+
|
|
38
|
+
> [!TIP]
|
|
39
|
+
> For team projects, install `esa-cli` as a dev dependency so everyone runs the same CLI version.
|
|
21
40
|
|
|
22
41
|
## Installation
|
|
23
42
|
|
|
24
|
-
|
|
43
|
+
Install locally in your project:
|
|
25
44
|
|
|
26
45
|
```bash
|
|
27
46
|
npm i -D esa-cli@latest
|
|
28
47
|
```
|
|
29
48
|
|
|
30
|
-
|
|
49
|
+
Or install globally:
|
|
31
50
|
|
|
32
51
|
```bash
|
|
33
52
|
npm i -g esa-cli@latest
|
|
34
53
|
```
|
|
35
54
|
|
|
36
|
-
|
|
37
|
-
> When `esa-cli` is not previously installed, `npx` will fetch and run the latest version from the registry.
|
|
38
|
-
|
|
39
|
-
## Check your ESA CLI version
|
|
55
|
+
The package exposes both `esa-cli` and the shorter `esa` command after installation.
|
|
40
56
|
|
|
41
|
-
|
|
57
|
+
Check the installed version:
|
|
42
58
|
|
|
43
59
|
```bash
|
|
44
60
|
npx esa-cli --version
|
|
45
|
-
# or
|
|
46
61
|
npx esa-cli -v
|
|
47
62
|
```
|
|
48
63
|
|
|
49
|
-
##
|
|
64
|
+
## Getting Started
|
|
65
|
+
|
|
66
|
+
### 1. Authenticate
|
|
50
67
|
|
|
51
|
-
|
|
68
|
+
Run the interactive login flow:
|
|
52
69
|
|
|
53
70
|
```bash
|
|
54
|
-
|
|
71
|
+
npx esa-cli login
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
You can also pass credentials directly:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
npx esa-cli login --access-key-id <ACCESS_KEY_ID> --access-key-secret <ACCESS_KEY_SECRET>
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
For temporary credentials, pass an STS token:
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
npx esa-cli login --sts-token "AccessKeyId,AccessKeySecret,SecurityToken"
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Environment variables are supported:
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
export ALIBABA_CLOUD_ACCESS_KEY_ID=<ACCESS_KEY_ID>
|
|
90
|
+
export ALIBABA_CLOUD_ACCESS_KEY_SECRET=<ACCESS_KEY_SECRET>
|
|
91
|
+
export ALIBABA_CLOUD_SECURITY_TOKEN=<SECURITY_TOKEN>
|
|
92
|
+
npx esa-cli login
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
The legacy `ESA_ACCESS_KEY_ID`, `ESA_ACCESS_KEY_SECRET`, and `ESA_SECURITY_TOKEN` variables remain supported as fallbacks. When both forms are set, the standard `ALIBABA_CLOUD_*` variables take precedence.
|
|
96
|
+
|
|
97
|
+
### 2. Create a Project
|
|
98
|
+
|
|
99
|
+
Create a new ESA-ready application from a template:
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
npx esa-cli init my-esa-app
|
|
103
|
+
cd my-esa-app
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
You can also make the template choice explicit:
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
npx esa-cli init my-esa-app --framework react --language typescript
|
|
55
110
|
```
|
|
56
111
|
|
|
57
|
-
|
|
112
|
+
### 3. Develop Locally
|
|
113
|
+
|
|
114
|
+
Start the local development server:
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
npx esa-cli dev
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Use a custom port or local upstream when needed:
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
npx esa-cli dev --port 18080 --local-upstream https://example.com
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### 4. Commit and Deploy
|
|
127
|
+
|
|
128
|
+
Create a code version without deploying it:
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
npx esa-cli commit --description "Prepare release"
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
Deploy the current project:
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
npx esa-cli deploy --description "Initial release"
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
Deploy an existing version:
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
npx esa-cli deploy --version <VERSION_ID> --environment production
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
Split traffic between two versions:
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
npx esa-cli deploy --versions v1:80,v2:20 --environment production
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
## Configuration
|
|
153
|
+
|
|
154
|
+
ESA CLI looks for `esa.jsonc` or `esa.toml` from the current directory upward. `esa.jsonc` is recommended for new projects.
|
|
155
|
+
|
|
156
|
+
```jsonc
|
|
157
|
+
{
|
|
158
|
+
"name": "my-esa-app",
|
|
159
|
+
"description": "My ESA Functions & Pages project",
|
|
160
|
+
"entry": "./src/index.ts",
|
|
161
|
+
"assets": {
|
|
162
|
+
"directory": "./dist",
|
|
163
|
+
"notFoundStrategy": "singlePageApplication"
|
|
164
|
+
},
|
|
165
|
+
"dev": {
|
|
166
|
+
"port": 18080,
|
|
167
|
+
"localUpstream": "https://example.com"
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
You can configure only `entry` for an edge function, only `assets.directory` for static Pages, or both for a hybrid project.
|
|
173
|
+
|
|
174
|
+
> [!NOTE]
|
|
175
|
+
> If both a function entry and `assets.notFoundStrategy` are configured, navigation requests are handled by the static fallback strategy instead of the function entry.
|
|
176
|
+
|
|
177
|
+
See the [ESA Configuration Guide](https://github.com/aliyun/alibabacloud-esa-cli/blob/master/docs/Config_en.md) for all fields and examples.
|
|
178
|
+
|
|
179
|
+
## Commands
|
|
180
|
+
|
|
181
|
+
| Command | Description |
|
|
182
|
+
| --- | --- |
|
|
183
|
+
| `esa-cli init [name]` | Create a new project from framework templates. |
|
|
184
|
+
| `esa-cli login` | Authenticate with AK/SK, STS token, or supported environment variables. |
|
|
185
|
+
| `esa-cli dev [entry]` | Start a local server for Functions & Pages development. |
|
|
186
|
+
| `esa-cli commit [entry]` | Package code and assets, then save them as a new version. |
|
|
187
|
+
| `esa-cli deploy [entry]` | Generate or select a version and deploy it to staging, production, or both. |
|
|
188
|
+
| `esa-cli deployments list` | List code versions for the current Functions & Pages project. |
|
|
189
|
+
| `esa-cli deployments delete` | Delete one or more code versions. |
|
|
190
|
+
| `esa-cli project list` | List Functions & Pages projects in the current account. |
|
|
191
|
+
| `esa-cli project delete` | Delete a Functions & Pages project. |
|
|
192
|
+
| `esa-cli site list` | List activated ESA sites. |
|
|
193
|
+
| `esa-cli domain add/list/delete` | Manage custom domain bindings. |
|
|
194
|
+
| `esa-cli route add/list/delete` | Manage route bindings for activated sites. |
|
|
195
|
+
| `esa-cli config --local/--global` | Edit local project or global CLI configuration. |
|
|
196
|
+
| `esa-cli lang` | Switch CLI language. |
|
|
197
|
+
|
|
198
|
+
For the full option reference, see [ESA CLI Commands](https://github.com/aliyun/alibabacloud-esa-cli/blob/master/docs/Commands_en.md).
|
|
199
|
+
|
|
200
|
+
## Development
|
|
201
|
+
|
|
202
|
+
Clone the repository and install dependencies:
|
|
203
|
+
|
|
204
|
+
```bash
|
|
205
|
+
git clone git@github.com:aliyun/alibabacloud-esa-cli.git
|
|
206
|
+
cd alibabacloud-esa-cli
|
|
207
|
+
npm install
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
Build the CLI:
|
|
211
|
+
|
|
212
|
+
```bash
|
|
213
|
+
npm run build
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
Run tests:
|
|
217
|
+
|
|
218
|
+
```bash
|
|
219
|
+
npm test
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
Useful scripts:
|
|
223
|
+
|
|
224
|
+
| Script | Description |
|
|
225
|
+
| --- | --- |
|
|
226
|
+
| `npm run dev` | Run TypeScript in watch mode. |
|
|
227
|
+
| `npm run build` | Generate locale files, compile TypeScript, and copy runtime assets into `dist`. |
|
|
228
|
+
| `npm test` | Run Vitest with coverage. |
|
|
229
|
+
| `npm run lint` | Run ESLint on `src`. |
|
|
230
|
+
| `npm run lint:fix` | Run ESLint with automatic fixes. |
|
|
231
|
+
|
|
232
|
+
## Troubleshooting
|
|
233
|
+
|
|
234
|
+
- Run commands with `--debug` to print more detailed logs where supported.
|
|
235
|
+
- Use `--skip-update-check` or `ESA_NO_UPDATE_CHECK=1` to skip the CLI update check.
|
|
236
|
+
- Set `ALIBABA_CLOUD_ESA_CLI_COMPAT_MODE` to override the CLI name shown in help, usage, and error messages when invoking ESA CLI through a compatibility wrapper.
|
|
237
|
+
- If packaging fails, confirm that `entry` points to an existing file and `assets.directory` points to an existing directory.
|
|
238
|
+
- If route or domain binding fails, confirm the target site is already activated under the current account.
|
|
239
|
+
|
|
240
|
+
## Resources
|
|
58
241
|
|
|
59
|
-
- [esa-cli
|
|
60
|
-
- [ESA Configuration Guide](
|
|
242
|
+
- [ESA CLI Commands](https://github.com/aliyun/alibabacloud-esa-cli/blob/master/docs/Commands_en.md)
|
|
243
|
+
- [ESA Configuration Guide](https://github.com/aliyun/alibabacloud-esa-cli/blob/master/docs/Config_en.md)
|
|
61
244
|
- [Alibaba Cloud ESA Documentation](https://www.alibabacloud.com/help/en/edge-security-acceleration/esa/user-guide/what-is-er/)
|
|
62
245
|
- [Functions and Pages API Reference](https://www.alibabacloud.com/help/en/edge-security-acceleration/esa/user-guide/api-documentation/)
|
|
246
|
+
- [中文文档](./zh_CN.md)
|
package/bin/enter.cjs
CHANGED
|
@@ -3,6 +3,38 @@ const fs = require('fs');
|
|
|
3
3
|
const spawn = require('cross-spawn');
|
|
4
4
|
const path = require('path');
|
|
5
5
|
|
|
6
|
+
const getRuntimeNodePath = () => {
|
|
7
|
+
const nodePaths = new Set();
|
|
8
|
+
const launcherDirs = [
|
|
9
|
+
__dirname,
|
|
10
|
+
process.argv[1] ? path.dirname(process.argv[1]) : undefined
|
|
11
|
+
].filter(Boolean);
|
|
12
|
+
|
|
13
|
+
for (const launcherDir of launcherDirs) {
|
|
14
|
+
const pnpmNodeModules = path.resolve(
|
|
15
|
+
launcherDir,
|
|
16
|
+
'..',
|
|
17
|
+
'..',
|
|
18
|
+
'.pnpm',
|
|
19
|
+
'node_modules'
|
|
20
|
+
);
|
|
21
|
+
|
|
22
|
+
if (fs.existsSync(pnpmNodeModules)) {
|
|
23
|
+
nodePaths.add(pnpmNodeModules);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (process.env.NODE_PATH) {
|
|
28
|
+
for (const nodePath of process.env.NODE_PATH.split(path.delimiter)) {
|
|
29
|
+
if (nodePath) {
|
|
30
|
+
nodePaths.add(nodePath);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return nodePaths.size > 0 ? Array.from(nodePaths).join(path.delimiter) : '';
|
|
36
|
+
};
|
|
37
|
+
|
|
6
38
|
const main = () => {
|
|
7
39
|
let entryPath;
|
|
8
40
|
if (fs.existsSync(path.join(__dirname, '../dist/index.js'))) {
|
|
@@ -13,29 +45,30 @@ const main = () => {
|
|
|
13
45
|
throw new Error('Neither dist/index.js nor index.js could be found.');
|
|
14
46
|
}
|
|
15
47
|
|
|
48
|
+
const nodePath = getRuntimeNodePath();
|
|
49
|
+
|
|
16
50
|
return spawn(
|
|
17
51
|
process.execPath,
|
|
18
52
|
['--no-warnings', ...process.execArgv, entryPath, ...process.argv.slice(2)],
|
|
19
53
|
{
|
|
20
|
-
stdio:
|
|
54
|
+
stdio: 'inherit',
|
|
21
55
|
env: {
|
|
22
|
-
...process.env
|
|
56
|
+
...process.env,
|
|
57
|
+
...(nodePath ? { NODE_PATH: nodePath } : {})
|
|
23
58
|
}
|
|
24
59
|
}
|
|
25
60
|
)
|
|
26
61
|
.on('error', (err) => {
|
|
27
62
|
console.log('Get Error', err);
|
|
28
63
|
})
|
|
29
|
-
.on('
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
.on('exit', (code) => {
|
|
38
|
-
process.exit && process.exit(code);
|
|
64
|
+
.on('exit', (code, signal) => {
|
|
65
|
+
if (code !== null) {
|
|
66
|
+
process.exit(code);
|
|
67
|
+
} else if (signal) {
|
|
68
|
+
process.kill(process.pid, signal);
|
|
69
|
+
} else {
|
|
70
|
+
process.exit(1);
|
|
71
|
+
}
|
|
39
72
|
});
|
|
40
73
|
};
|
|
41
74
|
|
package/dist/bin/enter.cjs
CHANGED
|
@@ -3,6 +3,38 @@ const fs = require('fs');
|
|
|
3
3
|
const spawn = require('cross-spawn');
|
|
4
4
|
const path = require('path');
|
|
5
5
|
|
|
6
|
+
const getRuntimeNodePath = () => {
|
|
7
|
+
const nodePaths = new Set();
|
|
8
|
+
const launcherDirs = [
|
|
9
|
+
__dirname,
|
|
10
|
+
process.argv[1] ? path.dirname(process.argv[1]) : undefined
|
|
11
|
+
].filter(Boolean);
|
|
12
|
+
|
|
13
|
+
for (const launcherDir of launcherDirs) {
|
|
14
|
+
const pnpmNodeModules = path.resolve(
|
|
15
|
+
launcherDir,
|
|
16
|
+
'..',
|
|
17
|
+
'..',
|
|
18
|
+
'.pnpm',
|
|
19
|
+
'node_modules'
|
|
20
|
+
);
|
|
21
|
+
|
|
22
|
+
if (fs.existsSync(pnpmNodeModules)) {
|
|
23
|
+
nodePaths.add(pnpmNodeModules);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (process.env.NODE_PATH) {
|
|
28
|
+
for (const nodePath of process.env.NODE_PATH.split(path.delimiter)) {
|
|
29
|
+
if (nodePath) {
|
|
30
|
+
nodePaths.add(nodePath);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return nodePaths.size > 0 ? Array.from(nodePaths).join(path.delimiter) : '';
|
|
36
|
+
};
|
|
37
|
+
|
|
6
38
|
const main = () => {
|
|
7
39
|
let entryPath;
|
|
8
40
|
if (fs.existsSync(path.join(__dirname, '../dist/index.js'))) {
|
|
@@ -13,29 +45,30 @@ const main = () => {
|
|
|
13
45
|
throw new Error('Neither dist/index.js nor index.js could be found.');
|
|
14
46
|
}
|
|
15
47
|
|
|
48
|
+
const nodePath = getRuntimeNodePath();
|
|
49
|
+
|
|
16
50
|
return spawn(
|
|
17
51
|
process.execPath,
|
|
18
52
|
['--no-warnings', ...process.execArgv, entryPath, ...process.argv.slice(2)],
|
|
19
53
|
{
|
|
20
|
-
stdio:
|
|
54
|
+
stdio: 'inherit',
|
|
21
55
|
env: {
|
|
22
|
-
...process.env
|
|
56
|
+
...process.env,
|
|
57
|
+
...(nodePath ? { NODE_PATH: nodePath } : {})
|
|
23
58
|
}
|
|
24
59
|
}
|
|
25
60
|
)
|
|
26
61
|
.on('error', (err) => {
|
|
27
62
|
console.log('Get Error', err);
|
|
28
63
|
})
|
|
29
|
-
.on('
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
.on('exit', (code) => {
|
|
38
|
-
process.exit && process.exit(code);
|
|
64
|
+
.on('exit', (code, signal) => {
|
|
65
|
+
if (code !== null) {
|
|
66
|
+
process.exit(code);
|
|
67
|
+
} else if (signal) {
|
|
68
|
+
process.kill(process.pid, signal);
|
|
69
|
+
} else {
|
|
70
|
+
process.exit(1);
|
|
71
|
+
}
|
|
39
72
|
});
|
|
40
73
|
};
|
|
41
74
|
|
|
@@ -47,8 +47,8 @@ const commit = {
|
|
|
47
47
|
});
|
|
48
48
|
},
|
|
49
49
|
handler: (argv) => __awaiter(void 0, void 0, void 0, function* () {
|
|
50
|
-
yield handleCommit(argv);
|
|
51
|
-
exit();
|
|
50
|
+
const success = yield handleCommit(argv);
|
|
51
|
+
exit(success ? 0 : 1);
|
|
52
52
|
})
|
|
53
53
|
};
|
|
54
54
|
export default commit;
|
|
@@ -58,7 +58,7 @@ export function handleCommit(argv) {
|
|
|
58
58
|
intro(`Commit an application with ESA`);
|
|
59
59
|
const projectInfo = yield validateAndInitializeProject(argv === null || argv === void 0 ? void 0 : argv.name);
|
|
60
60
|
if (!projectInfo)
|
|
61
|
-
return;
|
|
61
|
+
return false;
|
|
62
62
|
const { projectName } = projectInfo;
|
|
63
63
|
let description;
|
|
64
64
|
if (argv.description) {
|
|
@@ -77,7 +77,7 @@ export function handleCommit(argv) {
|
|
|
77
77
|
const { isSuccess } = res || {};
|
|
78
78
|
if (!isSuccess) {
|
|
79
79
|
logger.endSubStep('Generate version failed');
|
|
80
|
-
|
|
80
|
+
return false;
|
|
81
81
|
}
|
|
82
82
|
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;
|
|
83
83
|
if (!codeVersion) {
|
|
@@ -86,5 +86,6 @@ export function handleCommit(argv) {
|
|
|
86
86
|
}
|
|
87
87
|
logger.endSubStep(`Version generated: ${codeVersion}`);
|
|
88
88
|
outro(`Code version ${chalk.bold(codeVersion)} generated successfully`);
|
|
89
|
+
return true;
|
|
89
90
|
});
|
|
90
91
|
}
|
|
@@ -19,7 +19,7 @@ const deploymentsList = {
|
|
|
19
19
|
command: 'list',
|
|
20
20
|
describe: `🔍 ${t('deployments_list_describe').d('List all deployments')}`,
|
|
21
21
|
handler: () => __awaiter(void 0, void 0, void 0, function* () {
|
|
22
|
-
handleListDeployments();
|
|
22
|
+
yield handleListDeployments();
|
|
23
23
|
})
|
|
24
24
|
};
|
|
25
25
|
export default deploymentsList;
|
|
@@ -7,7 +7,10 @@ import esbuild from 'esbuild';
|
|
|
7
7
|
import { lessLoader } from 'esbuild-plugin-less';
|
|
8
8
|
import { getRoot } from '../../utils/fileUtils/base.js';
|
|
9
9
|
import { NODE_EXTERNALS } from '../common/constant.js';
|
|
10
|
-
const replacements = {
|
|
10
|
+
const replacements = {
|
|
11
|
+
cache: 'mockCache',
|
|
12
|
+
EdgeKV: 'mockKV'
|
|
13
|
+
};
|
|
11
14
|
const traverse = _traverse.default;
|
|
12
15
|
const generator = _generator.default;
|
|
13
16
|
const renameMock = {
|
|
@@ -8,26 +8,102 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
10
|
import chalk from 'chalk';
|
|
11
|
-
import { Box, Text, useApp, useInput, render } from 'ink';
|
|
12
|
-
import React, { useEffect } from 'react';
|
|
13
11
|
import t from '../../i18n/index.js';
|
|
14
12
|
import logger from '../../libs/logger.js';
|
|
15
13
|
import { checkOS, Platforms } from '../../utils/checkOS.js';
|
|
16
14
|
import { getDevOpenBrowserUrl } from '../../utils/fileUtils/index.js';
|
|
17
15
|
import openInBrowser from '../../utils/openInBrowser.js';
|
|
18
|
-
const
|
|
19
|
-
|
|
16
|
+
const getShortcutSegments = (useEw2) => [
|
|
17
|
+
['[b]', ' open a browser, '],
|
|
18
|
+
...(!useEw2
|
|
19
|
+
? [['[d]', ' open Devtools, ']]
|
|
20
|
+
: []),
|
|
21
|
+
['[c]', ' clear console, '],
|
|
22
|
+
['[x]', ' to exit']
|
|
23
|
+
];
|
|
24
|
+
export const formatShortcutPanel = (useEw2, columns = process.stdout.columns) => {
|
|
25
|
+
const segments = getShortcutSegments(useEw2);
|
|
26
|
+
const fullPlain = segments
|
|
27
|
+
.map(([key, description]) => key + description)
|
|
28
|
+
.join('');
|
|
29
|
+
const shouldStack = Boolean(columns && fullPlain.length + 4 > columns);
|
|
30
|
+
const rows = shouldStack
|
|
31
|
+
? segments.map(([key, description]) => ({
|
|
32
|
+
plain: key + description,
|
|
33
|
+
styled: chalk.bold(key) + description
|
|
34
|
+
}))
|
|
35
|
+
: [
|
|
36
|
+
{
|
|
37
|
+
plain: fullPlain,
|
|
38
|
+
styled: segments
|
|
39
|
+
.map(([key, description]) => chalk.bold(key) + description)
|
|
40
|
+
.join('')
|
|
41
|
+
}
|
|
42
|
+
];
|
|
43
|
+
const innerWidth = Math.max(...rows.map(({ plain }) => plain.length));
|
|
44
|
+
const border = `+${'-'.repeat(innerWidth + 2)}+`;
|
|
45
|
+
return [
|
|
46
|
+
border,
|
|
47
|
+
...rows.map(({ plain, styled }) => `| ${styled}${' '.repeat(innerWidth - plain.length)} |`),
|
|
48
|
+
border
|
|
49
|
+
];
|
|
50
|
+
};
|
|
51
|
+
const printShortcutPanel = (useEw2) => {
|
|
52
|
+
formatShortcutPanel(useEw2).forEach((line) => logger.log(line));
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* Keyboard shortcut panel for `dev` mode, implemented with raw stdin
|
|
56
|
+
* (previously an ink component). Returns the same shape as before:
|
|
57
|
+
* `{ devElement: { waitUntilExit }, exit }`.
|
|
58
|
+
*/
|
|
59
|
+
const doProcess = (worker) => {
|
|
20
60
|
const inspectLink = chalk.underline.blue('chrome://inspect/#devices');
|
|
21
61
|
const remoteTarget = chalk.blue('Remote Target');
|
|
22
62
|
const inspect = chalk.blue('inspect');
|
|
23
63
|
const OS = checkOS();
|
|
24
|
-
const useEw2 =
|
|
25
|
-
|
|
26
|
-
|
|
64
|
+
const useEw2 = [
|
|
65
|
+
Platforms.AppleArm,
|
|
66
|
+
Platforms.AppleIntel,
|
|
67
|
+
Platforms.LinuxX86
|
|
68
|
+
].includes(OS);
|
|
69
|
+
printShortcutPanel(useEw2);
|
|
70
|
+
let resolveExit;
|
|
71
|
+
const exitPromise = new Promise((resolve) => {
|
|
72
|
+
resolveExit = resolve;
|
|
73
|
+
});
|
|
74
|
+
let exited = false;
|
|
75
|
+
const cleanup = () => {
|
|
76
|
+
process.stdin.off('data', onData);
|
|
77
|
+
if (process.stdin.isTTY) {
|
|
78
|
+
process.stdin.setRawMode(false);
|
|
79
|
+
}
|
|
80
|
+
process.stdin.pause();
|
|
81
|
+
if (worker) {
|
|
82
|
+
worker.stop();
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
const exit = () => {
|
|
86
|
+
if (exited)
|
|
87
|
+
return;
|
|
88
|
+
exited = true;
|
|
89
|
+
cleanup();
|
|
90
|
+
resolveExit();
|
|
91
|
+
setTimeout(() => {
|
|
92
|
+
process.exit(0);
|
|
93
|
+
}, 500);
|
|
94
|
+
};
|
|
95
|
+
const onData = (data) => __awaiter(void 0, void 0, void 0, function* () {
|
|
96
|
+
const input = data.toString();
|
|
97
|
+
// Ctrl+C
|
|
98
|
+
if (input === '\u0003') {
|
|
99
|
+
exit();
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
27
102
|
switch (input.toLowerCase()) {
|
|
28
103
|
case 'c':
|
|
29
104
|
console.clear();
|
|
30
105
|
logger.block();
|
|
106
|
+
printShortcutPanel(useEw2);
|
|
31
107
|
break;
|
|
32
108
|
case 'b': {
|
|
33
109
|
yield openInBrowser(getDevOpenBrowserUrl());
|
|
@@ -46,36 +122,18 @@ const InteractionBox = ({ worker }) => {
|
|
|
46
122
|
default:
|
|
47
123
|
break;
|
|
48
124
|
}
|
|
49
|
-
})
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
}, []);
|
|
57
|
-
return (React.createElement(React.Fragment, null,
|
|
58
|
-
React.createElement(Box, { borderStyle: "classic", paddingLeft: 1, paddingRight: 1 },
|
|
59
|
-
React.createElement(Text, { bold: true }, "[b]"),
|
|
60
|
-
React.createElement(Text, null, " open a browser, "),
|
|
61
|
-
!useEw2 ? (React.createElement(React.Fragment, null,
|
|
62
|
-
React.createElement(Text, { bold: true }, "[d]"),
|
|
63
|
-
React.createElement(Text, null, " open Devtools, "))) : null,
|
|
64
|
-
React.createElement(Text, { bold: true }, "[c]"),
|
|
65
|
-
React.createElement(Text, null, " clear console, "),
|
|
66
|
-
React.createElement(Text, { bold: true }, "[x]"),
|
|
67
|
-
React.createElement(Text, null, " to exit"))));
|
|
68
|
-
};
|
|
69
|
-
const doProcess = (worker) => {
|
|
70
|
-
const devElement = render(React.createElement(InteractionBox, { worker: worker }));
|
|
125
|
+
});
|
|
126
|
+
if (process.stdin.isTTY) {
|
|
127
|
+
process.stdin.setRawMode(true);
|
|
128
|
+
}
|
|
129
|
+
process.stdin.setEncoding('utf8');
|
|
130
|
+
process.stdin.resume();
|
|
131
|
+
process.stdin.on('data', onData);
|
|
71
132
|
return {
|
|
72
|
-
devElement
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
process.exit(0);
|
|
77
|
-
}, 500);
|
|
78
|
-
}
|
|
133
|
+
devElement: {
|
|
134
|
+
waitUntilExit: () => exitPromise
|
|
135
|
+
},
|
|
136
|
+
exit
|
|
79
137
|
};
|
|
80
138
|
};
|
|
81
139
|
export default doProcess;
|
|
@@ -17,15 +17,14 @@ const deleteDomain = {
|
|
|
17
17
|
command: 'delete <domain>',
|
|
18
18
|
describe: `🗑 ${t('domain_delete_describe').d('Delete a related domain')}`,
|
|
19
19
|
builder: (yargs) => {
|
|
20
|
-
return yargs.positional('
|
|
20
|
+
return yargs.positional('domain', {
|
|
21
21
|
describe: t('domain_delete_positional_describe').d('The names of the related domains to delete'),
|
|
22
22
|
type: 'string',
|
|
23
|
-
array: true,
|
|
24
23
|
demandOption: true
|
|
25
24
|
});
|
|
26
25
|
},
|
|
27
26
|
handler: (argv) => __awaiter(void 0, void 0, void 0, function* () {
|
|
28
|
-
handleDeleteDomain(argv);
|
|
27
|
+
yield handleDeleteDomain(argv);
|
|
29
28
|
})
|
|
30
29
|
};
|
|
31
30
|
export default deleteDomain;
|