listpage_cli 0.0.294 → 0.0.296

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.
Files changed (32) hide show
  1. package/bin/{prompts.js → adapters/cli-interaction.js} +6 -15
  2. package/bin/adapters/dockerode-client.js +295 -0
  3. package/bin/app/parse-args.js +92 -1
  4. package/bin/cli.js +16 -7
  5. package/bin/commands/deploy-project-command.js +24 -0
  6. package/bin/commands/release-project-command.js +24 -0
  7. package/bin/domain/package-name.js +12 -0
  8. package/bin/ports/release-project-command.js +2 -0
  9. package/bin/services/build-artifact-validator.js +47 -0
  10. package/bin/services/command-runner.js +4 -3
  11. package/bin/services/config-value-utils.js +44 -0
  12. package/bin/services/deploy-project-service.js +390 -0
  13. package/bin/services/filesystem-capability-service.js +7 -11
  14. package/bin/services/init-service.js +0 -7
  15. package/bin/services/release-project-service.js +239 -0
  16. package/bin/shared/json-with-comments.js +9 -0
  17. package/bin/types/deploy-config.js +2 -0
  18. package/package.json +6 -4
  19. package/templates/backend-template/package.json.tmpl +1 -1
  20. package/templates/backend-template/tsconfig.build.json +12 -2
  21. package/templates/frontend-template/package.json.tmpl +2 -2
  22. package/templates/rush-template/listpage.config.json.tmpl +89 -0
  23. package/bin/copy.js +0 -40
  24. package/templates/package-app-template/.gitignore.tmpl +0 -28
  25. package/templates/package-app-template/README.md +0 -33
  26. package/templates/package-app-template/package.json +0 -27
  27. package/templates/package-app-template/src/build.ts +0 -6
  28. package/templates/package-app-template/src/config.ts.tmpl +0 -45
  29. package/templates/package-app-template/src/package.ts +0 -5
  30. package/templates/package-app-template/src/publish.ts +0 -6
  31. package/templates/package-app-template/tsconfig.json +0 -25
  32. /package/bin/{services/artifact-validator.js → ports/deploy-project-command.js} +0 -0
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.asObject = asObject;
4
+ exports.asOptionalObject = asOptionalObject;
5
+ exports.asRequiredString = asRequiredString;
6
+ exports.asRequiredNumber = asRequiredNumber;
7
+ exports.asOptionalString = asOptionalString;
8
+ function asObject(value, fieldName) {
9
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
10
+ throw new Error(`缺少对象字段: ${fieldName}`);
11
+ }
12
+ return value;
13
+ }
14
+ function asOptionalObject(value) {
15
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
16
+ return undefined;
17
+ }
18
+ return value;
19
+ }
20
+ function asRequiredString(value, fieldName) {
21
+ if (typeof value === "string" && value.trim() !== "") {
22
+ return value.trim();
23
+ }
24
+ throw new Error(`缺少字段: ${fieldName}`);
25
+ }
26
+ function asRequiredNumber(value, fieldName) {
27
+ if (typeof value === "number" && Number.isFinite(value)) {
28
+ return value;
29
+ }
30
+ if (typeof value === "string" && value.trim() !== "") {
31
+ const parsed = Number(value);
32
+ if (Number.isFinite(parsed)) {
33
+ return parsed;
34
+ }
35
+ }
36
+ throw new Error(`字段类型无效: ${fieldName} (需要 number)`);
37
+ }
38
+ function asOptionalString(value) {
39
+ if (typeof value !== "string") {
40
+ return undefined;
41
+ }
42
+ const normalized = value.trim();
43
+ return normalized === "" ? undefined : normalized;
44
+ }
@@ -0,0 +1,390 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.runDeployProjectFlow = runDeployProjectFlow;
4
+ const command_result_1 = require("../domain/command-result");
5
+ const config_loader_1 = require("./config-loader");
6
+ const dockerode_client_1 = require("../adapters/dockerode-client");
7
+ const config_value_utils_1 = require("./config-value-utils");
8
+ const DEPLOY_STAGE = "deploy";
9
+ const ANSI = {
10
+ reset: "\u001b[0m",
11
+ dim: "\u001b[2m",
12
+ red: "\u001b[31m",
13
+ green: "\u001b[32m",
14
+ yellow: "\u001b[33m",
15
+ blue: "\u001b[34m",
16
+ magenta: "\u001b[35m",
17
+ cyan: "\u001b[36m",
18
+ };
19
+ const USE_COLOR = process.env.NO_COLOR === undefined;
20
+ const CONFIG_ERROR_CODE_MAP = {
21
+ CONFIG_NOT_FOUND: "E_CONFIG_NOT_FOUND",
22
+ CONFIG_READ_FAILED: "E_CONFIG_READ_FAILED",
23
+ CONFIG_INVALID_JSON: "E_CONFIG_INVALID_JSON",
24
+ CONFIG_REQUIRED_FIELD_MISSING: "E_CONFIG_REQUIRED_FIELD_MISSING",
25
+ };
26
+ async function runDeployProjectFlow(deps) {
27
+ const projectRoot = deps.fs.cwd();
28
+ const configPath = (0, config_loader_1.getDefaultConfigPath)(projectRoot, deps.fs.join);
29
+ let configResult;
30
+ try {
31
+ configResult = (0, config_loader_1.loadProjectConfig)({
32
+ readText: deps.fs.readText,
33
+ }, configPath);
34
+ }
35
+ catch (error) {
36
+ if (error instanceof config_loader_1.ConfigLoaderError) {
37
+ return (0, command_result_1.commandError)(error.message, CONFIG_ERROR_CODE_MAP[error.code], 1);
38
+ }
39
+ const message = error instanceof Error ? error.message : String(error);
40
+ return (0, command_result_1.commandError)(message, command_result_1.COMMAND_ERROR_CODES.invalidPath, 1);
41
+ }
42
+ let executionInput;
43
+ try {
44
+ executionInput = resolveRuntimeConfig(configResult.config, deps.cliOverrides);
45
+ console.log(`[${DEPLOY_STAGE}][config]`, JSON.stringify(executionInput, null, 2));
46
+ }
47
+ catch (error) {
48
+ const message = error instanceof Error ? error.message : String(error);
49
+ return (0, command_result_1.commandError)(`[${DEPLOY_STAGE}][config] 部署配置无效: ${message}`, "E_CONFIG_REQUIRED_FIELD_MISSING", 1);
50
+ }
51
+ const createClient = deps.createDockerClient ?? dockerode_client_1.createDockerodeClient;
52
+ let client;
53
+ try {
54
+ client = createClient(executionInput.connection);
55
+ await client.ping();
56
+ }
57
+ catch (error) {
58
+ const message = error instanceof Error ? error.message : String(error);
59
+ return (0, command_result_1.commandError)(`[${DEPLOY_STAGE}][connect] Docker 连接失败: ${message}`, command_result_1.COMMAND_ERROR_CODES.executionFailed, 1);
60
+ }
61
+ if (deps.executeDeploy) {
62
+ try {
63
+ const result = await deps.executeDeploy({
64
+ projectRoot,
65
+ configPath: configResult.configPath,
66
+ config: configResult.config,
67
+ remoteImage: executionInput.remoteImage,
68
+ docker: executionInput.docker,
69
+ deploy: {
70
+ ...executionInput.connection,
71
+ containerName: executionInput.runtime.containerName,
72
+ envFilePath: executionInput.runtime.envFilePath,
73
+ env: executionInput.runtime.env,
74
+ ports: executionInput.runtime.ports,
75
+ binds: executionInput.runtime.binds,
76
+ nanoCpus: executionInput.runtime.nanoCpus,
77
+ memory: executionInput.runtime.memory,
78
+ },
79
+ });
80
+ return normalizeDeployResult(result);
81
+ }
82
+ catch (error) {
83
+ const message = error instanceof Error ? error.message : String(error);
84
+ return (0, command_result_1.commandError)(`[${DEPLOY_STAGE}] 部署执行异常: ${message}`, command_result_1.COMMAND_ERROR_CODES.executionFailed, 1);
85
+ }
86
+ }
87
+ return runDockerDeploy({
88
+ client,
89
+ projectRoot,
90
+ executionInput,
91
+ resolve: deps.fs.resolve,
92
+ readText: deps.fs.readText,
93
+ });
94
+ }
95
+ function resolveRuntimeConfig(config, cliOverrides) {
96
+ const typedConfig = config;
97
+ const dockerRaw = (0, config_value_utils_1.asObject)(typedConfig.docker, "docker");
98
+ const registry = (0, config_value_utils_1.asObject)(dockerRaw.registry, "docker.registry");
99
+ const imageName = (0, config_value_utils_1.asRequiredString)(dockerRaw.imageName, "docker.imageName");
100
+ const profileName = cliOverrides?.profile?.trim() || "dev";
101
+ const profile = resolveProfile(dockerRaw.releaseProfiles, profileName);
102
+ const imageTag = resolveImageTag(cliOverrides?.tag, (0, config_value_utils_1.asOptionalString)(profile.tag), (0, config_value_utils_1.asOptionalString)(dockerRaw.imageTag));
103
+ const containerConfig = resolveContainerConfig((dockerRaw.container ?? {}), profile, cliOverrides);
104
+ const remoteConfig = resolveRemoteConfig(dockerRaw.remote);
105
+ const registryUrl = (0, config_value_utils_1.asRequiredString)(registry.url, "docker.registry.url");
106
+ const registryNamespace = (0, config_value_utils_1.asOptionalString)(registry.namespace);
107
+ const registryUsername = (0, config_value_utils_1.asOptionalString)(registry.username);
108
+ const registryPassword = (0, config_value_utils_1.asOptionalString)(registry.password);
109
+ const repositoryPath = registryNamespace && registryNamespace !== ""
110
+ ? `${registryNamespace}/${imageName}`
111
+ : imageName;
112
+ const remoteImage = `${registryUrl}/${repositoryPath}:${imageTag}`;
113
+ const containerName = normalizeContainerName(containerConfig.name || `${imageName}:${imageTag}`);
114
+ if (!containerConfig.ports &&
115
+ (0, config_value_utils_1.asOptionalString)(dockerRaw.container?.port)) {
116
+ throw new Error("旧字段 docker.container.port 不再支持,请改用 docker.container.ports[]");
117
+ }
118
+ return {
119
+ remoteImage,
120
+ docker: {
121
+ imageName,
122
+ imageTag,
123
+ registryUrl,
124
+ registryNamespace,
125
+ registryUsername,
126
+ registryPassword,
127
+ },
128
+ connection: remoteConfig,
129
+ runtime: {
130
+ containerName,
131
+ envFilePath: containerConfig.envFile,
132
+ env: containerConfig.env,
133
+ cliEnv: cliOverrides?.env,
134
+ ports: containerConfig.ports,
135
+ binds: containerConfig.volumes,
136
+ nanoCpus: containerConfig.nanoCpus,
137
+ memory: containerConfig.memory,
138
+ },
139
+ };
140
+ }
141
+ async function runDockerDeploy(input) {
142
+ const { client, executionInput } = input;
143
+ const remoteImage = executionInput.remoteImage;
144
+ logDeployStep("run", `开始部署镜像: ${remoteImage}`);
145
+ try {
146
+ logDeployStep("run", `检查本地镜像是否存在: ${remoteImage}`);
147
+ const exists = await client.imageExists(remoteImage);
148
+ logDeployStep("run", `本地镜像检查结果: exists=${exists ? "yes" : "no"}`);
149
+ if (exists) {
150
+ logDeployStep("run", `删除旧镜像: ${remoteImage}`);
151
+ await client.removeImage(remoteImage);
152
+ logDeployStep("run", `旧镜像删除完成: ${remoteImage}`);
153
+ }
154
+ }
155
+ catch (error) {
156
+ return (0, command_result_1.commandError)(`[${DEPLOY_STAGE}][run] 清理镜像缓存失败: ${toErrorMessage(error)}`, command_result_1.COMMAND_ERROR_CODES.executionFailed, 1);
157
+ }
158
+ try {
159
+ const auth = buildPullAuth(executionInput.docker);
160
+ logDeployStep("run", `开始拉取镜像: ${remoteImage} (auth=${auth ? "yes" : "no"})`);
161
+ await client.pullImage(remoteImage, auth);
162
+ logDeployStep("run", `镜像拉取完成: ${remoteImage}`);
163
+ }
164
+ catch (error) {
165
+ return (0, command_result_1.commandError)(`[${DEPLOY_STAGE}][run] 拉取镜像失败: ${toErrorMessage(error)}`, command_result_1.COMMAND_ERROR_CODES.executionFailed, 1);
166
+ }
167
+ try {
168
+ logDeployStep("run", `检查已有容器: ${executionInput.runtime.containerName}`);
169
+ const existingContainerId = await client.findContainerIdByName(executionInput.runtime.containerName);
170
+ logDeployStep("run", `容器检查结果: existingContainerId=${existingContainerId ?? "none"}`);
171
+ if (existingContainerId) {
172
+ logDeployStep("run", `停止容器: ${existingContainerId}`);
173
+ await client.stopContainer(existingContainerId);
174
+ logDeployStep("run", `删除容器: ${existingContainerId}`);
175
+ await client.removeContainer(existingContainerId);
176
+ logDeployStep("run", `旧容器替换完成: ${existingContainerId}`);
177
+ }
178
+ }
179
+ catch (error) {
180
+ return (0, command_result_1.commandError)(`[${DEPLOY_STAGE}][run] 替换容器失败: ${toErrorMessage(error)}`, command_result_1.COMMAND_ERROR_CODES.executionFailed, 1);
181
+ }
182
+ let createContainerInput;
183
+ try {
184
+ createContainerInput = (0, dockerode_client_1.toRuntimeContainerInput)({
185
+ runtime: {
186
+ name: executionInput.runtime.containerName,
187
+ image: remoteImage,
188
+ projectRoot: input.projectRoot,
189
+ envFilePath: executionInput.runtime.envFilePath,
190
+ env: executionInput.runtime.env,
191
+ cliEnv: executionInput.runtime.cliEnv,
192
+ ports: executionInput.runtime.ports,
193
+ binds: executionInput.runtime.binds,
194
+ nanoCpus: executionInput.runtime.nanoCpus,
195
+ memory: executionInput.runtime.memory,
196
+ },
197
+ resolve: input.resolve,
198
+ readText: input.readText,
199
+ });
200
+ logDeployStep("run", `环境变量加载完成: count=${createContainerInput.env.length}`);
201
+ }
202
+ catch (error) {
203
+ return (0, command_result_1.commandError)(`[${DEPLOY_STAGE}][config] 环境变量文件无效: ${toErrorMessage(error)}`, "E_CONFIG_REQUIRED_FIELD_MISSING", 1);
204
+ }
205
+ try {
206
+ logDeployStep("run", `创建容器参数: ${JSON.stringify(createContainerInput)}`);
207
+ logDeployStep("run", `创建容器: name=${executionInput.runtime.containerName}, image=${remoteImage}`);
208
+ const containerId = await client.createContainer(createContainerInput);
209
+ logDeployStep("run", `容器创建完成: containerId=${containerId}`);
210
+ logDeployStep("run", `启动容器: ${containerId}`);
211
+ await client.startContainer(containerId);
212
+ logDeployStep("run", `容器启动完成: ${containerId}`);
213
+ const containerState = await client.inspectContainer(containerId);
214
+ logDeployStep("run", `容器状态: running=${containerState.running ?? "unknown"}, ` +
215
+ `status=${containerState.status ?? "unknown"}, ` +
216
+ `exitCode=${containerState.exitCode ?? "unknown"}, ` +
217
+ `health=${containerState.health ?? "unknown"}`);
218
+ logDeployStep("run", `容器端口映射: ${containerState.portMappings && containerState.portMappings.length > 0
219
+ ? containerState.portMappings.join(", ")
220
+ : "<none>"}`);
221
+ if (containerState.running === false) {
222
+ return (0, command_result_1.commandError)(`[${DEPLOY_STAGE}][run] 容器启动后已退出: ` +
223
+ `status=${containerState.status ?? "unknown"}, ` +
224
+ `exitCode=${containerState.exitCode ?? "unknown"}, ` +
225
+ `error=${containerState.error ?? "none"}`, command_result_1.COMMAND_ERROR_CODES.executionFailed, 1);
226
+ }
227
+ logDeployStep("run", `拉取容器启动日志: containerId=${containerId}, tail=100`);
228
+ try {
229
+ const startupLogs = await client.getContainerLogs(containerId, 100);
230
+ const trimmed = startupLogs.trim();
231
+ if (trimmed === "") {
232
+ logDeployStep("run", "容器启动日志为空");
233
+ }
234
+ else {
235
+ console.log(colorizeMultiline(`[${DEPLOY_STAGE}][container-logs]\n${trimmed}`));
236
+ }
237
+ }
238
+ catch (error) {
239
+ logDeployStep("run", `拉取容器启动日志失败(不影响部署结果): ${toErrorMessage(error)}`);
240
+ }
241
+ }
242
+ catch (error) {
243
+ return (0, command_result_1.commandError)(`[${DEPLOY_STAGE}][run] 创建或启动容器失败: ${toErrorMessage(error)}`, command_result_1.COMMAND_ERROR_CODES.executionFailed, 1);
244
+ }
245
+ return (0, command_result_1.commandOk)(`${colorizeDeployLine(`[${DEPLOY_STAGE}] 部署完成: ${remoteImage}`)}\n` +
246
+ `${colorizeDeployLine(`[${DEPLOY_STAGE}] 容器名称: ${executionInput.runtime.containerName}`)}`);
247
+ }
248
+ function buildPullAuth(docker) {
249
+ if (!docker.registryUsername || !docker.registryPassword) {
250
+ return undefined;
251
+ }
252
+ return {
253
+ username: docker.registryUsername,
254
+ password: docker.registryPassword,
255
+ serveraddress: docker.registryUrl,
256
+ };
257
+ }
258
+ function asOptionalNumber(value) {
259
+ if (typeof value === "number" && Number.isFinite(value)) {
260
+ return value;
261
+ }
262
+ if (typeof value === "string" && value.trim() !== "") {
263
+ const parsed = Number(value);
264
+ if (Number.isFinite(parsed)) {
265
+ return parsed;
266
+ }
267
+ }
268
+ return undefined;
269
+ }
270
+ function resolveProfile(profiles, profileName) {
271
+ const profile = profiles && typeof profiles === "object" && !Array.isArray(profiles)
272
+ ? profiles[profileName]
273
+ : undefined;
274
+ if (!profile) {
275
+ throw new Error(`缺少字段: docker.releaseProfiles.${profileName}`);
276
+ }
277
+ return profile;
278
+ }
279
+ function resolveImageTag(cliTag, profileTag, fallbackTag) {
280
+ const normalizedCli = cliTag?.trim();
281
+ if (normalizedCli) {
282
+ return normalizedCli;
283
+ }
284
+ if (profileTag && profileTag.trim() !== "") {
285
+ return profileTag;
286
+ }
287
+ if (fallbackTag && fallbackTag.trim() !== "") {
288
+ return fallbackTag;
289
+ }
290
+ throw new Error("缺少字段: docker.releaseProfiles.<profile>.tag");
291
+ }
292
+ function resolveContainerConfig(baseContainer, profile, cliOverrides) {
293
+ const containerOverrides = ((0, config_value_utils_1.asOptionalObject)(profile.containerOverrides) ??
294
+ {});
295
+ const mergedEnv = {
296
+ ...(baseContainer.env ?? {}),
297
+ ...(containerOverrides.env ?? {}),
298
+ };
299
+ const merged = {
300
+ ...baseContainer,
301
+ ...containerOverrides,
302
+ ...(Object.keys(mergedEnv).length > 0 ? { env: mergedEnv } : {}),
303
+ };
304
+ if (profile.envFile && profile.envFile.trim() !== "") {
305
+ merged.envFile = profile.envFile.trim();
306
+ }
307
+ if (cliOverrides?.env && Object.keys(cliOverrides.env).length > 0) {
308
+ merged.env = {
309
+ ...(merged.env ?? {}),
310
+ ...cliOverrides.env,
311
+ };
312
+ }
313
+ return merged;
314
+ }
315
+ function resolveRemoteConfig(remote) {
316
+ const remoteObj = ((0, config_value_utils_1.asOptionalObject)(remote) ?? {});
317
+ const protocol = (remoteObj.protocol ?? "https").toLowerCase();
318
+ if (!["http", "https"].includes(protocol)) {
319
+ throw new Error("docker.remote.protocol 仅支持 http 或 https");
320
+ }
321
+ return {
322
+ socketPath: (0, config_value_utils_1.asOptionalString)(remoteObj.socketPath),
323
+ host: (0, config_value_utils_1.asOptionalString)(remoteObj.host) ?? "127.0.0.1",
324
+ port: asOptionalNumber(remoteObj.port) ?? 2376,
325
+ protocol,
326
+ ca: (0, config_value_utils_1.asOptionalString)(remoteObj.tls?.ca),
327
+ cert: (0, config_value_utils_1.asOptionalString)(remoteObj.tls?.cert),
328
+ key: (0, config_value_utils_1.asOptionalString)(remoteObj.tls?.key),
329
+ };
330
+ }
331
+ function toErrorMessage(error) {
332
+ if (error instanceof Error) {
333
+ return error.message;
334
+ }
335
+ return String(error ?? "unknown");
336
+ }
337
+ function normalizeContainerName(raw) {
338
+ return raw.replace(/[^a-zA-Z0-9_.-]/g, "-");
339
+ }
340
+ function normalizeDeployResult(result) {
341
+ if (result.ok) {
342
+ if (result.exitCode === 0) {
343
+ return result;
344
+ }
345
+ return (0, command_result_1.commandError)(`[${DEPLOY_STAGE}] 部署执行器返回成功但退出码非零 (exit=${result.exitCode})`, command_result_1.COMMAND_ERROR_CODES.executionFailed, result.exitCode);
346
+ }
347
+ if (result.exitCode !== 0) {
348
+ return result;
349
+ }
350
+ return (0, command_result_1.commandError)(result.message ?? `[${DEPLOY_STAGE}] 部署执行器返回失败但退出码为 0`, result.errorCode ?? command_result_1.COMMAND_ERROR_CODES.executionFailed, 1);
351
+ }
352
+ function logDeployStep(stage, message) {
353
+ console.log(colorizeDeployLine(`[${DEPLOY_STAGE}][${stage}] ${message}`));
354
+ }
355
+ function colorizeDeployLine(line) {
356
+ if (!USE_COLOR || line.trim() === "") {
357
+ return line;
358
+ }
359
+ if (line.startsWith("[deploy][run]")) {
360
+ return wrapColor(line, ANSI.cyan);
361
+ }
362
+ if (line.startsWith("[deploy][container-logs]")) {
363
+ return wrapColor(line, ANSI.yellow);
364
+ }
365
+ if (line.startsWith("[deploy][config]")) {
366
+ return wrapColor(line, ANSI.blue);
367
+ }
368
+ if (line.startsWith("[deploy][connect]")) {
369
+ return wrapColor(line, ANSI.magenta);
370
+ }
371
+ if (line.startsWith("[deploy] 部署完成")) {
372
+ return wrapColor(line, ANSI.green);
373
+ }
374
+ if (line.startsWith("[deploy] 容器名称")) {
375
+ return wrapColor(line, ANSI.dim);
376
+ }
377
+ if (line.startsWith("[deploy]")) {
378
+ return wrapColor(line, ANSI.blue);
379
+ }
380
+ return line;
381
+ }
382
+ function colorizeMultiline(text) {
383
+ return text
384
+ .split("\n")
385
+ .map((line) => colorizeDeployLine(line))
386
+ .join("\n");
387
+ }
388
+ function wrapColor(text, color) {
389
+ return `${color}${text}${ANSI.reset}`;
390
+ }
@@ -1,7 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createFilesystemCapabilityService = createFilesystemCapabilityService;
4
- const utils_1 = require("../utils");
4
+ const package_name_1 = require("../domain/package-name");
5
+ const json_with_comments_1 = require("../shared/json-with-comments");
5
6
  function createFilesystemCapabilityService(fs, options) {
6
7
  return {
7
8
  isDirEmpty: (dir) => {
@@ -15,40 +16,35 @@ function createFilesystemCapabilityService(fs, options) {
15
16
  const projects = [];
16
17
  if (feAppName) {
17
18
  projects.push({
18
- packageName: (0, utils_1.composePkgName)(feAppName),
19
+ packageName: (0, package_name_1.composePkgName)(feAppName),
19
20
  projectFolder: `apps/${feAppName}`,
20
21
  reviewCategory: "production",
21
22
  });
22
23
  }
23
24
  if (beAppName) {
24
25
  projects.push({
25
- packageName: (0, utils_1.composePkgName)(beAppName),
26
+ packageName: (0, package_name_1.composePkgName)(beAppName),
26
27
  projectFolder: `servers/${beAppName}`,
27
28
  reviewCategory: "production",
28
29
  });
29
30
  }
30
31
  const content = fs.readText(filepath);
31
- const json = (0, utils_1.readJsonWithComments)(content);
32
+ const json = (0, json_with_comments_1.parseJsonWithComments)(content);
32
33
  json.projects = projects;
33
34
  fs.writeText(filepath, JSON.stringify(json, null, 2));
34
35
  },
35
36
  copyFrontendTemplate: (targetDir, vars) => {
36
- const appName = (0, utils_1.composePkgName)(vars.FRONTEND_NAME);
37
+ const appName = (0, package_name_1.composePkgName)(vars.FRONTEND_NAME);
37
38
  const resolvedTargetDir = fs.join(targetDir, `apps/${appName}`);
38
39
  const source = getTemplateDir(fs, options.templateRootDir, "frontend");
39
40
  copyDir(fs, source, resolvedTargetDir, vars);
40
41
  },
41
42
  copyBackendTemplate: (targetDir, vars) => {
42
- const appName = (0, utils_1.composePkgName)(vars.BACKEND_NAME);
43
+ const appName = (0, package_name_1.composePkgName)(vars.BACKEND_NAME);
43
44
  const resolvedTargetDir = fs.join(targetDir, `servers/${appName}`);
44
45
  const source = getTemplateDir(fs, options.templateRootDir, "backend");
45
46
  copyDir(fs, source, resolvedTargetDir, vars);
46
47
  },
47
- copyDeployScriptTemplate: (targetDir, vars) => {
48
- const resolvedTargetDir = fs.join(targetDir, "common", "scripts", "package-app");
49
- const source = getTemplateDir(fs, options.templateRootDir, "package-app");
50
- copyDir(fs, source, resolvedTargetDir, vars);
51
- },
52
48
  copySkillDir: (sourceDir, targetDir) => {
53
49
  syncDirWithRename(fs, sourceDir, targetDir);
54
50
  },
@@ -34,13 +34,6 @@ async function runInitRushFlow(deps, targetDir, projectName) {
34
34
  FRONTEND_NAME: frontendName,
35
35
  };
36
36
  deps.files.copyRushTemplate(targetDir, vars);
37
- const installDeployScriptResult = await deps.prompts.askInstallDeployScript();
38
- if (installDeployScriptResult.status !== "value") {
39
- return mapInteractionToCommandResult(installDeployScriptResult, "部署脚本确认");
40
- }
41
- if (installDeployScriptResult.value) {
42
- deps.files.copyDeployScriptTemplate(targetDir, vars);
43
- }
44
37
  deps.files.updateRushJsonProjects(deps.fs.join(targetDir, "rush.json"), frontendName, backendName);
45
38
  if (frontendName) {
46
39
  deps.files.copyFrontendTemplate(targetDir, vars);