@lark-apaas/miaoda-cli 0.1.4 → 0.1.5-alpha.2f1e0ff
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 +6 -5
- package/dist/api/deploy/index.js +13 -1
- package/dist/api/deploy/modern-types.js +23 -0
- package/dist/api/deploy/modern.js +78 -0
- package/dist/api/deploy/plugin-instances-types.js +6 -0
- package/dist/api/deploy/plugin-instances.js +22 -0
- package/dist/api/observability/api.js +10 -0
- package/dist/api/observability/index.js +2 -1
- package/dist/cli/commands/app/index.js +144 -2
- package/dist/cli/commands/deploy/modern.js +50 -0
- package/dist/cli/commands/index.js +68 -5
- package/dist/cli/commands/observability/index.js +62 -6
- package/dist/cli/commands/shared.js +5 -0
- package/dist/cli/commands/skills/index.js +79 -0
- package/dist/cli/handlers/app/index.js +9 -1
- package/dist/cli/handlers/app/init.js +132 -0
- package/dist/cli/handlers/app/sync.js +215 -0
- package/dist/cli/handlers/deploy/modern.js +33 -0
- package/dist/cli/handlers/observability/helpers.js +4 -0
- package/dist/cli/handlers/observability/index.js +3 -1
- package/dist/cli/handlers/observability/log.js +8 -2
- package/dist/cli/handlers/observability/source-stack.js +389 -0
- package/dist/cli/handlers/observability/trace.js +7 -1
- package/dist/cli/handlers/skills/index.js +7 -0
- package/dist/cli/handlers/skills/status.js +31 -0
- package/dist/cli/handlers/skills/sync.js +49 -0
- package/dist/config/fullstack-cli-pin.js +17 -0
- package/dist/config/sync-configs/design-stack.js +98 -0
- package/dist/config/sync-configs/index.js +62 -0
- package/dist/config/sync-configs/nestjs-react-fullstack.js +177 -0
- package/dist/config/sync.js +14 -0
- package/dist/services/app/init/index.js +12 -0
- package/dist/services/app/init/install.js +123 -0
- package/dist/services/app/init/template.js +108 -0
- package/dist/services/deploy/modern/atoms/build.js +59 -0
- package/dist/services/deploy/modern/atoms/context.js +27 -0
- package/dist/services/deploy/modern/atoms/index.js +17 -0
- package/dist/services/deploy/modern/atoms/local-release.js +27 -0
- package/dist/services/deploy/modern/atoms/pre-release.js +13 -0
- package/dist/services/deploy/modern/atoms/save-plugin-instances.js +72 -0
- package/dist/services/deploy/modern/atoms/upload.js +246 -0
- package/dist/services/deploy/modern/check.js +53 -0
- package/dist/services/deploy/modern/constants.js +13 -0
- package/dist/services/deploy/modern/index.js +16 -0
- package/dist/services/deploy/modern/pipelines/index.js +5 -0
- package/dist/services/deploy/modern/pipelines/local.js +75 -0
- package/dist/services/deploy/modern/protocol.js +122 -0
- package/dist/services/deploy/modern/run-types.js +4 -0
- package/dist/services/deploy/modern/run.js +13 -0
- package/dist/services/deploy/modern/template-key-map.js +22 -0
- package/dist/services/skills/index.js +5 -0
- package/dist/services/skills/status.js +37 -0
- package/dist/utils/coding-steering.js +169 -0
- package/dist/utils/file-ops.js +45 -0
- package/dist/utils/git.js +22 -0
- package/dist/utils/githooks.js +55 -0
- package/dist/utils/http.js +21 -11
- package/dist/utils/merge-json.js +63 -0
- package/dist/utils/npm-pack.js +55 -0
- package/dist/utils/platform-sync.js +160 -0
- package/dist/utils/spark-meta.js +42 -0
- package/dist/utils/sync-rule.js +295 -0
- package/package.json +5 -3
- package/upgrade/templates/README.md +34 -0
- package/upgrade/templates/design-stack/templates/.githooks/pre-commit +4 -0
- package/upgrade/templates/design-stack/templates/scripts/dev-local.sh +53 -0
- package/upgrade/templates/design-stack/templates/scripts/dev.sh +25 -0
- package/upgrade/templates/design-stack/templates/scripts/hooks/run-precommit.js +37 -0
- package/upgrade/templates/nestjs-react-fullstack/templates/.githooks/pre-commit +4 -0
- package/upgrade/templates/nestjs-react-fullstack/templates/.gitignore.append +8 -0
- package/upgrade/templates/nestjs-react-fullstack/templates/.spark_project +16 -0
- package/upgrade/templates/nestjs-react-fullstack/templates/drizzle.config.ts +55 -0
- package/upgrade/templates/nestjs-react-fullstack/templates/helper/gen-openapi.ts +34 -0
- package/upgrade/templates/nestjs-react-fullstack/templates/nest-cli.json +25 -0
- package/upgrade/templates/nestjs-react-fullstack/templates/scripts/build.sh +207 -0
- package/upgrade/templates/nestjs-react-fullstack/templates/scripts/dev-local.sh +61 -0
- package/upgrade/templates/nestjs-react-fullstack/templates/scripts/dev.js +295 -0
- package/upgrade/templates/nestjs-react-fullstack/templates/scripts/dev.sh +25 -0
- package/upgrade/templates/nestjs-react-fullstack/templates/scripts/hooks/run-precommit.js +37 -0
- package/upgrade/templates/nestjs-react-fullstack/templates/scripts/lint.js +150 -0
- package/upgrade/templates/nestjs-react-fullstack/templates/scripts/prune-smart.js +330 -0
- package/upgrade/templates/nestjs-react-fullstack/templates/scripts/run.sh +8 -0
- package/upgrade/templates/nestjs-react-fullstack/templates/server/global.d.ts +19 -0
- package/upgrade/templates/nestjs-react-fullstack/templates/tsconfig.node.json +5 -0
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* 按 stack 短名拿到对应的 SyncConfig + 模板源根目录。
|
|
4
|
+
*
|
|
5
|
+
* - 类型化的 SyncConfig 放在 src/config/sync-configs/<stack>.ts(被 tsc 编进 dist 一起发)。
|
|
6
|
+
* - 模板资源文件放在 upgrade/templates/<stack>/templates/(cli 发布时整个目录原样 ship)。
|
|
7
|
+
*
|
|
8
|
+
* handler 拿到 stack 后,先 getSyncConfig 拿 rule 列表,再 getStackTemplatesRoot 拿模板根,
|
|
9
|
+
* 一起喂给 applySyncRules。
|
|
10
|
+
*
|
|
11
|
+
* 新加 stack:
|
|
12
|
+
* 1. src/config/sync-configs/<stack>.ts 里 export default SYNC_CONFIG
|
|
13
|
+
* 2. upgrade/templates/<stack>/templates/ 下放对应资源文件
|
|
14
|
+
* 3. 在 STACK_REGISTRY 里加一条
|
|
15
|
+
*/
|
|
16
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
17
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
18
|
+
};
|
|
19
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
+
exports.getSyncConfig = getSyncConfig;
|
|
21
|
+
exports.getStackTemplatesRoot = getStackTemplatesRoot;
|
|
22
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
23
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
24
|
+
const nestjs_react_fullstack_1 = __importDefault(require("./nestjs-react-fullstack"));
|
|
25
|
+
const design_stack_1 = __importDefault(require("./design-stack"));
|
|
26
|
+
/**
|
|
27
|
+
* 已纳入新 sync 机制的 stack 注册表。未在表里的 stack(如老 vite-react / html)走旧的
|
|
28
|
+
* `upgrade/templates/<stack>/{files,patches}` 机制,由 sync handler 兜底。
|
|
29
|
+
*/
|
|
30
|
+
const STACK_REGISTRY = {
|
|
31
|
+
'nestjs-react-fullstack': nestjs_react_fullstack_1.default,
|
|
32
|
+
'design-stack': design_stack_1.default,
|
|
33
|
+
};
|
|
34
|
+
/** 返回该 stack 的 SyncConfig;表里没有时返回 null。 */
|
|
35
|
+
function getSyncConfig(stack) {
|
|
36
|
+
return STACK_REGISTRY[stack] ?? null;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* 计算 stack 模板资源根目录(绝对路径)。
|
|
40
|
+
*
|
|
41
|
+
* cli 发布时 upgrade/ 目录整个 ship,编译产物在 dist/ 下若干层。从当前模块向上回溯找含
|
|
42
|
+
* upgrade/ + package.json 的目录就是 cli 根。
|
|
43
|
+
*
|
|
44
|
+
* 跟 utils/platform-sync.ts 同款 pattern;保持对齐避免两边漂移。
|
|
45
|
+
*/
|
|
46
|
+
function getStackTemplatesRoot(stack) {
|
|
47
|
+
return node_path_1.default.join(findCliRoot(), 'upgrade', 'templates', stack, 'templates');
|
|
48
|
+
}
|
|
49
|
+
let cliRootCache = null;
|
|
50
|
+
function findCliRoot() {
|
|
51
|
+
if (cliRootCache !== null)
|
|
52
|
+
return cliRootCache;
|
|
53
|
+
let dir = __dirname;
|
|
54
|
+
while (dir !== node_path_1.default.dirname(dir)) {
|
|
55
|
+
if (node_fs_1.default.existsSync(node_path_1.default.join(dir, 'upgrade')) && node_fs_1.default.existsSync(node_path_1.default.join(dir, 'package.json'))) {
|
|
56
|
+
cliRootCache = dir;
|
|
57
|
+
return dir;
|
|
58
|
+
}
|
|
59
|
+
dir = node_path_1.default.dirname(dir);
|
|
60
|
+
}
|
|
61
|
+
throw new Error(`miaoda-cli root (containing upgrade/) not found from ${__dirname}`);
|
|
62
|
+
}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* nestjs-react-fullstack stack 的 sync 规则。
|
|
4
|
+
*
|
|
5
|
+
* 跟沙箱里 `npm run upgrade → npx fullstack-cli sync --disable-gen-openapi` 行为对齐
|
|
6
|
+
* (fullstack-cli/src/config/sync.ts),新增的 miaoda-cli 本地开发规则单独标注。
|
|
7
|
+
*
|
|
8
|
+
* 改这里请同步把 user app 端到端 smoke 跑一次(init → sync → npm run dev)。
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.SYNC_CONFIG = void 0;
|
|
12
|
+
const fullstack_cli_pin_1 = require("../../config/fullstack-cli-pin");
|
|
13
|
+
exports.SYNC_CONFIG = {
|
|
14
|
+
sync: [
|
|
15
|
+
// ===== fullstack-cli sync 同款规则(对齐沙箱行为) =====
|
|
16
|
+
// 1. 派生 scripts 目录(包含 dev.sh / dev-local.sh / dev.js / build.sh / run.sh /
|
|
17
|
+
// lint.js / prune-smart.js / hooks/run-precommit.js;directory rule 自动给 .sh +x)
|
|
18
|
+
{
|
|
19
|
+
type: 'directory',
|
|
20
|
+
from: 'scripts',
|
|
21
|
+
to: 'scripts',
|
|
22
|
+
overwrite: true,
|
|
23
|
+
},
|
|
24
|
+
// 1a. 同步 .githooks 目录(hook 入口,可执行 sh 脚本)
|
|
25
|
+
{
|
|
26
|
+
type: 'directory',
|
|
27
|
+
from: '.githooks',
|
|
28
|
+
to: '.githooks',
|
|
29
|
+
overwrite: true,
|
|
30
|
+
},
|
|
31
|
+
// 1b. scripts.prepare:npm install 后自动激活 git hooks(原生 git,无第三方依赖)
|
|
32
|
+
// 直接写 core.hooksPath,并保底给 pre-commit 加执行位;非 git 仓库下静默退出
|
|
33
|
+
{
|
|
34
|
+
type: 'add-script',
|
|
35
|
+
name: 'prepare',
|
|
36
|
+
command: 'chmod +x .githooks/pre-commit 2>/dev/null; git config core.hooksPath .githooks 2>/dev/null || true',
|
|
37
|
+
overwrite: false,
|
|
38
|
+
},
|
|
39
|
+
// 1c. scripts.precommit = pre-commit 真正的执行体(跑 npm run lint)
|
|
40
|
+
{
|
|
41
|
+
type: 'add-script',
|
|
42
|
+
name: 'precommit',
|
|
43
|
+
command: 'node scripts/hooks/run-precommit.js',
|
|
44
|
+
overwrite: false,
|
|
45
|
+
},
|
|
46
|
+
// 2. 智能合并 nest-cli.json 配置(保留用户自定义的 assets、plugins 等)
|
|
47
|
+
{
|
|
48
|
+
type: 'merge-json',
|
|
49
|
+
from: 'nest-cli.json',
|
|
50
|
+
to: 'nest-cli.json',
|
|
51
|
+
arrayMerge: {
|
|
52
|
+
'compilerOptions.assets': { key: 'include' },
|
|
53
|
+
'compilerOptions.plugins': { key: 'name' },
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
// 3. 删除 .swc 缓存目录(如果存在)
|
|
57
|
+
{
|
|
58
|
+
type: 'delete-directory',
|
|
59
|
+
to: '.swc',
|
|
60
|
+
},
|
|
61
|
+
// 4. 从 .gitignore 中移除 package-lock.json
|
|
62
|
+
{
|
|
63
|
+
type: 'remove-line',
|
|
64
|
+
to: '.gitignore',
|
|
65
|
+
pattern: 'package-lock.json',
|
|
66
|
+
},
|
|
67
|
+
// 5. 注册 postinstall 脚本,自动恢复 action plugins。
|
|
68
|
+
// 用 npx -y 形式而不是裸 fullstack-cli:用户项目的 deps 没有 fullstack-cli,
|
|
69
|
+
// bare 形式在新机器(PATH 没全局 fullstack-cli)下 npm i 立即 ENOENT。
|
|
70
|
+
// fullstack-cli 版本临时钉到 FULLSTACK_CLI_PIN_SPEC,避免 npx 走 latest 碰外部回归版本。
|
|
71
|
+
{
|
|
72
|
+
type: 'add-script',
|
|
73
|
+
name: 'postinstall',
|
|
74
|
+
command: `npx -y ${fullstack_cli_pin_1.FULLSTACK_CLI_PIN_SPEC} action-plugin init`,
|
|
75
|
+
overwrite: false,
|
|
76
|
+
},
|
|
77
|
+
// 5a. 迁移已有应用的老形式 postinstall(裸 fullstack-cli → npx -y 钉版)。
|
|
78
|
+
// patch-script 只在脚本以指定前缀开头时改写,用户真正手改过的脚本保持原样。
|
|
79
|
+
{
|
|
80
|
+
type: 'patch-script',
|
|
81
|
+
name: 'postinstall',
|
|
82
|
+
to: `npx -y ${fullstack_cli_pin_1.FULLSTACK_CLI_PIN_SPEC} action-plugin init`,
|
|
83
|
+
ifStartsWith: 'fullstack-cli action-plugin init',
|
|
84
|
+
},
|
|
85
|
+
// 5b. 迁移已有应用 npx 未钉版的 postinstall —— sync 之前的版本生成的是
|
|
86
|
+
// `npx -y @lark-apaas/fullstack-cli action-plugin init`(无版本号),现在统一钉版。
|
|
87
|
+
{
|
|
88
|
+
type: 'patch-script',
|
|
89
|
+
name: 'postinstall',
|
|
90
|
+
to: `npx -y ${fullstack_cli_pin_1.FULLSTACK_CLI_PIN_SPEC} action-plugin init`,
|
|
91
|
+
ifStartsWith: 'npx -y @lark-apaas/fullstack-cli action-plugin init',
|
|
92
|
+
},
|
|
93
|
+
// 5c. gen:db-schema —— 把裸 `fullstack-cli gen-db-schema` 迁到钉版 npx。
|
|
94
|
+
// 这条只在 user app 自己 package.json 已经有 gen:db-schema 时才动(patch-script
|
|
95
|
+
// 语义),新模板里如果有就一并升级。
|
|
96
|
+
{
|
|
97
|
+
type: 'patch-script',
|
|
98
|
+
name: 'gen:db-schema',
|
|
99
|
+
to: `npx -y ${fullstack_cli_pin_1.FULLSTACK_CLI_PIN_SPEC} gen-db-schema`,
|
|
100
|
+
ifStartsWith: 'fullstack-cli gen-db-schema',
|
|
101
|
+
},
|
|
102
|
+
// 6. 替换 drizzle.config.ts(仅当文件存在时)
|
|
103
|
+
{
|
|
104
|
+
type: 'file',
|
|
105
|
+
from: 'drizzle.config.ts',
|
|
106
|
+
to: 'drizzle.config.ts',
|
|
107
|
+
overwrite: true,
|
|
108
|
+
onlyIfExists: true,
|
|
109
|
+
},
|
|
110
|
+
// 7. 确保 .gitignore 包含 .agent/ 目录
|
|
111
|
+
{
|
|
112
|
+
type: 'add-line',
|
|
113
|
+
to: '.gitignore',
|
|
114
|
+
line: '.agent/',
|
|
115
|
+
},
|
|
116
|
+
// 8. 同步 .spark_project 配置文件(总是覆盖)
|
|
117
|
+
{
|
|
118
|
+
type: 'file',
|
|
119
|
+
from: '.spark_project',
|
|
120
|
+
to: '.spark_project',
|
|
121
|
+
overwrite: true,
|
|
122
|
+
},
|
|
123
|
+
// 9. 把模板版本的 lint 脚本替换为支持 --files 的 runner
|
|
124
|
+
// 只识别平台模板生成的 `concurrently ...` 形态,用户真正改写过的脚本保持原样
|
|
125
|
+
{
|
|
126
|
+
type: 'patch-script',
|
|
127
|
+
name: 'lint',
|
|
128
|
+
to: 'node ./scripts/lint.js',
|
|
129
|
+
ifStartsWith: 'concurrently ',
|
|
130
|
+
},
|
|
131
|
+
// 10. 把老 `npm run upgrade && ./scripts/dev.sh` 形式迁移到 `./scripts/dev.sh`,
|
|
132
|
+
// 让本地 `npm run dev` 不再前置跑 fullstack-cli sync。新版 dev.sh 按 SANDBOX_ID 是否非空
|
|
133
|
+
// 判分支:沙箱直接 exec dev.js(脚本同步由平台 pod 启动时做过,dev 入口不再 upgrade);
|
|
134
|
+
// 本地走 miaoda app sync 兜底 + dev-local.sh。
|
|
135
|
+
{
|
|
136
|
+
type: 'patch-script',
|
|
137
|
+
name: 'dev',
|
|
138
|
+
to: './scripts/dev.sh',
|
|
139
|
+
ifStartsWith: 'npm run upgrade && ',
|
|
140
|
+
},
|
|
141
|
+
// 11. 把 `upgrade` 脚本里裸 `fullstack-cli sync` 改成钉版 npx。
|
|
142
|
+
// 跟 postinstall 同款根因:fullstack-cli 不是用户应用的 dep,新机器无全局命令会 ENOENT。
|
|
143
|
+
{
|
|
144
|
+
type: 'patch-script',
|
|
145
|
+
name: 'upgrade',
|
|
146
|
+
to: `npx -y ${fullstack_cli_pin_1.FULLSTACK_CLI_PIN_SPEC} sync --disable-gen-openapi`,
|
|
147
|
+
ifStartsWith: 'fullstack-cli sync',
|
|
148
|
+
},
|
|
149
|
+
// 11a. 迁移已有 npx 未钉版的 upgrade
|
|
150
|
+
{
|
|
151
|
+
type: 'patch-script',
|
|
152
|
+
name: 'upgrade',
|
|
153
|
+
to: `npx -y ${fullstack_cli_pin_1.FULLSTACK_CLI_PIN_SPEC} sync --disable-gen-openapi`,
|
|
154
|
+
ifStartsWith: 'npx -y @lark-apaas/fullstack-cli sync',
|
|
155
|
+
},
|
|
156
|
+
// ===== miaoda-cli 本地开发新增规则(fullstack-cli sync 不会执行) =====
|
|
157
|
+
// M1. scripts.dev:local —— 本地用户绕过 SANDBOX_ID 分发直接跑本地链路(npm run dev:local)。
|
|
158
|
+
// dev.sh 在 SANDBOX_ID 非空时跑 dev.js(沙箱保活)、否则 exec dev-local.sh;显式 dev:local
|
|
159
|
+
// 用于 agent 在本地稳定调试,不受任何 env 影响。
|
|
160
|
+
{
|
|
161
|
+
type: 'add-script',
|
|
162
|
+
name: 'dev:local',
|
|
163
|
+
command: './scripts/dev-local.sh',
|
|
164
|
+
overwrite: false,
|
|
165
|
+
},
|
|
166
|
+
// M2. tsconfig.node.json 合并 watchOptions.preserveWatchOutput —— tsc --watch 默认每次
|
|
167
|
+
// 重编译都会 clear screen + scrollback,本地 nest start --watch 跑下来日志全没。打开
|
|
168
|
+
// preserveWatchOutput 让 watch 模式追加而不是清屏。模板只放需要 merge 的几个字段,
|
|
169
|
+
// 不动用户的 compilerOptions / include / exclude。
|
|
170
|
+
{
|
|
171
|
+
type: 'merge-json',
|
|
172
|
+
from: 'tsconfig.node.json',
|
|
173
|
+
to: 'tsconfig.node.json',
|
|
174
|
+
},
|
|
175
|
+
],
|
|
176
|
+
};
|
|
177
|
+
exports.default = exports.SYNC_CONFIG;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* SyncRule 类型定义 —— miaoda app sync 的核心抽象。
|
|
4
|
+
*
|
|
5
|
+
* 完整搬自 @lark-apaas/fullstack-cli(packages/tools/fullstack-cli/src/config/sync.ts),
|
|
6
|
+
* 保持 rule shape 与 fullstack-cli 严格一致。沙箱里跑的 `npm run upgrade →
|
|
7
|
+
* npx fullstack-cli sync` 走 fullstack-cli 一侧;本地 `miaoda app sync` 走 miaoda-cli
|
|
8
|
+
* 一侧。两边的 apply 行为对齐,rule 配置则按 stack 拆开(每个 stack 一份
|
|
9
|
+
* upgrade/templates/<stack>/sync.config.ts)。
|
|
10
|
+
*
|
|
11
|
+
* 不同于 fullstack-cli 把 rule 全局 hardcode 在包内:miaoda-cli 把 rule 拆到 stack 级别
|
|
12
|
+
* 文件,便于 nestjs-react-fullstack / vite-react / html / design-stack 各自维护。
|
|
13
|
+
*/
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.installDependencies = exports.writeSparkMeta = exports.readSparkMeta = exports.TEMPLATE_PACKAGE_BY_STACK = exports.SUPPORTED_STACKS = exports.renderTemplate = void 0;
|
|
4
|
+
var template_1 = require("./template");
|
|
5
|
+
Object.defineProperty(exports, "renderTemplate", { enumerable: true, get: function () { return template_1.renderTemplate; } });
|
|
6
|
+
Object.defineProperty(exports, "SUPPORTED_STACKS", { enumerable: true, get: function () { return template_1.SUPPORTED_STACKS; } });
|
|
7
|
+
Object.defineProperty(exports, "TEMPLATE_PACKAGE_BY_STACK", { enumerable: true, get: function () { return template_1.TEMPLATE_PACKAGE_BY_STACK; } });
|
|
8
|
+
var spark_meta_1 = require("../../../utils/spark-meta");
|
|
9
|
+
Object.defineProperty(exports, "readSparkMeta", { enumerable: true, get: function () { return spark_meta_1.readSparkMeta; } });
|
|
10
|
+
Object.defineProperty(exports, "writeSparkMeta", { enumerable: true, get: function () { return spark_meta_1.writeSparkMeta; } });
|
|
11
|
+
var install_1 = require("./install");
|
|
12
|
+
Object.defineProperty(exports, "installDependencies", { enumerable: true, get: function () { return install_1.installDependencies; } });
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.installDependencies = installDependencies;
|
|
7
|
+
const node_child_process_1 = require("node:child_process");
|
|
8
|
+
const node_crypto_1 = __importDefault(require("node:crypto"));
|
|
9
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
10
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
11
|
+
const error_1 = require("../../../utils/error");
|
|
12
|
+
const logger_1 = require("../../../utils/logger");
|
|
13
|
+
const DEP_CACHE_ENV = 'MIAODA_DEP_CACHE_DIR';
|
|
14
|
+
/**
|
|
15
|
+
* 依赖安装。
|
|
16
|
+
*
|
|
17
|
+
* 优先级:
|
|
18
|
+
* 1. skip=true → 直接返回 source=skipped
|
|
19
|
+
* 2. MIAODA_DEP_CACHE_DIR 设了 + 目标目录有 package.json:
|
|
20
|
+
* - 算 md5(package.json)(与 CI 生产端 dep-cache pipeline 一致)
|
|
21
|
+
* - 若 ${cache}/${hash}.zip 存在 → unzip 到目标目录
|
|
22
|
+
* - 校验 node_modules/ 非空:通过则 source=cache,否则 fallback npm install
|
|
23
|
+
* - zip 不存在 → fallback npm install,但 hash 仍记录
|
|
24
|
+
* 3. `npm install --no-audit --no-fund`
|
|
25
|
+
*
|
|
26
|
+
* 不做 cache 回写(read-only)。
|
|
27
|
+
*/
|
|
28
|
+
function installDependencies(opts) {
|
|
29
|
+
if (opts.skip) {
|
|
30
|
+
(0, logger_1.log)('init', 'Skipping dependency install (--skip-install)');
|
|
31
|
+
return { installed: false, source: 'skipped' };
|
|
32
|
+
}
|
|
33
|
+
const childStdio = stdioFor(opts.quietStdout);
|
|
34
|
+
const cacheDir = process.env[DEP_CACHE_ENV];
|
|
35
|
+
const pkgJsonPath = node_path_1.default.join(opts.targetDir, 'package.json');
|
|
36
|
+
const hasPkg = node_fs_1.default.existsSync(pkgJsonPath);
|
|
37
|
+
if (cacheDir && hasPkg) {
|
|
38
|
+
const hash = md5File(pkgJsonPath);
|
|
39
|
+
const cacheZip = node_path_1.default.join(cacheDir, `${hash}.zip`);
|
|
40
|
+
if (node_fs_1.default.existsSync(cacheZip)) {
|
|
41
|
+
(0, logger_1.log)('init', `Cache hit: ${cacheZip}`);
|
|
42
|
+
extractZip(cacheZip, opts.targetDir, childStdio);
|
|
43
|
+
if (nodeModulesUsable(opts.targetDir)) {
|
|
44
|
+
return { installed: true, source: 'cache', hash, cacheZip };
|
|
45
|
+
}
|
|
46
|
+
(0, logger_1.log)('init', 'Cache zip extracted but node_modules/ missing or empty; falling back to npm install');
|
|
47
|
+
return runInstallSoft(opts.targetDir, childStdio, hash);
|
|
48
|
+
}
|
|
49
|
+
(0, logger_1.log)('init', `Cache miss for ${hash}.zip, falling back to npm install`);
|
|
50
|
+
return runInstallSoft(opts.targetDir, childStdio, hash);
|
|
51
|
+
}
|
|
52
|
+
if (cacheDir && !hasPkg) {
|
|
53
|
+
(0, logger_1.log)('init', `${DEP_CACHE_ENV} set but no package.json in target; running npm install`);
|
|
54
|
+
}
|
|
55
|
+
return runInstallSoft(opts.targetDir, childStdio);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* 跑 npm install;失败不抛错,返回 source='failed' 让上层 init handler 继续走 writeSparkMeta
|
|
59
|
+
* 等后续步骤(避免 install 挂了 .spark/meta.json 没写出来,下次 init 看到半渲染状态又得重跑全套)。
|
|
60
|
+
* 失败信息通过 stderr 直出 + emit data.installError 透传给用户。
|
|
61
|
+
*/
|
|
62
|
+
function runInstallSoft(targetDir, stdio, hash) {
|
|
63
|
+
try {
|
|
64
|
+
runNpmInstall(targetDir, stdio);
|
|
65
|
+
return { installed: true, source: 'npm', hash };
|
|
66
|
+
}
|
|
67
|
+
catch (err) {
|
|
68
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
69
|
+
(0, logger_1.log)('init', `⚠ npm install failed (continuing init): ${msg}`);
|
|
70
|
+
return { installed: false, source: 'failed', hash, error: msg };
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
function nodeModulesUsable(targetDir) {
|
|
74
|
+
const nm = node_path_1.default.join(targetDir, 'node_modules');
|
|
75
|
+
if (!node_fs_1.default.existsSync(nm))
|
|
76
|
+
return false;
|
|
77
|
+
try {
|
|
78
|
+
return node_fs_1.default.readdirSync(nm).length > 0;
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
function stdioFor(quietStdout) {
|
|
85
|
+
// quietStdout=true:子进程 stdout 重定向到 fd 2(父进程 stderr),
|
|
86
|
+
// 保留 stderr 直出 → 终端仍能看到 npm install 进度,但父进程 stdout 干净,
|
|
87
|
+
// 后续 emit(JSON) 不会被污染。
|
|
88
|
+
return quietStdout ? ['ignore', 2, 'inherit'] : ['ignore', 'inherit', 'inherit'];
|
|
89
|
+
}
|
|
90
|
+
function md5File(filePath) {
|
|
91
|
+
const buf = node_fs_1.default.readFileSync(filePath);
|
|
92
|
+
return node_crypto_1.default.createHash('md5').update(buf).digest('hex');
|
|
93
|
+
}
|
|
94
|
+
function extractZip(zipPath, targetDir, stdio) {
|
|
95
|
+
try {
|
|
96
|
+
(0, node_child_process_1.execFileSync)('unzip', ['-q', '-o', zipPath, '-d', targetDir], { stdio });
|
|
97
|
+
}
|
|
98
|
+
catch (err) {
|
|
99
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
100
|
+
throw new error_1.AppError('DEP_CACHE_EXTRACT_FAILED', `解压依赖缓存失败 (${zipPath}): ${msg}`, {
|
|
101
|
+
next_actions: [`确认 ${zipPath} 是合法 zip`, `或 unset ${DEP_CACHE_ENV} 走 npm install`],
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* 显式钉死 npmmirror。原因:
|
|
107
|
+
* - user 全局 `~/.npmrc` 千奇百怪(bnpm / npmjs / 自定义代理),npm config 层叠下
|
|
108
|
+
* CLI flag 优先级最高,写在这里能盖掉所有上游配置,行为可预测。
|
|
109
|
+
* - 模板 `_npmrc → .npmrc` 虽然项目级 registry 写得是 npmmirror,但只在 cwd 含 .npmrc
|
|
110
|
+
* 时才生效,env / CLI 层先到先得,落到这里钉死最稳。
|
|
111
|
+
* - 字节内网 DNS 会把 npmmirror 域名透明指向公司镜像,外网就是公网阿里源;同一行配置
|
|
112
|
+
* 在两套环境都拉得到 @lark-apaas/* 私包(内网经公司镜像,外网经阿里同步过去的副本)。
|
|
113
|
+
* - 留 `MIAODA_NPM_REGISTRY` env 应急覆盖。
|
|
114
|
+
*/
|
|
115
|
+
const NPM_INSTALL_REGISTRY_DEFAULT = 'https://registry.npmmirror.com/';
|
|
116
|
+
function runNpmInstall(targetDir, stdio) {
|
|
117
|
+
(0, logger_1.log)('init', `npm install in ${targetDir}...`);
|
|
118
|
+
const registry = process.env.MIAODA_NPM_REGISTRY ?? NPM_INSTALL_REGISTRY_DEFAULT;
|
|
119
|
+
(0, node_child_process_1.execFileSync)('npm', ['install', '--no-audit', '--no-fund', '--registry', registry], {
|
|
120
|
+
cwd: targetDir,
|
|
121
|
+
stdio,
|
|
122
|
+
});
|
|
123
|
+
}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.SUPPORTED_STACKS = exports.TEMPLATE_PINNED_VERSION_BY_STACK = exports.TEMPLATE_PACKAGE_BY_STACK = void 0;
|
|
7
|
+
exports.renderTemplate = renderTemplate;
|
|
8
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
9
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
10
|
+
const npm_pack_1 = require("../../../utils/npm-pack");
|
|
11
|
+
const error_1 = require("../../../utils/error");
|
|
12
|
+
const logger_1 = require("../../../utils/logger");
|
|
13
|
+
/** 短名 → 包名映射。新增 stack 时改这里。archType 由 template 包自报,CLI 不维护。 */
|
|
14
|
+
exports.TEMPLATE_PACKAGE_BY_STACK = {
|
|
15
|
+
'vite-react': '@lark-apaas/coding-template-vite-react',
|
|
16
|
+
html: '@lark-apaas/coding-template-html',
|
|
17
|
+
'nestjs-react-fullstack': '@lark-apaas/coding-template-nestjs-react-fullstack',
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* 短名 → template 包钉死版本。renderTemplate 默认按这张表取版本号,表外 stack 走 npm latest。
|
|
21
|
+
*
|
|
22
|
+
* 钉死稳定版本而非跟 alpha dist-tag —— alpha 通道被多团队共享,外部 prerelease 时常打过去,
|
|
23
|
+
* 自动跟 alpha 会把回归版本拉进 user app。每次升基线人工 review 一次再改这里。
|
|
24
|
+
* 用户显式传 `--conf '{"version": "..."}'` 仍 override 此默认值。
|
|
25
|
+
*/
|
|
26
|
+
exports.TEMPLATE_PINNED_VERSION_BY_STACK = {
|
|
27
|
+
'nestjs-react-fullstack': '0.1.0-alpha.5',
|
|
28
|
+
// vite-react / html 暂不钉版,跟 latest dist-tag(新版正常迭代后再纳入钉版)
|
|
29
|
+
};
|
|
30
|
+
exports.SUPPORTED_STACKS = Object.keys(exports.TEMPLATE_PACKAGE_BY_STACK);
|
|
31
|
+
// template/ 内以下划线开头的占位文件名在渲染时改名。
|
|
32
|
+
// 原因:
|
|
33
|
+
// 1. npm pack 强制剥的:.npmrc(防 auth token 泄露)
|
|
34
|
+
// 2. 沙箱平台特殊处理的:.gitignore(避免与平台仓库 .gitignore 冲突)
|
|
35
|
+
// .env 通过 negation pattern 例外直接 ship;.env.local 完全由 lark-cli +env-pull
|
|
36
|
+
// 运行时下发,模板里不再放占位文件。
|
|
37
|
+
const RENAME_FILES = {
|
|
38
|
+
_gitignore: '.gitignore',
|
|
39
|
+
_npmrc: '.npmrc',
|
|
40
|
+
};
|
|
41
|
+
function renderTemplate(opts) {
|
|
42
|
+
const packageName = exports.TEMPLATE_PACKAGE_BY_STACK[opts.stack];
|
|
43
|
+
if (!packageName) {
|
|
44
|
+
throw new error_1.AppError('ARGS_INVALID', `不支持的 template: ${opts.stack}`, {
|
|
45
|
+
next_actions: [`可用 stack:${exports.SUPPORTED_STACKS.join(', ')}`],
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
// 默认按 TEMPLATE_PINNED_VERSION_BY_STACK 取钉版(避免 npm latest 碰外部 prerelease 回归);
|
|
49
|
+
// 表外 stack fallback 到 'latest';用户显式传 --conf.version 仍 override 钉版。
|
|
50
|
+
const pinned = Object.prototype.hasOwnProperty.call(exports.TEMPLATE_PINNED_VERSION_BY_STACK, opts.stack)
|
|
51
|
+
? exports.TEMPLATE_PINNED_VERSION_BY_STACK[opts.stack]
|
|
52
|
+
: undefined;
|
|
53
|
+
const effectiveVersion = opts.version ?? pinned ?? 'latest';
|
|
54
|
+
(0, logger_1.log)('init', `Fetching ${packageName}@${effectiveVersion}...`);
|
|
55
|
+
const fetched = (0, npm_pack_1.fetchNpmPackage)({ packageName, version: effectiveVersion });
|
|
56
|
+
try {
|
|
57
|
+
const templateDir = node_path_1.default.join(fetched.extractDir, 'template');
|
|
58
|
+
if (!node_fs_1.default.existsSync(templateDir)) {
|
|
59
|
+
throw new error_1.AppError('TEMPLATE_INVALID', `包 ${packageName}@${fetched.version} 缺少 template/ 目录`);
|
|
60
|
+
}
|
|
61
|
+
const pkgJsonPath = node_path_1.default.join(fetched.extractDir, 'package.json');
|
|
62
|
+
let archType;
|
|
63
|
+
if (node_fs_1.default.existsSync(pkgJsonPath)) {
|
|
64
|
+
const pkgJson = JSON.parse(node_fs_1.default.readFileSync(pkgJsonPath, 'utf-8'));
|
|
65
|
+
archType = pkgJson.miaodaTemplate?.archType;
|
|
66
|
+
}
|
|
67
|
+
// 用显式 null/undefined/'' 判,避免把合法值 0 / false 当成"缺失"误抛
|
|
68
|
+
if (archType === undefined || archType === null || archType === '') {
|
|
69
|
+
throw new error_1.AppError('TEMPLATE_INVALID', `包 ${packageName}@${fetched.version} 缺少 package.json.miaodaTemplate.archType`);
|
|
70
|
+
}
|
|
71
|
+
(0, logger_1.log)('init', `Rendering template to ${opts.targetDir}...`);
|
|
72
|
+
copyDir(templateDir, opts.targetDir);
|
|
73
|
+
for (const [from, to] of Object.entries(RENAME_FILES)) {
|
|
74
|
+
const fromPath = node_path_1.default.join(opts.targetDir, from);
|
|
75
|
+
const toPath = node_path_1.default.join(opts.targetDir, to);
|
|
76
|
+
if (node_fs_1.default.existsSync(fromPath))
|
|
77
|
+
node_fs_1.default.renameSync(fromPath, toPath);
|
|
78
|
+
}
|
|
79
|
+
// 仅替换展示性文件;package.json 写固定 name,保证 md5(package.json) 跨渲染稳定,
|
|
80
|
+
// 可被 install 阶段直接当 MIAODA_DEP_CACHE_DIR 的 cache key。
|
|
81
|
+
for (const rel of ['index.html', 'README.md']) {
|
|
82
|
+
const p = node_path_1.default.join(opts.targetDir, rel);
|
|
83
|
+
if (node_fs_1.default.existsSync(p))
|
|
84
|
+
replaceInFile(p, '{{projectName}}', opts.projectName);
|
|
85
|
+
}
|
|
86
|
+
return { version: fetched.version, packageName, archType };
|
|
87
|
+
}
|
|
88
|
+
finally {
|
|
89
|
+
fetched.cleanup();
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
function copyDir(src, dest) {
|
|
93
|
+
node_fs_1.default.mkdirSync(dest, { recursive: true });
|
|
94
|
+
for (const entry of node_fs_1.default.readdirSync(src, { withFileTypes: true })) {
|
|
95
|
+
const srcPath = node_path_1.default.join(src, entry.name);
|
|
96
|
+
const destPath = node_path_1.default.join(dest, entry.name);
|
|
97
|
+
if (entry.isDirectory()) {
|
|
98
|
+
copyDir(srcPath, destPath);
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
node_fs_1.default.copyFileSync(srcPath, destPath);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
function replaceInFile(filePath, search, replace) {
|
|
106
|
+
const content = node_fs_1.default.readFileSync(filePath, 'utf-8');
|
|
107
|
+
node_fs_1.default.writeFileSync(filePath, content.replaceAll(search, replace), 'utf-8');
|
|
108
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.runBuild = runBuild;
|
|
4
|
+
const node_child_process_1 = require("node:child_process");
|
|
5
|
+
const error_1 = require("../../../../utils/error");
|
|
6
|
+
const logger_1 = require("../../../../utils/logger");
|
|
7
|
+
const protocol_1 = require("../protocol");
|
|
8
|
+
/**
|
|
9
|
+
* 给 RESOURCE_CDN_PREFIX 补 https:// 协议头:
|
|
10
|
+
* - 已带 http:// 或 https:// → 原样返回
|
|
11
|
+
* - 以 / 开头(绝对路径)→ 原样返回
|
|
12
|
+
* - 不含 dot(看起来不像域名,比如纯路径 app_xxx/2)→ 原样返回
|
|
13
|
+
* - 其它(典型:lf-xxx.bytetos.com/...)→ 前缀 https://
|
|
14
|
+
*
|
|
15
|
+
* template 的 build script 直接拿来当 vite base / asset URL 用,必须是合法 URL。
|
|
16
|
+
* STATIC_CDN_PREFIX 由 runtime 同域提供(相对路径),不走这里。
|
|
17
|
+
*/
|
|
18
|
+
function ensureHttpsScheme(v) {
|
|
19
|
+
if (/^https?:\/\//i.test(v))
|
|
20
|
+
return v;
|
|
21
|
+
if (v.startsWith('/'))
|
|
22
|
+
return v;
|
|
23
|
+
if (!v.includes('.'))
|
|
24
|
+
return v;
|
|
25
|
+
return `https://${v}`;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* 跑 `npm run build`,把 preRelease 下发的动态配置注入 env:
|
|
29
|
+
* MIAODA_APP_ID / MIAODA_VERSION / MIAODA_STACK
|
|
30
|
+
* MIAODA_RESOURCE_CDN_PREFIX / MIAODA_STATIC_CDN_PREFIX
|
|
31
|
+
*
|
|
32
|
+
* MIAODA_STATIC_CDN_PREFIX 取自 output_static_paas_storage_credential.downloadURLPrefix,
|
|
33
|
+
* 是 runtime 同域相对路径(例如 /app/<appId>/runtime/api/v1/storage/object/<bucket>/),
|
|
34
|
+
* 不补 https scheme,原样注入。顶层 static_cdn_prefix 不再下发。
|
|
35
|
+
*
|
|
36
|
+
* build 失败抛 AppError(execSync 自身会 throw,捕获后包一层加错误码)。
|
|
37
|
+
*/
|
|
38
|
+
function runBuild(opts) {
|
|
39
|
+
const staticCred = (0, protocol_1.parsePaasStorageCredential)((0, protocol_1.requireDataKey)(opts.data, protocol_1.DataKey.OUTPUT_STATIC_PAAS_STORAGE_CREDENTIAL), protocol_1.DataKey.OUTPUT_STATIC_PAAS_STORAGE_CREDENTIAL);
|
|
40
|
+
const buildEnv = {
|
|
41
|
+
...process.env,
|
|
42
|
+
MIAODA_APP_ID: opts.appId,
|
|
43
|
+
MIAODA_VERSION: opts.version,
|
|
44
|
+
MIAODA_STACK: opts.templateKey,
|
|
45
|
+
MIAODA_RESOURCE_CDN_PREFIX: ensureHttpsScheme((0, protocol_1.requireDataKey)(opts.data, protocol_1.DataKey.RESOURCE_CDN_PREFIX)),
|
|
46
|
+
MIAODA_STATIC_CDN_PREFIX: staticCred.downloadURLPrefix,
|
|
47
|
+
};
|
|
48
|
+
(0, logger_1.log)('deploy', 'Building...');
|
|
49
|
+
try {
|
|
50
|
+
(0, node_child_process_1.execSync)('npm run build', {
|
|
51
|
+
cwd: opts.projectDir,
|
|
52
|
+
stdio: 'inherit',
|
|
53
|
+
env: buildEnv,
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
catch (err) {
|
|
57
|
+
throw new error_1.AppError('DEPLOY_BUILD_FAILED', `npm run build failed: ${err.message}`);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.prepareDeployContext = prepareDeployContext;
|
|
4
|
+
const error_1 = require("../../../../utils/error");
|
|
5
|
+
const spark_meta_1 = require("../../../../utils/spark-meta");
|
|
6
|
+
const check_1 = require("../check");
|
|
7
|
+
const template_key_map_1 = require("../template-key-map");
|
|
8
|
+
/**
|
|
9
|
+
* 准备 deploy 上下文:跑前置检查、读 .spark/meta.json 拿 stack,
|
|
10
|
+
* 并把 stack 短名映射成后端 templateKey。appId 由调用方从 env 解析后传入。
|
|
11
|
+
*
|
|
12
|
+
* 任何前置失败统一抛 AppError。返回值是后续 atom 唯一信任的入参源。
|
|
13
|
+
*/
|
|
14
|
+
function prepareDeployContext(projectDir, appId) {
|
|
15
|
+
(0, check_1.runDeployChecks)(projectDir);
|
|
16
|
+
const meta = (0, spark_meta_1.readSparkMeta)(projectDir);
|
|
17
|
+
if (meta.stack === undefined || meta.stack === '') {
|
|
18
|
+
throw new error_1.AppError('DEPLOY_META_INCOMPLETE', '.spark/meta.json missing stack — run `miaoda app init` first');
|
|
19
|
+
}
|
|
20
|
+
return {
|
|
21
|
+
projectDir,
|
|
22
|
+
appId,
|
|
23
|
+
stack: meta.stack,
|
|
24
|
+
templateKey: (0, template_key_map_1.resolveTemplateKey)(meta.stack),
|
|
25
|
+
meta,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.savePluginInstances = exports.LocalReleaseStatus = exports.finalizeLocalRelease = exports.createLocalRelease = exports.uploadArtifacts = exports.runBuild = exports.preRelease = exports.prepareDeployContext = void 0;
|
|
4
|
+
var context_1 = require("./context");
|
|
5
|
+
Object.defineProperty(exports, "prepareDeployContext", { enumerable: true, get: function () { return context_1.prepareDeployContext; } });
|
|
6
|
+
var pre_release_1 = require("./pre-release");
|
|
7
|
+
Object.defineProperty(exports, "preRelease", { enumerable: true, get: function () { return pre_release_1.preRelease; } });
|
|
8
|
+
var build_1 = require("./build");
|
|
9
|
+
Object.defineProperty(exports, "runBuild", { enumerable: true, get: function () { return build_1.runBuild; } });
|
|
10
|
+
var upload_1 = require("./upload");
|
|
11
|
+
Object.defineProperty(exports, "uploadArtifacts", { enumerable: true, get: function () { return upload_1.uploadArtifacts; } });
|
|
12
|
+
var local_release_1 = require("./local-release");
|
|
13
|
+
Object.defineProperty(exports, "createLocalRelease", { enumerable: true, get: function () { return local_release_1.createLocalRelease; } });
|
|
14
|
+
Object.defineProperty(exports, "finalizeLocalRelease", { enumerable: true, get: function () { return local_release_1.finalizeLocalRelease; } });
|
|
15
|
+
Object.defineProperty(exports, "LocalReleaseStatus", { enumerable: true, get: function () { return local_release_1.LocalReleaseStatus; } });
|
|
16
|
+
var save_plugin_instances_1 = require("./save-plugin-instances");
|
|
17
|
+
Object.defineProperty(exports, "savePluginInstances", { enumerable: true, get: function () { return save_plugin_instances_1.savePluginInstances; } });
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.LocalReleaseStatus = void 0;
|
|
4
|
+
exports.createLocalRelease = createLocalRelease;
|
|
5
|
+
exports.finalizeLocalRelease = finalizeLocalRelease;
|
|
6
|
+
const index_1 = require("../../../../api/deploy/index");
|
|
7
|
+
Object.defineProperty(exports, "LocalReleaseStatus", { enumerable: true, get: function () { return index_1.LocalReleaseStatus; } });
|
|
8
|
+
const logger_1 = require("../../../../utils/logger");
|
|
9
|
+
/**
|
|
10
|
+
* 创建本地发布单(加锁;不挂 pipeline)。
|
|
11
|
+
* 返回的 releaseId 必须由 finalizeLocalRelease 翻为终态,否则发布单一直挂着。
|
|
12
|
+
*/
|
|
13
|
+
async function createLocalRelease(appId, version) {
|
|
14
|
+
return (0, index_1.createLocalRelease)({ appID: appId, version });
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* 把本地发布单翻为终态。Finished / Failed 由 pipeline 视上下游结果决定。
|
|
18
|
+
* 失败不抛(避免覆盖上游真错误),但记一行 stderr 让排查可定位。
|
|
19
|
+
*/
|
|
20
|
+
async function finalizeLocalRelease(appId, releaseId, status) {
|
|
21
|
+
try {
|
|
22
|
+
await (0, index_1.updateLocalRelease)({ appID: appId, releaseID: releaseId, status });
|
|
23
|
+
}
|
|
24
|
+
catch (err) {
|
|
25
|
+
(0, logger_1.log)('deploy', `finalize release(${releaseId}, status=${String(status)}) failed: ${err.message}`);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.preRelease = preRelease;
|
|
4
|
+
const index_1 = require("../../../../api/deploy/index");
|
|
5
|
+
/**
|
|
6
|
+
* 调用 preRelease,拿到 pre_release_id、version 和动态配置 data。
|
|
7
|
+
*
|
|
8
|
+
* 失败由 api 层抛 HttpError / AppError 透传上去;atom 本身不再做语义包装,
|
|
9
|
+
* 让 pipeline 层决定怎么向 handler 报告。
|
|
10
|
+
*/
|
|
11
|
+
async function preRelease(appId, templateKey) {
|
|
12
|
+
return (0, index_1.preRelease)({ appID: appId, templateKey });
|
|
13
|
+
}
|