@icyouo/evt-cli 0.1.2 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +16 -5
- package/README.zh-CN.md +15 -5
- package/package.json +2 -2
- package/src/index.js +25 -5
- package/src/util/settings.js +45 -0
- package/test/profileDefault.test.js +70 -0
package/README.md
CHANGED
|
@@ -25,18 +25,21 @@ Run the bundled example data:
|
|
|
25
25
|
|
|
26
26
|
```bash
|
|
27
27
|
evt profile list
|
|
28
|
+
evt profile set local
|
|
29
|
+
evt profile current
|
|
28
30
|
evt api list
|
|
29
31
|
evt validate
|
|
30
|
-
evt api call todo.list --
|
|
32
|
+
evt api call todo.list --dry-run
|
|
31
33
|
```
|
|
32
34
|
|
|
33
35
|
During local development, run the entry file directly:
|
|
34
36
|
|
|
35
37
|
```bash
|
|
36
38
|
node bin/evt.js profile list
|
|
39
|
+
node bin/evt.js profile set local
|
|
37
40
|
node bin/evt.js api list
|
|
38
41
|
node bin/evt.js validate
|
|
39
|
-
node bin/evt.js api call todo.list --
|
|
42
|
+
node bin/evt.js api call todo.list --dry-run
|
|
40
43
|
```
|
|
41
44
|
|
|
42
45
|
Use your own project data directory:
|
|
@@ -44,7 +47,8 @@ Use your own project data directory:
|
|
|
44
47
|
```bash
|
|
45
48
|
evt validate --config-root /path/to/project/cli
|
|
46
49
|
evt api list --config-root /path/to/project/cli
|
|
47
|
-
evt
|
|
50
|
+
evt profile set dev --config-root /path/to/project/cli
|
|
51
|
+
evt flow run login --config-root /path/to/project/cli
|
|
48
52
|
```
|
|
49
53
|
|
|
50
54
|
Or set an environment variable:
|
|
@@ -54,6 +58,11 @@ export EVT_CLI_ROOT=/path/to/project/cli
|
|
|
54
58
|
evt validate
|
|
55
59
|
```
|
|
56
60
|
|
|
61
|
+
`evt profile set <name>` stores the default profile in
|
|
62
|
+
`data/.evt/config.json` under the active config root. Commands that need a
|
|
63
|
+
profile use that value when `--profile` is omitted. Passing `--profile <name>`
|
|
64
|
+
still overrides the default for one command.
|
|
65
|
+
|
|
57
66
|
## Data Layout
|
|
58
67
|
|
|
59
68
|
Recommended project data layout:
|
|
@@ -270,14 +279,16 @@ This JSON is used only for scanning, coverage, and sync. Runtime execution still
|
|
|
270
279
|
|
|
271
280
|
```bash
|
|
272
281
|
evt profile list
|
|
282
|
+
evt profile set local
|
|
283
|
+
evt profile current
|
|
273
284
|
evt api list
|
|
274
285
|
evt api discover --config-root ./cli
|
|
275
286
|
evt api sync --config-root ./cli
|
|
276
287
|
evt api audit --config-root ./cli --strict
|
|
277
288
|
evt api coverage --config-root ./cli
|
|
278
289
|
evt api call todo.list --dry-run
|
|
279
|
-
evt flow run login
|
|
290
|
+
evt flow run login
|
|
280
291
|
evt cache show
|
|
281
292
|
evt cache clear
|
|
282
|
-
evt api test-all
|
|
293
|
+
evt api test-all
|
|
283
294
|
```
|
package/README.zh-CN.md
CHANGED
|
@@ -25,18 +25,21 @@ npm install -g @icyouo/evt-cli
|
|
|
25
25
|
|
|
26
26
|
```bash
|
|
27
27
|
evt profile list
|
|
28
|
+
evt profile set local
|
|
29
|
+
evt profile current
|
|
28
30
|
evt api list
|
|
29
31
|
evt validate
|
|
30
|
-
evt api call todo.list --
|
|
32
|
+
evt api call todo.list --dry-run
|
|
31
33
|
```
|
|
32
34
|
|
|
33
35
|
仓库内开发时也可以直接运行:
|
|
34
36
|
|
|
35
37
|
```bash
|
|
36
38
|
node bin/evt.js profile list
|
|
39
|
+
node bin/evt.js profile set local
|
|
37
40
|
node bin/evt.js api list
|
|
38
41
|
node bin/evt.js validate
|
|
39
|
-
node bin/evt.js api call todo.list --
|
|
42
|
+
node bin/evt.js api call todo.list --dry-run
|
|
40
43
|
```
|
|
41
44
|
|
|
42
45
|
使用项目自己的数据目录:
|
|
@@ -44,7 +47,8 @@ node bin/evt.js api call todo.list --profile local --dry-run
|
|
|
44
47
|
```bash
|
|
45
48
|
evt validate --config-root /path/to/project/cli
|
|
46
49
|
evt api list --config-root /path/to/project/cli
|
|
47
|
-
evt
|
|
50
|
+
evt profile set dev --config-root /path/to/project/cli
|
|
51
|
+
evt flow run login --config-root /path/to/project/cli
|
|
48
52
|
```
|
|
49
53
|
|
|
50
54
|
也可以设置环境变量:
|
|
@@ -54,6 +58,10 @@ export EVT_CLI_ROOT=/path/to/project/cli
|
|
|
54
58
|
evt validate
|
|
55
59
|
```
|
|
56
60
|
|
|
61
|
+
`evt profile set <name>` 会把默认 profile 写到当前 config root 下的
|
|
62
|
+
`data/.evt/config.json`。需要 profile 的命令在未传 `--profile` 时会使用这个默认值。
|
|
63
|
+
临时传入 `--profile <name>` 仍然可以覆盖本次命令。
|
|
64
|
+
|
|
57
65
|
## 数据目录
|
|
58
66
|
|
|
59
67
|
项目数据目录结构:
|
|
@@ -260,14 +268,16 @@ npm run sync:api -- --config-root /path/to/project/cli
|
|
|
260
268
|
|
|
261
269
|
```bash
|
|
262
270
|
evt profile list
|
|
271
|
+
evt profile set local
|
|
272
|
+
evt profile current
|
|
263
273
|
evt api list
|
|
264
274
|
evt api discover --config-root ./cli
|
|
265
275
|
evt api sync --config-root ./cli
|
|
266
276
|
evt api audit --config-root ./cli --strict
|
|
267
277
|
evt api coverage --config-root ./cli
|
|
268
278
|
evt api call todo.list --dry-run
|
|
269
|
-
evt flow run login
|
|
279
|
+
evt flow run login
|
|
270
280
|
evt cache show
|
|
271
281
|
evt cache clear
|
|
272
|
-
evt api test-all
|
|
282
|
+
evt api test-all
|
|
273
283
|
```
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@icyouo/evt-cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "Run YAML-defined HTTP APIs and interactive workflows from your terminal.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"scripts": {
|
|
28
28
|
"ci:local": "node scripts/local-ci.js",
|
|
29
29
|
"test": "node --test",
|
|
30
|
-
"check": "node --check bin/evt.js && node --check src/index.js && node --check src/api/liveTester.js && node --check scripts/sync-api-coverage.js && node --check scripts/check-api-coverage.js && node --check scripts/check-api-audit.js && node --check scripts/local-ci.js && node --check scripts/build-package.js && node --check skills/evt-api-scanner/scripts/discover.js && node --check skills/evt-api-scanner/scripts/scan.js",
|
|
30
|
+
"check": "node --check bin/evt.js && node --check src/index.js && node --check src/util/settings.js && node --check src/api/liveTester.js && node --check scripts/sync-api-coverage.js && node --check scripts/check-api-coverage.js && node --check scripts/check-api-audit.js && node --check scripts/local-ci.js && node --check scripts/build-package.js && node --check skills/evt-api-scanner/scripts/discover.js && node --check skills/evt-api-scanner/scripts/scan.js",
|
|
31
31
|
"package:local": "node scripts/build-package.js",
|
|
32
32
|
"sync:api": "node scripts/sync-api-coverage.js",
|
|
33
33
|
"coverage:api": "node scripts/check-api-coverage.js",
|
package/src/index.js
CHANGED
|
@@ -4,6 +4,7 @@ const { parseArgs } = require("./util/args");
|
|
|
4
4
|
const { parseJsonObject, stableJson } = require("./util/json");
|
|
5
5
|
const { redact } = require("./util/redact");
|
|
6
6
|
const { cliRoot, setConfigRoot } = require("./util/paths");
|
|
7
|
+
const { getDefaultProfile, resolveProfileName, setDefaultProfile, settingsPath } = require("./util/settings");
|
|
7
8
|
const {
|
|
8
9
|
listApiFiles,
|
|
9
10
|
listProfiles,
|
|
@@ -34,6 +35,8 @@ function usage() {
|
|
|
34
35
|
return [
|
|
35
36
|
"Usage:",
|
|
36
37
|
" evt profile list [--config-root ./cli]",
|
|
38
|
+
" evt profile current [--config-root ./cli]",
|
|
39
|
+
" evt profile set <name> [--config-root ./cli]",
|
|
37
40
|
" evt profile show <name>",
|
|
38
41
|
" evt api list",
|
|
39
42
|
" evt api show <id>",
|
|
@@ -42,11 +45,11 @@ function usage() {
|
|
|
42
45
|
" evt api sync [--config-root ./cli]",
|
|
43
46
|
" evt api coverage [--config-root ./cli]",
|
|
44
47
|
" evt api audit [--config-root ./cli] [--strict]",
|
|
45
|
-
" evt api call <id> [--profile
|
|
46
|
-
" evt api test-all [--profile
|
|
48
|
+
" evt api call <id> [--profile name] [--set k=v] [--body '{...}'] [--dry-run]",
|
|
49
|
+
" evt api test-all [--profile name] [--include-dangerous] [--only namespace]",
|
|
47
50
|
" evt validate",
|
|
48
51
|
" evt flow list",
|
|
49
|
-
" evt flow run <name> [--profile
|
|
52
|
+
" evt flow run <name> [--profile name] [--set k=v] [--dry-run]",
|
|
50
53
|
" evt cache show|clear|path"
|
|
51
54
|
].join("\n");
|
|
52
55
|
}
|
|
@@ -63,7 +66,7 @@ function runNodeScript(relativeScript, args) {
|
|
|
63
66
|
}
|
|
64
67
|
|
|
65
68
|
function commonRuntime(options) {
|
|
66
|
-
const profile = loadProfile(options.profile
|
|
69
|
+
const profile = loadProfile(resolveProfileName(options.profile));
|
|
67
70
|
const cachePath = resolveCachePath(options.cache);
|
|
68
71
|
const cache = readCache(cachePath);
|
|
69
72
|
return {
|
|
@@ -82,8 +85,25 @@ async function handleProfile(tokens) {
|
|
|
82
85
|
print(listProfiles(), options.json);
|
|
83
86
|
return;
|
|
84
87
|
}
|
|
88
|
+
if (sub === "current") {
|
|
89
|
+
const profile = getDefaultProfile();
|
|
90
|
+
if (options.json) {
|
|
91
|
+
print({ profile, settingsPath: settingsPath() }, true);
|
|
92
|
+
} else {
|
|
93
|
+
print(profile);
|
|
94
|
+
}
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
if (sub === "set") {
|
|
98
|
+
const name = options._[0];
|
|
99
|
+
if (!name) throw new Error("evt profile set expects a profile name");
|
|
100
|
+
loadProfile(name);
|
|
101
|
+
const result = setDefaultProfile(name);
|
|
102
|
+
print(options.json ? { ok: true, ...result } : `Default profile set to ${name}`);
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
85
105
|
if (sub === "show") {
|
|
86
|
-
print(loadProfile(options._[0]), true);
|
|
106
|
+
print(loadProfile(resolveProfileName(options._[0])), true);
|
|
87
107
|
return;
|
|
88
108
|
}
|
|
89
109
|
throw new Error(usage());
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
const fs = require("node:fs");
|
|
2
|
+
const path = require("node:path");
|
|
3
|
+
const { resolveCliPath } = require("./paths");
|
|
4
|
+
|
|
5
|
+
function settingsPath() {
|
|
6
|
+
return resolveCliPath("data", ".evt", "config.json");
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
function readSettings() {
|
|
10
|
+
const file = settingsPath();
|
|
11
|
+
if (!fs.existsSync(file)) return {};
|
|
12
|
+
return JSON.parse(fs.readFileSync(file, "utf8"));
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function writeSettings(settings) {
|
|
16
|
+
const file = settingsPath();
|
|
17
|
+
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
18
|
+
fs.writeFileSync(file, `${JSON.stringify(settings, null, 2)}\n`);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function getDefaultProfile() {
|
|
22
|
+
return readSettings().defaultProfile || "local";
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function setDefaultProfile(profile) {
|
|
26
|
+
const settings = readSettings();
|
|
27
|
+
settings.defaultProfile = profile;
|
|
28
|
+
writeSettings(settings);
|
|
29
|
+
return {
|
|
30
|
+
profile,
|
|
31
|
+
path: settingsPath()
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function resolveProfileName(profile) {
|
|
36
|
+
return profile || getDefaultProfile();
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
module.exports = {
|
|
40
|
+
getDefaultProfile,
|
|
41
|
+
readSettings,
|
|
42
|
+
resolveProfileName,
|
|
43
|
+
setDefaultProfile,
|
|
44
|
+
settingsPath
|
|
45
|
+
};
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
const fs = require("node:fs");
|
|
2
|
+
const os = require("node:os");
|
|
3
|
+
const path = require("node:path");
|
|
4
|
+
const test = require("node:test");
|
|
5
|
+
const assert = require("node:assert/strict");
|
|
6
|
+
const { run } = require("../src/index");
|
|
7
|
+
|
|
8
|
+
function write(file, content) {
|
|
9
|
+
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
10
|
+
fs.writeFileSync(file, content);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
async function capture(fn) {
|
|
14
|
+
const originalLog = console.log;
|
|
15
|
+
const lines = [];
|
|
16
|
+
console.log = (value) => lines.push(value);
|
|
17
|
+
try {
|
|
18
|
+
await fn();
|
|
19
|
+
} finally {
|
|
20
|
+
console.log = originalLog;
|
|
21
|
+
}
|
|
22
|
+
return lines;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function createConfigRoot() {
|
|
26
|
+
const root = fs.mkdtempSync(path.join(os.tmpdir(), "evt-profile-default-"));
|
|
27
|
+
write(path.join(root, "data", "profiles", "dev.json"), JSON.stringify({
|
|
28
|
+
name: "dev",
|
|
29
|
+
baseUrl: "https://dev.example.test",
|
|
30
|
+
headers: {
|
|
31
|
+
"X-Profile": "dev"
|
|
32
|
+
}
|
|
33
|
+
}, null, 2));
|
|
34
|
+
write(path.join(root, "data", "apis", "todo.yaml"), [
|
|
35
|
+
"namespace: todo",
|
|
36
|
+
"",
|
|
37
|
+
"endpoints:",
|
|
38
|
+
" list:",
|
|
39
|
+
" method: \"GET\"",
|
|
40
|
+
" path: \"/api/todos\"",
|
|
41
|
+
" auth: false",
|
|
42
|
+
" response:",
|
|
43
|
+
" data:",
|
|
44
|
+
" type: \"array\"",
|
|
45
|
+
""
|
|
46
|
+
].join("\n"));
|
|
47
|
+
return root;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
test("profile set stores a project default profile used by api calls", async () => {
|
|
51
|
+
const root = createConfigRoot();
|
|
52
|
+
|
|
53
|
+
await capture(() => run(["profile", "set", "dev", "--config-root", root]));
|
|
54
|
+
|
|
55
|
+
const current = await capture(() => run(["profile", "current", "--config-root", root]));
|
|
56
|
+
assert.equal(current[0], "dev");
|
|
57
|
+
|
|
58
|
+
const output = await capture(() => run([
|
|
59
|
+
"api",
|
|
60
|
+
"call",
|
|
61
|
+
"todo.list",
|
|
62
|
+
"--config-root",
|
|
63
|
+
root,
|
|
64
|
+
"--dry-run",
|
|
65
|
+
"--json"
|
|
66
|
+
]));
|
|
67
|
+
const payload = JSON.parse(output[0]);
|
|
68
|
+
assert.equal(payload.request.url, "https://dev.example.test/api/todos");
|
|
69
|
+
assert.equal(payload.request.headers["X-Profile"], "dev");
|
|
70
|
+
});
|