@simplysm/sd-cli 14.0.95 → 14.0.97

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 (99) hide show
  1. package/dist/commands/init/generators/client.d.ts.map +1 -1
  2. package/dist/commands/init/generators/client.js +12 -0
  3. package/dist/commands/init/generators/client.js.map +1 -1
  4. package/dist/commands/init/generators/server.d.ts.map +1 -1
  5. package/dist/commands/init/generators/server.js +1 -0
  6. package/dist/commands/init/generators/server.js.map +1 -1
  7. package/dist/commands/init/normalize.d.ts.map +1 -1
  8. package/dist/commands/init/normalize.js +1 -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 +8 -1
  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/engines/EsbuildClientEngine.d.ts.map +1 -1
  16. package/dist/engines/EsbuildClientEngine.js +1 -0
  17. package/dist/engines/EsbuildClientEngine.js.map +1 -1
  18. package/dist/esbuild/esbuild-client-config.d.ts.map +1 -1
  19. package/dist/esbuild/esbuild-client-config.js +2 -11
  20. package/dist/esbuild/esbuild-client-config.js.map +1 -1
  21. package/dist/esbuild/esbuild-postcss-plugin.d.ts +4 -0
  22. package/dist/esbuild/esbuild-postcss-plugin.d.ts.map +1 -1
  23. package/dist/esbuild/esbuild-postcss-plugin.js +15 -0
  24. package/dist/esbuild/esbuild-postcss-plugin.js.map +1 -1
  25. package/dist/esbuild/esbuild-ssr-config.d.ts +27 -0
  26. package/dist/esbuild/esbuild-ssr-config.d.ts.map +1 -0
  27. package/dist/esbuild/esbuild-ssr-config.js +113 -0
  28. package/dist/esbuild/esbuild-ssr-config.js.map +1 -0
  29. package/dist/sd-config.types.d.ts +7 -0
  30. package/dist/sd-config.types.d.ts.map +1 -1
  31. package/dist/ssg/prerender.d.ts +19 -0
  32. package/dist/ssg/prerender.d.ts.map +1 -0
  33. package/dist/ssg/prerender.js +43 -0
  34. package/dist/ssg/prerender.js.map +1 -0
  35. package/dist/workers/client.worker.d.ts +2 -0
  36. package/dist/workers/client.worker.d.ts.map +1 -1
  37. package/dist/workers/client.worker.js +21 -0
  38. package/dist/workers/client.worker.js.map +1 -1
  39. package/package.json +6 -6
  40. package/src/commands/init/generators/client.ts +53 -0
  41. package/src/commands/init/generators/server.ts +5 -0
  42. package/src/commands/init/normalize.ts +1 -0
  43. package/src/commands/init/prompts.ts +9 -1
  44. package/src/commands/init/templates/client/package.json.hbs +2 -1
  45. package/src/commands/init/templates/client/src/app/home/home.view.ts.hbs +1 -1
  46. package/src/commands/init/templates/client/src/app/home/master/role-permission/role-permission.detail.ts.hbs +221 -0
  47. package/src/commands/init/templates/client/src/app/home/master/role-permission/role-permission.view.ts.hbs +106 -0
  48. package/src/commands/init/templates/client/src/app/home/master/role-permission/role.detail.ts.hbs +277 -0
  49. package/src/commands/init/templates/client/src/app/home/master/role-permission/role.list.ts.hbs +537 -0
  50. package/src/commands/init/templates/client/src/app/home/master/user.detail.ts.hbs +337 -0
  51. package/src/commands/init/templates/client/src/app/home/master/user.list.ts.hbs +540 -0
  52. package/src/commands/init/templates/client/src/app/home/my-info/my-info.detail.ts.hbs +4 -6
  53. package/src/commands/init/templates/client/src/app/home/system/data-log/data-log.list.ts.hbs +355 -0
  54. package/src/commands/init/templates/client/src/app/home/system/system-log/system-log.list.ts.hbs +382 -0
  55. package/src/commands/init/templates/client/src/app/login/login.view.ts.hbs +3 -4
  56. package/src/commands/init/templates/client/src/app.root.ts.hbs +9 -3
  57. package/src/commands/init/templates/client/src/index.html.hbs +1 -0
  58. package/src/commands/init/templates/client/src/main.server.ts.hbs +24 -0
  59. package/src/commands/init/templates/client/src/main.ts.hbs +36 -18
  60. package/src/commands/init/templates/client/src/modals/text-view.modal.ts.hbs +30 -0
  61. package/src/commands/init/templates/client/src/routes.ts.hbs +22 -0
  62. package/src/commands/init/templates/client-common/src/index.ts.hbs +6 -4
  63. package/src/commands/init/templates/client-common/src/providers/app-auth.provider.ts.hbs +3 -3
  64. package/src/commands/init/templates/client-common/src/providers/app-orm.provider.ts.hbs +0 -11
  65. package/src/commands/init/templates/client-common/src/providers/app-service.provider.ts.hbs +24 -10
  66. package/src/commands/init/templates/client-common/src/providers/app-shared-data.provider.ts.hbs +2 -2
  67. package/src/commands/init/templates/common/package.json.hbs +2 -1
  68. package/src/commands/init/templates/common/src/app-structure.ts.hbs +7 -2
  69. package/src/commands/init/templates/common/src/auth-info-changed.event.ts.hbs +3 -1
  70. package/src/commands/init/templates/common/src/db/db-context.ts.hbs +2 -2
  71. package/src/commands/init/templates/common/src/db/tables/master/user.ts.hbs +2 -2
  72. package/src/commands/init/templates/common/src/db/tables/system/role.ts.hbs +1 -0
  73. package/src/commands/init/templates/common/src/index.ts.hbs +1 -1
  74. package/src/commands/init/templates/server/src/index.ts.hbs +3 -0
  75. package/src/commands/init/templates/server/src/main.ts.hbs +15 -1
  76. package/src/commands/init/templates/server/src/services/auth.service.ts.hbs +28 -22
  77. package/src/commands/init/templates/server/src/services/dev.service.ts.hbs +5 -5
  78. package/src/commands/init/templates/server/src/services/user.service.ts.hbs +191 -0
  79. package/src/commands/init/templates/workspace-root/sd.config.ts.hbs +3 -0
  80. package/src/commands/init/types.ts +3 -0
  81. package/src/engines/EsbuildClientEngine.ts +1 -0
  82. package/src/esbuild/esbuild-client-config.ts +2 -12
  83. package/src/esbuild/esbuild-postcss-plugin.ts +18 -0
  84. package/src/esbuild/esbuild-ssr-config.ts +149 -0
  85. package/src/sd-config.types.ts +7 -0
  86. package/src/ssg/prerender.ts +65 -0
  87. package/src/workers/client.worker.ts +26 -0
  88. package/tests/engines/base-engine.spec.ts +1 -26
  89. package/tests/init/__snapshots__/render.spec.ts.snap +38 -20
  90. package/tests/init/render.spec.ts +113 -33
  91. package/tests/utils/hmr-client-script.acc.spec.ts +0 -21
  92. package/tests/angular/vite-angular-plugin.spec.ts +0 -102
  93. package/tests/engines/engine-adapter-isolation.spec.ts +0 -79
  94. package/tests/runtime/signal-handler.spec.ts +0 -21
  95. package/tests/utils/angular-build.spec.ts +0 -109
  96. package/tests/utils/esbuild-client-config.acc.spec.ts +0 -438
  97. package/tests/utils/esbuild-client-config.spec.ts +0 -659
  98. package/tests/utils/hmr-client-script.spec.ts +0 -44
  99. package/tests/utils/tsconfig-angular.spec.ts +0 -9
