@wwchao6411/create-web-ui-template 0.1.0

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 (74) hide show
  1. package/README.md +54 -0
  2. package/dist/chunk-DRNPNIJR.js +131 -0
  3. package/dist/chunk-DRNPNIJR.js.map +1 -0
  4. package/dist/chunk-HDMQ6CVP.js +22 -0
  5. package/dist/chunk-HDMQ6CVP.js.map +1 -0
  6. package/dist/chunk-N6W5XQS6.js +24 -0
  7. package/dist/chunk-N6W5XQS6.js.map +1 -0
  8. package/dist/chunk-NOZ2FVZU.js +89 -0
  9. package/dist/chunk-NOZ2FVZU.js.map +1 -0
  10. package/dist/chunk-QKC3LLVR.js +81 -0
  11. package/dist/chunk-QKC3LLVR.js.map +1 -0
  12. package/dist/chunk-VKUDWI56.js +21 -0
  13. package/dist/chunk-VKUDWI56.js.map +1 -0
  14. package/dist/chunk-ZCLQAKLB.js +93 -0
  15. package/dist/chunk-ZCLQAKLB.js.map +1 -0
  16. package/dist/chunk-ZWYKFM47.js +21 -0
  17. package/dist/chunk-ZWYKFM47.js.map +1 -0
  18. package/dist/cli.d.ts +9 -0
  19. package/dist/cli.js +16 -0
  20. package/dist/cli.js.map +1 -0
  21. package/dist/index.d.ts +9 -0
  22. package/dist/index.js +49 -0
  23. package/dist/index.js.map +1 -0
  24. package/dist/modes/standalone.d.ts +10 -0
  25. package/dist/modes/standalone.js +11 -0
  26. package/dist/modes/standalone.js.map +1 -0
  27. package/dist/modes/workspace.d.ts +10 -0
  28. package/dist/modes/workspace.js +11 -0
  29. package/dist/modes/workspace.js.map +1 -0
  30. package/dist/prompts.d.ts +20 -0
  31. package/dist/prompts.js +9 -0
  32. package/dist/prompts.js.map +1 -0
  33. package/dist/render-template.d.ts +15 -0
  34. package/dist/render-template.js +10 -0
  35. package/dist/render-template.js.map +1 -0
  36. package/dist/transforms/apply-feature-flags.d.ts +5 -0
  37. package/dist/transforms/apply-feature-flags.js +7 -0
  38. package/dist/transforms/apply-feature-flags.js.map +1 -0
  39. package/dist/transforms/replace-tokens.d.ts +5 -0
  40. package/dist/transforms/replace-tokens.js +7 -0
  41. package/dist/transforms/replace-tokens.js.map +1 -0
  42. package/dist/transforms/write-package-manager-notes.d.ts +5 -0
  43. package/dist/transforms/write-package-manager-notes.js +7 -0
  44. package/dist/transforms/write-package-manager-notes.js.map +1 -0
  45. package/package.json +37 -0
  46. package/templates/web-ui-template/README.md +44 -0
  47. package/templates/web-ui-template/config/template.config.json +11 -0
  48. package/templates/web-ui-template/electron/config/config-manager.ts +9 -0
  49. package/templates/web-ui-template/electron/forwarding/forwarding-manager.ts +9 -0
  50. package/templates/web-ui-template/electron/ipc/index.ts +4 -0
  51. package/templates/web-ui-template/electron/main/index.ts +10 -0
  52. package/templates/web-ui-template/electron/preload/index.ts +7 -0
  53. package/templates/web-ui-template/electron.vite.config.ts +50 -0
  54. package/templates/web-ui-template/index.html +12 -0
  55. package/templates/web-ui-template/package.json +38 -0
  56. package/templates/web-ui-template/public/.gitkeep +1 -0
  57. package/templates/web-ui-template/scripts/post-create.mjs +1 -0
  58. package/templates/web-ui-template/src/app/App.vue +38 -0
  59. package/templates/web-ui-template/src/app/app.scss +8 -0
  60. package/templates/web-ui-template/src/app/main.ts +24 -0
  61. package/templates/web-ui-template/src/app/tailwind.css +1 -0
  62. package/templates/web-ui-template/src/business/HomePage.vue +18 -0
  63. package/templates/web-ui-template/src/business/LoginPage.vue +17 -0
  64. package/templates/web-ui-template/src/business/PreviewMicroAppPage.vue +15 -0
  65. package/templates/web-ui-template/src/business/WorkspacePage.vue +22 -0
  66. package/templates/web-ui-template/src/business/apps.ts +12 -0
  67. package/templates/web-ui-template/src/business/menu.ts +23 -0
  68. package/templates/web-ui-template/src/business/permissions.ts +1 -0
  69. package/templates/web-ui-template/src/platform/create-platform.ts +29 -0
  70. package/templates/web-ui-template/src/platform/register-microapps.ts +8 -0
  71. package/templates/web-ui-template/src/platform/register-routes.ts +32 -0
  72. package/templates/web-ui-template/src/shared/config.ts +28 -0
  73. package/templates/web-ui-template/tsconfig.json +13 -0
  74. package/templates/web-ui-template/vite.config.ts +22 -0
