birc-generator 0.9.0 → 0.9.1

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/PROJECT.md CHANGED
@@ -48,7 +48,7 @@ anchor 就不要重寫整份設定;推測以後會用到的模組先不要做
48
48
 
49
49
  ## 慣例
50
50
 
51
- **make 一次整組。** `make` 串 `makeStackActions`:Entity + DAO + Mapper + DTO + Service + Controller。`--migration` 生 `create_{table}_table`(Flyway SQL)。`--seed` 生 `XxxSeeder`(Java,走 DAO;`birc seed` 才執行)。單層指令共用同一組 actions,不另寫一份。`make:entity` 產出 Entity、`XxxDAO extends BaseDAO`。`--migration` / `--seed` 同 `make:model`;已有 Entity 就跳過,只補 SQL / Seeder。`make:model` 同 Entity + DAO;`--migration` / `--seed` 同上,`--controller` 生 Controller。`make:seeder BookSeeder` 只生 Seeder(寫 `Book` 也可以,結尾 `Seeder` 會剝掉再對 Entity)。`--soft-delete` 在 Entity 加 Hibernate `@SoftDelete(columnName = "deleted_at", strategy = TIMESTAMP)`,migration 加 `deleted_at TIMESTAMP NULL`;`deleteById` 不用改。不做 restore / withTrashed。`make:entity --dto` 與 `make:entity --mapper` 一併生 Mapper 與 Request / Response DTO(同一組檔)。`make:mapper` 連 Request / Response DTO,並把 MapStruct 依賴接到 `build.gradle` 的 dependency-anchor 後面(已有則跳過)。`make:service` 的 `XxxService extends BaseService`,CRUD 在 `BaseServiceImpl`;多出來的業務方法寫在 `XxxService` / `XxxServiceImpl`。指令是 `make:entity`,不是 `make::entity`。預設只生引入與初稿;加 `--example` 或 `--fields` 才生完整範例(CRUD、欄位、`@Column`)。`--example` 的 Entity 與 `make:migration` 一樣帶 `created_at` / `updated_at`(DB 填,JPA `insertable = false`),不進 CreateRequest。多模組時 Entity / DAO 落在 `databaseconfig`。路徑以 `.bircrc.json` 的 `entityPath` / `daoPath` 為準。
51
+ **make 一次整組。** `make` 串 `makeStackActions`:Entity + DAO + Mapper + DTO + Service + Controller。`--migration` 生 `create_{table}_table`(Flyway SQL)。`--seed` 生 `XxxSeeder`(Java,走 DAO;`birc seed` 才執行)。加 `--migration` / `--seed` 時已有 Java 就跳過,只補缺的檔與 SQL / Seeder。單層指令共用同一組 actions,不另寫一份。`make:entity` 產出 Entity、`XxxDAO extends BaseDAO`。`--migration` / `--seed` 同 `make:model`;已有 Entity 就跳過,只補 SQL / Seeder。`make:model` 同 Entity + DAO;`--migration` / `--seed` 同上,`--controller` 生 Controller。`make:seeder BookSeeder` 只生 Seeder(寫 `Book` 也可以,結尾 `Seeder` 會剝掉再對 Entity)。`--soft-delete` 在 Entity 加 Hibernate `@SoftDelete(columnName = "deleted_at", strategy = TIMESTAMP)`,migration 加 `deleted_at TIMESTAMP NULL`;`deleteById` 不用改。不做 restore / withTrashed。`make:entity --dto` 與 `make:entity --mapper` 一併生 Mapper 與 Request / Response DTO(同一組檔)。`make:mapper` 連 Request / Response DTO,並把 MapStruct 依賴接到 `build.gradle` 的 dependency-anchor 後面(已有則跳過)。`make:service` 的 `XxxService extends BaseService`,CRUD 在 `BaseServiceImpl`;多出來的業務方法寫在 `XxxService` / `XxxServiceImpl`。指令是 `make:entity`,不是 `make::entity`。預設只生引入與初稿;加 `--example` 或 `--fields` 才生完整範例(CRUD、欄位、`@Column`)。`--example` 的 Entity 與 `make:migration` 一樣帶 `created_at` / `updated_at`(DB 填,JPA `insertable = false`),不進 CreateRequest。多模組時 Entity / DAO 落在 `databaseconfig`。路徑以 `.bircrc.json` 的 `entityPath` / `daoPath` 為準。
52
52
 