@@ -0,0 +1,149 @@
1
+ import path from "path";
2
+ import esbuild from "esbuild";
3
+ import { AngularSourceFileCache } from "../angular/angular-compiler.js";
4
+ import { createClientTransformStylesheet } from "../angular/client-transform-stylesheet.js";
5
+ import {
6
+ createAngularCompilerPlugin,
7
+ type AngularCompilerPluginOptions,
8
+ } from "./esbuild-angular-compiler-plugin.js";
9
+ import { MemoryLoadResultCache } from "./load-result-cache.js";
10
+ import { createScssPlugin } from "./esbuild-scss-plugin";
11
+ import { createPostcssPlugin, loadPostcssPlugins } from "./esbuild-postcss-plugin";
12
+
13
+ export interface BuildSsrBundleOptions {
14
+ /** 패키지 디렉토리 경로 */
15
+ pkgDir: string;
16
+ /** 모노레포 루트 (workspaceRoot) */
17
+ cwd: string;
18
+ /** tsconfig 경로 (기본: pkgDir/tsconfig.json) */
19
+ tsconfig?: string;
20
+ /** 빌드 시 치환할 환경변수 */
21
+ env?: Record<string, string>;
22
+ /** PostCSS 플러그인 ([name, options] 튜플 배열) */
23
+ postcssPlugins?: [string, (object | string)?][];
24
+ /** 번들 출력 디렉토리 (기본: pkgDir/.angular/ssg) */
25
+ outdir?: string;
26
+ }
27
+
28
+ export interface SsrBundleResult {
29
+ /** 생성된 server 번들 파일 경로 */
30
+ bundlePath: string;
31
+ }
32
+
33
+ class SsrSourceFileCache extends AngularSourceFileCache {
34
+ readonly typeScriptFileCache = new Map<string, string | Uint8Array>();
35
+ readonly loadResultCache = new MemoryLoadResultCache();
36
+ }
37
+
38
+ /**
39
+ * SSG 프리렌더용 server 번들을 빌드한다.
40
+ *
41
+ * - 진입점: 가상 래퍼 — src/main.server.ts(부트스트랩 default export)를
42
+ * @angular/platform-server의 renderApplication으로 감싸 render(url, document)를 export
43
+ * - platform: node, format: esm (server 패키지 빌드 패턴과 동일)
44
+ */
45
+ export async function buildSsrBundle(options: BuildSsrBundleOptions): Promise<SsrBundleResult> {
46
+ const outdir = options.outdir ?? path.join(options.pkgDir, ".angular", "ssg");
47
+ const bundlePath = path.join(outdir, "sd-ssg-entry.mjs");
48
+
49
+ // SourceFileCache 생성 (일회성 빌드 — 증분 캐시 불필요)
50
+ const sourceFileCache = new SsrSourceFileCache();
51
+
52
+ // SCSS 스타일시트 변환용 공유 상태
53
+ const stylesheetDependencies = new Map<string, Set<string>>();
54
+ const stylesheetErrors: string[] = [];
55
+
56
+ // PostCSS 플러그인 로딩 (튜플 → 인스턴스)
57
+ const loadedPostcssPlugins = loadPostcssPlugins(options.pkgDir, options.postcssPlugins);
58
+
59
+ const cachePath = path.join(options.pkgDir, ".angular", "cache");
60
+ const transformStylesheet = createClientTransformStylesheet({
61
+ loadPaths: [
62
+ path.join(options.pkgDir, "node_modules"),
63
+ path.join(options.cwd, "node_modules"),
64
+ ],
65
+ postcssPlugins: loadedPostcssPlugins,
66
+ scssErrors: stylesheetErrors,
67
+ scssDependencies: stylesheetDependencies,
68
+ cacheDir: path.join(cachePath, "scss"),
69
+ });
70
+
71
+ const pluginOptions: AngularCompilerPluginOptions = {
72
+ tsconfig: options.tsconfig ?? path.join(options.pkgDir, "tsconfig.json"),
73
+ sourcemap: false,
74
+ advancedOptimizations: true,
75
+ thirdPartySourcemaps: false,
76
+ incremental: false,
77
+ sourceFileCache,
78
+ typeScriptFileCache: sourceFileCache.typeScriptFileCache,
79
+ loadResultCache: sourceFileCache.loadResultCache,
80
+ includeTestMetadata: false,
81
+ persistentCachePath: cachePath,
82
+ transformStylesheet,
83
+ stylesheetDependencies,
84
+ stylesheetErrors,
85
+ };
86
+
87
+ const angularPlugin = createAngularCompilerPlugin(pluginOptions);
88
+
89
+ const scssPlugin = createScssPlugin({
90
+ loadPaths: [
91
+ path.join(options.pkgDir, "node_modules"),
92
+ path.join(options.cwd, "node_modules"),
93
+ ],
94
+ });
95
+
96
+ // define 주입 (client 빌드 패턴 + 서버 렌더 플래그)
97
+ const define: Record<string, string> = {
98
+ ngDevMode: "false",
99
+ ngJitMode: "false",
100
+ ngHmrMode: "false",
101
+ ngServerMode: "true",
102
+ };
103
+ if (options.env != null) {
104
+ define["import.meta.env"] = JSON.stringify(options.env);
105
+ }
106
+
107
+ // CJS 패키지 require() 지원 banner (server 패키지 빌드 패턴과 동일)
108
+ const bannerJs =
109
+ "import { createRequire } from 'module'; const require = createRequire(import.meta.url);";
110
+
111
+ await esbuild.build({
112
+ stdin: {
113
+ contents: [
114
+ 'import bootstrap from "./src/main.server";',
115
+ 'import { renderApplication } from "@angular/platform-server";',
116
+ "export function render(url: string, document: string): Promise<string> {",
117
+ " return renderApplication(bootstrap, { document, url });",
118
+ "}",
119
+ ].join("\n"),
120
+ resolveDir: options.pkgDir,
121
+ sourcefile: "sd-ssg-entry.ts",
122
+ loader: "ts",
123
+ },
124
+ target: "node20",
125
+ bundle: true,
126
+ splitting: false,
127
+ format: "esm",
128
+ platform: "node",
129
+ outdir,
130
+ // stdin 진입점의 출력 이름은 "stdin"으로 고정되므로 entryNames로 결정론적 지정
131
+ entryNames: "sd-ssg-entry",
132
+ outExtension: { ".js": ".mjs" },
133
+ write: true,
134
+ sourcemap: false,
135
+ logLevel: "silent",
136
+ tsconfig: options.tsconfig ?? path.join(options.pkgDir, "tsconfig.json"),
137
+ define,
138
+ banner: { js: bannerJs },
139
+ plugins: [
140
+ angularPlugin,
141
+ scssPlugin,
142
+ ...(loadedPostcssPlugins != null
143
+ ? [createPostcssPlugin({ plugins: loadedPostcssPlugins })]
144
+ : []),
145
+ ],
146
+ });
147
+
148
+ return { bundlePath };
149
+ }
@@ -240,6 +240,13 @@ export interface SdClientPackageConfig {
240
240
  browserSupport?: SdBrowserSupportConfig;
241
241
  /** PWA 설정. false이면 비활성화. 미지정 시 기본값으로 활성화 */
242
242
  pwa?: false | SdPwaConfig;
243
+ /**
244
+ * SSG(빌드 타임 프리렌더) 라우트 목록 (예: ["/", "/about"])
245
+ * - 지정 시 프로덕션 빌드에서 src/main.server.ts 진입점으로 라우트별 HTML을 생성
246
+ * - SPA 셸은 index.csr.html로 별도 출력 (비프리렌더 라우트 딥링크 폴백용)
247
+ * - dev/watch 모드에는 적용되지 않음 (기존 SPA dev 서버 그대로)
248
+ */
249
+ prerender?: string[];
243
250
  }
