import { AsyncLocalStorage } from "async_hooks"; import { type IncomingMessage, type Server, type ServerResponse } from "http"; import { type Auth, type BetterAuthOptions } from "better-auth"; import { type FSWatcher } from "chokidar"; import { type FastifyInstance, type FastifyReply, type FastifyRequest } from "fastify"; import { type CacheManager } from "../cache/types"; import { type SonamuDBConfig } from "../database/db"; import { type StorageManager } from "../storage/storage-manager"; import { WebSocketRuntime } from "../stream/ws"; import { type Syncer } from "../syncer/syncer"; import { type WorkflowManager } from "../tasks/workflow-manager"; import { type DevVitestManager } from "../testing/dev-vitest-manager"; import { type SonamuFastifyConfig } from "../types/types"; import { type AbsolutePath } from "../utils/path-utils"; import { type SonamuConfig } from "./config"; import { type Context, type RuntimeContext, type WebSocketContext } from "./context"; import { type ExtendedApi } from "./decorators"; import { type SonamuSecrets } from "./secret"; export { createWebSocketReplyStub, resolveWebSocketCloseDescriptor, resolveWebSocketPluginOptions, } from "./websocket-helpers"; declare class SonamuClass { isInitialized: boolean; forTesting: boolean; asyncLocalStorage: AsyncLocalStorage<{ context: RuntimeContext; }>; getContext(): T; private _apiRootPath; set apiRootPath(apiRootPath: AbsolutePath); get apiRootPath(): AbsolutePath; get appRootPath(): string; private _dbConfig; set dbConfig(dbConfig: SonamuDBConfig); get dbConfig(): SonamuDBConfig; private _syncer; set syncer(syncer: Syncer); get syncer(): Syncer; private _config; set config(config: SonamuConfig); get config(): SonamuConfig; readonly secrets: SonamuSecrets; private _storage; /** * StorageManager 인스턴스 */ get storage(): StorageManager; private _cache; /** * CacheManager 인스턴스 (BentoCache) */ get cache(): CacheManager; private _workflows; get workflows(): WorkflowManager; private _auth; get auth(): Auth; private _devVitestManager; get devVitestManager(): DevVitestManager | null; set devVitestManager(manager: DevVitestManager | null); private _websocketRuntime; private readonly websocketPluginServers; get websocketRuntime(): WebSocketRuntime; set websocketRuntime(runtime: WebSocketRuntime | null); watcher: FSWatcher | null; server: FastifyInstance | null; initForTesting(): Promise; init(doSilent?: boolean, enableSync?: boolean, apiRootPath?: AbsolutePath, forTesting?: boolean): Promise; private _initElapsed; private _configElapsed; createServer(initOptions?: { enableSync?: boolean; doSilent?: boolean; }): Promise, import("fastify").FastifyBaseLogger, import("fastify").FastifyTypeProviderDefault>>; withFastify(server: FastifyInstance, config: SonamuFastifyConfig, options?: { enableSync?: boolean; doSilent?: boolean; }): Promise; /** * dev 모드 공통: catch-all에서 syncer.apis를 동적으로 탐색하여 API 요청을 처리합니다. * server.route()로 개별 등록하면 handler가 고정되어 HMR이 동작하지 않으므로, * 매 요청마다 syncer.apis를 조회하는 이 방식을 사용합니다. * * 요청이 /api(정확히는 this.config.api.route.prefix)로 시작하지 않는 경우라면 null을 반환하며 끝냅니다. */ private handleDevApiRequest; private findMatchedApi; /** * dev api 모드: Vite 없이 API 동적 라우팅만 제공합니다. * HMR을 위해 catch-all에서 매 요청마다 syncer.apis를 조회합니다. */ private setupDevServer; private viteServer; /** * dev all 모드: Vite Dev Server를 통합하여 API + SSR + CSR을 모두 제공합니다. * API 동적 매칭은 handleDevApiRequest를 공유합니다. */ private setupDevServerWithVite; private setupStaticWebServer; createApiHandler(api: ExtendedApi, config: SonamuFastifyConfig): (request: FastifyRequest, reply: FastifyReply) => Promise; private createWebSocketUpgradeRequiredHandler; private handleDevWebSocketRequest; private createWebSocketHandler; private createScopedWebSocketConnection; private parseWebSocketRequestParams; /** * URL에서 path params를 추출합니다. * 예: pattern="/admin/companies/:companyId", url="/admin/companies/123" → { companyId: "123" } */ private extractPathParams; private isPathPatternMatch; private getPathnameFromUrl; private resolvePathWithinBaseDir; /** * API 응답에 적용할 Cache-Control 설정을 결정합니다. * 우선순위: 개별 지정 > cacheControlHandler */ private getApiCacheControl; /** * SSR용 API 호출 (HTTP 오버헤드 없이 직접 호출) * createApiHandler의 로직을 재사용하되, request 파싱 대신 params 직접 사용 */ invokeApiForSSR(api: ExtendedApi, params: any[], config: SonamuFastifyConfig, request: FastifyRequest, reply: FastifyReply): Promise; invokeModelMethod(api: ExtendedApi, args: unknown[], reply?: FastifyReply): Promise; createContext(config: SonamuFastifyConfig, request: FastifyRequest, reply: FastifyReply): Promise; createWebSocketContext(config: SonamuFastifyConfig, request: FastifyRequest, ws: WebSocketContext["ws"]): Promise; /** * Accept-Language 헤더에서 지원하는 locale을 찾습니다. * @example "ko-KR,ko;q=0.9,en;q=0.8" → "ko" */ private detectLocale; startWatcher(): Promise; /** * Watcher가 100ms batch로 모은 fileEvents 하나에 대해 한 번의 HMR/sync 사이클을 돕니다. * batch 큐잉 덕에 한 시점에 하나만 실행됨이 보장됩니다 (event-batcher가 직렬화). */ private runHmrSyncCycle; runScript(fn: () => Promise): Promise; private registerPlugins; private ensureWebSocketPlugin; private warnOnPotentialWebSocketTimeoutConflicts; /** * better-auth 라우트를 등록합니다. * /api/auth/* 경로로 인증 API가 자동 등록됩니다. */ private registerBetterAuth; private printStartupSummary; private initializeCache; private initializeWorkflows; private boot; destroy(): Promise; } export declare const Sonamu: SonamuClass; //# sourceMappingURL=sonamu.d.ts.map