53
53
  **例外走 ProjectException。** 基底是專案內的 `ProjectException`(`getErrorCode` / `getHttpStatus`),不是 starter 的 `BusinessException`。`create` 會生 `ProjectException`、`NotFoundException`、`ExceptionHandleController`、`web/Result`。`make:exception` 生的類別一律 `extends ProjectException`。Controller 回傳專案內 `Result<T>`,不引用 `tw.edu.ntub.birc.starter`。
54
54
 
package/README.md CHANGED
@@ -122,7 +122,7 @@ ValidGroup、Spotless、注入 agent 文件),不再問。
122
122
  | `birc update` | 更新本機 `birc`(`npm install -g birc-generator@latest`) |
123
123
  | `birc add` | 往既有專案加模組。沒帶名稱會互動勾選;`birc add email sentry` 直接加。`--force` 覆寫已選的已安裝 feature 檔 |
124
124
  | `birc sync` | 用目前 template 覆寫全部已安裝 feature 的檔(不動 yml / gradle) |
125
- | `birc make` | 一次生 Entity + DAO + Mapper + DTO + Service + Controller;加 `--migration` / `--seed` |
125
+ | `birc make` | 一次生 Entity + DAO + Mapper + DTO + Service + Controller;加 `--migration` / `--seed`。已有 Java 時加這兩個旗標會跳過,只補缺的檔與 SQL / Seeder |
126
126
  | `birc make:entity` | Entity、`XxxDAO`;加 `--migration` / `--seed` / `--dto`、`--mapper`、`--soft-delete`。已有檔要覆寫加 `--force`;只要表或 Seeder 可 `--migration` / `--seed`,不會覆寫 Entity |
127
127
  | `birc make:model` | 同 `make:entity`;加 `--migration` / `--seed` / `--controller` / `--soft-delete` |
128
128
  | `birc make:mapper` | Mapper 和 CreateRequest / Response |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "birc-generator",
3
- "version": "0.9.0",
3
+ "version": "0.9.1",
4
4
  "description": "Spring Boot 4 CRUD scaffold generator built on Plop.js",
5
5
  "license": "MIT",
6
6
  "author": "lucashsu95",
package/plopfile.js CHANGED
@@ -201,6 +201,10 @@ function includeModelSeed(data) {
201
201
  return Boolean(data && data.seed) || process.env.BIRC_MAKE_SEED === '1';
202
202
  }
203
203
 
204
+ function skipExistingMakeFiles(data) {
205
+ return includeModelMigration(data) || includeModelSeed(data);
206
+ }
207
+
204
208
  function includeModelController(data) {
205
209
  return Boolean(data && data.controller) || process.env.BIRC_MAKE_CONTROLLER === '1';
206
210
  }
@@ -1157,12 +1161,13 @@ module.exports = function (plop) {
1157
1161
  ];
1158
1162
  }
1159
1163
 
