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.
- package/README.md +9 -0
- package/bin/mega-ws-hub.js +2 -2
- package/package.json +33 -9
- package/sample/crud/.env +10 -1
- package/sample/crud/.env.example +10 -1
- package/sample/crud/.mega/journal/history/20260612092543-create-users.json +261 -0
- package/sample/crud/.mega/journal/snapshot.json +261 -0
- package/sample/crud/apps/main/controllers/auth-controller.js +22 -14
- package/sample/crud/apps/main/controllers/web-controller.js +7 -5
- package/sample/crud/apps/main/locales/server/en.json +12 -1
- package/sample/crud/apps/main/locales/server/ko.json +12 -1
- package/sample/crud/apps/main/migrations/20260606000001-create-users.js +91 -13
- package/sample/crud/apps/main/migrations/20260606000002-create-boards.js +165 -0
- package/sample/crud/apps/main/migrations/20260606000003-create-logs.js +107 -0
- package/sample/crud/apps/main/models/log-partition-model.js +105 -0
- package/sample/crud/apps/main/models/note-model.js +79 -0
- package/sample/crud/apps/main/models/user-level-model.js +24 -0
- package/sample/crud/apps/main/models/user-model.js +146 -0
- package/sample/crud/apps/main/models/user-type-model.js +21 -0
- package/sample/crud/apps/main/models/wallet-model.js +24 -0
- package/sample/crud/apps/main/routes/users.js +55 -10
- package/sample/crud/apps/main/schedules/log-partition-schedule.js +33 -0
- package/sample/crud/apps/main/services/auth-service.js +39 -24
- package/sample/crud/apps/main/services/log-partition-service.js +101 -0
- package/sample/crud/apps/main/services/note-service.js +6 -6
- package/sample/crud/apps/main/services/redis-demo-service.js +3 -3
- package/sample/crud/apps/main/services/user-service.js +62 -21
- package/sample/crud/apps/main/views/auth/login.ejs +6 -6
- package/sample/crud/apps/main/views/auth/register.ejs +46 -5
- package/sample/crud/apps/main/views/users/edit.ejs +42 -5
- package/sample/crud/apps/main/views/users/list.ejs +6 -2
- package/sample/crud/apps/main/views/users/new.ejs +56 -4
- package/sample/crud/docs/log_partition_design.mm.md +23 -0
- package/sample/crud/mega.config.js +10 -2
- package/sample/crud/package.json +3 -3
- package/sample/crud/scripts/start-ws-hub.sh +20 -6
- package/sample/simple/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -0
- package/sample/simple/package.json +2 -2
- package/src/adapters/adapter-manager.js +2 -1
- package/src/adapters/adapter-options.js +44 -3
- package/src/adapters/file-adapter.js +9 -5
- package/src/adapters/file-session-adapter.js +4 -3
- package/src/adapters/maria-adapter.js +33 -7
- package/src/adapters/mega-cache-adapter.js +83 -6
- package/src/adapters/mega-db-adapter.js +10 -1
- package/src/adapters/mongo-adapter.js +40 -8
- package/src/adapters/postgres-adapter.js +33 -6
- package/src/adapters/redis-adapter.js +7 -3
- package/src/adapters/sqlite-adapter.js +26 -3
- package/src/cli/commands/console-cmd.js +3 -1
- package/src/cli/commands/new.js +13 -3
- package/src/cli/commands/scaffold.js +173 -33
- package/src/cli/generators/index.js +140 -3
- package/src/cli/index.js +437 -155
- package/src/cli/watch.js +188 -0
- package/src/core/ajv-mapper.js +30 -3
- package/src/core/boot.js +464 -245
- package/src/core/cluster-metrics.js +13 -4
- package/src/core/ctx-builder.js +65 -3
- package/src/core/envelope.js +119 -12
- package/src/core/hub-link.js +89 -18
- package/src/core/i18n.js +11 -1
- package/src/core/index.js +7 -3
- package/src/core/mega-app.js +253 -505
- package/src/core/mega-cluster.js +4 -1
- package/src/core/mega-server.js +40 -9
- package/src/core/migration/dialect-registry.js +107 -0
- package/src/core/migration/dialects/README.md +62 -0
- package/src/core/migration/dialects/maria.js +496 -0
- package/src/core/migration/dialects/mongo.js +824 -0
- package/src/core/migration/dialects/postgres.js +563 -0
- package/src/core/migration/dialects/sqlite.js +476 -0
- package/src/core/migration/differ.js +456 -0
- package/src/core/migration/generate.js +508 -0
- package/src/core/migration/journal.js +167 -0
- package/src/core/migration/model-scan.js +84 -0
- package/src/core/migration/mongo-migration-db.js +97 -0
- package/src/core/migration/schema-builder.js +400 -0
- package/src/core/migration/schema-validator.js +315 -0
- package/src/core/migration-lock.js +205 -0
- package/src/core/migration-runner.js +166 -38
- package/src/core/multipart.js +28 -5
- package/src/core/pipeline.js +131 -0
- package/src/core/router.js +70 -65
- package/src/core/scope-registry.js +1 -0
- package/src/core/security.js +70 -12
- package/src/core/session-store.js +14 -1
- package/src/core/workers-manager.js +12 -1
- package/src/core/ws-cluster.js +10 -3
- package/src/core/ws-message.js +48 -4
- package/src/core/ws-presence.js +636 -0
- package/src/core/ws-roster.js +50 -8
- package/src/core/ws-upgrade.js +223 -12
- package/src/index.js +1 -1
- package/src/lib/hub-protocol.js +29 -0
- package/src/lib/mega-circuit-breaker.js +5 -3
- package/src/lib/mega-health.js +35 -4
- package/src/lib/mega-job-queue.js +151 -34
- package/src/lib/mega-job.js +37 -1
- package/src/lib/mega-metrics.js +31 -13
- package/src/lib/mega-plugin.js +34 -3
- package/src/lib/mega-schedule.js +40 -22
- package/src/lib/mega-shutdown.js +114 -39
- package/src/lib/mega-tracing.js +66 -19
- package/src/lib/mega-worker.js +33 -6
- package/src/lib/otel-resource.js +36 -0
- package/src/{cli → lib}/ws-hub.js +139 -15
- package/src/models/crud-sql-builder.js +133 -0
- package/src/models/mega-model.js +82 -2
- package/src/models/model-crud.js +483 -0
- package/src/models/mongo-crud.js +285 -0
- package/templates/adr/code.tpl +23 -0
- package/templates/model/code-mongo.tpl +35 -0
- package/templates/model/code.tpl +15 -1
- package/templates/model/test-mongo.tpl +38 -0
- package/templates/model/test.tpl +4 -0
- package/types/adapters/adapter-manager.d.ts +95 -0
- package/types/adapters/adapter-options.d.ts +93 -0
- package/types/adapters/file-adapter.d.ts +105 -0
- package/types/adapters/file-session-adapter.d.ts +103 -0
- package/types/adapters/index.d.ts +20 -0
- package/types/adapters/maria-adapter.d.ts +117 -0
- package/types/adapters/mega-adapter.d.ts +215 -0
- package/types/adapters/mega-bus-adapter.d.ts +45 -0
- package/types/adapters/mega-cache-adapter.d.ts +73 -0
- package/types/adapters/mega-db-adapter.d.ts +50 -0
- package/types/adapters/mega-lock-adapter.d.ts +62 -0
- package/types/adapters/mega-log-sink-adapter.d.ts +15 -0
- package/types/adapters/mega-session-adapter.d.ts +32 -0
- package/types/adapters/mongo-adapter.d.ts +150 -0
- package/types/adapters/nats-adapter.d.ts +108 -0
- package/types/adapters/postgres-adapter.d.ts +141 -0
- package/types/adapters/redis-adapter.d.ts +78 -0
- package/types/adapters/redis-session-adapter.d.ts +82 -0
- package/types/adapters/redlock-adapter.d.ts +149 -0
- package/types/adapters/registry.d.ts +46 -0
- package/types/adapters/sqlite-adapter.d.ts +112 -0
- package/types/auth/index.d.ts +24 -0
- package/types/cli/commands/console-cmd.d.ts +37 -0
- package/types/cli/commands/new.d.ts +16 -0
- package/types/cli/commands/routes.d.ts +36 -0
- package/types/cli/commands/scaffold.d.ts +78 -0
- package/types/cli/commands/test-cmd.d.ts +14 -0
- package/types/cli/generators/index.d.ts +122 -0
- package/types/cli/index.d.ts +234 -0
- package/types/cli/template-engine.d.ts +40 -0
- package/types/cli/watch.d.ts +59 -0
- package/types/core/ajv-mapper.d.ts +27 -0
- package/types/core/boot.d.ts +233 -0
- package/types/core/cluster-metrics.d.ts +52 -0
- package/types/core/config-loader.d.ts +13 -0
- package/types/core/config-validator.d.ts +30 -0
- package/types/core/ctx-builder.d.ts +103 -0
- package/types/core/envelope.d.ts +79 -0
- package/types/core/error-mapper.d.ts +17 -0
- package/types/core/formbody.d.ts +41 -0
- package/types/core/hub-link.d.ts +266 -0
- package/types/core/i18n.d.ts +178 -0
- package/types/core/index.d.ts +28 -0
- package/types/core/mega-app.d.ts +529 -0
- package/types/core/mega-cluster.d.ts +104 -0
- package/types/core/mega-server.d.ts +91 -0
- package/types/core/mega-service.d.ts +31 -0
- package/types/core/migration/dialect-registry.d.ts +22 -0
- package/types/core/migration/dialects/maria.d.ts +99 -0
- package/types/core/migration/dialects/mongo.d.ts +89 -0
- package/types/core/migration/dialects/postgres.d.ts +117 -0
- package/types/core/migration/dialects/sqlite.d.ts +111 -0
- package/types/core/migration/differ.d.ts +47 -0
- package/types/core/migration/generate.d.ts +56 -0
- package/types/core/migration/journal.d.ts +52 -0
- package/types/core/migration/model-scan.d.ts +19 -0
- package/types/core/migration/mongo-migration-db.d.ts +7 -0
- package/types/core/migration/schema-builder.d.ts +197 -0
- package/types/core/migration/schema-validator.d.ts +20 -0
- package/types/core/migration-lock.d.ts +33 -0
- package/types/core/migration-runner.d.ts +101 -0
- package/types/core/multipart.d.ts +86 -0
- package/types/core/openapi.d.ts +62 -0
- package/types/core/pipeline.d.ts +93 -0
- package/types/core/router.d.ts +159 -0
- package/types/core/routes-loader.d.ts +21 -0
- package/types/core/scope-registry.d.ts +14 -0
- package/types/core/security.d.ts +77 -0
- package/types/core/services-loader.d.ts +27 -0
- package/types/core/session-cleanup-schedule.d.ts +19 -0
- package/types/core/session-store.d.ts +25 -0
- package/types/core/session.d.ts +77 -0
- package/types/core/static-assets.d.ts +73 -0
- package/types/core/template.d.ts +106 -0
- package/types/core/workers-manager.d.ts +79 -0
- package/types/core/ws-cluster.d.ts +208 -0
- package/types/core/ws-compression.d.ts +112 -0
- package/types/core/ws-controller.d.ts +65 -0
- package/types/core/ws-message.d.ts +106 -0
- package/types/core/ws-presence.d.ts +273 -0
- package/types/core/ws-roster.d.ts +108 -0
- package/types/core/ws-upgrade.d.ts +260 -0
- package/types/errors/config-error.d.ts +10 -0
- package/types/errors/http-errors.d.ts +120 -0
- package/types/errors/index.d.ts +3 -0
- package/types/errors/mega-error.d.ts +32 -0
- package/types/index.d.ts +39 -0
- package/types/lib/asp/config.d.ts +49 -0
- package/types/lib/asp/crypto.d.ts +43 -0
- package/types/lib/asp/errors.d.ts +30 -0
- package/types/lib/asp/nonce-cache.d.ts +52 -0
- package/types/lib/asp/plugin.d.ts +30 -0
- package/types/lib/asp/ws-terminator.d.ts +45 -0
- package/types/lib/env-mapper.d.ts +14 -0
- package/types/lib/hub-protocol.d.ts +106 -0
- package/types/lib/index.d.ts +22 -0
- package/types/lib/logger/telegram-core.d.ts +104 -0
- package/types/lib/logger/telegram-transport.d.ts +45 -0
- package/types/lib/mega-brute-force.d.ts +66 -0
- package/types/lib/mega-circuit-breaker.d.ts +243 -0
- package/types/lib/mega-cron.d.ts +66 -0
- package/types/lib/mega-hash.d.ts +32 -0
- package/types/lib/mega-health.d.ts +48 -0
- package/types/lib/mega-job-queue.d.ts +188 -0
- package/types/lib/mega-job-worker.d.ts +130 -0
- package/types/lib/mega-job.d.ts +145 -0
- package/types/lib/mega-logger.d.ts +45 -0
- package/types/lib/mega-metrics.d.ts +285 -0
- package/types/lib/mega-plugin.d.ts +245 -0
- package/types/lib/mega-retry.d.ts +85 -0
- package/types/lib/mega-schedule.d.ts +260 -0
- package/types/lib/mega-shutdown.d.ts +135 -0
- package/types/lib/mega-tracing.d.ts +224 -0
- package/types/lib/mega-worker.d.ts +129 -0
- package/types/lib/otel-resource.d.ts +16 -0
- package/types/lib/worker-runner/process-entry.d.ts +1 -0
- package/types/lib/worker-runner/task-dispatch.d.ts +28 -0
- package/types/lib/worker-runner/thread-entry.d.ts +1 -0
- package/types/lib/ws-hub.d.ts +259 -0
- package/types/models/crud-sql-builder.d.ts +48 -0
- package/types/models/index.d.ts +1 -0
- package/types/models/mega-model.d.ts +138 -0
- package/types/models/model-crud.d.ts +82 -0
- package/types/models/mongo-crud.d.ts +59 -0
- package/types/test/index.d.ts +84 -0
- package/.env +0 -127
- package/sample/crud/apps/main/migrations/20260606000002-add-auth-to-users.js +0 -30
- package/sample/crud/apps/main/models/note.js +0 -71
- package/sample/crud/apps/main/models/user.js +0 -86
- package/sample/crud/package-lock.json +0 -5665
- package/sample/crud/yarn.lock +0 -2142
- package/sample/simple/package-lock.json +0 -1851
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 활성 여부 (Boolean — `is*`). `init` 후 `shutdown` 전이면 true.
|
|
3
|
+
* @returns {boolean}
|
|
4
|
+
*/
|
|
5
|
+
export function isEnabled(): boolean;
|
|
6
|
+
/**
|
|
7
|
+
* OTel 메트릭 초기화. 옵트인 — 본 함수를 부르지 않으면 모든 `record*` 가 0 비용 no-op.
|
|
8
|
+
*
|
|
9
|
+
* @param {object} opts
|
|
10
|
+
* @param {string} opts.serviceName - **필수**. `service.name` resource 속성.
|
|
11
|
+
* @param {string} [opts.version] - `service.version`.
|
|
12
|
+
* @param {string} [opts.environment] - `deployment.environment.name`.
|
|
13
|
+
* @param {Record<string, any>} [opts.attributes] - 추가 resource 속성(머지). 시크릿 금지.
|
|
14
|
+
* @returns {void}
|
|
15
|
+
* @throws {MegaConfigError} `metrics.already_initialized` / `metrics.service_name_required`.
|
|
16
|
+
*/
|
|
17
|
+
export function init(opts?: {
|
|
18
|
+
serviceName: string;
|
|
19
|
+
version?: string;
|
|
20
|
+
environment?: string;
|
|
21
|
+
attributes?: Record<string, any>;
|
|
22
|
+
}): void;
|
|
23
|
+
/**
|
|
24
|
+
* `MEGA_METRICS_*` / `METRICS_ENABLED` 환경변수로 옵트인 초기화 (12-factor). 비활성이면 **no-op**.
|
|
25
|
+
* `/metrics` 자체는 `health.exposeMetrics` config 로 켜지지만(ADR-072), SDK 초기화는 env 로도 가능하게
|
|
26
|
+
* 트레이싱(`MegaTracing.fromEnv`)과 대칭으로 둔다. 둘 중 하나라도 켜지면 활성.
|
|
27
|
+
*
|
|
28
|
+
* 매핑:
|
|
29
|
+
* - `METRICS_ENABLED` 또는 `MEGA_METRICS_ENABLED` (true 면 활성)
|
|
30
|
+
* - `MEGA_METRICS_SERVICE_NAME` → serviceName (없으면 `MEGA_OTEL_SERVICE_NAME` 폴백)
|
|
31
|
+
* - `MEGA_METRICS_VERSION` / `MEGA_METRICS_ENVIRONMENT` → resource 속성
|
|
32
|
+
*
|
|
33
|
+
* @param {Record<string, string|undefined>} [env=process.env]
|
|
34
|
+
* @returns {boolean} 활성화돼 init 했으면 true, 옵트인 OFF 면 false.
|
|
35
|
+
* @throws {MegaConfigError} 활성인데 serviceName 누락 시 `metrics.service_name_required`.
|
|
36
|
+
*/
|
|
37
|
+
export function fromEnv(env?: Record<string, string | undefined>): boolean;
|
|
38
|
+
/**
|
|
39
|
+
* 현재 누적된 메트릭을 Prometheus 텍스트(exposition format)로 직렬화한다. `/metrics` 라우트와 테스트가
|
|
40
|
+
* **같은 경로**로 사용한다. 옵트인 OFF 면 빈 문자열.
|
|
41
|
+
* @returns {Promise<string>}
|
|
42
|
+
*/
|
|
43
|
+
export function collect(): Promise<string>;
|
|
44
|
+
/**
|
|
45
|
+
* 트레이싱 종료 대칭 — provider 종료(+ 구독 해제). init 전이면 no-op.
|
|
46
|
+
* @returns {Promise<void>}
|
|
47
|
+
*/
|
|
48
|
+
export function shutdown(): Promise<void>;
|
|
49
|
+
/**
|
|
50
|
+
* HTTP 요청 1건 기록 — 카운터 +1 + latency 히스토그램. mega-app `onResponse` hook 이 호출.
|
|
51
|
+
* @param {object} info
|
|
52
|
+
* @param {string} info.method - HTTP 메서드(대문자).
|
|
53
|
+
* @param {string} [info.route] - **매칭된 라우트 패턴**(`/users/:id`). 없으면 `__unmatched__`(M-A).
|
|
54
|
+
* @param {number} info.statusCode - 응답 상태코드.
|
|
55
|
+
* @param {number} info.durationMs - 처리 시간(ms).
|
|
56
|
+
* @param {string} info.app - 앱 이름.
|
|
57
|
+
* @returns {void}
|
|
58
|
+
*/
|
|
59
|
+
export function recordHttp({ method, route, statusCode, durationMs, app }: {
|
|
60
|
+
method: string;
|
|
61
|
+
route?: string;
|
|
62
|
+
statusCode: number;
|
|
63
|
+
durationMs: number;
|
|
64
|
+
app: string;
|
|
65
|
+
}): void;
|
|
66
|
+
/**
|
|
67
|
+
* WebSocket 메시지 1건 기록. ws 수신 배선이 호출.
|
|
68
|
+
* @param {object} info
|
|
69
|
+
* @param {string} info.type - 메시지 타입(라우트 키처럼 bounded 한 값만 — raw payload X).
|
|
70
|
+
* @param {string} [info.ns] - 네임스페이스.
|
|
71
|
+
* @param {number} [info.durationMs] - 처리 시간(ms). 있으면 히스토그램 기록.
|
|
72
|
+
* @param {string} [info.app] - 앱 이름.
|
|
73
|
+
* @returns {void}
|
|
74
|
+
*/
|
|
75
|
+
export function recordWs({ type, ns, durationMs, app }: {
|
|
76
|
+
type: string;
|
|
77
|
+
ns?: string;
|
|
78
|
+
durationMs?: number;
|
|
79
|
+
app?: string;
|
|
80
|
+
}): void;
|
|
81
|
+
/**
|
|
82
|
+
* 어댑터 호출 1건 기록 — 도메인/드라이버/콜별 카운터 + latency. 보통 `subscribe`(onCallEnd)가 호출.
|
|
83
|
+
* @param {object} info
|
|
84
|
+
* @param {string} info.domain - db|cache|bus|lock.
|
|
85
|
+
* @param {string} info.driver - 드라이버명(postgres|redis|nats|…).
|
|
86
|
+
* @param {string} info.call - 도메인 콜명(query|get|publish|acquire|…).
|
|
87
|
+
* @param {number} info.durationMs - latency(ms).
|
|
88
|
+
* @param {boolean} info.isError - 실패 여부.
|
|
89
|
+
* @returns {void}
|
|
90
|
+
*/
|
|
91
|
+
export function recordAdapterCall({ domain, driver, call, durationMs, isError }: {
|
|
92
|
+
domain: string;
|
|
93
|
+
driver: string;
|
|
94
|
+
call: string;
|
|
95
|
+
durationMs: number;
|
|
96
|
+
isError: boolean;
|
|
97
|
+
}): void;
|
|
98
|
+
/**
|
|
99
|
+
* 잡 큐 이벤트 1건 기록(enqueued|processed|retried|dlq). MegaJobQueue/Worker 가 호출.
|
|
100
|
+
* @param {object} info
|
|
101
|
+
* @param {string} info.queue - 큐 이름.
|
|
102
|
+
* @param {'enqueued'|'processed'|'retried'|'dlq'} info.event
|
|
103
|
+
* @returns {void}
|
|
104
|
+
*/
|
|
105
|
+
export function recordJob({ queue, event }: {
|
|
106
|
+
queue: string;
|
|
107
|
+
event: "enqueued" | "processed" | "retried" | "dlq";
|
|
108
|
+
}): void;
|
|
109
|
+
/**
|
|
110
|
+
* 세션 이벤트 1건 기록(created|destroyed). 세션 미들웨어가 호출.
|
|
111
|
+
* @param {object} info
|
|
112
|
+
* @param {string} [info.driver] - file|redis.
|
|
113
|
+
* @param {'created'|'destroyed'} info.event
|
|
114
|
+
* @returns {void}
|
|
115
|
+
*/
|
|
116
|
+
export function recordSession({ driver, event }: {
|
|
117
|
+
driver?: string;
|
|
118
|
+
event: "created" | "destroyed";
|
|
119
|
+
}): void;
|
|
120
|
+
/**
|
|
121
|
+
* 브루트포스 이벤트 1건 기록(check|fail|lockout|reset). MegaBruteForce 가 호출.
|
|
122
|
+
* subject(이메일·IP)는 **라벨에 절대 안 넣는다** — 카디널리티 폭증 + PII. namespace 만 라벨.
|
|
123
|
+
* @param {object} info
|
|
124
|
+
* @param {string} info.namespace - 도메인 네임스페이스(login|password-reset|…).
|
|
125
|
+
* @param {'check'|'fail'|'lockout'|'reset'} info.event
|
|
126
|
+
* @returns {void}
|
|
127
|
+
*/
|
|
128
|
+
export function recordBruteForce({ namespace, event }: {
|
|
129
|
+
namespace: string;
|
|
130
|
+
event: "check" | "fail" | "lockout" | "reset";
|
|
131
|
+
}): void;
|
|
132
|
+
/**
|
|
133
|
+
* 파일 업로드 결과 1건 기록. multipart 통합(`src/core/multipart.js`)이 호출.
|
|
134
|
+
*
|
|
135
|
+
* - 카운터 `mega_upload_files_total{app,result}` +1 — result 는 **bounded enum** 만:
|
|
136
|
+
* `accepted`(MIME 화이트리스트 통과) / `rejected_mime`(비허용 MIME) / `saved`(디스크 저장 완료).
|
|
137
|
+
* 파일명·MIME 문자열은 라벨에 **안 넣는다** — 카디널리티 폭증·PII 방지. 크기 초과(413)·개수
|
|
138
|
+
* 초과(413)는 @fastify/multipart 가 네이티브로 throw 하므로 `mega_http_requests_total{status_code="413"}`
|
|
139
|
+
* 로 이미 관측된다(중복 집계 안 함).
|
|
140
|
+
* - `bytes` 가 주어지면 히스토그램 `mega_upload_file_bytes{app}` 에 분포 기록(저장 완료 시점).
|
|
141
|
+
*
|
|
142
|
+
* @param {object} info
|
|
143
|
+
* @param {string} [info.app] - 앱 이름.
|
|
144
|
+
* @param {'accepted'|'rejected_mime'|'saved'} info.result - 업로드 결과(bounded enum).
|
|
145
|
+
* @param {number} [info.bytes] - 파일 크기(바이트). 있으면 히스토그램 기록.
|
|
146
|
+
* @returns {void}
|
|
147
|
+
*/
|
|
148
|
+
export function recordUpload({ app, result, bytes }: {
|
|
149
|
+
app?: string;
|
|
150
|
+
result: "accepted" | "rejected_mime" | "saved";
|
|
151
|
+
bytes?: number;
|
|
152
|
+
}): void;
|
|
153
|
+
/**
|
|
154
|
+
* i18n 이벤트 1건 집계(ADR-135). init 전이면 no-op.
|
|
155
|
+
*
|
|
156
|
+
* - `event='request'`: 요청별 결정 언어 분포(앱·언어 라벨). onRequest 1회.
|
|
157
|
+
* - `event='missing'`: 누락 키(dev saveMissing 신호 — 앱·언어·scope 라벨). 키 자체는 라벨 미노출(카디널리티).
|
|
158
|
+
*
|
|
159
|
+
* lang/scope 는 `available`·{server,client} 로 bounded 라 카디널리티 안전.
|
|
160
|
+
*
|
|
161
|
+
* @param {object} info
|
|
162
|
+
* @param {string} [info.app] - 앱 이름.
|
|
163
|
+
* @param {string} info.lang - 결정/요청 언어.
|
|
164
|
+
* @param {string} [info.scope] - namespace scope(missing 시 server|client). request 면 생략.
|
|
165
|
+
* @param {'request'|'missing'} info.event
|
|
166
|
+
* @returns {void}
|
|
167
|
+
*/
|
|
168
|
+
export function recordI18n({ app, lang, scope, event }: {
|
|
169
|
+
app?: string;
|
|
170
|
+
lang: string;
|
|
171
|
+
scope?: string;
|
|
172
|
+
event: "request" | "missing";
|
|
173
|
+
}): void;
|
|
174
|
+
/**
|
|
175
|
+
* 템플릿 렌더 1건 기록(ADR-136). init 전이면 no-op. 템플릿 통합(`src/core/template.js`)이 호출.
|
|
176
|
+
*
|
|
177
|
+
* - 카운터 `mega_template_renders_total{app,result}` +1 — result 는 **bounded enum** 만:
|
|
178
|
+
* `rendered`(성공) / `error`(렌더 실패 — 문법 오류·파일 없음·참조 throw). view 이름·경로는 라벨에
|
|
179
|
+
* **안 넣는다** — 카디널리티 폭증·경로 노출 방지(upload/i18n 패턴 정합).
|
|
180
|
+
* - `durationMs` 가 주어지면 히스토그램 `mega_template_render_duration_seconds{app}` 에 분포 기록.
|
|
181
|
+
* - `bytes` 는 span 속성으로만 남기고 메트릭 라벨엔 안 쓴다(렌더 시간이 운영 신호 — 크기는 응답 메트릭과 중복).
|
|
182
|
+
*
|
|
183
|
+
* @param {object} info
|
|
184
|
+
* @param {string} [info.app] - 앱 이름.
|
|
185
|
+
* @param {'rendered'|'error'} info.result - 렌더 결과(bounded enum).
|
|
186
|
+
* @param {number} [info.durationMs] - 렌더 소요(ms). 있으면 히스토그램 기록(초 단위 변환).
|
|
187
|
+
* @param {number} [info.bytes] - 렌더 바이트(현재 메트릭 미사용 — 시그니처 호환·향후 확장용).
|
|
188
|
+
* @returns {void}
|
|
189
|
+
*/
|
|
190
|
+
export function recordTemplate({ app, result, durationMs }: {
|
|
191
|
+
app?: string;
|
|
192
|
+
result: "rendered" | "error";
|
|
193
|
+
durationMs?: number;
|
|
194
|
+
bytes?: number;
|
|
195
|
+
}): void;
|
|
196
|
+
/**
|
|
197
|
+
* 단일 어댑터의 `onCallEnd` 를 구독해 호출 메트릭으로 변환한다. init 전이면 no-op. 중복 구독 방지.
|
|
198
|
+
* @param {import('../adapters/mega-adapter.js').MegaAdapter} adapter
|
|
199
|
+
* @param {{ domain?: string, driver?: string, key?: string }} [meta]
|
|
200
|
+
* @returns {() => void} 구독 해제 함수.
|
|
201
|
+
*/
|
|
202
|
+
export function subscribe(adapter: import("../adapters/mega-adapter.js").MegaAdapter, meta?: {
|
|
203
|
+
domain?: string;
|
|
204
|
+
driver?: string;
|
|
205
|
+
key?: string;
|
|
206
|
+
}): () => void;
|
|
207
|
+
/**
|
|
208
|
+
* 부팅된 전역 어댑터 매니저의 모든 공유 어댑터에 onCallEnd 리스너를 일괄 구독한다(트레이싱 attachToManager 대칭).
|
|
209
|
+
* @param {{ entries: () => Array<{ domain: string, key: string, driver: string, adapter: import('../adapters/mega-adapter.js').MegaAdapter }> }} manager
|
|
210
|
+
* @returns {number} 구독한 어댑터 수.
|
|
211
|
+
*/
|
|
212
|
+
export function attachToManager(manager: {
|
|
213
|
+
entries: () => Array<{
|
|
214
|
+
domain: string;
|
|
215
|
+
key: string;
|
|
216
|
+
driver: string;
|
|
217
|
+
adapter: import("../adapters/mega-adapter.js").MegaAdapter;
|
|
218
|
+
}>;
|
|
219
|
+
}): number;
|
|
220
|
+
/**
|
|
221
|
+
* 잡 워커(또는 큐)의 이벤트를 구독해 잡 메트릭(`mega_jobs_total`)으로 변환한다(어댑터 {@link subscribe} 대칭).
|
|
222
|
+
* `init` 전이면 **no-op**(0 비용 — 빈 해제 함수 반환). 같은 emitter 를 다시 구독하면 기존 해제 함수를 반환해
|
|
223
|
+
* **중복 부착을 방지**한다(어댑터 subscribe 와 동일 정책).
|
|
224
|
+
*
|
|
225
|
+
* `MegaJobWorker` 는 하부 `MegaJobQueue` 의 이벤트를 그대로 재방출(forward)하므로, **워커 1곳만 구독하면**
|
|
226
|
+
* 그 워커가 든 모든 bus 큐의 잡이 집계된다. `MegaJobQueue` 를 직접 구독해도 동일하게 동작한다(둘 다 같은
|
|
227
|
+
* 이벤트명을 방출). queue 라벨 = 이벤트 payload 의 `subject`.
|
|
228
|
+
*
|
|
229
|
+
* 리스너가 던질 일은 없지만(`recordJob` 은 카운터 add 뿐), 만에 하나 던져도 큐의 `#safeEmit`/워커 forward
|
|
230
|
+
* 가 격리하므로 잡 처리 흐름(ack/nak/DLQ)에는 영향이 없다(M-3 불변식 정합).
|
|
231
|
+
*
|
|
232
|
+
* @param {import('node:events').EventEmitter} emitter - `dispatch/done/retry/dlq` 를 방출하는 MegaJobWorker/MegaJobQueue.
|
|
233
|
+
* @returns {() => void} 구독 해제 함수.
|
|
234
|
+
*/
|
|
235
|
+
export function subscribeJobs(emitter: import("node:events").EventEmitter): () => void;
|
|
236
|
+
/**
|
|
237
|
+
* 클라이언트 IP 가 allowList 에 허용되는지 (Boolean — `is*`). `/metrics` 엔드포인트 접근 제어용(ADR-072
|
|
238
|
+
* 면제 위에 추가 인증). allowList 항목은 **정확한 IP**(IPv4/IPv6) 또는 **IPv4 CIDR**(`10.0.0.0/8`).
|
|
239
|
+
* 빈 list/미지정이면 **모두 허용**(메인 포트 노출 — 사이드카/내부망 전제, 운영자 결정).
|
|
240
|
+
*
|
|
241
|
+
* IPv6 CIDR 는 미지원(정확 매치만) — 필요 시 후속 확장. 잘못된 CIDR 항목은 매치 실패로 간주(조용히
|
|
242
|
+
* 통과시키지 않음 = fail-closed 방향).
|
|
243
|
+
*
|
|
244
|
+
* @param {string} ip - 클라이언트 IP(Fastify `req.ip`). IPv4-mapped IPv6(`::ffff:1.2.3.4`)는 IPv4 로 정규화.
|
|
245
|
+
* @param {string[]} [allowList] - 허용 IP/CIDR 목록.
|
|
246
|
+
* @returns {boolean}
|
|
247
|
+
*/
|
|
248
|
+
export function isIpAllowed(ip: string, allowList?: string[]): boolean;
|
|
249
|
+
/**
|
|
250
|
+
* 테스트 격리용 reset — 동기 강제 정리(provider flush 없이 상태만 비움). 정상 종료는 `shutdown`.
|
|
251
|
+
* @returns {void}
|
|
252
|
+
*/
|
|
253
|
+
export function _reset(): void;
|
|
254
|
+
/** Prometheus 텍스트 노출 포맷 content-type (exposition format 0.0.4). */
|
|
255
|
+
export const PROM_CONTENT_TYPE: "text/plain; version=0.0.4; charset=utf-8";
|
|
256
|
+
export type MetricsState = {
|
|
257
|
+
provider: import("@opentelemetry/sdk-metrics").MeterProvider;
|
|
258
|
+
/**
|
|
259
|
+
* - MetricReader(=PrometheusExporter, preventServerStart).
|
|
260
|
+
*/
|
|
261
|
+
reader: PrometheusExporter;
|
|
262
|
+
serializer: PrometheusSerializer;
|
|
263
|
+
/**
|
|
264
|
+
* - 생성된 인스트루먼트 묶음.
|
|
265
|
+
*/
|
|
266
|
+
m: Instruments;
|
|
267
|
+
};
|
|
268
|
+
export type Instruments = {
|
|
269
|
+
httpRequests: import("@opentelemetry/api").Counter;
|
|
270
|
+
httpDuration: import("@opentelemetry/api").Histogram;
|
|
271
|
+
wsMessages: import("@opentelemetry/api").Counter;
|
|
272
|
+
wsDuration: import("@opentelemetry/api").Histogram;
|
|
273
|
+
adapterCalls: import("@opentelemetry/api").Counter;
|
|
274
|
+
adapterDuration: import("@opentelemetry/api").Histogram;
|
|
275
|
+
jobs: import("@opentelemetry/api").Counter;
|
|
276
|
+
sessions: import("@opentelemetry/api").Counter;
|
|
277
|
+
bruteforce: import("@opentelemetry/api").Counter;
|
|
278
|
+
uploadFiles: import("@opentelemetry/api").Counter;
|
|
279
|
+
uploadBytes: import("@opentelemetry/api").Histogram;
|
|
280
|
+
i18n: import("@opentelemetry/api").Counter;
|
|
281
|
+
templateRenders: import("@opentelemetry/api").Counter;
|
|
282
|
+
templateDuration: import("@opentelemetry/api").Histogram;
|
|
283
|
+
};
|
|
284
|
+
import { PrometheusExporter } from '@opentelemetry/exporter-prometheus';
|
|
285
|
+
import { PrometheusSerializer } from '@opentelemetry/exporter-prometheus';
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `plugins` 배열을 순서대로 로딩한다 — resolve → shape 검증 → apiVersion 체크 → `install(mega, options)`.
|
|
3
|
+
*
|
|
4
|
+
* 02-architecture §14 부팅 시퀀스 4·5단계. 배열에 **명시된 것만** 로딩(auto-discovery X) → 배열에 없는
|
|
5
|
+
* 패키지는 `node_modules` 에 있어도 `install` 이 호출되지 않는다(ADR-079). 어느 단계든 실패하면
|
|
6
|
+
* `MegaConfigError` 로 fail-fast(부팅 중단, silent skip 금지).
|
|
7
|
+
*
|
|
8
|
+
* @param {MegaPluginsConfig | null | undefined} plugins -
|
|
9
|
+
* `Array<string | { name, options }>`. 테스트·프로그램 편의로 **인라인 플러그인 객체**(`install` 함수
|
|
10
|
+
* 보유)도 원소로 허용한다.
|
|
11
|
+
* @param {MegaPluginHost} host - 코어가 만든 hook 컨텍스트.
|
|
12
|
+
* @param {{ projectRoot?: string, importer?: (spec: string) => Promise<MegaPlugin>, logger?: { debug?: Function } }} [opts] -
|
|
13
|
+
* `projectRoot` 는 로컬 경로(`./...`) 해석 기준. `importer` 주입 시 모듈 해석을 가로채(테스트). `logger`
|
|
14
|
+
* 는 길목 debug 로그.
|
|
15
|
+
* @returns {Promise<LoadedPluginMeta[]>} 로딩된 플러그인 메타 목록(등록 순서).
|
|
16
|
+
* @throws {MegaConfigError} 잘못된 config/entry/shape/apiVersion/로드 실패/중복 플러그인(plugin.duplicate_plugin).
|
|
17
|
+
* @throws {TypeError} host 가 MegaPluginHost 인스턴스가 아님.
|
|
18
|
+
*/
|
|
19
|
+
export function loadPlugins(plugins: MegaPluginsConfig | null | undefined, host: MegaPluginHost, { projectRoot, importer, logger }?: {
|
|
20
|
+
projectRoot?: string;
|
|
21
|
+
importer?: (spec: string) => Promise<MegaPlugin>;
|
|
22
|
+
logger?: {
|
|
23
|
+
debug?: Function;
|
|
24
|
+
};
|
|
25
|
+
}): Promise<LoadedPluginMeta[]>;
|
|
26
|
+
/**
|
|
27
|
+
* 코어 플러그인 API 계약 메이저 버전 (ADR-122). npm 패키지 버전(`package.json`, 현재 pre-1.0 `0.x`)과
|
|
28
|
+
* **분리**한다 — 패키지 0.x 는 자주 바뀌어 거기 묶으면 0.x bump 마다 모든 플러그인이 깨진다. 플러그인은
|
|
29
|
+
* 코어 *내부 구조*가 아니라 *공개 hook 계약*에 의존하므로, 계약이 바뀔 때만 올리는 독립 버전이 맞다.
|
|
30
|
+
* 03-api-spec/02-architecture 의 예시(`apiVersion: '1'`)와도 정합.
|
|
31
|
+
* @type {string}
|
|
32
|
+
*/
|
|
33
|
+
export const CORE_API_VERSION: string;
|
|
34
|
+
/**
|
|
35
|
+
* @typedef {Object} MegaPlugin
|
|
36
|
+
* @property {string} name - npm 패키지명 또는 식별자.
|
|
37
|
+
* @property {string} version - semver (예: '1.0.0').
|
|
38
|
+
* @property {string} apiVersion - 코어 API 계약 메이저 버전. mismatch 시 부팅 throw.
|
|
39
|
+
* @property {(mega: MegaPluginHost, options?: object) => void | Promise<void>} install
|
|
40
|
+
*/
|
|
41
|
+
/**
|
|
42
|
+
* @typedef {Object} MegaCliCommandDef
|
|
43
|
+
* @property {string} description
|
|
44
|
+
* @property {(args: object) => unknown} handler - 03-api-spec 은 `Promise<void>|void` 로 적었으나,
|
|
45
|
+
* 핸들러가 결과(예: exit code·출력)를 반환할 수 있게 `unknown` 으로 넓힘(CLI 가 소비).
|
|
46
|
+
*/
|
|
47
|
+
/**
|
|
48
|
+
* 플러그인 scaffold generator manifest(03-api-spec §11) — `mega g <name>` 이 소비한다(ADR-187/199).
|
|
49
|
+
* `dir` 는 프로젝트 루트 상대 출력 기준, `files[].path`/`files[].template` 의 `{{token}}` 은
|
|
50
|
+
* cli/generators 의 `SCAFFOLD_TOKENS` 계약(Name/name/camelName/snake/app)으로 치환된다.
|
|
51
|
+
* @typedef {Object} MegaScaffoldDef
|
|
52
|
+
* @property {string} dir
|
|
53
|
+
* @property {Array<{ path: string, template: string }>} files
|
|
54
|
+
* @property {string} [description] - `mega help` 가 병기하는 한 줄 설명(선택).
|
|
55
|
+
*/
|
|
56
|
+
/** 빌트인 generator 이름 — 플러그인 scaffold 가 점유 금지(빌트인이 우선이라 silent shadow 가 됨).
|
|
57
|
+
* cli/generators 의 `GENERATOR_KINDS` 와 동일해야 한다(레이어 역전 회피를 위해 미러 — 동기화는
|
|
58
|
+
* mega-plugin 단위 테스트가 GENERATOR_KINDS 와 집합 비교로 강제한다). */
|
|
59
|
+
export const RESERVED_GENERATOR_NAMES: Set<string>;
|
|
60
|
+
/**
|
|
61
|
+
* @typedef {Object} LoadedPluginMeta
|
|
62
|
+
* @property {string} name
|
|
63
|
+
* @property {string} version
|
|
64
|
+
* @property {string} apiVersion
|
|
65
|
+
*/
|
|
66
|
+
/**
|
|
67
|
+
* `mega.config.js` 의 `plugins` 배열 (04-data-models §1.1 MegaPluginsConfig).
|
|
68
|
+
* @typedef {Array<string | { name: string, options?: object }>} MegaPluginsConfig
|
|
69
|
+
*/
|
|
70
|
+
/**
|
|
71
|
+
* `MegaPluginContext` — `install(mega)` 가 받는 `mega` 인자(03-api-spec §11).
|
|
72
|
+
*
|
|
73
|
+
* 코어 hook 의 등록 표면을 dot-notation(`mega.adapters.register(...)`)으로 노출하고, 등록 결과를
|
|
74
|
+
* 내부 레지스트리에 수집한다. 수집물은 getter/list 메서드로 queryable 하다(후속 Step 이 소비).
|
|
75
|
+
*/
|
|
76
|
+
export class MegaPluginHost {
|
|
77
|
+
/**
|
|
78
|
+
* @param {{ logger?: { debug?: Function } }} [opts] - 길목 debug 로그용(선택). 순수 등록 유틸이라
|
|
79
|
+
* 미주입이 기본 — 미주입 시 no-op.
|
|
80
|
+
*/
|
|
81
|
+
constructor({ logger }?: {
|
|
82
|
+
logger?: {
|
|
83
|
+
debug?: Function;
|
|
84
|
+
};
|
|
85
|
+
});
|
|
86
|
+
/** 3rd party 어댑터 등록 (ADR-044) — 실 드라이버 레지스트리에 즉시 위임. */
|
|
87
|
+
adapters: {
|
|
88
|
+
/** @param {string} driver @param {Function} AdapterClass */
|
|
89
|
+
register: (driver: string, AdapterClass: Function) => void;
|
|
90
|
+
};
|
|
91
|
+
/** CLI 명령 등록 — `mega <name>`(소비는 CLI). */
|
|
92
|
+
cli: {
|
|
93
|
+
/** @param {string} name @param {MegaCliCommandDef} opts */
|
|
94
|
+
command: (name: string, opts: MegaCliCommandDef) => void;
|
|
95
|
+
};
|
|
96
|
+
/** Fastify 플러그인을 모든 앱에 등록(소비는 부팅 orchestrator). */
|
|
97
|
+
app: {
|
|
98
|
+
/** @param {Function} fastifyPlugin @param {object} [opts] */
|
|
99
|
+
use: (fastifyPlugin: Function, opts?: object) => void;
|
|
100
|
+
};
|
|
101
|
+
/** 글로벌 미들웨어 등록(소비는 라우트 파이프라인). */
|
|
102
|
+
middlewares: {
|
|
103
|
+
/** @param {Function} mw */
|
|
104
|
+
global: (mw: Function) => void;
|
|
105
|
+
};
|
|
106
|
+
/** 스캐폴드 generator 등록 — `mega g <name>`(소비는 CLI). */
|
|
107
|
+
scaffold: {
|
|
108
|
+
/** @param {string} name @param {MegaScaffoldDef} def */
|
|
109
|
+
register: (name: string, def: MegaScaffoldDef) => void;
|
|
110
|
+
};
|
|
111
|
+
/** 코어 lib 노출 — `ctx.lib.<name>`(소비는 ctx 빌더). */
|
|
112
|
+
lib: {
|
|
113
|
+
/** @param {string} name @param {Function} Class */
|
|
114
|
+
register: (name: string, Class: Function) => void;
|
|
115
|
+
};
|
|
116
|
+
/** 잡 등록 — `mega worker` 가 `config.jobs` 정적 등록분과 함께 흡수(ADR-123). */
|
|
117
|
+
jobs: {
|
|
118
|
+
/** @param {Function} JobClass - MegaJob 서브클래스. */
|
|
119
|
+
register: (JobClass: Function) => void;
|
|
120
|
+
};
|
|
121
|
+
/** 스케줄 등록 — `mega scheduler` 가 `config.schedules` 정적 등록분과 함께 흡수(ADR-123). */
|
|
122
|
+
schedules: {
|
|
123
|
+
/** @param {Function} TaskClass - MegaSchedule 서브클래스. */
|
|
124
|
+
register: (TaskClass: Function) => void;
|
|
125
|
+
};
|
|
126
|
+
/** 워커 등록 — `buildWorkers` 가 `config.workers` 정적 등록분과 함께 흡수(ADR-134). */
|
|
127
|
+
workers: {
|
|
128
|
+
/** @param {Function} WorkerClass - MegaWorker 서브클래스. */
|
|
129
|
+
register: (WorkerClass: Function) => void;
|
|
130
|
+
};
|
|
131
|
+
/**
|
|
132
|
+
* 라이프사이클 이벤트 구독. 미지정 이벤트는 `RangeError`(오타 차단 — 형제 MegaScheduler `on` 정책).
|
|
133
|
+
* hook 은 부팅 orchestrator 가 넘기는 boot context 를 선택적으로 받는다(L-2/ADR-123, `(ctx?) => ...`).
|
|
134
|
+
* @param {'beforeBoot' | 'afterBoot' | 'beforeShutdown'} event
|
|
135
|
+
* @param {(ctx?: object) => Promise<void> | void} fn
|
|
136
|
+
* @returns {this}
|
|
137
|
+
*/
|
|
138
|
+
on(event: "beforeBoot" | "afterBoot" | "beforeShutdown", fn: (ctx?: object) => Promise<void> | void): this;
|
|
139
|
+
/**
|
|
140
|
+
* 한 lifecycle 단계의 구독 hook 을 **등록 순서대로** 실행한다(부팅 orchestrator 가 호출).
|
|
141
|
+
* beforeBoot/afterBoot 는 fail-fast(에러 전파)로 부팅을 멈춘다. beforeShutdown 은 graceful
|
|
142
|
+
* shutdown 경로에서 보통 `MegaShutdown.register`(per-hook catch)로 브리지된다(ADR-122).
|
|
143
|
+
*
|
|
144
|
+
* **L-2(ADR-123)**: 부팅 orchestrator 가 boot context(`{ config, log, db/cache/bus/lock }`)를
|
|
145
|
+
* 인자로 넘기면 각 hook 이 `fn(ctx)` 로 받는다. ctx 미주입 시 `undefined` 전달(03-api-spec 의
|
|
146
|
+
* `() => void` 시그니처와 하위 호환 — 인자 안 받는 hook 은 그대로 동작).
|
|
147
|
+
* @param {'beforeBoot' | 'afterBoot' | 'beforeShutdown'} event
|
|
148
|
+
* @param {object} [ctx] - boot context(L-2). orchestrator 가 주입, 미주입 시 undefined.
|
|
149
|
+
* @returns {Promise<void>}
|
|
150
|
+
*/
|
|
151
|
+
runLifecycle(event: "beforeBoot" | "afterBoot" | "beforeShutdown", ctx?: object): Promise<void>;
|
|
152
|
+
/**
|
|
153
|
+
* loadPlugins 가 install 성공 후 메타를 기록한다(framework-internal).
|
|
154
|
+
* @param {LoadedPluginMeta} meta
|
|
155
|
+
* @returns {void}
|
|
156
|
+
*/
|
|
157
|
+
_recordLoaded(meta: LoadedPluginMeta): void;
|
|
158
|
+
/** 등록 순서대로 install 된 플러그인 메타 목록. @returns {LoadedPluginMeta[]} */
|
|
159
|
+
get loadedPlugins(): LoadedPluginMeta[];
|
|
160
|
+
/** 등록된 CLI 명령 이름 목록. @returns {string[]} */
|
|
161
|
+
listCommands(): string[];
|
|
162
|
+
/** CLI 명령 정의 조회(없으면 undefined). @param {string} name @returns {MegaCliCommandDef | undefined} */
|
|
163
|
+
getCommand(name: string): MegaCliCommandDef | undefined;
|
|
164
|
+
/** CLI 명령 존재 여부. @param {string} name @returns {boolean} */
|
|
165
|
+
hasCommand(name: string): boolean;
|
|
166
|
+
/** 등록된 스캐폴드 generator 이름 목록. @returns {string[]} */
|
|
167
|
+
listGenerators(): string[];
|
|
168
|
+
/** 스캐폴드 generator 정의 조회. @param {string} name @returns {MegaScaffoldDef | undefined} */
|
|
169
|
+
getGenerator(name: string): MegaScaffoldDef | undefined;
|
|
170
|
+
/** 등록된 lib 이름 목록. @returns {string[]} */
|
|
171
|
+
listLibs(): string[];
|
|
172
|
+
/** lib 클래스 조회. @param {string} name @returns {Function | undefined} */
|
|
173
|
+
getLib(name: string): Function | undefined;
|
|
174
|
+
/** 플러그인이 등록한 잡 클래스 목록(복사본 — `mega worker` 가 소비). @returns {Function[]} */
|
|
175
|
+
listJobs(): Function[];
|
|
176
|
+
/** 플러그인이 등록한 스케줄 클래스 목록(복사본 — `mega scheduler` 가 소비). @returns {Function[]} */
|
|
177
|
+
listSchedules(): Function[];
|
|
178
|
+
/** 플러그인이 등록한 워커 클래스 목록(복사본 — `buildWorkers` 가 소비). @returns {Function[]} */
|
|
179
|
+
listWorkers(): Function[];
|
|
180
|
+
/** 등록된 Fastify 플러그인 목록(복사본). @returns {Array<{ plugin: Function, opts: object | undefined }>} */
|
|
181
|
+
get fastifyPlugins(): Array<{
|
|
182
|
+
plugin: Function;
|
|
183
|
+
opts: object | undefined;
|
|
184
|
+
}>;
|
|
185
|
+
/** 등록된 글로벌 미들웨어 목록(복사본). @returns {Function[]} */
|
|
186
|
+
get globalMiddlewares(): Function[];
|
|
187
|
+
/**
|
|
188
|
+
* 한 lifecycle 단계의 구독 hook 목록(복사본).
|
|
189
|
+
* @param {'beforeBoot' | 'afterBoot' | 'beforeShutdown'} event
|
|
190
|
+
* @returns {Function[]}
|
|
191
|
+
*/
|
|
192
|
+
lifecycleHooks(event: "beforeBoot" | "afterBoot" | "beforeShutdown"): Function[];
|
|
193
|
+
#private;
|
|
194
|
+
}
|
|
195
|
+
export type MegaPlugin = {
|
|
196
|
+
/**
|
|
197
|
+
* - npm 패키지명 또는 식별자.
|
|
198
|
+
*/
|
|
199
|
+
name: string;
|
|
200
|
+
/**
|
|
201
|
+
* - semver (예: '1.0.0').
|
|
202
|
+
*/
|
|
203
|
+
version: string;
|
|
204
|
+
/**
|
|
205
|
+
* - 코어 API 계약 메이저 버전. mismatch 시 부팅 throw.
|
|
206
|
+
*/
|
|
207
|
+
apiVersion: string;
|
|
208
|
+
install: (mega: MegaPluginHost, options?: object) => void | Promise<void>;
|
|
209
|
+
};
|
|
210
|
+
export type MegaCliCommandDef = {
|
|
211
|
+
description: string;
|
|
212
|
+
/**
|
|
213
|
+
* - 03-api-spec 은 `Promise<void>|void` 로 적었으나,
|
|
214
|
+
* 핸들러가 결과(예: exit code·출력)를 반환할 수 있게 `unknown` 으로 넓힘(CLI 가 소비).
|
|
215
|
+
*/
|
|
216
|
+
handler: (args: object) => unknown;
|
|
217
|
+
};
|
|
218
|
+
/**
|
|
219
|
+
* 플러그인 scaffold generator manifest(03-api-spec §11) — `mega g <name>` 이 소비한다(ADR-187/199).
|
|
220
|
+
* `dir` 는 프로젝트 루트 상대 출력 기준, `files[].path`/`files[].template` 의 `{{token}}` 은
|
|
221
|
+
* cli/generators 의 `SCAFFOLD_TOKENS` 계약(Name/name/camelName/snake/app)으로 치환된다.
|
|
222
|
+
*/
|
|
223
|
+
export type MegaScaffoldDef = {
|
|
224
|
+
dir: string;
|
|
225
|
+
files: Array<{
|
|
226
|
+
path: string;
|
|
227
|
+
template: string;
|
|
228
|
+
}>;
|
|
229
|
+
/**
|
|
230
|
+
* - `mega help` 가 병기하는 한 줄 설명(선택).
|
|
231
|
+
*/
|
|
232
|
+
description?: string;
|
|
233
|
+
};
|
|
234
|
+
export type LoadedPluginMeta = {
|
|
235
|
+
name: string;
|
|
236
|
+
version: string;
|
|
237
|
+
apiVersion: string;
|
|
238
|
+
};
|
|
239
|
+
/**
|
|
240
|
+
* `mega.config.js` 의 `plugins` 배열 (04-data-models §1.1 MegaPluginsConfig).
|
|
241
|
+
*/
|
|
242
|
+
export type MegaPluginsConfig = Array<string | {
|
|
243
|
+
name: string;
|
|
244
|
+
options?: object;
|
|
245
|
+
}>;
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {Object} MegaRetryOptions
|
|
3
|
+
* @property {number} [retries=10] - 최대 **추가** 재시도 횟수(첫 시도 제외). Infinity 허용.
|
|
4
|
+
* @property {number} [minTimeout=1000] - 첫 백오프 지연(ms).
|
|
5
|
+
* @property {number} [maxTimeout=30000] - 백오프 지연 상한(ms).
|
|
6
|
+
* @property {number} [factor=2] - 지수 증가율.
|
|
7
|
+
* @property {boolean} [jitter=true] - 지연에 random[1,2) 곱(thundering herd 완화). false 면 결정적.
|
|
8
|
+
* @property {(ctx: { error: Error, attemptNumber: number, retriesLeft: number, retryDelay: number }) => void|Promise<void>} [onFailedAttempt]
|
|
9
|
+
* - 매 시도 실패 직후 호출(다음 지연 전). 로그/관측용. throw 하면 재시도 중단.
|
|
10
|
+
* @property {(ctx: { error: Error, attemptNumber: number, retriesLeft: number }) => boolean|Promise<boolean>} [shouldRetry]
|
|
11
|
+
* - false 반환 시 재시도 중단(마지막 에러 throw). 특정 에러만 재시도할 때.
|
|
12
|
+
* @property {AbortSignal} [signal] - abort 시 대기/재시도 즉시 취소.
|
|
13
|
+
* @property {boolean} [unref=true] - 백오프 타이머 unref(프로세스 종료를 막지 않음). 기본 true.
|
|
14
|
+
*/
|
|
15
|
+
/**
|
|
16
|
+
* `fn` 을 지수 백오프로 재시도한다. 성공 시 그 반환값을, 모두 실패하면 마지막 에러를 throw.
|
|
17
|
+
*
|
|
18
|
+
* @template T
|
|
19
|
+
* @param {(attemptNumber: number) => Promise<T>|T} fn - 실행할 작업. attemptNumber(1-based) 를 받는다.
|
|
20
|
+
* @param {MegaRetryOptions} [options]
|
|
21
|
+
* @returns {Promise<T>}
|
|
22
|
+
* @throws {Error} 모든 시도 실패 시 마지막 에러(또는 RetryAbortError 의 원본 에러).
|
|
23
|
+
* @example
|
|
24
|
+
* await withRetry(() => connectToHub(), { retries: 5, minTimeout: 500, maxTimeout: 10_000 })
|
|
25
|
+
*/
|
|
26
|
+
export function withRetry<T>(fn: (attemptNumber: number) => Promise<T> | T, options?: MegaRetryOptions): Promise<T>;
|
|
27
|
+
/**
|
|
28
|
+
* 재시도를 즉시 중단시키는 에러 래퍼 (p-retry `AbortError`). `throw new RetryAbortError(원본에러)`
|
|
29
|
+
* 하면 더 이상 재시도하지 않고 원본 에러가 호출부로 전파된다.
|
|
30
|
+
* @type {typeof AbortError}
|
|
31
|
+
*/
|
|
32
|
+
export const RetryAbortError: typeof AbortError;
|
|
33
|
+
/** 네임스페이스 형태 접근(다른 Mega* 유틸과 일관). `MegaRetry.withRetry(...)`. */
|
|
34
|
+
export const MegaRetry: Readonly<{
|
|
35
|
+
withRetry: typeof withRetry;
|
|
36
|
+
RetryAbortError: typeof AbortError;
|
|
37
|
+
}>;
|
|
38
|
+
export type MegaRetryOptions = {
|
|
39
|
+
/**
|
|
40
|
+
* - 최대 **추가** 재시도 횟수(첫 시도 제외). Infinity 허용.
|
|
41
|
+
*/
|
|
42
|
+
retries?: number;
|
|
43
|
+
/**
|
|
44
|
+
* - 첫 백오프 지연(ms).
|
|
45
|
+
*/
|
|
46
|
+
minTimeout?: number;
|
|
47
|
+
/**
|
|
48
|
+
* - 백오프 지연 상한(ms).
|
|
49
|
+
*/
|
|
50
|
+
maxTimeout?: number;
|
|
51
|
+
/**
|
|
52
|
+
* - 지수 증가율.
|
|
53
|
+
*/
|
|
54
|
+
factor?: number;
|
|
55
|
+
/**
|
|
56
|
+
* - 지연에 random[1,2) 곱(thundering herd 완화). false 면 결정적.
|
|
57
|
+
*/
|
|
58
|
+
jitter?: boolean;
|
|
59
|
+
/**
|
|
60
|
+
* - 매 시도 실패 직후 호출(다음 지연 전). 로그/관측용. throw 하면 재시도 중단.
|
|
61
|
+
*/
|
|
62
|
+
onFailedAttempt?: (ctx: {
|
|
63
|
+
error: Error;
|
|
64
|
+
attemptNumber: number;
|
|
65
|
+
retriesLeft: number;
|
|
66
|
+
retryDelay: number;
|
|
67
|
+
}) => void | Promise<void>;
|
|
68
|
+
/**
|
|
69
|
+
* - false 반환 시 재시도 중단(마지막 에러 throw). 특정 에러만 재시도할 때.
|
|
70
|
+
*/
|
|
71
|
+
shouldRetry?: (ctx: {
|
|
72
|
+
error: Error;
|
|
73
|
+
attemptNumber: number;
|
|
74
|
+
retriesLeft: number;
|
|
75
|
+
}) => boolean | Promise<boolean>;
|
|
76
|
+
/**
|
|
77
|
+
* - abort 시 대기/재시도 즉시 취소.
|
|
78
|
+
*/
|
|
79
|
+
signal?: AbortSignal;
|
|
80
|
+
/**
|
|
81
|
+
* - 백오프 타이머 unref(프로세스 종료를 막지 않음). 기본 true.
|
|
82
|
+
*/
|
|
83
|
+
unref?: boolean;
|
|
84
|
+
};
|
|
85
|
+
import { AbortError } from 'p-retry';
|