@nilejs/nile 0.0.2 → 0.0.4

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 CHANGED
@@ -17,6 +17,22 @@ You define actions, group them into services, and get a predictable API with val
17
17
 
18
18
  > Or View Full Docs -> [nile-js.github.io/nile](https://nile-js.github.io/nile)
19
19
 
20
+ ### Scaffold a project (recommended)
21
+
22
+ The fastest way to start is with the CLI. It creates a working project with services, database, and dev tooling pre-configured:
23
+
24
+ ```bash
25
+ npx @nilejs/cli new my-app
26
+ ```
27
+
28
+ ```bash
29
+ cd my-app && bun install && bun run dev
30
+ ```
31
+
32
+ The CLI also includes generators for adding services, actions, and extracting Zod schemas with TypeScript types. See [`@nilejs/cli`](./cli/README.md) for details.
33
+
34
+ ### Manual install
35
+
20
36
  ```bash
21
37
  bun add @nilejs/nile zod slang-ts
22
38
  ```
package/dist/index.cjs CHANGED
@@ -1409,7 +1409,7 @@ function createNileServer(config) {
1409
1409
  });
1410
1410
  server.rest = { app, config: config.rest };
1411
1411
  const host = config.rest.host ?? "localhost";
1412
- const port = config.rest.port ?? 3e3;
1412
+ const port = config.rest.port ?? 8e3;
1413
1413
  const base = `http://${host}:${port}`;
1414
1414
  console.log(`
1415
1415
  POST ${base}${config.rest.baseUrl}/services`);
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/engine/create-action.ts","../src/engine/create-service.ts","../src/logging/logger.ts","../src/logging/create-log.ts","../src/nile/server.ts","../src/engine/engine.ts","../src/utils/db/create-model.ts","../src/utils/handle-error.ts","../src/utils/db/create-transaction-variant.ts","../src/utils/db/get-zod-schema.ts","../src/utils/diagnostics-log.ts","../src/engine/pipeline.ts","../src/rest/rest.ts","../src/cors/cors.ts","../src/rest/intent-handlers.ts","../src/rest/middleware.ts","../src/nile/nile.ts"],"sourcesContent":["// CORS types — origin control, per-route rules, and resolver functions\nexport type {\n CorsConfig,\n CorsOptions,\n CorsResolver,\n CorsRouteRule,\n} from \"./cors/types\";\n// Engine utilities — action and service factory functions\nexport { createAction, createActions } from \"./engine/create-action\";\nexport { createService, createServices } from \"./engine/create-service\";\n// Engine types — defining services, actions, hooks, and the engine interface\nexport type {\n Action,\n ActionHandler,\n ActionResultConfig,\n ActionSummary,\n Actions,\n Engine,\n EngineOptions,\n HookContext,\n HookDefinition,\n HookLogEntry,\n Service,\n ServiceSummary,\n Services,\n} from \"./engine/types\";\n\n// Logging — structured log persistence with chunking support\nexport {\n createLog,\n createLogger,\n getLogs,\n type Log,\n type LogFilter,\n type LoggerConfig,\n} from \"./logging\";\n// Server factory — the main entry point for developers\nexport { createNileServer, getContext } from \"./nile/server\";\n// Nile types — server config, context, request/response, and lifecycle hooks\nexport type {\n AfterActionHandler,\n BaseContext,\n BeforeActionHandler,\n ExternalRequest,\n ExternalResponse,\n NileContext,\n NileLogger,\n NileServer,\n Resources,\n RPCContext,\n ServerConfig,\n ServerRuntime,\n Sessions,\n WebSocketContext,\n} from \"./nile/types\";\n// REST types — REST interface and rate limiting configuration\nexport type { RateLimitConfig, RestConfig } from \"./rest/types\";\n// Utilities — error handling, diagnostics, and database helpers\nexport {\n type CursorPage,\n type CursorPaginationOptions,\n createModel,\n createTransactionVariant,\n type DBParams,\n type DBX,\n getZodSchema,\n handleError,\n type ModelOperations,\n type ModelOptions,\n type OffsetPage,\n type OffsetPaginationOptions,\n} from \"./utils\";\n","import type { Action } from \"./types\";\n\n/**\n * Typed identity for defining a single action with full type inference.\n * No runtime overhead — returns the config object as-is.\n */\nexport function createAction(config: Action): Action {\n return config;\n}\n\n/**\n * Typed identity for defining multiple actions with full type inference.\n * No runtime overhead — returns the config array as-is.\n */\nexport function createActions(configs: Action[]): Action[] {\n return configs;\n}\n","import type { Service } from \"./types\";\n\n/**\n * Typed identity for defining a service with full type inference.\n * No runtime overhead — returns the config object as-is.\n */\nexport function createService(config: Service): Service {\n return config;\n}\n\n/**\n * Typed identity for defining multiple services with full type inference.\n * No runtime overhead — returns the config array as-is.\n */\nexport function createServices(configs: Service[]): Service[] {\n return configs;\n}\n","import {\n appendFileSync,\n existsSync,\n mkdirSync,\n readdirSync,\n readFileSync,\n} from \"node:fs\";\nimport { join } from \"node:path\";\nimport { nanoid } from \"nanoid\";\nimport pino, { type Logger } from \"pino\";\n\nexport interface Log {\n atFunction: string;\n appName: string;\n message: string;\n data?: unknown;\n level?: \"info\" | \"warn\" | \"error\";\n log_id?: string;\n}\n\n/** Configuration for log file chunking behavior */\nexport interface LoggerConfig {\n /** Time-based chunking strategy. Default: 'none' (single file per app) */\n chunking?: \"monthly\" | \"daily\" | \"weekly\" | \"none\";\n}\n\n// Lazy evaluation of MODE - only check when logging is actually used\nconst getMode = () => {\n if (!process.env.MODE) {\n throw new Error(\"Missing MODE environment variable\");\n }\n return process.env.MODE;\n};\n\nconst logDir = join(process.cwd(), \"logs\");\n\nif (!existsSync(logDir)) {\n mkdirSync(logDir);\n}\n\n// Chunk filename patterns — hoisted for performance (used in hot path by getLogs)\nconst MONTHLY_PATTERN = /^(\\d{4})-(\\d{2})$/;\nconst DAILY_PATTERN = /^(\\d{4})-(\\d{2})-(\\d{2})$/;\nconst WEEKLY_PATTERN = /^(\\d{4})-W(\\d{2})$/;\n\n/**\n * Resolves the correct log file path based on app name and chunking config.\n * - 'none' (default): logs/{appName}.log (backwards compatible)\n * - 'monthly': logs/{appName}/YYYY-MM.log\n * - 'daily': logs/{appName}/YYYY-MM-DD.log\n * - 'weekly': logs/{appName}/YYYY-WNN.log (ISO week number)\n */\nexport function resolveLogPath(appName: string, config?: LoggerConfig): string {\n const chunking = config?.chunking ?? \"none\";\n\n if (chunking === \"none\") {\n return join(logDir, `${appName}.log`);\n }\n\n const appDir = join(logDir, appName);\n if (!existsSync(appDir)) {\n mkdirSync(appDir, { recursive: true });\n }\n\n const now = new Date();\n const chunk = formatChunkName(now, chunking);\n return join(appDir, `${chunk}.log`);\n}\n\n/**\n * Formats a date into the correct chunk filename based on chunking strategy.\n * Exported for testing and reuse by getLogs.\n */\nexport function formatChunkName(\n date: Date,\n chunking: \"monthly\" | \"daily\" | \"weekly\"\n): string {\n const year = date.getFullYear();\n const month = String(date.getMonth() + 1).padStart(2, \"0\");\n\n if (chunking === \"monthly\") {\n return `${year}-${month}`;\n }\n\n if (chunking === \"daily\") {\n const day = String(date.getDate()).padStart(2, \"0\");\n return `${year}-${month}-${day}`;\n }\n\n // Weekly: ISO week number\n const weekNum = getISOWeekNumber(date);\n return `${year}-W${String(weekNum).padStart(2, \"0\")}`;\n}\n\n/** Returns the ISO 8601 week number for a given date */\nfunction getISOWeekNumber(date: Date): number {\n const target = new Date(date.valueOf());\n // Set to nearest Thursday (current date + 4 - current day number, with Sunday as 7)\n const dayNum = target.getDay() || 7;\n target.setDate(target.getDate() + 4 - dayNum);\n const yearStart = new Date(target.getFullYear(), 0, 1);\n return Math.ceil(\n ((target.getTime() - yearStart.getTime()) / 86_400_000 + 1) / 7\n );\n}\n\n/**\n * Creates a pino logger instance that writes to the resolved log file path.\n * Each call creates a fresh pino transport — callers should cache if needed.\n */\nfunction createLoggerForApp(appName: string, config?: LoggerConfig): Logger {\n const logFile = resolveLogPath(appName, config);\n\n const transport = pino.transport({\n targets: [\n {\n level: \"info\",\n target: \"pino/file\",\n options: {\n destination: logFile,\n mkdir: true,\n },\n },\n ],\n });\n\n return pino(\n {\n base: null,\n timestamp: () => `,\"time\":\"${new Date().toISOString()}\"`,\n formatters: {\n level(label) {\n return { level: label };\n },\n },\n },\n transport\n );\n}\n\n/**\n * Creates a new log entry with the provided log information.\n * Supports optional chunking config to split logs into time-based files.\n * @param log - The log object containing the log details\n * @param config - Optional logger config for chunking behavior\n * @returns The generated log ID (or JSON string in agentic mode)\n * @throws {Error} If appName is missing in the log object\n */\nexport const createLog = (log: Log, config?: LoggerConfig) => {\n if (!log.appName) {\n throw new Error(`Missing appName in log: ${JSON.stringify(log)}`);\n }\n\n const level = log.level || \"info\";\n const log_id = log.log_id || nanoid(6);\n\n const logRecord = {\n log_id,\n appName: log.appName,\n atFunction: log.atFunction,\n message: log.message,\n data: log.data ?? null,\n level,\n time: new Date().toISOString(),\n };\n\n const mode = getMode();\n\n if (mode === \"prod\" || process.env.NODE_ENV === \"test\") {\n const logFile = resolveLogPath(log.appName, config);\n\n if (process.env.NODE_ENV === \"test\") {\n // For tests, write synchronously to ensure file exists immediately\n appendFileSync(logFile, `${JSON.stringify(logRecord)}\\n`, \"utf-8\");\n } else {\n // For production, use pino logger\n const appLogger = createLoggerForApp(log.appName, config);\n appLogger[level as \"info\" | \"warn\" | \"error\"](logRecord);\n }\n return log_id;\n }\n\n if (mode === \"agentic\") {\n return JSON.stringify(logRecord);\n }\n\n console.log({\n ...logRecord,\n data: JSON.stringify(logRecord.data, null, 2),\n });\n return \"dev-mode, see your dev console!\";\n};\n\nexport interface LogFilter {\n appName?: string;\n log_id?: string;\n level?: \"info\" | \"warn\" | \"error\";\n from?: Date;\n to?: Date;\n}\n\n/**\n * Retrieves logs based on the provided filters.\n * Supports reading from chunked files when a LoggerConfig with chunking is provided.\n * When chunking is enabled, uses from/to date filters to intelligently select\n * only the relevant chunk files instead of scanning all files.\n * @param filters - Optional filters to apply when retrieving logs\n * @param config - Optional logger config matching the chunking used when writing\n * @returns An array of log entries matching the filters\n */\nexport const getLogs = (\n filters: LogFilter = {},\n config?: LoggerConfig\n): Log[] => {\n const chunking = config?.chunking ?? \"none\";\n\n const filesToRead = resolveLogFiles(filters, chunking);\n const logs = readAndParseLogFiles(filesToRead);\n return applyLogFilters(logs, filters);\n};\n\n/**\n * Determines which log files to read based on filters and chunking strategy.\n * For 'none' chunking, returns the single flat file.\n * For time-based chunking, scans the app directory and filters by date range.\n */\nfunction resolveLogFiles(\n filters: LogFilter,\n chunking: \"monthly\" | \"daily\" | \"weekly\" | \"none\"\n): string[] {\n if (chunking === \"none\") {\n const logFile = filters.appName\n ? join(logDir, `${filters.appName}.log`)\n : join(logDir, \"app.log\");\n return existsSync(logFile) ? [logFile] : [];\n }\n\n // Chunked mode requires appName to locate the directory\n if (!filters.appName) {\n return [];\n }\n\n const appDir = join(logDir, filters.appName);\n if (!existsSync(appDir)) {\n return [];\n }\n\n const allFiles = readdirSync(appDir)\n .filter((f) => f.endsWith(\".log\"))\n .sort();\n\n // If no date filters, read all chunk files\n if (!(filters.from || filters.to)) {\n return allFiles.map((f) => join(appDir, f));\n }\n\n // Filter chunks by date relevance to avoid reading unnecessary files\n return allFiles\n .filter((filename) => isChunkRelevant(filename, chunking, filters))\n .map((f) => join(appDir, f));\n}\n\n/**\n * Checks if a chunk file is relevant to the given date range filter.\n * Compares the chunk's time range against the filter's from/to dates.\n */\nfunction isChunkRelevant(\n filename: string,\n chunking: \"monthly\" | \"daily\" | \"weekly\",\n filters: LogFilter\n): boolean {\n // Extract the chunk name (strip .log extension)\n const chunkName = filename.replace(\".log\", \"\");\n const range = getChunkDateRange(chunkName, chunking);\n\n if (!range) {\n return true; // Can't parse — include to be safe\n }\n\n const { start, end } = range;\n\n // Chunk is relevant if its range overlaps with the filter range\n if (filters.to && start > filters.to) {\n return false;\n }\n if (filters.from && end < filters.from) {\n return false;\n }\n\n return true;\n}\n\n/**\n * Returns the start and end date boundaries of a chunk based on its name and strategy.\n * This allows getLogs to skip chunks that fall outside the requested date range.\n */\nfunction getChunkDateRange(\n chunkName: string,\n chunking: \"monthly\" | \"daily\" | \"weekly\"\n): { start: Date; end: Date } | null {\n if (chunking === \"monthly\") {\n // Format: YYYY-MM\n const match = chunkName.match(MONTHLY_PATTERN);\n if (!(match?.[1] && match[2])) {\n return null;\n }\n const year = Number(match[1]);\n const month = Number(match[2]) - 1;\n const start = new Date(year, month, 1);\n const end = new Date(year, month + 1, 0, 23, 59, 59, 999);\n return { start, end };\n }\n\n if (chunking === \"daily\") {\n // Format: YYYY-MM-DD\n const match = chunkName.match(DAILY_PATTERN);\n if (!(match?.[1] && match[2] && match[3])) {\n return null;\n }\n const year = Number(match[1]);\n const month = Number(match[2]) - 1;\n const day = Number(match[3]);\n const start = new Date(year, month, day);\n const end = new Date(year, month, day, 23, 59, 59, 999);\n return { start, end };\n }\n\n // Weekly: YYYY-WNN\n const match = chunkName.match(WEEKLY_PATTERN);\n if (!(match?.[1] && match[2])) {\n return null;\n }\n const year = Number(match[1]);\n const week = Number(match[2]);\n const start = getDateFromISOWeek(year, week);\n const end = new Date(start);\n end.setDate(end.getDate() + 6);\n end.setHours(23, 59, 59, 999);\n return { start, end };\n}\n\n/** Returns the Monday date for a given ISO year and week number */\nfunction getDateFromISOWeek(year: number, week: number): Date {\n const jan4 = new Date(year, 0, 4);\n const dayOfWeek = jan4.getDay() || 7;\n // Monday of week 1\n const monday = new Date(jan4);\n monday.setDate(jan4.getDate() - dayOfWeek + 1);\n // Add (week - 1) weeks\n monday.setDate(monday.getDate() + (week - 1) * 7);\n monday.setHours(0, 0, 0, 0);\n return monday;\n}\n\n/** Reads and parses NDJSON log entries from multiple files into a single array */\nfunction readAndParseLogFiles(files: string[]): Record<string, unknown>[] {\n const logs: Record<string, unknown>[] = [];\n\n for (const file of files) {\n if (!existsSync(file)) {\n continue;\n }\n\n const content = readFileSync(file, \"utf-8\").trim();\n if (!content) {\n continue;\n }\n\n const lines = content.split(\"\\n\");\n for (const line of lines) {\n try {\n const parsed = JSON.parse(line) as Record<string, unknown>;\n logs.push(parsed);\n } catch {\n // Skip malformed lines\n }\n }\n }\n\n return logs;\n}\n\n/** Applies log_id, level, and time range filters to parsed log entries */\nfunction applyLogFilters(\n logs: Record<string, unknown>[],\n filters: LogFilter\n): Log[] {\n return logs.filter((log) => {\n if (filters.appName && log.appName !== filters.appName) {\n return false;\n }\n if (filters.log_id && log.log_id !== filters.log_id) {\n return false;\n }\n if (filters.level && log.level !== filters.level) {\n return false;\n }\n\n const time = new Date(log.time as string);\n if (filters.from && time < filters.from) {\n return false;\n }\n if (filters.to && time > filters.to) {\n return false;\n }\n\n return true;\n }) as unknown as Log[];\n}\n","import { type Log, type LoggerConfig, createLog as newLog } from \"./logger\";\n\ntype LogInput = Omit<Log, \"appName\">;\n\n/**\n * Creates a logger instance bound to a specific app name.\n * Optionally accepts a LoggerConfig for time-based file chunking.\n * @param appName - The application name (determines log file/directory)\n * @param config - Optional config for chunking (monthly, daily, weekly)\n */\nexport const createLogger = (appName: string, config?: LoggerConfig) => {\n return {\n info: (input: LogInput) =>\n newLog({ ...input, appName, level: \"info\" }, config),\n warn: (input: LogInput) =>\n newLog({ ...input, appName, level: \"warn\" }, config),\n error: (input: LogInput) =>\n newLog({ ...input, appName, level: \"error\" }, config),\n };\n};\n","import { safeTry } from \"slang-ts\";\nimport { createEngine } from \"@/engine/engine\";\nimport type { Engine } from \"@/engine/types\";\nimport { createRestApp } from \"@/rest/rest\";\nimport { createDiagnosticsLog } from \"@/utils\";\nimport { createNileContext } from \"./nile\";\nimport type { NileContext, NileServer, Resources, ServerConfig } from \"./types\";\n\nlet _nileContext: NileContext | null = null;\n\n/**\n * Retrieves the runtime NileContext.\n *\n * Use this to access shared resources (database, logger) and context storage\n * from anywhere in your application. Supports a TDB generic to provide\n * end-to-end type safety for your database instance.\n *\n * @template TDB - The type of your database instance (e.g. typeof db)\n * @returns The active NileContext<TDB>\n * @throws If called before createNileServer has initialized the global context.\n */\nexport function getContext<TDB = unknown>(): NileContext<TDB> {\n if (!_nileContext) {\n throw new Error(\n \"getContext: Server not initialized. Call createNileServer first.\"\n );\n }\n return _nileContext as NileContext<TDB>;\n}\n\n/**\n * Bootstraps a Nile server instance.\n *\n * Wires together the Action Engine, shared NileContext, and interface layers (REST).\n * This is the primary entry point for a Nile application. It handles service\n * registration, resource attachment, and server lifecycle.\n *\n * @param config - Server configuration including services, rest options, and resources\n * @returns A NileServer instance containing the engine and (optional) REST app\n */\nexport function createNileServer(config: ServerConfig): NileServer {\n if (!config.services?.length) {\n throw new Error(\n \"createNileServer requires at least one service in config.services\"\n );\n }\n\n const log = createDiagnosticsLog(\"NileServer\", {\n diagnostics: config.diagnostics,\n logger: config.resources?.logger as unknown as Parameters<\n typeof createDiagnosticsLog\n >[1][\"logger\"],\n });\n\n // Shared context -- created once with resources, passed to all layers\n const nileContext = createNileContext({\n resources: config.resources as unknown as Resources<unknown>,\n });\n\n _nileContext = nileContext as unknown as NileContext<unknown>;\n\n // Initialize the Action Engine\n const engine: Engine = createEngine({\n services: config.services,\n diagnostics: config.diagnostics,\n logger: config.resources?.logger as unknown as Parameters<\n typeof createEngine\n >[0][\"logger\"],\n onBeforeActionHandler: config.onBeforeActionHandler,\n onAfterActionHandler: config.onAfterActionHandler,\n });\n\n log(`Engine initialized with ${config.services.length} service(s)`);\n\n // Print registered services table (on by default, opt-out with logServices: false)\n if (config.logServices !== false) {\n const servicesResult = engine.getServices();\n if (servicesResult.isOk) {\n const table = servicesResult.value.map((s) => ({\n Service: s.name,\n Description: s.description,\n Actions: s.actions.length,\n }));\n console.table(table);\n }\n }\n\n // Build the server object incrementally\n const server: NileServer = {\n config,\n engine,\n context: nileContext as NileContext<unknown>,\n };\n\n // Initialize REST interface if configured\n if (config.rest) {\n const app = createRestApp({\n config: config.rest,\n engine,\n nileContext: nileContext as NileContext<unknown>,\n serverName: config.serverName,\n runtime: config.runtime ?? \"bun\",\n });\n\n server.rest = { app, config: config.rest };\n\n const host = config.rest.host ?? \"localhost\";\n const port = config.rest.port ?? 3000;\n const base = `http://${host}:${port}`;\n\n console.log(`\\n POST ${base}${config.rest.baseUrl}/services`);\n if (config.rest.enableStatus) {\n console.log(` GET ${base}/status`);\n }\n console.log(\"\");\n }\n\n // Run onBoot lifecycle hook\n if (config.onBoot) {\n const { fn } = config.onBoot;\n // Fire-and-forget with crash safety via async IIFE\n const _boot = (async () => {\n const result = await safeTry(() => fn(nileContext));\n if (result.isErr) {\n console.error(\"[NileServer] onBoot failed:\", result.error);\n }\n })();\n // Intentionally not awaited — boot runs in background\n _boot;\n }\n\n log(`${config.serverName} server ready`);\n\n return server;\n}\n","import { Err, Ok, type Result } from \"slang-ts\";\nimport type { NileContext } from \"@/nile/types\";\nimport { createDiagnosticsLog } from \"@/utils\";\nimport {\n processHooks,\n runGlobalAfterHook,\n runGlobalBeforeHook,\n runHandler,\n validatePayload,\n} from \"./pipeline\";\nimport type {\n Action,\n ActionSummary,\n EngineOptions,\n ServiceSummary,\n} from \"./types\";\n\nexport function createEngine(options: EngineOptions) {\n const { diagnostics, services, logger } = options;\n\n const log = createDiagnosticsLog(\"Engine\", {\n diagnostics,\n logger: logger as unknown as Parameters<\n typeof createDiagnosticsLog\n >[1][\"logger\"],\n });\n\n // O(1) Pre-computed Lookups\n const serviceSummaries: ServiceSummary[] = [];\n const serviceActionsStore: Record<string, ActionSummary[]> = {};\n const actionStore: Record<string, Record<string, Action>> = {};\n\n // Build stores once on init\n const initStartTime = performance.now();\n\n for (const service of services) {\n const actionNames: string[] = [];\n serviceActionsStore[service.name] = [];\n actionStore[service.name] = {};\n\n for (const action of service.actions) {\n actionNames.push(action.name);\n\n serviceActionsStore[service.name]?.push({\n name: action.name,\n description: action.description,\n isProtected: !!action.isProtected,\n validation: !!action.validation,\n accessControl: action.accessControl || [],\n });\n\n const serviceActions = actionStore[service.name];\n if (serviceActions) {\n serviceActions[action.name] = action;\n }\n }\n\n serviceSummaries.push({\n name: service.name,\n description: service.description,\n meta: service.meta,\n actions: actionNames,\n });\n }\n\n log(\n `Initialized in ${performance.now() - initStartTime}ms. Loaded ${services.length} services.`\n );\n\n // --- Discovery API ---\n\n const getServices = (): Result<ServiceSummary[], string> =>\n Ok(serviceSummaries);\n\n const getServiceActions = (\n serviceName: string\n ): Result<ActionSummary[], string> => {\n const actions = serviceActionsStore[serviceName];\n return actions ? Ok(actions) : Err(`Service '${serviceName}' not found`);\n };\n\n const getAction = (\n serviceName: string,\n actionName: string\n ): Result<Action, string> => {\n const serviceMap = actionStore[serviceName];\n if (!serviceMap) {\n return Err(`Service '${serviceName}' not found`);\n }\n\n const action = serviceMap[actionName];\n return action\n ? Ok(action)\n : Err(`Action '${actionName}' not found in service '${serviceName}'`);\n };\n\n const executeAction = async (\n serviceName: string,\n actionName: string,\n payload: unknown,\n nileContext: NileContext<unknown>\n ): Promise<Result<unknown, string>> => {\n const { onBeforeActionHandler, onAfterActionHandler } = options;\n\n // Resolve action\n const actionResult = getAction(serviceName, actionName);\n if (actionResult.isErr) {\n return Err(actionResult.error);\n }\n const action = actionResult.value;\n\n // Reset hook context for this execution\n nileContext.resetHookContext(`${serviceName}.${actionName}`, payload);\n\n // Step 1: Global Before Hook\n const globalBeforeResult = await runGlobalBeforeHook(\n onBeforeActionHandler,\n nileContext,\n action,\n payload,\n log\n );\n if (globalBeforeResult.isErr) {\n return Err(globalBeforeResult.error);\n }\n\n // Step 2: Action Before Hooks\n const beforeHooksResult = await processHooks(\n action.hooks?.before ?? [],\n payload,\n getAction,\n nileContext,\n \"before\",\n log\n );\n if (beforeHooksResult.isErr) {\n return Err(beforeHooksResult.error);\n }\n\n // Step 3: Validation\n const validationResult = validatePayload(\n action,\n beforeHooksResult.value,\n nileContext,\n log\n );\n if (validationResult.isErr) {\n return Err(validationResult.error);\n }\n\n // Step 4: Handler\n const handlerResult = await runHandler(\n action,\n validationResult.value,\n nileContext,\n log\n );\n if (handlerResult.isErr) {\n return Err(handlerResult.error);\n }\n\n // Step 5: Action After Hooks\n const afterHooksResult = await processHooks(\n action.hooks?.after ?? [],\n handlerResult.value,\n getAction,\n nileContext,\n \"after\",\n log\n );\n if (afterHooksResult.isErr) {\n return Err(afterHooksResult.error);\n }\n\n // Step 6: Global After Hook\n const globalAfterResult = await runGlobalAfterHook(\n onAfterActionHandler,\n nileContext,\n action,\n validationResult.value,\n afterHooksResult.value,\n log\n );\n if (globalAfterResult.isErr) {\n return Err(globalAfterResult.error);\n }\n\n // Final response\n return action.result?.pipeline\n ? Ok({\n data: globalAfterResult.value,\n pipeline: nileContext.hookContext.log,\n })\n : Ok(globalAfterResult.value);\n };\n\n return {\n getServices,\n getServiceActions,\n getAction,\n executeAction,\n };\n}\n","import { count, desc, eq, lt, type SQL } from \"drizzle-orm\";\nimport { Ok, safeTry } from \"slang-ts\";\nimport { getContext } from \"@/nile/server\";\nimport { handleError } from \"../handle-error\";\nimport { createTransactionVariant } from \"./create-transaction-variant\";\nimport { getZodSchema } from \"./get-zod-schema\";\nimport type {\n CursorPage,\n ModelOperations,\n ModelOptions,\n ModelUpdateParams,\n ModelWriteParams,\n OffsetPage,\n OffsetPaginationOptions,\n PaginationOptions,\n TableSchemas,\n} from \"./types\";\n\n/**\n * Minimal shape of a Drizzle database instance for dynamic query building.\n * Covers the select/insert/update/delete chains used by createModel internals.\n * Avoids using the `Function` type while remaining compatible with both\n * Neon and PGLite Drizzle drivers.\n */\ninterface DrizzleDbLike {\n select(fields?: Record<string, unknown>): {\n from(table: unknown): DrizzleSelectQuery;\n };\n insert(table: unknown): {\n values(data: unknown): {\n returning(): Promise<unknown[]>;\n };\n };\n update(table: unknown): {\n set(data: unknown): {\n where(condition: SQL): {\n returning(): Promise<unknown[]>;\n };\n };\n };\n delete(table: unknown): {\n where(condition: SQL): {\n returning(): Promise<unknown[]>;\n };\n };\n}\n\n/** Chainable select query shape — supports where/orderBy/limit/offset in any valid order */\ninterface DrizzleSelectQuery extends Promise<unknown[]> {\n where(condition: SQL): DrizzleSelectQuery;\n orderBy(...cols: SQL[]): DrizzleSelectQuery;\n limit(n: number): DrizzleSelectQuery;\n offset(n: number): DrizzleSelectQuery;\n}\n\n/** Cast db to our minimal interface — safe because Drizzle drivers all expose these methods */\nfunction asDb(db: unknown): DrizzleDbLike {\n return db as DrizzleDbLike;\n}\n\n/**\n * Resolves a database instance from the explicit option or the Nile request context.\n * Throws immediately if neither is available — this is a developer configuration error.\n */\nfunction resolveDb<TDB>(explicitDb: TDB | undefined): TDB {\n if (explicitDb) {\n return explicitDb;\n }\n\n try {\n const ctx = getContext();\n if (ctx.resources?.database) {\n return ctx.resources.database as TDB;\n }\n } catch (_) {\n // context not available — fall through to throw\n }\n throw new Error(\n \"createModel: No database available. Pass db in ModelOptions or set resources.database on server config.\"\n );\n}\n\n/**\n * Detects the timestamp column used for default ordering.\n * Checks for both snake_case (created_at) and camelCase (createdAt) conventions.\n */\nfunction findTimestampColumn(table: Record<string, unknown>): string | null {\n if (\"created_at\" in table) {\n return \"created_at\";\n }\n if (\"createdAt\" in table) {\n return \"createdAt\";\n }\n return null;\n}\n\n/**\n * Creates a CRUD model for a Drizzle table, eliminating repetitive boilerplate.\n *\n * All methods return `Result<T, string>` — `Ok(data)` on success, `Err(message)` on failure.\n * Validation, error handling, and transaction variants are built in.\n *\n * For anything beyond basic CRUD, use the exposed `table` and `schemas` properties\n * to compose custom queries with Drizzle directly.\n *\n * @param table - Drizzle table definition (from pgTable, sqliteTable, etc.)\n * @param options - Configuration: entity name, optional db instance, cursor column\n * @returns Object with CRUD operations, plus escape hatches (table, schemas)\n *\n * @example\n * ```typescript\n * import { createModel } from \"@nilejs/nile\";\n * import { tasks } from \"./schema\";\n * import { db } from \"./client\";\n *\n * // Explicit db\n * export const taskModel = createModel(tasks, { db, name: \"task\" });\n *\n * // Context-resolved db (resolved at call time)\n * export const taskModel = createModel(tasks, { name: \"task\" });\n *\n * // Usage\n * const result = await taskModel.create({ data: { title: \"Ship it\" } });\n * const task = await taskModel.findById(\"uuid-123\");\n * const page = await taskModel.findPaginated({ limit: 20, offset: 0 });\n * ```\n */\nexport function createModel<\n TTable extends { $inferSelect: unknown; $inferInsert: unknown },\n TDB = unknown,\n>(\n table: TTable,\n options: ModelOptions<TDB>\n): ModelOperations<TTable[\"$inferSelect\"], TTable[\"$inferInsert\"], TDB> {\n type TSelect = TTable[\"$inferSelect\"];\n type TInsert = TTable[\"$inferInsert\"];\n\n const { name, cursorColumn = \"id\" } = options;\n const entityName = name.charAt(0).toUpperCase() + name.slice(1);\n const schemas = getZodSchema(table) as TableSchemas<TTable>;\n const tableRef = table as Record<string, unknown>;\n\n /** Resolve and cast db for the current call */\n const getDb = () => asDb(resolveDb<TDB>(options.db));\n\n // -- Core CRUD --\n\n const create = async ({ data, dbx }: ModelWriteParams<TInsert, TDB>) => {\n const parsed = schemas.insert.safeParse(data);\n if (!parsed.success) {\n return handleError({\n message: `Invalid ${name} data`,\n data: { errors: parsed.error },\n atFunction: `${name}.create`,\n });\n }\n\n const db = dbx ? asDb(dbx) : getDb();\n const result = await safeTry(() =>\n db.insert(table).values(data).returning()\n );\n if (result.isErr) {\n return handleError({\n message: `Error creating ${name}`,\n data: { error: result.error },\n atFunction: `${name}.create`,\n });\n }\n\n const row = (result.value as TSelect[])?.[0] ?? null;\n if (!row) {\n return handleError({\n message: `${entityName} creation returned no data`,\n atFunction: `${name}.create`,\n });\n }\n return Ok(row);\n };\n\n const update = async ({ id, data, dbx }: ModelUpdateParams<TSelect, TDB>) => {\n const parsed = schemas.update.safeParse(data);\n if (!parsed.success) {\n return handleError({\n message: `Invalid ${name} data`,\n data: { errors: parsed.error },\n atFunction: `${name}.update`,\n });\n }\n\n const db = dbx ? asDb(dbx) : getDb();\n const idCol = tableRef.id as Parameters<typeof eq>[0];\n const result = await safeTry(() =>\n db.update(table).set(data).where(eq(idCol, id)).returning()\n );\n if (result.isErr) {\n return handleError({\n message: `Error updating ${name}`,\n data: { id, error: result.error },\n atFunction: `${name}.update`,\n });\n }\n\n const row = (result.value as TSelect[])?.[0] ?? null;\n if (!row) {\n return handleError({\n message: `${entityName} not found`,\n data: { id },\n atFunction: `${name}.update`,\n });\n }\n return Ok(row);\n };\n\n // Transaction variants via existing utility\n const createTx = createTransactionVariant(\n create as Parameters<typeof createTransactionVariant>[0]\n );\n const updateTx = createTransactionVariant(\n update as Parameters<typeof createTransactionVariant>[0]\n );\n\n const findById = async (id: string) => {\n const db = getDb();\n const idCol = tableRef.id as Parameters<typeof eq>[0];\n const result = await safeTry(() =>\n db.select().from(table).where(eq(idCol, id))\n );\n if (result.isErr) {\n return handleError({\n message: `Error getting ${name}`,\n data: { id, error: result.error },\n atFunction: `${name}.findById`,\n });\n }\n\n const row = (result.value as TSelect[])?.[0] ?? null;\n if (!row) {\n return handleError({\n message: `${entityName} not found`,\n data: { id },\n atFunction: `${name}.findById`,\n });\n }\n return Ok(row);\n };\n\n const deleteFn = async (id: string) => {\n const db = getDb();\n const idCol = tableRef.id as Parameters<typeof eq>[0];\n const result = await safeTry(() =>\n db.delete(table).where(eq(idCol, id)).returning()\n );\n if (result.isErr) {\n return handleError({\n message: `Error deleting ${name}`,\n data: { id, error: result.error },\n atFunction: `${name}.delete`,\n });\n }\n\n const row = (result.value as TSelect[])?.[0] ?? null;\n if (!row) {\n return handleError({\n message: `${entityName} not found`,\n data: { id },\n atFunction: `${name}.delete`,\n });\n }\n return Ok(row);\n };\n\n const findAll = async () => {\n const db = getDb();\n const tsCol = findTimestampColumn(tableRef);\n\n const result = await safeTry(() => {\n const query = db.select().from(table);\n if (!tsCol) {\n return query;\n }\n return query.orderBy(desc(tableRef[tsCol] as Parameters<typeof desc>[0]));\n });\n if (result.isErr) {\n return handleError({\n message: `Error getting all ${name}s`,\n data: { error: result.error },\n atFunction: `${name}.findAll`,\n });\n }\n\n return Ok((result.value ?? []) as TSelect[]);\n };\n\n /** Offset-based pagination — returns items, total count, and hasMore flag */\n const findOffsetPage = async (limit: number, offset: number) => {\n const db = getDb();\n const tsCol = findTimestampColumn(tableRef);\n\n const itemsResult = await safeTry(() => {\n const query = db.select().from(table);\n const ordered = tsCol\n ? query.orderBy(desc(tableRef[tsCol] as Parameters<typeof desc>[0]))\n : query;\n return ordered.limit(limit).offset(offset);\n });\n if (itemsResult.isErr) {\n return handleError({\n message: `Error getting paginated ${name}s`,\n data: { limit, offset, error: itemsResult.error },\n atFunction: `${name}.findPaginated`,\n });\n }\n\n const countResult = await safeTry(() =>\n db.select({ total: count() }).from(table)\n );\n if (countResult.isErr) {\n return handleError({\n message: `Error getting ${name} count`,\n data: { error: countResult.error },\n atFunction: `${name}.findPaginated`,\n });\n }\n\n const items = (itemsResult.value ?? []) as TSelect[];\n const total = (countResult.value as { total: number }[])?.[0]?.total ?? 0;\n\n return Ok({\n items,\n total,\n hasMore: offset + items.length < total,\n } satisfies OffsetPage<TSelect>);\n };\n\n /** Cursor-based pagination — uses lt() on the cursor column with desc ordering */\n const findCursorPage = async (\n limit: number,\n cursor: string,\n colName: string\n ) => {\n const db = getDb();\n const column = tableRef[colName];\n\n if (!column) {\n return handleError({\n message: `Cursor column '${colName}' does not exist on ${name} table`,\n atFunction: `${name}.findPaginated`,\n });\n }\n\n const typedColumn = column as Parameters<typeof lt>[0];\n\n // Fetch one extra row to determine hasMore without a separate count query\n const result = await safeTry(() =>\n db\n .select()\n .from(table)\n .where(lt(typedColumn, cursor))\n .orderBy(desc(typedColumn))\n .limit(limit + 1)\n );\n if (result.isErr) {\n return handleError({\n message: `Error getting paginated ${name}s`,\n data: { cursor, cursorColumn: colName, error: result.error },\n atFunction: `${name}.findPaginated`,\n });\n }\n\n const rows = (result.value ?? []) as TSelect[];\n const hasMore = rows.length > limit;\n const items = hasMore ? rows.slice(0, limit) : rows;\n const lastItem = items.at(-1) as Record<string, unknown> | undefined;\n const nextCursor = lastItem\n ? String(lastItem[colName] ?? \"\") || null\n : null;\n\n return Ok({\n items,\n nextCursor,\n hasMore,\n } satisfies CursorPage<TSelect>);\n };\n\n const findPaginated = (opts: PaginationOptions = {}) => {\n const limit = opts.limit ?? 50;\n\n // Cursor mode when cursor is provided\n if (\"cursor\" in opts && opts.cursor) {\n const colName = opts.cursorColumn ?? cursorColumn;\n return findCursorPage(limit, opts.cursor, colName);\n }\n\n // Default: offset mode\n const offset = (opts as OffsetPaginationOptions).offset ?? 0;\n return findOffsetPage(limit, offset);\n };\n\n return {\n create,\n createTx,\n findById,\n update,\n updateTx,\n delete: deleteFn,\n findAll,\n findPaginated,\n table,\n schemas,\n } as ModelOperations<TSelect, TInsert, TDB>;\n}\n","import { Err, type ErrType, type ResultMethods } from \"slang-ts\";\nimport { getContext } from \"@/nile/server\";\nimport type { NileLogger } from \"@/nile/types\";\n\n/**\n * Parameters for the handleError utility.\n *\n * @property message - Human-readable error description, included in the returned Result error string\n * @property data - Optional structured data logged alongside the error for debugging\n * @property logger - Explicit logger instance; when omitted, resolves from the current Nile request context\n * @property atFunction - Name of the calling function for log attribution; auto-inferred from stack trace when omitted\n */\nexport interface HandleErrorParams {\n message: string;\n data?: unknown;\n logger?: NileLogger;\n atFunction?: string;\n}\n\nconst CALLER_LINE_REGEX = /at\\s+(\\S+)\\s+/;\n\nfunction inferCallerName(): string {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const _err = new Error(\"capture stack trace\");\n const stack = _err.stack;\n const callerLine = stack?.split(\"\\n\")[3] ?? \"\";\n const match = callerLine.match(CALLER_LINE_REGEX);\n return match?.[1] ?? \"unknown\";\n}\n\nfunction resolveLogger(explicit?: NileLogger): NileLogger {\n if (explicit) {\n return explicit;\n }\n try {\n const ctx = getContext();\n if (ctx.resources?.logger) {\n return ctx.resources.logger;\n }\n } catch (_) {\n // Fall through to throw\n }\n throw new Error(\n \"handleError: No logger available. Provide a logger param or set resources.logger on server config.\"\n );\n}\n\n/**\n * Logs an error via the resolved logger and returns a typed Err result.\n * Resolves the logger from the current Nile request context when not provided explicitly.\n * The returned error string includes the log ID for traceability: `[logId] message`.\n *\n * @param params - Error details including message, optional data, logger, and caller function name\n * @returns Always an Err variant — `ErrType<string> & ResultMethods<never>`, compatible with any `Result<T, E>` union\n *\n * @example\n * ```typescript\n * if (!user) {\n * return handleError({\n * message: \"User not found\",\n * data: { userId },\n * atFunction: \"getUserById\",\n * });\n * }\n * ```\n */\nexport function handleError(\n params: HandleErrorParams\n): ErrType<string> & ResultMethods<never> {\n const atFunction = params.atFunction ?? inferCallerName();\n const logger = resolveLogger(params.logger);\n const logId = logger.error({\n atFunction,\n message: params.message,\n data: params.data,\n });\n return Err(`[${logId}] ${params.message}`);\n}\n","import type { Result } from \"slang-ts\";\nimport type { DBParams } from \"./types\";\n\n/**\n * Creates a transaction-aware variant of a database function.\n * Expects the wrapped function to accept a single object parameter with optional dbx field.\n *\n * When dbx is root db (has .transaction method):\n * - Creates new transaction and executes function inside it\n * - On Result.isError, throws Error to trigger automatic rollback\n * - Returns successful result or throws\n *\n * When dbx is tx pointer (no .transaction method):\n * - Executes function directly within existing transaction scope\n * - On Result.isError, throws Error to trigger parent transaction rollback\n * - Returns successful result or throws\n *\n * Both cases ensure database rollback on any error by throwing.\n *\n * @example\n * ```typescript\n * const createCompanyTx = createTransactionVariant(createCompany);\n * // Type-safe: requires all params from createCompany\n * const result = await createCompanyTx({ company: {...}, dbx: tx });\n * ```\n */\nexport function createTransactionVariant<\n TParams extends DBParams<TDB>,\n TData,\n TDB = unknown,\n>(\n fn: (params: TParams) => Promise<Result<TData, unknown>>\n): (params: TParams) => Promise<Result<TData, unknown>> {\n return async (params: TParams): Promise<Result<TData, unknown>> => {\n const { dbx, ...rest } = params;\n\n if (!dbx) {\n const result = await fn(params as TParams);\n if (result.isErr) {\n throw new Error(String(result.error));\n }\n return result;\n }\n\n const hasTransaction =\n typeof (dbx as Record<string, unknown>)?.transaction === \"function\";\n\n if (hasTransaction) {\n return await (\n dbx as unknown as {\n transaction: (\n fn: (tx: unknown) => Promise<Result<TData, unknown>>\n ) => Promise<Result<TData, unknown>>;\n }\n ).transaction(async (tx: unknown) => {\n const result = await fn({ ...rest, dbx: tx } as TParams);\n if (result.isErr) {\n throw new Error(String(result.error));\n }\n return result;\n });\n }\n\n const result = await fn({ ...rest, dbx } as TParams);\n if (result.isErr) {\n throw new Error(String(result.error));\n }\n return result;\n };\n}\n","import {\n createInsertSchema,\n createSelectSchema,\n createUpdateSchema,\n} from \"drizzle-zod\";\nimport type { TableSchemas } from \"./types\";\n\n/**\n * Generates Zod schemas (insert, update, select) from a Drizzle table.\n *\n * @param table - The Drizzle table definition\n * @returns Object containing insert, update, and select Zod schemas\n *\n * @example\n * ```typescript\n * import { getZodSchema } from '@nilejs/nile';\n * import { companies } from './schema';\n *\n * const schemas = getZodSchema(companies);\n * const insert = schemas.insert.parse(data);\n * const update = schemas.update.partial().parse(data);\n * ```\n */\nexport function getZodSchema<TTable extends object>(\n table: TTable\n): TableSchemas<TTable> {\n const isRelation =\n Object.hasOwn(table as object, \"config\") &&\n Object.hasOwn(table as object, \"table\");\n\n if (isRelation) {\n throw new Error(\n `${String(table)} is a relation schema, not a table schema`\n );\n }\n\n const insertSchema = createInsertSchema(\n table as unknown as Parameters<typeof createInsertSchema>[0]\n );\n const updateSchema = createUpdateSchema(\n table as unknown as Parameters<typeof createUpdateSchema>[0]\n );\n const selectSchema = createSelectSchema(\n table as unknown as Parameters<typeof createSelectSchema>[0]\n );\n\n return {\n insert: insertSchema,\n update: updateSchema,\n select: selectSchema,\n } as TableSchemas<TTable>;\n}\n","import type { NileLogger } from \"@/nile/types\";\n\ntype AnyLogger = NileLogger | { info: (msg: string, data?: unknown) => void };\n\nfunction isNileLogger(logger: AnyLogger): logger is NileLogger {\n return \"warn\" in logger && \"error\" in logger;\n}\n\ninterface CreateDiagnosticsLogParams {\n diagnostics?: boolean;\n logger?: AnyLogger;\n}\n\n/**\n * Creates a centralized diagnostics log function for nile internals.\n * Checks resources.logger first, falls back to console.log, respects diagnostics flag.\n * Returns a bound function with the prefix already applied for clean call sites.\n *\n * @param prefix - Component identifier e.g. \"NileServer\", \"REST\", \"Engine\"\n * @param params - Diagnostics flag and optional structured logger from resources\n * @returns A log function: (message, data?) => void\n */\nexport function createDiagnosticsLog(\n prefix: string,\n params: CreateDiagnosticsLogParams\n): (message: string, data?: unknown) => void {\n if (!params.diagnostics) {\n // biome-ignore lint/suspicious/noEmptyBlockStatements: intentional no-op when diagnostics disabled\n return () => {};\n }\n\n const { logger } = params;\n\n return (message: string, data?: unknown) => {\n if (!logger) {\n console.log(`[${prefix}] ${message}`, data ?? \"\");\n return;\n }\n\n if (isNileLogger(logger)) {\n logger.info({\n atFunction: prefix,\n message: `[${prefix}] ${message}`,\n data,\n });\n } else {\n logger.info(`[${prefix}] ${message}`, data);\n }\n };\n}\n","import { Err, Ok, type Result, safeTry } from \"slang-ts\";\nimport { prettifyError } from \"zod\";\nimport type {\n AfterActionHandler,\n BeforeActionHandler,\n NileContext,\n} from \"@/nile/types\";\nimport type { Action, HookDefinition, HookLogEntry } from \"./types\";\n\n/**\n * Executes a single hook and logs the result\n */\nasync function runHook(\n hookDef: HookDefinition,\n hookAction: Action,\n input: unknown,\n nileContext: NileContext\n): Promise<{ result: Result<unknown, string>; logEntry: HookLogEntry }> {\n const result = await safeTry(() =>\n hookAction.handler(input as Record<string, unknown>, nileContext)\n );\n return {\n result,\n logEntry: {\n name: `${hookDef.service}.${hookDef.action}`,\n input,\n output: result.isOk ? result.value : result.error,\n passed: result.isOk,\n },\n };\n}\n\n/**\n * Process hooks sequentially, each hook output becomes the next input\n */\nexport async function processHooks(\n hooks: HookDefinition[],\n initialValue: unknown,\n getAction: (service: string, action: string) => Result<Action, string>,\n nileContext: NileContext,\n logTarget: \"before\" | \"after\",\n log: (msg: string, data?: unknown) => void\n): Promise<Result<unknown, string>> {\n let currentValue = initialValue;\n\n for (const hookDef of hooks) {\n const hookActionResult = getAction(hookDef.service, hookDef.action);\n\n if (hookActionResult.isErr) {\n const errorMsg = `${logTarget} hook '${hookDef.service}.${hookDef.action}' not found`;\n log(errorMsg);\n if (hookDef.isCritical) {\n nileContext.setHookError(errorMsg);\n return Err(errorMsg);\n }\n continue;\n }\n\n const { result, logEntry } = await runHook(\n hookDef,\n hookActionResult.value,\n currentValue,\n nileContext\n );\n nileContext.addHookLog(logTarget, logEntry);\n\n if (result.isErr) {\n const errorMsg = String(result.error);\n log(\n `${logTarget} hook '${hookDef.service}.${hookDef.action}' failed`,\n result.error\n );\n if (hookDef.isCritical) {\n nileContext.setHookError(errorMsg);\n return Err(errorMsg);\n }\n continue;\n }\n\n currentValue = result.value;\n }\n\n return Ok(currentValue);\n}\n\n/**\n * Run global before hook if configured, wrapped in safeTry for crash safety\n */\nexport async function runGlobalBeforeHook(\n handler: BeforeActionHandler<unknown, unknown> | undefined,\n nileContext: NileContext,\n action: Action,\n payload: unknown,\n log: (msg: string) => void\n): Promise<Result<true, string>> {\n if (!handler) {\n return Ok(true);\n }\n\n const result = await safeTry(() => handler({ nileContext, action, payload }));\n if (result.isErr) {\n log(`Global before hook failed for ${action.name}`);\n nileContext.setHookError(result.error);\n return Err(result.error);\n }\n\n return Ok(true);\n}\n\n/**\n * Run global after hook if configured, wrapped in safeTry for crash safety\n */\nexport async function runGlobalAfterHook(\n handler: AfterActionHandler<unknown, unknown> | undefined,\n nileContext: NileContext,\n action: Action,\n payload: unknown,\n currentResult: unknown,\n log: (msg: string) => void\n): Promise<Result<unknown, string>> {\n if (!handler) {\n return Ok(currentResult);\n }\n\n const result = await safeTry(() =>\n handler({\n nileContext,\n action,\n payload,\n result: Ok(currentResult),\n })\n );\n if (result.isErr) {\n log(`Global after hook failed for ${action.name}`);\n nileContext.setHookError(result.error);\n return Err(result.error);\n }\n\n return Ok(result.value);\n}\n\n/**\n * Validate payload against action's Zod schema\n */\nexport function validatePayload(\n action: Action,\n payload: unknown,\n nileContext: NileContext,\n log: (msg: string, data?: unknown) => void\n): Result<unknown, string> {\n if (!action.validation) {\n return Ok(payload);\n }\n\n const parseResult = action.validation.safeParse(payload);\n if (!parseResult.success) {\n const validationError = prettifyError(parseResult.error);\n log(`Validation failed for ${action.name}`, validationError);\n nileContext.setHookError(validationError);\n return Err(`Validation failed: ${validationError}`);\n }\n\n return Ok(parseResult.data);\n}\n\n/**\n * Execute the main action handler, wrapped in safeTry for crash safety\n */\nexport async function runHandler(\n action: Action,\n payload: unknown,\n nileContext: NileContext,\n log: (msg: string, data?: unknown) => void\n): Promise<Result<unknown, string>> {\n const result = await safeTry(() =>\n action.handler(payload as Record<string, unknown>, nileContext)\n );\n\n if (result.isErr) {\n log(`Handler failed for ${action.name}`, result.error);\n nileContext.setHookError(result.error);\n return Err(result.error);\n }\n\n nileContext.setHookOutput(result.value);\n return Ok(result.value);\n}\n","import { Hono } from \"hono\";\nimport z from \"zod\";\nimport { applyCorsConfig } from \"@/cors/cors\";\nimport type { Engine } from \"@/engine/types\";\nimport type {\n ExternalRequest,\n ExternalResponse,\n NileContext,\n ServerRuntime,\n} from \"@/nile/types\";\nimport { createDiagnosticsLog } from \"@/utils\";\nimport { intentHandlers } from \"./intent-handlers\";\nimport { applyRateLimiting, applyStaticServing } from \"./middleware\";\nimport type { RestConfig } from \"./types\";\n\n// --- Zod schema for incoming requests ---\n\nconst externalRequestSchema = z.object({\n intent: z.enum([\"explore\", \"execute\", \"schema\"]),\n service: z.string().min(1),\n action: z.string().min(1),\n payload: z.record(z.string(), z.unknown()),\n});\n\n// --- Factory ---\n\ninterface CreateRestAppParams {\n config: RestConfig;\n engine: Engine;\n nileContext: NileContext<unknown>;\n serverName: string;\n runtime: ServerRuntime;\n}\n\n/**\n * Creates the Hono REST app with a single POST endpoint for all service interactions\n * and an optional GET /status health check.\n *\n * All service communication flows through POST {baseUrl}/services using\n * the intent field to discriminate between explore, execute, and schema operations.\n */\nexport function createRestApp(params: CreateRestAppParams): Hono {\n const { config, engine, nileContext, serverName, runtime } = params;\n const app = new Hono();\n\n const log = createDiagnosticsLog(\"REST\", {\n diagnostics: config.diagnostics,\n logger: nileContext.resources?.logger as\n | { info: (msg: string, data?: unknown) => void }\n | undefined,\n });\n\n // Apply CORS\n applyCorsConfig(app, config);\n\n // Apply rate limiting when a limiting header is configured\n applyRateLimiting(app, config, log);\n\n // Apply static file serving based on runtime\n applyStaticServing(app, config, runtime, log);\n\n // Single POST endpoint for all service interactions\n const servicesPath = `${config.baseUrl}/services`;\n\n app.post(servicesPath, async (c) => {\n const body = await c.req.json().catch(() => null);\n\n if (!body) {\n return c.json(\n {\n status: false,\n message: \"Invalid or missing JSON body\",\n data: {},\n } satisfies ExternalResponse,\n 400\n );\n }\n\n const parsed = externalRequestSchema.safeParse(body);\n if (!parsed.success) {\n return c.json(\n {\n status: false,\n message: \"Invalid request format\",\n data: { errors: parsed.error.issues },\n } satisfies ExternalResponse,\n 400\n );\n }\n\n const request = parsed.data as ExternalRequest;\n\n log(`${request.intent} -> ${request.service}.${request.action}`);\n\n const handler = intentHandlers[request.intent];\n // biome-ignore lint/suspicious/noExplicitAny: internal dispatch\n const response = await (handler as any)(engine, request, nileContext);\n\n const statusCode = response.status ? 200 : 400;\n return c.json(response, statusCode);\n });\n\n // Health check endpoint\n if (config.enableStatus) {\n app.get(\"/status\", (c) => {\n return c.json({\n status: true,\n message: `${serverName} is running`,\n data: {},\n } satisfies ExternalResponse);\n });\n }\n\n // 404 handler\n app.notFound((c) => {\n return c.json(\n {\n status: false,\n message: `Route not found. Use POST ${servicesPath} for all operations.`,\n data: {},\n } satisfies ExternalResponse,\n 404\n );\n });\n\n log(`REST interface ready at ${servicesPath}`);\n\n return app;\n}\n","import type { Context, Hono } from \"hono\";\nimport { cors } from \"hono/cors\";\nimport type { RestConfig } from \"@/rest/types\";\nimport type { CorsConfig, CorsOptions } from \"./types\";\n\n/**\n * Build default CORS options from REST config\n */\nexport const buildDefaultCorsOptions = (config: RestConfig): CorsOptions => {\n const getDefaultOrigin = (reqOrigin: string) => {\n if (config.allowedOrigins.length > 0) {\n return config.allowedOrigins.includes(reqOrigin ?? \"\") ? reqOrigin : \"\";\n }\n return \"*\";\n };\n\n return {\n origin: config.cors?.defaults?.origin ?? getDefaultOrigin,\n credentials: config.cors?.defaults?.credentials ?? true,\n allowHeaders: config.cors?.defaults?.allowHeaders ?? [\n \"Content-Type\",\n \"Authorization\",\n ],\n allowMethods: config.cors?.defaults?.allowMethods ?? [\n \"POST\",\n \"GET\",\n \"OPTIONS\",\n ],\n exposeHeaders: config.cors?.defaults?.exposeHeaders ?? [\"Content-Length\"],\n maxAge: config.cors?.defaults?.maxAge ?? 600,\n };\n};\n\n/**\n * Apply CORS configuration to a Hono app based on RestConfig\n */\nexport const applyCorsConfig = (app: Hono, config: RestConfig): void => {\n const corsEnabled = config.cors?.enabled ?? \"default\";\n\n if (corsEnabled === false) {\n return;\n }\n\n const defaultCorsOpts = buildDefaultCorsOptions(config);\n\n // Apply route-specific CORS rules FIRST (before global catch-all)\n const corsRules = config.cors?.addCors ?? [];\n for (const rule of corsRules) {\n applyRouteCorsRule(app, rule, defaultCorsOpts);\n }\n\n // Apply global CORS as fallback\n app.use(\"*\", cors(defaultCorsOpts as Parameters<typeof cors>[0]));\n};\n\n/**\n * Apply a single route-specific CORS rule\n */\nconst applyRouteCorsRule = (\n app: Hono,\n rule: NonNullable<CorsConfig[\"addCors\"]>[number],\n defaultOpts: CorsOptions\n): void => {\n if (rule.resolver) {\n applyResolverBasedCors(app, rule.path, rule.resolver, defaultOpts);\n } else if (rule.options) {\n applyStaticCors(app, rule.path, rule.options, defaultOpts);\n }\n};\n\n/**\n * Apply resolver-based CORS for a specific path\n */\nconst applyResolverBasedCors = (\n app: Hono,\n path: string,\n resolver: NonNullable<CorsConfig[\"addCors\"]>[number][\"resolver\"],\n defaultOpts: CorsOptions\n): void => {\n if (!resolver) {\n return;\n }\n\n app.use(path, (c, next) => {\n const reqOrigin = c.req.header(\"origin\") ?? \"\";\n const corsOpts = evaluateResolver(resolver, reqOrigin, c, defaultOpts);\n return cors(corsOpts as Parameters<typeof cors>[0])(c, next);\n });\n};\n\n/**\n * Apply static CORS options for a specific path\n */\nconst applyStaticCors = (\n app: Hono,\n path: string,\n options: CorsOptions,\n defaultOpts: CorsOptions\n): void => {\n app.use(\n path,\n cors({ ...defaultOpts, ...options } as Parameters<typeof cors>[0])\n );\n};\n\n/**\n * Evaluate CORS resolver and return appropriate options\n */\nconst evaluateResolver = (\n resolver: NonNullable<CorsConfig[\"addCors\"]>[number][\"resolver\"],\n origin: string,\n c: Context,\n defaultOpts: CorsOptions\n): CorsOptions => {\n if (!resolver) {\n return defaultOpts;\n }\n\n try {\n const result = resolver(origin, c);\n\n if (result === true) {\n return { ...defaultOpts, origin: origin || \"*\" };\n }\n\n if (result === false) {\n return { ...defaultOpts, origin: \"\" };\n }\n\n if (result && typeof result === \"object\") {\n return { ...defaultOpts, ...result };\n }\n\n return defaultOpts;\n } catch (error) {\n // Security: deny on resolver failure — never fall through to allow\n console.error(\"CORS resolver error:\", error);\n return { ...defaultOpts, origin: \"\" };\n }\n};\n","import { Ok, type Result } from \"slang-ts\";\nimport z from \"zod\";\nimport type { Engine } from \"@/engine/types\";\nimport type {\n ExternalRequest,\n ExternalResponse,\n NileContext,\n} from \"@/nile/types\";\n\n// --- Response mapping ---\n\n/**\n * Maps an internal Result to the external API response shape.\n * This is the single point where internal Result types cross the boundary\n * into the HTTP-facing ExternalResponse format.\n */\nexport function toExternalResponse(\n result: Result<unknown, string>,\n successMessage: string\n): ExternalResponse {\n if (result.isOk) {\n const value = result.value;\n const data =\n value !== null && typeof value === \"object\" && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : { result: value };\n\n return { status: true, message: successMessage, data };\n }\n\n return { status: false, message: result.error, data: {} };\n}\n\n// --- Intent handlers ---\n\n/**\n * Handles the \"explore\" intent for service/action discovery.\n * - service: \"*\", action: \"*\" -> list all services\n * - service: \"name\", action: \"*\" -> list actions for service\n * - service: \"name\", action: \"name\" -> action metadata\n */\nexport function handleExplore(\n engine: Engine,\n request: ExternalRequest\n): ExternalResponse {\n const { service, action } = request;\n\n if (service === \"*\") {\n return toExternalResponse(engine.getServices(), \"Available services\");\n }\n\n if (action === \"*\") {\n return toExternalResponse(\n engine.getServiceActions(service),\n `Actions for '${service}'`\n );\n }\n\n const actionResult = engine.getAction(service, action);\n if (actionResult.isErr) {\n return toExternalResponse(actionResult, \"\");\n }\n\n const act = actionResult.value;\n return toExternalResponse(\n Ok({\n name: act.name,\n description: act.description,\n isProtected: act.isProtected ?? false,\n accessControl: act.accessControl,\n hooks: act.hooks\n ? { before: act.hooks.before ?? [], after: act.hooks.after ?? [] }\n : null,\n meta: act.meta ?? null,\n }),\n `Details for '${service}.${action}'`\n );\n}\n\n/**\n * Handles the \"execute\" intent by running an action through the engine pipeline.\n */\nexport async function handleExecute(\n engine: Engine,\n request: ExternalRequest,\n nileContext: NileContext<unknown>\n): Promise<ExternalResponse> {\n const { service, action, payload } = request;\n\n if (service === \"*\" || action === \"*\") {\n return {\n status: false,\n message:\n \"Execute intent requires specific service and action, wildcards not allowed\",\n data: {},\n };\n }\n\n const result = await engine.executeAction(\n service,\n action,\n payload,\n nileContext\n );\n\n return toExternalResponse(result, `Action '${service}.${action}' executed`);\n}\n\n/**\n * Handles the \"schema\" intent for Zod-to-JSON-Schema export.\n * - service: \"*\", action: \"*\" -> all schemas across all services\n * - service: \"name\", action: \"*\" -> all schemas in a service\n * - service: \"name\", action: \"name\" -> single action schema\n */\nexport function handleSchema(\n engine: Engine,\n request: ExternalRequest\n): ExternalResponse {\n const { service, action } = request;\n\n if (service === \"*\") {\n const servicesResult = engine.getServices();\n if (servicesResult.isErr) {\n return toExternalResponse(servicesResult, \"\");\n }\n\n const schemas: Record<string, unknown> = {};\n for (const svc of servicesResult.value) {\n const actionsResult = engine.getServiceActions(svc.name);\n if (actionsResult.isErr) {\n continue;\n }\n\n schemas[svc.name] = buildServiceSchemas(\n engine,\n svc.name,\n actionsResult.value.map((a) => a.name)\n );\n }\n\n return toExternalResponse(Ok(schemas), \"All service schemas\");\n }\n\n if (action === \"*\") {\n const actionsResult = engine.getServiceActions(service);\n if (actionsResult.isErr) {\n return toExternalResponse(actionsResult, \"\");\n }\n\n const schemas = buildServiceSchemas(\n engine,\n service,\n actionsResult.value.map((a) => a.name)\n );\n return toExternalResponse(Ok(schemas), `Schemas for '${service}'`);\n }\n\n const actionResult = engine.getAction(service, action);\n if (actionResult.isErr) {\n return toExternalResponse(actionResult, \"\");\n }\n\n const schema = extractActionSchema(actionResult.value);\n return toExternalResponse(\n Ok({ [action]: schema }),\n `Schema for '${service}.${action}'`\n );\n}\n\n/**\n * Builds a map of action schemas for a service\n */\nfunction buildServiceSchemas(\n engine: Engine,\n serviceName: string,\n actionNames: string[]\n): Record<string, unknown> {\n const schemas: Record<string, unknown> = {};\n\n for (const actionName of actionNames) {\n const actionResult = engine.getAction(serviceName, actionName);\n if (actionResult.isErr) {\n continue;\n }\n schemas[actionName] = extractActionSchema(actionResult.value);\n }\n\n return schemas;\n}\n\n/**\n * Extracts JSON schema from an action's zod validation, returns null on failure\n */\nfunction extractActionSchema(action: {\n validation?: import(\"zod\").ZodType | null;\n}): unknown {\n const schema = action.validation;\n if (!schema) {\n return null;\n }\n\n const { err, result } = safeTrySync(() =>\n z.toJSONSchema(schema, { unrepresentable: \"any\" })\n );\n\n return err ? null : result;\n}\n\n/**\n * Synchronous try-catch wrapper for simple operations.\n * Unlike slang-ts safeTry (always async), this is for sync-only code paths.\n */\nfunction safeTrySync<T>(fn: () => T): { err: unknown; result: T | null } {\n try {\n return { err: null, result: fn() };\n } catch (error) {\n return { err: error, result: null };\n }\n}\n\n// --- Intent dispatch ---\n\n/** Object lookup for intent handlers — cleaner than switch/if-else */\nexport const intentHandlers: Record<\n ExternalRequest[\"intent\"],\n (\n engine: Engine,\n request: ExternalRequest,\n nileContext: NileContext<unknown>\n ) => ExternalResponse | Promise<ExternalResponse>\n> = {\n explore: (engine, request) => handleExplore(engine, request),\n execute: (engine, request, nileContext) =>\n handleExecute(engine, request, nileContext),\n schema: (engine, request) => handleSchema(engine, request),\n};\n","import type { Hono } from \"hono\";\nimport { rateLimiter } from \"hono-rate-limiter\";\nimport { safeTry } from \"slang-ts\";\nimport type { ServerRuntime } from \"@/nile/types\";\nimport type { RestConfig } from \"./types\";\n\nconst ASSETS_REGEX = /^\\/assets\\//;\nconst DEFAULT_RATE_LIMIT_WINDOW_MS = 15 * 60 * 1000; // 15 minutes\nconst DEFAULT_RATE_LIMIT_MAX = 100;\nconst UNKNOWN_CLIENT_KEY = \"__unknown_client__\";\n\n/**\n * Applies rate limiting middleware when a limiting header is configured.\n * Extracts the client key from the configured request header for per-client tracking.\n * Falls back to a shared key when the header is missing (graceful degradation).\n */\nexport function applyRateLimiting(\n app: Hono,\n config: RestConfig,\n log: (msg: string, data?: unknown) => void\n): void {\n if (!config.rateLimiting?.limitingHeader) {\n return;\n }\n\n const { rateLimiting } = config;\n\n app.use(\n rateLimiter({\n windowMs: rateLimiting.windowMs ?? DEFAULT_RATE_LIMIT_WINDOW_MS,\n limit: rateLimiting.limit ?? DEFAULT_RATE_LIMIT_MAX,\n standardHeaders: rateLimiting.standardHeaders ?? true,\n keyGenerator: (c) => {\n const key = c.req.header(rateLimiting.limitingHeader);\n if (!key) {\n log(\n `Rate limiting header '${rateLimiting.limitingHeader}' missing from request`\n );\n return UNKNOWN_CLIENT_KEY;\n }\n return key;\n },\n store: rateLimiting.store ?? undefined,\n })\n );\n\n log(\n `Rate limiting enabled: ${rateLimiting.limit ?? DEFAULT_RATE_LIMIT_MAX} requests per ${rateLimiting.windowMs ?? DEFAULT_RATE_LIMIT_WINDOW_MS}ms window`\n );\n}\n\n/**\n * Applies static file serving from ./assets at /assets/*.\n * Uses dynamic import to load the runtime-specific serveStatic adapter,\n * avoiding issues with Bun globals in non-Bun environments (e.g. vitest).\n * Import errors are caught gracefully — static serving is skipped if the adapter fails to load.\n */\nexport function applyStaticServing(\n app: Hono,\n config: RestConfig,\n runtime: ServerRuntime,\n log: (msg: string, data?: unknown) => void\n): void {\n if (!config.enableStatic) {\n return;\n }\n\n if (runtime !== \"bun\") {\n log(`Static file serving not yet supported for runtime: ${runtime}`);\n return;\n }\n\n // Lazy-load the bun serveStatic adapter to avoid referencing Bun globals at import time\n let cachedHandler:\n | ((c: never, next: never) => Promise<Response | undefined>)\n | null = null;\n let importFailed = false;\n\n app.use(\"/assets/*\", async (c, next) => {\n if (importFailed) {\n return next();\n }\n\n if (!cachedHandler) {\n const importResult = await safeTry(async () => {\n const mod = await import(\"hono/bun\");\n return mod.serveStatic({\n root: \"./assets\",\n rewriteRequestPath: (path: string) => path.replace(ASSETS_REGEX, \"\"),\n });\n });\n\n if (importResult.isErr) {\n log(\"Failed to load static file adapter\", importResult.error);\n importFailed = true;\n return next();\n }\n\n cachedHandler = importResult.value as unknown as typeof cachedHandler;\n }\n\n if (cachedHandler) {\n return cachedHandler(c as never, next as never);\n }\n });\n\n log(\"Static file serving enabled at /assets/*\");\n}\n","import type { BaseContext, NileContext, Resources, Sessions } from \"./types\";\n\ninterface CreateNileContextParams<TDB = unknown> {\n interfaceContext?: BaseContext;\n resources?: Resources<TDB>;\n}\n\n/**\n * Creates a new Nile context with an internal key-value store.\n * The context carries interface-specific data (REST, WebSocket, RPC),\n * hook execution context, and provides get/set methods for storing arbitrary values.\n *\n * Sessions are instance-scoped — each NileContext owns its own session store,\n * so multiple server instances don't share authentication state.\n *\n * @param params - Optional configuration including interface adapters and shared resources\n * @returns A fully initialized NileContext\n */\nexport function createNileContext<TDB = unknown>(\n params?: CreateNileContextParams<TDB>\n): NileContext<TDB> {\n const store = new Map<string, unknown>();\n const interfaceContext = params?.interfaceContext;\n\n /** Instance-scoped session store — not shared across server instances */\n const sessions: Sessions = {};\n\n const context: NileContext<TDB> = {\n rest: interfaceContext?.rest,\n ws: interfaceContext?.ws,\n rpc: interfaceContext?.rpc,\n resources: params?.resources,\n sessions,\n _store: store,\n\n get<T = unknown>(key: string): T | undefined {\n return store.get(key) as T | undefined;\n },\n\n set<T = unknown>(key: string, value: T): void {\n store.set(key, value);\n },\n\n getSession(name: keyof Sessions) {\n return sessions[name];\n },\n\n setSession(name: keyof Sessions, data: Record<string, unknown>) {\n sessions[name] = data;\n },\n\n hookContext: {\n actionName: \"\",\n input: null,\n state: {},\n log: { before: [], after: [] },\n },\n\n updateHookState(key: string, value: unknown) {\n context.hookContext.state[key] = value;\n },\n\n addHookLog(\n phase: \"before\" | \"after\",\n logEntry: {\n name: string;\n input: unknown;\n output: unknown;\n passed: boolean;\n }\n ) {\n context.hookContext.log[phase].push(logEntry);\n },\n\n setHookError(error: string) {\n context.hookContext.error = error;\n },\n\n setHookOutput(output: unknown) {\n context.hookContext.output = output;\n },\n\n resetHookContext(actionName: string, input: unknown) {\n context.hookContext = {\n actionName,\n input,\n state: {},\n log: { before: [], after: [] },\n };\n },\n };\n\n return context;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACMO,SAAS,aAAa,QAAwB;AACnD,SAAO;AACT;AAMO,SAAS,cAAc,SAA6B;AACzD,SAAO;AACT;;;ACVO,SAAS,cAAc,QAA0B;AACtD,SAAO;AACT;AAMO,SAAS,eAAe,SAA+B;AAC5D,SAAO;AACT;;;AChBA,qBAMO;AACP,uBAAqB;AACrB,oBAAuB;AACvB,kBAAkC;AAkBlC,IAAM,UAAU,MAAM;AACpB,MAAI,CAAC,QAAQ,IAAI,MAAM;AACrB,UAAM,IAAI,MAAM,mCAAmC;AAAA,EACrD;AACA,SAAO,QAAQ,IAAI;AACrB;AAEA,IAAM,aAAS,uBAAK,QAAQ,IAAI,GAAG,MAAM;AAEzC,IAAI,KAAC,2BAAW,MAAM,GAAG;AACvB,gCAAU,MAAM;AAClB;AAGA,IAAM,kBAAkB;AACxB,IAAM,gBAAgB;AACtB,IAAM,iBAAiB;AAShB,SAAS,eAAe,SAAiB,QAA+B;AAC7E,QAAM,WAAW,QAAQ,YAAY;AAErC,MAAI,aAAa,QAAQ;AACvB,eAAO,uBAAK,QAAQ,GAAG,OAAO,MAAM;AAAA,EACtC;AAEA,QAAM,aAAS,uBAAK,QAAQ,OAAO;AACnC,MAAI,KAAC,2BAAW,MAAM,GAAG;AACvB,kCAAU,QAAQ,EAAE,WAAW,KAAK,CAAC;AAAA,EACvC;AAEA,QAAM,MAAM,oBAAI,KAAK;AACrB,QAAM,QAAQ,gBAAgB,KAAK,QAAQ;AAC3C,aAAO,uBAAK,QAAQ,GAAG,KAAK,MAAM;AACpC;AAMO,SAAS,gBACd,MACA,UACQ;AACR,QAAM,OAAO,KAAK,YAAY;AAC9B,QAAM,QAAQ,OAAO,KAAK,SAAS,IAAI,CAAC,EAAE,SAAS,GAAG,GAAG;AAEzD,MAAI,aAAa,WAAW;AAC1B,WAAO,GAAG,IAAI,IAAI,KAAK;AAAA,EACzB;AAEA,MAAI,aAAa,SAAS;AACxB,UAAM,MAAM,OAAO,KAAK,QAAQ,CAAC,EAAE,SAAS,GAAG,GAAG;AAClD,WAAO,GAAG,IAAI,IAAI,KAAK,IAAI,GAAG;AAAA,EAChC;AAGA,QAAM,UAAU,iBAAiB,IAAI;AACrC,SAAO,GAAG,IAAI,KAAK,OAAO,OAAO,EAAE,SAAS,GAAG,GAAG,CAAC;AACrD;AAGA,SAAS,iBAAiB,MAAoB;AAC5C,QAAM,SAAS,IAAI,KAAK,KAAK,QAAQ,CAAC;AAEtC,QAAM,SAAS,OAAO,OAAO,KAAK;AAClC,SAAO,QAAQ,OAAO,QAAQ,IAAI,IAAI,MAAM;AAC5C,QAAM,YAAY,IAAI,KAAK,OAAO,YAAY,GAAG,GAAG,CAAC;AACrD,SAAO,KAAK;AAAA,MACR,OAAO,QAAQ,IAAI,UAAU,QAAQ,KAAK,QAAa,KAAK;AAAA,EAChE;AACF;AAMA,SAAS,mBAAmB,SAAiB,QAA+B;AAC1E,QAAM,UAAU,eAAe,SAAS,MAAM;AAE9C,QAAM,YAAY,YAAAA,QAAK,UAAU;AAAA,IAC/B,SAAS;AAAA,MACP;AAAA,QACE,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,SAAS;AAAA,UACP,aAAa;AAAA,UACb,OAAO;AAAA,QACT;AAAA,MACF;AAAA,IACF;AAAA,EACF,CAAC;AAED,aAAO,YAAAA;AAAA,IACL;AAAA,MACE,MAAM;AAAA,MACN,WAAW,MAAM,aAAY,oBAAI,KAAK,GAAE,YAAY,CAAC;AAAA,MACrD,YAAY;AAAA,QACV,MAAM,OAAO;AACX,iBAAO,EAAE,OAAO,MAAM;AAAA,QACxB;AAAA,MACF;AAAA,IACF;AAAA,IACA;AAAA,EACF;AACF;AAUO,IAAM,YAAY,CAAC,KAAU,WAA0B;AAC5D,MAAI,CAAC,IAAI,SAAS;AAChB,UAAM,IAAI,MAAM,2BAA2B,KAAK,UAAU,GAAG,CAAC,EAAE;AAAA,EAClE;AAEA,QAAM,QAAQ,IAAI,SAAS;AAC3B,QAAM,SAAS,IAAI,cAAU,sBAAO,CAAC;AAErC,QAAM,YAAY;AAAA,IAChB;AAAA,IACA,SAAS,IAAI;AAAA,IACb,YAAY,IAAI;AAAA,IAChB,SAAS,IAAI;AAAA,IACb,MAAM,IAAI,QAAQ;AAAA,IAClB;AAAA,IACA,OAAM,oBAAI,KAAK,GAAE,YAAY;AAAA,EAC/B;AAEA,QAAM,OAAO,QAAQ;AAErB,MAAI,SAAS,UAAU,QAAQ,IAAI,aAAa,QAAQ;AACtD,UAAM,UAAU,eAAe,IAAI,SAAS,MAAM;AAElD,QAAI,QAAQ,IAAI,aAAa,QAAQ;AAEnC,yCAAe,SAAS,GAAG,KAAK,UAAU,SAAS,CAAC;AAAA,GAAM,OAAO;AAAA,IACnE,OAAO;AAEL,YAAM,YAAY,mBAAmB,IAAI,SAAS,MAAM;AACxD,gBAAU,KAAkC,EAAE,SAAS;AAAA,IACzD;AACA,WAAO;AAAA,EACT;AAEA,MAAI,SAAS,WAAW;AACtB,WAAO,KAAK,UAAU,SAAS;AAAA,EACjC;AAEA,UAAQ,IAAI;AAAA,IACV,GAAG;AAAA,IACH,MAAM,KAAK,UAAU,UAAU,MAAM,MAAM,CAAC;AAAA,EAC9C,CAAC;AACD,SAAO;AACT;AAmBO,IAAM,UAAU,CACrB,UAAqB,CAAC,GACtB,WACU;AACV,QAAM,WAAW,QAAQ,YAAY;AAErC,QAAM,cAAc,gBAAgB,SAAS,QAAQ;AACrD,QAAM,OAAO,qBAAqB,WAAW;AAC7C,SAAO,gBAAgB,MAAM,OAAO;AACtC;AAOA,SAAS,gBACP,SACA,UACU;AACV,MAAI,aAAa,QAAQ;AACvB,UAAM,UAAU,QAAQ,cACpB,uBAAK,QAAQ,GAAG,QAAQ,OAAO,MAAM,QACrC,uBAAK,QAAQ,SAAS;AAC1B,eAAO,2BAAW,OAAO,IAAI,CAAC,OAAO,IAAI,CAAC;AAAA,EAC5C;AAGA,MAAI,CAAC,QAAQ,SAAS;AACpB,WAAO,CAAC;AAAA,EACV;AAEA,QAAM,aAAS,uBAAK,QAAQ,QAAQ,OAAO;AAC3C,MAAI,KAAC,2BAAW,MAAM,GAAG;AACvB,WAAO,CAAC;AAAA,EACV;AAEA,QAAM,eAAW,4BAAY,MAAM,EAChC,OAAO,CAAC,MAAM,EAAE,SAAS,MAAM,CAAC,EAChC,KAAK;AAGR,MAAI,EAAE,QAAQ,QAAQ,QAAQ,KAAK;AACjC,WAAO,SAAS,IAAI,CAAC,UAAM,uBAAK,QAAQ,CAAC,CAAC;AAAA,EAC5C;AAGA,SAAO,SACJ,OAAO,CAAC,aAAa,gBAAgB,UAAU,UAAU,OAAO,CAAC,EACjE,IAAI,CAAC,UAAM,uBAAK,QAAQ,CAAC,CAAC;AAC/B;AAMA,SAAS,gBACP,UACA,UACA,SACS;AAET,QAAM,YAAY,SAAS,QAAQ,QAAQ,EAAE;AAC7C,QAAM,QAAQ,kBAAkB,WAAW,QAAQ;AAEnD,MAAI,CAAC,OAAO;AACV,WAAO;AAAA,EACT;AAEA,QAAM,EAAE,OAAO,IAAI,IAAI;AAGvB,MAAI,QAAQ,MAAM,QAAQ,QAAQ,IAAI;AACpC,WAAO;AAAA,EACT;AACA,MAAI,QAAQ,QAAQ,MAAM,QAAQ,MAAM;AACtC,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAMA,SAAS,kBACP,WACA,UACmC;AACnC,MAAI,aAAa,WAAW;AAE1B,UAAMC,SAAQ,UAAU,MAAM,eAAe;AAC7C,QAAI,EAAEA,SAAQ,CAAC,KAAKA,OAAM,CAAC,IAAI;AAC7B,aAAO;AAAA,IACT;AACA,UAAMC,QAAO,OAAOD,OAAM,CAAC,CAAC;AAC5B,UAAM,QAAQ,OAAOA,OAAM,CAAC,CAAC,IAAI;AACjC,UAAME,SAAQ,IAAI,KAAKD,OAAM,OAAO,CAAC;AACrC,UAAME,OAAM,IAAI,KAAKF,OAAM,QAAQ,GAAG,GAAG,IAAI,IAAI,IAAI,GAAG;AACxD,WAAO,EAAE,OAAAC,QAAO,KAAAC,KAAI;AAAA,EACtB;AAEA,MAAI,aAAa,SAAS;AAExB,UAAMH,SAAQ,UAAU,MAAM,aAAa;AAC3C,QAAI,EAAEA,SAAQ,CAAC,KAAKA,OAAM,CAAC,KAAKA,OAAM,CAAC,IAAI;AACzC,aAAO;AAAA,IACT;AACA,UAAMC,QAAO,OAAOD,OAAM,CAAC,CAAC;AAC5B,UAAM,QAAQ,OAAOA,OAAM,CAAC,CAAC,IAAI;AACjC,UAAM,MAAM,OAAOA,OAAM,CAAC,CAAC;AAC3B,UAAME,SAAQ,IAAI,KAAKD,OAAM,OAAO,GAAG;AACvC,UAAME,OAAM,IAAI,KAAKF,OAAM,OAAO,KAAK,IAAI,IAAI,IAAI,GAAG;AACtD,WAAO,EAAE,OAAAC,QAAO,KAAAC,KAAI;AAAA,EACtB;AAGA,QAAM,QAAQ,UAAU,MAAM,cAAc;AAC5C,MAAI,EAAE,QAAQ,CAAC,KAAK,MAAM,CAAC,IAAI;AAC7B,WAAO;AAAA,EACT;AACA,QAAM,OAAO,OAAO,MAAM,CAAC,CAAC;AAC5B,QAAM,OAAO,OAAO,MAAM,CAAC,CAAC;AAC5B,QAAM,QAAQ,mBAAmB,MAAM,IAAI;AAC3C,QAAM,MAAM,IAAI,KAAK,KAAK;AAC1B,MAAI,QAAQ,IAAI,QAAQ,IAAI,CAAC;AAC7B,MAAI,SAAS,IAAI,IAAI,IAAI,GAAG;AAC5B,SAAO,EAAE,OAAO,IAAI;AACtB;AAGA,SAAS,mBAAmB,MAAc,MAAoB;AAC5D,QAAM,OAAO,IAAI,KAAK,MAAM,GAAG,CAAC;AAChC,QAAM,YAAY,KAAK,OAAO,KAAK;AAEnC,QAAM,SAAS,IAAI,KAAK,IAAI;AAC5B,SAAO,QAAQ,KAAK,QAAQ,IAAI,YAAY,CAAC;AAE7C,SAAO,QAAQ,OAAO,QAAQ,KAAK,OAAO,KAAK,CAAC;AAChD,SAAO,SAAS,GAAG,GAAG,GAAG,CAAC;AAC1B,SAAO;AACT;AAGA,SAAS,qBAAqB,OAA4C;AACxE,QAAM,OAAkC,CAAC;AAEzC,aAAW,QAAQ,OAAO;AACxB,QAAI,KAAC,2BAAW,IAAI,GAAG;AACrB;AAAA,IACF;AAEA,UAAM,cAAU,6BAAa,MAAM,OAAO,EAAE,KAAK;AACjD,QAAI,CAAC,SAAS;AACZ;AAAA,IACF;AAEA,UAAM,QAAQ,QAAQ,MAAM,IAAI;AAChC,eAAW,QAAQ,OAAO;AACxB,UAAI;AACF,cAAM,SAAS,KAAK,MAAM,IAAI;AAC9B,aAAK,KAAK,MAAM;AAAA,MAClB,QAAQ;AAAA,MAER;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAGA,SAAS,gBACP,MACA,SACO;AACP,SAAO,KAAK,OAAO,CAAC,QAAQ;AAC1B,QAAI,QAAQ,WAAW,IAAI,YAAY,QAAQ,SAAS;AACtD,aAAO;AAAA,IACT;AACA,QAAI,QAAQ,UAAU,IAAI,WAAW,QAAQ,QAAQ;AACnD,aAAO;AAAA,IACT;AACA,QAAI,QAAQ,SAAS,IAAI,UAAU,QAAQ,OAAO;AAChD,aAAO;AAAA,IACT;AAEA,UAAM,OAAO,IAAI,KAAK,IAAI,IAAc;AACxC,QAAI,QAAQ,QAAQ,OAAO,QAAQ,MAAM;AACvC,aAAO;AAAA,IACT;AACA,QAAI,QAAQ,MAAM,OAAO,QAAQ,IAAI;AACnC,aAAO;AAAA,IACT;AAEA,WAAO;AAAA,EACT,CAAC;AACH;;;AC9YO,IAAM,eAAe,CAAC,SAAiB,WAA0B;AACtE,SAAO;AAAA,IACL,MAAM,CAAC,UACL,UAAO,EAAE,GAAG,OAAO,SAAS,OAAO,OAAO,GAAG,MAAM;AAAA,IACrD,MAAM,CAAC,UACL,UAAO,EAAE,GAAG,OAAO,SAAS,OAAO,OAAO,GAAG,MAAM;AAAA,IACrD,OAAO,CAAC,UACN,UAAO,EAAE,GAAG,OAAO,SAAS,OAAO,QAAQ,GAAG,MAAM;AAAA,EACxD;AACF;;;ACnBA,IAAAC,mBAAwB;;;ACAxB,IAAAC,mBAAqC;;;ACArC,yBAA8C;AAC9C,IAAAC,mBAA4B;;;ACD5B,sBAAsD;AAmBtD,IAAM,oBAAoB;AAE1B,SAAS,kBAA0B;AAEjC,QAAM,OAAO,IAAI,MAAM,qBAAqB;AAC5C,QAAM,QAAQ,KAAK;AACnB,QAAM,aAAa,OAAO,MAAM,IAAI,EAAE,CAAC,KAAK;AAC5C,QAAM,QAAQ,WAAW,MAAM,iBAAiB;AAChD,SAAO,QAAQ,CAAC,KAAK;AACvB;AAEA,SAAS,cAAc,UAAmC;AACxD,MAAI,UAAU;AACZ,WAAO;AAAA,EACT;AACA,MAAI;AACF,UAAM,MAAM,WAAW;AACvB,QAAI,IAAI,WAAW,QAAQ;AACzB,aAAO,IAAI,UAAU;AAAA,IACvB;AAAA,EACF,SAAS,GAAG;AAAA,EAEZ;AACA,QAAM,IAAI;AAAA,IACR;AAAA,EACF;AACF;AAqBO,SAAS,YACd,QACwC;AACxC,QAAM,aAAa,OAAO,cAAc,gBAAgB;AACxD,QAAM,SAAS,cAAc,OAAO,MAAM;AAC1C,QAAM,QAAQ,OAAO,MAAM;AAAA,IACzB;AAAA,IACA,SAAS,OAAO;AAAA,IAChB,MAAM,OAAO;AAAA,EACf,CAAC;AACD,aAAO,qBAAI,IAAI,KAAK,KAAK,OAAO,OAAO,EAAE;AAC3C;;;ACnDO,SAAS,yBAKd,IACsD;AACtD,SAAO,OAAO,WAAqD;AACjE,UAAM,EAAE,KAAK,GAAG,KAAK,IAAI;AAEzB,QAAI,CAAC,KAAK;AACR,YAAMC,UAAS,MAAM,GAAG,MAAiB;AACzC,UAAIA,QAAO,OAAO;AAChB,cAAM,IAAI,MAAM,OAAOA,QAAO,KAAK,CAAC;AAAA,MACtC;AACA,aAAOA;AAAA,IACT;AAEA,UAAM,iBACJ,OAAQ,KAAiC,gBAAgB;AAE3D,QAAI,gBAAgB;AAClB,aAAO,MACL,IAKA,YAAY,OAAO,OAAgB;AACnC,cAAMA,UAAS,MAAM,GAAG,EAAE,GAAG,MAAM,KAAK,GAAG,CAAY;AACvD,YAAIA,QAAO,OAAO;AAChB,gBAAM,IAAI,MAAM,OAAOA,QAAO,KAAK,CAAC;AAAA,QACtC;AACA,eAAOA;AAAA,MACT,CAAC;AAAA,IACH;AAEA,UAAM,SAAS,MAAM,GAAG,EAAE,GAAG,MAAM,IAAI,CAAY;AACnD,QAAI,OAAO,OAAO;AAChB,YAAM,IAAI,MAAM,OAAO,OAAO,KAAK,CAAC;AAAA,IACtC;AACA,WAAO;AAAA,EACT;AACF;;;ACrEA,yBAIO;AAmBA,SAAS,aACd,OACsB;AACtB,QAAM,aACJ,OAAO,OAAO,OAAiB,QAAQ,KACvC,OAAO,OAAO,OAAiB,OAAO;AAExC,MAAI,YAAY;AACd,UAAM,IAAI;AAAA,MACR,GAAG,OAAO,KAAK,CAAC;AAAA,IAClB;AAAA,EACF;AAEA,QAAM,mBAAe;AAAA,IACnB;AAAA,EACF;AACA,QAAM,mBAAe;AAAA,IACnB;AAAA,EACF;AACA,QAAM,mBAAe;AAAA,IACnB;AAAA,EACF;AAEA,SAAO;AAAA,IACL,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,EACV;AACF;;;AHKA,SAAS,KAAK,IAA4B;AACxC,SAAO;AACT;AAMA,SAAS,UAAe,YAAkC;AACxD,MAAI,YAAY;AACd,WAAO;AAAA,EACT;AAEA,MAAI;AACF,UAAM,MAAM,WAAW;AACvB,QAAI,IAAI,WAAW,UAAU;AAC3B,aAAO,IAAI,UAAU;AAAA,IACvB;AAAA,EACF,SAAS,GAAG;AAAA,EAEZ;AACA,QAAM,IAAI;AAAA,IACR;AAAA,EACF;AACF;AAMA,SAAS,oBAAoB,OAA+C;AAC1E,MAAI,gBAAgB,OAAO;AACzB,WAAO;AAAA,EACT;AACA,MAAI,eAAe,OAAO;AACxB,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAiCO,SAAS,YAId,OACA,SACsE;AAItE,QAAM,EAAE,MAAM,eAAe,KAAK,IAAI;AACtC,QAAM,aAAa,KAAK,OAAO,CAAC,EAAE,YAAY,IAAI,KAAK,MAAM,CAAC;AAC9D,QAAM,UAAU,aAAa,KAAK;AAClC,QAAM,WAAW;AAGjB,QAAM,QAAQ,MAAM,KAAK,UAAe,QAAQ,EAAE,CAAC;AAInD,QAAM,SAAS,OAAO,EAAE,MAAM,IAAI,MAAsC;AACtE,UAAM,SAAS,QAAQ,OAAO,UAAU,IAAI;AAC5C,QAAI,CAAC,OAAO,SAAS;AACnB,aAAO,YAAY;AAAA,QACjB,SAAS,WAAW,IAAI;AAAA,QACxB,MAAM,EAAE,QAAQ,OAAO,MAAM;AAAA,QAC7B,YAAY,GAAG,IAAI;AAAA,MACrB,CAAC;AAAA,IACH;AAEA,UAAM,KAAK,MAAM,KAAK,GAAG,IAAI,MAAM;AACnC,UAAM,SAAS,UAAM;AAAA,MAAQ,MAC3B,GAAG,OAAO,KAAK,EAAE,OAAO,IAAI,EAAE,UAAU;AAAA,IAC1C;AACA,QAAI,OAAO,OAAO;AAChB,aAAO,YAAY;AAAA,QACjB,SAAS,kBAAkB,IAAI;AAAA,QAC/B,MAAM,EAAE,OAAO,OAAO,MAAM;AAAA,QAC5B,YAAY,GAAG,IAAI;AAAA,MACrB,CAAC;AAAA,IACH;AAEA,UAAM,MAAO,OAAO,QAAsB,CAAC,KAAK;AAChD,QAAI,CAAC,KAAK;AACR,aAAO,YAAY;AAAA,QACjB,SAAS,GAAG,UAAU;AAAA,QACtB,YAAY,GAAG,IAAI;AAAA,MACrB,CAAC;AAAA,IACH;AACA,eAAO,qBAAG,GAAG;AAAA,EACf;AAEA,QAAM,SAAS,OAAO,EAAE,IAAI,MAAM,IAAI,MAAuC;AAC3E,UAAM,SAAS,QAAQ,OAAO,UAAU,IAAI;AAC5C,QAAI,CAAC,OAAO,SAAS;AACnB,aAAO,YAAY;AAAA,QACjB,SAAS,WAAW,IAAI;AAAA,QACxB,MAAM,EAAE,QAAQ,OAAO,MAAM;AAAA,QAC7B,YAAY,GAAG,IAAI;AAAA,MACrB,CAAC;AAAA,IACH;AAEA,UAAM,KAAK,MAAM,KAAK,GAAG,IAAI,MAAM;AACnC,UAAM,QAAQ,SAAS;AACvB,UAAM,SAAS,UAAM;AAAA,MAAQ,MAC3B,GAAG,OAAO,KAAK,EAAE,IAAI,IAAI,EAAE,UAAM,uBAAG,OAAO,EAAE,CAAC,EAAE,UAAU;AAAA,IAC5D;AACA,QAAI,OAAO,OAAO;AAChB,aAAO,YAAY;AAAA,QACjB,SAAS,kBAAkB,IAAI;AAAA,QAC/B,MAAM,EAAE,IAAI,OAAO,OAAO,MAAM;AAAA,QAChC,YAAY,GAAG,IAAI;AAAA,MACrB,CAAC;AAAA,IACH;AAEA,UAAM,MAAO,OAAO,QAAsB,CAAC,KAAK;AAChD,QAAI,CAAC,KAAK;AACR,aAAO,YAAY;AAAA,QACjB,SAAS,GAAG,UAAU;AAAA,QACtB,MAAM,EAAE,GAAG;AAAA,QACX,YAAY,GAAG,IAAI;AAAA,MACrB,CAAC;AAAA,IACH;AACA,eAAO,qBAAG,GAAG;AAAA,EACf;AAGA,QAAM,WAAW;AAAA,IACf;AAAA,EACF;AACA,QAAM,WAAW;AAAA,IACf;AAAA,EACF;AAEA,QAAM,WAAW,OAAO,OAAe;AACrC,UAAM,KAAK,MAAM;AACjB,UAAM,QAAQ,SAAS;AACvB,UAAM,SAAS,UAAM;AAAA,MAAQ,MAC3B,GAAG,OAAO,EAAE,KAAK,KAAK,EAAE,UAAM,uBAAG,OAAO,EAAE,CAAC;AAAA,IAC7C;AACA,QAAI,OAAO,OAAO;AAChB,aAAO,YAAY;AAAA,QACjB,SAAS,iBAAiB,IAAI;AAAA,QAC9B,MAAM,EAAE,IAAI,OAAO,OAAO,MAAM;AAAA,QAChC,YAAY,GAAG,IAAI;AAAA,MACrB,CAAC;AAAA,IACH;AAEA,UAAM,MAAO,OAAO,QAAsB,CAAC,KAAK;AAChD,QAAI,CAAC,KAAK;AACR,aAAO,YAAY;AAAA,QACjB,SAAS,GAAG,UAAU;AAAA,QACtB,MAAM,EAAE,GAAG;AAAA,QACX,YAAY,GAAG,IAAI;AAAA,MACrB,CAAC;AAAA,IACH;AACA,eAAO,qBAAG,GAAG;AAAA,EACf;AAEA,QAAM,WAAW,OAAO,OAAe;AACrC,UAAM,KAAK,MAAM;AACjB,UAAM,QAAQ,SAAS;AACvB,UAAM,SAAS,UAAM;AAAA,MAAQ,MAC3B,GAAG,OAAO,KAAK,EAAE,UAAM,uBAAG,OAAO,EAAE,CAAC,EAAE,UAAU;AAAA,IAClD;AACA,QAAI,OAAO,OAAO;AAChB,aAAO,YAAY;AAAA,QACjB,SAAS,kBAAkB,IAAI;AAAA,QAC/B,MAAM,EAAE,IAAI,OAAO,OAAO,MAAM;AAAA,QAChC,YAAY,GAAG,IAAI;AAAA,MACrB,CAAC;AAAA,IACH;AAEA,UAAM,MAAO,OAAO,QAAsB,CAAC,KAAK;AAChD,QAAI,CAAC,KAAK;AACR,aAAO,YAAY;AAAA,QACjB,SAAS,GAAG,UAAU;AAAA,QACtB,MAAM,EAAE,GAAG;AAAA,QACX,YAAY,GAAG,IAAI;AAAA,MACrB,CAAC;AAAA,IACH;AACA,eAAO,qBAAG,GAAG;AAAA,EACf;AAEA,QAAM,UAAU,YAAY;AAC1B,UAAM,KAAK,MAAM;AACjB,UAAM,QAAQ,oBAAoB,QAAQ;AAE1C,UAAM,SAAS,UAAM,0BAAQ,MAAM;AACjC,YAAM,QAAQ,GAAG,OAAO,EAAE,KAAK,KAAK;AACpC,UAAI,CAAC,OAAO;AACV,eAAO;AAAA,MACT;AACA,aAAO,MAAM,YAAQ,yBAAK,SAAS,KAAK,CAA+B,CAAC;AAAA,IAC1E,CAAC;AACD,QAAI,OAAO,OAAO;AAChB,aAAO,YAAY;AAAA,QACjB,SAAS,qBAAqB,IAAI;AAAA,QAClC,MAAM,EAAE,OAAO,OAAO,MAAM;AAAA,QAC5B,YAAY,GAAG,IAAI;AAAA,MACrB,CAAC;AAAA,IACH;AAEA,eAAO,qBAAI,OAAO,SAAS,CAAC,CAAe;AAAA,EAC7C;AAGA,QAAM,iBAAiB,OAAO,OAAe,WAAmB;AAC9D,UAAM,KAAK,MAAM;AACjB,UAAM,QAAQ,oBAAoB,QAAQ;AAE1C,UAAM,cAAc,UAAM,0BAAQ,MAAM;AACtC,YAAM,QAAQ,GAAG,OAAO,EAAE,KAAK,KAAK;AACpC,YAAM,UAAU,QACZ,MAAM,YAAQ,yBAAK,SAAS,KAAK,CAA+B,CAAC,IACjE;AACJ,aAAO,QAAQ,MAAM,KAAK,EAAE,OAAO,MAAM;AAAA,IAC3C,CAAC;AACD,QAAI,YAAY,OAAO;AACrB,aAAO,YAAY;AAAA,QACjB,SAAS,2BAA2B,IAAI;AAAA,QACxC,MAAM,EAAE,OAAO,QAAQ,OAAO,YAAY,MAAM;AAAA,QAChD,YAAY,GAAG,IAAI;AAAA,MACrB,CAAC;AAAA,IACH;AAEA,UAAM,cAAc,UAAM;AAAA,MAAQ,MAChC,GAAG,OAAO,EAAE,WAAO,0BAAM,EAAE,CAAC,EAAE,KAAK,KAAK;AAAA,IAC1C;AACA,QAAI,YAAY,OAAO;AACrB,aAAO,YAAY;AAAA,QACjB,SAAS,iBAAiB,IAAI;AAAA,QAC9B,MAAM,EAAE,OAAO,YAAY,MAAM;AAAA,QACjC,YAAY,GAAG,IAAI;AAAA,MACrB,CAAC;AAAA,IACH;AAEA,UAAM,QAAS,YAAY,SAAS,CAAC;AACrC,UAAM,QAAS,YAAY,QAAgC,CAAC,GAAG,SAAS;AAExE,eAAO,qBAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA,SAAS,SAAS,MAAM,SAAS;AAAA,IACnC,CAA+B;AAAA,EACjC;AAGA,QAAM,iBAAiB,OACrB,OACA,QACA,YACG;AACH,UAAM,KAAK,MAAM;AACjB,UAAM,SAAS,SAAS,OAAO;AAE/B,QAAI,CAAC,QAAQ;AACX,aAAO,YAAY;AAAA,QACjB,SAAS,kBAAkB,OAAO,uBAAuB,IAAI;AAAA,QAC7D,YAAY,GAAG,IAAI;AAAA,MACrB,CAAC;AAAA,IACH;AAEA,UAAM,cAAc;AAGpB,UAAM,SAAS,UAAM;AAAA,MAAQ,MAC3B,GACG,OAAO,EACP,KAAK,KAAK,EACV,UAAM,uBAAG,aAAa,MAAM,CAAC,EAC7B,YAAQ,yBAAK,WAAW,CAAC,EACzB,MAAM,QAAQ,CAAC;AAAA,IACpB;AACA,QAAI,OAAO,OAAO;AAChB,aAAO,YAAY;AAAA,QACjB,SAAS,2BAA2B,IAAI;AAAA,QACxC,MAAM,EAAE,QAAQ,cAAc,SAAS,OAAO,OAAO,MAAM;AAAA,QAC3D,YAAY,GAAG,IAAI;AAAA,MACrB,CAAC;AAAA,IACH;AAEA,UAAM,OAAQ,OAAO,SAAS,CAAC;AAC/B,UAAM,UAAU,KAAK,SAAS;AAC9B,UAAM,QAAQ,UAAU,KAAK,MAAM,GAAG,KAAK,IAAI;AAC/C,UAAM,WAAW,MAAM,GAAG,EAAE;AAC5B,UAAM,aAAa,WACf,OAAO,SAAS,OAAO,KAAK,EAAE,KAAK,OACnC;AAEJ,eAAO,qBAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAA+B;AAAA,EACjC;AAEA,QAAM,gBAAgB,CAAC,OAA0B,CAAC,MAAM;AACtD,UAAM,QAAQ,KAAK,SAAS;AAG5B,QAAI,YAAY,QAAQ,KAAK,QAAQ;AACnC,YAAM,UAAU,KAAK,gBAAgB;AACrC,aAAO,eAAe,OAAO,KAAK,QAAQ,OAAO;AAAA,IACnD;AAGA,UAAM,SAAU,KAAiC,UAAU;AAC3D,WAAO,eAAe,OAAO,MAAM;AAAA,EACrC;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,IACR;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;;;AItZA,SAAS,aAAa,QAAyC;AAC7D,SAAO,UAAU,UAAU,WAAW;AACxC;AAgBO,SAAS,qBACd,QACA,QAC2C;AAC3C,MAAI,CAAC,OAAO,aAAa;AAEvB,WAAO,MAAM;AAAA,IAAC;AAAA,EAChB;AAEA,QAAM,EAAE,OAAO,IAAI;AAEnB,SAAO,CAAC,SAAiB,SAAmB;AAC1C,QAAI,CAAC,QAAQ;AACX,cAAQ,IAAI,IAAI,MAAM,KAAK,OAAO,IAAI,QAAQ,EAAE;AAChD;AAAA,IACF;AAEA,QAAI,aAAa,MAAM,GAAG;AACxB,aAAO,KAAK;AAAA,QACV,YAAY;AAAA,QACZ,SAAS,IAAI,MAAM,KAAK,OAAO;AAAA,QAC/B;AAAA,MACF,CAAC;AAAA,IACH,OAAO;AACL,aAAO,KAAK,IAAI,MAAM,KAAK,OAAO,IAAI,IAAI;AAAA,IAC5C;AAAA,EACF;AACF;;;ACjDA,IAAAC,mBAA8C;AAC9C,iBAA8B;AAW9B,eAAe,QACb,SACA,YACA,OACA,aACsE;AACtE,QAAM,SAAS,UAAM;AAAA,IAAQ,MAC3B,WAAW,QAAQ,OAAkC,WAAW;AAAA,EAClE;AACA,SAAO;AAAA,IACL;AAAA,IACA,UAAU;AAAA,MACR,MAAM,GAAG,QAAQ,OAAO,IAAI,QAAQ,MAAM;AAAA,MAC1C;AAAA,MACA,QAAQ,OAAO,OAAO,OAAO,QAAQ,OAAO;AAAA,MAC5C,QAAQ,OAAO;AAAA,IACjB;AAAA,EACF;AACF;AAKA,eAAsB,aACpB,OACA,cACA,WACA,aACA,WACA,KACkC;AAClC,MAAI,eAAe;AAEnB,aAAW,WAAW,OAAO;AAC3B,UAAM,mBAAmB,UAAU,QAAQ,SAAS,QAAQ,MAAM;AAElE,QAAI,iBAAiB,OAAO;AAC1B,YAAM,WAAW,GAAG,SAAS,UAAU,QAAQ,OAAO,IAAI,QAAQ,MAAM;AACxE,UAAI,QAAQ;AACZ,UAAI,QAAQ,YAAY;AACtB,oBAAY,aAAa,QAAQ;AACjC,mBAAO,sBAAI,QAAQ;AAAA,MACrB;AACA;AAAA,IACF;AAEA,UAAM,EAAE,QAAQ,SAAS,IAAI,MAAM;AAAA,MACjC;AAAA,MACA,iBAAiB;AAAA,MACjB;AAAA,MACA;AAAA,IACF;AACA,gBAAY,WAAW,WAAW,QAAQ;AAE1C,QAAI,OAAO,OAAO;AAChB,YAAM,WAAW,OAAO,OAAO,KAAK;AACpC;AAAA,QACE,GAAG,SAAS,UAAU,QAAQ,OAAO,IAAI,QAAQ,MAAM;AAAA,QACvD,OAAO;AAAA,MACT;AACA,UAAI,QAAQ,YAAY;AACtB,oBAAY,aAAa,QAAQ;AACjC,mBAAO,sBAAI,QAAQ;AAAA,MACrB;AACA;AAAA,IACF;AAEA,mBAAe,OAAO;AAAA,EACxB;AAEA,aAAO,qBAAG,YAAY;AACxB;AAKA,eAAsB,oBACpB,SACA,aACA,QACA,SACA,KAC+B;AAC/B,MAAI,CAAC,SAAS;AACZ,eAAO,qBAAG,IAAI;AAAA,EAChB;AAEA,QAAM,SAAS,UAAM,0BAAQ,MAAM,QAAQ,EAAE,aAAa,QAAQ,QAAQ,CAAC,CAAC;AAC5E,MAAI,OAAO,OAAO;AAChB,QAAI,iCAAiC,OAAO,IAAI,EAAE;AAClD,gBAAY,aAAa,OAAO,KAAK;AACrC,eAAO,sBAAI,OAAO,KAAK;AAAA,EACzB;AAEA,aAAO,qBAAG,IAAI;AAChB;AAKA,eAAsB,mBACpB,SACA,aACA,QACA,SACA,eACA,KACkC;AAClC,MAAI,CAAC,SAAS;AACZ,eAAO,qBAAG,aAAa;AAAA,EACzB;AAEA,QAAM,SAAS,UAAM;AAAA,IAAQ,MAC3B,QAAQ;AAAA,MACN;AAAA,MACA;AAAA,MACA;AAAA,MACA,YAAQ,qBAAG,aAAa;AAAA,IAC1B,CAAC;AAAA,EACH;AACA,MAAI,OAAO,OAAO;AAChB,QAAI,gCAAgC,OAAO,IAAI,EAAE;AACjD,gBAAY,aAAa,OAAO,KAAK;AACrC,eAAO,sBAAI,OAAO,KAAK;AAAA,EACzB;AAEA,aAAO,qBAAG,OAAO,KAAK;AACxB;AAKO,SAAS,gBACd,QACA,SACA,aACA,KACyB;AACzB,MAAI,CAAC,OAAO,YAAY;AACtB,eAAO,qBAAG,OAAO;AAAA,EACnB;AAEA,QAAM,cAAc,OAAO,WAAW,UAAU,OAAO;AACvD,MAAI,CAAC,YAAY,SAAS;AACxB,UAAM,sBAAkB,0BAAc,YAAY,KAAK;AACvD,QAAI,yBAAyB,OAAO,IAAI,IAAI,eAAe;AAC3D,gBAAY,aAAa,eAAe;AACxC,eAAO,sBAAI,sBAAsB,eAAe,EAAE;AAAA,EACpD;AAEA,aAAO,qBAAG,YAAY,IAAI;AAC5B;AAKA,eAAsB,WACpB,QACA,SACA,aACA,KACkC;AAClC,QAAM,SAAS,UAAM;AAAA,IAAQ,MAC3B,OAAO,QAAQ,SAAoC,WAAW;AAAA,EAChE;AAEA,MAAI,OAAO,OAAO;AAChB,QAAI,sBAAsB,OAAO,IAAI,IAAI,OAAO,KAAK;AACrD,gBAAY,aAAa,OAAO,KAAK;AACrC,eAAO,sBAAI,OAAO,KAAK;AAAA,EACzB;AAEA,cAAY,cAAc,OAAO,KAAK;AACtC,aAAO,qBAAG,OAAO,KAAK;AACxB;;;ANzKO,SAAS,aAAa,SAAwB;AACnD,QAAM,EAAE,aAAa,UAAU,OAAO,IAAI;AAE1C,QAAM,MAAM,qBAAqB,UAAU;AAAA,IACzC;AAAA,IACA;AAAA,EAGF,CAAC;AAGD,QAAM,mBAAqC,CAAC;AAC5C,QAAM,sBAAuD,CAAC;AAC9D,QAAM,cAAsD,CAAC;AAG7D,QAAM,gBAAgB,YAAY,IAAI;AAEtC,aAAW,WAAW,UAAU;AAC9B,UAAM,cAAwB,CAAC;AAC/B,wBAAoB,QAAQ,IAAI,IAAI,CAAC;AACrC,gBAAY,QAAQ,IAAI,IAAI,CAAC;AAE7B,eAAW,UAAU,QAAQ,SAAS;AACpC,kBAAY,KAAK,OAAO,IAAI;AAE5B,0BAAoB,QAAQ,IAAI,GAAG,KAAK;AAAA,QACtC,MAAM,OAAO;AAAA,QACb,aAAa,OAAO;AAAA,QACpB,aAAa,CAAC,CAAC,OAAO;AAAA,QACtB,YAAY,CAAC,CAAC,OAAO;AAAA,QACrB,eAAe,OAAO,iBAAiB,CAAC;AAAA,MAC1C,CAAC;AAED,YAAM,iBAAiB,YAAY,QAAQ,IAAI;AAC/C,UAAI,gBAAgB;AAClB,uBAAe,OAAO,IAAI,IAAI;AAAA,MAChC;AAAA,IACF;AAEA,qBAAiB,KAAK;AAAA,MACpB,MAAM,QAAQ;AAAA,MACd,aAAa,QAAQ;AAAA,MACrB,MAAM,QAAQ;AAAA,MACd,SAAS;AAAA,IACX,CAAC;AAAA,EACH;AAEA;AAAA,IACE,kBAAkB,YAAY,IAAI,IAAI,aAAa,cAAc,SAAS,MAAM;AAAA,EAClF;AAIA,QAAM,cAAc,UAClB,qBAAG,gBAAgB;AAErB,QAAM,oBAAoB,CACxB,gBACoC;AACpC,UAAM,UAAU,oBAAoB,WAAW;AAC/C,WAAO,cAAU,qBAAG,OAAO,QAAI,sBAAI,YAAY,WAAW,aAAa;AAAA,EACzE;AAEA,QAAM,YAAY,CAChB,aACA,eAC2B;AAC3B,UAAM,aAAa,YAAY,WAAW;AAC1C,QAAI,CAAC,YAAY;AACf,iBAAO,sBAAI,YAAY,WAAW,aAAa;AAAA,IACjD;AAEA,UAAM,SAAS,WAAW,UAAU;AACpC,WAAO,aACH,qBAAG,MAAM,QACT,sBAAI,WAAW,UAAU,2BAA2B,WAAW,GAAG;AAAA,EACxE;AAEA,QAAM,gBAAgB,OACpB,aACA,YACA,SACA,gBACqC;AACrC,UAAM,EAAE,uBAAuB,qBAAqB,IAAI;AAGxD,UAAM,eAAe,UAAU,aAAa,UAAU;AACtD,QAAI,aAAa,OAAO;AACtB,iBAAO,sBAAI,aAAa,KAAK;AAAA,IAC/B;AACA,UAAM,SAAS,aAAa;AAG5B,gBAAY,iBAAiB,GAAG,WAAW,IAAI,UAAU,IAAI,OAAO;AAGpE,UAAM,qBAAqB,MAAM;AAAA,MAC/B;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,QAAI,mBAAmB,OAAO;AAC5B,iBAAO,sBAAI,mBAAmB,KAAK;AAAA,IACrC;AAGA,UAAM,oBAAoB,MAAM;AAAA,MAC9B,OAAO,OAAO,UAAU,CAAC;AAAA,MACzB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,QAAI,kBAAkB,OAAO;AAC3B,iBAAO,sBAAI,kBAAkB,KAAK;AAAA,IACpC;AAGA,UAAM,mBAAmB;AAAA,MACvB;AAAA,MACA,kBAAkB;AAAA,MAClB;AAAA,MACA;AAAA,IACF;AACA,QAAI,iBAAiB,OAAO;AAC1B,iBAAO,sBAAI,iBAAiB,KAAK;AAAA,IACnC;AAGA,UAAM,gBAAgB,MAAM;AAAA,MAC1B;AAAA,MACA,iBAAiB;AAAA,MACjB;AAAA,MACA;AAAA,IACF;AACA,QAAI,cAAc,OAAO;AACvB,iBAAO,sBAAI,cAAc,KAAK;AAAA,IAChC;AAGA,UAAM,mBAAmB,MAAM;AAAA,MAC7B,OAAO,OAAO,SAAS,CAAC;AAAA,MACxB,cAAc;AAAA,MACd;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,QAAI,iBAAiB,OAAO;AAC1B,iBAAO,sBAAI,iBAAiB,KAAK;AAAA,IACnC;AAGA,UAAM,oBAAoB,MAAM;AAAA,MAC9B;AAAA,MACA;AAAA,MACA;AAAA,MACA,iBAAiB;AAAA,MACjB,iBAAiB;AAAA,MACjB;AAAA,IACF;AACA,QAAI,kBAAkB,OAAO;AAC3B,iBAAO,sBAAI,kBAAkB,KAAK;AAAA,IACpC;AAGA,WAAO,OAAO,QAAQ,eAClB,qBAAG;AAAA,MACD,MAAM,kBAAkB;AAAA,MACxB,UAAU,YAAY,YAAY;AAAA,IACpC,CAAC,QACD,qBAAG,kBAAkB,KAAK;AAAA,EAChC;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;;;AO1MA,kBAAqB;AACrB,IAAAC,cAAc;;;ACAd,kBAAqB;AAOd,IAAM,0BAA0B,CAAC,WAAoC;AAC1E,QAAM,mBAAmB,CAAC,cAAsB;AAC9C,QAAI,OAAO,eAAe,SAAS,GAAG;AACpC,aAAO,OAAO,eAAe,SAAS,aAAa,EAAE,IAAI,YAAY;AAAA,IACvE;AACA,WAAO;AAAA,EACT;AAEA,SAAO;AAAA,IACL,QAAQ,OAAO,MAAM,UAAU,UAAU;AAAA,IACzC,aAAa,OAAO,MAAM,UAAU,eAAe;AAAA,IACnD,cAAc,OAAO,MAAM,UAAU,gBAAgB;AAAA,MACnD;AAAA,MACA;AAAA,IACF;AAAA,IACA,cAAc,OAAO,MAAM,UAAU,gBAAgB;AAAA,MACnD;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,eAAe,OAAO,MAAM,UAAU,iBAAiB,CAAC,gBAAgB;AAAA,IACxE,QAAQ,OAAO,MAAM,UAAU,UAAU;AAAA,EAC3C;AACF;AAKO,IAAM,kBAAkB,CAAC,KAAW,WAA6B;AACtE,QAAM,cAAc,OAAO,MAAM,WAAW;AAE5C,MAAI,gBAAgB,OAAO;AACzB;AAAA,EACF;AAEA,QAAM,kBAAkB,wBAAwB,MAAM;AAGtD,QAAM,YAAY,OAAO,MAAM,WAAW,CAAC;AAC3C,aAAW,QAAQ,WAAW;AAC5B,uBAAmB,KAAK,MAAM,eAAe;AAAA,EAC/C;AAGA,MAAI,IAAI,SAAK,kBAAK,eAA6C,CAAC;AAClE;AAKA,IAAM,qBAAqB,CACzB,KACA,MACA,gBACS;AACT,MAAI,KAAK,UAAU;AACjB,2BAAuB,KAAK,KAAK,MAAM,KAAK,UAAU,WAAW;AAAA,EACnE,WAAW,KAAK,SAAS;AACvB,oBAAgB,KAAK,KAAK,MAAM,KAAK,SAAS,WAAW;AAAA,EAC3D;AACF;AAKA,IAAM,yBAAyB,CAC7B,KACA,MACA,UACA,gBACS;AACT,MAAI,CAAC,UAAU;AACb;AAAA,EACF;AAEA,MAAI,IAAI,MAAM,CAAC,GAAG,SAAS;AACzB,UAAM,YAAY,EAAE,IAAI,OAAO,QAAQ,KAAK;AAC5C,UAAM,WAAW,iBAAiB,UAAU,WAAW,GAAG,WAAW;AACrE,eAAO,kBAAK,QAAsC,EAAE,GAAG,IAAI;AAAA,EAC7D,CAAC;AACH;AAKA,IAAM,kBAAkB,CACtB,KACA,MACA,SACA,gBACS;AACT,MAAI;AAAA,IACF;AAAA,QACA,kBAAK,EAAE,GAAG,aAAa,GAAG,QAAQ,CAA+B;AAAA,EACnE;AACF;AAKA,IAAM,mBAAmB,CACvB,UACA,QACA,GACA,gBACgB;AAChB,MAAI,CAAC,UAAU;AACb,WAAO;AAAA,EACT;AAEA,MAAI;AACF,UAAM,SAAS,SAAS,QAAQ,CAAC;AAEjC,QAAI,WAAW,MAAM;AACnB,aAAO,EAAE,GAAG,aAAa,QAAQ,UAAU,IAAI;AAAA,IACjD;AAEA,QAAI,WAAW,OAAO;AACpB,aAAO,EAAE,GAAG,aAAa,QAAQ,GAAG;AAAA,IACtC;AAEA,QAAI,UAAU,OAAO,WAAW,UAAU;AACxC,aAAO,EAAE,GAAG,aAAa,GAAG,OAAO;AAAA,IACrC;AAEA,WAAO;AAAA,EACT,SAAS,OAAO;AAEd,YAAQ,MAAM,wBAAwB,KAAK;AAC3C,WAAO,EAAE,GAAG,aAAa,QAAQ,GAAG;AAAA,EACtC;AACF;;;AC3IA,IAAAC,mBAAgC;AAChC,IAAAC,cAAc;AAeP,SAAS,mBACd,QACA,gBACkB;AAClB,MAAI,OAAO,MAAM;AACf,UAAM,QAAQ,OAAO;AACrB,UAAM,OACJ,UAAU,QAAQ,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK,IAC9D,QACD,EAAE,QAAQ,MAAM;AAEtB,WAAO,EAAE,QAAQ,MAAM,SAAS,gBAAgB,KAAK;AAAA,EACvD;AAEA,SAAO,EAAE,QAAQ,OAAO,SAAS,OAAO,OAAO,MAAM,CAAC,EAAE;AAC1D;AAUO,SAAS,cACd,QACA,SACkB;AAClB,QAAM,EAAE,SAAS,OAAO,IAAI;AAE5B,MAAI,YAAY,KAAK;AACnB,WAAO,mBAAmB,OAAO,YAAY,GAAG,oBAAoB;AAAA,EACtE;AAEA,MAAI,WAAW,KAAK;AAClB,WAAO;AAAA,MACL,OAAO,kBAAkB,OAAO;AAAA,MAChC,gBAAgB,OAAO;AAAA,IACzB;AAAA,EACF;AAEA,QAAM,eAAe,OAAO,UAAU,SAAS,MAAM;AACrD,MAAI,aAAa,OAAO;AACtB,WAAO,mBAAmB,cAAc,EAAE;AAAA,EAC5C;AAEA,QAAM,MAAM,aAAa;AACzB,SAAO;AAAA,QACL,qBAAG;AAAA,MACD,MAAM,IAAI;AAAA,MACV,aAAa,IAAI;AAAA,MACjB,aAAa,IAAI,eAAe;AAAA,MAChC,eAAe,IAAI;AAAA,MACnB,OAAO,IAAI,QACP,EAAE,QAAQ,IAAI,MAAM,UAAU,CAAC,GAAG,OAAO,IAAI,MAAM,SAAS,CAAC,EAAE,IAC/D;AAAA,MACJ,MAAM,IAAI,QAAQ;AAAA,IACpB,CAAC;AAAA,IACD,gBAAgB,OAAO,IAAI,MAAM;AAAA,EACnC;AACF;AAKA,eAAsB,cACpB,QACA,SACA,aAC2B;AAC3B,QAAM,EAAE,SAAS,QAAQ,QAAQ,IAAI;AAErC,MAAI,YAAY,OAAO,WAAW,KAAK;AACrC,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,SACE;AAAA,MACF,MAAM,CAAC;AAAA,IACT;AAAA,EACF;AAEA,QAAM,SAAS,MAAM,OAAO;AAAA,IAC1B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,SAAO,mBAAmB,QAAQ,WAAW,OAAO,IAAI,MAAM,YAAY;AAC5E;AAQO,SAAS,aACd,QACA,SACkB;AAClB,QAAM,EAAE,SAAS,OAAO,IAAI;AAE5B,MAAI,YAAY,KAAK;AACnB,UAAM,iBAAiB,OAAO,YAAY;AAC1C,QAAI,eAAe,OAAO;AACxB,aAAO,mBAAmB,gBAAgB,EAAE;AAAA,IAC9C;AAEA,UAAM,UAAmC,CAAC;AAC1C,eAAW,OAAO,eAAe,OAAO;AACtC,YAAM,gBAAgB,OAAO,kBAAkB,IAAI,IAAI;AACvD,UAAI,cAAc,OAAO;AACvB;AAAA,MACF;AAEA,cAAQ,IAAI,IAAI,IAAI;AAAA,QAClB;AAAA,QACA,IAAI;AAAA,QACJ,cAAc,MAAM,IAAI,CAAC,MAAM,EAAE,IAAI;AAAA,MACvC;AAAA,IACF;AAEA,WAAO,uBAAmB,qBAAG,OAAO,GAAG,qBAAqB;AAAA,EAC9D;AAEA,MAAI,WAAW,KAAK;AAClB,UAAM,gBAAgB,OAAO,kBAAkB,OAAO;AACtD,QAAI,cAAc,OAAO;AACvB,aAAO,mBAAmB,eAAe,EAAE;AAAA,IAC7C;AAEA,UAAM,UAAU;AAAA,MACd;AAAA,MACA;AAAA,MACA,cAAc,MAAM,IAAI,CAAC,MAAM,EAAE,IAAI;AAAA,IACvC;AACA,WAAO,uBAAmB,qBAAG,OAAO,GAAG,gBAAgB,OAAO,GAAG;AAAA,EACnE;AAEA,QAAM,eAAe,OAAO,UAAU,SAAS,MAAM;AACrD,MAAI,aAAa,OAAO;AACtB,WAAO,mBAAmB,cAAc,EAAE;AAAA,EAC5C;AAEA,QAAM,SAAS,oBAAoB,aAAa,KAAK;AACrD,SAAO;AAAA,QACL,qBAAG,EAAE,CAAC,MAAM,GAAG,OAAO,CAAC;AAAA,IACvB,eAAe,OAAO,IAAI,MAAM;AAAA,EAClC;AACF;AAKA,SAAS,oBACP,QACA,aACA,aACyB;AACzB,QAAM,UAAmC,CAAC;AAE1C,aAAW,cAAc,aAAa;AACpC,UAAM,eAAe,OAAO,UAAU,aAAa,UAAU;AAC7D,QAAI,aAAa,OAAO;AACtB;AAAA,IACF;AACA,YAAQ,UAAU,IAAI,oBAAoB,aAAa,KAAK;AAAA,EAC9D;AAEA,SAAO;AACT;AAKA,SAAS,oBAAoB,QAEjB;AACV,QAAM,SAAS,OAAO;AACtB,MAAI,CAAC,QAAQ;AACX,WAAO;AAAA,EACT;AAEA,QAAM,EAAE,KAAK,OAAO,IAAI;AAAA,IAAY,MAClC,YAAAC,QAAE,aAAa,QAAQ,EAAE,iBAAiB,MAAM,CAAC;AAAA,EACnD;AAEA,SAAO,MAAM,OAAO;AACtB;AAMA,SAAS,YAAe,IAAiD;AACvE,MAAI;AACF,WAAO,EAAE,KAAK,MAAM,QAAQ,GAAG,EAAE;AAAA,EACnC,SAAS,OAAO;AACd,WAAO,EAAE,KAAK,OAAO,QAAQ,KAAK;AAAA,EACpC;AACF;AAKO,IAAM,iBAOT;AAAA,EACF,SAAS,CAAC,QAAQ,YAAY,cAAc,QAAQ,OAAO;AAAA,EAC3D,SAAS,CAAC,QAAQ,SAAS,gBACzB,cAAc,QAAQ,SAAS,WAAW;AAAA,EAC5C,QAAQ,CAAC,QAAQ,YAAY,aAAa,QAAQ,OAAO;AAC3D;;;AC1OA,+BAA4B;AAC5B,IAAAC,mBAAwB;AAIxB,IAAM,eAAe;AACrB,IAAM,+BAA+B,KAAK,KAAK;AAC/C,IAAM,yBAAyB;AAC/B,IAAM,qBAAqB;AAOpB,SAAS,kBACd,KACA,QACA,KACM;AACN,MAAI,CAAC,OAAO,cAAc,gBAAgB;AACxC;AAAA,EACF;AAEA,QAAM,EAAE,aAAa,IAAI;AAEzB,MAAI;AAAA,QACF,sCAAY;AAAA,MACV,UAAU,aAAa,YAAY;AAAA,MACnC,OAAO,aAAa,SAAS;AAAA,MAC7B,iBAAiB,aAAa,mBAAmB;AAAA,MACjD,cAAc,CAAC,MAAM;AACnB,cAAM,MAAM,EAAE,IAAI,OAAO,aAAa,cAAc;AACpD,YAAI,CAAC,KAAK;AACR;AAAA,YACE,yBAAyB,aAAa,cAAc;AAAA,UACtD;AACA,iBAAO;AAAA,QACT;AACA,eAAO;AAAA,MACT;AAAA,MACA,OAAO,aAAa,SAAS;AAAA,IAC/B,CAAC;AAAA,EACH;AAEA;AAAA,IACE,0BAA0B,aAAa,SAAS,sBAAsB,iBAAiB,aAAa,YAAY,4BAA4B;AAAA,EAC9I;AACF;AAQO,SAAS,mBACd,KACA,QACA,SACA,KACM;AACN,MAAI,CAAC,OAAO,cAAc;AACxB;AAAA,EACF;AAEA,MAAI,YAAY,OAAO;AACrB,QAAI,sDAAsD,OAAO,EAAE;AACnE;AAAA,EACF;AAGA,MAAI,gBAEO;AACX,MAAI,eAAe;AAEnB,MAAI,IAAI,aAAa,OAAO,GAAG,SAAS;AACtC,QAAI,cAAc;AAChB,aAAO,KAAK;AAAA,IACd;AAEA,QAAI,CAAC,eAAe;AAClB,YAAM,eAAe,UAAM,0BAAQ,YAAY;AAC7C,cAAM,MAAM,MAAM,OAAO,UAAU;AACnC,eAAO,IAAI,YAAY;AAAA,UACrB,MAAM;AAAA,UACN,oBAAoB,CAAC,SAAiB,KAAK,QAAQ,cAAc,EAAE;AAAA,QACrE,CAAC;AAAA,MACH,CAAC;AAED,UAAI,aAAa,OAAO;AACtB,YAAI,sCAAsC,aAAa,KAAK;AAC5D,uBAAe;AACf,eAAO,KAAK;AAAA,MACd;AAEA,sBAAgB,aAAa;AAAA,IAC/B;AAEA,QAAI,eAAe;AACjB,aAAO,cAAc,GAAY,IAAa;AAAA,IAChD;AAAA,EACF,CAAC;AAED,MAAI,0CAA0C;AAChD;;;AH1FA,IAAM,wBAAwB,YAAAC,QAAE,OAAO;AAAA,EACrC,QAAQ,YAAAA,QAAE,KAAK,CAAC,WAAW,WAAW,QAAQ,CAAC;AAAA,EAC/C,SAAS,YAAAA,QAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EACzB,QAAQ,YAAAA,QAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EACxB,SAAS,YAAAA,QAAE,OAAO,YAAAA,QAAE,OAAO,GAAG,YAAAA,QAAE,QAAQ,CAAC;AAC3C,CAAC;AAmBM,SAAS,cAAc,QAAmC;AAC/D,QAAM,EAAE,QAAQ,QAAQ,aAAa,YAAY,QAAQ,IAAI;AAC7D,QAAM,MAAM,IAAI,iBAAK;AAErB,QAAM,MAAM,qBAAqB,QAAQ;AAAA,IACvC,aAAa,OAAO;AAAA,IACpB,QAAQ,YAAY,WAAW;AAAA,EAGjC,CAAC;AAGD,kBAAgB,KAAK,MAAM;AAG3B,oBAAkB,KAAK,QAAQ,GAAG;AAGlC,qBAAmB,KAAK,QAAQ,SAAS,GAAG;AAG5C,QAAM,eAAe,GAAG,OAAO,OAAO;AAEtC,MAAI,KAAK,cAAc,OAAO,MAAM;AAClC,UAAM,OAAO,MAAM,EAAE,IAAI,KAAK,EAAE,MAAM,MAAM,IAAI;AAEhD,QAAI,CAAC,MAAM;AACT,aAAO,EAAE;AAAA,QACP;AAAA,UACE,QAAQ;AAAA,UACR,SAAS;AAAA,UACT,MAAM,CAAC;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAEA,UAAM,SAAS,sBAAsB,UAAU,IAAI;AACnD,QAAI,CAAC,OAAO,SAAS;AACnB,aAAO,EAAE;AAAA,QACP;AAAA,UACE,QAAQ;AAAA,UACR,SAAS;AAAA,UACT,MAAM,EAAE,QAAQ,OAAO,MAAM,OAAO;AAAA,QACtC;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAEA,UAAM,UAAU,OAAO;AAEvB,QAAI,GAAG,QAAQ,MAAM,OAAO,QAAQ,OAAO,IAAI,QAAQ,MAAM,EAAE;AAE/D,UAAM,UAAU,eAAe,QAAQ,MAAM;AAE7C,UAAM,WAAW,MAAO,QAAgB,QAAQ,SAAS,WAAW;AAEpE,UAAM,aAAa,SAAS,SAAS,MAAM;AAC3C,WAAO,EAAE,KAAK,UAAU,UAAU;AAAA,EACpC,CAAC;AAGD,MAAI,OAAO,cAAc;AACvB,QAAI,IAAI,WAAW,CAAC,MAAM;AACxB,aAAO,EAAE,KAAK;AAAA,QACZ,QAAQ;AAAA,QACR,SAAS,GAAG,UAAU;AAAA,QACtB,MAAM,CAAC;AAAA,MACT,CAA4B;AAAA,IAC9B,CAAC;AAAA,EACH;AAGA,MAAI,SAAS,CAAC,MAAM;AAClB,WAAO,EAAE;AAAA,MACP;AAAA,QACE,QAAQ;AAAA,QACR,SAAS,6BAA6B,YAAY;AAAA,QAClD,MAAM,CAAC;AAAA,MACT;AAAA,MACA;AAAA,IACF;AAAA,EACF,CAAC;AAED,MAAI,2BAA2B,YAAY,EAAE;AAE7C,SAAO;AACT;;;AI9GO,SAAS,kBACd,QACkB;AAClB,QAAM,QAAQ,oBAAI,IAAqB;AACvC,QAAM,mBAAmB,QAAQ;AAGjC,QAAM,WAAqB,CAAC;AAE5B,QAAM,UAA4B;AAAA,IAChC,MAAM,kBAAkB;AAAA,IACxB,IAAI,kBAAkB;AAAA,IACtB,KAAK,kBAAkB;AAAA,IACvB,WAAW,QAAQ;AAAA,IACnB;AAAA,IACA,QAAQ;AAAA,IAER,IAAiB,KAA4B;AAC3C,aAAO,MAAM,IAAI,GAAG;AAAA,IACtB;AAAA,IAEA,IAAiB,KAAa,OAAgB;AAC5C,YAAM,IAAI,KAAK,KAAK;AAAA,IACtB;AAAA,IAEA,WAAW,MAAsB;AAC/B,aAAO,SAAS,IAAI;AAAA,IACtB;AAAA,IAEA,WAAW,MAAsB,MAA+B;AAC9D,eAAS,IAAI,IAAI;AAAA,IACnB;AAAA,IAEA,aAAa;AAAA,MACX,YAAY;AAAA,MACZ,OAAO;AAAA,MACP,OAAO,CAAC;AAAA,MACR,KAAK,EAAE,QAAQ,CAAC,GAAG,OAAO,CAAC,EAAE;AAAA,IAC/B;AAAA,IAEA,gBAAgB,KAAa,OAAgB;AAC3C,cAAQ,YAAY,MAAM,GAAG,IAAI;AAAA,IACnC;AAAA,IAEA,WACE,OACA,UAMA;AACA,cAAQ,YAAY,IAAI,KAAK,EAAE,KAAK,QAAQ;AAAA,IAC9C;AAAA,IAEA,aAAa,OAAe;AAC1B,cAAQ,YAAY,QAAQ;AAAA,IAC9B;AAAA,IAEA,cAAc,QAAiB;AAC7B,cAAQ,YAAY,SAAS;AAAA,IAC/B;AAAA,IAEA,iBAAiB,YAAoB,OAAgB;AACnD,cAAQ,cAAc;AAAA,QACpB;AAAA,QACA;AAAA,QACA,OAAO,CAAC;AAAA,QACR,KAAK,EAAE,QAAQ,CAAC,GAAG,OAAO,CAAC,EAAE;AAAA,MAC/B;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;;;AZrFA,IAAI,eAAmC;AAahC,SAAS,aAA8C;AAC5D,MAAI,CAAC,cAAc;AACjB,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAYO,SAAS,iBAAiB,QAAkC;AACjE,MAAI,CAAC,OAAO,UAAU,QAAQ;AAC5B,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,QAAM,MAAM,qBAAqB,cAAc;AAAA,IAC7C,aAAa,OAAO;AAAA,IACpB,QAAQ,OAAO,WAAW;AAAA,EAG5B,CAAC;AAGD,QAAM,cAAc,kBAAkB;AAAA,IACpC,WAAW,OAAO;AAAA,EACpB,CAAC;AAED,iBAAe;AAGf,QAAM,SAAiB,aAAa;AAAA,IAClC,UAAU,OAAO;AAAA,IACjB,aAAa,OAAO;AAAA,IACpB,QAAQ,OAAO,WAAW;AAAA,IAG1B,uBAAuB,OAAO;AAAA,IAC9B,sBAAsB,OAAO;AAAA,EAC/B,CAAC;AAED,MAAI,2BAA2B,OAAO,SAAS,MAAM,aAAa;AAGlE,MAAI,OAAO,gBAAgB,OAAO;AAChC,UAAM,iBAAiB,OAAO,YAAY;AAC1C,QAAI,eAAe,MAAM;AACvB,YAAM,QAAQ,eAAe,MAAM,IAAI,CAAC,OAAO;AAAA,QAC7C,SAAS,EAAE;AAAA,QACX,aAAa,EAAE;AAAA,QACf,SAAS,EAAE,QAAQ;AAAA,MACrB,EAAE;AACF,cAAQ,MAAM,KAAK;AAAA,IACrB;AAAA,EACF;AAGA,QAAM,SAAqB;AAAA,IACzB;AAAA,IACA;AAAA,IACA,SAAS;AAAA,EACX;AAGA,MAAI,OAAO,MAAM;AACf,UAAM,MAAM,cAAc;AAAA,MACxB,QAAQ,OAAO;AAAA,MACf;AAAA,MACA;AAAA,MACA,YAAY,OAAO;AAAA,MACnB,SAAS,OAAO,WAAW;AAAA,IAC7B,CAAC;AAED,WAAO,OAAO,EAAE,KAAK,QAAQ,OAAO,KAAK;AAEzC,UAAM,OAAO,OAAO,KAAK,QAAQ;AACjC,UAAM,OAAO,OAAO,KAAK,QAAQ;AACjC,UAAM,OAAO,UAAU,IAAI,IAAI,IAAI;AAEnC,YAAQ,IAAI;AAAA,SAAY,IAAI,GAAG,OAAO,KAAK,OAAO,WAAW;AAC7D,QAAI,OAAO,KAAK,cAAc;AAC5B,cAAQ,IAAI,UAAU,IAAI,SAAS;AAAA,IACrC;AACA,YAAQ,IAAI,EAAE;AAAA,EAChB;AAGA,MAAI,OAAO,QAAQ;AACjB,UAAM,EAAE,GAAG,IAAI,OAAO;AAEtB,UAAM,SAAS,YAAY;AACzB,YAAM,SAAS,UAAM,0BAAQ,MAAM,GAAG,WAAW,CAAC;AAClD,UAAI,OAAO,OAAO;AAChB,gBAAQ,MAAM,+BAA+B,OAAO,KAAK;AAAA,MAC3D;AAAA,IACF,GAAG;AAEH;AAAA,EACF;AAEA,MAAI,GAAG,OAAO,UAAU,eAAe;AAEvC,SAAO;AACT;","names":["pino","match","year","start","end","import_slang_ts","import_slang_ts","import_slang_ts","result","import_slang_ts","import_zod","import_slang_ts","import_zod","z","import_slang_ts","z"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/engine/create-action.ts","../src/engine/create-service.ts","../src/logging/logger.ts","../src/logging/create-log.ts","../src/nile/server.ts","../src/engine/engine.ts","../src/utils/db/create-model.ts","../src/utils/handle-error.ts","../src/utils/db/create-transaction-variant.ts","../src/utils/db/get-zod-schema.ts","../src/utils/diagnostics-log.ts","../src/engine/pipeline.ts","../src/rest/rest.ts","../src/cors/cors.ts","../src/rest/intent-handlers.ts","../src/rest/middleware.ts","../src/nile/nile.ts"],"sourcesContent":["// CORS types — origin control, per-route rules, and resolver functions\nexport type {\n CorsConfig,\n CorsOptions,\n CorsResolver,\n CorsRouteRule,\n} from \"./cors/types\";\n// Engine utilities — action and service factory functions\nexport { createAction, createActions } from \"./engine/create-action\";\nexport { createService, createServices } from \"./engine/create-service\";\n// Engine types — defining services, actions, hooks, and the engine interface\nexport type {\n Action,\n ActionHandler,\n ActionResultConfig,\n ActionSummary,\n Actions,\n Engine,\n EngineOptions,\n HookContext,\n HookDefinition,\n HookLogEntry,\n Service,\n ServiceSummary,\n Services,\n} from \"./engine/types\";\n\n// Logging — structured log persistence with chunking support\nexport {\n createLog,\n createLogger,\n getLogs,\n type Log,\n type LogFilter,\n type LoggerConfig,\n} from \"./logging\";\n// Server factory — the main entry point for developers\nexport { createNileServer, getContext } from \"./nile/server\";\n// Nile types — server config, context, request/response, and lifecycle hooks\nexport type {\n AfterActionHandler,\n BaseContext,\n BeforeActionHandler,\n ExternalRequest,\n ExternalResponse,\n NileContext,\n NileLogger,\n NileServer,\n Resources,\n RPCContext,\n ServerConfig,\n ServerRuntime,\n Sessions,\n WebSocketContext,\n} from \"./nile/types\";\n// REST types — REST interface and rate limiting configuration\nexport type { RateLimitConfig, RestConfig } from \"./rest/types\";\n// Utilities — error handling, diagnostics, and database helpers\nexport {\n type CursorPage,\n type CursorPaginationOptions,\n createModel,\n createTransactionVariant,\n type DBParams,\n type DBX,\n getZodSchema,\n handleError,\n type ModelOperations,\n type ModelOptions,\n type OffsetPage,\n type OffsetPaginationOptions,\n} from \"./utils\";\n","import type { Action } from \"./types\";\n\n/**\n * Typed identity for defining a single action with full type inference.\n * No runtime overhead — returns the config object as-is.\n */\nexport function createAction(config: Action): Action {\n return config;\n}\n\n/**\n * Typed identity for defining multiple actions with full type inference.\n * No runtime overhead — returns the config array as-is.\n */\nexport function createActions(configs: Action[]): Action[] {\n return configs;\n}\n","import type { Service } from \"./types\";\n\n/**\n * Typed identity for defining a service with full type inference.\n * No runtime overhead — returns the config object as-is.\n */\nexport function createService(config: Service): Service {\n return config;\n}\n\n/**\n * Typed identity for defining multiple services with full type inference.\n * No runtime overhead — returns the config array as-is.\n */\nexport function createServices(configs: Service[]): Service[] {\n return configs;\n}\n","import {\n appendFileSync,\n existsSync,\n mkdirSync,\n readdirSync,\n readFileSync,\n} from \"node:fs\";\nimport { join } from \"node:path\";\nimport { nanoid } from \"nanoid\";\nimport pino, { type Logger } from \"pino\";\n\nexport interface Log {\n atFunction: string;\n appName: string;\n message: string;\n data?: unknown;\n level?: \"info\" | \"warn\" | \"error\";\n log_id?: string;\n}\n\n/** Configuration for log file chunking behavior */\nexport interface LoggerConfig {\n /** Time-based chunking strategy. Default: 'none' (single file per app) */\n chunking?: \"monthly\" | \"daily\" | \"weekly\" | \"none\";\n}\n\n// Lazy evaluation of MODE - only check when logging is actually used\nconst getMode = () => {\n if (!process.env.MODE) {\n throw new Error(\"Missing MODE environment variable\");\n }\n return process.env.MODE;\n};\n\nconst logDir = join(process.cwd(), \"logs\");\n\nif (!existsSync(logDir)) {\n mkdirSync(logDir);\n}\n\n// Chunk filename patterns — hoisted for performance (used in hot path by getLogs)\nconst MONTHLY_PATTERN = /^(\\d{4})-(\\d{2})$/;\nconst DAILY_PATTERN = /^(\\d{4})-(\\d{2})-(\\d{2})$/;\nconst WEEKLY_PATTERN = /^(\\d{4})-W(\\d{2})$/;\n\n/**\n * Resolves the correct log file path based on app name and chunking config.\n * - 'none' (default): logs/{appName}.log (backwards compatible)\n * - 'monthly': logs/{appName}/YYYY-MM.log\n * - 'daily': logs/{appName}/YYYY-MM-DD.log\n * - 'weekly': logs/{appName}/YYYY-WNN.log (ISO week number)\n */\nexport function resolveLogPath(appName: string, config?: LoggerConfig): string {\n const chunking = config?.chunking ?? \"none\";\n\n if (chunking === \"none\") {\n return join(logDir, `${appName}.log`);\n }\n\n const appDir = join(logDir, appName);\n if (!existsSync(appDir)) {\n mkdirSync(appDir, { recursive: true });\n }\n\n const now = new Date();\n const chunk = formatChunkName(now, chunking);\n return join(appDir, `${chunk}.log`);\n}\n\n/**\n * Formats a date into the correct chunk filename based on chunking strategy.\n * Exported for testing and reuse by getLogs.\n */\nexport function formatChunkName(\n date: Date,\n chunking: \"monthly\" | \"daily\" | \"weekly\"\n): string {\n const year = date.getFullYear();\n const month = String(date.getMonth() + 1).padStart(2, \"0\");\n\n if (chunking === \"monthly\") {\n return `${year}-${month}`;\n }\n\n if (chunking === \"daily\") {\n const day = String(date.getDate()).padStart(2, \"0\");\n return `${year}-${month}-${day}`;\n }\n\n // Weekly: ISO week number\n const weekNum = getISOWeekNumber(date);\n return `${year}-W${String(weekNum).padStart(2, \"0\")}`;\n}\n\n/** Returns the ISO 8601 week number for a given date */\nfunction getISOWeekNumber(date: Date): number {\n const target = new Date(date.valueOf());\n // Set to nearest Thursday (current date + 4 - current day number, with Sunday as 7)\n const dayNum = target.getDay() || 7;\n target.setDate(target.getDate() + 4 - dayNum);\n const yearStart = new Date(target.getFullYear(), 0, 1);\n return Math.ceil(\n ((target.getTime() - yearStart.getTime()) / 86_400_000 + 1) / 7\n );\n}\n\n/**\n * Creates a pino logger instance that writes to the resolved log file path.\n * Each call creates a fresh pino transport — callers should cache if needed.\n */\nfunction createLoggerForApp(appName: string, config?: LoggerConfig): Logger {\n const logFile = resolveLogPath(appName, config);\n\n const transport = pino.transport({\n targets: [\n {\n level: \"info\",\n target: \"pino/file\",\n options: {\n destination: logFile,\n mkdir: true,\n },\n },\n ],\n });\n\n return pino(\n {\n base: null,\n timestamp: () => `,\"time\":\"${new Date().toISOString()}\"`,\n formatters: {\n level(label) {\n return { level: label };\n },\n },\n },\n transport\n );\n}\n\n/**\n * Creates a new log entry with the provided log information.\n * Supports optional chunking config to split logs into time-based files.\n * @param log - The log object containing the log details\n * @param config - Optional logger config for chunking behavior\n * @returns The generated log ID (or JSON string in agentic mode)\n * @throws {Error} If appName is missing in the log object\n */\nexport const createLog = (log: Log, config?: LoggerConfig) => {\n if (!log.appName) {\n throw new Error(`Missing appName in log: ${JSON.stringify(log)}`);\n }\n\n const level = log.level || \"info\";\n const log_id = log.log_id || nanoid(6);\n\n const logRecord = {\n log_id,\n appName: log.appName,\n atFunction: log.atFunction,\n message: log.message,\n data: log.data ?? null,\n level,\n time: new Date().toISOString(),\n };\n\n const mode = getMode();\n\n if (mode === \"prod\" || process.env.NODE_ENV === \"test\") {\n const logFile = resolveLogPath(log.appName, config);\n\n if (process.env.NODE_ENV === \"test\") {\n // For tests, write synchronously to ensure file exists immediately\n appendFileSync(logFile, `${JSON.stringify(logRecord)}\\n`, \"utf-8\");\n } else {\n // For production, use pino logger\n const appLogger = createLoggerForApp(log.appName, config);\n appLogger[level as \"info\" | \"warn\" | \"error\"](logRecord);\n }\n return log_id;\n }\n\n if (mode === \"agentic\") {\n return JSON.stringify(logRecord);\n }\n\n console.log({\n ...logRecord,\n data: JSON.stringify(logRecord.data, null, 2),\n });\n return \"dev-mode, see your dev console!\";\n};\n\nexport interface LogFilter {\n appName?: string;\n log_id?: string;\n level?: \"info\" | \"warn\" | \"error\";\n from?: Date;\n to?: Date;\n}\n\n/**\n * Retrieves logs based on the provided filters.\n * Supports reading from chunked files when a LoggerConfig with chunking is provided.\n * When chunking is enabled, uses from/to date filters to intelligently select\n * only the relevant chunk files instead of scanning all files.\n * @param filters - Optional filters to apply when retrieving logs\n * @param config - Optional logger config matching the chunking used when writing\n * @returns An array of log entries matching the filters\n */\nexport const getLogs = (\n filters: LogFilter = {},\n config?: LoggerConfig\n): Log[] => {\n const chunking = config?.chunking ?? \"none\";\n\n const filesToRead = resolveLogFiles(filters, chunking);\n const logs = readAndParseLogFiles(filesToRead);\n return applyLogFilters(logs, filters);\n};\n\n/**\n * Determines which log files to read based on filters and chunking strategy.\n * For 'none' chunking, returns the single flat file.\n * For time-based chunking, scans the app directory and filters by date range.\n */\nfunction resolveLogFiles(\n filters: LogFilter,\n chunking: \"monthly\" | \"daily\" | \"weekly\" | \"none\"\n): string[] {\n if (chunking === \"none\") {\n const logFile = filters.appName\n ? join(logDir, `${filters.appName}.log`)\n : join(logDir, \"app.log\");\n return existsSync(logFile) ? [logFile] : [];\n }\n\n // Chunked mode requires appName to locate the directory\n if (!filters.appName) {\n return [];\n }\n\n const appDir = join(logDir, filters.appName);\n if (!existsSync(appDir)) {\n return [];\n }\n\n const allFiles = readdirSync(appDir)\n .filter((f) => f.endsWith(\".log\"))\n .sort();\n\n // If no date filters, read all chunk files\n if (!(filters.from || filters.to)) {\n return allFiles.map((f) => join(appDir, f));\n }\n\n // Filter chunks by date relevance to avoid reading unnecessary files\n return allFiles\n .filter((filename) => isChunkRelevant(filename, chunking, filters))\n .map((f) => join(appDir, f));\n}\n\n/**\n * Checks if a chunk file is relevant to the given date range filter.\n * Compares the chunk's time range against the filter's from/to dates.\n */\nfunction isChunkRelevant(\n filename: string,\n chunking: \"monthly\" | \"daily\" | \"weekly\",\n filters: LogFilter\n): boolean {\n // Extract the chunk name (strip .log extension)\n const chunkName = filename.replace(\".log\", \"\");\n const range = getChunkDateRange(chunkName, chunking);\n\n if (!range) {\n return true; // Can't parse — include to be safe\n }\n\n const { start, end } = range;\n\n // Chunk is relevant if its range overlaps with the filter range\n if (filters.to && start > filters.to) {\n return false;\n }\n if (filters.from && end < filters.from) {\n return false;\n }\n\n return true;\n}\n\n/**\n * Returns the start and end date boundaries of a chunk based on its name and strategy.\n * This allows getLogs to skip chunks that fall outside the requested date range.\n */\nfunction getChunkDateRange(\n chunkName: string,\n chunking: \"monthly\" | \"daily\" | \"weekly\"\n): { start: Date; end: Date } | null {\n if (chunking === \"monthly\") {\n // Format: YYYY-MM\n const match = chunkName.match(MONTHLY_PATTERN);\n if (!(match?.[1] && match[2])) {\n return null;\n }\n const year = Number(match[1]);\n const month = Number(match[2]) - 1;\n const start = new Date(year, month, 1);\n const end = new Date(year, month + 1, 0, 23, 59, 59, 999);\n return { start, end };\n }\n\n if (chunking === \"daily\") {\n // Format: YYYY-MM-DD\n const match = chunkName.match(DAILY_PATTERN);\n if (!(match?.[1] && match[2] && match[3])) {\n return null;\n }\n const year = Number(match[1]);\n const month = Number(match[2]) - 1;\n const day = Number(match[3]);\n const start = new Date(year, month, day);\n const end = new Date(year, month, day, 23, 59, 59, 999);\n return { start, end };\n }\n\n // Weekly: YYYY-WNN\n const match = chunkName.match(WEEKLY_PATTERN);\n if (!(match?.[1] && match[2])) {\n return null;\n }\n const year = Number(match[1]);\n const week = Number(match[2]);\n const start = getDateFromISOWeek(year, week);\n const end = new Date(start);\n end.setDate(end.getDate() + 6);\n end.setHours(23, 59, 59, 999);\n return { start, end };\n}\n\n/** Returns the Monday date for a given ISO year and week number */\nfunction getDateFromISOWeek(year: number, week: number): Date {\n const jan4 = new Date(year, 0, 4);\n const dayOfWeek = jan4.getDay() || 7;\n // Monday of week 1\n const monday = new Date(jan4);\n monday.setDate(jan4.getDate() - dayOfWeek + 1);\n // Add (week - 1) weeks\n monday.setDate(monday.getDate() + (week - 1) * 7);\n monday.setHours(0, 0, 0, 0);\n return monday;\n}\n\n/** Reads and parses NDJSON log entries from multiple files into a single array */\nfunction readAndParseLogFiles(files: string[]): Record<string, unknown>[] {\n const logs: Record<string, unknown>[] = [];\n\n for (const file of files) {\n if (!existsSync(file)) {\n continue;\n }\n\n const content = readFileSync(file, \"utf-8\").trim();\n if (!content) {\n continue;\n }\n\n const lines = content.split(\"\\n\");\n for (const line of lines) {\n try {\n const parsed = JSON.parse(line) as Record<string, unknown>;\n logs.push(parsed);\n } catch {\n // Skip malformed lines\n }\n }\n }\n\n return logs;\n}\n\n/** Applies log_id, level, and time range filters to parsed log entries */\nfunction applyLogFilters(\n logs: Record<string, unknown>[],\n filters: LogFilter\n): Log[] {\n return logs.filter((log) => {\n if (filters.appName && log.appName !== filters.appName) {\n return false;\n }\n if (filters.log_id && log.log_id !== filters.log_id) {\n return false;\n }\n if (filters.level && log.level !== filters.level) {\n return false;\n }\n\n const time = new Date(log.time as string);\n if (filters.from && time < filters.from) {\n return false;\n }\n if (filters.to && time > filters.to) {\n return false;\n }\n\n return true;\n }) as unknown as Log[];\n}\n","import { type Log, type LoggerConfig, createLog as newLog } from \"./logger\";\n\ntype LogInput = Omit<Log, \"appName\">;\n\n/**\n * Creates a logger instance bound to a specific app name.\n * Optionally accepts a LoggerConfig for time-based file chunking.\n * @param appName - The application name (determines log file/directory)\n * @param config - Optional config for chunking (monthly, daily, weekly)\n */\nexport const createLogger = (appName: string, config?: LoggerConfig) => {\n return {\n info: (input: LogInput) =>\n newLog({ ...input, appName, level: \"info\" }, config),\n warn: (input: LogInput) =>\n newLog({ ...input, appName, level: \"warn\" }, config),\n error: (input: LogInput) =>\n newLog({ ...input, appName, level: \"error\" }, config),\n };\n};\n","import { safeTry } from \"slang-ts\";\nimport { createEngine } from \"@/engine/engine\";\nimport type { Engine } from \"@/engine/types\";\nimport { createRestApp } from \"@/rest/rest\";\nimport { createDiagnosticsLog } from \"@/utils\";\nimport { createNileContext } from \"./nile\";\nimport type { NileContext, NileServer, Resources, ServerConfig } from \"./types\";\n\nlet _nileContext: NileContext | null = null;\n\n/**\n * Retrieves the runtime NileContext.\n *\n * Use this to access shared resources (database, logger) and context storage\n * from anywhere in your application. Supports a TDB generic to provide\n * end-to-end type safety for your database instance.\n *\n * @template TDB - The type of your database instance (e.g. typeof db)\n * @returns The active NileContext<TDB>\n * @throws If called before createNileServer has initialized the global context.\n */\nexport function getContext<TDB = unknown>(): NileContext<TDB> {\n if (!_nileContext) {\n throw new Error(\n \"getContext: Server not initialized. Call createNileServer first.\"\n );\n }\n return _nileContext as NileContext<TDB>;\n}\n\n/**\n * Bootstraps a Nile server instance.\n *\n * Wires together the Action Engine, shared NileContext, and interface layers (REST).\n * This is the primary entry point for a Nile application. It handles service\n * registration, resource attachment, and server lifecycle.\n *\n * @param config - Server configuration including services, rest options, and resources\n * @returns A NileServer instance containing the engine and (optional) REST app\n */\nexport function createNileServer(config: ServerConfig): NileServer {\n if (!config.services?.length) {\n throw new Error(\n \"createNileServer requires at least one service in config.services\"\n );\n }\n\n const log = createDiagnosticsLog(\"NileServer\", {\n diagnostics: config.diagnostics,\n logger: config.resources?.logger as unknown as Parameters<\n typeof createDiagnosticsLog\n >[1][\"logger\"],\n });\n\n // Shared context -- created once with resources, passed to all layers\n const nileContext = createNileContext({\n resources: config.resources as unknown as Resources<unknown>,\n });\n\n _nileContext = nileContext as unknown as NileContext<unknown>;\n\n // Initialize the Action Engine\n const engine: Engine = createEngine({\n services: config.services,\n diagnostics: config.diagnostics,\n logger: config.resources?.logger as unknown as Parameters<\n typeof createEngine\n >[0][\"logger\"],\n onBeforeActionHandler: config.onBeforeActionHandler,\n onAfterActionHandler: config.onAfterActionHandler,\n });\n\n log(`Engine initialized with ${config.services.length} service(s)`);\n\n // Print registered services table (on by default, opt-out with logServices: false)\n if (config.logServices !== false) {\n const servicesResult = engine.getServices();\n if (servicesResult.isOk) {\n const table = servicesResult.value.map((s) => ({\n Service: s.name,\n Description: s.description,\n Actions: s.actions.length,\n }));\n console.table(table);\n }\n }\n\n // Build the server object incrementally\n const server: NileServer = {\n config,\n engine,\n context: nileContext as NileContext<unknown>,\n };\n\n // Initialize REST interface if configured\n if (config.rest) {\n const app = createRestApp({\n config: config.rest,\n engine,\n nileContext: nileContext as NileContext<unknown>,\n serverName: config.serverName,\n runtime: config.runtime ?? \"bun\",\n });\n\n server.rest = { app, config: config.rest };\n\n const host = config.rest.host ?? \"localhost\";\n const port = config.rest.port ?? 8000;\n const base = `http://${host}:${port}`;\n\n console.log(`\\n POST ${base}${config.rest.baseUrl}/services`);\n if (config.rest.enableStatus) {\n console.log(` GET ${base}/status`);\n }\n console.log(\"\");\n }\n\n // Run onBoot lifecycle hook\n if (config.onBoot) {\n const { fn } = config.onBoot;\n // Fire-and-forget with crash safety via async IIFE\n const _boot = (async () => {\n const result = await safeTry(() => fn(nileContext));\n if (result.isErr) {\n console.error(\"[NileServer] onBoot failed:\", result.error);\n }\n })();\n // Intentionally not awaited — boot runs in background\n _boot;\n }\n\n log(`${config.serverName} server ready`);\n\n return server;\n}\n","import { Err, Ok, type Result } from \"slang-ts\";\nimport type { NileContext } from \"@/nile/types\";\nimport { createDiagnosticsLog } from \"@/utils\";\nimport {\n processHooks,\n runGlobalAfterHook,\n runGlobalBeforeHook,\n runHandler,\n validatePayload,\n} from \"./pipeline\";\nimport type {\n Action,\n ActionSummary,\n EngineOptions,\n ServiceSummary,\n} from \"./types\";\n\nexport function createEngine(options: EngineOptions) {\n const { diagnostics, services, logger } = options;\n\n const log = createDiagnosticsLog(\"Engine\", {\n diagnostics,\n logger: logger as unknown as Parameters<\n typeof createDiagnosticsLog\n >[1][\"logger\"],\n });\n\n // O(1) Pre-computed Lookups\n const serviceSummaries: ServiceSummary[] = [];\n const serviceActionsStore: Record<string, ActionSummary[]> = {};\n const actionStore: Record<string, Record<string, Action>> = {};\n\n // Build stores once on init\n const initStartTime = performance.now();\n\n for (const service of services) {\n const actionNames: string[] = [];\n serviceActionsStore[service.name] = [];\n actionStore[service.name] = {};\n\n for (const action of service.actions) {\n actionNames.push(action.name);\n\n serviceActionsStore[service.name]?.push({\n name: action.name,\n description: action.description,\n isProtected: !!action.isProtected,\n validation: !!action.validation,\n accessControl: action.accessControl || [],\n });\n\n const serviceActions = actionStore[service.name];\n if (serviceActions) {\n serviceActions[action.name] = action;\n }\n }\n\n serviceSummaries.push({\n name: service.name,\n description: service.description,\n meta: service.meta,\n actions: actionNames,\n });\n }\n\n log(\n `Initialized in ${performance.now() - initStartTime}ms. Loaded ${services.length} services.`\n );\n\n // --- Discovery API ---\n\n const getServices = (): Result<ServiceSummary[], string> =>\n Ok(serviceSummaries);\n\n const getServiceActions = (\n serviceName: string\n ): Result<ActionSummary[], string> => {\n const actions = serviceActionsStore[serviceName];\n return actions ? Ok(actions) : Err(`Service '${serviceName}' not found`);\n };\n\n const getAction = (\n serviceName: string,\n actionName: string\n ): Result<Action, string> => {\n const serviceMap = actionStore[serviceName];\n if (!serviceMap) {\n return Err(`Service '${serviceName}' not found`);\n }\n\n const action = serviceMap[actionName];\n return action\n ? Ok(action)\n : Err(`Action '${actionName}' not found in service '${serviceName}'`);\n };\n\n const executeAction = async (\n serviceName: string,\n actionName: string,\n payload: unknown,\n nileContext: NileContext<unknown>\n ): Promise<Result<unknown, string>> => {\n const { onBeforeActionHandler, onAfterActionHandler } = options;\n\n // Resolve action\n const actionResult = getAction(serviceName, actionName);\n if (actionResult.isErr) {\n return Err(actionResult.error);\n }\n const action = actionResult.value;\n\n // Reset hook context for this execution\n nileContext.resetHookContext(`${serviceName}.${actionName}`, payload);\n\n // Step 1: Global Before Hook\n const globalBeforeResult = await runGlobalBeforeHook(\n onBeforeActionHandler,\n nileContext,\n action,\n payload,\n log\n );\n if (globalBeforeResult.isErr) {\n return Err(globalBeforeResult.error);\n }\n\n // Step 2: Action Before Hooks\n const beforeHooksResult = await processHooks(\n action.hooks?.before ?? [],\n payload,\n getAction,\n nileContext,\n \"before\",\n log\n );\n if (beforeHooksResult.isErr) {\n return Err(beforeHooksResult.error);\n }\n\n // Step 3: Validation\n const validationResult = validatePayload(\n action,\n beforeHooksResult.value,\n nileContext,\n log\n );\n if (validationResult.isErr) {\n return Err(validationResult.error);\n }\n\n // Step 4: Handler\n const handlerResult = await runHandler(\n action,\n validationResult.value,\n nileContext,\n log\n );\n if (handlerResult.isErr) {\n return Err(handlerResult.error);\n }\n\n // Step 5: Action After Hooks\n const afterHooksResult = await processHooks(\n action.hooks?.after ?? [],\n handlerResult.value,\n getAction,\n nileContext,\n \"after\",\n log\n );\n if (afterHooksResult.isErr) {\n return Err(afterHooksResult.error);\n }\n\n // Step 6: Global After Hook\n const globalAfterResult = await runGlobalAfterHook(\n onAfterActionHandler,\n nileContext,\n action,\n validationResult.value,\n afterHooksResult.value,\n log\n );\n if (globalAfterResult.isErr) {\n return Err(globalAfterResult.error);\n }\n\n // Final response\n return action.result?.pipeline\n ? Ok({\n data: globalAfterResult.value,\n pipeline: nileContext.hookContext.log,\n })\n : Ok(globalAfterResult.value);\n };\n\n return {\n getServices,\n getServiceActions,\n getAction,\n executeAction,\n };\n}\n","import { count, desc, eq, lt, type SQL } from \"drizzle-orm\";\nimport { Ok, safeTry } from \"slang-ts\";\nimport { getContext } from \"@/nile/server\";\nimport { handleError } from \"../handle-error\";\nimport { createTransactionVariant } from \"./create-transaction-variant\";\nimport { getZodSchema } from \"./get-zod-schema\";\nimport type {\n CursorPage,\n ModelOperations,\n ModelOptions,\n ModelUpdateParams,\n ModelWriteParams,\n OffsetPage,\n OffsetPaginationOptions,\n PaginationOptions,\n TableSchemas,\n} from \"./types\";\n\n/**\n * Minimal shape of a Drizzle database instance for dynamic query building.\n * Covers the select/insert/update/delete chains used by createModel internals.\n * Avoids using the `Function` type while remaining compatible with both\n * Neon and PGLite Drizzle drivers.\n */\ninterface DrizzleDbLike {\n select(fields?: Record<string, unknown>): {\n from(table: unknown): DrizzleSelectQuery;\n };\n insert(table: unknown): {\n values(data: unknown): {\n returning(): Promise<unknown[]>;\n };\n };\n update(table: unknown): {\n set(data: unknown): {\n where(condition: SQL): {\n returning(): Promise<unknown[]>;\n };\n };\n };\n delete(table: unknown): {\n where(condition: SQL): {\n returning(): Promise<unknown[]>;\n };\n };\n}\n\n/** Chainable select query shape — supports where/orderBy/limit/offset in any valid order */\ninterface DrizzleSelectQuery extends Promise<unknown[]> {\n where(condition: SQL): DrizzleSelectQuery;\n orderBy(...cols: SQL[]): DrizzleSelectQuery;\n limit(n: number): DrizzleSelectQuery;\n offset(n: number): DrizzleSelectQuery;\n}\n\n/** Cast db to our minimal interface — safe because Drizzle drivers all expose these methods */\nfunction asDb(db: unknown): DrizzleDbLike {\n return db as DrizzleDbLike;\n}\n\n/**\n * Resolves a database instance from the explicit option or the Nile request context.\n * Throws immediately if neither is available — this is a developer configuration error.\n */\nfunction resolveDb<TDB>(explicitDb: TDB | undefined): TDB {\n if (explicitDb) {\n return explicitDb;\n }\n\n try {\n const ctx = getContext();\n if (ctx.resources?.database) {\n return ctx.resources.database as TDB;\n }\n } catch (_) {\n // context not available — fall through to throw\n }\n throw new Error(\n \"createModel: No database available. Pass db in ModelOptions or set resources.database on server config.\"\n );\n}\n\n/**\n * Detects the timestamp column used for default ordering.\n * Checks for both snake_case (created_at) and camelCase (createdAt) conventions.\n */\nfunction findTimestampColumn(table: Record<string, unknown>): string | null {\n if (\"created_at\" in table) {\n return \"created_at\";\n }\n if (\"createdAt\" in table) {\n return \"createdAt\";\n }\n return null;\n}\n\n/**\n * Creates a CRUD model for a Drizzle table, eliminating repetitive boilerplate.\n *\n * All methods return `Result<T, string>` — `Ok(data)` on success, `Err(message)` on failure.\n * Validation, error handling, and transaction variants are built in.\n *\n * For anything beyond basic CRUD, use the exposed `table` and `schemas` properties\n * to compose custom queries with Drizzle directly.\n *\n * @param table - Drizzle table definition (from pgTable, sqliteTable, etc.)\n * @param options - Configuration: entity name, optional db instance, cursor column\n * @returns Object with CRUD operations, plus escape hatches (table, schemas)\n *\n * @example\n * ```typescript\n * import { createModel } from \"@nilejs/nile\";\n * import { tasks } from \"./schema\";\n * import { db } from \"./client\";\n *\n * // Explicit db\n * export const taskModel = createModel(tasks, { db, name: \"task\" });\n *\n * // Context-resolved db (resolved at call time)\n * export const taskModel = createModel(tasks, { name: \"task\" });\n *\n * // Usage\n * const result = await taskModel.create({ data: { title: \"Ship it\" } });\n * const task = await taskModel.findById(\"uuid-123\");\n * const page = await taskModel.findPaginated({ limit: 20, offset: 0 });\n * ```\n */\nexport function createModel<\n TTable extends { $inferSelect: unknown; $inferInsert: unknown },\n TDB = unknown,\n>(\n table: TTable,\n options: ModelOptions<TDB>\n): ModelOperations<TTable[\"$inferSelect\"], TTable[\"$inferInsert\"], TDB> {\n type TSelect = TTable[\"$inferSelect\"];\n type TInsert = TTable[\"$inferInsert\"];\n\n const { name, cursorColumn = \"id\" } = options;\n const entityName = name.charAt(0).toUpperCase() + name.slice(1);\n const schemas = getZodSchema(table) as TableSchemas<TTable>;\n const tableRef = table as Record<string, unknown>;\n\n /** Resolve and cast db for the current call */\n const getDb = () => asDb(resolveDb<TDB>(options.db));\n\n // -- Core CRUD --\n\n const create = async ({ data, dbx }: ModelWriteParams<TInsert, TDB>) => {\n const parsed = schemas.insert.safeParse(data);\n if (!parsed.success) {\n return handleError({\n message: `Invalid ${name} data`,\n data: { errors: parsed.error },\n atFunction: `${name}.create`,\n });\n }\n\n const db = dbx ? asDb(dbx) : getDb();\n const result = await safeTry(() =>\n db.insert(table).values(data).returning()\n );\n if (result.isErr) {\n return handleError({\n message: `Error creating ${name}`,\n data: { error: result.error },\n atFunction: `${name}.create`,\n });\n }\n\n const row = (result.value as TSelect[])?.[0] ?? null;\n if (!row) {\n return handleError({\n message: `${entityName} creation returned no data`,\n atFunction: `${name}.create`,\n });\n }\n return Ok(row);\n };\n\n const update = async ({ id, data, dbx }: ModelUpdateParams<TSelect, TDB>) => {\n const parsed = schemas.update.safeParse(data);\n if (!parsed.success) {\n return handleError({\n message: `Invalid ${name} data`,\n data: { errors: parsed.error },\n atFunction: `${name}.update`,\n });\n }\n\n const db = dbx ? asDb(dbx) : getDb();\n const idCol = tableRef.id as Parameters<typeof eq>[0];\n const result = await safeTry(() =>\n db.update(table).set(data).where(eq(idCol, id)).returning()\n );\n if (result.isErr) {\n return handleError({\n message: `Error updating ${name}`,\n data: { id, error: result.error },\n atFunction: `${name}.update`,\n });\n }\n\n const row = (result.value as TSelect[])?.[0] ?? null;\n if (!row) {\n return handleError({\n message: `${entityName} not found`,\n data: { id },\n atFunction: `${name}.update`,\n });\n }\n return Ok(row);\n };\n\n // Transaction variants via existing utility\n const createTx = createTransactionVariant(\n create as Parameters<typeof createTransactionVariant>[0]\n );\n const updateTx = createTransactionVariant(\n update as Parameters<typeof createTransactionVariant>[0]\n );\n\n const findById = async (id: string) => {\n const db = getDb();\n const idCol = tableRef.id as Parameters<typeof eq>[0];\n const result = await safeTry(() =>\n db.select().from(table).where(eq(idCol, id))\n );\n if (result.isErr) {\n return handleError({\n message: `Error getting ${name}`,\n data: { id, error: result.error },\n atFunction: `${name}.findById`,\n });\n }\n\n const row = (result.value as TSelect[])?.[0] ?? null;\n if (!row) {\n return handleError({\n message: `${entityName} not found`,\n data: { id },\n atFunction: `${name}.findById`,\n });\n }\n return Ok(row);\n };\n\n const deleteFn = async (id: string) => {\n const db = getDb();\n const idCol = tableRef.id as Parameters<typeof eq>[0];\n const result = await safeTry(() =>\n db.delete(table).where(eq(idCol, id)).returning()\n );\n if (result.isErr) {\n return handleError({\n message: `Error deleting ${name}`,\n data: { id, error: result.error },\n atFunction: `${name}.delete`,\n });\n }\n\n const row = (result.value as TSelect[])?.[0] ?? null;\n if (!row) {\n return handleError({\n message: `${entityName} not found`,\n data: { id },\n atFunction: `${name}.delete`,\n });\n }\n return Ok(row);\n };\n\n const findAll = async () => {\n const db = getDb();\n const tsCol = findTimestampColumn(tableRef);\n\n const result = await safeTry(() => {\n const query = db.select().from(table);\n if (!tsCol) {\n return query;\n }\n return query.orderBy(desc(tableRef[tsCol] as Parameters<typeof desc>[0]));\n });\n if (result.isErr) {\n return handleError({\n message: `Error getting all ${name}s`,\n data: { error: result.error },\n atFunction: `${name}.findAll`,\n });\n }\n\n return Ok((result.value ?? []) as TSelect[]);\n };\n\n /** Offset-based pagination — returns items, total count, and hasMore flag */\n const findOffsetPage = async (limit: number, offset: number) => {\n const db = getDb();\n const tsCol = findTimestampColumn(tableRef);\n\n const itemsResult = await safeTry(() => {\n const query = db.select().from(table);\n const ordered = tsCol\n ? query.orderBy(desc(tableRef[tsCol] as Parameters<typeof desc>[0]))\n : query;\n return ordered.limit(limit).offset(offset);\n });\n if (itemsResult.isErr) {\n return handleError({\n message: `Error getting paginated ${name}s`,\n data: { limit, offset, error: itemsResult.error },\n atFunction: `${name}.findPaginated`,\n });\n }\n\n const countResult = await safeTry(() =>\n db.select({ total: count() }).from(table)\n );\n if (countResult.isErr) {\n return handleError({\n message: `Error getting ${name} count`,\n data: { error: countResult.error },\n atFunction: `${name}.findPaginated`,\n });\n }\n\n const items = (itemsResult.value ?? []) as TSelect[];\n const total = (countResult.value as { total: number }[])?.[0]?.total ?? 0;\n\n return Ok({\n items,\n total,\n hasMore: offset + items.length < total,\n } satisfies OffsetPage<TSelect>);\n };\n\n /** Cursor-based pagination — uses lt() on the cursor column with desc ordering */\n const findCursorPage = async (\n limit: number,\n cursor: string,\n colName: string\n ) => {\n const db = getDb();\n const column = tableRef[colName];\n\n if (!column) {\n return handleError({\n message: `Cursor column '${colName}' does not exist on ${name} table`,\n atFunction: `${name}.findPaginated`,\n });\n }\n\n const typedColumn = column as Parameters<typeof lt>[0];\n\n // Fetch one extra row to determine hasMore without a separate count query\n const result = await safeTry(() =>\n db\n .select()\n .from(table)\n .where(lt(typedColumn, cursor))\n .orderBy(desc(typedColumn))\n .limit(limit + 1)\n );\n if (result.isErr) {\n return handleError({\n message: `Error getting paginated ${name}s`,\n data: { cursor, cursorColumn: colName, error: result.error },\n atFunction: `${name}.findPaginated`,\n });\n }\n\n const rows = (result.value ?? []) as TSelect[];\n const hasMore = rows.length > limit;\n const items = hasMore ? rows.slice(0, limit) : rows;\n const lastItem = items.at(-1) as Record<string, unknown> | undefined;\n const nextCursor = lastItem\n ? String(lastItem[colName] ?? \"\") || null\n : null;\n\n return Ok({\n items,\n nextCursor,\n hasMore,\n } satisfies CursorPage<TSelect>);\n };\n\n const findPaginated = (opts: PaginationOptions = {}) => {\n const limit = opts.limit ?? 50;\n\n // Cursor mode when cursor is provided\n if (\"cursor\" in opts && opts.cursor) {\n const colName = opts.cursorColumn ?? cursorColumn;\n return findCursorPage(limit, opts.cursor, colName);\n }\n\n // Default: offset mode\n const offset = (opts as OffsetPaginationOptions).offset ?? 0;\n return findOffsetPage(limit, offset);\n };\n\n return {\n create,\n createTx,\n findById,\n update,\n updateTx,\n delete: deleteFn,\n findAll,\n findPaginated,\n table,\n schemas,\n } as ModelOperations<TSelect, TInsert, TDB>;\n}\n","import { Err, type ErrType, type ResultMethods } from \"slang-ts\";\nimport { getContext } from \"@/nile/server\";\nimport type { NileLogger } from \"@/nile/types\";\n\n/**\n * Parameters for the handleError utility.\n *\n * @property message - Human-readable error description, included in the returned Result error string\n * @property data - Optional structured data logged alongside the error for debugging\n * @property logger - Explicit logger instance; when omitted, resolves from the current Nile request context\n * @property atFunction - Name of the calling function for log attribution; auto-inferred from stack trace when omitted\n */\nexport interface HandleErrorParams {\n message: string;\n data?: unknown;\n logger?: NileLogger;\n atFunction?: string;\n}\n\nconst CALLER_LINE_REGEX = /at\\s+(\\S+)\\s+/;\n\nfunction inferCallerName(): string {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const _err = new Error(\"capture stack trace\");\n const stack = _err.stack;\n const callerLine = stack?.split(\"\\n\")[3] ?? \"\";\n const match = callerLine.match(CALLER_LINE_REGEX);\n return match?.[1] ?? \"unknown\";\n}\n\nfunction resolveLogger(explicit?: NileLogger): NileLogger {\n if (explicit) {\n return explicit;\n }\n try {\n const ctx = getContext();\n if (ctx.resources?.logger) {\n return ctx.resources.logger;\n }\n } catch (_) {\n // Fall through to throw\n }\n throw new Error(\n \"handleError: No logger available. Provide a logger param or set resources.logger on server config.\"\n );\n}\n\n/**\n * Logs an error via the resolved logger and returns a typed Err result.\n * Resolves the logger from the current Nile request context when not provided explicitly.\n * The returned error string includes the log ID for traceability: `[logId] message`.\n *\n * @param params - Error details including message, optional data, logger, and caller function name\n * @returns Always an Err variant — `ErrType<string> & ResultMethods<never>`, compatible with any `Result<T, E>` union\n *\n * @example\n * ```typescript\n * if (!user) {\n * return handleError({\n * message: \"User not found\",\n * data: { userId },\n * atFunction: \"getUserById\",\n * });\n * }\n * ```\n */\nexport function handleError(\n params: HandleErrorParams\n): ErrType<string> & ResultMethods<never> {\n const atFunction = params.atFunction ?? inferCallerName();\n const logger = resolveLogger(params.logger);\n const logId = logger.error({\n atFunction,\n message: params.message,\n data: params.data,\n });\n return Err(`[${logId}] ${params.message}`);\n}\n","import type { Result } from \"slang-ts\";\nimport type { DBParams } from \"./types\";\n\n/**\n * Creates a transaction-aware variant of a database function.\n * Expects the wrapped function to accept a single object parameter with optional dbx field.\n *\n * When dbx is root db (has .transaction method):\n * - Creates new transaction and executes function inside it\n * - On Result.isError, throws Error to trigger automatic rollback\n * - Returns successful result or throws\n *\n * When dbx is tx pointer (no .transaction method):\n * - Executes function directly within existing transaction scope\n * - On Result.isError, throws Error to trigger parent transaction rollback\n * - Returns successful result or throws\n *\n * Both cases ensure database rollback on any error by throwing.\n *\n * @example\n * ```typescript\n * const createCompanyTx = createTransactionVariant(createCompany);\n * // Type-safe: requires all params from createCompany\n * const result = await createCompanyTx({ company: {...}, dbx: tx });\n * ```\n */\nexport function createTransactionVariant<\n TParams extends DBParams<TDB>,\n TData,\n TDB = unknown,\n>(\n fn: (params: TParams) => Promise<Result<TData, unknown>>\n): (params: TParams) => Promise<Result<TData, unknown>> {\n return async (params: TParams): Promise<Result<TData, unknown>> => {\n const { dbx, ...rest } = params;\n\n if (!dbx) {\n const result = await fn(params as TParams);\n if (result.isErr) {\n throw new Error(String(result.error));\n }\n return result;\n }\n\n const hasTransaction =\n typeof (dbx as Record<string, unknown>)?.transaction === \"function\";\n\n if (hasTransaction) {\n return await (\n dbx as unknown as {\n transaction: (\n fn: (tx: unknown) => Promise<Result<TData, unknown>>\n ) => Promise<Result<TData, unknown>>;\n }\n ).transaction(async (tx: unknown) => {\n const result = await fn({ ...rest, dbx: tx } as TParams);\n if (result.isErr) {\n throw new Error(String(result.error));\n }\n return result;\n });\n }\n\n const result = await fn({ ...rest, dbx } as TParams);\n if (result.isErr) {\n throw new Error(String(result.error));\n }\n return result;\n };\n}\n","import {\n createInsertSchema,\n createSelectSchema,\n createUpdateSchema,\n} from \"drizzle-zod\";\nimport type { TableSchemas } from \"./types\";\n\n/**\n * Generates Zod schemas (insert, update, select) from a Drizzle table.\n *\n * @param table - The Drizzle table definition\n * @returns Object containing insert, update, and select Zod schemas\n *\n * @example\n * ```typescript\n * import { getZodSchema } from '@nilejs/nile';\n * import { companies } from './schema';\n *\n * const schemas = getZodSchema(companies);\n * const insert = schemas.insert.parse(data);\n * const update = schemas.update.partial().parse(data);\n * ```\n */\nexport function getZodSchema<TTable extends object>(\n table: TTable\n): TableSchemas<TTable> {\n const isRelation =\n Object.hasOwn(table as object, \"config\") &&\n Object.hasOwn(table as object, \"table\");\n\n if (isRelation) {\n throw new Error(\n `${String(table)} is a relation schema, not a table schema`\n );\n }\n\n const insertSchema = createInsertSchema(\n table as unknown as Parameters<typeof createInsertSchema>[0]\n );\n const updateSchema = createUpdateSchema(\n table as unknown as Parameters<typeof createUpdateSchema>[0]\n );\n const selectSchema = createSelectSchema(\n table as unknown as Parameters<typeof createSelectSchema>[0]\n );\n\n return {\n insert: insertSchema,\n update: updateSchema,\n select: selectSchema,\n } as TableSchemas<TTable>;\n}\n","import type { NileLogger } from \"@/nile/types\";\n\ntype AnyLogger = NileLogger | { info: (msg: string, data?: unknown) => void };\n\nfunction isNileLogger(logger: AnyLogger): logger is NileLogger {\n return \"warn\" in logger && \"error\" in logger;\n}\n\ninterface CreateDiagnosticsLogParams {\n diagnostics?: boolean;\n logger?: AnyLogger;\n}\n\n/**\n * Creates a centralized diagnostics log function for nile internals.\n * Checks resources.logger first, falls back to console.log, respects diagnostics flag.\n * Returns a bound function with the prefix already applied for clean call sites.\n *\n * @param prefix - Component identifier e.g. \"NileServer\", \"REST\", \"Engine\"\n * @param params - Diagnostics flag and optional structured logger from resources\n * @returns A log function: (message, data?) => void\n */\nexport function createDiagnosticsLog(\n prefix: string,\n params: CreateDiagnosticsLogParams\n): (message: string, data?: unknown) => void {\n if (!params.diagnostics) {\n // biome-ignore lint/suspicious/noEmptyBlockStatements: intentional no-op when diagnostics disabled\n return () => {};\n }\n\n const { logger } = params;\n\n return (message: string, data?: unknown) => {\n if (!logger) {\n console.log(`[${prefix}] ${message}`, data ?? \"\");\n return;\n }\n\n if (isNileLogger(logger)) {\n logger.info({\n atFunction: prefix,\n message: `[${prefix}] ${message}`,\n data,\n });\n } else {\n logger.info(`[${prefix}] ${message}`, data);\n }\n };\n}\n","import { Err, Ok, type Result, safeTry } from \"slang-ts\";\nimport { prettifyError } from \"zod\";\nimport type {\n AfterActionHandler,\n BeforeActionHandler,\n NileContext,\n} from \"@/nile/types\";\nimport type { Action, HookDefinition, HookLogEntry } from \"./types\";\n\n/**\n * Executes a single hook and logs the result\n */\nasync function runHook(\n hookDef: HookDefinition,\n hookAction: Action,\n input: unknown,\n nileContext: NileContext\n): Promise<{ result: Result<unknown, string>; logEntry: HookLogEntry }> {\n const result = await safeTry(() =>\n hookAction.handler(input as Record<string, unknown>, nileContext)\n );\n return {\n result,\n logEntry: {\n name: `${hookDef.service}.${hookDef.action}`,\n input,\n output: result.isOk ? result.value : result.error,\n passed: result.isOk,\n },\n };\n}\n\n/**\n * Process hooks sequentially, each hook output becomes the next input\n */\nexport async function processHooks(\n hooks: HookDefinition[],\n initialValue: unknown,\n getAction: (service: string, action: string) => Result<Action, string>,\n nileContext: NileContext,\n logTarget: \"before\" | \"after\",\n log: (msg: string, data?: unknown) => void\n): Promise<Result<unknown, string>> {\n let currentValue = initialValue;\n\n for (const hookDef of hooks) {\n const hookActionResult = getAction(hookDef.service, hookDef.action);\n\n if (hookActionResult.isErr) {\n const errorMsg = `${logTarget} hook '${hookDef.service}.${hookDef.action}' not found`;\n log(errorMsg);\n if (hookDef.isCritical) {\n nileContext.setHookError(errorMsg);\n return Err(errorMsg);\n }\n continue;\n }\n\n const { result, logEntry } = await runHook(\n hookDef,\n hookActionResult.value,\n currentValue,\n nileContext\n );\n nileContext.addHookLog(logTarget, logEntry);\n\n if (result.isErr) {\n const errorMsg = String(result.error);\n log(\n `${logTarget} hook '${hookDef.service}.${hookDef.action}' failed`,\n result.error\n );\n if (hookDef.isCritical) {\n nileContext.setHookError(errorMsg);\n return Err(errorMsg);\n }\n continue;\n }\n\n currentValue = result.value;\n }\n\n return Ok(currentValue);\n}\n\n/**\n * Run global before hook if configured, wrapped in safeTry for crash safety\n */\nexport async function runGlobalBeforeHook(\n handler: BeforeActionHandler<unknown, unknown> | undefined,\n nileContext: NileContext,\n action: Action,\n payload: unknown,\n log: (msg: string) => void\n): Promise<Result<true, string>> {\n if (!handler) {\n return Ok(true);\n }\n\n const result = await safeTry(() => handler({ nileContext, action, payload }));\n if (result.isErr) {\n log(`Global before hook failed for ${action.name}`);\n nileContext.setHookError(result.error);\n return Err(result.error);\n }\n\n return Ok(true);\n}\n\n/**\n * Run global after hook if configured, wrapped in safeTry for crash safety\n */\nexport async function runGlobalAfterHook(\n handler: AfterActionHandler<unknown, unknown> | undefined,\n nileContext: NileContext,\n action: Action,\n payload: unknown,\n currentResult: unknown,\n log: (msg: string) => void\n): Promise<Result<unknown, string>> {\n if (!handler) {\n return Ok(currentResult);\n }\n\n const result = await safeTry(() =>\n handler({\n nileContext,\n action,\n payload,\n result: Ok(currentResult),\n })\n );\n if (result.isErr) {\n log(`Global after hook failed for ${action.name}`);\n nileContext.setHookError(result.error);\n return Err(result.error);\n }\n\n return Ok(result.value);\n}\n\n/**\n * Validate payload against action's Zod schema\n */\nexport function validatePayload(\n action: Action,\n payload: unknown,\n nileContext: NileContext,\n log: (msg: string, data?: unknown) => void\n): Result<unknown, string> {\n if (!action.validation) {\n return Ok(payload);\n }\n\n const parseResult = action.validation.safeParse(payload);\n if (!parseResult.success) {\n const validationError = prettifyError(parseResult.error);\n log(`Validation failed for ${action.name}`, validationError);\n nileContext.setHookError(validationError);\n return Err(`Validation failed: ${validationError}`);\n }\n\n return Ok(parseResult.data);\n}\n\n/**\n * Execute the main action handler, wrapped in safeTry for crash safety\n */\nexport async function runHandler(\n action: Action,\n payload: unknown,\n nileContext: NileContext,\n log: (msg: string, data?: unknown) => void\n): Promise<Result<unknown, string>> {\n const result = await safeTry(() =>\n action.handler(payload as Record<string, unknown>, nileContext)\n );\n\n if (result.isErr) {\n log(`Handler failed for ${action.name}`, result.error);\n nileContext.setHookError(result.error);\n return Err(result.error);\n }\n\n nileContext.setHookOutput(result.value);\n return Ok(result.value);\n}\n","import { Hono } from \"hono\";\nimport z from \"zod\";\nimport { applyCorsConfig } from \"@/cors/cors\";\nimport type { Engine } from \"@/engine/types\";\nimport type {\n ExternalRequest,\n ExternalResponse,\n NileContext,\n ServerRuntime,\n} from \"@/nile/types\";\nimport { createDiagnosticsLog } from \"@/utils\";\nimport { intentHandlers } from \"./intent-handlers\";\nimport { applyRateLimiting, applyStaticServing } from \"./middleware\";\nimport type { RestConfig } from \"./types\";\n\n// --- Zod schema for incoming requests ---\n\nconst externalRequestSchema = z.object({\n intent: z.enum([\"explore\", \"execute\", \"schema\"]),\n service: z.string().min(1),\n action: z.string().min(1),\n payload: z.record(z.string(), z.unknown()),\n});\n\n// --- Factory ---\n\ninterface CreateRestAppParams {\n config: RestConfig;\n engine: Engine;\n nileContext: NileContext<unknown>;\n serverName: string;\n runtime: ServerRuntime;\n}\n\n/**\n * Creates the Hono REST app with a single POST endpoint for all service interactions\n * and an optional GET /status health check.\n *\n * All service communication flows through POST {baseUrl}/services using\n * the intent field to discriminate between explore, execute, and schema operations.\n */\nexport function createRestApp(params: CreateRestAppParams): Hono {\n const { config, engine, nileContext, serverName, runtime } = params;\n const app = new Hono();\n\n const log = createDiagnosticsLog(\"REST\", {\n diagnostics: config.diagnostics,\n logger: nileContext.resources?.logger as\n | { info: (msg: string, data?: unknown) => void }\n | undefined,\n });\n\n // Apply CORS\n applyCorsConfig(app, config);\n\n // Apply rate limiting when a limiting header is configured\n applyRateLimiting(app, config, log);\n\n // Apply static file serving based on runtime\n applyStaticServing(app, config, runtime, log);\n\n // Single POST endpoint for all service interactions\n const servicesPath = `${config.baseUrl}/services`;\n\n app.post(servicesPath, async (c) => {\n const body = await c.req.json().catch(() => null);\n\n if (!body) {\n return c.json(\n {\n status: false,\n message: \"Invalid or missing JSON body\",\n data: {},\n } satisfies ExternalResponse,\n 400\n );\n }\n\n const parsed = externalRequestSchema.safeParse(body);\n if (!parsed.success) {\n return c.json(\n {\n status: false,\n message: \"Invalid request format\",\n data: { errors: parsed.error.issues },\n } satisfies ExternalResponse,\n 400\n );\n }\n\n const request = parsed.data as ExternalRequest;\n\n log(`${request.intent} -> ${request.service}.${request.action}`);\n\n const handler = intentHandlers[request.intent];\n // biome-ignore lint/suspicious/noExplicitAny: internal dispatch\n const response = await (handler as any)(engine, request, nileContext);\n\n const statusCode = response.status ? 200 : 400;\n return c.json(response, statusCode);\n });\n\n // Health check endpoint\n if (config.enableStatus) {\n app.get(\"/status\", (c) => {\n return c.json({\n status: true,\n message: `${serverName} is running`,\n data: {},\n } satisfies ExternalResponse);\n });\n }\n\n // 404 handler\n app.notFound((c) => {\n return c.json(\n {\n status: false,\n message: `Route not found. Use POST ${servicesPath} for all operations.`,\n data: {},\n } satisfies ExternalResponse,\n 404\n );\n });\n\n log(`REST interface ready at ${servicesPath}`);\n\n return app;\n}\n","import type { Context, Hono } from \"hono\";\nimport { cors } from \"hono/cors\";\nimport type { RestConfig } from \"@/rest/types\";\nimport type { CorsConfig, CorsOptions } from \"./types\";\n\n/**\n * Build default CORS options from REST config\n */\nexport const buildDefaultCorsOptions = (config: RestConfig): CorsOptions => {\n const getDefaultOrigin = (reqOrigin: string) => {\n if (config.allowedOrigins.length > 0) {\n return config.allowedOrigins.includes(reqOrigin ?? \"\") ? reqOrigin : \"\";\n }\n return \"*\";\n };\n\n return {\n origin: config.cors?.defaults?.origin ?? getDefaultOrigin,\n credentials: config.cors?.defaults?.credentials ?? true,\n allowHeaders: config.cors?.defaults?.allowHeaders ?? [\n \"Content-Type\",\n \"Authorization\",\n ],\n allowMethods: config.cors?.defaults?.allowMethods ?? [\n \"POST\",\n \"GET\",\n \"OPTIONS\",\n ],\n exposeHeaders: config.cors?.defaults?.exposeHeaders ?? [\"Content-Length\"],\n maxAge: config.cors?.defaults?.maxAge ?? 600,\n };\n};\n\n/**\n * Apply CORS configuration to a Hono app based on RestConfig\n */\nexport const applyCorsConfig = (app: Hono, config: RestConfig): void => {\n const corsEnabled = config.cors?.enabled ?? \"default\";\n\n if (corsEnabled === false) {\n return;\n }\n\n const defaultCorsOpts = buildDefaultCorsOptions(config);\n\n // Apply route-specific CORS rules FIRST (before global catch-all)\n const corsRules = config.cors?.addCors ?? [];\n for (const rule of corsRules) {\n applyRouteCorsRule(app, rule, defaultCorsOpts);\n }\n\n // Apply global CORS as fallback\n app.use(\"*\", cors(defaultCorsOpts as Parameters<typeof cors>[0]));\n};\n\n/**\n * Apply a single route-specific CORS rule\n */\nconst applyRouteCorsRule = (\n app: Hono,\n rule: NonNullable<CorsConfig[\"addCors\"]>[number],\n defaultOpts: CorsOptions\n): void => {\n if (rule.resolver) {\n applyResolverBasedCors(app, rule.path, rule.resolver, defaultOpts);\n } else if (rule.options) {\n applyStaticCors(app, rule.path, rule.options, defaultOpts);\n }\n};\n\n/**\n * Apply resolver-based CORS for a specific path\n */\nconst applyResolverBasedCors = (\n app: Hono,\n path: string,\n resolver: NonNullable<CorsConfig[\"addCors\"]>[number][\"resolver\"],\n defaultOpts: CorsOptions\n): void => {\n if (!resolver) {\n return;\n }\n\n app.use(path, (c, next) => {\n const reqOrigin = c.req.header(\"origin\") ?? \"\";\n const corsOpts = evaluateResolver(resolver, reqOrigin, c, defaultOpts);\n return cors(corsOpts as Parameters<typeof cors>[0])(c, next);\n });\n};\n\n/**\n * Apply static CORS options for a specific path\n */\nconst applyStaticCors = (\n app: Hono,\n path: string,\n options: CorsOptions,\n defaultOpts: CorsOptions\n): void => {\n app.use(\n path,\n cors({ ...defaultOpts, ...options } as Parameters<typeof cors>[0])\n );\n};\n\n/**\n * Evaluate CORS resolver and return appropriate options\n */\nconst evaluateResolver = (\n resolver: NonNullable<CorsConfig[\"addCors\"]>[number][\"resolver\"],\n origin: string,\n c: Context,\n defaultOpts: CorsOptions\n): CorsOptions => {\n if (!resolver) {\n return defaultOpts;\n }\n\n try {\n const result = resolver(origin, c);\n\n if (result === true) {\n return { ...defaultOpts, origin: origin || \"*\" };\n }\n\n if (result === false) {\n return { ...defaultOpts, origin: \"\" };\n }\n\n if (result && typeof result === \"object\") {\n return { ...defaultOpts, ...result };\n }\n\n return defaultOpts;\n } catch (error) {\n // Security: deny on resolver failure — never fall through to allow\n console.error(\"CORS resolver error:\", error);\n return { ...defaultOpts, origin: \"\" };\n }\n};\n","import { Ok, type Result } from \"slang-ts\";\nimport z from \"zod\";\nimport type { Engine } from \"@/engine/types\";\nimport type {\n ExternalRequest,\n ExternalResponse,\n NileContext,\n} from \"@/nile/types\";\n\n// --- Response mapping ---\n\n/**\n * Maps an internal Result to the external API response shape.\n * This is the single point where internal Result types cross the boundary\n * into the HTTP-facing ExternalResponse format.\n */\nexport function toExternalResponse(\n result: Result<unknown, string>,\n successMessage: string\n): ExternalResponse {\n if (result.isOk) {\n const value = result.value;\n const data =\n value !== null && typeof value === \"object\" && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : { result: value };\n\n return { status: true, message: successMessage, data };\n }\n\n return { status: false, message: result.error, data: {} };\n}\n\n// --- Intent handlers ---\n\n/**\n * Handles the \"explore\" intent for service/action discovery.\n * - service: \"*\", action: \"*\" -> list all services\n * - service: \"name\", action: \"*\" -> list actions for service\n * - service: \"name\", action: \"name\" -> action metadata\n */\nexport function handleExplore(\n engine: Engine,\n request: ExternalRequest\n): ExternalResponse {\n const { service, action } = request;\n\n if (service === \"*\") {\n return toExternalResponse(engine.getServices(), \"Available services\");\n }\n\n if (action === \"*\") {\n return toExternalResponse(\n engine.getServiceActions(service),\n `Actions for '${service}'`\n );\n }\n\n const actionResult = engine.getAction(service, action);\n if (actionResult.isErr) {\n return toExternalResponse(actionResult, \"\");\n }\n\n const act = actionResult.value;\n return toExternalResponse(\n Ok({\n name: act.name,\n description: act.description,\n isProtected: act.isProtected ?? false,\n accessControl: act.accessControl,\n hooks: act.hooks\n ? { before: act.hooks.before ?? [], after: act.hooks.after ?? [] }\n : null,\n meta: act.meta ?? null,\n }),\n `Details for '${service}.${action}'`\n );\n}\n\n/**\n * Handles the \"execute\" intent by running an action through the engine pipeline.\n */\nexport async function handleExecute(\n engine: Engine,\n request: ExternalRequest,\n nileContext: NileContext<unknown>\n): Promise<ExternalResponse> {\n const { service, action, payload } = request;\n\n if (service === \"*\" || action === \"*\") {\n return {\n status: false,\n message:\n \"Execute intent requires specific service and action, wildcards not allowed\",\n data: {},\n };\n }\n\n const result = await engine.executeAction(\n service,\n action,\n payload,\n nileContext\n );\n\n return toExternalResponse(result, `Action '${service}.${action}' executed`);\n}\n\n/**\n * Handles the \"schema\" intent for Zod-to-JSON-Schema export.\n * - service: \"*\", action: \"*\" -> all schemas across all services\n * - service: \"name\", action: \"*\" -> all schemas in a service\n * - service: \"name\", action: \"name\" -> single action schema\n */\nexport function handleSchema(\n engine: Engine,\n request: ExternalRequest\n): ExternalResponse {\n const { service, action } = request;\n\n if (service === \"*\") {\n const servicesResult = engine.getServices();\n if (servicesResult.isErr) {\n return toExternalResponse(servicesResult, \"\");\n }\n\n const schemas: Record<string, unknown> = {};\n for (const svc of servicesResult.value) {\n const actionsResult = engine.getServiceActions(svc.name);\n if (actionsResult.isErr) {\n continue;\n }\n\n schemas[svc.name] = buildServiceSchemas(\n engine,\n svc.name,\n actionsResult.value.map((a) => a.name)\n );\n }\n\n return toExternalResponse(Ok(schemas), \"All service schemas\");\n }\n\n if (action === \"*\") {\n const actionsResult = engine.getServiceActions(service);\n if (actionsResult.isErr) {\n return toExternalResponse(actionsResult, \"\");\n }\n\n const schemas = buildServiceSchemas(\n engine,\n service,\n actionsResult.value.map((a) => a.name)\n );\n return toExternalResponse(Ok(schemas), `Schemas for '${service}'`);\n }\n\n const actionResult = engine.getAction(service, action);\n if (actionResult.isErr) {\n return toExternalResponse(actionResult, \"\");\n }\n\n const schema = extractActionSchema(actionResult.value);\n return toExternalResponse(\n Ok({ [action]: schema }),\n `Schema for '${service}.${action}'`\n );\n}\n\n/**\n * Builds a map of action schemas for a service\n */\nfunction buildServiceSchemas(\n engine: Engine,\n serviceName: string,\n actionNames: string[]\n): Record<string, unknown> {\n const schemas: Record<string, unknown> = {};\n\n for (const actionName of actionNames) {\n const actionResult = engine.getAction(serviceName, actionName);\n if (actionResult.isErr) {\n continue;\n }\n schemas[actionName] = extractActionSchema(actionResult.value);\n }\n\n return schemas;\n}\n\n/**\n * Extracts JSON schema from an action's zod validation, returns null on failure\n */\nfunction extractActionSchema(action: {\n validation?: import(\"zod\").ZodType | null;\n}): unknown {\n const schema = action.validation;\n if (!schema) {\n return null;\n }\n\n const { err, result } = safeTrySync(() =>\n z.toJSONSchema(schema, { unrepresentable: \"any\" })\n );\n\n return err ? null : result;\n}\n\n/**\n * Synchronous try-catch wrapper for simple operations.\n * Unlike slang-ts safeTry (always async), this is for sync-only code paths.\n */\nfunction safeTrySync<T>(fn: () => T): { err: unknown; result: T | null } {\n try {\n return { err: null, result: fn() };\n } catch (error) {\n return { err: error, result: null };\n }\n}\n\n// --- Intent dispatch ---\n\n/** Object lookup for intent handlers — cleaner than switch/if-else */\nexport const intentHandlers: Record<\n ExternalRequest[\"intent\"],\n (\n engine: Engine,\n request: ExternalRequest,\n nileContext: NileContext<unknown>\n ) => ExternalResponse | Promise<ExternalResponse>\n> = {\n explore: (engine, request) => handleExplore(engine, request),\n execute: (engine, request, nileContext) =>\n handleExecute(engine, request, nileContext),\n schema: (engine, request) => handleSchema(engine, request),\n};\n","import type { Hono } from \"hono\";\nimport { rateLimiter } from \"hono-rate-limiter\";\nimport { safeTry } from \"slang-ts\";\nimport type { ServerRuntime } from \"@/nile/types\";\nimport type { RestConfig } from \"./types\";\n\nconst ASSETS_REGEX = /^\\/assets\\//;\nconst DEFAULT_RATE_LIMIT_WINDOW_MS = 15 * 60 * 1000; // 15 minutes\nconst DEFAULT_RATE_LIMIT_MAX = 100;\nconst UNKNOWN_CLIENT_KEY = \"__unknown_client__\";\n\n/**\n * Applies rate limiting middleware when a limiting header is configured.\n * Extracts the client key from the configured request header for per-client tracking.\n * Falls back to a shared key when the header is missing (graceful degradation).\n */\nexport function applyRateLimiting(\n app: Hono,\n config: RestConfig,\n log: (msg: string, data?: unknown) => void\n): void {\n if (!config.rateLimiting?.limitingHeader) {\n return;\n }\n\n const { rateLimiting } = config;\n\n app.use(\n rateLimiter({\n windowMs: rateLimiting.windowMs ?? DEFAULT_RATE_LIMIT_WINDOW_MS,\n limit: rateLimiting.limit ?? DEFAULT_RATE_LIMIT_MAX,\n standardHeaders: rateLimiting.standardHeaders ?? true,\n keyGenerator: (c) => {\n const key = c.req.header(rateLimiting.limitingHeader);\n if (!key) {\n log(\n `Rate limiting header '${rateLimiting.limitingHeader}' missing from request`\n );\n return UNKNOWN_CLIENT_KEY;\n }\n return key;\n },\n store: rateLimiting.store ?? undefined,\n })\n );\n\n log(\n `Rate limiting enabled: ${rateLimiting.limit ?? DEFAULT_RATE_LIMIT_MAX} requests per ${rateLimiting.windowMs ?? DEFAULT_RATE_LIMIT_WINDOW_MS}ms window`\n );\n}\n\n/**\n * Applies static file serving from ./assets at /assets/*.\n * Uses dynamic import to load the runtime-specific serveStatic adapter,\n * avoiding issues with Bun globals in non-Bun environments (e.g. vitest).\n * Import errors are caught gracefully — static serving is skipped if the adapter fails to load.\n */\nexport function applyStaticServing(\n app: Hono,\n config: RestConfig,\n runtime: ServerRuntime,\n log: (msg: string, data?: unknown) => void\n): void {\n if (!config.enableStatic) {\n return;\n }\n\n if (runtime !== \"bun\") {\n log(`Static file serving not yet supported for runtime: ${runtime}`);\n return;\n }\n\n // Lazy-load the bun serveStatic adapter to avoid referencing Bun globals at import time\n let cachedHandler:\n | ((c: never, next: never) => Promise<Response | undefined>)\n | null = null;\n let importFailed = false;\n\n app.use(\"/assets/*\", async (c, next) => {\n if (importFailed) {\n return next();\n }\n\n if (!cachedHandler) {\n const importResult = await safeTry(async () => {\n const mod = await import(\"hono/bun\");\n return mod.serveStatic({\n root: \"./assets\",\n rewriteRequestPath: (path: string) => path.replace(ASSETS_REGEX, \"\"),\n });\n });\n\n if (importResult.isErr) {\n log(\"Failed to load static file adapter\", importResult.error);\n importFailed = true;\n return next();\n }\n\n cachedHandler = importResult.value as unknown as typeof cachedHandler;\n }\n\n if (cachedHandler) {\n return cachedHandler(c as never, next as never);\n }\n });\n\n log(\"Static file serving enabled at /assets/*\");\n}\n","import type { BaseContext, NileContext, Resources, Sessions } from \"./types\";\n\ninterface CreateNileContextParams<TDB = unknown> {\n interfaceContext?: BaseContext;\n resources?: Resources<TDB>;\n}\n\n/**\n * Creates a new Nile context with an internal key-value store.\n * The context carries interface-specific data (REST, WebSocket, RPC),\n * hook execution context, and provides get/set methods for storing arbitrary values.\n *\n * Sessions are instance-scoped — each NileContext owns its own session store,\n * so multiple server instances don't share authentication state.\n *\n * @param params - Optional configuration including interface adapters and shared resources\n * @returns A fully initialized NileContext\n */\nexport function createNileContext<TDB = unknown>(\n params?: CreateNileContextParams<TDB>\n): NileContext<TDB> {\n const store = new Map<string, unknown>();\n const interfaceContext = params?.interfaceContext;\n\n /** Instance-scoped session store — not shared across server instances */\n const sessions: Sessions = {};\n\n const context: NileContext<TDB> = {\n rest: interfaceContext?.rest,\n ws: interfaceContext?.ws,\n rpc: interfaceContext?.rpc,\n resources: params?.resources,\n sessions,\n _store: store,\n\n get<T = unknown>(key: string): T | undefined {\n return store.get(key) as T | undefined;\n },\n\n set<T = unknown>(key: string, value: T): void {\n store.set(key, value);\n },\n\n getSession(name: keyof Sessions) {\n return sessions[name];\n },\n\n setSession(name: keyof Sessions, data: Record<string, unknown>) {\n sessions[name] = data;\n },\n\n hookContext: {\n actionName: \"\",\n input: null,\n state: {},\n log: { before: [], after: [] },\n },\n\n updateHookState(key: string, value: unknown) {\n context.hookContext.state[key] = value;\n },\n\n addHookLog(\n phase: \"before\" | \"after\",\n logEntry: {\n name: string;\n input: unknown;\n output: unknown;\n passed: boolean;\n }\n ) {\n context.hookContext.log[phase].push(logEntry);\n },\n\n setHookError(error: string) {\n context.hookContext.error = error;\n },\n\n setHookOutput(output: unknown) {\n context.hookContext.output = output;\n },\n\n resetHookContext(actionName: string, input: unknown) {\n context.hookContext = {\n actionName,\n input,\n state: {},\n log: { before: [], after: [] },\n };\n },\n };\n\n return context;\n}\n"],"mappings":"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","names":["pino","match","year","start","end","import_slang_ts","import_slang_ts","import_slang_ts","result","import_slang_ts","import_zod","import_slang_ts","import_zod","z","import_slang_ts","z"]}
package/dist/index.js CHANGED
@@ -1371,7 +1371,7 @@ function createNileServer(config) {
1371
1371
  });
1372
1372
  server.rest = { app, config: config.rest };
1373
1373
  const host = config.rest.host ?? "localhost";
1374
- const port = config.rest.port ?? 3e3;
1374
+ const port = config.rest.port ?? 8e3;
1375
1375
  const base = `http://${host}:${port}`;
1376
1376
  console.log(`
1377
1377
  POST ${base}${config.rest.baseUrl}/services`);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/engine/create-action.ts","../src/engine/create-service.ts","../src/logging/logger.ts","../src/logging/create-log.ts","../src/nile/server.ts","../src/engine/engine.ts","../src/utils/db/create-model.ts","../src/utils/handle-error.ts","../src/utils/db/create-transaction-variant.ts","../src/utils/db/get-zod-schema.ts","../src/utils/diagnostics-log.ts","../src/engine/pipeline.ts","../src/rest/rest.ts","../src/cors/cors.ts","../src/rest/intent-handlers.ts","../src/rest/middleware.ts","../src/nile/nile.ts"],"sourcesContent":["import type { Action } from \"./types\";\n\n/**\n * Typed identity for defining a single action with full type inference.\n * No runtime overhead — returns the config object as-is.\n */\nexport function createAction(config: Action): Action {\n return config;\n}\n\n/**\n * Typed identity for defining multiple actions with full type inference.\n * No runtime overhead — returns the config array as-is.\n */\nexport function createActions(configs: Action[]): Action[] {\n return configs;\n}\n","import type { Service } from \"./types\";\n\n/**\n * Typed identity for defining a service with full type inference.\n * No runtime overhead — returns the config object as-is.\n */\nexport function createService(config: Service): Service {\n return config;\n}\n\n/**\n * Typed identity for defining multiple services with full type inference.\n * No runtime overhead — returns the config array as-is.\n */\nexport function createServices(configs: Service[]): Service[] {\n return configs;\n}\n","import {\n appendFileSync,\n existsSync,\n mkdirSync,\n readdirSync,\n readFileSync,\n} from \"node:fs\";\nimport { join } from \"node:path\";\nimport { nanoid } from \"nanoid\";\nimport pino, { type Logger } from \"pino\";\n\nexport interface Log {\n atFunction: string;\n appName: string;\n message: string;\n data?: unknown;\n level?: \"info\" | \"warn\" | \"error\";\n log_id?: string;\n}\n\n/** Configuration for log file chunking behavior */\nexport interface LoggerConfig {\n /** Time-based chunking strategy. Default: 'none' (single file per app) */\n chunking?: \"monthly\" | \"daily\" | \"weekly\" | \"none\";\n}\n\n// Lazy evaluation of MODE - only check when logging is actually used\nconst getMode = () => {\n if (!process.env.MODE) {\n throw new Error(\"Missing MODE environment variable\");\n }\n return process.env.MODE;\n};\n\nconst logDir = join(process.cwd(), \"logs\");\n\nif (!existsSync(logDir)) {\n mkdirSync(logDir);\n}\n\n// Chunk filename patterns — hoisted for performance (used in hot path by getLogs)\nconst MONTHLY_PATTERN = /^(\\d{4})-(\\d{2})$/;\nconst DAILY_PATTERN = /^(\\d{4})-(\\d{2})-(\\d{2})$/;\nconst WEEKLY_PATTERN = /^(\\d{4})-W(\\d{2})$/;\n\n/**\n * Resolves the correct log file path based on app name and chunking config.\n * - 'none' (default): logs/{appName}.log (backwards compatible)\n * - 'monthly': logs/{appName}/YYYY-MM.log\n * - 'daily': logs/{appName}/YYYY-MM-DD.log\n * - 'weekly': logs/{appName}/YYYY-WNN.log (ISO week number)\n */\nexport function resolveLogPath(appName: string, config?: LoggerConfig): string {\n const chunking = config?.chunking ?? \"none\";\n\n if (chunking === \"none\") {\n return join(logDir, `${appName}.log`);\n }\n\n const appDir = join(logDir, appName);\n if (!existsSync(appDir)) {\n mkdirSync(appDir, { recursive: true });\n }\n\n const now = new Date();\n const chunk = formatChunkName(now, chunking);\n return join(appDir, `${chunk}.log`);\n}\n\n/**\n * Formats a date into the correct chunk filename based on chunking strategy.\n * Exported for testing and reuse by getLogs.\n */\nexport function formatChunkName(\n date: Date,\n chunking: \"monthly\" | \"daily\" | \"weekly\"\n): string {\n const year = date.getFullYear();\n const month = String(date.getMonth() + 1).padStart(2, \"0\");\n\n if (chunking === \"monthly\") {\n return `${year}-${month}`;\n }\n\n if (chunking === \"daily\") {\n const day = String(date.getDate()).padStart(2, \"0\");\n return `${year}-${month}-${day}`;\n }\n\n // Weekly: ISO week number\n const weekNum = getISOWeekNumber(date);\n return `${year}-W${String(weekNum).padStart(2, \"0\")}`;\n}\n\n/** Returns the ISO 8601 week number for a given date */\nfunction getISOWeekNumber(date: Date): number {\n const target = new Date(date.valueOf());\n // Set to nearest Thursday (current date + 4 - current day number, with Sunday as 7)\n const dayNum = target.getDay() || 7;\n target.setDate(target.getDate() + 4 - dayNum);\n const yearStart = new Date(target.getFullYear(), 0, 1);\n return Math.ceil(\n ((target.getTime() - yearStart.getTime()) / 86_400_000 + 1) / 7\n );\n}\n\n/**\n * Creates a pino logger instance that writes to the resolved log file path.\n * Each call creates a fresh pino transport — callers should cache if needed.\n */\nfunction createLoggerForApp(appName: string, config?: LoggerConfig): Logger {\n const logFile = resolveLogPath(appName, config);\n\n const transport = pino.transport({\n targets: [\n {\n level: \"info\",\n target: \"pino/file\",\n options: {\n destination: logFile,\n mkdir: true,\n },\n },\n ],\n });\n\n return pino(\n {\n base: null,\n timestamp: () => `,\"time\":\"${new Date().toISOString()}\"`,\n formatters: {\n level(label) {\n return { level: label };\n },\n },\n },\n transport\n );\n}\n\n/**\n * Creates a new log entry with the provided log information.\n * Supports optional chunking config to split logs into time-based files.\n * @param log - The log object containing the log details\n * @param config - Optional logger config for chunking behavior\n * @returns The generated log ID (or JSON string in agentic mode)\n * @throws {Error} If appName is missing in the log object\n */\nexport const createLog = (log: Log, config?: LoggerConfig) => {\n if (!log.appName) {\n throw new Error(`Missing appName in log: ${JSON.stringify(log)}`);\n }\n\n const level = log.level || \"info\";\n const log_id = log.log_id || nanoid(6);\n\n const logRecord = {\n log_id,\n appName: log.appName,\n atFunction: log.atFunction,\n message: log.message,\n data: log.data ?? null,\n level,\n time: new Date().toISOString(),\n };\n\n const mode = getMode();\n\n if (mode === \"prod\" || process.env.NODE_ENV === \"test\") {\n const logFile = resolveLogPath(log.appName, config);\n\n if (process.env.NODE_ENV === \"test\") {\n // For tests, write synchronously to ensure file exists immediately\n appendFileSync(logFile, `${JSON.stringify(logRecord)}\\n`, \"utf-8\");\n } else {\n // For production, use pino logger\n const appLogger = createLoggerForApp(log.appName, config);\n appLogger[level as \"info\" | \"warn\" | \"error\"](logRecord);\n }\n return log_id;\n }\n\n if (mode === \"agentic\") {\n return JSON.stringify(logRecord);\n }\n\n console.log({\n ...logRecord,\n data: JSON.stringify(logRecord.data, null, 2),\n });\n return \"dev-mode, see your dev console!\";\n};\n\nexport interface LogFilter {\n appName?: string;\n log_id?: string;\n level?: \"info\" | \"warn\" | \"error\";\n from?: Date;\n to?: Date;\n}\n\n/**\n * Retrieves logs based on the provided filters.\n * Supports reading from chunked files when a LoggerConfig with chunking is provided.\n * When chunking is enabled, uses from/to date filters to intelligently select\n * only the relevant chunk files instead of scanning all files.\n * @param filters - Optional filters to apply when retrieving logs\n * @param config - Optional logger config matching the chunking used when writing\n * @returns An array of log entries matching the filters\n */\nexport const getLogs = (\n filters: LogFilter = {},\n config?: LoggerConfig\n): Log[] => {\n const chunking = config?.chunking ?? \"none\";\n\n const filesToRead = resolveLogFiles(filters, chunking);\n const logs = readAndParseLogFiles(filesToRead);\n return applyLogFilters(logs, filters);\n};\n\n/**\n * Determines which log files to read based on filters and chunking strategy.\n * For 'none' chunking, returns the single flat file.\n * For time-based chunking, scans the app directory and filters by date range.\n */\nfunction resolveLogFiles(\n filters: LogFilter,\n chunking: \"monthly\" | \"daily\" | \"weekly\" | \"none\"\n): string[] {\n if (chunking === \"none\") {\n const logFile = filters.appName\n ? join(logDir, `${filters.appName}.log`)\n : join(logDir, \"app.log\");\n return existsSync(logFile) ? [logFile] : [];\n }\n\n // Chunked mode requires appName to locate the directory\n if (!filters.appName) {\n return [];\n }\n\n const appDir = join(logDir, filters.appName);\n if (!existsSync(appDir)) {\n return [];\n }\n\n const allFiles = readdirSync(appDir)\n .filter((f) => f.endsWith(\".log\"))\n .sort();\n\n // If no date filters, read all chunk files\n if (!(filters.from || filters.to)) {\n return allFiles.map((f) => join(appDir, f));\n }\n\n // Filter chunks by date relevance to avoid reading unnecessary files\n return allFiles\n .filter((filename) => isChunkRelevant(filename, chunking, filters))\n .map((f) => join(appDir, f));\n}\n\n/**\n * Checks if a chunk file is relevant to the given date range filter.\n * Compares the chunk's time range against the filter's from/to dates.\n */\nfunction isChunkRelevant(\n filename: string,\n chunking: \"monthly\" | \"daily\" | \"weekly\",\n filters: LogFilter\n): boolean {\n // Extract the chunk name (strip .log extension)\n const chunkName = filename.replace(\".log\", \"\");\n const range = getChunkDateRange(chunkName, chunking);\n\n if (!range) {\n return true; // Can't parse — include to be safe\n }\n\n const { start, end } = range;\n\n // Chunk is relevant if its range overlaps with the filter range\n if (filters.to && start > filters.to) {\n return false;\n }\n if (filters.from && end < filters.from) {\n return false;\n }\n\n return true;\n}\n\n/**\n * Returns the start and end date boundaries of a chunk based on its name and strategy.\n * This allows getLogs to skip chunks that fall outside the requested date range.\n */\nfunction getChunkDateRange(\n chunkName: string,\n chunking: \"monthly\" | \"daily\" | \"weekly\"\n): { start: Date; end: Date } | null {\n if (chunking === \"monthly\") {\n // Format: YYYY-MM\n const match = chunkName.match(MONTHLY_PATTERN);\n if (!(match?.[1] && match[2])) {\n return null;\n }\n const year = Number(match[1]);\n const month = Number(match[2]) - 1;\n const start = new Date(year, month, 1);\n const end = new Date(year, month + 1, 0, 23, 59, 59, 999);\n return { start, end };\n }\n\n if (chunking === \"daily\") {\n // Format: YYYY-MM-DD\n const match = chunkName.match(DAILY_PATTERN);\n if (!(match?.[1] && match[2] && match[3])) {\n return null;\n }\n const year = Number(match[1]);\n const month = Number(match[2]) - 1;\n const day = Number(match[3]);\n const start = new Date(year, month, day);\n const end = new Date(year, month, day, 23, 59, 59, 999);\n return { start, end };\n }\n\n // Weekly: YYYY-WNN\n const match = chunkName.match(WEEKLY_PATTERN);\n if (!(match?.[1] && match[2])) {\n return null;\n }\n const year = Number(match[1]);\n const week = Number(match[2]);\n const start = getDateFromISOWeek(year, week);\n const end = new Date(start);\n end.setDate(end.getDate() + 6);\n end.setHours(23, 59, 59, 999);\n return { start, end };\n}\n\n/** Returns the Monday date for a given ISO year and week number */\nfunction getDateFromISOWeek(year: number, week: number): Date {\n const jan4 = new Date(year, 0, 4);\n const dayOfWeek = jan4.getDay() || 7;\n // Monday of week 1\n const monday = new Date(jan4);\n monday.setDate(jan4.getDate() - dayOfWeek + 1);\n // Add (week - 1) weeks\n monday.setDate(monday.getDate() + (week - 1) * 7);\n monday.setHours(0, 0, 0, 0);\n return monday;\n}\n\n/** Reads and parses NDJSON log entries from multiple files into a single array */\nfunction readAndParseLogFiles(files: string[]): Record<string, unknown>[] {\n const logs: Record<string, unknown>[] = [];\n\n for (const file of files) {\n if (!existsSync(file)) {\n continue;\n }\n\n const content = readFileSync(file, \"utf-8\").trim();\n if (!content) {\n continue;\n }\n\n const lines = content.split(\"\\n\");\n for (const line of lines) {\n try {\n const parsed = JSON.parse(line) as Record<string, unknown>;\n logs.push(parsed);\n } catch {\n // Skip malformed lines\n }\n }\n }\n\n return logs;\n}\n\n/** Applies log_id, level, and time range filters to parsed log entries */\nfunction applyLogFilters(\n logs: Record<string, unknown>[],\n filters: LogFilter\n): Log[] {\n return logs.filter((log) => {\n if (filters.appName && log.appName !== filters.appName) {\n return false;\n }\n if (filters.log_id && log.log_id !== filters.log_id) {\n return false;\n }\n if (filters.level && log.level !== filters.level) {\n return false;\n }\n\n const time = new Date(log.time as string);\n if (filters.from && time < filters.from) {\n return false;\n }\n if (filters.to && time > filters.to) {\n return false;\n }\n\n return true;\n }) as unknown as Log[];\n}\n","import { type Log, type LoggerConfig, createLog as newLog } from \"./logger\";\n\ntype LogInput = Omit<Log, \"appName\">;\n\n/**\n * Creates a logger instance bound to a specific app name.\n * Optionally accepts a LoggerConfig for time-based file chunking.\n * @param appName - The application name (determines log file/directory)\n * @param config - Optional config for chunking (monthly, daily, weekly)\n */\nexport const createLogger = (appName: string, config?: LoggerConfig) => {\n return {\n info: (input: LogInput) =>\n newLog({ ...input, appName, level: \"info\" }, config),\n warn: (input: LogInput) =>\n newLog({ ...input, appName, level: \"warn\" }, config),\n error: (input: LogInput) =>\n newLog({ ...input, appName, level: \"error\" }, config),\n };\n};\n","import { safeTry } from \"slang-ts\";\nimport { createEngine } from \"@/engine/engine\";\nimport type { Engine } from \"@/engine/types\";\nimport { createRestApp } from \"@/rest/rest\";\nimport { createDiagnosticsLog } from \"@/utils\";\nimport { createNileContext } from \"./nile\";\nimport type { NileContext, NileServer, Resources, ServerConfig } from \"./types\";\n\nlet _nileContext: NileContext | null = null;\n\n/**\n * Retrieves the runtime NileContext.\n *\n * Use this to access shared resources (database, logger) and context storage\n * from anywhere in your application. Supports a TDB generic to provide\n * end-to-end type safety for your database instance.\n *\n * @template TDB - The type of your database instance (e.g. typeof db)\n * @returns The active NileContext<TDB>\n * @throws If called before createNileServer has initialized the global context.\n */\nexport function getContext<TDB = unknown>(): NileContext<TDB> {\n if (!_nileContext) {\n throw new Error(\n \"getContext: Server not initialized. Call createNileServer first.\"\n );\n }\n return _nileContext as NileContext<TDB>;\n}\n\n/**\n * Bootstraps a Nile server instance.\n *\n * Wires together the Action Engine, shared NileContext, and interface layers (REST).\n * This is the primary entry point for a Nile application. It handles service\n * registration, resource attachment, and server lifecycle.\n *\n * @param config - Server configuration including services, rest options, and resources\n * @returns A NileServer instance containing the engine and (optional) REST app\n */\nexport function createNileServer(config: ServerConfig): NileServer {\n if (!config.services?.length) {\n throw new Error(\n \"createNileServer requires at least one service in config.services\"\n );\n }\n\n const log = createDiagnosticsLog(\"NileServer\", {\n diagnostics: config.diagnostics,\n logger: config.resources?.logger as unknown as Parameters<\n typeof createDiagnosticsLog\n >[1][\"logger\"],\n });\n\n // Shared context -- created once with resources, passed to all layers\n const nileContext = createNileContext({\n resources: config.resources as unknown as Resources<unknown>,\n });\n\n _nileContext = nileContext as unknown as NileContext<unknown>;\n\n // Initialize the Action Engine\n const engine: Engine = createEngine({\n services: config.services,\n diagnostics: config.diagnostics,\n logger: config.resources?.logger as unknown as Parameters<\n typeof createEngine\n >[0][\"logger\"],\n onBeforeActionHandler: config.onBeforeActionHandler,\n onAfterActionHandler: config.onAfterActionHandler,\n });\n\n log(`Engine initialized with ${config.services.length} service(s)`);\n\n // Print registered services table (on by default, opt-out with logServices: false)\n if (config.logServices !== false) {\n const servicesResult = engine.getServices();\n if (servicesResult.isOk) {\n const table = servicesResult.value.map((s) => ({\n Service: s.name,\n Description: s.description,\n Actions: s.actions.length,\n }));\n console.table(table);\n }\n }\n\n // Build the server object incrementally\n const server: NileServer = {\n config,\n engine,\n context: nileContext as NileContext<unknown>,\n };\n\n // Initialize REST interface if configured\n if (config.rest) {\n const app = createRestApp({\n config: config.rest,\n engine,\n nileContext: nileContext as NileContext<unknown>,\n serverName: config.serverName,\n runtime: config.runtime ?? \"bun\",\n });\n\n server.rest = { app, config: config.rest };\n\n const host = config.rest.host ?? \"localhost\";\n const port = config.rest.port ?? 3000;\n const base = `http://${host}:${port}`;\n\n console.log(`\\n POST ${base}${config.rest.baseUrl}/services`);\n if (config.rest.enableStatus) {\n console.log(` GET ${base}/status`);\n }\n console.log(\"\");\n }\n\n // Run onBoot lifecycle hook\n if (config.onBoot) {\n const { fn } = config.onBoot;\n // Fire-and-forget with crash safety via async IIFE\n const _boot = (async () => {\n const result = await safeTry(() => fn(nileContext));\n if (result.isErr) {\n console.error(\"[NileServer] onBoot failed:\", result.error);\n }\n })();\n // Intentionally not awaited — boot runs in background\n _boot;\n }\n\n log(`${config.serverName} server ready`);\n\n return server;\n}\n","import { Err, Ok, type Result } from \"slang-ts\";\nimport type { NileContext } from \"@/nile/types\";\nimport { createDiagnosticsLog } from \"@/utils\";\nimport {\n processHooks,\n runGlobalAfterHook,\n runGlobalBeforeHook,\n runHandler,\n validatePayload,\n} from \"./pipeline\";\nimport type {\n Action,\n ActionSummary,\n EngineOptions,\n ServiceSummary,\n} from \"./types\";\n\nexport function createEngine(options: EngineOptions) {\n const { diagnostics, services, logger } = options;\n\n const log = createDiagnosticsLog(\"Engine\", {\n diagnostics,\n logger: logger as unknown as Parameters<\n typeof createDiagnosticsLog\n >[1][\"logger\"],\n });\n\n // O(1) Pre-computed Lookups\n const serviceSummaries: ServiceSummary[] = [];\n const serviceActionsStore: Record<string, ActionSummary[]> = {};\n const actionStore: Record<string, Record<string, Action>> = {};\n\n // Build stores once on init\n const initStartTime = performance.now();\n\n for (const service of services) {\n const actionNames: string[] = [];\n serviceActionsStore[service.name] = [];\n actionStore[service.name] = {};\n\n for (const action of service.actions) {\n actionNames.push(action.name);\n\n serviceActionsStore[service.name]?.push({\n name: action.name,\n description: action.description,\n isProtected: !!action.isProtected,\n validation: !!action.validation,\n accessControl: action.accessControl || [],\n });\n\n const serviceActions = actionStore[service.name];\n if (serviceActions) {\n serviceActions[action.name] = action;\n }\n }\n\n serviceSummaries.push({\n name: service.name,\n description: service.description,\n meta: service.meta,\n actions: actionNames,\n });\n }\n\n log(\n `Initialized in ${performance.now() - initStartTime}ms. Loaded ${services.length} services.`\n );\n\n // --- Discovery API ---\n\n const getServices = (): Result<ServiceSummary[], string> =>\n Ok(serviceSummaries);\n\n const getServiceActions = (\n serviceName: string\n ): Result<ActionSummary[], string> => {\n const actions = serviceActionsStore[serviceName];\n return actions ? Ok(actions) : Err(`Service '${serviceName}' not found`);\n };\n\n const getAction = (\n serviceName: string,\n actionName: string\n ): Result<Action, string> => {\n const serviceMap = actionStore[serviceName];\n if (!serviceMap) {\n return Err(`Service '${serviceName}' not found`);\n }\n\n const action = serviceMap[actionName];\n return action\n ? Ok(action)\n : Err(`Action '${actionName}' not found in service '${serviceName}'`);\n };\n\n const executeAction = async (\n serviceName: string,\n actionName: string,\n payload: unknown,\n nileContext: NileContext<unknown>\n ): Promise<Result<unknown, string>> => {\n const { onBeforeActionHandler, onAfterActionHandler } = options;\n\n // Resolve action\n const actionResult = getAction(serviceName, actionName);\n if (actionResult.isErr) {\n return Err(actionResult.error);\n }\n const action = actionResult.value;\n\n // Reset hook context for this execution\n nileContext.resetHookContext(`${serviceName}.${actionName}`, payload);\n\n // Step 1: Global Before Hook\n const globalBeforeResult = await runGlobalBeforeHook(\n onBeforeActionHandler,\n nileContext,\n action,\n payload,\n log\n );\n if (globalBeforeResult.isErr) {\n return Err(globalBeforeResult.error);\n }\n\n // Step 2: Action Before Hooks\n const beforeHooksResult = await processHooks(\n action.hooks?.before ?? [],\n payload,\n getAction,\n nileContext,\n \"before\",\n log\n );\n if (beforeHooksResult.isErr) {\n return Err(beforeHooksResult.error);\n }\n\n // Step 3: Validation\n const validationResult = validatePayload(\n action,\n beforeHooksResult.value,\n nileContext,\n log\n );\n if (validationResult.isErr) {\n return Err(validationResult.error);\n }\n\n // Step 4: Handler\n const handlerResult = await runHandler(\n action,\n validationResult.value,\n nileContext,\n log\n );\n if (handlerResult.isErr) {\n return Err(handlerResult.error);\n }\n\n // Step 5: Action After Hooks\n const afterHooksResult = await processHooks(\n action.hooks?.after ?? [],\n handlerResult.value,\n getAction,\n nileContext,\n \"after\",\n log\n );\n if (afterHooksResult.isErr) {\n return Err(afterHooksResult.error);\n }\n\n // Step 6: Global After Hook\n const globalAfterResult = await runGlobalAfterHook(\n onAfterActionHandler,\n nileContext,\n action,\n validationResult.value,\n afterHooksResult.value,\n log\n );\n if (globalAfterResult.isErr) {\n return Err(globalAfterResult.error);\n }\n\n // Final response\n return action.result?.pipeline\n ? Ok({\n data: globalAfterResult.value,\n pipeline: nileContext.hookContext.log,\n })\n : Ok(globalAfterResult.value);\n };\n\n return {\n getServices,\n getServiceActions,\n getAction,\n executeAction,\n };\n}\n","import { count, desc, eq, lt, type SQL } from \"drizzle-orm\";\nimport { Ok, safeTry } from \"slang-ts\";\nimport { getContext } from \"@/nile/server\";\nimport { handleError } from \"../handle-error\";\nimport { createTransactionVariant } from \"./create-transaction-variant\";\nimport { getZodSchema } from \"./get-zod-schema\";\nimport type {\n CursorPage,\n ModelOperations,\n ModelOptions,\n ModelUpdateParams,\n ModelWriteParams,\n OffsetPage,\n OffsetPaginationOptions,\n PaginationOptions,\n TableSchemas,\n} from \"./types\";\n\n/**\n * Minimal shape of a Drizzle database instance for dynamic query building.\n * Covers the select/insert/update/delete chains used by createModel internals.\n * Avoids using the `Function` type while remaining compatible with both\n * Neon and PGLite Drizzle drivers.\n */\ninterface DrizzleDbLike {\n select(fields?: Record<string, unknown>): {\n from(table: unknown): DrizzleSelectQuery;\n };\n insert(table: unknown): {\n values(data: unknown): {\n returning(): Promise<unknown[]>;\n };\n };\n update(table: unknown): {\n set(data: unknown): {\n where(condition: SQL): {\n returning(): Promise<unknown[]>;\n };\n };\n };\n delete(table: unknown): {\n where(condition: SQL): {\n returning(): Promise<unknown[]>;\n };\n };\n}\n\n/** Chainable select query shape — supports where/orderBy/limit/offset in any valid order */\ninterface DrizzleSelectQuery extends Promise<unknown[]> {\n where(condition: SQL): DrizzleSelectQuery;\n orderBy(...cols: SQL[]): DrizzleSelectQuery;\n limit(n: number): DrizzleSelectQuery;\n offset(n: number): DrizzleSelectQuery;\n}\n\n/** Cast db to our minimal interface — safe because Drizzle drivers all expose these methods */\nfunction asDb(db: unknown): DrizzleDbLike {\n return db as DrizzleDbLike;\n}\n\n/**\n * Resolves a database instance from the explicit option or the Nile request context.\n * Throws immediately if neither is available — this is a developer configuration error.\n */\nfunction resolveDb<TDB>(explicitDb: TDB | undefined): TDB {\n if (explicitDb) {\n return explicitDb;\n }\n\n try {\n const ctx = getContext();\n if (ctx.resources?.database) {\n return ctx.resources.database as TDB;\n }\n } catch (_) {\n // context not available — fall through to throw\n }\n throw new Error(\n \"createModel: No database available. Pass db in ModelOptions or set resources.database on server config.\"\n );\n}\n\n/**\n * Detects the timestamp column used for default ordering.\n * Checks for both snake_case (created_at) and camelCase (createdAt) conventions.\n */\nfunction findTimestampColumn(table: Record<string, unknown>): string | null {\n if (\"created_at\" in table) {\n return \"created_at\";\n }\n if (\"createdAt\" in table) {\n return \"createdAt\";\n }\n return null;\n}\n\n/**\n * Creates a CRUD model for a Drizzle table, eliminating repetitive boilerplate.\n *\n * All methods return `Result<T, string>` — `Ok(data)` on success, `Err(message)` on failure.\n * Validation, error handling, and transaction variants are built in.\n *\n * For anything beyond basic CRUD, use the exposed `table` and `schemas` properties\n * to compose custom queries with Drizzle directly.\n *\n * @param table - Drizzle table definition (from pgTable, sqliteTable, etc.)\n * @param options - Configuration: entity name, optional db instance, cursor column\n * @returns Object with CRUD operations, plus escape hatches (table, schemas)\n *\n * @example\n * ```typescript\n * import { createModel } from \"@nilejs/nile\";\n * import { tasks } from \"./schema\";\n * import { db } from \"./client\";\n *\n * // Explicit db\n * export const taskModel = createModel(tasks, { db, name: \"task\" });\n *\n * // Context-resolved db (resolved at call time)\n * export const taskModel = createModel(tasks, { name: \"task\" });\n *\n * // Usage\n * const result = await taskModel.create({ data: { title: \"Ship it\" } });\n * const task = await taskModel.findById(\"uuid-123\");\n * const page = await taskModel.findPaginated({ limit: 20, offset: 0 });\n * ```\n */\nexport function createModel<\n TTable extends { $inferSelect: unknown; $inferInsert: unknown },\n TDB = unknown,\n>(\n table: TTable,\n options: ModelOptions<TDB>\n): ModelOperations<TTable[\"$inferSelect\"], TTable[\"$inferInsert\"], TDB> {\n type TSelect = TTable[\"$inferSelect\"];\n type TInsert = TTable[\"$inferInsert\"];\n\n const { name, cursorColumn = \"id\" } = options;\n const entityName = name.charAt(0).toUpperCase() + name.slice(1);\n const schemas = getZodSchema(table) as TableSchemas<TTable>;\n const tableRef = table as Record<string, unknown>;\n\n /** Resolve and cast db for the current call */\n const getDb = () => asDb(resolveDb<TDB>(options.db));\n\n // -- Core CRUD --\n\n const create = async ({ data, dbx }: ModelWriteParams<TInsert, TDB>) => {\n const parsed = schemas.insert.safeParse(data);\n if (!parsed.success) {\n return handleError({\n message: `Invalid ${name} data`,\n data: { errors: parsed.error },\n atFunction: `${name}.create`,\n });\n }\n\n const db = dbx ? asDb(dbx) : getDb();\n const result = await safeTry(() =>\n db.insert(table).values(data).returning()\n );\n if (result.isErr) {\n return handleError({\n message: `Error creating ${name}`,\n data: { error: result.error },\n atFunction: `${name}.create`,\n });\n }\n\n const row = (result.value as TSelect[])?.[0] ?? null;\n if (!row) {\n return handleError({\n message: `${entityName} creation returned no data`,\n atFunction: `${name}.create`,\n });\n }\n return Ok(row);\n };\n\n const update = async ({ id, data, dbx }: ModelUpdateParams<TSelect, TDB>) => {\n const parsed = schemas.update.safeParse(data);\n if (!parsed.success) {\n return handleError({\n message: `Invalid ${name} data`,\n data: { errors: parsed.error },\n atFunction: `${name}.update`,\n });\n }\n\n const db = dbx ? asDb(dbx) : getDb();\n const idCol = tableRef.id as Parameters<typeof eq>[0];\n const result = await safeTry(() =>\n db.update(table).set(data).where(eq(idCol, id)).returning()\n );\n if (result.isErr) {\n return handleError({\n message: `Error updating ${name}`,\n data: { id, error: result.error },\n atFunction: `${name}.update`,\n });\n }\n\n const row = (result.value as TSelect[])?.[0] ?? null;\n if (!row) {\n return handleError({\n message: `${entityName} not found`,\n data: { id },\n atFunction: `${name}.update`,\n });\n }\n return Ok(row);\n };\n\n // Transaction variants via existing utility\n const createTx = createTransactionVariant(\n create as Parameters<typeof createTransactionVariant>[0]\n );\n const updateTx = createTransactionVariant(\n update as Parameters<typeof createTransactionVariant>[0]\n );\n\n const findById = async (id: string) => {\n const db = getDb();\n const idCol = tableRef.id as Parameters<typeof eq>[0];\n const result = await safeTry(() =>\n db.select().from(table).where(eq(idCol, id))\n );\n if (result.isErr) {\n return handleError({\n message: `Error getting ${name}`,\n data: { id, error: result.error },\n atFunction: `${name}.findById`,\n });\n }\n\n const row = (result.value as TSelect[])?.[0] ?? null;\n if (!row) {\n return handleError({\n message: `${entityName} not found`,\n data: { id },\n atFunction: `${name}.findById`,\n });\n }\n return Ok(row);\n };\n\n const deleteFn = async (id: string) => {\n const db = getDb();\n const idCol = tableRef.id as Parameters<typeof eq>[0];\n const result = await safeTry(() =>\n db.delete(table).where(eq(idCol, id)).returning()\n );\n if (result.isErr) {\n return handleError({\n message: `Error deleting ${name}`,\n data: { id, error: result.error },\n atFunction: `${name}.delete`,\n });\n }\n\n const row = (result.value as TSelect[])?.[0] ?? null;\n if (!row) {\n return handleError({\n message: `${entityName} not found`,\n data: { id },\n atFunction: `${name}.delete`,\n });\n }\n return Ok(row);\n };\n\n const findAll = async () => {\n const db = getDb();\n const tsCol = findTimestampColumn(tableRef);\n\n const result = await safeTry(() => {\n const query = db.select().from(table);\n if (!tsCol) {\n return query;\n }\n return query.orderBy(desc(tableRef[tsCol] as Parameters<typeof desc>[0]));\n });\n if (result.isErr) {\n return handleError({\n message: `Error getting all ${name}s`,\n data: { error: result.error },\n atFunction: `${name}.findAll`,\n });\n }\n\n return Ok((result.value ?? []) as TSelect[]);\n };\n\n /** Offset-based pagination — returns items, total count, and hasMore flag */\n const findOffsetPage = async (limit: number, offset: number) => {\n const db = getDb();\n const tsCol = findTimestampColumn(tableRef);\n\n const itemsResult = await safeTry(() => {\n const query = db.select().from(table);\n const ordered = tsCol\n ? query.orderBy(desc(tableRef[tsCol] as Parameters<typeof desc>[0]))\n : query;\n return ordered.limit(limit).offset(offset);\n });\n if (itemsResult.isErr) {\n return handleError({\n message: `Error getting paginated ${name}s`,\n data: { limit, offset, error: itemsResult.error },\n atFunction: `${name}.findPaginated`,\n });\n }\n\n const countResult = await safeTry(() =>\n db.select({ total: count() }).from(table)\n );\n if (countResult.isErr) {\n return handleError({\n message: `Error getting ${name} count`,\n data: { error: countResult.error },\n atFunction: `${name}.findPaginated`,\n });\n }\n\n const items = (itemsResult.value ?? []) as TSelect[];\n const total = (countResult.value as { total: number }[])?.[0]?.total ?? 0;\n\n return Ok({\n items,\n total,\n hasMore: offset + items.length < total,\n } satisfies OffsetPage<TSelect>);\n };\n\n /** Cursor-based pagination — uses lt() on the cursor column with desc ordering */\n const findCursorPage = async (\n limit: number,\n cursor: string,\n colName: string\n ) => {\n const db = getDb();\n const column = tableRef[colName];\n\n if (!column) {\n return handleError({\n message: `Cursor column '${colName}' does not exist on ${name} table`,\n atFunction: `${name}.findPaginated`,\n });\n }\n\n const typedColumn = column as Parameters<typeof lt>[0];\n\n // Fetch one extra row to determine hasMore without a separate count query\n const result = await safeTry(() =>\n db\n .select()\n .from(table)\n .where(lt(typedColumn, cursor))\n .orderBy(desc(typedColumn))\n .limit(limit + 1)\n );\n if (result.isErr) {\n return handleError({\n message: `Error getting paginated ${name}s`,\n data: { cursor, cursorColumn: colName, error: result.error },\n atFunction: `${name}.findPaginated`,\n });\n }\n\n const rows = (result.value ?? []) as TSelect[];\n const hasMore = rows.length > limit;\n const items = hasMore ? rows.slice(0, limit) : rows;\n const lastItem = items.at(-1) as Record<string, unknown> | undefined;\n const nextCursor = lastItem\n ? String(lastItem[colName] ?? \"\") || null\n : null;\n\n return Ok({\n items,\n nextCursor,\n hasMore,\n } satisfies CursorPage<TSelect>);\n };\n\n const findPaginated = (opts: PaginationOptions = {}) => {\n const limit = opts.limit ?? 50;\n\n // Cursor mode when cursor is provided\n if (\"cursor\" in opts && opts.cursor) {\n const colName = opts.cursorColumn ?? cursorColumn;\n return findCursorPage(limit, opts.cursor, colName);\n }\n\n // Default: offset mode\n const offset = (opts as OffsetPaginationOptions).offset ?? 0;\n return findOffsetPage(limit, offset);\n };\n\n return {\n create,\n createTx,\n findById,\n update,\n updateTx,\n delete: deleteFn,\n findAll,\n findPaginated,\n table,\n schemas,\n } as ModelOperations<TSelect, TInsert, TDB>;\n}\n","import { Err, type ErrType, type ResultMethods } from \"slang-ts\";\nimport { getContext } from \"@/nile/server\";\nimport type { NileLogger } from \"@/nile/types\";\n\n/**\n * Parameters for the handleError utility.\n *\n * @property message - Human-readable error description, included in the returned Result error string\n * @property data - Optional structured data logged alongside the error for debugging\n * @property logger - Explicit logger instance; when omitted, resolves from the current Nile request context\n * @property atFunction - Name of the calling function for log attribution; auto-inferred from stack trace when omitted\n */\nexport interface HandleErrorParams {\n message: string;\n data?: unknown;\n logger?: NileLogger;\n atFunction?: string;\n}\n\nconst CALLER_LINE_REGEX = /at\\s+(\\S+)\\s+/;\n\nfunction inferCallerName(): string {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const _err = new Error(\"capture stack trace\");\n const stack = _err.stack;\n const callerLine = stack?.split(\"\\n\")[3] ?? \"\";\n const match = callerLine.match(CALLER_LINE_REGEX);\n return match?.[1] ?? \"unknown\";\n}\n\nfunction resolveLogger(explicit?: NileLogger): NileLogger {\n if (explicit) {\n return explicit;\n }\n try {\n const ctx = getContext();\n if (ctx.resources?.logger) {\n return ctx.resources.logger;\n }\n } catch (_) {\n // Fall through to throw\n }\n throw new Error(\n \"handleError: No logger available. Provide a logger param or set resources.logger on server config.\"\n );\n}\n\n/**\n * Logs an error via the resolved logger and returns a typed Err result.\n * Resolves the logger from the current Nile request context when not provided explicitly.\n * The returned error string includes the log ID for traceability: `[logId] message`.\n *\n * @param params - Error details including message, optional data, logger, and caller function name\n * @returns Always an Err variant — `ErrType<string> & ResultMethods<never>`, compatible with any `Result<T, E>` union\n *\n * @example\n * ```typescript\n * if (!user) {\n * return handleError({\n * message: \"User not found\",\n * data: { userId },\n * atFunction: \"getUserById\",\n * });\n * }\n * ```\n */\nexport function handleError(\n params: HandleErrorParams\n): ErrType<string> & ResultMethods<never> {\n const atFunction = params.atFunction ?? inferCallerName();\n const logger = resolveLogger(params.logger);\n const logId = logger.error({\n atFunction,\n message: params.message,\n data: params.data,\n });\n return Err(`[${logId}] ${params.message}`);\n}\n","import type { Result } from \"slang-ts\";\nimport type { DBParams } from \"./types\";\n\n/**\n * Creates a transaction-aware variant of a database function.\n * Expects the wrapped function to accept a single object parameter with optional dbx field.\n *\n * When dbx is root db (has .transaction method):\n * - Creates new transaction and executes function inside it\n * - On Result.isError, throws Error to trigger automatic rollback\n * - Returns successful result or throws\n *\n * When dbx is tx pointer (no .transaction method):\n * - Executes function directly within existing transaction scope\n * - On Result.isError, throws Error to trigger parent transaction rollback\n * - Returns successful result or throws\n *\n * Both cases ensure database rollback on any error by throwing.\n *\n * @example\n * ```typescript\n * const createCompanyTx = createTransactionVariant(createCompany);\n * // Type-safe: requires all params from createCompany\n * const result = await createCompanyTx({ company: {...}, dbx: tx });\n * ```\n */\nexport function createTransactionVariant<\n TParams extends DBParams<TDB>,\n TData,\n TDB = unknown,\n>(\n fn: (params: TParams) => Promise<Result<TData, unknown>>\n): (params: TParams) => Promise<Result<TData, unknown>> {\n return async (params: TParams): Promise<Result<TData, unknown>> => {\n const { dbx, ...rest } = params;\n\n if (!dbx) {\n const result = await fn(params as TParams);\n if (result.isErr) {\n throw new Error(String(result.error));\n }\n return result;\n }\n\n const hasTransaction =\n typeof (dbx as Record<string, unknown>)?.transaction === \"function\";\n\n if (hasTransaction) {\n return await (\n dbx as unknown as {\n transaction: (\n fn: (tx: unknown) => Promise<Result<TData, unknown>>\n ) => Promise<Result<TData, unknown>>;\n }\n ).transaction(async (tx: unknown) => {\n const result = await fn({ ...rest, dbx: tx } as TParams);\n if (result.isErr) {\n throw new Error(String(result.error));\n }\n return result;\n });\n }\n\n const result = await fn({ ...rest, dbx } as TParams);\n if (result.isErr) {\n throw new Error(String(result.error));\n }\n return result;\n };\n}\n","import {\n createInsertSchema,\n createSelectSchema,\n createUpdateSchema,\n} from \"drizzle-zod\";\nimport type { TableSchemas } from \"./types\";\n\n/**\n * Generates Zod schemas (insert, update, select) from a Drizzle table.\n *\n * @param table - The Drizzle table definition\n * @returns Object containing insert, update, and select Zod schemas\n *\n * @example\n * ```typescript\n * import { getZodSchema } from '@nilejs/nile';\n * import { companies } from './schema';\n *\n * const schemas = getZodSchema(companies);\n * const insert = schemas.insert.parse(data);\n * const update = schemas.update.partial().parse(data);\n * ```\n */\nexport function getZodSchema<TTable extends object>(\n table: TTable\n): TableSchemas<TTable> {\n const isRelation =\n Object.hasOwn(table as object, \"config\") &&\n Object.hasOwn(table as object, \"table\");\n\n if (isRelation) {\n throw new Error(\n `${String(table)} is a relation schema, not a table schema`\n );\n }\n\n const insertSchema = createInsertSchema(\n table as unknown as Parameters<typeof createInsertSchema>[0]\n );\n const updateSchema = createUpdateSchema(\n table as unknown as Parameters<typeof createUpdateSchema>[0]\n );\n const selectSchema = createSelectSchema(\n table as unknown as Parameters<typeof createSelectSchema>[0]\n );\n\n return {\n insert: insertSchema,\n update: updateSchema,\n select: selectSchema,\n } as TableSchemas<TTable>;\n}\n","import type { NileLogger } from \"@/nile/types\";\n\ntype AnyLogger = NileLogger | { info: (msg: string, data?: unknown) => void };\n\nfunction isNileLogger(logger: AnyLogger): logger is NileLogger {\n return \"warn\" in logger && \"error\" in logger;\n}\n\ninterface CreateDiagnosticsLogParams {\n diagnostics?: boolean;\n logger?: AnyLogger;\n}\n\n/**\n * Creates a centralized diagnostics log function for nile internals.\n * Checks resources.logger first, falls back to console.log, respects diagnostics flag.\n * Returns a bound function with the prefix already applied for clean call sites.\n *\n * @param prefix - Component identifier e.g. \"NileServer\", \"REST\", \"Engine\"\n * @param params - Diagnostics flag and optional structured logger from resources\n * @returns A log function: (message, data?) => void\n */\nexport function createDiagnosticsLog(\n prefix: string,\n params: CreateDiagnosticsLogParams\n): (message: string, data?: unknown) => void {\n if (!params.diagnostics) {\n // biome-ignore lint/suspicious/noEmptyBlockStatements: intentional no-op when diagnostics disabled\n return () => {};\n }\n\n const { logger } = params;\n\n return (message: string, data?: unknown) => {\n if (!logger) {\n console.log(`[${prefix}] ${message}`, data ?? \"\");\n return;\n }\n\n if (isNileLogger(logger)) {\n logger.info({\n atFunction: prefix,\n message: `[${prefix}] ${message}`,\n data,\n });\n } else {\n logger.info(`[${prefix}] ${message}`, data);\n }\n };\n}\n","import { Err, Ok, type Result, safeTry } from \"slang-ts\";\nimport { prettifyError } from \"zod\";\nimport type {\n AfterActionHandler,\n BeforeActionHandler,\n NileContext,\n} from \"@/nile/types\";\nimport type { Action, HookDefinition, HookLogEntry } from \"./types\";\n\n/**\n * Executes a single hook and logs the result\n */\nasync function runHook(\n hookDef: HookDefinition,\n hookAction: Action,\n input: unknown,\n nileContext: NileContext\n): Promise<{ result: Result<unknown, string>; logEntry: HookLogEntry }> {\n const result = await safeTry(() =>\n hookAction.handler(input as Record<string, unknown>, nileContext)\n );\n return {\n result,\n logEntry: {\n name: `${hookDef.service}.${hookDef.action}`,\n input,\n output: result.isOk ? result.value : result.error,\n passed: result.isOk,\n },\n };\n}\n\n/**\n * Process hooks sequentially, each hook output becomes the next input\n */\nexport async function processHooks(\n hooks: HookDefinition[],\n initialValue: unknown,\n getAction: (service: string, action: string) => Result<Action, string>,\n nileContext: NileContext,\n logTarget: \"before\" | \"after\",\n log: (msg: string, data?: unknown) => void\n): Promise<Result<unknown, string>> {\n let currentValue = initialValue;\n\n for (const hookDef of hooks) {\n const hookActionResult = getAction(hookDef.service, hookDef.action);\n\n if (hookActionResult.isErr) {\n const errorMsg = `${logTarget} hook '${hookDef.service}.${hookDef.action}' not found`;\n log(errorMsg);\n if (hookDef.isCritical) {\n nileContext.setHookError(errorMsg);\n return Err(errorMsg);\n }\n continue;\n }\n\n const { result, logEntry } = await runHook(\n hookDef,\n hookActionResult.value,\n currentValue,\n nileContext\n );\n nileContext.addHookLog(logTarget, logEntry);\n\n if (result.isErr) {\n const errorMsg = String(result.error);\n log(\n `${logTarget} hook '${hookDef.service}.${hookDef.action}' failed`,\n result.error\n );\n if (hookDef.isCritical) {\n nileContext.setHookError(errorMsg);\n return Err(errorMsg);\n }\n continue;\n }\n\n currentValue = result.value;\n }\n\n return Ok(currentValue);\n}\n\n/**\n * Run global before hook if configured, wrapped in safeTry for crash safety\n */\nexport async function runGlobalBeforeHook(\n handler: BeforeActionHandler<unknown, unknown> | undefined,\n nileContext: NileContext,\n action: Action,\n payload: unknown,\n log: (msg: string) => void\n): Promise<Result<true, string>> {\n if (!handler) {\n return Ok(true);\n }\n\n const result = await safeTry(() => handler({ nileContext, action, payload }));\n if (result.isErr) {\n log(`Global before hook failed for ${action.name}`);\n nileContext.setHookError(result.error);\n return Err(result.error);\n }\n\n return Ok(true);\n}\n\n/**\n * Run global after hook if configured, wrapped in safeTry for crash safety\n */\nexport async function runGlobalAfterHook(\n handler: AfterActionHandler<unknown, unknown> | undefined,\n nileContext: NileContext,\n action: Action,\n payload: unknown,\n currentResult: unknown,\n log: (msg: string) => void\n): Promise<Result<unknown, string>> {\n if (!handler) {\n return Ok(currentResult);\n }\n\n const result = await safeTry(() =>\n handler({\n nileContext,\n action,\n payload,\n result: Ok(currentResult),\n })\n );\n if (result.isErr) {\n log(`Global after hook failed for ${action.name}`);\n nileContext.setHookError(result.error);\n return Err(result.error);\n }\n\n return Ok(result.value);\n}\n\n/**\n * Validate payload against action's Zod schema\n */\nexport function validatePayload(\n action: Action,\n payload: unknown,\n nileContext: NileContext,\n log: (msg: string, data?: unknown) => void\n): Result<unknown, string> {\n if (!action.validation) {\n return Ok(payload);\n }\n\n const parseResult = action.validation.safeParse(payload);\n if (!parseResult.success) {\n const validationError = prettifyError(parseResult.error);\n log(`Validation failed for ${action.name}`, validationError);\n nileContext.setHookError(validationError);\n return Err(`Validation failed: ${validationError}`);\n }\n\n return Ok(parseResult.data);\n}\n\n/**\n * Execute the main action handler, wrapped in safeTry for crash safety\n */\nexport async function runHandler(\n action: Action,\n payload: unknown,\n nileContext: NileContext,\n log: (msg: string, data?: unknown) => void\n): Promise<Result<unknown, string>> {\n const result = await safeTry(() =>\n action.handler(payload as Record<string, unknown>, nileContext)\n );\n\n if (result.isErr) {\n log(`Handler failed for ${action.name}`, result.error);\n nileContext.setHookError(result.error);\n return Err(result.error);\n }\n\n nileContext.setHookOutput(result.value);\n return Ok(result.value);\n}\n","import { Hono } from \"hono\";\nimport z from \"zod\";\nimport { applyCorsConfig } from \"@/cors/cors\";\nimport type { Engine } from \"@/engine/types\";\nimport type {\n ExternalRequest,\n ExternalResponse,\n NileContext,\n ServerRuntime,\n} from \"@/nile/types\";\nimport { createDiagnosticsLog } from \"@/utils\";\nimport { intentHandlers } from \"./intent-handlers\";\nimport { applyRateLimiting, applyStaticServing } from \"./middleware\";\nimport type { RestConfig } from \"./types\";\n\n// --- Zod schema for incoming requests ---\n\nconst externalRequestSchema = z.object({\n intent: z.enum([\"explore\", \"execute\", \"schema\"]),\n service: z.string().min(1),\n action: z.string().min(1),\n payload: z.record(z.string(), z.unknown()),\n});\n\n// --- Factory ---\n\ninterface CreateRestAppParams {\n config: RestConfig;\n engine: Engine;\n nileContext: NileContext<unknown>;\n serverName: string;\n runtime: ServerRuntime;\n}\n\n/**\n * Creates the Hono REST app with a single POST endpoint for all service interactions\n * and an optional GET /status health check.\n *\n * All service communication flows through POST {baseUrl}/services using\n * the intent field to discriminate between explore, execute, and schema operations.\n */\nexport function createRestApp(params: CreateRestAppParams): Hono {\n const { config, engine, nileContext, serverName, runtime } = params;\n const app = new Hono();\n\n const log = createDiagnosticsLog(\"REST\", {\n diagnostics: config.diagnostics,\n logger: nileContext.resources?.logger as\n | { info: (msg: string, data?: unknown) => void }\n | undefined,\n });\n\n // Apply CORS\n applyCorsConfig(app, config);\n\n // Apply rate limiting when a limiting header is configured\n applyRateLimiting(app, config, log);\n\n // Apply static file serving based on runtime\n applyStaticServing(app, config, runtime, log);\n\n // Single POST endpoint for all service interactions\n const servicesPath = `${config.baseUrl}/services`;\n\n app.post(servicesPath, async (c) => {\n const body = await c.req.json().catch(() => null);\n\n if (!body) {\n return c.json(\n {\n status: false,\n message: \"Invalid or missing JSON body\",\n data: {},\n } satisfies ExternalResponse,\n 400\n );\n }\n\n const parsed = externalRequestSchema.safeParse(body);\n if (!parsed.success) {\n return c.json(\n {\n status: false,\n message: \"Invalid request format\",\n data: { errors: parsed.error.issues },\n } satisfies ExternalResponse,\n 400\n );\n }\n\n const request = parsed.data as ExternalRequest;\n\n log(`${request.intent} -> ${request.service}.${request.action}`);\n\n const handler = intentHandlers[request.intent];\n // biome-ignore lint/suspicious/noExplicitAny: internal dispatch\n const response = await (handler as any)(engine, request, nileContext);\n\n const statusCode = response.status ? 200 : 400;\n return c.json(response, statusCode);\n });\n\n // Health check endpoint\n if (config.enableStatus) {\n app.get(\"/status\", (c) => {\n return c.json({\n status: true,\n message: `${serverName} is running`,\n data: {},\n } satisfies ExternalResponse);\n });\n }\n\n // 404 handler\n app.notFound((c) => {\n return c.json(\n {\n status: false,\n message: `Route not found. Use POST ${servicesPath} for all operations.`,\n data: {},\n } satisfies ExternalResponse,\n 404\n );\n });\n\n log(`REST interface ready at ${servicesPath}`);\n\n return app;\n}\n","import type { Context, Hono } from \"hono\";\nimport { cors } from \"hono/cors\";\nimport type { RestConfig } from \"@/rest/types\";\nimport type { CorsConfig, CorsOptions } from \"./types\";\n\n/**\n * Build default CORS options from REST config\n */\nexport const buildDefaultCorsOptions = (config: RestConfig): CorsOptions => {\n const getDefaultOrigin = (reqOrigin: string) => {\n if (config.allowedOrigins.length > 0) {\n return config.allowedOrigins.includes(reqOrigin ?? \"\") ? reqOrigin : \"\";\n }\n return \"*\";\n };\n\n return {\n origin: config.cors?.defaults?.origin ?? getDefaultOrigin,\n credentials: config.cors?.defaults?.credentials ?? true,\n allowHeaders: config.cors?.defaults?.allowHeaders ?? [\n \"Content-Type\",\n \"Authorization\",\n ],\n allowMethods: config.cors?.defaults?.allowMethods ?? [\n \"POST\",\n \"GET\",\n \"OPTIONS\",\n ],\n exposeHeaders: config.cors?.defaults?.exposeHeaders ?? [\"Content-Length\"],\n maxAge: config.cors?.defaults?.maxAge ?? 600,\n };\n};\n\n/**\n * Apply CORS configuration to a Hono app based on RestConfig\n */\nexport const applyCorsConfig = (app: Hono, config: RestConfig): void => {\n const corsEnabled = config.cors?.enabled ?? \"default\";\n\n if (corsEnabled === false) {\n return;\n }\n\n const defaultCorsOpts = buildDefaultCorsOptions(config);\n\n // Apply route-specific CORS rules FIRST (before global catch-all)\n const corsRules = config.cors?.addCors ?? [];\n for (const rule of corsRules) {\n applyRouteCorsRule(app, rule, defaultCorsOpts);\n }\n\n // Apply global CORS as fallback\n app.use(\"*\", cors(defaultCorsOpts as Parameters<typeof cors>[0]));\n};\n\n/**\n * Apply a single route-specific CORS rule\n */\nconst applyRouteCorsRule = (\n app: Hono,\n rule: NonNullable<CorsConfig[\"addCors\"]>[number],\n defaultOpts: CorsOptions\n): void => {\n if (rule.resolver) {\n applyResolverBasedCors(app, rule.path, rule.resolver, defaultOpts);\n } else if (rule.options) {\n applyStaticCors(app, rule.path, rule.options, defaultOpts);\n }\n};\n\n/**\n * Apply resolver-based CORS for a specific path\n */\nconst applyResolverBasedCors = (\n app: Hono,\n path: string,\n resolver: NonNullable<CorsConfig[\"addCors\"]>[number][\"resolver\"],\n defaultOpts: CorsOptions\n): void => {\n if (!resolver) {\n return;\n }\n\n app.use(path, (c, next) => {\n const reqOrigin = c.req.header(\"origin\") ?? \"\";\n const corsOpts = evaluateResolver(resolver, reqOrigin, c, defaultOpts);\n return cors(corsOpts as Parameters<typeof cors>[0])(c, next);\n });\n};\n\n/**\n * Apply static CORS options for a specific path\n */\nconst applyStaticCors = (\n app: Hono,\n path: string,\n options: CorsOptions,\n defaultOpts: CorsOptions\n): void => {\n app.use(\n path,\n cors({ ...defaultOpts, ...options } as Parameters<typeof cors>[0])\n );\n};\n\n/**\n * Evaluate CORS resolver and return appropriate options\n */\nconst evaluateResolver = (\n resolver: NonNullable<CorsConfig[\"addCors\"]>[number][\"resolver\"],\n origin: string,\n c: Context,\n defaultOpts: CorsOptions\n): CorsOptions => {\n if (!resolver) {\n return defaultOpts;\n }\n\n try {\n const result = resolver(origin, c);\n\n if (result === true) {\n return { ...defaultOpts, origin: origin || \"*\" };\n }\n\n if (result === false) {\n return { ...defaultOpts, origin: \"\" };\n }\n\n if (result && typeof result === \"object\") {\n return { ...defaultOpts, ...result };\n }\n\n return defaultOpts;\n } catch (error) {\n // Security: deny on resolver failure — never fall through to allow\n console.error(\"CORS resolver error:\", error);\n return { ...defaultOpts, origin: \"\" };\n }\n};\n","import { Ok, type Result } from \"slang-ts\";\nimport z from \"zod\";\nimport type { Engine } from \"@/engine/types\";\nimport type {\n ExternalRequest,\n ExternalResponse,\n NileContext,\n} from \"@/nile/types\";\n\n// --- Response mapping ---\n\n/**\n * Maps an internal Result to the external API response shape.\n * This is the single point where internal Result types cross the boundary\n * into the HTTP-facing ExternalResponse format.\n */\nexport function toExternalResponse(\n result: Result<unknown, string>,\n successMessage: string\n): ExternalResponse {\n if (result.isOk) {\n const value = result.value;\n const data =\n value !== null && typeof value === \"object\" && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : { result: value };\n\n return { status: true, message: successMessage, data };\n }\n\n return { status: false, message: result.error, data: {} };\n}\n\n// --- Intent handlers ---\n\n/**\n * Handles the \"explore\" intent for service/action discovery.\n * - service: \"*\", action: \"*\" -> list all services\n * - service: \"name\", action: \"*\" -> list actions for service\n * - service: \"name\", action: \"name\" -> action metadata\n */\nexport function handleExplore(\n engine: Engine,\n request: ExternalRequest\n): ExternalResponse {\n const { service, action } = request;\n\n if (service === \"*\") {\n return toExternalResponse(engine.getServices(), \"Available services\");\n }\n\n if (action === \"*\") {\n return toExternalResponse(\n engine.getServiceActions(service),\n `Actions for '${service}'`\n );\n }\n\n const actionResult = engine.getAction(service, action);\n if (actionResult.isErr) {\n return toExternalResponse(actionResult, \"\");\n }\n\n const act = actionResult.value;\n return toExternalResponse(\n Ok({\n name: act.name,\n description: act.description,\n isProtected: act.isProtected ?? false,\n accessControl: act.accessControl,\n hooks: act.hooks\n ? { before: act.hooks.before ?? [], after: act.hooks.after ?? [] }\n : null,\n meta: act.meta ?? null,\n }),\n `Details for '${service}.${action}'`\n );\n}\n\n/**\n * Handles the \"execute\" intent by running an action through the engine pipeline.\n */\nexport async function handleExecute(\n engine: Engine,\n request: ExternalRequest,\n nileContext: NileContext<unknown>\n): Promise<ExternalResponse> {\n const { service, action, payload } = request;\n\n if (service === \"*\" || action === \"*\") {\n return {\n status: false,\n message:\n \"Execute intent requires specific service and action, wildcards not allowed\",\n data: {},\n };\n }\n\n const result = await engine.executeAction(\n service,\n action,\n payload,\n nileContext\n );\n\n return toExternalResponse(result, `Action '${service}.${action}' executed`);\n}\n\n/**\n * Handles the \"schema\" intent for Zod-to-JSON-Schema export.\n * - service: \"*\", action: \"*\" -> all schemas across all services\n * - service: \"name\", action: \"*\" -> all schemas in a service\n * - service: \"name\", action: \"name\" -> single action schema\n */\nexport function handleSchema(\n engine: Engine,\n request: ExternalRequest\n): ExternalResponse {\n const { service, action } = request;\n\n if (service === \"*\") {\n const servicesResult = engine.getServices();\n if (servicesResult.isErr) {\n return toExternalResponse(servicesResult, \"\");\n }\n\n const schemas: Record<string, unknown> = {};\n for (const svc of servicesResult.value) {\n const actionsResult = engine.getServiceActions(svc.name);\n if (actionsResult.isErr) {\n continue;\n }\n\n schemas[svc.name] = buildServiceSchemas(\n engine,\n svc.name,\n actionsResult.value.map((a) => a.name)\n );\n }\n\n return toExternalResponse(Ok(schemas), \"All service schemas\");\n }\n\n if (action === \"*\") {\n const actionsResult = engine.getServiceActions(service);\n if (actionsResult.isErr) {\n return toExternalResponse(actionsResult, \"\");\n }\n\n const schemas = buildServiceSchemas(\n engine,\n service,\n actionsResult.value.map((a) => a.name)\n );\n return toExternalResponse(Ok(schemas), `Schemas for '${service}'`);\n }\n\n const actionResult = engine.getAction(service, action);\n if (actionResult.isErr) {\n return toExternalResponse(actionResult, \"\");\n }\n\n const schema = extractActionSchema(actionResult.value);\n return toExternalResponse(\n Ok({ [action]: schema }),\n `Schema for '${service}.${action}'`\n );\n}\n\n/**\n * Builds a map of action schemas for a service\n */\nfunction buildServiceSchemas(\n engine: Engine,\n serviceName: string,\n actionNames: string[]\n): Record<string, unknown> {\n const schemas: Record<string, unknown> = {};\n\n for (const actionName of actionNames) {\n const actionResult = engine.getAction(serviceName, actionName);\n if (actionResult.isErr) {\n continue;\n }\n schemas[actionName] = extractActionSchema(actionResult.value);\n }\n\n return schemas;\n}\n\n/**\n * Extracts JSON schema from an action's zod validation, returns null on failure\n */\nfunction extractActionSchema(action: {\n validation?: import(\"zod\").ZodType | null;\n}): unknown {\n const schema = action.validation;\n if (!schema) {\n return null;\n }\n\n const { err, result } = safeTrySync(() =>\n z.toJSONSchema(schema, { unrepresentable: \"any\" })\n );\n\n return err ? null : result;\n}\n\n/**\n * Synchronous try-catch wrapper for simple operations.\n * Unlike slang-ts safeTry (always async), this is for sync-only code paths.\n */\nfunction safeTrySync<T>(fn: () => T): { err: unknown; result: T | null } {\n try {\n return { err: null, result: fn() };\n } catch (error) {\n return { err: error, result: null };\n }\n}\n\n// --- Intent dispatch ---\n\n/** Object lookup for intent handlers — cleaner than switch/if-else */\nexport const intentHandlers: Record<\n ExternalRequest[\"intent\"],\n (\n engine: Engine,\n request: ExternalRequest,\n nileContext: NileContext<unknown>\n ) => ExternalResponse | Promise<ExternalResponse>\n> = {\n explore: (engine, request) => handleExplore(engine, request),\n execute: (engine, request, nileContext) =>\n handleExecute(engine, request, nileContext),\n schema: (engine, request) => handleSchema(engine, request),\n};\n","import type { Hono } from \"hono\";\nimport { rateLimiter } from \"hono-rate-limiter\";\nimport { safeTry } from \"slang-ts\";\nimport type { ServerRuntime } from \"@/nile/types\";\nimport type { RestConfig } from \"./types\";\n\nconst ASSETS_REGEX = /^\\/assets\\//;\nconst DEFAULT_RATE_LIMIT_WINDOW_MS = 15 * 60 * 1000; // 15 minutes\nconst DEFAULT_RATE_LIMIT_MAX = 100;\nconst UNKNOWN_CLIENT_KEY = \"__unknown_client__\";\n\n/**\n * Applies rate limiting middleware when a limiting header is configured.\n * Extracts the client key from the configured request header for per-client tracking.\n * Falls back to a shared key when the header is missing (graceful degradation).\n */\nexport function applyRateLimiting(\n app: Hono,\n config: RestConfig,\n log: (msg: string, data?: unknown) => void\n): void {\n if (!config.rateLimiting?.limitingHeader) {\n return;\n }\n\n const { rateLimiting } = config;\n\n app.use(\n rateLimiter({\n windowMs: rateLimiting.windowMs ?? DEFAULT_RATE_LIMIT_WINDOW_MS,\n limit: rateLimiting.limit ?? DEFAULT_RATE_LIMIT_MAX,\n standardHeaders: rateLimiting.standardHeaders ?? true,\n keyGenerator: (c) => {\n const key = c.req.header(rateLimiting.limitingHeader);\n if (!key) {\n log(\n `Rate limiting header '${rateLimiting.limitingHeader}' missing from request`\n );\n return UNKNOWN_CLIENT_KEY;\n }\n return key;\n },\n store: rateLimiting.store ?? undefined,\n })\n );\n\n log(\n `Rate limiting enabled: ${rateLimiting.limit ?? DEFAULT_RATE_LIMIT_MAX} requests per ${rateLimiting.windowMs ?? DEFAULT_RATE_LIMIT_WINDOW_MS}ms window`\n );\n}\n\n/**\n * Applies static file serving from ./assets at /assets/*.\n * Uses dynamic import to load the runtime-specific serveStatic adapter,\n * avoiding issues with Bun globals in non-Bun environments (e.g. vitest).\n * Import errors are caught gracefully — static serving is skipped if the adapter fails to load.\n */\nexport function applyStaticServing(\n app: Hono,\n config: RestConfig,\n runtime: ServerRuntime,\n log: (msg: string, data?: unknown) => void\n): void {\n if (!config.enableStatic) {\n return;\n }\n\n if (runtime !== \"bun\") {\n log(`Static file serving not yet supported for runtime: ${runtime}`);\n return;\n }\n\n // Lazy-load the bun serveStatic adapter to avoid referencing Bun globals at import time\n let cachedHandler:\n | ((c: never, next: never) => Promise<Response | undefined>)\n | null = null;\n let importFailed = false;\n\n app.use(\"/assets/*\", async (c, next) => {\n if (importFailed) {\n return next();\n }\n\n if (!cachedHandler) {\n const importResult = await safeTry(async () => {\n const mod = await import(\"hono/bun\");\n return mod.serveStatic({\n root: \"./assets\",\n rewriteRequestPath: (path: string) => path.replace(ASSETS_REGEX, \"\"),\n });\n });\n\n if (importResult.isErr) {\n log(\"Failed to load static file adapter\", importResult.error);\n importFailed = true;\n return next();\n }\n\n cachedHandler = importResult.value as unknown as typeof cachedHandler;\n }\n\n if (cachedHandler) {\n return cachedHandler(c as never, next as never);\n }\n });\n\n log(\"Static file serving enabled at /assets/*\");\n}\n","import type { BaseContext, NileContext, Resources, Sessions } from \"./types\";\n\ninterface CreateNileContextParams<TDB = unknown> {\n interfaceContext?: BaseContext;\n resources?: Resources<TDB>;\n}\n\n/**\n * Creates a new Nile context with an internal key-value store.\n * The context carries interface-specific data (REST, WebSocket, RPC),\n * hook execution context, and provides get/set methods for storing arbitrary values.\n *\n * Sessions are instance-scoped — each NileContext owns its own session store,\n * so multiple server instances don't share authentication state.\n *\n * @param params - Optional configuration including interface adapters and shared resources\n * @returns A fully initialized NileContext\n */\nexport function createNileContext<TDB = unknown>(\n params?: CreateNileContextParams<TDB>\n): NileContext<TDB> {\n const store = new Map<string, unknown>();\n const interfaceContext = params?.interfaceContext;\n\n /** Instance-scoped session store — not shared across server instances */\n const sessions: Sessions = {};\n\n const context: NileContext<TDB> = {\n rest: interfaceContext?.rest,\n ws: interfaceContext?.ws,\n rpc: interfaceContext?.rpc,\n resources: params?.resources,\n sessions,\n _store: store,\n\n get<T = unknown>(key: string): T | undefined {\n return store.get(key) as T | undefined;\n },\n\n set<T = unknown>(key: string, value: T): void {\n store.set(key, value);\n },\n\n getSession(name: keyof Sessions) {\n return sessions[name];\n },\n\n setSession(name: keyof Sessions, data: Record<string, unknown>) {\n sessions[name] = data;\n },\n\n hookContext: {\n actionName: \"\",\n input: null,\n state: {},\n log: { before: [], after: [] },\n },\n\n updateHookState(key: string, value: unknown) {\n context.hookContext.state[key] = value;\n },\n\n addHookLog(\n phase: \"before\" | \"after\",\n logEntry: {\n name: string;\n input: unknown;\n output: unknown;\n passed: boolean;\n }\n ) {\n context.hookContext.log[phase].push(logEntry);\n },\n\n setHookError(error: string) {\n context.hookContext.error = error;\n },\n\n setHookOutput(output: unknown) {\n context.hookContext.output = output;\n },\n\n resetHookContext(actionName: string, input: unknown) {\n context.hookContext = {\n actionName,\n input,\n state: {},\n log: { before: [], after: [] },\n };\n },\n };\n\n return context;\n}\n"],"mappings":"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","names":["match","year","start","end","safeTry","Err","Ok","result","Err","Ok","safeTry","Ok","Err","z","Ok","safeTry","z","safeTry"]}
1
+ {"version":3,"sources":["../src/engine/create-action.ts","../src/engine/create-service.ts","../src/logging/logger.ts","../src/logging/create-log.ts","../src/nile/server.ts","../src/engine/engine.ts","../src/utils/db/create-model.ts","../src/utils/handle-error.ts","../src/utils/db/create-transaction-variant.ts","../src/utils/db/get-zod-schema.ts","../src/utils/diagnostics-log.ts","../src/engine/pipeline.ts","../src/rest/rest.ts","../src/cors/cors.ts","../src/rest/intent-handlers.ts","../src/rest/middleware.ts","../src/nile/nile.ts"],"sourcesContent":["import type { Action } from \"./types\";\n\n/**\n * Typed identity for defining a single action with full type inference.\n * No runtime overhead — returns the config object as-is.\n */\nexport function createAction(config: Action): Action {\n return config;\n}\n\n/**\n * Typed identity for defining multiple actions with full type inference.\n * No runtime overhead — returns the config array as-is.\n */\nexport function createActions(configs: Action[]): Action[] {\n return configs;\n}\n","import type { Service } from \"./types\";\n\n/**\n * Typed identity for defining a service with full type inference.\n * No runtime overhead — returns the config object as-is.\n */\nexport function createService(config: Service): Service {\n return config;\n}\n\n/**\n * Typed identity for defining multiple services with full type inference.\n * No runtime overhead — returns the config array as-is.\n */\nexport function createServices(configs: Service[]): Service[] {\n return configs;\n}\n","import {\n appendFileSync,\n existsSync,\n mkdirSync,\n readdirSync,\n readFileSync,\n} from \"node:fs\";\nimport { join } from \"node:path\";\nimport { nanoid } from \"nanoid\";\nimport pino, { type Logger } from \"pino\";\n\nexport interface Log {\n atFunction: string;\n appName: string;\n message: string;\n data?: unknown;\n level?: \"info\" | \"warn\" | \"error\";\n log_id?: string;\n}\n\n/** Configuration for log file chunking behavior */\nexport interface LoggerConfig {\n /** Time-based chunking strategy. Default: 'none' (single file per app) */\n chunking?: \"monthly\" | \"daily\" | \"weekly\" | \"none\";\n}\n\n// Lazy evaluation of MODE - only check when logging is actually used\nconst getMode = () => {\n if (!process.env.MODE) {\n throw new Error(\"Missing MODE environment variable\");\n }\n return process.env.MODE;\n};\n\nconst logDir = join(process.cwd(), \"logs\");\n\nif (!existsSync(logDir)) {\n mkdirSync(logDir);\n}\n\n// Chunk filename patterns — hoisted for performance (used in hot path by getLogs)\nconst MONTHLY_PATTERN = /^(\\d{4})-(\\d{2})$/;\nconst DAILY_PATTERN = /^(\\d{4})-(\\d{2})-(\\d{2})$/;\nconst WEEKLY_PATTERN = /^(\\d{4})-W(\\d{2})$/;\n\n/**\n * Resolves the correct log file path based on app name and chunking config.\n * - 'none' (default): logs/{appName}.log (backwards compatible)\n * - 'monthly': logs/{appName}/YYYY-MM.log\n * - 'daily': logs/{appName}/YYYY-MM-DD.log\n * - 'weekly': logs/{appName}/YYYY-WNN.log (ISO week number)\n */\nexport function resolveLogPath(appName: string, config?: LoggerConfig): string {\n const chunking = config?.chunking ?? \"none\";\n\n if (chunking === \"none\") {\n return join(logDir, `${appName}.log`);\n }\n\n const appDir = join(logDir, appName);\n if (!existsSync(appDir)) {\n mkdirSync(appDir, { recursive: true });\n }\n\n const now = new Date();\n const chunk = formatChunkName(now, chunking);\n return join(appDir, `${chunk}.log`);\n}\n\n/**\n * Formats a date into the correct chunk filename based on chunking strategy.\n * Exported for testing and reuse by getLogs.\n */\nexport function formatChunkName(\n date: Date,\n chunking: \"monthly\" | \"daily\" | \"weekly\"\n): string {\n const year = date.getFullYear();\n const month = String(date.getMonth() + 1).padStart(2, \"0\");\n\n if (chunking === \"monthly\") {\n return `${year}-${month}`;\n }\n\n if (chunking === \"daily\") {\n const day = String(date.getDate()).padStart(2, \"0\");\n return `${year}-${month}-${day}`;\n }\n\n // Weekly: ISO week number\n const weekNum = getISOWeekNumber(date);\n return `${year}-W${String(weekNum).padStart(2, \"0\")}`;\n}\n\n/** Returns the ISO 8601 week number for a given date */\nfunction getISOWeekNumber(date: Date): number {\n const target = new Date(date.valueOf());\n // Set to nearest Thursday (current date + 4 - current day number, with Sunday as 7)\n const dayNum = target.getDay() || 7;\n target.setDate(target.getDate() + 4 - dayNum);\n const yearStart = new Date(target.getFullYear(), 0, 1);\n return Math.ceil(\n ((target.getTime() - yearStart.getTime()) / 86_400_000 + 1) / 7\n );\n}\n\n/**\n * Creates a pino logger instance that writes to the resolved log file path.\n * Each call creates a fresh pino transport — callers should cache if needed.\n */\nfunction createLoggerForApp(appName: string, config?: LoggerConfig): Logger {\n const logFile = resolveLogPath(appName, config);\n\n const transport = pino.transport({\n targets: [\n {\n level: \"info\",\n target: \"pino/file\",\n options: {\n destination: logFile,\n mkdir: true,\n },\n },\n ],\n });\n\n return pino(\n {\n base: null,\n timestamp: () => `,\"time\":\"${new Date().toISOString()}\"`,\n formatters: {\n level(label) {\n return { level: label };\n },\n },\n },\n transport\n );\n}\n\n/**\n * Creates a new log entry with the provided log information.\n * Supports optional chunking config to split logs into time-based files.\n * @param log - The log object containing the log details\n * @param config - Optional logger config for chunking behavior\n * @returns The generated log ID (or JSON string in agentic mode)\n * @throws {Error} If appName is missing in the log object\n */\nexport const createLog = (log: Log, config?: LoggerConfig) => {\n if (!log.appName) {\n throw new Error(`Missing appName in log: ${JSON.stringify(log)}`);\n }\n\n const level = log.level || \"info\";\n const log_id = log.log_id || nanoid(6);\n\n const logRecord = {\n log_id,\n appName: log.appName,\n atFunction: log.atFunction,\n message: log.message,\n data: log.data ?? null,\n level,\n time: new Date().toISOString(),\n };\n\n const mode = getMode();\n\n if (mode === \"prod\" || process.env.NODE_ENV === \"test\") {\n const logFile = resolveLogPath(log.appName, config);\n\n if (process.env.NODE_ENV === \"test\") {\n // For tests, write synchronously to ensure file exists immediately\n appendFileSync(logFile, `${JSON.stringify(logRecord)}\\n`, \"utf-8\");\n } else {\n // For production, use pino logger\n const appLogger = createLoggerForApp(log.appName, config);\n appLogger[level as \"info\" | \"warn\" | \"error\"](logRecord);\n }\n return log_id;\n }\n\n if (mode === \"agentic\") {\n return JSON.stringify(logRecord);\n }\n\n console.log({\n ...logRecord,\n data: JSON.stringify(logRecord.data, null, 2),\n });\n return \"dev-mode, see your dev console!\";\n};\n\nexport interface LogFilter {\n appName?: string;\n log_id?: string;\n level?: \"info\" | \"warn\" | \"error\";\n from?: Date;\n to?: Date;\n}\n\n/**\n * Retrieves logs based on the provided filters.\n * Supports reading from chunked files when a LoggerConfig with chunking is provided.\n * When chunking is enabled, uses from/to date filters to intelligently select\n * only the relevant chunk files instead of scanning all files.\n * @param filters - Optional filters to apply when retrieving logs\n * @param config - Optional logger config matching the chunking used when writing\n * @returns An array of log entries matching the filters\n */\nexport const getLogs = (\n filters: LogFilter = {},\n config?: LoggerConfig\n): Log[] => {\n const chunking = config?.chunking ?? \"none\";\n\n const filesToRead = resolveLogFiles(filters, chunking);\n const logs = readAndParseLogFiles(filesToRead);\n return applyLogFilters(logs, filters);\n};\n\n/**\n * Determines which log files to read based on filters and chunking strategy.\n * For 'none' chunking, returns the single flat file.\n * For time-based chunking, scans the app directory and filters by date range.\n */\nfunction resolveLogFiles(\n filters: LogFilter,\n chunking: \"monthly\" | \"daily\" | \"weekly\" | \"none\"\n): string[] {\n if (chunking === \"none\") {\n const logFile = filters.appName\n ? join(logDir, `${filters.appName}.log`)\n : join(logDir, \"app.log\");\n return existsSync(logFile) ? [logFile] : [];\n }\n\n // Chunked mode requires appName to locate the directory\n if (!filters.appName) {\n return [];\n }\n\n const appDir = join(logDir, filters.appName);\n if (!existsSync(appDir)) {\n return [];\n }\n\n const allFiles = readdirSync(appDir)\n .filter((f) => f.endsWith(\".log\"))\n .sort();\n\n // If no date filters, read all chunk files\n if (!(filters.from || filters.to)) {\n return allFiles.map((f) => join(appDir, f));\n }\n\n // Filter chunks by date relevance to avoid reading unnecessary files\n return allFiles\n .filter((filename) => isChunkRelevant(filename, chunking, filters))\n .map((f) => join(appDir, f));\n}\n\n/**\n * Checks if a chunk file is relevant to the given date range filter.\n * Compares the chunk's time range against the filter's from/to dates.\n */\nfunction isChunkRelevant(\n filename: string,\n chunking: \"monthly\" | \"daily\" | \"weekly\",\n filters: LogFilter\n): boolean {\n // Extract the chunk name (strip .log extension)\n const chunkName = filename.replace(\".log\", \"\");\n const range = getChunkDateRange(chunkName, chunking);\n\n if (!range) {\n return true; // Can't parse — include to be safe\n }\n\n const { start, end } = range;\n\n // Chunk is relevant if its range overlaps with the filter range\n if (filters.to && start > filters.to) {\n return false;\n }\n if (filters.from && end < filters.from) {\n return false;\n }\n\n return true;\n}\n\n/**\n * Returns the start and end date boundaries of a chunk based on its name and strategy.\n * This allows getLogs to skip chunks that fall outside the requested date range.\n */\nfunction getChunkDateRange(\n chunkName: string,\n chunking: \"monthly\" | \"daily\" | \"weekly\"\n): { start: Date; end: Date } | null {\n if (chunking === \"monthly\") {\n // Format: YYYY-MM\n const match = chunkName.match(MONTHLY_PATTERN);\n if (!(match?.[1] && match[2])) {\n return null;\n }\n const year = Number(match[1]);\n const month = Number(match[2]) - 1;\n const start = new Date(year, month, 1);\n const end = new Date(year, month + 1, 0, 23, 59, 59, 999);\n return { start, end };\n }\n\n if (chunking === \"daily\") {\n // Format: YYYY-MM-DD\n const match = chunkName.match(DAILY_PATTERN);\n if (!(match?.[1] && match[2] && match[3])) {\n return null;\n }\n const year = Number(match[1]);\n const month = Number(match[2]) - 1;\n const day = Number(match[3]);\n const start = new Date(year, month, day);\n const end = new Date(year, month, day, 23, 59, 59, 999);\n return { start, end };\n }\n\n // Weekly: YYYY-WNN\n const match = chunkName.match(WEEKLY_PATTERN);\n if (!(match?.[1] && match[2])) {\n return null;\n }\n const year = Number(match[1]);\n const week = Number(match[2]);\n const start = getDateFromISOWeek(year, week);\n const end = new Date(start);\n end.setDate(end.getDate() + 6);\n end.setHours(23, 59, 59, 999);\n return { start, end };\n}\n\n/** Returns the Monday date for a given ISO year and week number */\nfunction getDateFromISOWeek(year: number, week: number): Date {\n const jan4 = new Date(year, 0, 4);\n const dayOfWeek = jan4.getDay() || 7;\n // Monday of week 1\n const monday = new Date(jan4);\n monday.setDate(jan4.getDate() - dayOfWeek + 1);\n // Add (week - 1) weeks\n monday.setDate(monday.getDate() + (week - 1) * 7);\n monday.setHours(0, 0, 0, 0);\n return monday;\n}\n\n/** Reads and parses NDJSON log entries from multiple files into a single array */\nfunction readAndParseLogFiles(files: string[]): Record<string, unknown>[] {\n const logs: Record<string, unknown>[] = [];\n\n for (const file of files) {\n if (!existsSync(file)) {\n continue;\n }\n\n const content = readFileSync(file, \"utf-8\").trim();\n if (!content) {\n continue;\n }\n\n const lines = content.split(\"\\n\");\n for (const line of lines) {\n try {\n const parsed = JSON.parse(line) as Record<string, unknown>;\n logs.push(parsed);\n } catch {\n // Skip malformed lines\n }\n }\n }\n\n return logs;\n}\n\n/** Applies log_id, level, and time range filters to parsed log entries */\nfunction applyLogFilters(\n logs: Record<string, unknown>[],\n filters: LogFilter\n): Log[] {\n return logs.filter((log) => {\n if (filters.appName && log.appName !== filters.appName) {\n return false;\n }\n if (filters.log_id && log.log_id !== filters.log_id) {\n return false;\n }\n if (filters.level && log.level !== filters.level) {\n return false;\n }\n\n const time = new Date(log.time as string);\n if (filters.from && time < filters.from) {\n return false;\n }\n if (filters.to && time > filters.to) {\n return false;\n }\n\n return true;\n }) as unknown as Log[];\n}\n","import { type Log, type LoggerConfig, createLog as newLog } from \"./logger\";\n\ntype LogInput = Omit<Log, \"appName\">;\n\n/**\n * Creates a logger instance bound to a specific app name.\n * Optionally accepts a LoggerConfig for time-based file chunking.\n * @param appName - The application name (determines log file/directory)\n * @param config - Optional config for chunking (monthly, daily, weekly)\n */\nexport const createLogger = (appName: string, config?: LoggerConfig) => {\n return {\n info: (input: LogInput) =>\n newLog({ ...input, appName, level: \"info\" }, config),\n warn: (input: LogInput) =>\n newLog({ ...input, appName, level: \"warn\" }, config),\n error: (input: LogInput) =>\n newLog({ ...input, appName, level: \"error\" }, config),\n };\n};\n","import { safeTry } from \"slang-ts\";\nimport { createEngine } from \"@/engine/engine\";\nimport type { Engine } from \"@/engine/types\";\nimport { createRestApp } from \"@/rest/rest\";\nimport { createDiagnosticsLog } from \"@/utils\";\nimport { createNileContext } from \"./nile\";\nimport type { NileContext, NileServer, Resources, ServerConfig } from \"./types\";\n\nlet _nileContext: NileContext | null = null;\n\n/**\n * Retrieves the runtime NileContext.\n *\n * Use this to access shared resources (database, logger) and context storage\n * from anywhere in your application. Supports a TDB generic to provide\n * end-to-end type safety for your database instance.\n *\n * @template TDB - The type of your database instance (e.g. typeof db)\n * @returns The active NileContext<TDB>\n * @throws If called before createNileServer has initialized the global context.\n */\nexport function getContext<TDB = unknown>(): NileContext<TDB> {\n if (!_nileContext) {\n throw new Error(\n \"getContext: Server not initialized. Call createNileServer first.\"\n );\n }\n return _nileContext as NileContext<TDB>;\n}\n\n/**\n * Bootstraps a Nile server instance.\n *\n * Wires together the Action Engine, shared NileContext, and interface layers (REST).\n * This is the primary entry point for a Nile application. It handles service\n * registration, resource attachment, and server lifecycle.\n *\n * @param config - Server configuration including services, rest options, and resources\n * @returns A NileServer instance containing the engine and (optional) REST app\n */\nexport function createNileServer(config: ServerConfig): NileServer {\n if (!config.services?.length) {\n throw new Error(\n \"createNileServer requires at least one service in config.services\"\n );\n }\n\n const log = createDiagnosticsLog(\"NileServer\", {\n diagnostics: config.diagnostics,\n logger: config.resources?.logger as unknown as Parameters<\n typeof createDiagnosticsLog\n >[1][\"logger\"],\n });\n\n // Shared context -- created once with resources, passed to all layers\n const nileContext = createNileContext({\n resources: config.resources as unknown as Resources<unknown>,\n });\n\n _nileContext = nileContext as unknown as NileContext<unknown>;\n\n // Initialize the Action Engine\n const engine: Engine = createEngine({\n services: config.services,\n diagnostics: config.diagnostics,\n logger: config.resources?.logger as unknown as Parameters<\n typeof createEngine\n >[0][\"logger\"],\n onBeforeActionHandler: config.onBeforeActionHandler,\n onAfterActionHandler: config.onAfterActionHandler,\n });\n\n log(`Engine initialized with ${config.services.length} service(s)`);\n\n // Print registered services table (on by default, opt-out with logServices: false)\n if (config.logServices !== false) {\n const servicesResult = engine.getServices();\n if (servicesResult.isOk) {\n const table = servicesResult.value.map((s) => ({\n Service: s.name,\n Description: s.description,\n Actions: s.actions.length,\n }));\n console.table(table);\n }\n }\n\n // Build the server object incrementally\n const server: NileServer = {\n config,\n engine,\n context: nileContext as NileContext<unknown>,\n };\n\n // Initialize REST interface if configured\n if (config.rest) {\n const app = createRestApp({\n config: config.rest,\n engine,\n nileContext: nileContext as NileContext<unknown>,\n serverName: config.serverName,\n runtime: config.runtime ?? \"bun\",\n });\n\n server.rest = { app, config: config.rest };\n\n const host = config.rest.host ?? \"localhost\";\n const port = config.rest.port ?? 8000;\n const base = `http://${host}:${port}`;\n\n console.log(`\\n POST ${base}${config.rest.baseUrl}/services`);\n if (config.rest.enableStatus) {\n console.log(` GET ${base}/status`);\n }\n console.log(\"\");\n }\n\n // Run onBoot lifecycle hook\n if (config.onBoot) {\n const { fn } = config.onBoot;\n // Fire-and-forget with crash safety via async IIFE\n const _boot = (async () => {\n const result = await safeTry(() => fn(nileContext));\n if (result.isErr) {\n console.error(\"[NileServer] onBoot failed:\", result.error);\n }\n })();\n // Intentionally not awaited — boot runs in background\n _boot;\n }\n\n log(`${config.serverName} server ready`);\n\n return server;\n}\n","import { Err, Ok, type Result } from \"slang-ts\";\nimport type { NileContext } from \"@/nile/types\";\nimport { createDiagnosticsLog } from \"@/utils\";\nimport {\n processHooks,\n runGlobalAfterHook,\n runGlobalBeforeHook,\n runHandler,\n validatePayload,\n} from \"./pipeline\";\nimport type {\n Action,\n ActionSummary,\n EngineOptions,\n ServiceSummary,\n} from \"./types\";\n\nexport function createEngine(options: EngineOptions) {\n const { diagnostics, services, logger } = options;\n\n const log = createDiagnosticsLog(\"Engine\", {\n diagnostics,\n logger: logger as unknown as Parameters<\n typeof createDiagnosticsLog\n >[1][\"logger\"],\n });\n\n // O(1) Pre-computed Lookups\n const serviceSummaries: ServiceSummary[] = [];\n const serviceActionsStore: Record<string, ActionSummary[]> = {};\n const actionStore: Record<string, Record<string, Action>> = {};\n\n // Build stores once on init\n const initStartTime = performance.now();\n\n for (const service of services) {\n const actionNames: string[] = [];\n serviceActionsStore[service.name] = [];\n actionStore[service.name] = {};\n\n for (const action of service.actions) {\n actionNames.push(action.name);\n\n serviceActionsStore[service.name]?.push({\n name: action.name,\n description: action.description,\n isProtected: !!action.isProtected,\n validation: !!action.validation,\n accessControl: action.accessControl || [],\n });\n\n const serviceActions = actionStore[service.name];\n if (serviceActions) {\n serviceActions[action.name] = action;\n }\n }\n\n serviceSummaries.push({\n name: service.name,\n description: service.description,\n meta: service.meta,\n actions: actionNames,\n });\n }\n\n log(\n `Initialized in ${performance.now() - initStartTime}ms. Loaded ${services.length} services.`\n );\n\n // --- Discovery API ---\n\n const getServices = (): Result<ServiceSummary[], string> =>\n Ok(serviceSummaries);\n\n const getServiceActions = (\n serviceName: string\n ): Result<ActionSummary[], string> => {\n const actions = serviceActionsStore[serviceName];\n return actions ? Ok(actions) : Err(`Service '${serviceName}' not found`);\n };\n\n const getAction = (\n serviceName: string,\n actionName: string\n ): Result<Action, string> => {\n const serviceMap = actionStore[serviceName];\n if (!serviceMap) {\n return Err(`Service '${serviceName}' not found`);\n }\n\n const action = serviceMap[actionName];\n return action\n ? Ok(action)\n : Err(`Action '${actionName}' not found in service '${serviceName}'`);\n };\n\n const executeAction = async (\n serviceName: string,\n actionName: string,\n payload: unknown,\n nileContext: NileContext<unknown>\n ): Promise<Result<unknown, string>> => {\n const { onBeforeActionHandler, onAfterActionHandler } = options;\n\n // Resolve action\n const actionResult = getAction(serviceName, actionName);\n if (actionResult.isErr) {\n return Err(actionResult.error);\n }\n const action = actionResult.value;\n\n // Reset hook context for this execution\n nileContext.resetHookContext(`${serviceName}.${actionName}`, payload);\n\n // Step 1: Global Before Hook\n const globalBeforeResult = await runGlobalBeforeHook(\n onBeforeActionHandler,\n nileContext,\n action,\n payload,\n log\n );\n if (globalBeforeResult.isErr) {\n return Err(globalBeforeResult.error);\n }\n\n // Step 2: Action Before Hooks\n const beforeHooksResult = await processHooks(\n action.hooks?.before ?? [],\n payload,\n getAction,\n nileContext,\n \"before\",\n log\n );\n if (beforeHooksResult.isErr) {\n return Err(beforeHooksResult.error);\n }\n\n // Step 3: Validation\n const validationResult = validatePayload(\n action,\n beforeHooksResult.value,\n nileContext,\n log\n );\n if (validationResult.isErr) {\n return Err(validationResult.error);\n }\n\n // Step 4: Handler\n const handlerResult = await runHandler(\n action,\n validationResult.value,\n nileContext,\n log\n );\n if (handlerResult.isErr) {\n return Err(handlerResult.error);\n }\n\n // Step 5: Action After Hooks\n const afterHooksResult = await processHooks(\n action.hooks?.after ?? [],\n handlerResult.value,\n getAction,\n nileContext,\n \"after\",\n log\n );\n if (afterHooksResult.isErr) {\n return Err(afterHooksResult.error);\n }\n\n // Step 6: Global After Hook\n const globalAfterResult = await runGlobalAfterHook(\n onAfterActionHandler,\n nileContext,\n action,\n validationResult.value,\n afterHooksResult.value,\n log\n );\n if (globalAfterResult.isErr) {\n return Err(globalAfterResult.error);\n }\n\n // Final response\n return action.result?.pipeline\n ? Ok({\n data: globalAfterResult.value,\n pipeline: nileContext.hookContext.log,\n })\n : Ok(globalAfterResult.value);\n };\n\n return {\n getServices,\n getServiceActions,\n getAction,\n executeAction,\n };\n}\n","import { count, desc, eq, lt, type SQL } from \"drizzle-orm\";\nimport { Ok, safeTry } from \"slang-ts\";\nimport { getContext } from \"@/nile/server\";\nimport { handleError } from \"../handle-error\";\nimport { createTransactionVariant } from \"./create-transaction-variant\";\nimport { getZodSchema } from \"./get-zod-schema\";\nimport type {\n CursorPage,\n ModelOperations,\n ModelOptions,\n ModelUpdateParams,\n ModelWriteParams,\n OffsetPage,\n OffsetPaginationOptions,\n PaginationOptions,\n TableSchemas,\n} from \"./types\";\n\n/**\n * Minimal shape of a Drizzle database instance for dynamic query building.\n * Covers the select/insert/update/delete chains used by createModel internals.\n * Avoids using the `Function` type while remaining compatible with both\n * Neon and PGLite Drizzle drivers.\n */\ninterface DrizzleDbLike {\n select(fields?: Record<string, unknown>): {\n from(table: unknown): DrizzleSelectQuery;\n };\n insert(table: unknown): {\n values(data: unknown): {\n returning(): Promise<unknown[]>;\n };\n };\n update(table: unknown): {\n set(data: unknown): {\n where(condition: SQL): {\n returning(): Promise<unknown[]>;\n };\n };\n };\n delete(table: unknown): {\n where(condition: SQL): {\n returning(): Promise<unknown[]>;\n };\n };\n}\n\n/** Chainable select query shape — supports where/orderBy/limit/offset in any valid order */\ninterface DrizzleSelectQuery extends Promise<unknown[]> {\n where(condition: SQL): DrizzleSelectQuery;\n orderBy(...cols: SQL[]): DrizzleSelectQuery;\n limit(n: number): DrizzleSelectQuery;\n offset(n: number): DrizzleSelectQuery;\n}\n\n/** Cast db to our minimal interface — safe because Drizzle drivers all expose these methods */\nfunction asDb(db: unknown): DrizzleDbLike {\n return db as DrizzleDbLike;\n}\n\n/**\n * Resolves a database instance from the explicit option or the Nile request context.\n * Throws immediately if neither is available — this is a developer configuration error.\n */\nfunction resolveDb<TDB>(explicitDb: TDB | undefined): TDB {\n if (explicitDb) {\n return explicitDb;\n }\n\n try {\n const ctx = getContext();\n if (ctx.resources?.database) {\n return ctx.resources.database as TDB;\n }\n } catch (_) {\n // context not available — fall through to throw\n }\n throw new Error(\n \"createModel: No database available. Pass db in ModelOptions or set resources.database on server config.\"\n );\n}\n\n/**\n * Detects the timestamp column used for default ordering.\n * Checks for both snake_case (created_at) and camelCase (createdAt) conventions.\n */\nfunction findTimestampColumn(table: Record<string, unknown>): string | null {\n if (\"created_at\" in table) {\n return \"created_at\";\n }\n if (\"createdAt\" in table) {\n return \"createdAt\";\n }\n return null;\n}\n\n/**\n * Creates a CRUD model for a Drizzle table, eliminating repetitive boilerplate.\n *\n * All methods return `Result<T, string>` — `Ok(data)` on success, `Err(message)` on failure.\n * Validation, error handling, and transaction variants are built in.\n *\n * For anything beyond basic CRUD, use the exposed `table` and `schemas` properties\n * to compose custom queries with Drizzle directly.\n *\n * @param table - Drizzle table definition (from pgTable, sqliteTable, etc.)\n * @param options - Configuration: entity name, optional db instance, cursor column\n * @returns Object with CRUD operations, plus escape hatches (table, schemas)\n *\n * @example\n * ```typescript\n * import { createModel } from \"@nilejs/nile\";\n * import { tasks } from \"./schema\";\n * import { db } from \"./client\";\n *\n * // Explicit db\n * export const taskModel = createModel(tasks, { db, name: \"task\" });\n *\n * // Context-resolved db (resolved at call time)\n * export const taskModel = createModel(tasks, { name: \"task\" });\n *\n * // Usage\n * const result = await taskModel.create({ data: { title: \"Ship it\" } });\n * const task = await taskModel.findById(\"uuid-123\");\n * const page = await taskModel.findPaginated({ limit: 20, offset: 0 });\n * ```\n */\nexport function createModel<\n TTable extends { $inferSelect: unknown; $inferInsert: unknown },\n TDB = unknown,\n>(\n table: TTable,\n options: ModelOptions<TDB>\n): ModelOperations<TTable[\"$inferSelect\"], TTable[\"$inferInsert\"], TDB> {\n type TSelect = TTable[\"$inferSelect\"];\n type TInsert = TTable[\"$inferInsert\"];\n\n const { name, cursorColumn = \"id\" } = options;\n const entityName = name.charAt(0).toUpperCase() + name.slice(1);\n const schemas = getZodSchema(table) as TableSchemas<TTable>;\n const tableRef = table as Record<string, unknown>;\n\n /** Resolve and cast db for the current call */\n const getDb = () => asDb(resolveDb<TDB>(options.db));\n\n // -- Core CRUD --\n\n const create = async ({ data, dbx }: ModelWriteParams<TInsert, TDB>) => {\n const parsed = schemas.insert.safeParse(data);\n if (!parsed.success) {\n return handleError({\n message: `Invalid ${name} data`,\n data: { errors: parsed.error },\n atFunction: `${name}.create`,\n });\n }\n\n const db = dbx ? asDb(dbx) : getDb();\n const result = await safeTry(() =>\n db.insert(table).values(data).returning()\n );\n if (result.isErr) {\n return handleError({\n message: `Error creating ${name}`,\n data: { error: result.error },\n atFunction: `${name}.create`,\n });\n }\n\n const row = (result.value as TSelect[])?.[0] ?? null;\n if (!row) {\n return handleError({\n message: `${entityName} creation returned no data`,\n atFunction: `${name}.create`,\n });\n }\n return Ok(row);\n };\n\n const update = async ({ id, data, dbx }: ModelUpdateParams<TSelect, TDB>) => {\n const parsed = schemas.update.safeParse(data);\n if (!parsed.success) {\n return handleError({\n message: `Invalid ${name} data`,\n data: { errors: parsed.error },\n atFunction: `${name}.update`,\n });\n }\n\n const db = dbx ? asDb(dbx) : getDb();\n const idCol = tableRef.id as Parameters<typeof eq>[0];\n const result = await safeTry(() =>\n db.update(table).set(data).where(eq(idCol, id)).returning()\n );\n if (result.isErr) {\n return handleError({\n message: `Error updating ${name}`,\n data: { id, error: result.error },\n atFunction: `${name}.update`,\n });\n }\n\n const row = (result.value as TSelect[])?.[0] ?? null;\n if (!row) {\n return handleError({\n message: `${entityName} not found`,\n data: { id },\n atFunction: `${name}.update`,\n });\n }\n return Ok(row);\n };\n\n // Transaction variants via existing utility\n const createTx = createTransactionVariant(\n create as Parameters<typeof createTransactionVariant>[0]\n );\n const updateTx = createTransactionVariant(\n update as Parameters<typeof createTransactionVariant>[0]\n );\n\n const findById = async (id: string) => {\n const db = getDb();\n const idCol = tableRef.id as Parameters<typeof eq>[0];\n const result = await safeTry(() =>\n db.select().from(table).where(eq(idCol, id))\n );\n if (result.isErr) {\n return handleError({\n message: `Error getting ${name}`,\n data: { id, error: result.error },\n atFunction: `${name}.findById`,\n });\n }\n\n const row = (result.value as TSelect[])?.[0] ?? null;\n if (!row) {\n return handleError({\n message: `${entityName} not found`,\n data: { id },\n atFunction: `${name}.findById`,\n });\n }\n return Ok(row);\n };\n\n const deleteFn = async (id: string) => {\n const db = getDb();\n const idCol = tableRef.id as Parameters<typeof eq>[0];\n const result = await safeTry(() =>\n db.delete(table).where(eq(idCol, id)).returning()\n );\n if (result.isErr) {\n return handleError({\n message: `Error deleting ${name}`,\n data: { id, error: result.error },\n atFunction: `${name}.delete`,\n });\n }\n\n const row = (result.value as TSelect[])?.[0] ?? null;\n if (!row) {\n return handleError({\n message: `${entityName} not found`,\n data: { id },\n atFunction: `${name}.delete`,\n });\n }\n return Ok(row);\n };\n\n const findAll = async () => {\n const db = getDb();\n const tsCol = findTimestampColumn(tableRef);\n\n const result = await safeTry(() => {\n const query = db.select().from(table);\n if (!tsCol) {\n return query;\n }\n return query.orderBy(desc(tableRef[tsCol] as Parameters<typeof desc>[0]));\n });\n if (result.isErr) {\n return handleError({\n message: `Error getting all ${name}s`,\n data: { error: result.error },\n atFunction: `${name}.findAll`,\n });\n }\n\n return Ok((result.value ?? []) as TSelect[]);\n };\n\n /** Offset-based pagination — returns items, total count, and hasMore flag */\n const findOffsetPage = async (limit: number, offset: number) => {\n const db = getDb();\n const tsCol = findTimestampColumn(tableRef);\n\n const itemsResult = await safeTry(() => {\n const query = db.select().from(table);\n const ordered = tsCol\n ? query.orderBy(desc(tableRef[tsCol] as Parameters<typeof desc>[0]))\n : query;\n return ordered.limit(limit).offset(offset);\n });\n if (itemsResult.isErr) {\n return handleError({\n message: `Error getting paginated ${name}s`,\n data: { limit, offset, error: itemsResult.error },\n atFunction: `${name}.findPaginated`,\n });\n }\n\n const countResult = await safeTry(() =>\n db.select({ total: count() }).from(table)\n );\n if (countResult.isErr) {\n return handleError({\n message: `Error getting ${name} count`,\n data: { error: countResult.error },\n atFunction: `${name}.findPaginated`,\n });\n }\n\n const items = (itemsResult.value ?? []) as TSelect[];\n const total = (countResult.value as { total: number }[])?.[0]?.total ?? 0;\n\n return Ok({\n items,\n total,\n hasMore: offset + items.length < total,\n } satisfies OffsetPage<TSelect>);\n };\n\n /** Cursor-based pagination — uses lt() on the cursor column with desc ordering */\n const findCursorPage = async (\n limit: number,\n cursor: string,\n colName: string\n ) => {\n const db = getDb();\n const column = tableRef[colName];\n\n if (!column) {\n return handleError({\n message: `Cursor column '${colName}' does not exist on ${name} table`,\n atFunction: `${name}.findPaginated`,\n });\n }\n\n const typedColumn = column as Parameters<typeof lt>[0];\n\n // Fetch one extra row to determine hasMore without a separate count query\n const result = await safeTry(() =>\n db\n .select()\n .from(table)\n .where(lt(typedColumn, cursor))\n .orderBy(desc(typedColumn))\n .limit(limit + 1)\n );\n if (result.isErr) {\n return handleError({\n message: `Error getting paginated ${name}s`,\n data: { cursor, cursorColumn: colName, error: result.error },\n atFunction: `${name}.findPaginated`,\n });\n }\n\n const rows = (result.value ?? []) as TSelect[];\n const hasMore = rows.length > limit;\n const items = hasMore ? rows.slice(0, limit) : rows;\n const lastItem = items.at(-1) as Record<string, unknown> | undefined;\n const nextCursor = lastItem\n ? String(lastItem[colName] ?? \"\") || null\n : null;\n\n return Ok({\n items,\n nextCursor,\n hasMore,\n } satisfies CursorPage<TSelect>);\n };\n\n const findPaginated = (opts: PaginationOptions = {}) => {\n const limit = opts.limit ?? 50;\n\n // Cursor mode when cursor is provided\n if (\"cursor\" in opts && opts.cursor) {\n const colName = opts.cursorColumn ?? cursorColumn;\n return findCursorPage(limit, opts.cursor, colName);\n }\n\n // Default: offset mode\n const offset = (opts as OffsetPaginationOptions).offset ?? 0;\n return findOffsetPage(limit, offset);\n };\n\n return {\n create,\n createTx,\n findById,\n update,\n updateTx,\n delete: deleteFn,\n findAll,\n findPaginated,\n table,\n schemas,\n } as ModelOperations<TSelect, TInsert, TDB>;\n}\n","import { Err, type ErrType, type ResultMethods } from \"slang-ts\";\nimport { getContext } from \"@/nile/server\";\nimport type { NileLogger } from \"@/nile/types\";\n\n/**\n * Parameters for the handleError utility.\n *\n * @property message - Human-readable error description, included in the returned Result error string\n * @property data - Optional structured data logged alongside the error for debugging\n * @property logger - Explicit logger instance; when omitted, resolves from the current Nile request context\n * @property atFunction - Name of the calling function for log attribution; auto-inferred from stack trace when omitted\n */\nexport interface HandleErrorParams {\n message: string;\n data?: unknown;\n logger?: NileLogger;\n atFunction?: string;\n}\n\nconst CALLER_LINE_REGEX = /at\\s+(\\S+)\\s+/;\n\nfunction inferCallerName(): string {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const _err = new Error(\"capture stack trace\");\n const stack = _err.stack;\n const callerLine = stack?.split(\"\\n\")[3] ?? \"\";\n const match = callerLine.match(CALLER_LINE_REGEX);\n return match?.[1] ?? \"unknown\";\n}\n\nfunction resolveLogger(explicit?: NileLogger): NileLogger {\n if (explicit) {\n return explicit;\n }\n try {\n const ctx = getContext();\n if (ctx.resources?.logger) {\n return ctx.resources.logger;\n }\n } catch (_) {\n // Fall through to throw\n }\n throw new Error(\n \"handleError: No logger available. Provide a logger param or set resources.logger on server config.\"\n );\n}\n\n/**\n * Logs an error via the resolved logger and returns a typed Err result.\n * Resolves the logger from the current Nile request context when not provided explicitly.\n * The returned error string includes the log ID for traceability: `[logId] message`.\n *\n * @param params - Error details including message, optional data, logger, and caller function name\n * @returns Always an Err variant — `ErrType<string> & ResultMethods<never>`, compatible with any `Result<T, E>` union\n *\n * @example\n * ```typescript\n * if (!user) {\n * return handleError({\n * message: \"User not found\",\n * data: { userId },\n * atFunction: \"getUserById\",\n * });\n * }\n * ```\n */\nexport function handleError(\n params: HandleErrorParams\n): ErrType<string> & ResultMethods<never> {\n const atFunction = params.atFunction ?? inferCallerName();\n const logger = resolveLogger(params.logger);\n const logId = logger.error({\n atFunction,\n message: params.message,\n data: params.data,\n });\n return Err(`[${logId}] ${params.message}`);\n}\n","import type { Result } from \"slang-ts\";\nimport type { DBParams } from \"./types\";\n\n/**\n * Creates a transaction-aware variant of a database function.\n * Expects the wrapped function to accept a single object parameter with optional dbx field.\n *\n * When dbx is root db (has .transaction method):\n * - Creates new transaction and executes function inside it\n * - On Result.isError, throws Error to trigger automatic rollback\n * - Returns successful result or throws\n *\n * When dbx is tx pointer (no .transaction method):\n * - Executes function directly within existing transaction scope\n * - On Result.isError, throws Error to trigger parent transaction rollback\n * - Returns successful result or throws\n *\n * Both cases ensure database rollback on any error by throwing.\n *\n * @example\n * ```typescript\n * const createCompanyTx = createTransactionVariant(createCompany);\n * // Type-safe: requires all params from createCompany\n * const result = await createCompanyTx({ company: {...}, dbx: tx });\n * ```\n */\nexport function createTransactionVariant<\n TParams extends DBParams<TDB>,\n TData,\n TDB = unknown,\n>(\n fn: (params: TParams) => Promise<Result<TData, unknown>>\n): (params: TParams) => Promise<Result<TData, unknown>> {\n return async (params: TParams): Promise<Result<TData, unknown>> => {\n const { dbx, ...rest } = params;\n\n if (!dbx) {\n const result = await fn(params as TParams);\n if (result.isErr) {\n throw new Error(String(result.error));\n }\n return result;\n }\n\n const hasTransaction =\n typeof (dbx as Record<string, unknown>)?.transaction === \"function\";\n\n if (hasTransaction) {\n return await (\n dbx as unknown as {\n transaction: (\n fn: (tx: unknown) => Promise<Result<TData, unknown>>\n ) => Promise<Result<TData, unknown>>;\n }\n ).transaction(async (tx: unknown) => {\n const result = await fn({ ...rest, dbx: tx } as TParams);\n if (result.isErr) {\n throw new Error(String(result.error));\n }\n return result;\n });\n }\n\n const result = await fn({ ...rest, dbx } as TParams);\n if (result.isErr) {\n throw new Error(String(result.error));\n }\n return result;\n };\n}\n","import {\n createInsertSchema,\n createSelectSchema,\n createUpdateSchema,\n} from \"drizzle-zod\";\nimport type { TableSchemas } from \"./types\";\n\n/**\n * Generates Zod schemas (insert, update, select) from a Drizzle table.\n *\n * @param table - The Drizzle table definition\n * @returns Object containing insert, update, and select Zod schemas\n *\n * @example\n * ```typescript\n * import { getZodSchema } from '@nilejs/nile';\n * import { companies } from './schema';\n *\n * const schemas = getZodSchema(companies);\n * const insert = schemas.insert.parse(data);\n * const update = schemas.update.partial().parse(data);\n * ```\n */\nexport function getZodSchema<TTable extends object>(\n table: TTable\n): TableSchemas<TTable> {\n const isRelation =\n Object.hasOwn(table as object, \"config\") &&\n Object.hasOwn(table as object, \"table\");\n\n if (isRelation) {\n throw new Error(\n `${String(table)} is a relation schema, not a table schema`\n );\n }\n\n const insertSchema = createInsertSchema(\n table as unknown as Parameters<typeof createInsertSchema>[0]\n );\n const updateSchema = createUpdateSchema(\n table as unknown as Parameters<typeof createUpdateSchema>[0]\n );\n const selectSchema = createSelectSchema(\n table as unknown as Parameters<typeof createSelectSchema>[0]\n );\n\n return {\n insert: insertSchema,\n update: updateSchema,\n select: selectSchema,\n } as TableSchemas<TTable>;\n}\n","import type { NileLogger } from \"@/nile/types\";\n\ntype AnyLogger = NileLogger | { info: (msg: string, data?: unknown) => void };\n\nfunction isNileLogger(logger: AnyLogger): logger is NileLogger {\n return \"warn\" in logger && \"error\" in logger;\n}\n\ninterface CreateDiagnosticsLogParams {\n diagnostics?: boolean;\n logger?: AnyLogger;\n}\n\n/**\n * Creates a centralized diagnostics log function for nile internals.\n * Checks resources.logger first, falls back to console.log, respects diagnostics flag.\n * Returns a bound function with the prefix already applied for clean call sites.\n *\n * @param prefix - Component identifier e.g. \"NileServer\", \"REST\", \"Engine\"\n * @param params - Diagnostics flag and optional structured logger from resources\n * @returns A log function: (message, data?) => void\n */\nexport function createDiagnosticsLog(\n prefix: string,\n params: CreateDiagnosticsLogParams\n): (message: string, data?: unknown) => void {\n if (!params.diagnostics) {\n // biome-ignore lint/suspicious/noEmptyBlockStatements: intentional no-op when diagnostics disabled\n return () => {};\n }\n\n const { logger } = params;\n\n return (message: string, data?: unknown) => {\n if (!logger) {\n console.log(`[${prefix}] ${message}`, data ?? \"\");\n return;\n }\n\n if (isNileLogger(logger)) {\n logger.info({\n atFunction: prefix,\n message: `[${prefix}] ${message}`,\n data,\n });\n } else {\n logger.info(`[${prefix}] ${message}`, data);\n }\n };\n}\n","import { Err, Ok, type Result, safeTry } from \"slang-ts\";\nimport { prettifyError } from \"zod\";\nimport type {\n AfterActionHandler,\n BeforeActionHandler,\n NileContext,\n} from \"@/nile/types\";\nimport type { Action, HookDefinition, HookLogEntry } from \"./types\";\n\n/**\n * Executes a single hook and logs the result\n */\nasync function runHook(\n hookDef: HookDefinition,\n hookAction: Action,\n input: unknown,\n nileContext: NileContext\n): Promise<{ result: Result<unknown, string>; logEntry: HookLogEntry }> {\n const result = await safeTry(() =>\n hookAction.handler(input as Record<string, unknown>, nileContext)\n );\n return {\n result,\n logEntry: {\n name: `${hookDef.service}.${hookDef.action}`,\n input,\n output: result.isOk ? result.value : result.error,\n passed: result.isOk,\n },\n };\n}\n\n/**\n * Process hooks sequentially, each hook output becomes the next input\n */\nexport async function processHooks(\n hooks: HookDefinition[],\n initialValue: unknown,\n getAction: (service: string, action: string) => Result<Action, string>,\n nileContext: NileContext,\n logTarget: \"before\" | \"after\",\n log: (msg: string, data?: unknown) => void\n): Promise<Result<unknown, string>> {\n let currentValue = initialValue;\n\n for (const hookDef of hooks) {\n const hookActionResult = getAction(hookDef.service, hookDef.action);\n\n if (hookActionResult.isErr) {\n const errorMsg = `${logTarget} hook '${hookDef.service}.${hookDef.action}' not found`;\n log(errorMsg);\n if (hookDef.isCritical) {\n nileContext.setHookError(errorMsg);\n return Err(errorMsg);\n }\n continue;\n }\n\n const { result, logEntry } = await runHook(\n hookDef,\n hookActionResult.value,\n currentValue,\n nileContext\n );\n nileContext.addHookLog(logTarget, logEntry);\n\n if (result.isErr) {\n const errorMsg = String(result.error);\n log(\n `${logTarget} hook '${hookDef.service}.${hookDef.action}' failed`,\n result.error\n );\n if (hookDef.isCritical) {\n nileContext.setHookError(errorMsg);\n return Err(errorMsg);\n }\n continue;\n }\n\n currentValue = result.value;\n }\n\n return Ok(currentValue);\n}\n\n/**\n * Run global before hook if configured, wrapped in safeTry for crash safety\n */\nexport async function runGlobalBeforeHook(\n handler: BeforeActionHandler<unknown, unknown> | undefined,\n nileContext: NileContext,\n action: Action,\n payload: unknown,\n log: (msg: string) => void\n): Promise<Result<true, string>> {\n if (!handler) {\n return Ok(true);\n }\n\n const result = await safeTry(() => handler({ nileContext, action, payload }));\n if (result.isErr) {\n log(`Global before hook failed for ${action.name}`);\n nileContext.setHookError(result.error);\n return Err(result.error);\n }\n\n return Ok(true);\n}\n\n/**\n * Run global after hook if configured, wrapped in safeTry for crash safety\n */\nexport async function runGlobalAfterHook(\n handler: AfterActionHandler<unknown, unknown> | undefined,\n nileContext: NileContext,\n action: Action,\n payload: unknown,\n currentResult: unknown,\n log: (msg: string) => void\n): Promise<Result<unknown, string>> {\n if (!handler) {\n return Ok(currentResult);\n }\n\n const result = await safeTry(() =>\n handler({\n nileContext,\n action,\n payload,\n result: Ok(currentResult),\n })\n );\n if (result.isErr) {\n log(`Global after hook failed for ${action.name}`);\n nileContext.setHookError(result.error);\n return Err(result.error);\n }\n\n return Ok(result.value);\n}\n\n/**\n * Validate payload against action's Zod schema\n */\nexport function validatePayload(\n action: Action,\n payload: unknown,\n nileContext: NileContext,\n log: (msg: string, data?: unknown) => void\n): Result<unknown, string> {\n if (!action.validation) {\n return Ok(payload);\n }\n\n const parseResult = action.validation.safeParse(payload);\n if (!parseResult.success) {\n const validationError = prettifyError(parseResult.error);\n log(`Validation failed for ${action.name}`, validationError);\n nileContext.setHookError(validationError);\n return Err(`Validation failed: ${validationError}`);\n }\n\n return Ok(parseResult.data);\n}\n\n/**\n * Execute the main action handler, wrapped in safeTry for crash safety\n */\nexport async function runHandler(\n action: Action,\n payload: unknown,\n nileContext: NileContext,\n log: (msg: string, data?: unknown) => void\n): Promise<Result<unknown, string>> {\n const result = await safeTry(() =>\n action.handler(payload as Record<string, unknown>, nileContext)\n );\n\n if (result.isErr) {\n log(`Handler failed for ${action.name}`, result.error);\n nileContext.setHookError(result.error);\n return Err(result.error);\n }\n\n nileContext.setHookOutput(result.value);\n return Ok(result.value);\n}\n","import { Hono } from \"hono\";\nimport z from \"zod\";\nimport { applyCorsConfig } from \"@/cors/cors\";\nimport type { Engine } from \"@/engine/types\";\nimport type {\n ExternalRequest,\n ExternalResponse,\n NileContext,\n ServerRuntime,\n} from \"@/nile/types\";\nimport { createDiagnosticsLog } from \"@/utils\";\nimport { intentHandlers } from \"./intent-handlers\";\nimport { applyRateLimiting, applyStaticServing } from \"./middleware\";\nimport type { RestConfig } from \"./types\";\n\n// --- Zod schema for incoming requests ---\n\nconst externalRequestSchema = z.object({\n intent: z.enum([\"explore\", \"execute\", \"schema\"]),\n service: z.string().min(1),\n action: z.string().min(1),\n payload: z.record(z.string(), z.unknown()),\n});\n\n// --- Factory ---\n\ninterface CreateRestAppParams {\n config: RestConfig;\n engine: Engine;\n nileContext: NileContext<unknown>;\n serverName: string;\n runtime: ServerRuntime;\n}\n\n/**\n * Creates the Hono REST app with a single POST endpoint for all service interactions\n * and an optional GET /status health check.\n *\n * All service communication flows through POST {baseUrl}/services using\n * the intent field to discriminate between explore, execute, and schema operations.\n */\nexport function createRestApp(params: CreateRestAppParams): Hono {\n const { config, engine, nileContext, serverName, runtime } = params;\n const app = new Hono();\n\n const log = createDiagnosticsLog(\"REST\", {\n diagnostics: config.diagnostics,\n logger: nileContext.resources?.logger as\n | { info: (msg: string, data?: unknown) => void }\n | undefined,\n });\n\n // Apply CORS\n applyCorsConfig(app, config);\n\n // Apply rate limiting when a limiting header is configured\n applyRateLimiting(app, config, log);\n\n // Apply static file serving based on runtime\n applyStaticServing(app, config, runtime, log);\n\n // Single POST endpoint for all service interactions\n const servicesPath = `${config.baseUrl}/services`;\n\n app.post(servicesPath, async (c) => {\n const body = await c.req.json().catch(() => null);\n\n if (!body) {\n return c.json(\n {\n status: false,\n message: \"Invalid or missing JSON body\",\n data: {},\n } satisfies ExternalResponse,\n 400\n );\n }\n\n const parsed = externalRequestSchema.safeParse(body);\n if (!parsed.success) {\n return c.json(\n {\n status: false,\n message: \"Invalid request format\",\n data: { errors: parsed.error.issues },\n } satisfies ExternalResponse,\n 400\n );\n }\n\n const request = parsed.data as ExternalRequest;\n\n log(`${request.intent} -> ${request.service}.${request.action}`);\n\n const handler = intentHandlers[request.intent];\n // biome-ignore lint/suspicious/noExplicitAny: internal dispatch\n const response = await (handler as any)(engine, request, nileContext);\n\n const statusCode = response.status ? 200 : 400;\n return c.json(response, statusCode);\n });\n\n // Health check endpoint\n if (config.enableStatus) {\n app.get(\"/status\", (c) => {\n return c.json({\n status: true,\n message: `${serverName} is running`,\n data: {},\n } satisfies ExternalResponse);\n });\n }\n\n // 404 handler\n app.notFound((c) => {\n return c.json(\n {\n status: false,\n message: `Route not found. Use POST ${servicesPath} for all operations.`,\n data: {},\n } satisfies ExternalResponse,\n 404\n );\n });\n\n log(`REST interface ready at ${servicesPath}`);\n\n return app;\n}\n","import type { Context, Hono } from \"hono\";\nimport { cors } from \"hono/cors\";\nimport type { RestConfig } from \"@/rest/types\";\nimport type { CorsConfig, CorsOptions } from \"./types\";\n\n/**\n * Build default CORS options from REST config\n */\nexport const buildDefaultCorsOptions = (config: RestConfig): CorsOptions => {\n const getDefaultOrigin = (reqOrigin: string) => {\n if (config.allowedOrigins.length > 0) {\n return config.allowedOrigins.includes(reqOrigin ?? \"\") ? reqOrigin : \"\";\n }\n return \"*\";\n };\n\n return {\n origin: config.cors?.defaults?.origin ?? getDefaultOrigin,\n credentials: config.cors?.defaults?.credentials ?? true,\n allowHeaders: config.cors?.defaults?.allowHeaders ?? [\n \"Content-Type\",\n \"Authorization\",\n ],\n allowMethods: config.cors?.defaults?.allowMethods ?? [\n \"POST\",\n \"GET\",\n \"OPTIONS\",\n ],\n exposeHeaders: config.cors?.defaults?.exposeHeaders ?? [\"Content-Length\"],\n maxAge: config.cors?.defaults?.maxAge ?? 600,\n };\n};\n\n/**\n * Apply CORS configuration to a Hono app based on RestConfig\n */\nexport const applyCorsConfig = (app: Hono, config: RestConfig): void => {\n const corsEnabled = config.cors?.enabled ?? \"default\";\n\n if (corsEnabled === false) {\n return;\n }\n\n const defaultCorsOpts = buildDefaultCorsOptions(config);\n\n // Apply route-specific CORS rules FIRST (before global catch-all)\n const corsRules = config.cors?.addCors ?? [];\n for (const rule of corsRules) {\n applyRouteCorsRule(app, rule, defaultCorsOpts);\n }\n\n // Apply global CORS as fallback\n app.use(\"*\", cors(defaultCorsOpts as Parameters<typeof cors>[0]));\n};\n\n/**\n * Apply a single route-specific CORS rule\n */\nconst applyRouteCorsRule = (\n app: Hono,\n rule: NonNullable<CorsConfig[\"addCors\"]>[number],\n defaultOpts: CorsOptions\n): void => {\n if (rule.resolver) {\n applyResolverBasedCors(app, rule.path, rule.resolver, defaultOpts);\n } else if (rule.options) {\n applyStaticCors(app, rule.path, rule.options, defaultOpts);\n }\n};\n\n/**\n * Apply resolver-based CORS for a specific path\n */\nconst applyResolverBasedCors = (\n app: Hono,\n path: string,\n resolver: NonNullable<CorsConfig[\"addCors\"]>[number][\"resolver\"],\n defaultOpts: CorsOptions\n): void => {\n if (!resolver) {\n return;\n }\n\n app.use(path, (c, next) => {\n const reqOrigin = c.req.header(\"origin\") ?? \"\";\n const corsOpts = evaluateResolver(resolver, reqOrigin, c, defaultOpts);\n return cors(corsOpts as Parameters<typeof cors>[0])(c, next);\n });\n};\n\n/**\n * Apply static CORS options for a specific path\n */\nconst applyStaticCors = (\n app: Hono,\n path: string,\n options: CorsOptions,\n defaultOpts: CorsOptions\n): void => {\n app.use(\n path,\n cors({ ...defaultOpts, ...options } as Parameters<typeof cors>[0])\n );\n};\n\n/**\n * Evaluate CORS resolver and return appropriate options\n */\nconst evaluateResolver = (\n resolver: NonNullable<CorsConfig[\"addCors\"]>[number][\"resolver\"],\n origin: string,\n c: Context,\n defaultOpts: CorsOptions\n): CorsOptions => {\n if (!resolver) {\n return defaultOpts;\n }\n\n try {\n const result = resolver(origin, c);\n\n if (result === true) {\n return { ...defaultOpts, origin: origin || \"*\" };\n }\n\n if (result === false) {\n return { ...defaultOpts, origin: \"\" };\n }\n\n if (result && typeof result === \"object\") {\n return { ...defaultOpts, ...result };\n }\n\n return defaultOpts;\n } catch (error) {\n // Security: deny on resolver failure — never fall through to allow\n console.error(\"CORS resolver error:\", error);\n return { ...defaultOpts, origin: \"\" };\n }\n};\n","import { Ok, type Result } from \"slang-ts\";\nimport z from \"zod\";\nimport type { Engine } from \"@/engine/types\";\nimport type {\n ExternalRequest,\n ExternalResponse,\n NileContext,\n} from \"@/nile/types\";\n\n// --- Response mapping ---\n\n/**\n * Maps an internal Result to the external API response shape.\n * This is the single point where internal Result types cross the boundary\n * into the HTTP-facing ExternalResponse format.\n */\nexport function toExternalResponse(\n result: Result<unknown, string>,\n successMessage: string\n): ExternalResponse {\n if (result.isOk) {\n const value = result.value;\n const data =\n value !== null && typeof value === \"object\" && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : { result: value };\n\n return { status: true, message: successMessage, data };\n }\n\n return { status: false, message: result.error, data: {} };\n}\n\n// --- Intent handlers ---\n\n/**\n * Handles the \"explore\" intent for service/action discovery.\n * - service: \"*\", action: \"*\" -> list all services\n * - service: \"name\", action: \"*\" -> list actions for service\n * - service: \"name\", action: \"name\" -> action metadata\n */\nexport function handleExplore(\n engine: Engine,\n request: ExternalRequest\n): ExternalResponse {\n const { service, action } = request;\n\n if (service === \"*\") {\n return toExternalResponse(engine.getServices(), \"Available services\");\n }\n\n if (action === \"*\") {\n return toExternalResponse(\n engine.getServiceActions(service),\n `Actions for '${service}'`\n );\n }\n\n const actionResult = engine.getAction(service, action);\n if (actionResult.isErr) {\n return toExternalResponse(actionResult, \"\");\n }\n\n const act = actionResult.value;\n return toExternalResponse(\n Ok({\n name: act.name,\n description: act.description,\n isProtected: act.isProtected ?? false,\n accessControl: act.accessControl,\n hooks: act.hooks\n ? { before: act.hooks.before ?? [], after: act.hooks.after ?? [] }\n : null,\n meta: act.meta ?? null,\n }),\n `Details for '${service}.${action}'`\n );\n}\n\n/**\n * Handles the \"execute\" intent by running an action through the engine pipeline.\n */\nexport async function handleExecute(\n engine: Engine,\n request: ExternalRequest,\n nileContext: NileContext<unknown>\n): Promise<ExternalResponse> {\n const { service, action, payload } = request;\n\n if (service === \"*\" || action === \"*\") {\n return {\n status: false,\n message:\n \"Execute intent requires specific service and action, wildcards not allowed\",\n data: {},\n };\n }\n\n const result = await engine.executeAction(\n service,\n action,\n payload,\n nileContext\n );\n\n return toExternalResponse(result, `Action '${service}.${action}' executed`);\n}\n\n/**\n * Handles the \"schema\" intent for Zod-to-JSON-Schema export.\n * - service: \"*\", action: \"*\" -> all schemas across all services\n * - service: \"name\", action: \"*\" -> all schemas in a service\n * - service: \"name\", action: \"name\" -> single action schema\n */\nexport function handleSchema(\n engine: Engine,\n request: ExternalRequest\n): ExternalResponse {\n const { service, action } = request;\n\n if (service === \"*\") {\n const servicesResult = engine.getServices();\n if (servicesResult.isErr) {\n return toExternalResponse(servicesResult, \"\");\n }\n\n const schemas: Record<string, unknown> = {};\n for (const svc of servicesResult.value) {\n const actionsResult = engine.getServiceActions(svc.name);\n if (actionsResult.isErr) {\n continue;\n }\n\n schemas[svc.name] = buildServiceSchemas(\n engine,\n svc.name,\n actionsResult.value.map((a) => a.name)\n );\n }\n\n return toExternalResponse(Ok(schemas), \"All service schemas\");\n }\n\n if (action === \"*\") {\n const actionsResult = engine.getServiceActions(service);\n if (actionsResult.isErr) {\n return toExternalResponse(actionsResult, \"\");\n }\n\n const schemas = buildServiceSchemas(\n engine,\n service,\n actionsResult.value.map((a) => a.name)\n );\n return toExternalResponse(Ok(schemas), `Schemas for '${service}'`);\n }\n\n const actionResult = engine.getAction(service, action);\n if (actionResult.isErr) {\n return toExternalResponse(actionResult, \"\");\n }\n\n const schema = extractActionSchema(actionResult.value);\n return toExternalResponse(\n Ok({ [action]: schema }),\n `Schema for '${service}.${action}'`\n );\n}\n\n/**\n * Builds a map of action schemas for a service\n */\nfunction buildServiceSchemas(\n engine: Engine,\n serviceName: string,\n actionNames: string[]\n): Record<string, unknown> {\n const schemas: Record<string, unknown> = {};\n\n for (const actionName of actionNames) {\n const actionResult = engine.getAction(serviceName, actionName);\n if (actionResult.isErr) {\n continue;\n }\n schemas[actionName] = extractActionSchema(actionResult.value);\n }\n\n return schemas;\n}\n\n/**\n * Extracts JSON schema from an action's zod validation, returns null on failure\n */\nfunction extractActionSchema(action: {\n validation?: import(\"zod\").ZodType | null;\n}): unknown {\n const schema = action.validation;\n if (!schema) {\n return null;\n }\n\n const { err, result } = safeTrySync(() =>\n z.toJSONSchema(schema, { unrepresentable: \"any\" })\n );\n\n return err ? null : result;\n}\n\n/**\n * Synchronous try-catch wrapper for simple operations.\n * Unlike slang-ts safeTry (always async), this is for sync-only code paths.\n */\nfunction safeTrySync<T>(fn: () => T): { err: unknown; result: T | null } {\n try {\n return { err: null, result: fn() };\n } catch (error) {\n return { err: error, result: null };\n }\n}\n\n// --- Intent dispatch ---\n\n/** Object lookup for intent handlers — cleaner than switch/if-else */\nexport const intentHandlers: Record<\n ExternalRequest[\"intent\"],\n (\n engine: Engine,\n request: ExternalRequest,\n nileContext: NileContext<unknown>\n ) => ExternalResponse | Promise<ExternalResponse>\n> = {\n explore: (engine, request) => handleExplore(engine, request),\n execute: (engine, request, nileContext) =>\n handleExecute(engine, request, nileContext),\n schema: (engine, request) => handleSchema(engine, request),\n};\n","import type { Hono } from \"hono\";\nimport { rateLimiter } from \"hono-rate-limiter\";\nimport { safeTry } from \"slang-ts\";\nimport type { ServerRuntime } from \"@/nile/types\";\nimport type { RestConfig } from \"./types\";\n\nconst ASSETS_REGEX = /^\\/assets\\//;\nconst DEFAULT_RATE_LIMIT_WINDOW_MS = 15 * 60 * 1000; // 15 minutes\nconst DEFAULT_RATE_LIMIT_MAX = 100;\nconst UNKNOWN_CLIENT_KEY = \"__unknown_client__\";\n\n/**\n * Applies rate limiting middleware when a limiting header is configured.\n * Extracts the client key from the configured request header for per-client tracking.\n * Falls back to a shared key when the header is missing (graceful degradation).\n */\nexport function applyRateLimiting(\n app: Hono,\n config: RestConfig,\n log: (msg: string, data?: unknown) => void\n): void {\n if (!config.rateLimiting?.limitingHeader) {\n return;\n }\n\n const { rateLimiting } = config;\n\n app.use(\n rateLimiter({\n windowMs: rateLimiting.windowMs ?? DEFAULT_RATE_LIMIT_WINDOW_MS,\n limit: rateLimiting.limit ?? DEFAULT_RATE_LIMIT_MAX,\n standardHeaders: rateLimiting.standardHeaders ?? true,\n keyGenerator: (c) => {\n const key = c.req.header(rateLimiting.limitingHeader);\n if (!key) {\n log(\n `Rate limiting header '${rateLimiting.limitingHeader}' missing from request`\n );\n return UNKNOWN_CLIENT_KEY;\n }\n return key;\n },\n store: rateLimiting.store ?? undefined,\n })\n );\n\n log(\n `Rate limiting enabled: ${rateLimiting.limit ?? DEFAULT_RATE_LIMIT_MAX} requests per ${rateLimiting.windowMs ?? DEFAULT_RATE_LIMIT_WINDOW_MS}ms window`\n );\n}\n\n/**\n * Applies static file serving from ./assets at /assets/*.\n * Uses dynamic import to load the runtime-specific serveStatic adapter,\n * avoiding issues with Bun globals in non-Bun environments (e.g. vitest).\n * Import errors are caught gracefully — static serving is skipped if the adapter fails to load.\n */\nexport function applyStaticServing(\n app: Hono,\n config: RestConfig,\n runtime: ServerRuntime,\n log: (msg: string, data?: unknown) => void\n): void {\n if (!config.enableStatic) {\n return;\n }\n\n if (runtime !== \"bun\") {\n log(`Static file serving not yet supported for runtime: ${runtime}`);\n return;\n }\n\n // Lazy-load the bun serveStatic adapter to avoid referencing Bun globals at import time\n let cachedHandler:\n | ((c: never, next: never) => Promise<Response | undefined>)\n | null = null;\n let importFailed = false;\n\n app.use(\"/assets/*\", async (c, next) => {\n if (importFailed) {\n return next();\n }\n\n if (!cachedHandler) {\n const importResult = await safeTry(async () => {\n const mod = await import(\"hono/bun\");\n return mod.serveStatic({\n root: \"./assets\",\n rewriteRequestPath: (path: string) => path.replace(ASSETS_REGEX, \"\"),\n });\n });\n\n if (importResult.isErr) {\n log(\"Failed to load static file adapter\", importResult.error);\n importFailed = true;\n return next();\n }\n\n cachedHandler = importResult.value as unknown as typeof cachedHandler;\n }\n\n if (cachedHandler) {\n return cachedHandler(c as never, next as never);\n }\n });\n\n log(\"Static file serving enabled at /assets/*\");\n}\n","import type { BaseContext, NileContext, Resources, Sessions } from \"./types\";\n\ninterface CreateNileContextParams<TDB = unknown> {\n interfaceContext?: BaseContext;\n resources?: Resources<TDB>;\n}\n\n/**\n * Creates a new Nile context with an internal key-value store.\n * The context carries interface-specific data (REST, WebSocket, RPC),\n * hook execution context, and provides get/set methods for storing arbitrary values.\n *\n * Sessions are instance-scoped — each NileContext owns its own session store,\n * so multiple server instances don't share authentication state.\n *\n * @param params - Optional configuration including interface adapters and shared resources\n * @returns A fully initialized NileContext\n */\nexport function createNileContext<TDB = unknown>(\n params?: CreateNileContextParams<TDB>\n): NileContext<TDB> {\n const store = new Map<string, unknown>();\n const interfaceContext = params?.interfaceContext;\n\n /** Instance-scoped session store — not shared across server instances */\n const sessions: Sessions = {};\n\n const context: NileContext<TDB> = {\n rest: interfaceContext?.rest,\n ws: interfaceContext?.ws,\n rpc: interfaceContext?.rpc,\n resources: params?.resources,\n sessions,\n _store: store,\n\n get<T = unknown>(key: string): T | undefined {\n return store.get(key) as T | undefined;\n },\n\n set<T = unknown>(key: string, value: T): void {\n store.set(key, value);\n },\n\n getSession(name: keyof Sessions) {\n return sessions[name];\n },\n\n setSession(name: keyof Sessions, data: Record<string, unknown>) {\n sessions[name] = data;\n },\n\n hookContext: {\n actionName: \"\",\n input: null,\n state: {},\n log: { before: [], after: [] },\n },\n\n updateHookState(key: string, value: unknown) {\n context.hookContext.state[key] = value;\n },\n\n addHookLog(\n phase: \"before\" | \"after\",\n logEntry: {\n name: string;\n input: unknown;\n output: unknown;\n passed: boolean;\n }\n ) {\n context.hookContext.log[phase].push(logEntry);\n },\n\n setHookError(error: string) {\n context.hookContext.error = error;\n },\n\n setHookOutput(output: unknown) {\n context.hookContext.output = output;\n },\n\n resetHookContext(actionName: string, input: unknown) {\n context.hookContext = {\n actionName,\n input,\n state: {},\n log: { before: [], after: [] },\n };\n },\n };\n\n return context;\n}\n"],"mappings":"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","names":["match","year","start","end","safeTry","Err","Ok","result","Err","Ok","safeTry","Ok","Err","z","Ok","safeTry","z","safeTry"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nilejs/nile",
3
- "version": "0.0.2",
3
+ "version": "0.0.4",
4
4
  "type": "module",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.js",