244
251
 
245
252
  /**
@@ -0,0 +1,65 @@
1
+ import fs from "node:fs";
2
+ import path from "path";
3
+ import { pathToFileURL } from "node:url";
4
+ import { createLogger } from "@simplysm/core-common";
5
+
6
+ const logger = createLogger("sd:cli:ssg:prerender");
7
+
8
+ export interface PrerenderOptions {
9
+ /** buildSsrBundle로 생성된 server 번들 경로 */
10
+ bundlePath: string;
11
+ /** 프리렌더할 라우트 경로 목록 (예: ["/", "/about"]) */
12
+ routes: string[];
13
+ /** 렌더 기준 문서 (SPA 셸 index.html 내용) */
14
+ documentHtml: string;
15
+ /** base 경로 (예: "/my-client/") — 렌더 URL 구성에 사용 */
16
+ basePath: string;
17
+ /** HTML 출력 디렉토리 (dist/) */
18
+ outdir: string;
19
+ }
20
+
21
+ interface SsrBundleModule {
22
+ render(url: string, document: string): Promise<string>;
23
+ }
24
+
25
+ /**
26
+ * server 번들로 라우트별 HTML을 생성해 outdir에 기록한다.
27
+ *
28
+ * 라우트 1건이라도 실패하면 throw (빌드 전체 실패 — 부분 산출 금지).
29
+ */
30
+ export async function prerenderRoutes(options: PrerenderOptions): Promise<void> {
31
+ const bundleModule = (await import(
32
+ pathToFileURL(options.bundlePath).href
33
+ )) as SsrBundleModule;
34
+
35
+ // 1. 전체 라우트 렌더 (전부 성공해야 기록 단계로 진행)
36
+ const rendered: { route: string; html: string }[] = [];
37
+ for (const route of options.routes) {
38
+ const normalizedRoute = normalizeRoute(route);
39
+ const url = path.posix.join(options.basePath, normalizedRoute);
40
+ logger.debug(`프리렌더: ${url}`);
41
+ try {
42
+ const html = await bundleModule.render(url, options.documentHtml);
43
+ rendered.push({ route: normalizedRoute, html });
44
+ } catch (err) {
45
+ throw new Error(`프리렌더 실패 (라우트: ${route}): ${err instanceof Error ? err.message : String(err)}`, {
46
+ cause: err,
47
+ });
48
+ }
49
+ }
50
+
51
+ // 2. 라우트별 <경로>/index.html 기록 ("/"는 index.html)
52
+ for (const { route, html } of rendered) {
53
+ const htmlPath = path.join(options.outdir, route, "index.html");
54
+ fs.mkdirSync(path.dirname(htmlPath), { recursive: true });
55
+ fs.writeFileSync(htmlPath, html);
56
+ }
57
+ }
58
+
59
+ /** 라우트 경로 정규화: 선행 "/" 제거 ("/" → "") */
60
+ function normalizeRoute(route: string): string {
61
+ if (!route.startsWith("/")) {
62
+ throw new Error(`프리렌더 라우트는 "/"로 시작해야 합니다: "${route}"`);
63
+ }
64
+ return route.replace(/^\/+/, "").replace(/\/+$/, "");
65
+ }
@@ -14,6 +14,8 @@ import { createDevHttpServer, type DevHttpServer } from "../dev-server/dev-http-
14
14
  import { createHmrService, type HmrService } from "../dev-server/hmr-service";
