mega-framework 0.1.6 → 0.1.8

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 (248) hide show
  1. package/README.md +9 -0
  2. package/bin/mega-ws-hub.js +2 -2
  3. package/package.json +33 -9
  4. package/sample/crud/.env +10 -1
  5. package/sample/crud/.env.example +10 -1
  6. package/sample/crud/.mega/journal/history/20260612092543-create-users.json +261 -0
  7. package/sample/crud/.mega/journal/snapshot.json +261 -0
  8. package/sample/crud/apps/main/controllers/auth-controller.js +22 -14
  9. package/sample/crud/apps/main/controllers/web-controller.js +7 -5
  10. package/sample/crud/apps/main/locales/server/en.json +12 -1
  11. package/sample/crud/apps/main/locales/server/ko.json +12 -1
  12. package/sample/crud/apps/main/migrations/20260606000001-create-users.js +91 -13
  13. package/sample/crud/apps/main/migrations/20260606000002-create-boards.js +165 -0
  14. package/sample/crud/apps/main/migrations/20260606000003-create-logs.js +107 -0
  15. package/sample/crud/apps/main/models/log-partition-model.js +105 -0
  16. package/sample/crud/apps/main/models/note-model.js +79 -0
  17. package/sample/crud/apps/main/models/user-level-model.js +24 -0
  18. package/sample/crud/apps/main/models/user-model.js +146 -0
  19. package/sample/crud/apps/main/models/user-type-model.js +21 -0
  20. package/sample/crud/apps/main/models/wallet-model.js +24 -0
  21. package/sample/crud/apps/main/routes/users.js +55 -10
  22. package/sample/crud/apps/main/schedules/log-partition-schedule.js +33 -0
  23. package/sample/crud/apps/main/services/auth-service.js +39 -24
  24. package/sample/crud/apps/main/services/log-partition-service.js +101 -0
  25. package/sample/crud/apps/main/services/note-service.js +6 -6
  26. package/sample/crud/apps/main/services/redis-demo-service.js +3 -3
  27. package/sample/crud/apps/main/services/user-service.js +62 -21
  28. package/sample/crud/apps/main/views/auth/login.ejs +6 -6
  29. package/sample/crud/apps/main/views/auth/register.ejs +46 -5
  30. package/sample/crud/apps/main/views/users/edit.ejs +42 -5
  31. package/sample/crud/apps/main/views/users/list.ejs +6 -2
  32. package/sample/crud/apps/main/views/users/new.ejs +56 -4
  33. package/sample/crud/docs/log_partition_design.mm.md +23 -0
  34. package/sample/crud/mega.config.js +10 -2
  35. package/sample/crud/package.json +3 -3
  36. package/sample/crud/scripts/start-ws-hub.sh +20 -6
  37. package/sample/simple/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -0
  38. package/sample/simple/package.json +2 -2
  39. package/src/adapters/adapter-manager.js +2 -1
  40. package/src/adapters/adapter-options.js +44 -3
  41. package/src/adapters/file-adapter.js +9 -5
  42. package/src/adapters/file-session-adapter.js +4 -3
  43. package/src/adapters/maria-adapter.js +33 -7
  44. package/src/adapters/mega-cache-adapter.js +83 -6
  45. package/src/adapters/mega-db-adapter.js +10 -1
  46. package/src/adapters/mongo-adapter.js +40 -8
  47. package/src/adapters/postgres-adapter.js +33 -6
  48. package/src/adapters/redis-adapter.js +7 -3
  49. package/src/adapters/sqlite-adapter.js +26 -3
  50. package/src/cli/commands/console-cmd.js +3 -1
  51. package/src/cli/commands/new.js +13 -3
  52. package/src/cli/commands/scaffold.js +173 -33
  53. package/src/cli/generators/index.js +140 -3
  54. package/src/cli/index.js +437 -155
  55. package/src/cli/watch.js +188 -0
  56. package/src/core/ajv-mapper.js +30 -3
  57. package/src/core/boot.js +464 -245
  58. package/src/core/cluster-metrics.js +13 -4
  59. package/src/core/ctx-builder.js +65 -3
  60. package/src/core/envelope.js +119 -12
  61. package/src/core/hub-link.js +89 -18
  62. package/src/core/i18n.js +11 -1
  63. package/src/core/index.js +7 -3
  64. package/src/core/mega-app.js +253 -505
  65. package/src/core/mega-cluster.js +4 -1
  66. package/src/core/mega-server.js +40 -9
  67. package/src/core/migration/dialect-registry.js +107 -0
  68. package/src/core/migration/dialects/README.md +62 -0
  69. package/src/core/migration/dialects/maria.js +496 -0
  70. package/src/core/migration/dialects/mongo.js +824 -0
  71. package/src/core/migration/dialects/postgres.js +563 -0
  72. package/src/core/migration/dialects/sqlite.js +476 -0
  73. package/src/core/migration/differ.js +456 -0
  74. package/src/core/migration/generate.js +508 -0
  75. package/src/core/migration/journal.js +167 -0
  76. package/src/core/migration/model-scan.js +84 -0
  77. package/src/core/migration/mongo-migration-db.js +97 -0
  78. package/src/core/migration/schema-builder.js +400 -0
  79. package/src/core/migration/schema-validator.js +315 -0
  80. package/src/core/migration-lock.js +205 -0
  81. package/src/core/migration-runner.js +166 -38
  82. package/src/core/multipart.js +28 -5
  83. package/src/core/pipeline.js +131 -0
  84. package/src/core/router.js +70 -65
  85. package/src/core/scope-registry.js +1 -0
  86. package/src/core/security.js +70 -12
  87. package/src/core/session-store.js +14 -1
  88. package/src/core/workers-manager.js +12 -1
  89. package/src/core/ws-cluster.js +10 -3
  90. package/src/core/ws-message.js +48 -4
  91. package/src/core/ws-presence.js +636 -0
  92. package/src/core/ws-roster.js +50 -8
  93. package/src/core/ws-upgrade.js +223 -12
  94. package/src/index.js +1 -1
  95. package/src/lib/hub-protocol.js +29 -0
  96. package/src/lib/mega-circuit-breaker.js +5 -3
  97. package/src/lib/mega-health.js +35 -4
  98. package/src/lib/mega-job-queue.js +151 -34
  99. package/src/lib/mega-job.js +37 -1
  100. package/src/lib/mega-metrics.js +31 -13
  101. package/src/lib/mega-plugin.js +34 -3
  102. package/src/lib/mega-schedule.js +40 -22
  103. package/src/lib/mega-shutdown.js +114 -39
  104. package/src/lib/mega-tracing.js +66 -19
  105. package/src/lib/mega-worker.js +33 -6
  106. package/src/lib/otel-resource.js +36 -0
  107. package/src/{cli → lib}/ws-hub.js +139 -15
  108. package/src/models/crud-sql-builder.js +133 -0
  109. package/src/models/mega-model.js +82 -2
  110. package/src/models/model-crud.js +483 -0
  111. package/src/models/mongo-crud.js +285 -0
  112. package/templates/adr/code.tpl +23 -0
  113. package/templates/model/code-mongo.tpl +35 -0
  114. package/templates/model/code.tpl +15 -1
  115. package/templates/model/test-mongo.tpl +38 -0
  116. package/templates/model/test.tpl +4 -0
  117. package/types/adapters/adapter-manager.d.ts +95 -0
  118. package/types/adapters/adapter-options.d.ts +93 -0
  119. package/types/adapters/file-adapter.d.ts +105 -0
  120. package/types/adapters/file-session-adapter.d.ts +103 -0
  121. package/types/adapters/index.d.ts +20 -0
  122. package/types/adapters/maria-adapter.d.ts +117 -0
  123. package/types/adapters/mega-adapter.d.ts +215 -0
  124. package/types/adapters/mega-bus-adapter.d.ts +45 -0
  125. package/types/adapters/mega-cache-adapter.d.ts +73 -0
  126. package/types/adapters/mega-db-adapter.d.ts +50 -0
  127. package/types/adapters/mega-lock-adapter.d.ts +62 -0
  128. package/types/adapters/mega-log-sink-adapter.d.ts +15 -0
  129. package/types/adapters/mega-session-adapter.d.ts +32 -0
  130. package/types/adapters/mongo-adapter.d.ts +150 -0
  131. package/types/adapters/nats-adapter.d.ts +108 -0
  132. package/types/adapters/postgres-adapter.d.ts +141 -0
  133. package/types/adapters/redis-adapter.d.ts +78 -0
  134. package/types/adapters/redis-session-adapter.d.ts +82 -0
  135. package/types/adapters/redlock-adapter.d.ts +149 -0
  136. package/types/adapters/registry.d.ts +46 -0
  137. package/types/adapters/sqlite-adapter.d.ts +112 -0
  138. package/types/auth/index.d.ts +24 -0
  139. package/types/cli/commands/console-cmd.d.ts +37 -0
  140. package/types/cli/commands/new.d.ts +16 -0
  141. package/types/cli/commands/routes.d.ts +36 -0
  142. package/types/cli/commands/scaffold.d.ts +78 -0
  143. package/types/cli/commands/test-cmd.d.ts +14 -0
  144. package/types/cli/generators/index.d.ts +122 -0
  145. package/types/cli/index.d.ts +234 -0
  146. package/types/cli/template-engine.d.ts +40 -0
  147. package/types/cli/watch.d.ts +59 -0
  148. package/types/core/ajv-mapper.d.ts +27 -0
  149. package/types/core/boot.d.ts +233 -0
  150. package/types/core/cluster-metrics.d.ts +52 -0
  151. package/types/core/config-loader.d.ts +13 -0
  152. package/types/core/config-validator.d.ts +30 -0
  153. package/types/core/ctx-builder.d.ts +103 -0
  154. package/types/core/envelope.d.ts +79 -0
  155. package/types/core/error-mapper.d.ts +17 -0
  156. package/types/core/formbody.d.ts +41 -0
  157. package/types/core/hub-link.d.ts +266 -0
  158. package/types/core/i18n.d.ts +178 -0
  159. package/types/core/index.d.ts +28 -0
  160. package/types/core/mega-app.d.ts +529 -0
  161. package/types/core/mega-cluster.d.ts +104 -0
  162. package/types/core/mega-server.d.ts +91 -0
  163. package/types/core/mega-service.d.ts +31 -0
  164. package/types/core/migration/dialect-registry.d.ts +22 -0
  165. package/types/core/migration/dialects/maria.d.ts +99 -0
  166. package/types/core/migration/dialects/mongo.d.ts +89 -0
  167. package/types/core/migration/dialects/postgres.d.ts +117 -0
  168. package/types/core/migration/dialects/sqlite.d.ts +111 -0
  169. package/types/core/migration/differ.d.ts +47 -0
  170. package/types/core/migration/generate.d.ts +56 -0
  171. package/types/core/migration/journal.d.ts +52 -0
  172. package/types/core/migration/model-scan.d.ts +19 -0
  173. package/types/core/migration/mongo-migration-db.d.ts +7 -0
  174. package/types/core/migration/schema-builder.d.ts +197 -0
  175. package/types/core/migration/schema-validator.d.ts +20 -0
  176. package/types/core/migration-lock.d.ts +33 -0
  177. package/types/core/migration-runner.d.ts +101 -0
  178. package/types/core/multipart.d.ts +86 -0
  179. package/types/core/openapi.d.ts +62 -0
  180. package/types/core/pipeline.d.ts +93 -0
  181. package/types/core/router.d.ts +159 -0
  182. package/types/core/routes-loader.d.ts +21 -0
  183. package/types/core/scope-registry.d.ts +14 -0
  184. package/types/core/security.d.ts +77 -0
  185. package/types/core/services-loader.d.ts +27 -0
  186. package/types/core/session-cleanup-schedule.d.ts +19 -0
  187. package/types/core/session-store.d.ts +25 -0
  188. package/types/core/session.d.ts +77 -0
  189. package/types/core/static-assets.d.ts +73 -0
  190. package/types/core/template.d.ts +106 -0
  191. package/types/core/workers-manager.d.ts +79 -0
  192. package/types/core/ws-cluster.d.ts +208 -0
  193. package/types/core/ws-compression.d.ts +112 -0
  194. package/types/core/ws-controller.d.ts +65 -0
  195. package/types/core/ws-message.d.ts +106 -0
  196. package/types/core/ws-presence.d.ts +273 -0
  197. package/types/core/ws-roster.d.ts +108 -0
  198. package/types/core/ws-upgrade.d.ts +260 -0
  199. package/types/errors/config-error.d.ts +10 -0
  200. package/types/errors/http-errors.d.ts +120 -0
  201. package/types/errors/index.d.ts +3 -0
  202. package/types/errors/mega-error.d.ts +32 -0
  203. package/types/index.d.ts +39 -0
  204. package/types/lib/asp/config.d.ts +49 -0
  205. package/types/lib/asp/crypto.d.ts +43 -0
  206. package/types/lib/asp/errors.d.ts +30 -0
  207. package/types/lib/asp/nonce-cache.d.ts +52 -0
  208. package/types/lib/asp/plugin.d.ts +30 -0
  209. package/types/lib/asp/ws-terminator.d.ts +45 -0
  210. package/types/lib/env-mapper.d.ts +14 -0
  211. package/types/lib/hub-protocol.d.ts +106 -0
  212. package/types/lib/index.d.ts +22 -0
  213. package/types/lib/logger/telegram-core.d.ts +104 -0
  214. package/types/lib/logger/telegram-transport.d.ts +45 -0
  215. package/types/lib/mega-brute-force.d.ts +66 -0
  216. package/types/lib/mega-circuit-breaker.d.ts +243 -0
  217. package/types/lib/mega-cron.d.ts +66 -0
  218. package/types/lib/mega-hash.d.ts +32 -0
  219. package/types/lib/mega-health.d.ts +48 -0
  220. package/types/lib/mega-job-queue.d.ts +188 -0
  221. package/types/lib/mega-job-worker.d.ts +130 -0
  222. package/types/lib/mega-job.d.ts +145 -0
  223. package/types/lib/mega-logger.d.ts +45 -0
  224. package/types/lib/mega-metrics.d.ts +285 -0
  225. package/types/lib/mega-plugin.d.ts +245 -0
  226. package/types/lib/mega-retry.d.ts +85 -0
  227. package/types/lib/mega-schedule.d.ts +260 -0
  228. package/types/lib/mega-shutdown.d.ts +135 -0
  229. package/types/lib/mega-tracing.d.ts +224 -0
  230. package/types/lib/mega-worker.d.ts +129 -0
  231. package/types/lib/otel-resource.d.ts +16 -0
  232. package/types/lib/worker-runner/process-entry.d.ts +1 -0
  233. package/types/lib/worker-runner/task-dispatch.d.ts +28 -0
  234. package/types/lib/worker-runner/thread-entry.d.ts +1 -0
  235. package/types/lib/ws-hub.d.ts +259 -0
  236. package/types/models/crud-sql-builder.d.ts +48 -0
  237. package/types/models/index.d.ts +1 -0
  238. package/types/models/mega-model.d.ts +138 -0
  239. package/types/models/model-crud.d.ts +82 -0
  240. package/types/models/mongo-crud.d.ts +59 -0
  241. package/types/test/index.d.ts +84 -0
  242. package/.env +0 -127
  243. package/sample/crud/apps/main/migrations/20260606000002-add-auth-to-users.js +0 -30
  244. package/sample/crud/apps/main/models/note.js +0 -71
  245. package/sample/crud/apps/main/models/user.js +0 -86
  246. package/sample/crud/package-lock.json +0 -5665
  247. package/sample/crud/yarn.lock +0 -2142
  248. package/sample/simple/package-lock.json +0 -1851