1160
- function makeMapperActions(data) {
1164
+ function makeMapperActions(data, options) {
1161
1165
  const { root, gradlePath, templateData } = makeContext(data);
1166
+ const skipIfExists = Boolean(options && options.skipIfExists);
1162
1167
  return [
1163
- { type: 'add', path: `${root}/dto/{{pascalCase entityName}}CreateRequest.java`, templateFile: 'templates/dto-request.hbs', data: templateData },
1164
- { type: 'add', path: `${root}/dto/{{pascalCase entityName}}Response.java`, templateFile: 'templates/dto-response.hbs', data: templateData },
1165
- { type: 'add', path: `${root}/mapper/{{pascalCase entityName}}Mapper.java`, templateFile: 'templates/mapper.hbs', data: templateData },
1168
+ { type: 'add', path: `${root}/dto/{{pascalCase entityName}}CreateRequest.java`, templateFile: 'templates/dto-request.hbs', data: templateData, skipIfExists },
1169
+ { type: 'add', path: `${root}/dto/{{pascalCase entityName}}Response.java`, templateFile: 'templates/dto-response.hbs', data: templateData, skipIfExists },
1170
+ { type: 'add', path: `${root}/mapper/{{pascalCase entityName}}Mapper.java`, templateFile: 'templates/mapper.hbs', data: templateData, skipIfExists },
1166
1171
  {
1167
1172
  type: 'appendFragment',
1168
1173
  path: gradlePath,
@@ -1174,16 +1179,18 @@ module.exports = function (plop) {
1174
1179
  ];
1175
1180
  }
1176
1181
 
1177
- function makeServiceActions(data) {
1182
+ function makeServiceActions(data, options) {
1178
1183
  const { root, templateData } = makeContext(data);
1184
+ const skipIfExists = Boolean(options && options.skipIfExists);
1179
1185
  return [
1180
- { type: 'add', path: `${root}/service/{{pascalCase entityName}}Service.java`, templateFile: 'templates/service.hbs', data: templateData },
1181
- { type: 'add', path: `${root}/service/impl/{{pascalCase entityName}}ServiceImpl.java`, templateFile: 'templates/serviceImpl.hbs', data: templateData }
1186
+ { type: 'add', path: `${root}/service/{{pascalCase entityName}}Service.java`, templateFile: 'templates/service.hbs', data: templateData, skipIfExists },
1187
+ { type: 'add', path: `${root}/service/impl/{{pascalCase entityName}}ServiceImpl.java`, templateFile: 'templates/serviceImpl.hbs', data: templateData, skipIfExists }
1182
1188
  ];
1183
1189
  }
1184
1190
 
1185
- function makeControllerActions(data) {
1191
+ function makeControllerActions(data, options) {
1186
1192
  const { root, templateData } = makeContext(data);
1193
+ const skipIfExists = Boolean(options && options.skipIfExists);
1187
1194
  return [
1188
1195
  {
1189
1196
  type: 'add',
@@ -1192,16 +1199,17 @@ module.exports = function (plop) {
1192
1199
  data: templateData,
1193
1200
  skipIfExists: true
1194
1201
  },
1195
- { type: 'add', path: `${root}/controller/{{pascalCase entityName}}Controller.java`, templateFile: 'templates/controller.hbs', data: templateData }
1202
+ { type: 'add', path: `${root}/controller/{{pascalCase entityName}}Controller.java`, templateFile: 'templates/controller.hbs', data: templateData, skipIfExists }
1196
1203
  ];
1197
1204
  }
1198
1205
 
1199
1206
  function makeStackActions(data) {
1207
+ const skipIfExists = skipExistingMakeFiles(data);
1200
1208
  return appendMakeSqlActions([
1201
- ...makeEntityActions(data),
1202
- ...makeMapperActions(data),
1203
- ...makeServiceActions(data),
1204
- ...makeControllerActions(data)
1209
+ ...makeEntityActions(data, { skipIfExists }),
1210
+ ...makeMapperActions(data, { skipIfExists }),
1211
+ ...makeServiceActions(data, { skipIfExists }),
1212
+ ...makeControllerActions(data, { skipIfExists })
1205
1213
  ], data);
1206
1214
  }
1207
1215
 
@@ -1215,10 +1223,10 @@ module.exports = function (plop) {
1215
1223
  description: '產生 Entity 與 DAO;--migration / --seed / --dto / --mapper / --soft-delete',
1216
1224
  prompts: [entityNamePrompt, fieldsPrompt],
1217
1225
  actions(data) {
1218
- const extras = includeModelMigration(data) || includeModelSeed(data);
1226
+ const extras = skipExistingMakeFiles(data);
1219
1227
  const actions = makeEntityActions(data, { skipIfExists: extras });
1220
1228
  if (includeMapperWithEntity(data)) {
1221
- actions.push(...makeMapperActions(data));
1229
+ actions.push(...makeMapperActions(data, { skipIfExists: extras }));
1222
1230
  }
1223
1231
  appendMakeSqlActions(actions, data);
1224
1232
  return actions;
@@ -58,7 +58,7 @@ DB → Entity → Mapper → XxxResponse → Result<T>
58
58
  ## 統一規範
59
59
 
60
60
  - 例外丟 `ProjectException` 子類(例如 `NotFoundException`),由 `ExceptionHandleController` 轉成回應。Controller 不手動 try-catch 包錯誤訊息。
61
- - 整組骨架用 `birc make`;單層用 `birc make:entity` / `make:model` / `make:mapper` / `make:service` / `make:controller` / `make:exception`。`make:entity` 只生 Entity 與 DAO;`--migration` / `--seed` 同 `make:model`(已有 Entity 就跳過,只補 SQL / Seeder)。`--dto` 與 `--mapper` 一併生 Mapper 與 DTO。`make:model` 可加 `--migration` / `--seed` / `--controller`。`make` 也可加 `--migration` / `--seed`。`make:seeder BookSeeder` 生 Java Seeder。`--soft-delete` 用 Hibernate `@SoftDelete` 的 `deleted_at`,查詢自動排除已刪;不要自寫 `@SQLDelete`。預設是初稿,完整範例加 `--example` 或 `--fields`。`make:migration create_{table}_table` 讀對應 Entity 欄位寫進 SQL。`--seed` 生 Java Seeder,用 DAO 塞資料;`birc seed` 才執行。清空資料庫用 `birc db:wipe`。不要複製其他 Entity 的程式碼來改名。
61
+ - 整組骨架用 `birc make`;單層用 `birc make:entity` / `make:model` / `make:mapper` / `make:service` / `make:controller` / `make:exception`。`make:entity` 只生 Entity 與 DAO;`--migration` / `--seed` 同 `make:model`(已有 Entity 就跳過,只補 SQL / Seeder)。`--dto` 與 `--mapper` 一併生 Mapper 與 DTO。`make:model` 可加 `--migration` / `--seed` / `--controller`。`make` 也可加 `--migration` / `--seed`(已有 Java 就跳過,只補缺的檔與 SQL / Seeder)。`make:seeder BookSeeder` 生 Java Seeder。`--soft-delete` 用 Hibernate `@SoftDelete` 的 `deleted_at`,查詢自動排除已刪;不要自寫 `@SQLDelete`。預設是初稿,完整範例加 `--example` 或 `--fields`。`make:migration create_{table}_table` 讀對應 Entity 欄位寫進 SQL。`--seed` 生 Java Seeder,用 DAO 塞資料;`birc seed` 才執行。清空資料庫用 `birc db:wipe`。不要複製其他 Entity 的程式碼來改名。
62
62
  - 欄位驗證用專案內 `validation/ValidGroup`。CRUD 用 `Create` / `Update`。`Delete` 給「刪除還要帶原因、確認碼、樂觀鎖 version」的 body。`Submit` 給草稿可少填、送審要全填(活動送審就是這組)。Controller 的 `@Validated` 與欄位 `groups` 對同一組。
63
63
  - email / sso / oauth / validGroup 用 `birc add`,不要從別的專案抄設定。
64
64
  - 格式化走 Spotless(`./gradlew spotlessApply`),不要另裝 Checkstyle。
package/test.md CHANGED
@@ -35,7 +35,7 @@
35
35
  - CLI dest:檔落在呼叫者目錄,不是 generator repo。
36
36
  - 產出 Java 沒有 `tw.edu.ntub.birc.starter` / `birc-spring-boot-starter`。
37
37
  - `make:entity --dto` / `--mapper` 與 `make:mapper` 同一組 Mapper + DTO;預設 `make:entity` 不生它們。
38
- - `make --fields --migration --seed` 寫 CREATE TABLE 與 Java `XxxSeeder`,不生 seed SQL;`make:model --migration` 的表名跟 Entity `@Table` 一致。已有 Entity 時 `make:entity --migration` / `--seed` 跳過 Java,只補 CREATE TABLE / `XxxSeeder`。
38
+ - `make --fields --migration --seed` 寫 CREATE TABLE 與 Java `XxxSeeder`,不生 seed SQL;`make:model --migration` 的表名跟 Entity `@Table` 一致。已有 Entity 時 `make` / `make:entity --migration` / `--seed` 跳過 Java,只補 CREATE TABLE / `XxxSeeder`。
39
39
  - `make:seeder` / `--seed` 讀既有 Entity 欄位寫進 `setXxx`;沒有欄位時 `run()` 是空的。`make:seeder BookSeeder` 生 `BookSeeder.java`,不是 `BookSeederSeeder`。
40
40
  - `make:migration create_{table}_table` 讀既有 Entity 欄位寫進 SQL;找不到 Entity 時仍只有 `id`。
41
41
  - `--soft-delete` 的 Entity 用 `deleted_at` + `SoftDeleteType.TIMESTAMP`;沒加 flag 的 Entity / migration 沒有這欄。