@lark-apaas/miaoda-cli 0.1.19-alpha.834fd32 → 0.1.19-alpha.e4d5797
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 +2 -1
- package/dist/cli/commands/registry/index.js +16 -4
- package/dist/cli/handlers/registry/add.js +55 -12
- package/dist/services/deploy/modern/atoms/design-build.js +8 -0
- package/dist/services/deploy/modern/atoms/index.js +2 -1
- package/dist/services/deploy/modern/patch/source-scan.js +2 -0
- package/dist/services/deploy/modern/pipelines/design-local.js +30 -21
- package/dist/utils/http.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -75,6 +75,7 @@ miaoda registry add deck-slide --overwrite # 目标已存在时覆盖(
|
|
|
75
75
|
- **多匹配全拉**:token 命中多个同名条目时全部 copy-in(如 `add foo` 把 `foo.jsx` + `foo.css` 一起拉),想只要其一就用完整文件名或 relPath。
|
|
76
76
|
- **拍平落地**:所有文件**拍平**到项目根(`scripts/deck-slide.js` → 项目 `deck-slide.js`,不保留子目录);闭包内同名 basename 撞车时后者覆盖前者。
|
|
77
77
|
- **skip-by-disk**:项目已有同名(拍平后的 basename)文件默认跳过,`--overwrite` 才覆盖;不写任何安装记账文件,项目文件树即状态。
|
|
78
|
+
- **add 回执带 usage**:`add` 结果的 `entries` 只列**你请求的条目**(不含被 `Depends` 传递拉进来的依赖——依赖照常落地在 `added`/`skipped`,但那是"管道"),逐条给出 `usage`(USAGE 块原文)与 `dependsOn`,Agent `add` 完即可直接读用法,无需再 `registry list`。请求的条目即使已存在被跳过也回带 usage(`status` 标 `added`/`skipped`,据此判断磁盘上是 registry 版还是你改过的旧版)。`--json` 结构为 `{registryVersion, added, skipped, dryRun, entries}`;pretty(默认)输出 `registry@<ver>` + `added:`/`skipped:` 逗号列表 + 各请求条目的 USAGE 块,稳定 label、无 JSON 数组、无截断,对 Agent 与人同样可读。
|
|
78
79
|
- `--version <ver>` 指定 registry 包版本或 dist-tag(缺省 `latest`),`--dir <path>` 指定项目目录(缺省当前目录)。
|
|
79
80
|
|
|
80
81
|
## 全局参数
|
|
@@ -88,7 +89,7 @@ miaoda registry add deck-slide --overwrite # 目标已存在时覆盖(
|
|
|
88
89
|
## 环境变量
|
|
89
90
|
|
|
90
91
|
- `MIAODA_APP_ID`:默认应用 ID,等价于 `--app-id`。
|
|
91
|
-
- `MIAODA_CANARY_HEADER`:HTTP 请求的 `x-tt-env` 小流量头取值。未设置时默认 `
|
|
92
|
+
- `MIAODA_CANARY_HEADER`:HTTP 请求的 `x-tt-env` 小流量头取值。未设置时默认 `boe_miaoda_ccm`;设为空字符串则不带该头(例:`export MIAODA_CANARY_HEADER=boe_xxx`)。值形如 `ppe_xxx` 时额外带上 `x-use-ppe: 1`。
|
|
92
93
|
|
|
93
94
|
## 输出契约
|
|
94
95
|
|
|
@@ -80,10 +80,22 @@ function registerRegistryAdd(parent) {
|
|
|
80
80
|
- skip-by-disk:目标文件已存在默认跳过;--overwrite 才覆盖
|
|
81
81
|
- 不写任何安装记账文件(项目文件树即状态)
|
|
82
82
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
83
|
+
输出(pretty,默认)
|
|
84
|
+
registry@<ver>
|
|
85
|
+
added: <落地 basename 逗号列表> # 含 Depends 闭包全部落地文件
|
|
86
|
+
skipped: <逗号列表> # 仅有跳过时出现
|
|
87
|
+
dry-run: true (no files written) # 仅 --dry-run 时出现
|
|
88
|
+
|
|
89
|
+
# <请求条目落地 basename>
|
|
90
|
+
<该条目 USAGE 块原文> # 只列你请求的条目,依赖不占 usage 位
|
|
91
|
+
|
|
92
|
+
JSON 输出(--json)
|
|
93
|
+
{"data": {"registryVersion": "...", "added": [...], "skipped": [...], "dryRun": false,
|
|
94
|
+
"entries": [{"name": "...", "file": "<来源 relPath>", "dest": "<落地 basename>",
|
|
95
|
+
"status": "added|skipped", "usage": "<USAGE 块原文>", "dependsOn": [...]}, ...]}}
|
|
96
|
+
(added / skipped 覆盖依赖闭包全部落地文件;entries 只列**你请求的条目**
|
|
97
|
+
(不含被 Depends 传递拉入的依赖),逐条给 usage / dependsOn,add 完直接读用法。
|
|
98
|
+
请求的条目即使已存在被 skip 也回带 usage,status 标 added / skipped)
|
|
87
99
|
|
|
88
100
|
示例
|
|
89
101
|
$ miaoda registry add deck-slide
|
|
@@ -9,7 +9,6 @@ const index_1 = require("../../../services/registry/index");
|
|
|
9
9
|
const shared_1 = require("./shared");
|
|
10
10
|
const error_1 = require("../../../utils/error");
|
|
11
11
|
const output_1 = require("../../../utils/output");
|
|
12
|
-
const logger_1 = require("../../../utils/logger");
|
|
13
12
|
/**
|
|
14
13
|
* miaoda registry add <name...> [--overwrite] [--dry-run] [--dir <path>] [--version <ver>]
|
|
15
14
|
*
|
|
@@ -35,18 +34,62 @@ async function handleRegistryAdd(opts) {
|
|
|
35
34
|
overwrite: opts.overwrite === true,
|
|
36
35
|
dryRun: opts.dryRun === true,
|
|
37
36
|
});
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
37
|
+
// entries:**只列用户请求的条目**(opts.names 命中的),给它们的 usage / dependsOn,
|
|
38
|
+
// 让 Agent add 完直接拿到用法、无需再 `registry list`。被 Depends 传递拉进来的依赖是
|
|
39
|
+
// "管道"(照常在 added/skipped 里落地),不占 usage 位。请求的条目即使已存在被 skip
|
|
40
|
+
// 也回带 usage(status=skipped,Agent 借此判断磁盘上是 registry 版还是自己改过的旧版)。
|
|
41
|
+
const requestedRelPaths = new Set();
|
|
42
|
+
for (const token of opts.names) {
|
|
43
|
+
for (const e of plan.entries) {
|
|
44
|
+
if ((0, index_1.tokenMatches)(e, token))
|
|
45
|
+
requestedRelPaths.add(e.relPath);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
// relPath → 落地的 PlannedFile(拿 dest / 落地状态)
|
|
49
|
+
const fileByRelPath = new Map(plan.files.map((f) => [f.srcRelPath, f]));
|
|
50
|
+
const addedSet = new Set(result.added);
|
|
51
|
+
const skippedSet = new Set(result.skipped);
|
|
52
|
+
const entries = plan.entries
|
|
53
|
+
.filter((e) => requestedRelPaths.has(e.relPath))
|
|
54
|
+
.map((e) => {
|
|
55
|
+
const f = fileByRelPath.get(e.relPath);
|
|
56
|
+
const dest = f?.dest ?? e.relPath.split('/').pop() ?? e.relPath;
|
|
57
|
+
const status = skippedSet.has(dest) && !addedSet.has(dest) ? 'skipped' : 'added';
|
|
58
|
+
return {
|
|
59
|
+
name: e.name,
|
|
60
|
+
file: e.relPath,
|
|
61
|
+
dest,
|
|
62
|
+
status,
|
|
63
|
+
usage: e.usage,
|
|
64
|
+
dependsOn: e.dependsOn,
|
|
65
|
+
};
|
|
49
66
|
});
|
|
67
|
+
// 只透出对 add 完的 Agent 可操作的字段:项目里实际多了什么(added)、什么没动(skipped)、
|
|
68
|
+
// 请求条目怎么用(entries)。requested(纯回显)、resolved(包内诊断路径)不透出。
|
|
69
|
+
const data = {
|
|
70
|
+
registryVersion: reg.version,
|
|
71
|
+
added: result.added,
|
|
72
|
+
skipped: result.skipped,
|
|
73
|
+
dryRun: opts.dryRun === true,
|
|
74
|
+
entries,
|
|
75
|
+
};
|
|
76
|
+
if ((0, output_1.isJsonMode)()) {
|
|
77
|
+
(0, output_1.emit)({ data });
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
// pretty 是 Agent 不加 --json 时的默认载荷,也要对 AI 友好:信息量与 JSON 对齐,
|
|
81
|
+
// 但换成稳定 label + 逗号列表(无 JSON 数组、无 TTY 截断、空/默认值不打印),
|
|
82
|
+
// summary 在前、各请求条目的 USAGE 块原文在后。整体走一次纯字符串 emit(不进 key-value 渲染)。
|
|
83
|
+
const summaryLines = [`registry@${reg.version}`];
|
|
84
|
+
if (opts.dryRun === true)
|
|
85
|
+
summaryLines.push('dry-run: true (no files written)');
|
|
86
|
+
if (result.added.length > 0)
|
|
87
|
+
summaryLines.push(`added: ${result.added.join(', ')}`);
|
|
88
|
+
if (result.skipped.length > 0)
|
|
89
|
+
summaryLines.push(`skipped: ${result.skipped.join(', ')}`);
|
|
90
|
+
const blocks = entries.filter((e) => e.usage !== '').map((e) => `# ${e.dest}\n${e.usage}`);
|
|
91
|
+
const parts = [summaryLines.join('\n'), ...blocks];
|
|
92
|
+
(0, output_1.emit)(parts.join('\n\n'));
|
|
50
93
|
}
|
|
51
94
|
finally {
|
|
52
95
|
reg.cleanup();
|
|
@@ -4,6 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.buildDesignOutput = buildDesignOutput;
|
|
7
|
+
exports.cleanDesignDist = cleanDesignDist;
|
|
7
8
|
const node_fs_1 = __importDefault(require("node:fs"));
|
|
8
9
|
const node_path_1 = __importDefault(require("node:path"));
|
|
9
10
|
const error_1 = require("../../../../utils/error");
|
|
@@ -39,3 +40,10 @@ function buildDesignOutput(opts) {
|
|
|
39
40
|
throw new error_1.AppError('DEPLOY_BUILD_FAILED', `design build failed: ${err.message}`);
|
|
40
41
|
}
|
|
41
42
|
}
|
|
43
|
+
/**
|
|
44
|
+
* 删除 <projectDir>/dist(本地构建产物)。幂等:不存在也不报错(force)。
|
|
45
|
+
* design 部署收尾调用,部署动作结束后不在用户项目里留产物。
|
|
46
|
+
*/
|
|
47
|
+
function cleanDesignDist(projectDir) {
|
|
48
|
+
node_fs_1.default.rmSync(node_path_1.default.join(projectDir, constants_1.DIST_DIR), { recursive: true, force: true });
|
|
49
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.savePluginInstances = exports.LocalReleaseStatus = exports.finalizeLocalRelease = exports.createLocalRelease = exports.uploadArtifacts = exports.uploadDesignArtifacts = exports.buildDesignOutput = exports.runBuild = exports.preRelease = exports.prepareDeployContext = void 0;
|
|
3
|
+
exports.savePluginInstances = exports.LocalReleaseStatus = exports.finalizeLocalRelease = exports.createLocalRelease = exports.uploadArtifacts = exports.uploadDesignArtifacts = exports.cleanDesignDist = exports.buildDesignOutput = exports.runBuild = exports.preRelease = exports.prepareDeployContext = void 0;
|
|
4
4
|
var context_1 = require("./context");
|
|
5
5
|
Object.defineProperty(exports, "prepareDeployContext", { enumerable: true, get: function () { return context_1.prepareDeployContext; } });
|
|
6
6
|
var pre_release_1 = require("./pre-release");
|
|
@@ -9,6 +9,7 @@ var build_1 = require("./build");
|
|
|
9
9
|
Object.defineProperty(exports, "runBuild", { enumerable: true, get: function () { return build_1.runBuild; } });
|
|
10
10
|
var design_build_1 = require("./design-build");
|
|
11
11
|
Object.defineProperty(exports, "buildDesignOutput", { enumerable: true, get: function () { return design_build_1.buildDesignOutput; } });
|
|
12
|
+
Object.defineProperty(exports, "cleanDesignDist", { enumerable: true, get: function () { return design_build_1.cleanDesignDist; } });
|
|
12
13
|
var design_upload_1 = require("./design-upload");
|
|
13
14
|
Object.defineProperty(exports, "uploadDesignArtifacts", { enumerable: true, get: function () { return design_upload_1.uploadDesignArtifacts; } });
|
|
14
15
|
var upload_1 = require("./upload");
|
|
@@ -20,28 +20,37 @@ async function designLocalPublishPipeline(opts) {
|
|
|
20
20
|
throw new error_1.AppError('DEPLOY_PRE_RELEASE_DATA_MISSING', 'preRelease did not return a `data` map — backend tcc may not be configured for current template_key');
|
|
21
21
|
}
|
|
22
22
|
const data = pre.data;
|
|
23
|
-
|
|
24
|
-
(0, index_1.buildDesignOutput)({ projectDir: ctx.projectDir });
|
|
25
|
-
}
|
|
26
|
-
(0, logger_1.log)('deploy', 'Creating local release...');
|
|
27
|
-
const release = await (0, index_1.createLocalRelease)(ctx.appId, pre.version);
|
|
23
|
+
// dist 是本地构建产物,部署动作结束(无论成败)都清掉,不在用户项目里留产物。
|
|
28
24
|
try {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
await (0, index_1.
|
|
34
|
-
|
|
25
|
+
if (!opts.skipBuild) {
|
|
26
|
+
(0, index_1.buildDesignOutput)({ projectDir: ctx.projectDir });
|
|
27
|
+
}
|
|
28
|
+
(0, logger_1.log)('deploy', 'Creating local release...');
|
|
29
|
+
const release = await (0, index_1.createLocalRelease)(ctx.appId, pre.version, {
|
|
30
|
+
checkPointVersion: opts.checkPointVersion,
|
|
31
|
+
commitID: opts.commitID,
|
|
32
|
+
});
|
|
33
|
+
try {
|
|
34
|
+
await (0, index_1.uploadDesignArtifacts)({ projectDir: ctx.projectDir, data });
|
|
35
|
+
await (0, index_1.finalizeLocalRelease)(ctx.appId, release.releaseID, index_1.LocalReleaseStatus.Finished);
|
|
36
|
+
}
|
|
37
|
+
catch (err) {
|
|
38
|
+
await (0, index_1.finalizeLocalRelease)(ctx.appId, release.releaseID, index_1.LocalReleaseStatus.Failed);
|
|
39
|
+
throw err;
|
|
40
|
+
}
|
|
41
|
+
if (release.onlineUrl !== undefined && release.onlineUrl !== '') {
|
|
42
|
+
(0, spark_meta_1.writeSparkMeta)(ctx.projectDir, { appUrl: release.onlineUrl });
|
|
43
|
+
}
|
|
44
|
+
(0, logger_1.log)('deploy', 'Deployed successfully');
|
|
45
|
+
return {
|
|
46
|
+
appId: ctx.appId,
|
|
47
|
+
version: pre.version,
|
|
48
|
+
url: release.onlineUrl ?? '',
|
|
49
|
+
releaseID: release.releaseID,
|
|
50
|
+
preReleaseID: pre.preReleaseID,
|
|
51
|
+
};
|
|
35
52
|
}
|
|
36
|
-
|
|
37
|
-
(0,
|
|
53
|
+
finally {
|
|
54
|
+
(0, index_1.cleanDesignDist)(ctx.projectDir);
|
|
38
55
|
}
|
|
39
|
-
(0, logger_1.log)('deploy', 'Deployed successfully');
|
|
40
|
-
return {
|
|
41
|
-
appId: ctx.appId,
|
|
42
|
-
version: pre.version,
|
|
43
|
-
url: release.onlineUrl ?? '',
|
|
44
|
-
releaseID: release.releaseID,
|
|
45
|
-
preReleaseID: pre.preReleaseID,
|
|
46
|
-
};
|
|
47
56
|
}
|
package/dist/utils/http.js
CHANGED
|
@@ -64,7 +64,7 @@ function createClient(opts) {
|
|
|
64
64
|
* 默认灰度泳道。当前 miaoda CLI 接入的新接口(modern deploy 等)只在该泳道生效,
|
|
65
65
|
* 缺省走这个。MIAODA_CANARY_HEADER 可显式覆盖;设为空字符串则去掉头。
|
|
66
66
|
*/
|
|
67
|
-
const DEFAULT_CANARY_HEADER = '
|
|
67
|
+
const DEFAULT_CANARY_HEADER = 'boe_miaoda_ccm';
|
|
68
68
|
/**
|
|
69
69
|
* 注入 x-tt-env 小流量头:env 显式设值 > DEFAULT_CANARY_HEADER。
|
|
70
70
|
*
|