@simplysm/sd-cli 14.0.70 → 14.0.71

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 (42) hide show
  1. package/dist/commands/init/generators/client.d.ts.map +1 -1
  2. package/dist/commands/init/generators/client.js +4 -1
  3. package/dist/commands/init/generators/client.js.map +1 -1
  4. package/dist/commands/init/generators/common.d.ts.map +1 -1
  5. package/dist/commands/init/generators/common.js +1 -1
  6. package/dist/commands/init/generators/common.js.map +1 -1
  7. package/dist/commands/init/normalize.d.ts.map +1 -1
  8. package/dist/commands/init/normalize.js +13 -0
  9. package/dist/commands/init/normalize.js.map +1 -1
  10. package/dist/commands/init/prompts.d.ts.map +1 -1
  11. package/dist/commands/init/prompts.js +7 -0
  12. package/dist/commands/init/prompts.js.map +1 -1
  13. package/dist/commands/init/types.d.ts +3 -0
  14. package/dist/commands/init/types.d.ts.map +1 -1
  15. package/dist/commands/init/validate.d.ts.map +1 -1
  16. package/dist/commands/init/validate.js +2 -1
  17. package/dist/commands/init/validate.js.map +1 -1
  18. package/dist/sd-cli.js +15 -12
  19. package/dist/sd-cli.js.map +1 -1
  20. package/package.json +4 -4
  21. package/src/commands/init/generators/client.ts +5 -1
  22. package/src/commands/init/generators/common.ts +4 -3
  23. package/src/commands/init/normalize.ts +16 -0
  24. package/src/commands/init/prompts.ts +8 -0
  25. package/src/commands/init/templates/client/package.json.hbs +1 -3
  26. package/src/commands/init/templates/client/public/favicon.ico +0 -0
  27. package/src/commands/init/templates/client/public/robots.txt +1 -0
  28. package/src/commands/init/templates/client/res/icon.png +0 -0
  29. package/src/commands/init/templates/client-common/src/providers/AppOrmProvider.ts.hbs +7 -7
  30. package/src/commands/init/templates/common/src/DbContext.ts.hbs +4 -0
  31. package/src/commands/init/templates/common/src/index.ts.hbs +1 -1
  32. package/src/commands/init/templates/workspace-root/pnpm-workspace.yaml +3 -14
  33. package/src/commands/init/templates/workspace-root/sd.config.ts.hbs +2 -2
  34. package/src/commands/init/types.ts +3 -0
  35. package/src/commands/init/validate.ts +2 -1
  36. package/src/sd-cli.ts +15 -12
  37. package/tests/init/__snapshots__/render.spec.ts.snap +1 -1
  38. package/tests/init/normalize.spec.ts +58 -0
  39. package/tests/init/render.spec.ts +142 -1
  40. package/tests/init/validate.spec.ts +7 -0
  41. package/src/commands/init/templates/client/ngsw-config.json +0 -27
  42. package/src/commands/init/templates/common/src/MainDbContext.ts +0 -4
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../../src/commands/init/generators/client.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAIvD,wBAAsB,cAAc,CAClC,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,UAAU,EAChB,MAAM,EAAE,UAAU,GACjB,OAAO,CAAC,IAAI,CAAC,CAiBf"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../../src/commands/init/generators/client.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAIvD,wBAAsB,cAAc,CAClC,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,UAAU,EAChB,MAAM,EAAE,UAAU,GACjB,OAAO,CAAC,IAAI,CAAC,CAqBf"}
@@ -6,9 +6,12 @@ export async function generateClient(cwd, base, client) {
6
6
  const out = path.resolve(cwd, "packages", client.name);
7
7
  const data = { ...base, client };
8
8
  await copyFixed(path.join(TPL, "tsconfig.json"), path.join(out, "tsconfig.json"));
9
- await copyFixed(path.join(TPL, "ngsw-config.json"), path.join(out, "ngsw-config.json"));
9
+ await copyFixed(path.join(TPL, "public"), path.join(out, "public"));
10
10
  await copyFixed(path.join(TPL, "src/polyfills.ts"), path.join(out, "src/polyfills.ts"));
11
11
  await copyFixed(path.join(TPL, "src/styles.scss"), path.join(out, "src/styles.scss"));
12
+ if (client.isMobile) {
13
+ await copyFixed(path.join(TPL, "res"), path.join(out, "res"));
14
+ }
12
15
  await renderToFile(path.join(TPL, "package.json.hbs"), path.join(out, "package.json"), data);
13
16
  await renderToFile(path.join(TPL, "src/main.ts.hbs"), path.join(out, "src/main.ts"), data);
14
17
  await renderToFile(path.join(TPL, "src/AppPage.ts.hbs"), path.join(out, "src/AppPage.ts"), data);
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../../../../src/commands/init/generators/client.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAGnD,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,QAAQ,CAAC,CAAC;AAEhD,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,GAAW,EACX,IAAgB,EAChB,MAAkB;IAElB,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,UAAU,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;IACvD,MAAM,IAAI,GAAG,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,CAAC;IAEjC,MAAM,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,eAAe,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC,CAAC;IAClF,MAAM,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,kBAAkB,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,kBAAkB,CAAC,CAAC,CAAC;IACxF,MAAM,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,kBAAkB,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,kBAAkB,CAAC,CAAC,CAAC;IACxF,MAAM,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,iBAAiB,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,iBAAiB,CAAC,CAAC,CAAC;IAEtF,MAAM,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,kBAAkB,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,EAAE,IAAI,CAAC,CAAC;IAC7F,MAAM,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,iBAAiB,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,aAAa,CAAC,EAAE,IAAI,CAAC,CAAC;IAC3F,MAAM,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,oBAAoB,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,gBAAgB,CAAC,EAAE,IAAI,CAAC,CAAC;IACjG,MAAM,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,oBAAoB,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,gBAAgB,CAAC,EAAE,IAAI,CAAC,CAAC;IAEjG,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;QACrB,MAAM,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,eAAe,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC,CAAC;IACpF,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../../../src/commands/init/generators/client.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAGnD,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,QAAQ,CAAC,CAAC;AAEhD,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,GAAW,EACX,IAAgB,EAChB,MAAkB;IAElB,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,UAAU,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;IACvD,MAAM,IAAI,GAAG,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,CAAC;IAEjC,MAAM,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,eAAe,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC,CAAC;IAClF,MAAM,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC;IACpE,MAAM,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,kBAAkB,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,kBAAkB,CAAC,CAAC,CAAC;IACxF,MAAM,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,iBAAiB,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,iBAAiB,CAAC,CAAC,CAAC;IAEtF,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;QACpB,MAAM,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC;IAChE,CAAC;IAED,MAAM,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,kBAAkB,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,EAAE,IAAI,CAAC,CAAC;IAC7F,MAAM,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,iBAAiB,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,aAAa,CAAC,EAAE,IAAI,CAAC,CAAC;IAC3F,MAAM,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,oBAAoB,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,gBAAgB,CAAC,EAAE,IAAI,CAAC,CAAC;IACjG,MAAM,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,oBAAoB,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,gBAAgB,CAAC,EAAE,IAAI,CAAC,CAAC;IAEjG,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;QACrB,MAAM,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,eAAe,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC,CAAC;IACpF,CAAC;AACH,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../../../src/commands/init/generators/common.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAI3C,wBAAsB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAcjF"}
1
+ {"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../../../src/commands/init/generators/common.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAI3C,wBAAsB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAejF"}
@@ -8,7 +8,7 @@ export async function generateCommon(cwd, data) {
8
8
  await renderToFile(path.join(TPL, "package.json.hbs"), path.join(out, "package.json"), data);
9
9
  await renderToFile(path.join(TPL, "src/index.ts.hbs"), path.join(out, "src/index.ts"), data);
10
10
  if (data.hasDb) {
11
- await copyFixed(path.join(TPL, "src/MainDbContext.ts"), path.join(out, "src/MainDbContext.ts"));
11
+ await renderToFile(path.join(TPL, "src/DbContext.ts.hbs"), path.join(out, "src", `${data.dbContextClassName}.ts`), data);
12
12
  }
13
13
  }
14
14
  //# sourceMappingURL=common.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"common.js","sourceRoot":"","sources":["../../../../src/commands/init/generators/common.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAGnD,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,QAAQ,CAAC,CAAC;AAEhD,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,GAAW,EAAE,IAAgB;IAChE,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,iBAAiB,CAAC,CAAC;IAEjD,MAAM,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,eAAe,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC,CAAC;IAElF,MAAM,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,kBAAkB,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,EAAE,IAAI,CAAC,CAAC;IAC7F,MAAM,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,kBAAkB,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,EAAE,IAAI,CAAC,CAAC;IAE7F,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;QACf,MAAM,SAAS,CACb,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,sBAAsB,CAAC,EACtC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,sBAAsB,CAAC,CACvC,CAAC;IACJ,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"common.js","sourceRoot":"","sources":["../../../../src/commands/init/generators/common.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAGnD,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,QAAQ,CAAC,CAAC;AAEhD,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,GAAW,EAAE,IAAgB;IAChE,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,iBAAiB,CAAC,CAAC;IAEjD,MAAM,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,eAAe,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC,CAAC;IAElF,MAAM,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,kBAAkB,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,EAAE,IAAI,CAAC,CAAC;IAC7F,MAAM,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,kBAAkB,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,EAAE,IAAI,CAAC,CAAC;IAE7F,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;QACf,MAAM,YAAY,CAChB,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,sBAAsB,CAAC,EACtC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC,kBAAkB,KAAK,CAAC,EACtD,IAAI,CACL,CAAC;IACJ,CAAC;AACH,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"normalize.d.ts","sourceRoot":"","sources":["../../../src/commands/init/normalize.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAc,SAAS,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAQtE,wBAAgB,SAAS,CAAC,KAAK,EAAE,SAAS,GAAG,eAAe,CAqC3D"}
1
+ {"version":3,"file":"normalize.d.ts","sourceRoot":"","sources":["../../../src/commands/init/normalize.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAc,SAAS,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAsBtE,wBAAgB,SAAS,CAAC,KAAK,EAAE,SAAS,GAAG,eAAe,CAuC3D"}
@@ -3,6 +3,17 @@ const DB_PORTS = {
3
3
  postgres: 5432,
4
4
  mssql: 1433,
5
5
  };
6
+ function toDbContextBase(name) {
7
+ return name.replace(/DbContext$/i, "");
8
+ }
9
+ function toDbContextClassName(name) {
10
+ const trimmed = toDbContextBase(name);
11
+ const pascal = trimmed.charAt(0).toUpperCase() + trimmed.slice(1);
12
+ return `${pascal}DbContext`;
13
+ }
14
+ function toDbContextNameUpper(name) {
15
+ return toDbContextBase(name).toUpperCase();
16
+ }
6
17
  export function normalize(input) {
7
18
  const clients = input.clients.map((c) => {
8
19
  const name = c.name.startsWith("client-") ? c.name : `client-${c.name}`;
@@ -29,6 +40,8 @@ export function normalize(input) {
29
40
  isMysql: hasDb && input.dbDialect === "mysql",
30
41
  isPostgres: hasDb && input.dbDialect === "postgres",
31
42
  isMssql: hasDb && input.dbDialect === "mssql",
43
+ dbContextClassName: hasDb ? toDbContextClassName(input.dbContextName ?? "main") : "",
44
+ dbContextNameUpper: hasDb ? toDbContextNameUpper(input.dbContextName ?? "main") : "",
32
45
  serverPort: input.serverPort ?? 40080,
33
46
  mobileAppId: hasMobile ? input.mobileAppId : undefined,
34
47
  firstMobileClientName: clients.find((c) => c.isMobile)?.name,
@@ -1 +1 @@
1
- {"version":3,"file":"normalize.js","sourceRoot":"","sources":["../../../src/commands/init/normalize.ts"],"names":[],"mappings":"AAEA,MAAM,QAAQ,GAAwD;IACpE,KAAK,EAAE,IAAI;IACX,QAAQ,EAAE,IAAI;IACd,KAAK,EAAE,IAAI;CACZ,CAAC;AAEF,MAAM,UAAU,SAAS,CAAC,KAAgB;IACxC,MAAM,OAAO,GAAiB,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QACpD,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,IAAI,EAAE,CAAC;QACxE,MAAM,QAAQ,GAAG,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC;QACrC,OAAO;YACL,IAAI;YACJ,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,SAAS,EAAE,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS;YACzC,QAAQ;SACT,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,MAAM,KAAK,GAAG,KAAK,CAAC,SAAS,IAAI,KAAK,CAAC,KAAK,CAAC;IAC7C,MAAM,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC;IAClC,MAAM,eAAe,GAAG,KAAK,CAAC,SAAS,IAAI,OAAO,CAAC,MAAM,IAAI,CAAC,CAAC;IAC/D,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;IAElD,OAAO;QACL,aAAa,EAAE,KAAK,CAAC,aAAa;QAClC,kBAAkB,EAAE,KAAK,CAAC,aAAa,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC;QACxE,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,KAAK;QACL,SAAS,EAAE,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS;QAC9C,MAAM,EAAE,KAAK,IAAI,KAAK,CAAC,SAAS,IAAI,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;QACxE,OAAO,EAAE,KAAK,IAAI,KAAK,CAAC,SAAS,KAAK,OAAO;QAC7C,UAAU,EAAE,KAAK,IAAI,KAAK,CAAC,SAAS,KAAK,UAAU;QACnD,OAAO,EAAE,KAAK,IAAI,KAAK,CAAC,SAAS,KAAK,OAAO;QAC7C,UAAU,EAAE,KAAK,CAAC,UAAU,IAAI,KAAK;QACrC,WAAW,EAAE,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS;QACtD,qBAAqB,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,IAAI;QAC5D,OAAO;QACP,SAAS;QACT,eAAe;QACf,SAAS;QACT,YAAY,EAAE,OAAO,CAAC,MAAM,GAAG,CAAC;KACjC,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"normalize.js","sourceRoot":"","sources":["../../../src/commands/init/normalize.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../../src/commands/init/prompts.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAA0C,SAAS,EAAE,MAAM,SAAS,CAAC;AAKjF,wBAAsB,UAAU,IAAI,OAAO,CAAC,SAAS,CAAC,CA8FrD"}
1
+ {"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../../src/commands/init/prompts.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAA0C,SAAS,EAAE,MAAM,SAAS,CAAC;AAKjF,wBAAsB,UAAU,IAAI,OAAO,CAAC,SAAS,CAAC,CAsGrD"}
@@ -15,6 +15,7 @@ export async function promptInit() {
15
15
  });
16
16
  let hasDb = false;
17
17
  let dbDialect;
18
+ let dbContextName;
18
19
  let serverPort;
19
20
  if (hasServer) {
20
21
  hasDb = await confirm({
@@ -30,6 +31,11 @@ export async function promptInit() {
30
31
  { name: "MSSQL", value: "mssql" },
31
32
  ],
32
33
  });
34
+ dbContextName = await input({
35
+ message: "DB context base 이름 (예: main → MainDbContext 클래스 생성):",
36
+ default: "main",
37
+ validate: (v) => /^[A-Za-z][A-Za-z0-9]*$/.test(v) || "영문 (대소문자) + 숫자만, 첫 글자는 영문",
38
+ });
33
39
  }
34
40
  const portStr = await input({
35
41
  message: "server port (dev/prod 동일):",
@@ -82,6 +88,7 @@ export async function promptInit() {
82
88
  clients,
83
89
  hasDb,
84
90
  dbDialect,
91
+ dbContextName,
85
92
  mobileAppId,
86
93
  serverPort,
87
94
  };
@@ -1 +1 @@
1
- {"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../../src/commands/init/prompts.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../../src/commands/init/prompts.ts"],"names":[],"mappings":"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"}
@@ -12,6 +12,7 @@ export interface InitInput {
12
12
  clients: ClientInputSpec[];
13
13
  hasDb: boolean;
14
14
  dbDialect?: DbDialect;
15
+ dbContextName?: string;
15
16
  mobileAppId?: string;
16
17
  serverPort?: number;
17
18
  }
@@ -32,6 +33,8 @@ export interface NormalizedInput {
32
33
  isMysql: boolean;
33
34
  isPostgres: boolean;
34
35
  isMssql: boolean;
36
+ dbContextClassName: string;
37
+ dbContextNameUpper: string;
35
38
  serverPort: number;
36
39
  mobileAppId?: string;
37
40
  firstMobileClientName?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/commands/init/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,UAAU,GAAG,KAAK,GAAG,QAAQ,CAAC;AAC1C,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,UAAU,GAAG,OAAO,CAAC;AAEvD,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,UAAU,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,SAAS;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,eAAe,EAAE,CAAC;IAC3B,KAAK,EAAE,OAAO,CAAC;IACf,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,UAAU,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,aAAa,EAAE,MAAM,CAAC;IACtB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,OAAO,CAAC;IACf,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,OAAO,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,SAAS,EAAE,OAAO,CAAC;IACnB,eAAe,EAAE,OAAO,CAAC;IACzB,SAAS,EAAE,OAAO,CAAC;IACnB,YAAY,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,UAAW,SAAQ,eAAe;IACjD,SAAS,EAAE,MAAM,CAAC;CACnB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/commands/init/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,UAAU,GAAG,KAAK,GAAG,QAAQ,CAAC;AAC1C,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,UAAU,GAAG,OAAO,CAAC;AAEvD,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,UAAU,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,SAAS;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,eAAe,EAAE,CAAC;IAC3B,KAAK,EAAE,OAAO,CAAC;IACf,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,UAAU,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,aAAa,EAAE,MAAM,CAAC;IACtB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,OAAO,CAAC;IACf,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,OAAO,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;IACjB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,SAAS,EAAE,OAAO,CAAC;IACnB,eAAe,EAAE,OAAO,CAAC;IACzB,SAAS,EAAE,OAAO,CAAC;IACnB,YAAY,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,UAAW,SAAQ,eAAe;IACjD,SAAS,EAAE,MAAM,CAAC;CACnB"}
@@ -1 +1 @@
1
- {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../../src/commands/init/validate.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAIzC,wBAAsB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CASrE;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI,CAwBpD"}
1
+ {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../../src/commands/init/validate.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAIzC,wBAAsB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAUrE;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI,CAwBpD"}
@@ -4,7 +4,8 @@ export async function validateBeforePrompt(cwd) {
4
4
  if (!(await fsx.exists(cwd)))
5
5
  return;
6
6
  const children = await fsx.readdir(cwd);
7
- const significant = children.filter((n) => n !== ".git");
7
+ // 점프리픽스 항목 (`.git`, `.idea`, `.vscode`, `.logs`, `.cache`, `.DS_Store` 등 IDE/툴 자산) 은 무시
8
+ const significant = children.filter((n) => !n.startsWith("."));
8
9
  if (significant.length > 0) {
9
10
  throw new Error(`작업 디렉토리가 비어있지 않습니다 (감지된 항목: ${significant.join(", ")}). 빈 디렉토리에서 다시 실행하세요.`);
10
11
  }
@@ -1 +1 @@
1
- {"version":3,"file":"validate.js","sourceRoot":"","sources":["../../../src/commands/init/validate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,qBAAqB,CAAC;AAG1C,MAAM,aAAa,GAAG,+BAA+B,CAAC;AAEtD,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,GAAW;IACpD,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAAE,OAAO;IACrC,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACxC,MAAM,WAAW,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC;IACzD,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC3B,MAAM,IAAI,KAAK,CACb,+BAA+B,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,uBAAuB,CAC7E,CAAC;IACJ,CAAC;AACH,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,KAAgB;IAC5C,IAAI,CAAC,KAAK,CAAC,SAAS,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACnD,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;IAC7D,CAAC;IAED,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,EAAE,CAAC;QAC7C,MAAM,IAAI,KAAK,CACb,4DAA4D,KAAK,CAAC,aAAa,GAAG,CACnF,CAAC;IACJ,CAAC;IAED,MAAM,WAAW,GAAG,IAAI,GAAG,EAAU,CAAC;IACtC,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;QAC9B,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;YAChC,MAAM,IAAI,KAAK,CACb,0CAA0C,CAAC,CAAC,IAAI,GAAG,CACpD,CAAC;QACJ,CAAC;QACD,MAAM,UAAU,GAAG,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,IAAI,EAAE,CAAC;QAC9E,IAAI,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;YAChC,MAAM,IAAI,KAAK,CAAC,sBAAsB,UAAU,GAAG,CAAC,CAAC;QACvD,CAAC;QACD,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IAC9B,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"validate.js","sourceRoot":"","sources":["../../../src/commands/init/validate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,qBAAqB,CAAC;AAG1C,MAAM,aAAa,GAAG,+BAA+B,CAAC;AAEtD,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,GAAW;IACpD,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAAE,OAAO;IACrC,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACxC,wFAAwF;IACxF,MAAM,WAAW,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;IAC/D,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC3B,MAAM,IAAI,KAAK,CACb,+BAA+B,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,uBAAuB,CAC7E,CAAC;IACJ,CAAC;AACH,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,KAAgB;IAC5C,IAAI,CAAC,KAAK,CAAC,SAAS,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACnD,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;IAC7D,CAAC;IAED,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,EAAE,CAAC;QAC7C,MAAM,IAAI,KAAK,CACb,4DAA4D,KAAK,CAAC,aAAa,GAAG,CACnF,CAAC;IACJ,CAAC;IAED,MAAM,WAAW,GAAG,IAAI,GAAG,EAAU,CAAC;IACtC,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;QAC9B,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;YAChC,MAAM,IAAI,KAAK,CACb,0CAA0C,CAAC,CAAC,IAAI,GAAG,CACpD,CAAC;QACJ,CAAC;QACD,MAAM,UAAU,GAAG,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,IAAI,EAAE,CAAC;QAC9E,IAAI,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;YAChC,MAAM,IAAI,KAAK,CAAC,sBAAsB,UAAU,GAAG,CAAC,CAAC;QACvD,CAAC;QACD,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IAC9B,CAAC;AACH,CAAC"}
package/dist/sd-cli.js CHANGED
@@ -26,19 +26,22 @@ else {
26
26
  // Production mode (.js): two-stage execution
27
27
  setupConsola({ cli: true });
28
28
  // Phase 1: replaceDeps (인라인 — 설치된 버전으로 복사)
29
- try {
30
- const { loadSdConfig } = await import("./utils/sd-config.js");
31
- const { setupReplaceDeps } = await import("./deps/replace-deps/replace-deps.js");
32
- const sdConfig = await loadSdConfig({ cwd: process.cwd(), dev: false, opt: [] });
33
- if (process.argv[2] !== "replace-deps" && sdConfig.replaceDeps != null) {
34
- await setupReplaceDeps(process.cwd(), sdConfig.replaceDeps);
29
+ // init 명령은 빈 디렉토리에서 실행되므로 sd.config.ts 사전 로드 자체를 건너뜀
30
+ if (process.argv[2] !== "init") {
31
+ try {
32
+ const { loadSdConfig } = await import("./utils/sd-config.js");
33
+ const { setupReplaceDeps } = await import("./deps/replace-deps/replace-deps.js");
34
+ const sdConfig = await loadSdConfig({ cwd: process.cwd(), dev: false, opt: [] });
35
+ if (process.argv[2] !== "replace-deps" && sdConfig.replaceDeps != null) {
36
+ await setupReplaceDeps(process.cwd(), sdConfig.replaceDeps);
37
+ }
35
38
  }
36
- }
37
- catch (err) {
38
- // sd.config.ts가 없거나 replaceDeps가 설정되지 않으면 건너뜀
39
- const code = err instanceof Error && "code" in err ? err.code : undefined;
40
- if (code !== "MODULE_NOT_FOUND" && code !== "ERR_MODULE_NOT_FOUND") {
41
- logger.warn("replaceDeps 사전 설정 실패:", err instanceof Error ? err.message : err);
39
+ catch (err) {
40
+ // sd.config.ts가 없거나 replaceDeps가 설정되지 않으면 건너뜀
41
+ const code = err instanceof Error && "code" in err ? err.code : undefined;
42
+ if (code !== "MODULE_NOT_FOUND" && code !== "ERR_MODULE_NOT_FOUND") {
43
+ logger.warn("replaceDeps 사전 설정 실패:", err instanceof Error ? err.message : err);
44
+ }
42
45
  }
43
46
  }
44
47
  // Phase 2: 실제 CLI를 새 프로세스로 실행 (모듈 캐시 초기화)
@@ -1 +1 @@
1
- {"version":3,"file":"sd-cli.js","sourceRoot":"","sources":["../src/sd-cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sd-cli.js","sourceRoot":"","sources":["../src/sd-cli.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@simplysm/sd-cli",
3
- "version": "14.0.70",
3
+ "version": "14.0.71",
4
4
  "description": "Simplysm package - CLI tool",
5
5
  "author": "simplysm",
6
6
  "license": "Apache-2.0",
@@ -45,9 +45,9 @@
45
45
  "ws": "^8.20.1",
46
46
  "yaml": "^2.9.0",
47
47
  "yargs": "^18.0.0",
48
- "@simplysm/core-node": "14.0.70",
49
- "@simplysm/storage": "14.0.70",
50
- "@simplysm/core-common": "14.0.70"
48
+ "@simplysm/core-node": "14.0.71",
49
+ "@simplysm/core-common": "14.0.71",
50
+ "@simplysm/storage": "14.0.71"
51
51
  },
52
52
  "devDependencies": {
53
53
  "@types/semver": "^7.7.1",
@@ -14,10 +14,14 @@ export async function generateClient(
14
14
  const data = { ...base, client };
15
15
 
16
16
  await copyFixed(path.join(TPL, "tsconfig.json"), path.join(out, "tsconfig.json"));
17
- await copyFixed(path.join(TPL, "ngsw-config.json"), path.join(out, "ngsw-config.json"));
17
+ await copyFixed(path.join(TPL, "public"), path.join(out, "public"));
18
18
  await copyFixed(path.join(TPL, "src/polyfills.ts"), path.join(out, "src/polyfills.ts"));
19
19
  await copyFixed(path.join(TPL, "src/styles.scss"), path.join(out, "src/styles.scss"));
20
20
 
21
+ if (client.isMobile) {
22
+ await copyFixed(path.join(TPL, "res"), path.join(out, "res"));
23
+ }
24
+
21
25
  await renderToFile(path.join(TPL, "package.json.hbs"), path.join(out, "package.json"), data);
22
26
  await renderToFile(path.join(TPL, "src/main.ts.hbs"), path.join(out, "src/main.ts"), data);
23
27
  await renderToFile(path.join(TPL, "src/AppPage.ts.hbs"), path.join(out, "src/AppPage.ts"), data);
@@ -14,9 +14,10 @@ export async function generateCommon(cwd: string, data: RenderData): Promise<voi
14
14
  await renderToFile(path.join(TPL, "src/index.ts.hbs"), path.join(out, "src/index.ts"), data);
15
15
 
16
16
  if (data.hasDb) {
17
- await copyFixed(
18
- path.join(TPL, "src/MainDbContext.ts"),
19
- path.join(out, "src/MainDbContext.ts"),
17
+ await renderToFile(
18
+ path.join(TPL, "src/DbContext.ts.hbs"),
19
+ path.join(out, "src", `${data.dbContextClassName}.ts`),
20
+ data,
20
21
  );
21
22
  }
22
23
  }
@@ -6,6 +6,20 @@ const DB_PORTS: Record<NonNullable<InitInput["dbDialect"]>, number> = {
6
6
  mssql: 1433,
7
7
  };
8
8
 
9
+ function toDbContextBase(name: string): string {
10
+ return name.replace(/DbContext$/i, "");
11
+ }
12
+
13
+ function toDbContextClassName(name: string): string {
14
+ const trimmed = toDbContextBase(name);
15
+ const pascal = trimmed.charAt(0).toUpperCase() + trimmed.slice(1);
16
+ return `${pascal}DbContext`;
17
+ }
18
+
19
+ function toDbContextNameUpper(name: string): string {
20
+ return toDbContextBase(name).toUpperCase();
21
+ }
22
+
9
23
  export function normalize(input: InitInput): NormalizedInput {
10
24
  const clients: ClientSpec[] = input.clients.map((c) => {
11
25
  const name = c.name.startsWith("client-") ? c.name : `client-${c.name}`;
@@ -34,6 +48,8 @@ export function normalize(input: InitInput): NormalizedInput {
34
48
  isMysql: hasDb && input.dbDialect === "mysql",
35
49
  isPostgres: hasDb && input.dbDialect === "postgres",
36
50
  isMssql: hasDb && input.dbDialect === "mssql",
51
+ dbContextClassName: hasDb ? toDbContextClassName(input.dbContextName ?? "main") : "",
52
+ dbContextNameUpper: hasDb ? toDbContextNameUpper(input.dbContextName ?? "main") : "",
37
53
  serverPort: input.serverPort ?? 40080,
38
54
  mobileAppId: hasMobile ? input.mobileAppId : undefined,
39
55
  firstMobileClientName: clients.find((c) => c.isMobile)?.name,
@@ -21,6 +21,7 @@ export async function promptInit(): Promise<InitInput> {
21
21
 
22
22
  let hasDb = false;
23
23
  let dbDialect: DbDialect | undefined;
24
+ let dbContextName: string | undefined;
24
25
  let serverPort: number | undefined;
25
26
  if (hasServer) {
26
27
  hasDb = await confirm({
@@ -36,6 +37,12 @@ export async function promptInit(): Promise<InitInput> {
36
37
  { name: "MSSQL", value: "mssql" },
37
38
  ],
38
39
  });
40
+ dbContextName = await input({
41
+ message: "DB context base 이름 (예: main → MainDbContext 클래스 생성):",
42
+ default: "main",
43
+ validate: (v) =>
44
+ /^[A-Za-z][A-Za-z0-9]*$/.test(v) || "영문 (대소문자) + 숫자만, 첫 글자는 영문",
45
+ });
39
46
  }
40
47
 
41
48
  const portStr = await input({
@@ -95,6 +102,7 @@ export async function promptInit(): Promise<InitInput> {
95
102
  clients,
96
103
  hasDb,
97
104
  dbDialect,
105
+ dbContextName,
98
106
  mobileAppId,
99
107
  serverPort,
100
108
  };
@@ -18,9 +18,7 @@
18
18
  "@angular/router": "^21.2.0"{{/if}}{{#if hasDb}},
19
19
  "@{{workspaceName}}/common": "workspace:*",
20
20
  "@simplysm/orm-common": "^14.0.0"{{/if}}{{#if client.isMobile}},
21
- "@capacitor/core": "^7.0.0",
22
- "@capacitor/device": "^7.0.0",
23
- "@capacitor/haptics": "^7.0.0"{{/if}}
21
+ "@capacitor/core": "^7.0.0"{{/if}}
24
22
  },
25
23
  "devDependencies": {
26
24
  "@angular/compiler": "^21.2.0",
@@ -0,0 +1 @@
1
+ User-agent: * Disallow: /
@@ -1,6 +1,6 @@
1
1
  import { inject, Injectable } from "@angular/core";
2
2
  import { createOrmClientConnector, type OrmClientConnector } from "@simplysm/service-client";
3
- import { MainDbContext } from "@{{workspaceName}}/common";
3
+ import { {{dbContextClassName}} } from "@{{workspaceName}}/common";
4
4
  import { AppServiceProvider } from "./AppServiceProvider";
5
5
 
6
6
  @Injectable({ providedIn: "root" })
@@ -12,22 +12,22 @@ export class AppOrmProvider {
12
12
  return (this._orm ??= createOrmClientConnector(this._appService.client));
13
13
  }
14
14
 
15
- connectAsync<R>(callback: (db: MainDbContext) => Promise<R>): Promise<R> {
15
+ connectAsync<R>(callback: (db: {{dbContextClassName}}) => Promise<R>): Promise<R> {
16
16
  return this.orm.connect(
17
17
  {
18
- DbClass: MainDbContext,
19
- connOpt: { configName: "MAIN" },
18
+ DbClass: {{dbContextClassName}},
19
+ connOpt: { configName: "{{dbContextNameUpper}}" },
20
20
  dbContextOpt: { database: "{{workspaceNameUpper}}", schema: "dbo" },
21
21
  },
22
22
  callback,
23
23
  );
24
24
  }
25
25
 
26
- connectWithoutTransAsync<R>(callback: (db: MainDbContext) => Promise<R>): Promise<R> {
26
+ connectWithoutTransAsync<R>(callback: (db: {{dbContextClassName}}) => Promise<R>): Promise<R> {
27
27
  return this.orm.connectWithoutTransaction(
28
28
  {
29
- DbClass: MainDbContext,
30
- connOpt: { configName: "MAIN" },
29
+ DbClass: {{dbContextClassName}},
30
+ connOpt: { configName: "{{dbContextNameUpper}}" },
31
31
  dbContextOpt: { database: "{{workspaceNameUpper}}", schema: "dbo" },
32
32
  },
33
33
  callback,
@@ -0,0 +1,4 @@
1
+ import { DbContext } from "@simplysm/orm-common";
2
+
3
+ export class {{dbContextClassName}} extends DbContext {
4
+ }
@@ -1,5 +1,5 @@
1
1
  {{#if hasDb}}
2
- export * from "./MainDbContext";
2
+ export * from "./{{dbContextClassName}}";
3
3
  {{else}}
4
4
  export {};
5
5
  {{/if}}
@@ -1,17 +1,6 @@
1
1
  packages:
2
2
  - packages/*
3
3
  - tests/*
4
- allowBuilds:
5
- '@parcel/watcher': true
6
- '@simplysm/sd-claude': true
7
- '@simplysm/sd-codex': true
8
- bufferutil: true
9
- core-js: true
10
- cpu-features: true
11
- esbuild: true
12
- lmdb: true
13
- msgpackr-extract: true
14
- sharp: true
15
- ssh2: true
16
- unrs-resolver: true
17
- utf-8-validate: true
4
+ dangerouslyAllowAllBuilds: true
5
+ minimumReleaseAgeExclude:
6
+ - @simplysm/*
@@ -11,7 +11,7 @@ const config: SdConfigFn = () => ({
11
11
  configs: {
12
12
  {{#if hasDb}}
13
13
  orm: {
14
- MAIN: {
14
+ {{dbContextNameUpper}}: {
15
15
  dialect: "{{dbDialect}}",
16
16
  host: "localhost",
17
17
  port: {{dbPort}},
@@ -45,10 +45,10 @@ const config: SdConfigFn = () => ({
45
45
  server: "server",
46
46
  {{/if}}
47
47
  {{#if isMobile}}
48
+ pwa: false,
48
49
  capacitor: {
49
50
  appId: "{{../mobileAppId}}",
50
51
  appName: "{{../description}}",
51
- plugins: {},
52
52
  icon: "res/icon.png",
53
53
  platform: {
54
54
  android: {},
@@ -14,6 +14,7 @@ export interface InitInput {
14
14
  clients: ClientInputSpec[];
15
15
  hasDb: boolean;
16
16
  dbDialect?: DbDialect;
17
+ dbContextName?: string;
17
18
  mobileAppId?: string;
18
19
  serverPort?: number;
19
20
  }
@@ -36,6 +37,8 @@ export interface NormalizedInput {
36
37
  isMysql: boolean;
37
38
  isPostgres: boolean;
38
39
  isMssql: boolean;
40
+ dbContextClassName: string;
41
+ dbContextNameUpper: string;
39
42
  serverPort: number;
40
43
  mobileAppId?: string;
41
44
  firstMobileClientName?: string;
@@ -6,7 +6,8 @@ const KEBAB_CASE_RE = /^[a-z][a-z0-9]*(-[a-z0-9]+)*$/;
6
6
  export async function validateBeforePrompt(cwd: string): Promise<void> {
7
7
  if (!(await fsx.exists(cwd))) return;
8
8
  const children = await fsx.readdir(cwd);
9
- const significant = children.filter((n) => n !== ".git");
9
+ // 점프리픽스 항목 (`.git`, `.idea`, `.vscode`, `.logs`, `.cache`, `.DS_Store` 등 IDE/툴 자산) 은 무시
10
+ const significant = children.filter((n) => !n.startsWith("."));
10
11
  if (significant.length > 0) {
11
12
  throw new Error(
12
13
  `작업 디렉토리가 비어있지 않습니다 (감지된 항목: ${significant.join(", ")}). 빈 디렉토리에서 다시 실행하세요.`,
package/src/sd-cli.ts CHANGED
@@ -30,18 +30,21 @@ if (isDev) {
30
30
  setupConsola({ cli: true });
31
31
 
32
32
  // Phase 1: replaceDeps (인라인 — 설치된 버전으로 복사)
33
- try {
34
- const { loadSdConfig } = await import("./utils/sd-config.js");
35
- const { setupReplaceDeps } = await import("./deps/replace-deps/replace-deps.js");
36
- const sdConfig = await loadSdConfig({ cwd: process.cwd(), dev: false, opt: [] });
37
- if (process.argv[2] !== "replace-deps" && sdConfig.replaceDeps != null) {
38
- await setupReplaceDeps(process.cwd(), sdConfig.replaceDeps);
39
- }
40
- } catch (err: unknown) {
41
- // sd.config.ts가 없거나 replaceDeps가 설정되지 않으면 건너뜀
42
- const code = err instanceof Error && "code" in err ? (err as NodeJS.ErrnoException).code : undefined;
43
- if (code !== "MODULE_NOT_FOUND" && code !== "ERR_MODULE_NOT_FOUND") {
44
- logger.warn("replaceDeps 사전 설정 실패:", err instanceof Error ? err.message : err);
33
+ // init 명령은 빈 디렉토리에서 실행되므로 sd.config.ts 사전 로드 자체를 건너뜀
34
+ if (process.argv[2] !== "init") {
35
+ try {
36
+ const { loadSdConfig } = await import("./utils/sd-config.js");
37
+ const { setupReplaceDeps } = await import("./deps/replace-deps/replace-deps.js");
38
+ const sdConfig = await loadSdConfig({ cwd: process.cwd(), dev: false, opt: [] });
39
+ if (process.argv[2] !== "replace-deps" && sdConfig.replaceDeps != null) {
40
+ await setupReplaceDeps(process.cwd(), sdConfig.replaceDeps);
41
+ }
42
+ } catch (err: unknown) {
43
+ // sd.config.ts가 없거나 replaceDeps가 설정되지 않으면 건너뜀
44
+ const code = err instanceof Error && "code" in err ? (err as NodeJS.ErrnoException).code : undefined;
45
+ if (code !== "MODULE_NOT_FOUND" && code !== "ERR_MODULE_NOT_FOUND") {
46
+ logger.warn("replaceDeps 사전 설정 실패:", err instanceof Error ? err.message : err);
47
+ }
45
48
  }
46
49
  }
47
50
 
@@ -122,10 +122,10 @@ const config: SdConfigFn = () => ({
122
122
  "client-pda": {
123
123
  target: "client",
124
124
  server: "server",
125
+ pwa: false,
125
126
  capacitor: {
126
127
  appId: "kr.co.demo2.app",
127
128
  appName: "Demo2 Workspace",
128
- plugins: {},
129
129
  icon: "res/icon.png",
130
130
  platform: {
131
131
  android: {},
@@ -111,4 +111,62 @@ describe("normalize", () => {
111
111
  });
112
112
  expect(r.firstMobileClientName).toBe("client-pda");
113
113
  });
114
+
115
+ it("DB=Y default → MainDbContext", () => {
116
+ const r = normalize({ ...base, hasServer: true, hasDb: true, dbDialect: "mysql" });
117
+ expect(r.dbContextClassName).toBe("MainDbContext");
118
+ });
119
+
120
+ it("DB=Y dbContextName 자유 입력 → PascalCase + DbContext suffix", () => {
121
+ const r = normalize({
122
+ ...base,
123
+ hasServer: true,
124
+ hasDb: true,
125
+ dbDialect: "mysql",
126
+ dbContextName: "order",
127
+ });
128
+ expect(r.dbContextClassName).toBe("OrderDbContext");
129
+ });
130
+
131
+ it("DB=Y dbContextName 에 DbContext suffix 이미 포함 시 중복 제거", () => {
132
+ const r = normalize({
133
+ ...base,
134
+ hasServer: true,
135
+ hasDb: true,
136
+ dbDialect: "mysql",
137
+ dbContextName: "MainDbContext",
138
+ });
139
+ expect(r.dbContextClassName).toBe("MainDbContext");
140
+ });
141
+
142
+ it("DB=N 시 dbContextClassName 은 빈 문자열", () => {
143
+ expect(normalize(base).dbContextClassName).toBe("");
144
+ });
145
+
146
+ it("DB=Y default → dbContextNameUpper=MAIN", () => {
147
+ const r = normalize({ ...base, hasServer: true, hasDb: true, dbDialect: "mysql" });
148
+ expect(r.dbContextNameUpper).toBe("MAIN");
149
+ });
150
+
151
+ it("DB=Y dbContextName=order → dbContextNameUpper=ORDER", () => {
152
+ const r = normalize({
153
+ ...base,
154
+ hasServer: true,
155
+ hasDb: true,
156
+ dbDialect: "mysql",
157
+ dbContextName: "order",
158
+ });
159
+ expect(r.dbContextNameUpper).toBe("ORDER");
160
+ });
161
+
162
+ it("DB=Y dbContextName=MainDbContext → dbContextNameUpper=MAIN (suffix 제거 후)", () => {
163
+ const r = normalize({
164
+ ...base,
165
+ hasServer: true,
166
+ hasDb: true,
167
+ dbDialect: "mysql",
168
+ dbContextName: "MainDbContext",
169
+ });
170
+ expect(r.dbContextNameUpper).toBe("MAIN");
171
+ });
114
172
  });
@@ -29,6 +29,39 @@ describe("sd.config.ts.hbs", () => {
29
29
  expect(out).toMatchSnapshot();
30
30
  });
31
31
 
32
+ it("mobile client 정의에 pwa:false 자동 포함", async () => {
33
+ const data = buildData({
34
+ workspaceName: "demo",
35
+ description: "Demo",
36
+ hasServer: true,
37
+ hasDb: false,
38
+ mobileAppId: "kr.co.demo.app",
39
+ clients: [{ name: "pda", type: "mobile", hasRouter: false }],
40
+ serverPort: 40080,
41
+ });
42
+ const out = await renderTemplate(
43
+ path.join(TPL_ROOT, "workspace-root/sd.config.ts.hbs"),
44
+ data,
45
+ );
46
+ expect(out).toContain("pwa: false");
47
+ });
48
+
49
+ it("web client 정의에는 pwa 키 없음 (기본 활성)", async () => {
50
+ const data = buildData({
51
+ workspaceName: "demo",
52
+ description: "Demo",
53
+ hasServer: true,
54
+ hasDb: false,
55
+ clients: [{ name: "admin", type: "web", hasRouter: true }],
56
+ serverPort: 40080,
57
+ });
58
+ const out = await renderTemplate(
59
+ path.join(TPL_ROOT, "workspace-root/sd.config.ts.hbs"),
60
+ data,
61
+ );
62
+ expect(out).not.toContain("pwa: false");
63
+ });
64
+
32
65
  it("case-002: server+admin+pda(mobile), DB=mysql", async () => {
33
66
  const data = buildData({
34
67
  workspaceName: "demo2",
@@ -160,7 +193,7 @@ describe("client/src/AppPage.ts.hbs", () => {
160
193
  });
161
194
 
162
195
  describe("client-common/src/providers/AppOrmProvider.ts.hbs", () => {
163
- it("workspaceNameUpper database 명에 들어감", async () => {
196
+ it("default dbContextName=main MainDbContext + workspaceNameUpper database", async () => {
164
197
  const data = buildData({
165
198
  workspaceName: "demo2",
166
199
  description: "Demo2",
@@ -176,6 +209,114 @@ describe("client-common/src/providers/AppOrmProvider.ts.hbs", () => {
176
209
  );
177
210
  expect(out).toContain('database: "DEMO2"');
178
211
  expect(out).toContain('from "@demo2/common"');
212
+ expect(out).toContain("import { MainDbContext }");
213
+ expect(out).toContain("DbClass: MainDbContext");
214
+ expect(out).toContain('configName: "MAIN"');
215
+ });
216
+
217
+ it("custom dbContextName=order → OrderDbContext 가 import·DbClass 에 반영", async () => {
218
+ const data = buildData({
219
+ workspaceName: "demo",
220
+ description: "Demo",
221
+ hasServer: true,
222
+ hasDb: true,
223
+ dbDialect: "mysql",
224
+ dbContextName: "order",
225
+ clients: [],
226
+ serverPort: 40080,
227
+ });
228
+ const out = await renderTemplate(
229
+ path.join(TPL_ROOT, "client-common/src/providers/AppOrmProvider.ts.hbs"),
230
+ data,
231
+ );
232
+ expect(out).toContain("import { OrderDbContext }");
233
+ expect(out).toContain("DbClass: OrderDbContext");
234
+ expect(out).toContain('configName: "ORDER"');
235
+ });
236
+ });
237
+
238
+ describe("sd.config.ts.hbs orm config 키", () => {
239
+ it("DB=Y default → MAIN", async () => {
240
+ const data = buildData({
241
+ workspaceName: "demo",
242
+ description: "Demo",
243
+ hasServer: true,
244
+ hasDb: true,
245
+ dbDialect: "mysql",
246
+ clients: [],
247
+ serverPort: 40080,
248
+ });
249
+ const out = await renderTemplate(
250
+ path.join(TPL_ROOT, "workspace-root/sd.config.ts.hbs"),
251
+ data,
252
+ );
253
+ expect(out).toContain("MAIN: {");
254
+ });
255
+
256
+ it("DB=Y dbContextName=order → ORDER", async () => {
257
+ const data = buildData({
258
+ workspaceName: "demo",
259
+ description: "Demo",
260
+ hasServer: true,
261
+ hasDb: true,
262
+ dbDialect: "mysql",
263
+ dbContextName: "order",
264
+ clients: [],
265
+ serverPort: 40080,
266
+ });
267
+ const out = await renderTemplate(
268
+ path.join(TPL_ROOT, "workspace-root/sd.config.ts.hbs"),
269
+ data,
270
+ );
271
+ expect(out).toContain("ORDER: {");
272
+ expect(out).not.toContain("MAIN: {");
273
+ });
274
+ });
275
+
276
+ describe("common/src/DbContext.ts.hbs", () => {
277
+ it("dbContextClassName 자리에 클래스명 들어감", async () => {
278
+ const data = buildData({
279
+ workspaceName: "demo",
280
+ description: "Demo",
281
+ hasServer: true,
282
+ hasDb: true,
283
+ dbDialect: "mysql",
284
+ dbContextName: "main",
285
+ clients: [],
286
+ serverPort: 40080,
287
+ });
288
+ const out = await renderTemplate(path.join(TPL_ROOT, "common/src/DbContext.ts.hbs"), data);
289
+ expect(out).toContain("export class MainDbContext extends DbContext");
290
+ });
291
+ });
292
+
293
+ describe("common/src/index.ts.hbs", () => {
294
+ it("DB=Y → MainDbContext re-export", async () => {
295
+ const data = buildData({
296
+ workspaceName: "demo",
297
+ description: "Demo",
298
+ hasServer: true,
299
+ hasDb: true,
300
+ dbDialect: "mysql",
301
+ clients: [],
302
+ serverPort: 40080,
303
+ });
304
+ const out = await renderTemplate(path.join(TPL_ROOT, "common/src/index.ts.hbs"), data);
305
+ expect(out).toContain('export * from "./MainDbContext"');
306
+ });
307
+
308
+ it("DB=N → 빈 export", async () => {
309
+ const data = buildData({
310
+ workspaceName: "demo",
311
+ description: "Demo",
312
+ hasServer: true,
313
+ hasDb: false,
314
+ clients: [],
315
+ serverPort: 40080,
316
+ });
317
+ const out = await renderTemplate(path.join(TPL_ROOT, "common/src/index.ts.hbs"), data);
318
+ expect(out).toContain("export {}");
319
+ expect(out).not.toContain("DbContext");
179
320
  });
180
321
  });
181
322
 
@@ -38,6 +38,13 @@ describe("validateBeforePrompt", () => {
38
38
  await fsx.mkdir(join(dir, ".git"));
39
39
  await expect(validateBeforePrompt(dir)).resolves.toBeUndefined();
40
40
  });
41
+
42
+ it(".idea, .vscode, .logs 같은 점프리픽스 항목만 있는 디렉토리는 통과", async () => {
43
+ await fsx.mkdir(join(dir, ".idea"));
44
+ await fsx.mkdir(join(dir, ".vscode"));
45
+ await fsx.write(join(dir, ".logs"), "");
46
+ await expect(validateBeforePrompt(dir)).resolves.toBeUndefined();
47
+ });
41
48
  });
42
49
 
43
50
  describe("validateInput", () => {
@@ -1,27 +0,0 @@
1
- {
2
- "$schema": "./node_modules/@angular/service-worker/config/schema.json",
3
- "index": "/index.html",
4
- "assetGroups": [
5
- {
6
- "name": "app",
7
- "installMode": "prefetch",
8
- "resources": {
9
- "files": [
10
- "/*.html",
11
- "/*.css",
12
- "/*.js"
13
- ]
14
- }
15
- },
16
- {
17
- "name": "assets",
18
- "installMode": "lazy",
19
- "updateMode": "prefetch",
20
- "resources": {
21
- "files": [
22
- "/**/*.{png,jpg,svg,ico,woff2,webmanifest}"
23
- ]
24
- }
25
- }
26
- ]
27
- }
@@ -1,4 +0,0 @@
1
- import { DbContext } from "@simplysm/orm-common";
2
-
3
- export class MainDbContext extends DbContext {
4
- }