@deepstorm/cli 0.10.0 → 0.10.2

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/dist/cli.js CHANGED
@@ -6570,14 +6570,21 @@ async function runInit(baseDir, opts) {
6570
6570
  const hasNodeBackend = opts.backend === "nodejs";
6571
6571
  const hasBackend = hasJavaBackend || hasNodeBackend;
6572
6572
  try {
6573
- if (hasFrontend) {
6574
- renderAngularTemplate(projectDir, ctx);
6575
- }
6576
- if (hasJavaBackend) {
6577
- renderJavaTemplate(projectDir, ctx);
6578
- }
6579
- if (hasNodeBackend) {
6580
- renderNestJSTemplate(projectDir, ctx, opts);
6573
+ const isMonorepo = hasFrontend && hasNodeBackend;
6574
+ if (isMonorepo) {
6575
+ renderAngularTemplate(path2.join(projectDir, "client"), ctx, true);
6576
+ renderNestJSTemplate(path2.join(projectDir, "server"), ctx, opts);
6577
+ renderMonorepoRoot(projectDir, ctx);
6578
+ } else {
6579
+ if (hasFrontend) {
6580
+ renderAngularTemplate(projectDir, ctx);
6581
+ }
6582
+ if (hasJavaBackend) {
6583
+ renderJavaTemplate(projectDir, ctx);
6584
+ }
6585
+ if (hasNodeBackend) {
6586
+ renderNestJSTemplate(projectDir, ctx, opts);
6587
+ }
6581
6588
  }
6582
6589
  renderCommonFiles(projectDir, ctx, opts);
6583
6590
  console.log(`
@@ -6586,9 +6593,15 @@ async function runInit(baseDir, opts) {
6586
6593
  if (!inPlace) {
6587
6594
  console.log(` cd ${opts.projectName}`);
6588
6595
  }
6589
- if (opts.frontend) console.log(` pnpm install # \u5B89\u88C5\u524D\u7AEF\u4F9D\u8D56`);
6590
- if (hasJavaBackend) console.log(` ./gradlew build # \u6784\u5EFA\u540E\u7AEF`);
6591
- if (hasNodeBackend) console.log(` pnpm install # \u5B89\u88C5\u4F9D\u8D56`);
6596
+ if (isMonorepo) {
6597
+ console.log(` cd client && pnpm install # \u5B89\u88C5\u524D\u7AEF\u4F9D\u8D56`);
6598
+ console.log(` cd server && pnpm install # \u5B89\u88C5\u540E\u7AEF\u4F9D\u8D56`);
6599
+ console.log(` pnpm dev # \u542F\u52A8\u524D\u540E\u7AEF\u5F00\u53D1\u670D\u52A1\u5668`);
6600
+ } else {
6601
+ if (opts.frontend) console.log(` pnpm install # \u5B89\u88C5\u524D\u7AEF\u4F9D\u8D56`);
6602
+ if (hasJavaBackend) console.log(` ./gradlew build # \u6784\u5EFA\u540E\u7AEF`);
6603
+ if (hasNodeBackend) console.log(` pnpm install # \u5B89\u88C5\u4F9D\u8D56`);
6604
+ }
6592
6605
  console.log();
6593
6606
  printProjectTree(projectDir, hasFrontend, hasJavaBackend, hasNodeBackend);
6594
6607
  if (inPlace) {
@@ -6601,9 +6614,10 @@ async function runInit(baseDir, opts) {
6601
6614
  throw err;
6602
6615
  }
6603
6616
  }
6604
- function renderAngularTemplate(projectDir, ctx) {
6617
+ function renderAngularTemplate(projectDir, ctx, subPkg = false) {
6605
6618
  const hasPrimeng = ctx.uiLib === "primeng";
6606
6619
  const hasTailwind = ctx.cssFramework === "tailwind";
6620
+ const webRoot = subPkg ? "src" : "src/main/web";
6607
6621
  writeTemplate(projectDir, "angular.json", JSON.stringify({
6608
6622
  $schema: "./node_modules/@angular/cli/lib/config/schema.json",
6609
6623
  version: 1,
@@ -6612,19 +6626,19 @@ function renderAngularTemplate(projectDir, ctx) {
6612
6626
  [ctx.packageName]: {
6613
6627
  projectType: "application",
6614
6628
  root: "",
6615
- sourceRoot: "src/main/web",
6629
+ sourceRoot: webRoot,
6616
6630
  prefix: "app",
6617
6631
  architect: {
6618
6632
  build: {
6619
6633
  builder: "@angular-devkit/build-angular:application",
6620
6634
  options: {
6621
6635
  outputPath: "build",
6622
- index: "src/main/web/index.html",
6623
- browser: "src/main/web/main.ts",
6636
+ index: `${webRoot}/index.html`,
6637
+ browser: `${webRoot}/main.ts`,
6624
6638
  polyfills: ["zone.js"],
6625
6639
  tsConfig: "tsconfig.app.json",
6626
6640
  assets: [{ glob: "**/*", input: "public" }],
6627
- styles: getAngularStyles(hasPrimeng),
6641
+ styles: getAngularStyles(hasPrimeng, webRoot),
6628
6642
  scripts: []
6629
6643
  },
6630
6644
  configurations: {
@@ -6641,7 +6655,7 @@ function renderAngularTemplate(projectDir, ctx) {
6641
6655
  },
6642
6656
  test: {
6643
6657
  builder: "@angular-devkit/build-angular:karma",
6644
- options: { polyfills: ["zone.js", "zone.js/testing"], tsConfig: "tsconfig.spec.json", assets: [{ glob: "**/*", input: "public" }], styles: getAngularStyles(hasPrimeng), scripts: [] }
6658
+ options: { polyfills: ["zone.js", "zone.js/testing"], tsConfig: "tsconfig.spec.json", assets: [{ glob: "**/*", input: "public" }], styles: getAngularStyles(hasPrimeng, webRoot), scripts: [] }
6645
6659
  }
6646
6660
  }
6647
6661
  }
@@ -6679,7 +6693,7 @@ function renderAngularTemplate(projectDir, ctx) {
6679
6693
  writeTemplate(projectDir, "tsconfig.app.json", JSON.stringify({
6680
6694
  extends: "./tsconfig.json",
6681
6695
  compilerOptions: { outDir: "./out-tsc/app", types: [] },
6682
- files: ["src/main/web/main.ts"],
6696
+ files: [`${webRoot}/main.ts`],
6683
6697
  include: ["src/**/*.d.ts"]
6684
6698
  }, null, 2));
6685
6699
  writeTemplate(projectDir, "tsconfig.spec.json", JSON.stringify({
@@ -6745,8 +6759,8 @@ export default [
6745
6759
  ];
6746
6760
  `);
6747
6761
  ensureDir2(path2.join(projectDir, "public"));
6748
- ensureDir2(path2.join(projectDir, "src/main/web/app"));
6749
- writeTemplate(projectDir, "src/main/web/index.html", `<!doctype html>
6762
+ ensureDir2(path2.join(projectDir, webRoot, "app"));
6763
+ writeTemplate(projectDir, `${webRoot}/index.html`, `<!doctype html>
6750
6764
  <html lang="zh-CN">
6751
6765
  <head>
6752
6766
  <meta charset="utf-8">
@@ -6760,7 +6774,7 @@ export default [
6760
6774
  </body>
6761
6775
  </html>
6762
6776
  `);
6763
- writeTemplate(projectDir, "src/main/web/main.ts", `import { bootstrapApplication } from '@angular/platform-browser';
6777
+ writeTemplate(projectDir, `${webRoot}/main.ts`, `import { bootstrapApplication } from '@angular/platform-browser';
6764
6778
  import { appConfig } from './app/app.config';
6765
6779
  import { App } from './app/app';
6766
6780
 
@@ -6771,8 +6785,8 @@ bootstrapApplication(App, appConfig).catch((err) => console.error(err));
6771
6785
  /* \u5168\u5C40\u6837\u5F0F */
6772
6786
  ` : `/* \u5168\u5C40\u6837\u5F0F */
6773
6787
  `;
6774
- writeTemplate(projectDir, "src/main/web/styles.css", stylesContent);
6775
- writeTemplate(projectDir, "src/main/web/app/app.ts", `import { Component } from '@angular/core';
6788
+ writeTemplate(projectDir, `${webRoot}/styles.css`, stylesContent);
6789
+ writeTemplate(projectDir, `${webRoot}/app/app.ts`, `import { Component } from '@angular/core';
6776
6790
  import { RouterOutlet } from '@angular/router';
6777
6791
 
6778
6792
  @Component({
@@ -6783,7 +6797,7 @@ import { RouterOutlet } from '@angular/router';
6783
6797
  })
6784
6798
  export class App {}
6785
6799
  `);
6786
- writeTemplate(projectDir, "src/main/web/app/app.config.ts", `import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';
6800
+ writeTemplate(projectDir, `${webRoot}/app/app.config.ts`, `import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';
6787
6801
  import { provideRouter } from '@angular/router';
6788
6802
  import { routes } from './app.routes';
6789
6803
 
@@ -6794,7 +6808,7 @@ export const appConfig: ApplicationConfig = {
6794
6808
  ],
6795
6809
  };
6796
6810
  `);
6797
- writeTemplate(projectDir, "src/main/web/app/app.routes.ts", `import { Routes } from '@angular/router';
6811
+ writeTemplate(projectDir, `${webRoot}/app/app.routes.ts`, `import { Routes } from '@angular/router';
6798
6812
 
6799
6813
  export const routes: Routes = [];
6800
6814
  `);
@@ -6804,14 +6818,33 @@ export const routes: Routes = [];
6804
6818
  }, null, 2));
6805
6819
  }
6806
6820
  }
6807
- function getAngularStyles(hasPrimeng) {
6821
+ function getAngularStyles(hasPrimeng, webRoot) {
6808
6822
  const styles = [];
6809
6823
  if (hasPrimeng) {
6810
6824
  styles.push("@primeng/themes/aura/aura.css");
6811
6825
  }
6812
- styles.push("src/main/web/styles.css");
6826
+ styles.push(`${webRoot}/styles.css`);
6813
6827
  return styles;
6814
6828
  }
6829
+ function renderMonorepoRoot(projectDir, ctx) {
6830
+ writeTemplate(projectDir, "package.json", JSON.stringify({
6831
+ name: ctx.packageName,
6832
+ version: "0.1.0",
6833
+ private: true,
6834
+ description: "",
6835
+ scripts: {
6836
+ dev: "pnpm --filter server dev & pnpm --filter client dev",
6837
+ build: "pnpm --filter server build",
6838
+ lint: "pnpm --filter server lint",
6839
+ format: "pnpm --filter server format",
6840
+ test: "pnpm --filter server test"
6841
+ }
6842
+ }, null, 2));
6843
+ writeTemplate(projectDir, "pnpm-workspace.yaml", `packages:
6844
+ - "server"
6845
+ - "client"
6846
+ `);
6847
+ }
6815
6848
  function renderJavaTemplate(projectDir, ctx) {
6816
6849
  const hasOrm = ctx.orm === "hibernate";
6817
6850
  const hasLiquibase = ctx.migration === "liquibase";
@@ -7511,14 +7544,22 @@ function generateReadme(ctx, opts) {
7511
7544
  }
7512
7545
  lines.push("");
7513
7546
  lines.push("## \u5FEB\u901F\u5F00\u59CB", "");
7514
- if (ctx.frontend) {
7547
+ if (ctx.frontend && hasNodeBackend) {
7548
+ lines.push("```bash");
7549
+ lines.push("# \u5B89\u88C5\u6240\u6709\u4F9D\u8D56");
7550
+ lines.push("pnpm install");
7551
+ lines.push("");
7552
+ lines.push("# \u542F\u52A8\u524D\u540E\u7AEF\u5F00\u53D1\u670D\u52A1\u5668");
7553
+ lines.push("pnpm dev");
7554
+ lines.push("```", "");
7555
+ } else if (ctx.frontend) {
7515
7556
  lines.push("### \u524D\u7AEF", "");
7516
7557
  lines.push("```bash");
7517
7558
  lines.push("pnpm install");
7518
7559
  lines.push("pnpm start");
7519
7560
  lines.push("```", "");
7520
7561
  }
7521
- if (hasNodeBackend) {
7562
+ if (hasNodeBackend && !ctx.frontend) {
7522
7563
  lines.push("### \u540E\u7AEF", "");
7523
7564
  lines.push("```bash");
7524
7565
  lines.push("pnpm install");
@@ -7534,10 +7575,16 @@ function generateReadme(ctx, opts) {
7534
7575
  lines.push("## \u9879\u76EE\u7ED3\u6784", "");
7535
7576
  lines.push("```");
7536
7577
  if (ctx.frontend && hasNodeBackend) {
7537
- lines.push("\u251C\u2500\u2500 src/ # NestJS + Angular");
7538
- lines.push("\u251C\u2500\u2500 angular.json # Angular \u914D\u7F6E");
7539
- lines.push("\u251C\u2500\u2500 nest-cli.json # NestJS \u914D\u7F6E");
7540
- lines.push("\u251C\u2500\u2500 tsconfig.json");
7578
+ lines.push("\u251C\u2500\u2500 server/ # NestJS \u540E\u7AEF");
7579
+ lines.push("\u2502 \u251C\u2500\u2500 src/");
7580
+ lines.push("\u2502 \u251C\u2500\u2500 nest-cli.json");
7581
+ lines.push("\u2502 \u2514\u2500\u2500 package.json");
7582
+ lines.push("\u251C\u2500\u2500 client/ # Angular \u524D\u7AEF");
7583
+ lines.push("\u2502 \u251C\u2500\u2500 src/");
7584
+ lines.push("\u2502 \u251C\u2500\u2500 public/");
7585
+ lines.push("\u2502 \u251C\u2500\u2500 angular.json");
7586
+ lines.push("\u2502 \u2514\u2500\u2500 package.json");
7587
+ lines.push("\u251C\u2500\u2500 pnpm-workspace.yaml");
7541
7588
  lines.push("\u2514\u2500\u2500 package.json");
7542
7589
  } else if (ctx.frontend && ctx.backend) {
7543
7590
  lines.push("\u251C\u2500\u2500 src/main/web/ # Angular \u524D\u7AEF");
@@ -7600,19 +7647,33 @@ function printProjectTree(projectDir, hasFrontend, hasJavaBackend, hasNodeBacken
7600
7647
  console.log(" \u251C\u2500\u2500 angular.json");
7601
7648
  console.log(" \u2514\u2500\u2500 package.json");
7602
7649
  } else if (hasFrontend && hasNodeBackend) {
7603
- console.log(" \u251C\u2500\u2500 src/");
7604
- console.log(" \u2502 \u251C\u2500\u2500 app.controller.ts");
7605
- console.log(" \u2502 \u251C\u2500\u2500 app.module.ts");
7606
- console.log(" \u2502 \u251C\u2500\u2500 app.service.ts");
7607
- console.log(" \u2502 \u251C\u2500\u2500 main.ts");
7608
- console.log(" \u2502 \u251C\u2500\u2500 prisma/ # Prisma ORM");
7609
- console.log(" \u2502 \u2514\u2500\u2500 agent/ # Claude Agent SDK");
7610
- console.log(" \u251C\u2500\u2500 prisma/");
7611
- console.log(" \u2502 \u2514\u2500\u2500 schema.prisma");
7612
- console.log(" \u251C\u2500\u2500 nest-cli.json");
7613
- console.log(" \u251C\u2500\u2500 tsconfig.json");
7614
- console.log(" \u251C\u2500\u2500 angular.json");
7615
- console.log(" \u2514\u2500\u2500 package.json");
7650
+ console.log(" \u251C\u2500\u2500 server/ # NestJS \u540E\u7AEF");
7651
+ console.log(" \u2502 \u251C\u2500\u2500 src/");
7652
+ console.log(" \u2502 \u2502 \u251C\u2500\u2500 app.controller.ts");
7653
+ console.log(" \u2502 \u2502 \u251C\u2500\u2500 app.module.ts");
7654
+ console.log(" \u2502 \u2502 \u251C\u2500\u2500 app.service.ts");
7655
+ console.log(" \u2502 \u2502 \u251C\u2500\u2500 main.ts");
7656
+ console.log(" \u2502 \u2502 \u251C\u2500\u2500 prisma/ # Prisma ORM");
7657
+ console.log(" \u2502 \u2502 \u2514\u2500\u2500 agent/ # Claude Agent SDK");
7658
+ console.log(" \u2502 \u251C\u2500\u2500 prisma/");
7659
+ console.log(" \u2502 \u2502 \u2514\u2500\u2500 schema.prisma");
7660
+ console.log(" \u2502 \u251C\u2500\u2500 nest-cli.json");
7661
+ console.log(" \u2502 \u251C\u2500\u2500 tsconfig.json");
7662
+ console.log(" \u2502 \u2514\u2500\u2500 package.json");
7663
+ console.log(" \u251C\u2500\u2500 client/ # Angular \u524D\u7AEF");
7664
+ console.log(" \u2502 \u251C\u2500\u2500 src/");
7665
+ console.log(" \u2502 \u2502 \u251C\u2500\u2500 index.html");
7666
+ console.log(" \u2502 \u2502 \u251C\u2500\u2500 main.ts");
7667
+ console.log(" \u2502 \u2502 \u251C\u2500\u2500 styles.css");
7668
+ console.log(" \u2502 \u2502 \u2514\u2500\u2500 app/");
7669
+ console.log(" \u2502 \u251C\u2500\u2500 public/");
7670
+ console.log(" \u2502 \u251C\u2500\u2500 angular.json");
7671
+ console.log(" \u2502 \u251C\u2500\u2500 tsconfig.json");
7672
+ console.log(" \u2502 \u2514\u2500\u2500 package.json");
7673
+ console.log(" \u251C\u2500\u2500 pnpm-workspace.yaml");
7674
+ console.log(" \u251C\u2500\u2500 package.json");
7675
+ console.log(" \u251C\u2500\u2500 .env");
7676
+ console.log(" \u2514\u2500\u2500 .gitignore");
7616
7677
  } else if (hasFrontend) {
7617
7678
  console.log(" \u251C\u2500\u2500 src/main/web/ # Angular \u524D\u7AEF");
7618
7679
  console.log(" \u251C\u2500\u2500 angular.json");
@@ -104,7 +104,7 @@
104
104
  "buildTool": "pnpm:*",
105
105
  "formatCmd": "pnpm",
106
106
  "fileExt": "*.component.ts / *.service.ts / *.ts",
107
- "sourcePath": "src/main/web/",
107
+ "sourcePath": "client/src/",
108
108
  "styleRef": "→ 参考 [Angular 前端速查](quick-reference.md)"
109
109
  },
110
110
  "affectedTemplates": [
@@ -405,7 +405,7 @@
405
405
  "buildTool": "pnpm:*",
406
406
  "formatCmd": "npx eslint",
407
407
  "fileExt": "*.ts",
408
- "sourcePath": "src/ test/",
408
+ "sourcePath": "server/src/ server/test/",
409
409
  "styleRef": "→ 参考 [Node.js NestJS 后端速查](quick-reference.md)"
410
410
  },
411
411
  "availableAiFrameworks": [
@@ -35,19 +35,19 @@
35
35
  ## 构建命令
36
36
 
37
37
  ```bash
38
- # 依赖安装
38
+ # 依赖安装(在项目根目录执行)
39
39
  pnpm install
40
40
 
41
- # Prisma 客户端生成
42
- npx prisma generate
41
+ # Prisma 客户端生成(在 server/ 目录执行)
42
+ cd server && npx prisma generate
43
43
 
44
44
  # 代码检查
45
- npx eslint src/ --ext .ts
46
- npx prettier --check src/
45
+ cd server && npx eslint src/ --ext .ts
46
+ cd server && npx prettier --check src/
47
47
 
48
48
  # 测试
49
- npx jest
49
+ cd server && npx jest
50
50
 
51
51
  # 构建
52
- npx nest build
52
+ cd server && npx nest build
53
53
  ```
@@ -79,30 +79,31 @@ export class ToolsModule {}
79
79
  ## 项目目录结构
80
80
 
81
81
  ```
82
- src/
82
+ server/src/
83
83
  ├── main.ts # 入口文件
84
84
  ├── app.module.ts # 根模块
85
85
  ├── app.controller.ts # 根 Controller(健康检查)
86
86
  ├── prisma/
87
87
  │ ├── prisma.module.ts # Prisma 全局模块
88
88
  │ └── prisma.service.ts # Prisma Client 封装
89
- ├── modules/
90
- │ └── {module}/
91
- │ ├── {module}.module.ts
92
- │ ├── {module}.controller.ts
93
- │ ├── {module}.service.ts
94
- │ ├── dto/
95
- │ │ ├── create-{entity}.dto.ts
96
- │ │ └── update-{entity}.dto.ts
97
- │ └── entities/
98
- │ └── {entity}.entity.ts # Prisma 生成类型的二次封装(可选)
99
89
  ├── common/
100
- │ ├── filters/ # 全局异常过滤器
101
- │ ├── pipes/ # 全局管道
102
- │ ├── interceptors/ # 全局拦截器
103
- └── guards/ # 全局守卫
104
- └── config/
105
- └── configuration.ts # 配置模块
90
+ │ ├── guards/ # 认证/授权守卫
91
+ │ ├── interceptors/ # 请求拦截器
92
+ │ ├── filters/ # 异常过滤器
93
+ ├── pipes/ # 管道校验
94
+ └── decorators/ # 自定义装饰器
95
+ ├── config/
96
+ │ └── app.config.ts # 应用配置
97
+ └── modules/
98
+ └── {module}/
99
+ ├── {module}.module.ts
100
+ ├── {module}.controller.ts
101
+ ├── {module}.service.ts
102
+ ├── dto/
103
+ │ ├── create-{entity}.dto.ts
104
+ │ └── update-{entity}.dto.ts
105
+ └── entities/
106
+ └── {entity}.entity.ts # Prisma 生成类型的二次封装(可选)
106
107
  ```
107
108
 
108
109
  ## 常见坑
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deepstorm/cli",
3
- "version": "0.10.0",
3
+ "version": "0.10.2",
4
4
  "description": "DeepStorm CLI — 一键配置项目开发环境",
5
5
  "license": "MIT",
6
6
  "author": "billkang",
@@ -16,7 +16,7 @@
16
16
  "dotenv": "^17.4.2",
17
17
  "handlebars": "^4.7.8",
18
18
  "js-yaml": "^4.1.0",
19
- "@deepstorm/pilot": "^0.10.0"
19
+ "@deepstorm/pilot": "^0.10.2"
20
20
  },
21
21
  "devDependencies": {
22
22
  "@types/node": "^22.0.0",