package/README.md ADDED
@@ -0,0 +1,54 @@
1
+ # @wwchao6411/create-web-ui-template
2
+
3
+ `tools/create-web-ui-template` 是仓库内的模板初始化 CLI。它会复制 `templates/web-ui-template`,替换占位符,并按功能开关裁剪文件。
4
+
5
+ ## 支持的输出模式
6
+
7
+ - `workspace`: 生成到当前 monorepo 的 `apps/<name>`
8
+ - `standalone`: 生成到外部目标目录,并把 `workspace:*` 依赖改写成显式 semver
9
+
10
+ ## 本地开发命令
11
+
12
+ 在当前仓库内,推荐使用根脚本启动 CLI:
13
+
14
+ ```bash
15
+ pnpm web-ui-template:init demo-shell --workspace
16
+ pnpm web-ui-template:init demo-standalone --standalone --target .tmp/demo-standalone
17
+ ```
18
+
19
+ 如需只验证 CLI 包本身:
20
+
21
+ ```bash
22
+ pnpm --filter @wwchao6411/create-web-ui-template test
23
+ pnpm --filter @wwchao6411/create-web-ui-template exec node dist/index.js --help
24
+ ```
25
+
26
+ ## create 风格入口
27
+
28
+ CLI 已提供 `create-web-ui-template` 包名对应的 bin 入口,命令行语义如下:
29
+
30
+ ```bash
31
+ pnpm create @wwchao6411/web-ui-template my-app --workspace
32
+ pnpm create @wwchao6411/web-ui-template my-app --standalone --target ./my-app
33
+ npm create @wwchao6411/web-ui-template@latest -- my-app --standalone --target ./my-app
34
+ ```
35
+
36
+ ## 主要参数
37
+
38
+ - `--workspace`: 输出到当前仓库 `apps/<name>`
39
+ - `--standalone`: 输出到独立目录
40
+ - `--target <path>`: 指定 standalone 目标路径
41
+ - `--no-desktop`: 删除桌面运行时文件和脚本
42
+ - `--no-microapp`: 删除示例微前端页面和路由
43
+ - `--no-chrome-tabs`: 关闭 chrome-tabs 占位符
44
+ - `--no-auth`: 删除登录页与登录路由
45
+ - `--no-ssh-forwarding`: 删除 SSH 转发占位文件
46
+ - `--package-manager <pnpm|npm|yarn>`: 指定包管理器
47
+ - `--install`: 初始化完成后立即安装依赖
48
+
49
+ ## 输出说明
50
+
51
+ CLI 会在完成后打印下一步命令:
52
+
53
+ - workspace 模式输出根仓库内的 `pnpm` 命令
54
+ - standalone 模式输出进入目标目录后的安装和启动命令
@@ -0,0 +1,131 @@
1
+ // src/prompts.ts
2
+ var DEFAULT_PROJECT_NAME = "web-ui-template-app";
3
+ function createDefaultInitOptions() {
4
+ return {
5
+ projectName: DEFAULT_PROJECT_NAME,
6
+ targetMode: "standalone",
7
+ enableDesktop: true,
8
+ enableMicroApp: true,
9
+ enableChromeTabs: true,
10
+ enableAuth: true,
11
+ enableSshForwarding: true,
12
+ packageManager: "pnpm",
13
+ installNow: false
14
+ };
15
+ }
16
+ function parsePackageManager(value) {
17
+ return value === "npm" || value === "yarn" ? value : "pnpm";
18
+ }
19
+ function resolveInitOptions(argv) {
20
+ const options = createDefaultInitOptions();
21
+ let helpRequested = false;
22
+ let targetDirectory;
23
+ for (let index = 0; index < argv.length; index += 1) {
24
+ const argument = argv[index];
25
+ if (!argument) {
26
+ continue;
27
+ }
28
+ if (!argument.startsWith("-") && options.projectName === DEFAULT_PROJECT_NAME) {
29
+ options.projectName = argument;
30
+ continue;
31
+ }
32
+ switch (argument) {
33
+ case "--help":
34
+ case "-h": {
35
+ helpRequested = true;
36
+ break;
37
+ }
38
+ case "--workspace": {
39
+ options.targetMode = "workspace";
40
+ break;
41
+ }
42
+ case "--standalone": {
43
+ options.targetMode = "standalone";
44
+ break;
45
+ }
46
+ case "--desktop": {
47
+ options.enableDesktop = true;
48
+ break;
49
+ }
50
+ case "--no-desktop": {
51
+ options.enableDesktop = false;
52
+ break;
53
+ }
54
+ case "--microapp": {
55
+ options.enableMicroApp = true;
56
+ break;
57
+ }
58
+ case "--no-microapp": {
59
+ options.enableMicroApp = false;
60
+ break;
61
+ }
62
+ case "--chrome-tabs": {
63
+ options.enableChromeTabs = true;
64
+ break;
65
+ }
66
+ case "--no-chrome-tabs": {
67
+ options.enableChromeTabs = false;
68
+ break;
69
+ }
70
+ case "--auth": {
71
+ options.enableAuth = true;
72
+ break;
73
+ }
74
+ case "--no-auth": {
75
+ options.enableAuth = false;
76
+ break;
77
+ }
78
+ case "--ssh-forwarding": {
79
+ options.enableSshForwarding = true;
80
+ break;
81
+ }
82
+ case "--no-ssh-forwarding": {
83
+ options.enableSshForwarding = false;
84
+ break;
85
+ }
86
+ case "--install": {
87
+ options.installNow = true;
88
+ break;
89
+ }
90
+ case "--npm": {
91
+ options.packageManager = "npm";
92
+ break;
93
+ }
94
+ case "--yarn": {
95
+ options.packageManager = "yarn";
96
+ break;
97
+ }
98
+ case "--pnpm": {
99
+ options.packageManager = "pnpm";
100
+ break;
101
+ }
102
+ case "--package-manager": {
103
+ options.packageManager = parsePackageManager(argv[index + 1]);
104
+ index += 1;
105
+ break;
106
+ }
107
+ case "--target": {
108
+ targetDirectory = argv[index + 1];
109
+ index += 1;
110
+ break;
111
+ }
112
+ default: {
113
+ break;
114
+ }
115
+ }
116
+ }
117
+ if (options.targetMode === "workspace") {
118
+ options.packageManager = "pnpm";
119
+ }
120
+ return {
121
+ helpRequested,
122
+ options,
123
+ targetDirectory
124
+ };
125
+ }
126
+
127
+ export {
128
+ createDefaultInitOptions,
129
+ resolveInitOptions
130
+ };
131
+ //# sourceMappingURL=chunk-DRNPNIJR.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/prompts.ts"],"sourcesContent":["export interface InitOptions {\n projectName: string;\n targetMode: \"workspace\" | \"standalone\";\n enableDesktop: boolean;\n enableMicroApp: boolean;\n enableChromeTabs: boolean;\n enableAuth: boolean;\n enableSshForwarding: boolean;\n packageManager: \"pnpm\" | \"npm\" | \"yarn\";\n installNow: boolean;\n}\n\nexport interface ResolvedCliInput {\n helpRequested: boolean;\n options: InitOptions;\n targetDirectory?: string;\n}\n\nconst DEFAULT_PROJECT_NAME = \"web-ui-template-app\";\n\n// 创建 CLI 的默认初始化选项,确保未传参时仍有稳定行为。\nexport function createDefaultInitOptions(): InitOptions {\n return {\n projectName: DEFAULT_PROJECT_NAME,\n targetMode: \"standalone\",\n enableDesktop: true,\n enableMicroApp: true,\n enableChromeTabs: true,\n enableAuth: true,\n enableSshForwarding: true,\n packageManager: \"pnpm\",\n installNow: false\n };\n}\n\n// 解析字符串值形式的包管理器参数,并收敛到受支持的枚举值。\nfunction parsePackageManager(value: string | undefined): InitOptions[\"packageManager\"] {\n return value === \"npm\" || value === \"yarn\" ? value : \"pnpm\";\n}\n\n// 从命令行参数解析初始化选项,供 CLI 和测试共享。\nexport function resolveInitOptions(argv: string[]): ResolvedCliInput {\n const options = createDefaultInitOptions();\n let helpRequested = false;\n let targetDirectory: string | undefined;\n\n for (let index = 0; index < argv.length; index += 1) {\n const argument = argv[index];\n\n if (!argument) {\n continue;\n }\n\n if (!argument.startsWith(\"-\") && options.projectName === DEFAULT_PROJECT_NAME) {\n options.projectName = argument;\n continue;\n }\n\n switch (argument) {\n case \"--help\":\n case \"-h\": {\n helpRequested = true;\n break;\n }\n case \"--workspace\": {\n options.targetMode = \"workspace\";\n break;\n }\n case \"--standalone\": {\n options.targetMode = \"standalone\";\n break;\n }\n case \"--desktop\": {\n options.enableDesktop = true;\n break;\n }\n case \"--no-desktop\": {\n options.enableDesktop = false;\n break;\n }\n case \"--microapp\": {\n options.enableMicroApp = true;\n break;\n }\n case \"--no-microapp\": {\n options.enableMicroApp = false;\n break;\n }\n case \"--chrome-tabs\": {\n options.enableChromeTabs = true;\n break;\n }\n case \"--no-chrome-tabs\": {\n options.enableChromeTabs = false;\n break;\n }\n case \"--auth\": {\n options.enableAuth = true;\n break;\n }\n case \"--no-auth\": {\n options.enableAuth = false;\n break;\n }\n case \"--ssh-forwarding\": {\n options.enableSshForwarding = true;\n break;\n }\n case \"--no-ssh-forwarding\": {\n options.enableSshForwarding = false;\n break;\n }\n case \"--install\": {\n options.installNow = true;\n break;\n }\n case \"--npm\": {\n options.packageManager = \"npm\";\n break;\n }\n case \"--yarn\": {\n options.packageManager = \"yarn\";\n break;\n }\n case \"--pnpm\": {\n options.packageManager = \"pnpm\";\n break;\n }\n case \"--package-manager\": {\n options.packageManager = parsePackageManager(argv[index + 1]);\n index += 1;\n break;\n }\n case \"--target\": {\n targetDirectory = argv[index + 1];\n index += 1;\n break;\n }\n default: {\n break;\n }\n }\n }\n\n if (options.targetMode === \"workspace\") {\n options.packageManager = \"pnpm\";\n }\n\n return {\n helpRequested,\n options,\n targetDirectory\n };\n}\n"],"mappings":";AAkBA,IAAM,uBAAuB;AAGtB,SAAS,2BAAwC;AACtD,SAAO;AAAA,IACL,aAAa;AAAA,IACb,YAAY;AAAA,IACZ,eAAe;AAAA,IACf,gBAAgB;AAAA,IAChB,kBAAkB;AAAA,IAClB,YAAY;AAAA,IACZ,qBAAqB;AAAA,IACrB,gBAAgB;AAAA,IAChB,YAAY;AAAA,EACd;AACF;AAGA,SAAS,oBAAoB,OAA0D;AACrF,SAAO,UAAU,SAAS,UAAU,SAAS,QAAQ;AACvD;AAGO,SAAS,mBAAmB,MAAkC;AACnE,QAAM,UAAU,yBAAyB;AACzC,MAAI,gBAAgB;AACpB,MAAI;AAEJ,WAAS,QAAQ,GAAG,QAAQ,KAAK,QAAQ,SAAS,GAAG;AACnD,UAAM,WAAW,KAAK,KAAK;AAE3B,QAAI,CAAC,UAAU;AACb;AAAA,IACF;AAEA,QAAI,CAAC,SAAS,WAAW,GAAG,KAAK,QAAQ,gBAAgB,sBAAsB;AAC7E,cAAQ,cAAc;AACtB;AAAA,IACF;AAEA,YAAQ,UAAU;AAAA,MAChB,KAAK;AAAA,MACL,KAAK,MAAM;AACT,wBAAgB;AAChB;AAAA,MACF;AAAA,MACA,KAAK,eAAe;AAClB,gBAAQ,aAAa;AACrB;AAAA,MACF;AAAA,MACA,KAAK,gBAAgB;AACnB,gBAAQ,aAAa;AACrB;AAAA,MACF;AAAA,MACA,KAAK,aAAa;AAChB,gBAAQ,gBAAgB;AACxB;AAAA,MACF;AAAA,MACA,KAAK,gBAAgB;AACnB,gBAAQ,gBAAgB;AACxB;AAAA,MACF;AAAA,MACA,KAAK,cAAc;AACjB,gBAAQ,iBAAiB;AACzB;AAAA,MACF;AAAA,MACA,KAAK,iBAAiB;AACpB,gBAAQ,iBAAiB;AACzB;AAAA,MACF;AAAA,MACA,KAAK,iBAAiB;AACpB,gBAAQ,mBAAmB;AAC3B;AAAA,MACF;AAAA,MACA,KAAK,oBAAoB;AACvB,gBAAQ,mBAAmB;AAC3B;AAAA,MACF;AAAA,MACA,KAAK,UAAU;AACb,gBAAQ,aAAa;AACrB;AAAA,MACF;AAAA,MACA,KAAK,aAAa;AAChB,gBAAQ,aAAa;AACrB;AAAA,MACF;AAAA,MACA,KAAK,oBAAoB;AACvB,gBAAQ,sBAAsB;AAC9B;AAAA,MACF;AAAA,MACA,KAAK,uBAAuB;AAC1B,gBAAQ,sBAAsB;AAC9B;AAAA,MACF;AAAA,MACA,KAAK,aAAa;AAChB,gBAAQ,aAAa;AACrB;AAAA,MACF;AAAA,MACA,KAAK,SAAS;AACZ,gBAAQ,iBAAiB;AACzB;AAAA,MACF;AAAA,MACA,KAAK,UAAU;AACb,gBAAQ,iBAAiB;AACzB;AAAA,MACF;AAAA,MACA,KAAK,UAAU;AACb,gBAAQ,iBAAiB;AACzB;AAAA,MACF;AAAA,MACA,KAAK,qBAAqB;AACxB,gBAAQ,iBAAiB,oBAAoB,KAAK,QAAQ,CAAC,CAAC;AAC5D,iBAAS;AACT;AAAA,MACF;AAAA,MACA,KAAK,YAAY;AACf,0BAAkB,KAAK,QAAQ,CAAC;AAChC,iBAAS;AACT;AAAA,MACF;AAAA,MACA,SAAS;AACP;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,MAAI,QAAQ,eAAe,aAAa;AACtC,YAAQ,iBAAiB;AAAA,EAC3B;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;","names":[]}
@@ -0,0 +1,22 @@
1
+ import {
2
+ renderTemplate
3
+ } from "./chunk-QKC3LLVR.js";
4
+
5
+ // src/modes/workspace.ts
6
+ import { join } from "path";
7
+ async function renderWorkspaceMode(options, input) {
8
+ return renderTemplate({
9
+ mode: "workspace",
10
+ options: {
11
+ ...options,
12
+ targetMode: "workspace"
13
+ },
14
+ targetDirectory: join(input.workspaceRoot, "apps", options.projectName),
15
+ templateDirectory: input.templateDirectory
16
+ });
17
+ }
18
+
19
+ export {
20
+ renderWorkspaceMode
21
+ };
22
+ //# sourceMappingURL=chunk-HDMQ6CVP.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/modes/workspace.ts"],"sourcesContent":["import { join } from \"node:path\";\n\nimport type { InitOptions } from \"../prompts\";\nimport { renderTemplate, type RenderTemplateResult } from \"../render-template\";\n\nexport interface WorkspaceModeInput {\n workspaceRoot: string;\n templateDirectory?: string;\n}\n\n// 将模板渲染到 monorepo 的 apps 目录下,供工作区模式直接接入。\nexport async function renderWorkspaceMode(\n options: InitOptions,\n input: WorkspaceModeInput\n): Promise<RenderTemplateResult> {\n return renderTemplate({\n mode: \"workspace\",\n options: {\n ...options,\n targetMode: \"workspace\"\n },\n targetDirectory: join(input.workspaceRoot, \"apps\", options.projectName),\n templateDirectory: input.templateDirectory\n });\n}\n"],"mappings":";;;;;AAAA,SAAS,YAAY;AAWrB,eAAsB,oBACpB,SACA,OAC+B;AAC/B,SAAO,eAAe;AAAA,IACpB,MAAM;AAAA,IACN,SAAS;AAAA,MACP,GAAG;AAAA,MACH,YAAY;AAAA,IACd;AAAA,IACA,iBAAiB,KAAK,MAAM,eAAe,QAAQ,QAAQ,WAAW;AAAA,IACtE,mBAAmB,MAAM;AAAA,EAC3B,CAAC;AACH;","names":[]}
@@ -0,0 +1,24 @@
1
+ // src/transforms/write-package-manager-notes.ts
2
+ function writePackageManagerNotes(options, locationLabel) {
3
+ if (options.targetMode === "workspace") {
4
+ return [
5
+ `Scaffolded ${locationLabel}.`,
6
+ "Run these commands next:",
7
+ "pnpm install",
8
+ `pnpm --filter ${options.projectName} dev`
9
+ ].join("\n");
10
+ }
11
+ const installCommand = options.packageManager === "npm" ? "npm install" : options.packageManager === "yarn" ? "yarn install" : "pnpm install";
12
+ const devCommand = options.packageManager === "npm" ? "npm run dev:web" : `${options.packageManager} dev:web`;
13
+ return [
14
+ `Scaffolded ${locationLabel}.`,
15
+ `cd ${locationLabel}`,
16
+ installCommand,
17
+ devCommand
18
+ ].join("\n");
19
+ }
20
+
21
+ export {
22
+ writePackageManagerNotes
23
+ };
24
+ //# sourceMappingURL=chunk-N6W5XQS6.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/transforms/write-package-manager-notes.ts"],"sourcesContent":["import type { InitOptions } from \"../prompts\";\n\n// 生成初始化完成后的后续操作说明,按包管理器和目标模式给出命令。\nexport function writePackageManagerNotes(options: InitOptions, locationLabel: string): string {\n if (options.targetMode === \"workspace\") {\n return [\n `Scaffolded ${locationLabel}.`,\n \"Run these commands next:\",\n \"pnpm install\",\n `pnpm --filter ${options.projectName} dev`\n ].join(\"\\n\");\n }\n\n const installCommand = options.packageManager === \"npm\"\n ? \"npm install\"\n : options.packageManager === \"yarn\"\n ? \"yarn install\"\n : \"pnpm install\";\n const devCommand = options.packageManager === \"npm\" ? \"npm run dev:web\" : `${options.packageManager} dev:web`;\n\n return [\n `Scaffolded ${locationLabel}.`,\n `cd ${locationLabel}`,\n installCommand,\n devCommand\n ].join(\"\\n\");\n}\n"],"mappings":";AAGO,SAAS,yBAAyB,SAAsB,eAA+B;AAC5F,MAAI,QAAQ,eAAe,aAAa;AACtC,WAAO;AAAA,MACL,cAAc,aAAa;AAAA,MAC3B;AAAA,MACA;AAAA,MACA,iBAAiB,QAAQ,WAAW;AAAA,IACtC,EAAE,KAAK,IAAI;AAAA,EACb;AAEA,QAAM,iBAAiB,QAAQ,mBAAmB,QAC9C,gBACA,QAAQ,mBAAmB,SACzB,iBACA;AACN,QAAM,aAAa,QAAQ,mBAAmB,QAAQ,oBAAoB,GAAG,QAAQ,cAAc;AAEnG,SAAO;AAAA,IACL,cAAc,aAAa;AAAA,IAC3B,MAAM,aAAa;AAAA,IACnB;AAAA,IACA;AAAA,EACF,EAAE,KAAK,IAAI;AACb;","names":[]}
@@ -0,0 +1,89 @@
1
+ import {
2
+ resolveInitOptions
3
+ } from "./chunk-DRNPNIJR.js";
4
+ import {
5
+ renderStandaloneMode
6
+ } from "./chunk-ZWYKFM47.js";
7
+ import {
8
+ renderWorkspaceMode
9
+ } from "./chunk-HDMQ6CVP.js";
10
+
11
+ // src/cli.ts
12
+ import { spawn } from "child_process";
13
+ import { join, resolve } from "path";
14
+ var defaultEnvironment = {
15
+ cwd: process.cwd(),
16
+ stderr: console,
17
+ stdout: console
18
+ };
19
+ function createHelpText() {
20
+ return [
21
+ "@wwchao6411/create-web-ui-template",
22
+ "",
23
+ "Usage:",
24
+ " pnpm create @wwchao6411/web-ui-template my-app [options]",
25
+ " npm create @wwchao6411/web-ui-template@latest -- my-app [options]",
26
+ " pnpm web-ui-template:init my-app --workspace",
27
+ "",
28
+ "Options:",
29
+ " --workspace Generate into apps/<name> inside the current workspace",
30
+ " --standalone Generate into an external target directory",
31
+ " --target <path> Override the standalone target directory",
32
+ " --no-desktop Remove desktop runtime files and scripts",
33
+ " --no-microapp Remove sample microapp files and routes",
34
+ " --no-chrome-tabs Disable chrome-tabs token flags",
35
+ " --no-auth Remove login route and page",
36
+ " --no-ssh-forwarding Remove SSH forwarding placeholders",
37
+ " --package-manager One of pnpm, npm, yarn",
38
+ " --install Run install after scaffolding",
39
+ " -h, --help Show help"
40
+ ].join("\n");
41
+ }
42
+ function resolveTargetDirectory(cwd, targetMode, projectName, targetDirectory) {
43
+ if (targetMode === "workspace") {
44
+ return join(cwd, "apps", projectName);
45
+ }
46
+ return resolve(cwd, targetDirectory ?? projectName);
47
+ }
48
+ async function runInstallCommand(cwd, packageManager) {
49
+ await new Promise((resolvePromise, rejectPromise) => {
50
+ const child = spawn(packageManager, ["install"], {
51
+ cwd,
52
+ stdio: "inherit",
53
+ shell: process.platform === "win32"
54
+ });
55
+ child.on("exit", (code) => {
56
+ if (code === 0) {
57
+ resolvePromise();
58
+ return;
59
+ }
60
+ rejectPromise(new Error(`Install failed with exit code ${String(code)}`));
61
+ });
62
+ child.on("error", rejectPromise);
63
+ });
64
+ }
65
+ async function runCli(argv, environment = defaultEnvironment) {
66
+ const { helpRequested, options, targetDirectory } = resolveInitOptions(argv);
67
+ if (helpRequested) {
68
+ environment.stdout.log(createHelpText());
69
+ return 0;
70
+ }
71
+ const resolvedTargetDirectory = resolveTargetDirectory(
72
+ environment.cwd,
73
+ options.targetMode,
74
+ options.projectName,
75
+ targetDirectory
76
+ );
77
+ const result = options.targetMode === "workspace" ? await renderWorkspaceMode(options, { workspaceRoot: environment.cwd }) : await renderStandaloneMode(options, { targetDirectory: resolvedTargetDirectory });
78
+ environment.stdout.log(result.notes);
79
+ if (options.installNow) {
80
+ await runInstallCommand(result.targetDirectory, options.packageManager);
81
+ }
82
+ return 0;
83
+ }
84
+
85
+ export {
86
+ createHelpText,
87
+ runCli
88
+ };
89
+ //# sourceMappingURL=chunk-NOZ2FVZU.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli.ts"],"sourcesContent":["import { spawn } from \"node:child_process\";\nimport { join, resolve } from \"node:path\";\n\nimport { renderStandaloneMode } from \"./modes/standalone\";\nimport { resolveInitOptions } from \"./prompts\";\nimport { renderWorkspaceMode } from \"./modes/workspace\";\n\nexport interface CliEnvironment {\n cwd: string;\n stderr: Pick<Console, \"error\">;\n stdout: Pick<Console, \"log\">;\n}\n\nconst defaultEnvironment: CliEnvironment = {\n cwd: process.cwd(),\n stderr: console,\n stdout: console\n};\n\n// 生成 CLI 帮助文本。\nexport function createHelpText(): string {\n return [\n \"@wwchao6411/create-web-ui-template\",\n \"\",\n \"Usage:\",\n \" pnpm create @wwchao6411/web-ui-template my-app [options]\",\n \" npm create @wwchao6411/web-ui-template@latest -- my-app [options]\",\n \" pnpm web-ui-template:init my-app --workspace\",\n \"\",\n \"Options:\",\n \" --workspace Generate into apps/<name> inside the current workspace\",\n \" --standalone Generate into an external target directory\",\n \" --target <path> Override the standalone target directory\",\n \" --no-desktop Remove desktop runtime files and scripts\",\n \" --no-microapp Remove sample microapp files and routes\",\n \" --no-chrome-tabs Disable chrome-tabs token flags\",\n \" --no-auth Remove login route and page\",\n \" --no-ssh-forwarding Remove SSH forwarding placeholders\",\n \" --package-manager One of pnpm, npm, yarn\",\n \" --install Run install after scaffolding\",\n \" -h, --help Show help\"\n ].join(\"\\n\");\n}\n\n// 解析模板输出目录。\nfunction resolveTargetDirectory(\n cwd: string,\n targetMode: \"workspace\" | \"standalone\",\n projectName: string,\n targetDirectory?: string\n): string {\n if (targetMode === \"workspace\") {\n return join(cwd, \"apps\", projectName);\n }\n\n return resolve(cwd, targetDirectory ?? projectName);\n}\n\n// 执行依赖安装命令。\nasync function runInstallCommand(\n cwd: string,\n packageManager: \"pnpm\" | \"npm\" | \"yarn\"\n): Promise<void> {\n await new Promise<void>((resolvePromise, rejectPromise) => {\n const child = spawn(packageManager, [\"install\"], {\n cwd,\n stdio: \"inherit\",\n shell: process.platform === \"win32\"\n });\n\n child.on(\"exit\", (code) => {\n if (code === 0) {\n resolvePromise();\n return;\n }\n\n rejectPromise(new Error(`Install failed with exit code ${String(code)}`));\n });\n child.on(\"error\", rejectPromise);\n });\n}\n\n// 运行模板初始化 CLI。\nexport async function runCli(\n argv: string[],\n environment: CliEnvironment = defaultEnvironment\n): Promise<number> {\n const { helpRequested, options, targetDirectory } = resolveInitOptions(argv);\n\n if (helpRequested) {\n environment.stdout.log(createHelpText());\n return 0;\n }\n\n const resolvedTargetDirectory = resolveTargetDirectory(\n environment.cwd,\n options.targetMode,\n options.projectName,\n targetDirectory\n );\n const result =\n options.targetMode === \"workspace\"\n ? await renderWorkspaceMode(options, { workspaceRoot: environment.cwd })\n : await renderStandaloneMode(options, { targetDirectory: resolvedTargetDirectory });\n\n environment.stdout.log(result.notes);\n\n if (options.installNow) {\n await runInstallCommand(result.targetDirectory, options.packageManager);\n }\n\n return 0;\n}\n"],"mappings":";;;;;;;;;;;AAAA,SAAS,aAAa;AACtB,SAAS,MAAM,eAAe;AAY9B,IAAM,qBAAqC;AAAA,EACzC,KAAK,QAAQ,IAAI;AAAA,EACjB,QAAQ;AAAA,EACR,QAAQ;AACV;AAGO,SAAS,iBAAyB;AACvC,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,EAAE,KAAK,IAAI;AACb;AAGA,SAAS,uBACP,KACA,YACA,aACA,iBACQ;AACR,MAAI,eAAe,aAAa;AAC9B,WAAO,KAAK,KAAK,QAAQ,WAAW;AAAA,EACtC;AAEA,SAAO,QAAQ,KAAK,mBAAmB,WAAW;AACpD;AAGA,eAAe,kBACb,KACA,gBACe;AACf,QAAM,IAAI,QAAc,CAAC,gBAAgB,kBAAkB;AACzD,UAAM,QAAQ,MAAM,gBAAgB,CAAC,SAAS,GAAG;AAAA,MAC/C;AAAA,MACA,OAAO;AAAA,MACP,OAAO,QAAQ,aAAa;AAAA,IAC9B,CAAC;AAED,UAAM,GAAG,QAAQ,CAAC,SAAS;AACzB,UAAI,SAAS,GAAG;AACd,uBAAe;AACf;AAAA,MACF;AAEA,oBAAc,IAAI,MAAM,iCAAiC,OAAO,IAAI,CAAC,EAAE,CAAC;AAAA,IAC1E,CAAC;AACD,UAAM,GAAG,SAAS,aAAa;AAAA,EACjC,CAAC;AACH;AAGA,eAAsB,OACpB,MACA,cAA8B,oBACb;AACjB,QAAM,EAAE,eAAe,SAAS,gBAAgB,IAAI,mBAAmB,IAAI;AAE3E,MAAI,eAAe;AACjB,gBAAY,OAAO,IAAI,eAAe,CAAC;AACvC,WAAO;AAAA,EACT;AAEA,QAAM,0BAA0B;AAAA,IAC9B,YAAY;AAAA,IACZ,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR;AAAA,EACF;AACA,QAAM,SACJ,QAAQ,eAAe,cACnB,MAAM,oBAAoB,SAAS,EAAE,eAAe,YAAY,IAAI,CAAC,IACrE,MAAM,qBAAqB,SAAS,EAAE,iBAAiB,wBAAwB,CAAC;AAEtF,cAAY,OAAO,IAAI,OAAO,KAAK;AAEnC,MAAI,QAAQ,YAAY;AACtB,UAAM,kBAAkB,OAAO,iBAAiB,QAAQ,cAAc;AAAA,EACxE;AAEA,SAAO;AACT;","names":[]}
@@ -0,0 +1,81 @@
1
+ import {
2
+ writePackageManagerNotes
3
+ } from "./chunk-N6W5XQS6.js";
4
+ import {
5
+ applyFeatureFlags
6
+ } from "./chunk-ZCLQAKLB.js";
7
+ import {
8
+ replaceTemplateTokens
9
+ } from "./chunk-VKUDWI56.js";
10
+
11
+ // src/render-template.ts
12
+ import { existsSync } from "fs";
13
+ import { cp, mkdir, readdir, readFile, writeFile } from "fs/promises";
14
+ import { join } from "path";
15
+ import { fileURLToPath } from "url";
16
+ var STANDALONE_WORKSPACE_VERSION = "^0.1.0";
17
+ var defaultTemplateDirectoryCandidates = [
18
+ fileURLToPath(new URL("../templates/web-ui-template", import.meta.url)),
19
+ fileURLToPath(new URL("../../../templates/web-ui-template", import.meta.url))
20
+ ];
21
+ function resolveDefaultTemplateDirectory() {
22
+ const templateDirectory = defaultTemplateDirectoryCandidates.find((candidate) => existsSync(candidate));
23
+ if (!templateDirectory) {
24
+ throw new Error("Template directory not found for create-web-ui-template.");
25
+ }
26
+ return templateDirectory;
27
+ }
28
+ async function ensureEmptyDirectory(targetDirectory) {
29
+ await mkdir(targetDirectory, { recursive: true });
30
+ const entries = await readdir(targetDirectory);
31
+ if (entries.length > 0) {
32
+ throw new Error(`Target directory is not empty: ${targetDirectory}`);
33
+ }
34
+ }
35
+ async function replaceDirectoryTokens(targetDirectory, options) {
36
+ const entries = await readdir(targetDirectory, { withFileTypes: true });
37
+ for (const entry of entries) {
38
+ const entryPath = join(targetDirectory, entry.name);
39
+ if (entry.isDirectory()) {
40
+ await replaceDirectoryTokens(entryPath, options);
41
+ continue;
42
+ }
43
+ const content = await readFile(entryPath, "utf8");
44
+ await writeFile(entryPath, replaceTemplateTokens(content, options), "utf8");
45
+ }
46
+ }
47
+ async function rewriteStandalonePackageVersions(targetDirectory) {
48
+ const packageJsonPath = join(targetDirectory, "package.json");
49
+ const packageJson = JSON.parse(await readFile(packageJsonPath, "utf8"));
50
+ for (const dependencyMap of [packageJson.dependencies, packageJson.devDependencies]) {
51
+ if (!dependencyMap) {
52
+ continue;
53
+ }
54
+ for (const [name, version] of Object.entries(dependencyMap)) {
55
+ if (version === "workspace:*") {
56
+ dependencyMap[name] = STANDALONE_WORKSPACE_VERSION;
57
+ }
58
+ }
59
+ }
60
+ await writeFile(packageJsonPath, `${JSON.stringify(packageJson, null, 2)}
61
+ `, "utf8");
62
+ }
63
+ async function renderTemplate(input) {
64
+ const templateDirectory = input.templateDirectory ?? resolveDefaultTemplateDirectory();
65
+ await ensureEmptyDirectory(input.targetDirectory);
66
+ await cp(templateDirectory, input.targetDirectory, { recursive: true });
67
+ await replaceDirectoryTokens(input.targetDirectory, input.options);
68
+ if (input.mode === "standalone") {
69
+ await rewriteStandalonePackageVersions(input.targetDirectory);
70
+ }
71
+ await applyFeatureFlags(input.targetDirectory, input.options);
72
+ return {
73
+ targetDirectory: input.targetDirectory,
74
+ notes: writePackageManagerNotes(input.options, input.options.targetMode === "workspace" ? `apps/${input.options.projectName}` : input.options.projectName)
75
+ };
76
+ }
77
+
78
+ export {
79
+ renderTemplate
80
+ };
81
+ //# sourceMappingURL=chunk-QKC3LLVR.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/render-template.ts"],"sourcesContent":["import { existsSync } from \"node:fs\";\nimport { cp, mkdir, readdir, readFile, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nimport type { InitOptions } from \"./prompts\";\nimport { applyFeatureFlags } from \"./transforms/apply-feature-flags\";\nimport { replaceTemplateTokens } from \"./transforms/replace-tokens\";\nimport { writePackageManagerNotes } from \"./transforms/write-package-manager-notes\";\n\nexport interface RenderTemplateInput {\n mode: InitOptions[\"targetMode\"];\n options: InitOptions;\n targetDirectory: string;\n templateDirectory?: string;\n}\n\nexport interface RenderTemplateResult {\n targetDirectory: string;\n notes: string;\n}\n\nconst STANDALONE_WORKSPACE_VERSION = \"^0.1.0\";\nconst defaultTemplateDirectoryCandidates = [\n fileURLToPath(new URL(\"../templates/web-ui-template\", import.meta.url)),\n fileURLToPath(new URL(\"../../../templates/web-ui-template\", import.meta.url))\n];\n\n// 解析默认模板目录,兼容仓库开发与 npm 发布后的目录结构。\nfunction resolveDefaultTemplateDirectory(): string {\n const templateDirectory = defaultTemplateDirectoryCandidates.find((candidate) => existsSync(candidate));\n\n if (!templateDirectory) {\n throw new Error(\"Template directory not found for create-web-ui-template.\");\n }\n\n return templateDirectory;\n}\n\n// 判断目标目录是否已经包含文件,避免覆写用户已有工程内容。\nasync function ensureEmptyDirectory(targetDirectory: string): Promise<void> {\n await mkdir(targetDirectory, { recursive: true });\n const entries = await readdir(targetDirectory);\n\n if (entries.length > 0) {\n throw new Error(`Target directory is not empty: ${targetDirectory}`);\n }\n}\n\n// 递归替换模板目录中的文本占位符,生成可直接落盘的项目文件。\nasync function replaceDirectoryTokens(targetDirectory: string, options: InitOptions): Promise<void> {\n const entries = await readdir(targetDirectory, { withFileTypes: true });\n\n for (const entry of entries) {\n const entryPath = join(targetDirectory, entry.name);\n\n if (entry.isDirectory()) {\n await replaceDirectoryTokens(entryPath, options);\n continue;\n }\n\n const content = await readFile(entryPath, \"utf8\");\n await writeFile(entryPath, replaceTemplateTokens(content, options), \"utf8\");\n }\n}\n\n// 将 workspace 依赖版本改写为显式 semver,供独立仓库场景安装使用。\nasync function rewriteStandalonePackageVersions(targetDirectory: string): Promise<void> {\n const packageJsonPath = join(targetDirectory, \"package.json\");\n const packageJson = JSON.parse(await readFile(packageJsonPath, \"utf8\")) as {\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n };\n\n for (const dependencyMap of [packageJson.dependencies, packageJson.devDependencies]) {\n if (!dependencyMap) {\n continue;\n }\n\n for (const [name, version] of Object.entries(dependencyMap)) {\n if (version === \"workspace:*\") {\n dependencyMap[name] = STANDALONE_WORKSPACE_VERSION;\n }\n }\n }\n\n await writeFile(packageJsonPath, `${JSON.stringify(packageJson, null, 2)}\\n`, \"utf8\");\n}\n\n// 渲染模板目录到目标位置,并应用模式与功能开关对应的改写。\nexport async function renderTemplate(input: RenderTemplateInput): Promise<RenderTemplateResult> {\n const templateDirectory = input.templateDirectory ?? resolveDefaultTemplateDirectory();\n\n await ensureEmptyDirectory(input.targetDirectory);\n await cp(templateDirectory, input.targetDirectory, { recursive: true });\n await replaceDirectoryTokens(input.targetDirectory, input.options);\n\n if (input.mode === \"standalone\") {\n await rewriteStandalonePackageVersions(input.targetDirectory);\n }\n\n await applyFeatureFlags(input.targetDirectory, input.options);\n\n return {\n targetDirectory: input.targetDirectory,\n notes: writePackageManagerNotes(input.options, input.options.targetMode === \"workspace\" ? `apps/${input.options.projectName}` : input.options.projectName)\n };\n}\n"],"mappings":";;;;;;;;;;;AAAA,SAAS,kBAAkB;AAC3B,SAAS,IAAI,OAAO,SAAS,UAAU,iBAAiB;AACxD,SAAS,YAAY;AACrB,SAAS,qBAAqB;AAmB9B,IAAM,+BAA+B;AACrC,IAAM,qCAAqC;AAAA,EACzC,cAAc,IAAI,IAAI,gCAAgC,YAAY,GAAG,CAAC;AAAA,EACtE,cAAc,IAAI,IAAI,sCAAsC,YAAY,GAAG,CAAC;AAC9E;AAGA,SAAS,kCAA0C;AACjD,QAAM,oBAAoB,mCAAmC,KAAK,CAAC,cAAc,WAAW,SAAS,CAAC;AAEtG,MAAI,CAAC,mBAAmB;AACtB,UAAM,IAAI,MAAM,0DAA0D;AAAA,EAC5E;AAEA,SAAO;AACT;AAGA,eAAe,qBAAqB,iBAAwC;AAC1E,QAAM,MAAM,iBAAiB,EAAE,WAAW,KAAK,CAAC;AAChD,QAAM,UAAU,MAAM,QAAQ,eAAe;AAE7C,MAAI,QAAQ,SAAS,GAAG;AACtB,UAAM,IAAI,MAAM,kCAAkC,eAAe,EAAE;AAAA,EACrE;AACF;AAGA,eAAe,uBAAuB,iBAAyB,SAAqC;AAClG,QAAM,UAAU,MAAM,QAAQ,iBAAiB,EAAE,eAAe,KAAK,CAAC;AAEtE,aAAW,SAAS,SAAS;AAC3B,UAAM,YAAY,KAAK,iBAAiB,MAAM,IAAI;AAElD,QAAI,MAAM,YAAY,GAAG;AACvB,YAAM,uBAAuB,WAAW,OAAO;AAC/C;AAAA,IACF;AAEA,UAAM,UAAU,MAAM,SAAS,WAAW,MAAM;AAChD,UAAM,UAAU,WAAW,sBAAsB,SAAS,OAAO,GAAG,MAAM;AAAA,EAC5E;AACF;AAGA,eAAe,iCAAiC,iBAAwC;AACtF,QAAM,kBAAkB,KAAK,iBAAiB,cAAc;AAC5D,QAAM,cAAc,KAAK,MAAM,MAAM,SAAS,iBAAiB,MAAM,CAAC;AAKtE,aAAW,iBAAiB,CAAC,YAAY,cAAc,YAAY,eAAe,GAAG;AACnF,QAAI,CAAC,eAAe;AAClB;AAAA,IACF;AAEA,eAAW,CAAC,MAAM,OAAO,KAAK,OAAO,QAAQ,aAAa,GAAG;AAC3D,UAAI,YAAY,eAAe;AAC7B,sBAAc,IAAI,IAAI;AAAA,MACxB;AAAA,IACF;AAAA,EACF;AAEA,QAAM,UAAU,iBAAiB,GAAG,KAAK,UAAU,aAAa,MAAM,CAAC,CAAC;AAAA,GAAM,MAAM;AACtF;AAGA,eAAsB,eAAe,OAA2D;AAC9F,QAAM,oBAAoB,MAAM,qBAAqB,gCAAgC;AAErF,QAAM,qBAAqB,MAAM,eAAe;AAChD,QAAM,GAAG,mBAAmB,MAAM,iBAAiB,EAAE,WAAW,KAAK,CAAC;AACtE,QAAM,uBAAuB,MAAM,iBAAiB,MAAM,OAAO;AAEjE,MAAI,MAAM,SAAS,cAAc;AAC/B,UAAM,iCAAiC,MAAM,eAAe;AAAA,EAC9D;AAEA,QAAM,kBAAkB,MAAM,iBAAiB,MAAM,OAAO;AAE5D,SAAO;AAAA,IACL,iBAAiB,MAAM;AAAA,IACvB,OAAO,yBAAyB,MAAM,SAAS,MAAM,QAAQ,eAAe,cAAc,QAAQ,MAAM,QAAQ,WAAW,KAAK,MAAM,QAAQ,WAAW;AAAA,EAC3J;AACF;","names":[]}
@@ -0,0 +1,21 @@
1
+ // src/transforms/replace-tokens.ts
2
+ var TOKEN_MAP = {
3
+ __ENABLE_AUTH__: "enableAuth",
4
+ __ENABLE_CHROME_TABS__: "enableChromeTabs",
5
+ __ENABLE_DESKTOP__: "enableDesktop",
6
+ __ENABLE_MICROAPP__: "enableMicroApp",
7
+ __ENABLE_SSH_FORWARDING__: "enableSshForwarding"
8
+ };
9
+ function replaceTemplateTokens(content, options) {
10
+ let output = content.replaceAll("__PROJECT_NAME__", options.projectName);
11
+ output = output.replaceAll("__PACKAGE_MANAGER__", options.packageManager);
12
+ for (const [token, key] of Object.entries(TOKEN_MAP)) {
13
+ output = output.replaceAll(token, String(options[key]));
14
+ }
15
+ return output;
16
+ }
17
+
18
+ export {
19
+ replaceTemplateTokens
20
+ };
21
+ //# sourceMappingURL=chunk-VKUDWI56.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/transforms/replace-tokens.ts"],"sourcesContent":["import type { InitOptions } from \"../prompts\";\n\nconst TOKEN_MAP: Record<string, keyof Pick<InitOptions, \"enableDesktop\" | \"enableMicroApp\" | \"enableChromeTabs\" | \"enableAuth\" | \"enableSshForwarding\">> = {\n __ENABLE_AUTH__: \"enableAuth\",\n __ENABLE_CHROME_TABS__: \"enableChromeTabs\",\n __ENABLE_DESKTOP__: \"enableDesktop\",\n __ENABLE_MICROAPP__: \"enableMicroApp\",\n __ENABLE_SSH_FORWARDING__: \"enableSshForwarding\"\n};\n\n// 将模板源码中的占位符替换为当前初始化选项对应的值。\nexport function replaceTemplateTokens(content: string, options: InitOptions): string {\n let output = content.replaceAll(\"__PROJECT_NAME__\", options.projectName);\n output = output.replaceAll(\"__PACKAGE_MANAGER__\", options.packageManager);\n\n for (const [token, key] of Object.entries(TOKEN_MAP)) {\n output = output.replaceAll(token, String(options[key]));\n }\n\n return output;\n}\n"],"mappings":";AAEA,IAAM,YAAqJ;AAAA,EACzJ,iBAAiB;AAAA,EACjB,wBAAwB;AAAA,EACxB,oBAAoB;AAAA,EACpB,qBAAqB;AAAA,EACrB,2BAA2B;AAC7B;AAGO,SAAS,sBAAsB,SAAiB,SAA8B;AACnF,MAAI,SAAS,QAAQ,WAAW,oBAAoB,QAAQ,WAAW;AACvE,WAAS,OAAO,WAAW,uBAAuB,QAAQ,cAAc;AAExE,aAAW,CAAC,OAAO,GAAG,KAAK,OAAO,QAAQ,SAAS,GAAG;AACpD,aAAS,OAAO,WAAW,OAAO,OAAO,QAAQ,GAAG,CAAC,CAAC;AAAA,EACxD;AAEA,SAAO;AACT;","names":[]}
@@ -0,0 +1,93 @@
1
+ // src/transforms/apply-feature-flags.ts
2
+ import { readFile, rm, writeFile } from "fs/promises";
3
+ import { join } from "path";
4
+ function removeSnippet(content, snippet) {
5
+ return content.replace(snippet, "");
6
+ }
7
+ async function rewriteFile(filePath, transform) {
8
+ const content = await readFile(filePath, "utf8");
9
+ await writeFile(filePath, transform(content), "utf8");
10
+ }
11
+ async function rewritePackageJson(targetDirectory, options) {
12
+ const packageJsonPath = join(targetDirectory, "package.json");
13
+ const packageJson = JSON.parse(await readFile(packageJsonPath, "utf8"));
14
+ if (!options.enableDesktop) {
15
+ delete packageJson.scripts?.["dev:desktop"];
16
+ delete packageJson.dependencies?.["@wwchao6411/platform-shell-electron"];
17
+ delete packageJson.devDependencies?.electron;
18
+ delete packageJson.devDependencies?.["electron-vite"];
19
+ }
20
+ if (!options.enableMicroApp) {
21
+ delete packageJson.dependencies?.["@micro-zoe/micro-app"];
22
+ delete packageJson.dependencies?.["@wwchao6411/platform-shell-microapp"];
23
+ }
24
+ await writeFile(packageJsonPath, `${JSON.stringify(packageJson, null, 2)}
25
+ `, "utf8");
26
+ }
27
+ async function pruneAuthFiles(targetDirectory) {
28
+ await rm(join(targetDirectory, "src", "business", "LoginPage.vue"), { force: true });
29
+ await rewriteFile(
30
+ join(targetDirectory, "src", "app", "App.vue"),
31
+ (content) => removeSnippet(
32
+ content,
33
+ ' <RouterLink\n class="rounded-2xl px-4 py-2 text-sm text-slate-200 transition hover:bg-white/10"\n to="/login"\n >\n Login\n </RouterLink>\n'
34
+ )
35
+ );
36
+ await rewriteFile(
37
+ join(targetDirectory, "src", "platform", "register-routes.ts"),
38
+ (content) => removeSnippet(
39
+ removeSnippet(content, 'import LoginPage from "../business/LoginPage.vue";\n'),
40
+ ' {\n path: "/login",\n name: "login",\n component: LoginPage\n },\n'
41
+ )
42
+ );
43
+ }
44
+ async function pruneMicroAppFiles(targetDirectory) {
45
+ await rm(join(targetDirectory, "src", "business", "PreviewMicroAppPage.vue"), { force: true });
46
+ await rewriteFile(
47
+ join(targetDirectory, "src", "app", "App.vue"),
48
+ (content) => removeSnippet(
49
+ content,
50
+ ' <RouterLink\n class="rounded-2xl px-4 py-2 text-sm text-slate-200 transition hover:bg-white/10"\n to="/workspace/sample-microapp"\n >\n Sample MicroApp\n </RouterLink>\n'
51
+ )
52
+ );
53
+ await rewriteFile(
54
+ join(targetDirectory, "src", "business", "WorkspacePage.vue"),
55
+ (content) => removeSnippet(
56
+ content,
57
+ ' <template #launcher>\n <RouterLink\n class="rounded-3xl border border-white/10 bg-slate-950/60 px-5 py-4 text-left transition hover:border-cyan-300/40 hover:bg-slate-900/80"\n to="/workspace/sample-microapp"\n >\n <p class="text-sm font-semibold text-white">\n Sample MicroApp\n </p>\n <p class="mt-2 text-xs text-slate-400">\n /workspace/sample-microapp\n </p>\n </RouterLink>\n </template>\n'
58
+ ).replace('import { RouterLink } from "vue-router";\n', "")
59
+ );
60
+ await rewriteFile(
61
+ join(targetDirectory, "src", "platform", "register-routes.ts"),
62
+ (content) => removeSnippet(
63
+ removeSnippet(
64
+ content,
65
+ 'import PreviewMicroAppPage from "../business/PreviewMicroAppPage.vue";\n'
66
+ ),
67
+ ' {\n path: "/workspace/sample-microapp",\n name: "sample-microapp",\n component: PreviewMicroAppPage\n }\n'
68
+ )
69
+ );
70
+ }
71
+ async function applyFeatureFlags(targetDirectory, options) {
72
+ await rewritePackageJson(targetDirectory, options);
73
+ if (!options.enableDesktop) {
74
+ await rm(join(targetDirectory, "electron"), { force: true, recursive: true });
75
+ await rm(join(targetDirectory, "electron.vite.config.ts"), { force: true });
76
+ }
77
+ if (!options.enableMicroApp) {
78
+ await pruneMicroAppFiles(targetDirectory);
79
+ }
80
+ if (!options.enableAuth) {
81
+ await pruneAuthFiles(targetDirectory);
82
+ }
83
+ if (!options.enableSshForwarding) {
84
+ await rm(join(targetDirectory, "electron", "forwarding", "forwarding-manager.ts"), {
85
+ force: true
86
+ });
87
+ }
88
+ }
89
+
90
+ export {
91
+ applyFeatureFlags
92
+ };
93
+ //# sourceMappingURL=chunk-ZCLQAKLB.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/transforms/apply-feature-flags.ts"],"sourcesContent":["import { readFile, rm, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport type { InitOptions } from \"../prompts\";\n\n// 删除模板中的固定片段。\nfunction removeSnippet(content: string, snippet: string): string {\n return content.replace(snippet, \"\");\n}\n\n// 重写文本文件内容。\nasync function rewriteFile(\n filePath: string,\n transform: (content: string) => string\n): Promise<void> {\n const content = await readFile(filePath, \"utf8\");\n await writeFile(filePath, transform(content), \"utf8\");\n}\n\n// 按功能开关更新模板 package.json。\nasync function rewritePackageJson(targetDirectory: string, options: InitOptions): Promise<void> {\n const packageJsonPath = join(targetDirectory, \"package.json\");\n const packageJson = JSON.parse(await readFile(packageJsonPath, \"utf8\")) as {\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n scripts?: Record<string, string>;\n };\n\n if (!options.enableDesktop) {\n delete packageJson.scripts?.[\"dev:desktop\"];\n delete packageJson.dependencies?.[\"@wwchao6411/platform-shell-electron\"];\n delete packageJson.devDependencies?.electron;\n delete packageJson.devDependencies?.[\"electron-vite\"];\n }\n\n if (!options.enableMicroApp) {\n delete packageJson.dependencies?.[\"@micro-zoe/micro-app\"];\n delete packageJson.dependencies?.[\"@wwchao6411/platform-shell-microapp\"];\n }\n\n await writeFile(packageJsonPath, `${JSON.stringify(packageJson, null, 2)}\\n`, \"utf8\");\n}\n\n// 删除认证相关模板文件。\nasync function pruneAuthFiles(targetDirectory: string): Promise<void> {\n await rm(join(targetDirectory, \"src\", \"business\", \"LoginPage.vue\"), { force: true });\n await rewriteFile(join(targetDirectory, \"src\", \"app\", \"App.vue\"), (content) =>\n removeSnippet(\n content,\n ' <RouterLink\\n class=\"rounded-2xl px-4 py-2 text-sm text-slate-200 transition hover:bg-white/10\"\\n to=\"/login\"\\n >\\n Login\\n </RouterLink>\\n'\n )\n );\n await rewriteFile(join(targetDirectory, \"src\", \"platform\", \"register-routes.ts\"), (content) =>\n removeSnippet(\n removeSnippet(content, 'import LoginPage from \"../business/LoginPage.vue\";\\n'),\n ' {\\n path: \"/login\",\\n name: \"login\",\\n component: LoginPage\\n },\\n'\n )\n );\n}\n\n// 删除微前端示例相关模板文件。\nasync function pruneMicroAppFiles(targetDirectory: string): Promise<void> {\n await rm(join(targetDirectory, \"src\", \"business\", \"PreviewMicroAppPage.vue\"), { force: true });\n await rewriteFile(join(targetDirectory, \"src\", \"app\", \"App.vue\"), (content) =>\n removeSnippet(\n content,\n ' <RouterLink\\n class=\"rounded-2xl px-4 py-2 text-sm text-slate-200 transition hover:bg-white/10\"\\n to=\"/workspace/sample-microapp\"\\n >\\n Sample MicroApp\\n </RouterLink>\\n'\n )\n );\n await rewriteFile(join(targetDirectory, \"src\", \"business\", \"WorkspacePage.vue\"), (content) =>\n removeSnippet(\n content,\n ' <template #launcher>\\n <RouterLink\\n class=\"rounded-3xl border border-white/10 bg-slate-950/60 px-5 py-4 text-left transition hover:border-cyan-300/40 hover:bg-slate-900/80\"\\n to=\"/workspace/sample-microapp\"\\n >\\n <p class=\"text-sm font-semibold text-white\">\\n Sample MicroApp\\n </p>\\n <p class=\"mt-2 text-xs text-slate-400\">\\n /workspace/sample-microapp\\n </p>\\n </RouterLink>\\n </template>\\n'\n ).replace('import { RouterLink } from \"vue-router\";\\n', \"\")\n );\n await rewriteFile(join(targetDirectory, \"src\", \"platform\", \"register-routes.ts\"), (content) =>\n removeSnippet(\n removeSnippet(\n content,\n 'import PreviewMicroAppPage from \"../business/PreviewMicroAppPage.vue\";\\n'\n ),\n ' {\\n path: \"/workspace/sample-microapp\",\\n name: \"sample-microapp\",\\n component: PreviewMicroAppPage\\n }\\n'\n )\n );\n}\n\n// 按功能开关裁剪模板输出。\nexport async function applyFeatureFlags(\n targetDirectory: string,\n options: InitOptions\n): Promise<void> {\n await rewritePackageJson(targetDirectory, options);\n\n if (!options.enableDesktop) {\n await rm(join(targetDirectory, \"electron\"), { force: true, recursive: true });\n await rm(join(targetDirectory, \"electron.vite.config.ts\"), { force: true });\n }\n\n if (!options.enableMicroApp) {\n await pruneMicroAppFiles(targetDirectory);\n }\n\n if (!options.enableAuth) {\n await pruneAuthFiles(targetDirectory);\n }\n\n if (!options.enableSshForwarding) {\n await rm(join(targetDirectory, \"electron\", \"forwarding\", \"forwarding-manager.ts\"), {\n force: true\n });\n }\n}\n"],"mappings":";AAAA,SAAS,UAAU,IAAI,iBAAiB;AACxC,SAAS,YAAY;AAKrB,SAAS,cAAc,SAAiB,SAAyB;AAC/D,SAAO,QAAQ,QAAQ,SAAS,EAAE;AACpC;AAGA,eAAe,YACb,UACA,WACe;AACf,QAAM,UAAU,MAAM,SAAS,UAAU,MAAM;AAC/C,QAAM,UAAU,UAAU,UAAU,OAAO,GAAG,MAAM;AACtD;AAGA,eAAe,mBAAmB,iBAAyB,SAAqC;AAC9F,QAAM,kBAAkB,KAAK,iBAAiB,cAAc;AAC5D,QAAM,cAAc,KAAK,MAAM,MAAM,SAAS,iBAAiB,MAAM,CAAC;AAMtE,MAAI,CAAC,QAAQ,eAAe;AAC1B,WAAO,YAAY,UAAU,aAAa;AAC1C,WAAO,YAAY,eAAe,qCAAqC;AACvE,WAAO,YAAY,iBAAiB;AACpC,WAAO,YAAY,kBAAkB,eAAe;AAAA,EACtD;AAEA,MAAI,CAAC,QAAQ,gBAAgB;AAC3B,WAAO,YAAY,eAAe,sBAAsB;AACxD,WAAO,YAAY,eAAe,qCAAqC;AAAA,EACzE;AAEA,QAAM,UAAU,iBAAiB,GAAG,KAAK,UAAU,aAAa,MAAM,CAAC,CAAC;AAAA,GAAM,MAAM;AACtF;AAGA,eAAe,eAAe,iBAAwC;AACpE,QAAM,GAAG,KAAK,iBAAiB,OAAO,YAAY,eAAe,GAAG,EAAE,OAAO,KAAK,CAAC;AACnF,QAAM;AAAA,IAAY,KAAK,iBAAiB,OAAO,OAAO,SAAS;AAAA,IAAG,CAAC,YACjE;AAAA,MACE;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACA,QAAM;AAAA,IAAY,KAAK,iBAAiB,OAAO,YAAY,oBAAoB;AAAA,IAAG,CAAC,YACjF;AAAA,MACE,cAAc,SAAS,sDAAsD;AAAA,MAC7E;AAAA,IACF;AAAA,EACF;AACF;AAGA,eAAe,mBAAmB,iBAAwC;AACxE,QAAM,GAAG,KAAK,iBAAiB,OAAO,YAAY,yBAAyB,GAAG,EAAE,OAAO,KAAK,CAAC;AAC7F,QAAM;AAAA,IAAY,KAAK,iBAAiB,OAAO,OAAO,SAAS;AAAA,IAAG,CAAC,YACjE;AAAA,MACE;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACA,QAAM;AAAA,IAAY,KAAK,iBAAiB,OAAO,YAAY,mBAAmB;AAAA,IAAG,CAAC,YAChF;AAAA,MACE;AAAA,MACA;AAAA,IACF,EAAE,QAAQ,8CAA8C,EAAE;AAAA,EAC5D;AACA,QAAM;AAAA,IAAY,KAAK,iBAAiB,OAAO,YAAY,oBAAoB;AAAA,IAAG,CAAC,YACjF;AAAA,MACE;AAAA,QACE;AAAA,QACA;AAAA,MACF;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;AAGA,eAAsB,kBACpB,iBACA,SACe;AACf,QAAM,mBAAmB,iBAAiB,OAAO;AAEjD,MAAI,CAAC,QAAQ,eAAe;AAC1B,UAAM,GAAG,KAAK,iBAAiB,UAAU,GAAG,EAAE,OAAO,MAAM,WAAW,KAAK,CAAC;AAC5E,UAAM,GAAG,KAAK,iBAAiB,yBAAyB,GAAG,EAAE,OAAO,KAAK,CAAC;AAAA,EAC5E;AAEA,MAAI,CAAC,QAAQ,gBAAgB;AAC3B,UAAM,mBAAmB,eAAe;AAAA,EAC1C;AAEA,MAAI,CAAC,QAAQ,YAAY;AACvB,UAAM,eAAe,eAAe;AAAA,EACtC;AAEA,MAAI,CAAC,QAAQ,qBAAqB;AAChC,UAAM,GAAG,KAAK,iBAAiB,YAAY,cAAc,uBAAuB,GAAG;AAAA,MACjF,OAAO;AAAA,IACT,CAAC;AAAA,EACH;AACF;","names":[]}
@@ -0,0 +1,21 @@
1
+ import {
2
+ renderTemplate
3
+ } from "./chunk-QKC3LLVR.js";
4
+
5
+ // src/modes/standalone.ts
6
+ async function renderStandaloneMode(options, input) {
7
+ return renderTemplate({
8
+ mode: "standalone",
9
+ options: {
10
+ ...options,
11
+ targetMode: "standalone"
12
+ },
13
+ targetDirectory: input.targetDirectory,
14
+ templateDirectory: input.templateDirectory
15
+ });
16
+ }
17
+
18
+ export {
19
+ renderStandaloneMode
20
+ };
21
+ //# sourceMappingURL=chunk-ZWYKFM47.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/modes/standalone.ts"],"sourcesContent":["import type { InitOptions } from \"../prompts\";\nimport { renderTemplate, type RenderTemplateResult } from \"../render-template\";\n\nexport interface StandaloneModeInput {\n targetDirectory: string;\n templateDirectory?: string;\n}\n\n// 将模板渲染到外部目录,供独立仓库初始化场景使用。\nexport async function renderStandaloneMode(\n options: InitOptions,\n input: StandaloneModeInput\n): Promise<RenderTemplateResult> {\n return renderTemplate({\n mode: \"standalone\",\n options: {\n ...options,\n targetMode: \"standalone\"\n },\n targetDirectory: input.targetDirectory,\n templateDirectory: input.templateDirectory\n });\n}\n"],"mappings":";;;;;AASA,eAAsB,qBACpB,SACA,OAC+B;AAC/B,SAAO,eAAe;AAAA,IACpB,MAAM;AAAA,IACN,SAAS;AAAA,MACP,GAAG;AAAA,MACH,YAAY;AAAA,IACd;AAAA,IACA,iBAAiB,MAAM;AAAA,IACvB,mBAAmB,MAAM;AAAA,EAC3B,CAAC;AACH;","names":[]}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,9 @@
1
+ interface CliEnvironment {
2
+ cwd: string;
3
+ stderr: Pick<Console, "error">;
4
+ stdout: Pick<Console, "log">;
5
+ }
6
+ declare function createHelpText(): string;
7
+ declare function runCli(argv: string[], environment?: CliEnvironment): Promise<number>;
8
+
9
+ export { type CliEnvironment, createHelpText, runCli };
package/dist/cli.js ADDED
@@ -0,0 +1,16 @@
1
+ import {
2
+ createHelpText,
3
+ runCli
4
+ } from "./chunk-NOZ2FVZU.js";
5
+ import "./chunk-DRNPNIJR.js";
6
+ import "./chunk-ZWYKFM47.js";
7
+ import "./chunk-HDMQ6CVP.js";
8
+ import "./chunk-QKC3LLVR.js";
9
+ import "./chunk-N6W5XQS6.js";
10
+ import "./chunk-ZCLQAKLB.js";
11
+ import "./chunk-VKUDWI56.js";
12
+ export {
13
+ createHelpText,
14
+ runCli
15
+ };
16
+ //# sourceMappingURL=cli.js.map