@@ -0,0 +1,122 @@
1
+ /**
2
+ * @typedef {object} Artifact
3
+ * @property {string} outAbs - 쓸 파일 절대경로.
4
+ * @property {string} content - 렌더된 내용.
5
+ * @property {'code'|'test'|'task'|'route'} role
6
+ */
7
+ /**
8
+ * kind 별로 생성할 artifact 목록을 계획한다(아직 디스크에 쓰지 않음).
9
+ * @param {string} kind
10
+ * @param {string} rawName
11
+ * @param {Record<string, any>} opts - { app, version, kind(adapter), lng, ns }
12
+ * @param {string} projectRoot
13
+ * @returns {Artifact[]}
14
+ */
15
+ export function planArtifacts(kind: string, rawName: string, opts: Record<string, any>, projectRoot: string): Artifact[];
16
+ /**
17
+ * 다음 ADR 번호를 해석한다 — `docs/adr/NNNN-*.md` 파일명 + 레거시 `docs/09` 헤딩(`### ADR-N:`) +
18
+ * 호출측이 모은 추가 번호(예: `git ls-tree origin/main` 의 원격 파일 — 병렬 task 충돌 회피)의
19
+ * 최댓값 + 1. 아무 ADR 도 없으면 1.
20
+ *
21
+ * @param {string} projectRoot
22
+ * @param {number[]} [extraNumbers] - 로컬 밖에서 관측한 번호(원격 스캔 등).
23
+ * @returns {number}
24
+ */
25
+ export function nextAdrNumber(projectRoot: string, extraNumbers?: number[]): number;
26
+ /**
27
+ * 계획된 artifact 를 디스크에 쓴다. 이미 있으면 건너뛴다(force 면 덮어씀).
28
+ * @param {Artifact[]} artifacts
29
+ * @param {{ force?: boolean }} [opts]
30
+ * @returns {{ written: string[], skipped: string[] }}
31
+ */
32
+ export function writeArtifacts(artifacts: Artifact[], { force }?: {
33
+ force?: boolean;
34
+ }): {
35
+ written: string[];
36
+ skipped: string[];
37
+ };
38
+ /**
39
+ * 플러그인 scaffold manifest(`mega.scaffold.register(name, { dir, files, description? })`,
40
+ * 03-api-spec §11 / ADR-199)를 artifact 목록으로 계획한다 — 빌트인 13종과 같은 plan→write 2단 분리.
41
+ * 토큰 계약은 {@link SCAFFOLD_TOKENS} 가 정본이며 미정의 토큰은 renderTemplate 가 throw(P4).
42
+ * `files[].path` 에도 토큰을 쓸 수 있다(예 `services/{{name}}-service.js`).
43
+ *
44
+ * @param {{ dir: string, files: Array<{ path: string, template: string }> }} def - 플러그인 등록 정의.
45
+ * @param {string} rawName - `mega g <kind> <name>` 의 name.
46
+ * @param {Record<string, any>} opts - { app }.
47
+ * @param {string} projectRoot - 출력 기준 루트. `def.dir` 는 이 루트 상대.
48
+ * @returns {Artifact[]}
49
+ * @throws {Error} def 파일 항목이 `{ path, template }` 문자열 쌍이 아니거나, 출력 경로가 projectRoot 를
50
+ * 벗어나면(경로 탐색 차단 — template.js resolveViewPath 정합) fail-fast.
51
+ */
52
+ export function planScaffoldDef(def: {
53
+ dir: string;
54
+ files: Array<{
55
+ path: string;
56
+ template: string;
57
+ }>;
58
+ }, rawName: string, opts: Record<string, any>, projectRoot: string): Artifact[];
59
+ /**
60
+ * 플러그인 등록 scaffold generator 실행 — `mega g <plugin-generator> <name>` 의 본체. 빌트인 `generate`
61
+ * 와 같은 계획 → 쓰기 → 결과 계약(존재 파일 skip, `--force` 덮어쓰기).
62
+ * @param {string} kindName - 플러그인이 등록한 generator 이름(결과 보고용).
63
+ * @param {{ dir: string, files: Array<{ path: string, template: string }> }} def
64
+ * @param {string} rawName
65
+ * @param {object} [opts] - { app, force }
66
+ * @param {string} [projectRoot]
67
+ * @returns {{ kind: string, name: string, written: string[], skipped: string[] }}
68
+ */
69
+ export function generateFromScaffoldDef(kindName: string, def: {
70
+ dir: string;
71
+ files: Array<{
72
+ path: string;
73
+ template: string;
74
+ }>;
75
+ }, rawName: string, opts?: object, projectRoot?: string): {
76
+ kind: string;
77
+ name: string;
78
+ written: string[];
79
+ skipped: string[];
80
+ };
81
+ /**
82
+ * `mega g <kind> <name>` 실행 — 계획 → 쓰기 → 결과 반환.
83
+ * @param {string} kind
84
+ * @param {string} rawName
85
+ * @param {object} [opts] - { app, version, kind(adapter), lng, force }
86
+ * @param {string} [projectRoot]
87
+ * @returns {{ kind: string, name: string, written: string[], skipped: string[] }}
88
+ */
89
+ export function generate(kind: string, rawName: string, opts?: object, projectRoot?: string): {
90
+ kind: string;
91
+ name: string;
92
+ written: string[];
93
+ skipped: string[];
94
+ };
95
+ /** 지원 generator 종류(roadmap §337 — 13종). */
96
+ export const GENERATOR_KINDS: readonly ["app", "controller", "channel", "service", "model", "middleware", "route", "schedule", "job", "worker", "locale", "adapter", "migration", "adr"];
97
+ /**
98
+ * 플러그인 scaffold manifest 의 토큰 계약(ADR-199) — `files[].path`/`files[].template` 의 `{{token}}`
99
+ * 에 쓸 수 있는 이름과 의미. 빌트인 generator 의 base 토큰과 동일 집합이라 템플릿 작성 관례가 하나다.
100
+ * 미정의 토큰은 renderTemplate 가 throw 한다(P4 — silent 치환 누락 방지).
101
+ * @type {Readonly<Record<string, string>>}
102
+ */
103
+ export const SCAFFOLD_TOKENS: Readonly<Record<string, string>>;
104
+ export type Artifact = {
105
+ /**
106
+ * - 쓸 파일 절대경로.
107
+ */
108
+ outAbs: string;
109
+ /**
110
+ * - 렌더된 내용.
111
+ */
112
+ content: string;
113
+ role: "code" | "test" | "task" | "route";
114
+ };
115
+ export type Variants = {
116
+ kebab: string;
117
+ pascal: string;
118
+ camel: string;
119
+ snake: string;
120
+ words: string[];
121
+ };
122
+ export type BaseVars = Record<string, string>;
@@ -0,0 +1,234 @@
1
+ /**
2
+ * 프로젝트 루트의 `.env` 를 `process.env` 로 로드한다(파일이 있을 때만). Node 내장
3
+ * `process.loadEnvFile`(20.6+) 사용 — 신규 dep 0. **이미 설정된 실제 환경변수는 덮어쓰지 않는다**
4
+ * (`--env-file` 과 동일 우선순위 — 실 env 우선). config(`mega.config.js`)들이 `process.env.X` 를
5
+ * 참조하고 비밀은 `.env` 에만 두는 컨벤션(CLAUDE.md)을 CLI 가 보장한다(ADR-152). config 로드보다 먼저
6
+ * 호출해야 `process.env` 참조가 채워진다.
7
+ *
8
+ * @param {string} projectRoot - `.env` 를 찾을 프로젝트 루트(`--root` 또는 cwd).
9
+ * @param {{ debug?: Function }} [logger]
10
+ * @returns {boolean} 로드했으면 true, `.env` 부재면 false.
11
+ * @throws {Error} `.env` 가 존재하나 파싱 실패 시(fail-fast — silent 무시 X).
12
+ */
13
+ export function loadProjectEnv(projectRoot: string, logger?: {
14
+ debug?: Function;
15
+ }): boolean;
16
+ /**
17
+ * 인자 토큰을 `{ _: positionals[], flags: {} }` 로 파싱. `--key=value` / `--key value` / `--flag`(=true).
18
+ * commander 일원화(ADR-195) 이후에도 두 용도로 남는다 — ① runCli 의 사전 스캔(`--root`·명령어 판별,
19
+ * commander 진입 전), ② 플러그인 CLI 명령 핸들러 인자 계약(`handler({ _, flags })`, 03-api-spec §11).
20
+ * @param {string[]} argv - `process.argv.slice(2)` 형태.
21
+ * @returns {{ _: string[], flags: Record<string, string | boolean> }}
22
+ */
23
+ export function parseArgs(argv: string[]): {
24
+ _: string[];
25
+ flags: Record<string, string | boolean>;
26
+ };
27
+ /**
28
+ * cluster 워커 수 설정값을 실제 워커 수로 해석한다(ADR-154 / 04-data-models §MegaServerConfig).
29
+ *
30
+ * 유효 도메인: **양의 정수** 또는 **'max'**(= CPU 코어 수). 그 외(0·음수·소수·'max' 아닌 문자열)는
31
+ * fail-closed 로 throw 한다 — 잘못된 값을 1로 조용히 강등하면 운영자가 클러스터가 안 뜬 줄 모른다(P4/P7).
32
+ * 워커가 1개로 해석되면(설정 `1`, 또는 단일 코어의 'max') 마스터+워커 2프로세스는 오버헤드만 더하므로
33
+ * **단일 프로세스(클러스터 비활성)** 로 본다 → `null` 반환.
34
+ *
35
+ * @param {string | number | boolean | undefined | null} setting - `--cluster` 플래그 / `MEGA_CLUSTER_WORKERS`
36
+ * env / `server.cluster` config 값. 미지정(`undefined`/`null`/`''`)은 단일 프로세스. 베어 `--cluster`(=true)는 'max'.
37
+ * @param {() => number} [cpuCount] - CPU 코어 수 공급자(테스트 주입용). 기본 {@link defaultCpuCount}.
38
+ * @returns {number | null} 워커 수(≥2) 또는 단일 프로세스면 `null`.
39
+ * @throws {MegaConfigError} `config.invalid_cluster` — 양의 정수도 'max' 도 아닌 값.
40
+ */
41
+ export function resolveClusterWorkers(setting: string | number | boolean | undefined | null, cpuCount?: () => number): number | null;
42
+ /**
43
+ * `--port` 플래그를 검증된 listen 포트로 해석한다(fail-closed — {@link resolveClusterWorkers} 와 동형).
44
+ *
45
+ * 유효 도메인: **0~65535 정수**. 미지정(`undefined`)은 config/기본값에 위임하려 `undefined` 를 돌려준다.
46
+ * 값 없는 베어 `--port`(=`true`)·빈 값 `--port=`(=`''`)·정수 아님·범위 밖은 throw 한다 — 잘못된 값을
47
+ * 조용히 강등하면(`Number(true)=1` 특권포트, `Number('')=0` 랜덤포트, `Number('abc')=NaN` 은 어댑터
48
+ * connect 까지 부팅한 뒤 Node 가 `ERR_SOCKET_BAD_PORT` 로 늦게 throw) 운영자가 의도와 다른 포트를 쓰거나
49
+ * 늦은 cryptic 에러를 만난다(P4/P7). 명시적 `--port 0`(OS 랜덤 포트)은 정상 값으로 허용한다.
50
+ *
51
+ * @param {string | boolean | undefined | null} setting - `--port` 플래그 값.
52
+ * @returns {number | undefined} 검증된 포트, 또는 미지정이면 `undefined`(config/기본 위임).
53
+ * @throws {MegaConfigError} `config.invalid_port` — 값 없음/빈 값/정수 아님/범위 밖.
54
+ */
55
+ export function resolvePort(setting: string | boolean | undefined | null): number | undefined;
56
+ /**
57
+ * `--host` 플래그를 검증된 listen 호스트로 해석한다(fail-closed). 미지정은 config/기본값에 위임하려
58
+ * `undefined`. 값 없는 베어 `--host`·빈 값 `--host=`는 throw — 빈 호스트를 `MegaServer` 로 흘리면
59
+ * Node 가 전 인터페이스(`::`)에 silent bind 해 운영자 의도와 달라진다(P4). 비어 있지 않은 문자열은 그대로.
60
+ *
61
+ * @param {string | boolean | undefined | null} setting - `--host` 플래그 값.
62
+ * @returns {string | undefined} 검증된 호스트, 또는 미지정이면 `undefined`(config/기본 위임).
63
+ * @throws {MegaConfigError} `config.invalid_host` — 값 없음/빈 값.
64
+ */
65
+ export function resolveHost(setting: string | boolean | undefined | null): string | undefined;
66
+ /**
67
+ * `--root` 플래그를 검증된 프로젝트 루트로 해석한다(fail-closed — {@link resolveHost} 와 동형, OQ-029②).
68
+ *
69
+ * 미지정은 cwd 폴백에 위임하려 `undefined`. 값 없는 베어 `--root`(=`true`)·빈 값 `--root=`(=`''`)은
70
+ * throw — 빈 루트를 통과시키면 `join('', '.env')`/`loadAndValidateConfig('')` 가 cwd 상대로 silent
71
+ * 오동작해 운영자가 의도한 루트 지정 실패를 모른다(P4/P7). 비어 있지 않은 문자열은 그대로.
72
+ *
73
+ * @param {string | boolean | undefined | null} setting - `--root` 플래그 값.
74
+ * @returns {string | undefined} 검증된 루트, 또는 미지정이면 `undefined`(cwd 폴백 위임).
75
+ * @throws {MegaConfigError} `config.invalid_root` — 값 없음/빈 값.
76
+ */
77
+ export function resolveRoot(setting: string | boolean | undefined | null): string | undefined;
78
+ /**
79
+ * `--db` 플래그를 검증된 마이그레이션 대상 키로 해석한다(fail-closed — {@link resolveRoot} 와 동형, OQ-029②).
80
+ *
81
+ * 미지정은 자동 선택(`resolveMigrationAdapter` 의 유일 db/primary 규칙)에 위임하려 `undefined`. 값 없는
82
+ * 베어 `--db`(=`true`)·빈 값 `--db=`(=`''`)은 throw — 빈 키가 자동 선택으로 silent 강등되면 운영자가
83
+ * 지정 실패를 모른 채 다른 db 에 마이그레이션을 적용할 수 있다(P4/P7).
84
+ *
85
+ * @param {string | boolean | undefined | null} setting - `--db` 플래그 값.
86
+ * @returns {string | undefined} 검증된 db 키, 또는 미지정이면 `undefined`(자동 선택 위임).
87
+ * @throws {MegaConfigError} `config.invalid_db` — 값 없음/빈 값.
88
+ */
89
+ export function resolveDb(setting: string | boolean | undefined | null): string | undefined;
90
+ /**
91
+ * `mega start --watch` 가 자신을 `node --watch` 로 재실행해야 하는지 (ADR-182). `--watch` 플래그가 있고
92
+ * 아직 watch 하에 재실행되지 않았을 때만 true — 가드 env(`MEGA_WATCH_REEXEC`)로 무한재귀를 막는다.
93
+ * @param {Record<string, string|boolean>} flags
94
+ * @param {Record<string, string|undefined>} env
95
+ * @returns {boolean}
96
+ */
97
+ export function shouldReexecForWatch(flags: Record<string, string | boolean>, env: Record<string, string | undefined>): boolean;
98
+ /**
99
+ * `mega start --watch` supervisor 의 **자식 인자**를 빌드한다 (ADR-220, ADR-182 개정).
100
+ *
101
+ * - `--watch`/`--watch-ignore`(값 포함)는 부모(supervisor) 전용 — 자식 인자에서 제거한다
102
+ * (가드 env 와 이중 안전으로 무한재귀 방지).
103
+ * - **단일 프로세스 강제**(`--cluster 1`) — 멀티워커 watch 카오스 방지(기존 `--cluster` 값은 무시).
104
+ *
105
+ * @param {string[]} argv - 원본 mega argv(예: `['start','--watch','--port','3000']`).
106
+ * @returns {string[]} 자식 `mega` 인자(예: `['start','--port','3000','--cluster','1']`).
107
+ */
108
+ export function buildWatchChildArgs(argv: string[]): string[];
109
+ /**
110
+ * `mega` CLI 진입점. 파싱 → 명령 분기. **이 함수는 process.exit 를 호출하지 않는다**(테스트 가능) —
111
+ * exit code 를 반환하고, bin 래퍼가 `process.exitCode` 로 반영한다.
112
+ *
113
+ * @param {string[]} argv - `process.argv.slice(2)`.
114
+ * @param {Object} [deps] - 테스트 주입용.
115
+ * @param {(msg: string) => void} [deps.out] - stdout writer(기본 console.log).
116
+ * @param {(msg: string) => void} [deps.err] - stderr writer(기본 console.error).
117
+ * @param {string} [deps.cwd] - 기본 projectRoot(기본 process.cwd()).
118
+ * @param {{ debug?: Function, info?: Function, warn?: Function }} [deps.logger]
119
+ * @param {Function} [deps.spawn] - child_process.spawn 주입(기본 node:child_process). `--watch` 재실행 테스트용.
120
+ * @param {string} [deps.selfPath] - mega 진입 스크립트 경로(기본 `process.argv[1]`). `--watch` 재실행 대상.
121
+ * @returns {Promise<number>} exit code(0=성공, 1=실패/미지정 명령).
122
+ */
123
+ export function runCli(argv: string[], { out, err, cwd, logger, spawn, selfPath }?: {
124
+ out?: (msg: string) => void;
125
+ err?: (msg: string) => void;
126
+ cwd?: string;
127
+ logger?: {
128
+ debug?: Function;
129
+ info?: Function;
130
+ warn?: Function;
131
+ };
132
+ spawn?: Function;
133
+ selfPath?: string;
134
+ }): Promise<number>;
135
+ /**
136
+ * 플러그인 CLI 명령을 dispatch 한다 — config 로드 → 플러그인 install → `host.getCommand(name)` 조회.
137
+ * 어댑터 connect 는 하지 않는다(명령 핸들러가 필요하면 자체 처리 — 골격은 가볍게 유지, ADR-123).
138
+ *
139
+ * @param {string} projectRoot
140
+ * @param {string} name - 명령 이름.
141
+ * @param {{ _: string[], flags: Record<string, string | boolean> }} args - 핸들러에 그대로 전달.
142
+ * @param {{ debug?: Function }} [logger]
143
+ * @returns {Promise<{ found: boolean, code: number }>}
144
+ */
145
+ export function dispatchPluginCommand(projectRoot: string, name: string, args: {
146
+ _: string[];
147
+ flags: Record<string, string | boolean>;
148
+ }, logger?: {
149
+ debug?: Function;
150
+ }): Promise<{
151
+ found: boolean;
152
+ code: number;
153
+ }>;
154
+ /**
155
+ * 잡/스케줄 **등록 소스 흡수**(ADR-123) — `config.<key>`(정적) + 플러그인 `host.list*()`(동적)을 합친다.
156
+ * 명시 등록만(auto-discovery X, ADR-079 정합). 순수 함수라 단위 검증 가능(register 부작용 분리).
157
+ * @param {Object} global - global config(`jobs`/`schedules` 배열 보유 가능).
158
+ * @param {import('../lib/mega-plugin.js').MegaPluginHost} host
159
+ * @param {'jobs' | 'schedules'} kind
160
+ * @returns {Function[]} 등록할 클래스 목록(config 먼저, 플러그인 등록분 뒤).
161
+ */
162
+ export function collectRegistrations(global: Object, host: import("../lib/mega-plugin.js").MegaPluginHost, kind: "jobs" | "schedules"): Function[];
163
+ /**
164
+ * `mega worker` 호스트 골격 — config + 어댑터 connect + ctx + `MegaJobWorker` 인스턴스 + graceful.
165
+ * 등록 소스 = `config.jobs` + 플러그인 `mega.jobs.register` 분(`collectRegistrations`, ADR-123).
166
+ * @param {string} projectRoot
167
+ * @param {{ debug?: Function, info?: Function, warn?: Function }} [logger]
168
+ * @returns {Promise<import('../lib/mega-job-worker.js').MegaJobWorker>}
169
+ */
170
+ export function runWorkerHost(projectRoot: string, logger?: {
171
+ debug?: Function;
172
+ info?: Function;
173
+ warn?: Function;
174
+ }): Promise<import("../lib/mega-job-worker.js").MegaJobWorker>;
175
+ /**
176
+ * `mega scheduler` 호스트 골격 — config + 어댑터 connect + ctx + `MegaScheduler` 인스턴스 + graceful.
177
+ * @param {string} projectRoot
178
+ * @param {{ debug?: Function, info?: Function, warn?: Function }} [logger]
179
+ * @returns {Promise<import('../lib/mega-schedule.js').MegaScheduler>}
180
+ */
181
+ export function runSchedulerHost(projectRoot: string, logger?: {
182
+ debug?: Function;
183
+ info?: Function;
184
+ warn?: Function;
185
+ }): Promise<import("../lib/mega-schedule.js").MegaScheduler>;
186
+ /**
187
+ * 마이그레이션 대상 DB 어댑터 해석 — `services.databases` 의 globalKey 로 조회한다. `--db <key>` 미지정
188
+ * 시 유일 선언 db, 그게 아니면 `primary`, 둘 다 아니면(다중·미선언) fail-fast 로 명시를 요구한다.
189
+ *
190
+ * 러너는 SQL `query` 기반이라(ADR-149 ⑥) `query` 도메인 메서드를 구현하지 않은 어댑터(mongodb 등
191
+ * Document DB)는 대상이 될 수 없다 — 베이스의 `adapter.not_implemented` 가 늦게 터지는 대신 여기서
192
+ * `migrate.unsupported_driver` 로 명시 fail-fast 한다(ADR-190).
193
+ *
194
+ * @param {Object} global - global config.
195
+ * @param {string} [dbKey] - `--db` 플래그.
196
+ * @returns {import('../adapters/mega-adapter.js').MegaAdapter}
197
+ */
198
+ export function resolveMigrationAdapter(global: Object, dbKey?: string): import("../adapters/mega-adapter.js").MegaAdapter;
199
+ /**
200
+ * `mega migrate` 일회성 호스트 — config 로드 → 플러그인 install → DB build/connect → 러너 실행 →
201
+ * disconnect. 워커/wsHub/메트릭은 띄우지 않는다(마이그레이션엔 불필요·이벤트루프 유지 회피).
202
+ * `MegaShutdown.now`(process.exit)를 쓰지 않고 직접 disconnect 해 반환값으로 결과를 돌려준다(테스트 가능).
203
+ *
204
+ * up/down 은 driver 별 마이그레이션 락({@link module:core/migration-lock}, ADR-190)으로 직렬화한다 —
205
+ * 동시 `mega migrate`(멀티 인스턴스 배포 훅)의 중복 적용 방지. status 는 읽기 전용이라 락 없이 실행.
206
+ *
207
+ * @param {string} projectRoot
208
+ * @param {{ direction?: 'up'|'down'|'status', dbKey?: string, logger?: { debug?: Function, info?: Function, warn?: Function }, out?: (msg: string) => void }} [opts]
209
+ * @returns {Promise<{ applied: string[] } | { rolledBack: string|null } | { applied: string[], pending: string[], modified: string[] }>}
210
+ */
211
+ export function runMigrateHost(projectRoot: string, { direction, dbKey, logger, out }?: {
212
+ direction?: "up" | "down" | "status";
213
+ dbKey?: string;
214
+ logger?: {
215
+ debug?: Function;
216
+ info?: Function;
217
+ warn?: Function;
218
+ };
219
+ out?: (msg: string) => void;
220
+ }): Promise<{
221
+ applied: string[];
222
+ } | {
223
+ rolledBack: string | null;
224
+ } | {
225
+ applied: string[];
226
+ pending: string[];
227
+ modified: string[];
228
+ }>;
229
+ /** 빌트인 명령 이름·별칭 전체 — 이 표 밖의 첫 positional 은 플러그인 명령 dispatch 로 fallthrough 한다
230
+ * (ADR-123 계약 유지). `buildProgram` 의 commander 등록과 동기를 유지할 것. */
231
+ export const BUILTIN_COMMANDS: Set<string>;
232
+ /** CLI 사용법 텍스트 — commander 자동 생성(ADR-195) + 플러그인 명령 안내. 명령·옵션 정의가 곧 도움말의
233
+ * 단일 정본이라 수기 USAGE 와의 드리프트가 없다. */
234
+ export const USAGE: string;
@@ -0,0 +1,40 @@
1
+ /**
2
+ * zero-dep 템플릿 엔진 + 이름 변형 유틸 (ADR-142).
3
+ *
4
+ * `templates/<kind>/*.tpl` 파일의 `{{token}}` 자리를 vars 로 치환한다. 외부 템플릿 dep(handlebars 등)
5
+ * 없이 `process.argv` 파싱(ADR-123)과 같은 정책으로 단순 토큰 치환만 한다 — generator 가 만드는 코드는
6
+ * 정적 골격이라 조건/루프 같은 복잡한 템플릿 기능이 필요 없다.
7
+ *
8
+ * 토큰 형식은 `{{word}}`(이중 중괄호)라 생성 코드의 JSDoc `@param {string}`·객체 리터럴 `{ x }`
9
+ * (단일 중괄호)와 충돌하지 않는다. 미정의 토큰은 즉시 throw(silent 치환 누락 방지, P4).
10
+ *
11
+ * @module cli/template-engine
12
+ */
13
+ /**
14
+ * 입력 이름을 단어 배열로 분해한다. camelCase 경계와 구분자(`-`, `_`, 공백, `.`)를 모두 단어 경계로
15
+ * 본다. 예: `'UserProfile'`/`'user-profile'`/`'user_profile'` → `['user','profile']`.
16
+ * @param {string} raw
17
+ * @returns {string[]}
18
+ */
19
+ export function toWords(raw: string): string[];
20
+ /**
21
+ * 입력 이름에서 표준 변형 4종을 만든다.
22
+ * @param {string} raw
23
+ * @returns {{ kebab: string, pascal: string, camel: string, snake: string, words: string[] }}
24
+ * @throws {Error} 영숫자 단어가 하나도 없으면(빈/특수문자만) fail-fast.
25
+ */
26
+ export function nameVariants(raw: string): {
27
+ kebab: string;
28
+ pascal: string;
29
+ camel: string;
30
+ snake: string;
31
+ words: string[];
32
+ };
33
+ /**
34
+ * 템플릿 문자열의 `{{token}}` 을 vars 값으로 치환한다.
35
+ * @param {string} tpl - 템플릿 본문.
36
+ * @param {Record<string, string>} vars - 토큰 → 값.
37
+ * @returns {string}
38
+ * @throws {Error} 템플릿에 vars 에 없는 토큰이 있으면(오타·누락 방지).
39
+ */
40
+ export function renderTemplate(tpl: string, vars: Record<string, string>): string;
@@ -0,0 +1,59 @@
1
+ /**
2
+ * 미니 glob → RegExp. 지원: 더블스타+슬래시(0개 이상의 디렉토리), 더블스타(경로 전체), `*`(세그먼트
3
+ * 내), `?`(1글자). 그 외 문자는 리터럴(정규식 특수문자 escape). 매칭 대상은 루트 상대 POSIX 경로
4
+ * 전체(^…$). 패턴 예시는 스캐폴드 `.env` 의 `WATCH_IGNORE` 참조 — JS 블록 주석 안에는
5
+ * 더블스타+슬래시 시퀀스를 쓸 수 없어(주석 조기 종료) 여기 직접 못 적는다.
6
+ *
7
+ * @param {string} pattern - glob 패턴(예 `.env.*`).
8
+ * @returns {RegExp}
9
+ */
10
+ export function globToRegExp(pattern: string): RegExp;
11
+ /**
12
+ * ignore 패턴 합성 — config(`watch.ignore`) + CLI(`--watch-ignore a,b`). 숨은 디폴트 없음(모듈
13
+ * docstring 참조). 잘못된 모양은 fail-fast(silent 무시 금지).
14
+ *
15
+ * @param {{ ignore?: unknown }} [watchConfig] - mega.config.js 의 `watch`.
16
+ * @param {string | undefined} [cliIgnore] - `--watch-ignore` 값(콤마 구분).
17
+ * @returns {string[]}
18
+ * @throws {TypeError} config `watch.ignore` 가 문자열 배열이 아닐 때.
19
+ */
20
+ export function mergeWatchIgnore(watchConfig?: {
21
+ ignore?: unknown;
22
+ }, cliIgnore?: string | undefined): string[];
23
+ /**
24
+ * 루트 상대 경로가 ignore 에 걸리는지 (Boolean — `is*`).
25
+ * @param {string} rel - 루트 상대 POSIX 경로(예 `apps/main/locales/ko.json`).
26
+ * @param {RegExp[]} regexps - {@link globToRegExp} 컴파일 결과.
27
+ * @returns {boolean}
28
+ */
29
+ export function isIgnoredPath(rel: string, regexps: RegExp[]): boolean;
30
+ /**
31
+ * watch supervisor — 감시 경로의 변경(ignore 통과분)을 debounce 후 자식(`mega start`)을
32
+ * SIGTERM → respawn 한다. 자식이 스스로 죽으면(crash) 재시작하지 않고 다음 변경을 기다린다
33
+ * (crash-loop 방지 — nodemon 의 "app crashed - waiting for file changes" 와 동형).
34
+ *
35
+ * @param {object} o
36
+ * @param {string} o.projectRoot
37
+ * @param {string[]} o.watchPaths - 감시할 절대경로(존재하는 것만 — 호출측이 필터).
38
+ * @param {string[]} o.ignore - glob 패턴 목록.
39
+ * @param {() => import('node:child_process').ChildProcess} o.spawnChild - 자식 기동 팩토리(주입 — 테스트).
40
+ * @param {(msg: string) => void} o.out
41
+ * @param {number} [o.debounceMs=500] - 연속 변경 디바운스.
42
+ * @param {(dir: string, opts: object, cb: (event: string, filename: string | Buffer | null) => void) => { close(): void }} [o.watchFn] -
43
+ * fs.watch 주입(테스트). 기본 node:fs watch.
44
+ * @returns {Promise<number>} 부모(supervisor)의 exit code — SIGINT/SIGTERM 수신 시 자식 정리 후 0.
45
+ */
46
+ export function startWatchSupervisor({ projectRoot, watchPaths, ignore, spawnChild, out, debounceMs, watchFn }: {
47
+ projectRoot: string;
48
+ watchPaths: string[];
49
+ ignore: string[];
50
+ spawnChild: () => import("node:child_process").ChildProcess;
51
+ out: (msg: string) => void;
52
+ debounceMs?: number;
53
+ watchFn?: (dir: string, opts: object, cb: (event: string, filename: string | Buffer | null) => void) => {
54
+ close(): void;
55
+ };
56
+ }): Promise<number>;
57
+ /** {@link startWatchSupervisor} 의 watchPaths 기본 집합 — 존재하는 것만.
58
+ * @param {string} projectRoot @returns {string[]} */
59
+ export function defaultWatchPaths(projectRoot: string): string[];
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Fastify 가 던진 AJV 검증 에러 객체 → MegaValidationError 로 매핑.
3
+ *
4
+ * Fastify 의 AJV 에러는 `err.validation: AjvErrorObject[]` + `err.validationContext: string`
5
+ * 형태. AjvErrorObject 는 { instancePath, schemaPath, keyword, message, params } 가짐.
6
+ *
7
+ * envelope details 형식 (ADR-075 배열):
8
+ * [{ field: string, rule: string, value?: any, message: string }, ...]
9
+ *
10
+ * @param {Error & { validation?: any[], validationContext?: string }} err
11
+ * @returns {MegaValidationError | null}
12
+ * AJV 에러가 아니면 null (호출자가 그대로 throw).
13
+ */
14
+ export function ajvErrorToValidationError(err: Error & {
15
+ validation?: any[];
16
+ validationContext?: string;
17
+ }): MegaValidationError | null;
18
+ /**
19
+ * envelope `details` 배열 상한 (ADR-193 — allErrors DoS 방어의 응답측 bound).
20
+ *
21
+ * allErrors:true 는 위반을 전수 수집하므로(@fastify/ajv-compiler 디폴트가 allErrors:false 인 이유 =
22
+ * DoS 가능성 명시) 악의적 페이로드가 수천 개 위반을 만들 수 있다. 입력측은 Fastify bodyLimit
23
+ * (기본 1 MiB)이 막고, 응답·로그측은 이 cap 이 막는다 — 초과분은 잘라내되 silent 가 아니라
24
+ * `rule:'truncated'` 합성 항목으로 생략 개수를 명시한다.
25
+ */
26
+ export const MAX_VALIDATION_DETAILS: 20;
27
+ import { MegaValidationError } from '../errors/http-errors.js';