15
15
  import { createHmrPostTransform } from "../dev-server/hmr-client-script";
16
16
  import { copyPublicFiles, watchPublicFiles } from "../utils/copy-public";
17
+ import { buildSsrBundle } from "../esbuild/esbuild-ssr-config";
18
+ import { prerenderRoutes } from "../ssg/prerender";
17
19
  import type { SdBrowserSupportConfig, SdPwaConfig } from "../sd-config.types";
18
20
  import type esbuild from "esbuild";
19
21
  import type { PartialMessage } from "esbuild";
@@ -40,6 +42,8 @@ export interface ClientBuildInfo {
40
42
  base?: string;
41
43
  /** 브라우저 지원 설정 (메인 프로세스에서 전달, Worker 내 sd.config.ts 재로드 방지) */
42
44
  browserSupport?: SdBrowserSupportConfig;
45
+ /** SSG(빌드 타임 프리렌더) 라우트 목록. 지정 시 프로덕션 빌드에서만 적용 */
46
+ prerender?: string[];
43
47
  }
44
48
 
45
49
  /** Client 빌드 결과 */
@@ -150,6 +154,28 @@ async function build(info: ClientBuildInfo): Promise<ClientBuildResult> {
150
154
 
151
155
  fs.writeFileSync(path.join(outdir, "index.html"), indexResult.content);
152
156
 
157
+ // 5.5. SSG 프리렌더 (opt-in — prerender 설정이 있을 때만)
158
+ if (info.prerender != null && info.prerender.length > 0 && indexResult.errors.length === 0) {
159
+ // SPA 셸 별도 보존 (비프리렌더 라우트 딥링크 폴백용 — 서버 정적 핸들러가 사용)
160
+ fs.writeFileSync(path.join(outdir, "index.csr.html"), indexResult.content);
161
+
162
+ const { bundlePath } = await buildSsrBundle({
163
+ pkgDir: info.pkgDir,
164
+ cwd: info.cwd,
165
+ env: info.env,
166
+ postcssPlugins: info.browserSupport?.postCss?.plugins,
167
+ });
168
+
169
+ // 라우트별 HTML 생성 ("/"는 index.html을 프리렌더 결과로 대체)
170
+ await prerenderRoutes({
171
+ bundlePath,
172
+ routes: info.prerender,
173
+ documentHtml: indexResult.content,
174
+ basePath,
175
+ outdir,
176
+ });
177
+ }
178
+
153
179
  // 6. PWA 적용
154
180
  await applyPwa({
155
181
  pkgDir: info.pkgDir,
@@ -14,8 +14,7 @@ vi.spyOn(Worker, "create").mockReturnValue(mockWorker as any);
14
14
  import { TscEngine } from "../../src/engines/TscEngine";
15
15
  import { BaseEngine } from "../../src/engines/BaseEngine";
16
16
 
17
- import type { BuildPackageInfo, BuildOutput } from "../../src/engines/types";
18
- import type { BuildResult } from "../../src/runtime/ResultCollector";
17
+ import type { BuildPackageInfo } from "../../src/engines/types";
19
18
 
20
19
  // --- Helpers ---
21
20
 
@@ -373,18 +372,6 @@ describe("BaseEngine", () => {
373
372
  });
374
373
 
375
374
  describe("lint 통합", () => {
376
- describe("BuildOutput.lint flag controls lint execution", () => {
377
- it("BuildOutput이 lint 불리언 플래그를 수용", () => {
378
- const output: BuildOutput = { js: true, dts: true, lint: true };
379
- expect(output.lint).toBe(true);
380
- });
381
-
382
- it("BuildOutput.lint는 미설정 시 undefined가 기본값", () => {
383
- const output: BuildOutput = { js: true, dts: true };
384
- expect(output.lint).toBeUndefined();
385
- });
386
- });
387
-
388
375
  describe("EngineResult includes lint field", () => {
389
376
  it("run() returns EngineResult with lint field when worker provides it", async () => {
390
377
  mockWorker.build.mockResolvedValue({
@@ -496,17 +483,5 @@ describe("BaseEngine", () => {
496
483
  await engine.stop();
497
484
  });
498
485
  });
499
-
500
- describe("ResultCollector supports lint type", () => {
501
- it("BuildResult 타입에 lint 포함", () => {
502
- const lintResult: BuildResult = {
503
- name: "test-pkg",
504
- target: "node",
505
- type: "lint",
506
- status: "success",
507
- };
508
- expect(lintResult.type).toBe("lint");
509
- });
510
- });
511
486
  });
512
487
  });
@@ -1,68 +1,82 @@
1
1
  // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2
2
 
3
3
  exports[`client/src/main.ts.hbs > 라우팅 N (mobile) 1`] = `
4
- "import consola from "consola";
5
- import { enableProdMode, inject, provideAppInitializer } from "@angular/core";
4
+ "import { enableProdMode, inject, provideAppInitializer } from "@angular/core";
6
5
  import { bootstrapApplication } from "@angular/platform-browser";
7
6
  import { provideHttpClient, withFetch } from "@angular/common/http";
8
- import { provideSdAngular } from "@simplysm/angular";
9
- import { AppServiceProvider } from "@demo/client-common";
7
+ import {
8
+ provideSdAngular,
9
+ } from "@simplysm/angular";
10
+ import { createLogger } from "@simplysm/core-common";
10
11
  import { AppRoot } from "./app.root";
11
12
  import "./styles.scss";
13
+ import {
14
+ AppServiceProvider,
15
+ } from "@demo/client-common";
16
+
17
+ const CLIENT_NAME = "client-pda";
18
+
19
+ const logger = createLogger(CLIENT_NAME);
12
20
 
13
21
  if (typeof ngDevMode !== "undefined" && !ngDevMode) {
14
22
  enableProdMode();
15
23
  } else {
16
- consola.log("dev mode");
24
+ logger.info("dev mode");
17
25
  }
18
26
 
19
27
  bootstrapApplication(AppRoot, {
20
28
  providers: [
21
29
  provideHttpClient(withFetch()),
22
- provideSdAngular({ clientName: "client-pda" }),
30
+ provideSdAngular({ clientName: CLIENT_NAME }),
23
31
 
24
- //-- app-service 연결
25
32
  provideAppInitializer(async () => {
26
33
  await inject(AppServiceProvider).connectAsync();
27
34
  }),
28
35
  ],
29
36
  }).catch((err: unknown) => {
30
- consola.error(err);
37
+ logger.error("부트스트랩 실패", err);
31
38
  });
32
39
  "
33
40
  `;
34
41
 
35
42
  exports[`client/src/main.ts.hbs > 라우팅 Y (web) 1`] = `
36
- "import consola from "consola";
37
- import { enableProdMode, inject, provideAppInitializer } from "@angular/core";
43
+ "import { enableProdMode, inject, provideAppInitializer } from "@angular/core";
38
44
  import { bootstrapApplication } from "@angular/platform-browser";
39
45
  import { provideHttpClient, withFetch } from "@angular/common/http";
40
46
  import { provideRouter, withHashLocation } from "@angular/router";
41
- import { provideSdAngular } from "@simplysm/angular";
42
- import { AppServiceProvider } from "@demo/client-common";
47
+ import {
48
+ provideSdAngular,
49
+ } from "@simplysm/angular";
50
+ import { createLogger } from "@simplysm/core-common";
43
51
  import { AppRoot } from "./app.root";
44
52
  import { routes } from "./routes";
45
53
  import "./styles.scss";
54
+ import {
55
+ AppServiceProvider,
56
+ } from "@demo/client-common";
57
+
58
+ const CLIENT_NAME = "client-admin";
59
+
60
+ const logger = createLogger(CLIENT_NAME);
46
61
 
47
62
  if (typeof ngDevMode !== "undefined" && !ngDevMode) {
48
63
  enableProdMode();
49
64
  } else {
50
- consola.log("dev mode");
65
+ logger.info("dev mode");
51
66
  }
52
67
 
53
68
  bootstrapApplication(AppRoot, {
54
69
  providers: [
55
70
  provideHttpClient(withFetch()),
56
71
  provideRouter(routes, withHashLocation()),
57
- provideSdAngular({ clientName: "client-admin" }),
72
+ provideSdAngular({ clientName: CLIENT_NAME }),
58
73
 
59
- //-- app-service 연결
60
74
  provideAppInitializer(async () => {
61
75
  await inject(AppServiceProvider).connectAsync();
62
76
  }),
63
77
  ],
64
78
  }).catch((err: unknown) => {
65
- consola.error(err);
79
+ logger.error("부트스트랩 실패", err);
66
80
  });
67
81
  "
68
82
  `;
@@ -177,7 +191,7 @@ exports[`server/src/main.ts.hbs > DB=N — OrmService 없음 1`] = `
177
191
  import { env, num, parseBoolEnv } from "@simplysm/core-common";
178
192
  import { setupConsola } from "@simplysm/core-node";
179
193
  import { createServiceServer, getConfig } from "@simplysm/service-server";
180
- import {EventEmitter} from "node:events";
194
+ import { EventEmitter } from "node:events";
181
195
 
182
196
  Error.stackTraceLimit = Infinity;
183
197
  EventEmitter.defaultMaxListeners = 0;
@@ -194,7 +208,8 @@ if (authConfig?.jwtSecret == null) {
194
208
 
195
209
  export const server = createServiceServer({
196
210
  rootPath: import.meta.dirname,
197
- services: [],
211
+ services: [
212
+ ],
198
213
  port: num.parseInt(env("SERVER_PORT"))!,
199
214
  auth: { jwtSecret: authConfig.jwtSecret },
200
215
  });
@@ -210,7 +225,7 @@ exports[`server/src/main.ts.hbs > DB=Y — OrmService 포함 1`] = `
210
225
  import { env, num, parseBoolEnv } from "@simplysm/core-common";
211
226
  import { setupConsola } from "@simplysm/core-node";
212
227
  import { createServiceServer, getConfig, OrmService } from "@simplysm/service-server";
213
- import {EventEmitter} from "node:events";
228
+ import { EventEmitter } from "node:events";
214
229
  import { DevService } from "./services/dev.service";
215
230
 
216
231
  Error.stackTraceLimit = Infinity;
@@ -228,7 +243,10 @@ if (authConfig?.jwtSecret == null) {
228
243
 
229
244
  export const server = createServiceServer({
230
245
  rootPath: import.meta.dirname,
231
- services: [OrmService, ...(parseBoolEnv(env("DEV")) ? [DevService] : [])],
246
+ services: [
247
+ OrmService,
248
+ ...(parseBoolEnv(env("DEV")) ? [DevService] : []),
249
+ ],
232
250
  port: num.parseInt(env("SERVER_PORT"))!,
233
251
  auth: { jwtSecret: authConfig.jwtSecret },
234
252
  });