veryfront 0.0.65 → 0.0.66
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/dist/ai/index.js +6 -6
- package/dist/ai/index.js.map +1 -1
- package/dist/ai/workflow.js +6 -6
- package/dist/ai/workflow.js.map +1 -1
- package/dist/cli.js +9 -9
- package/dist/components.js +7 -6
- package/dist/components.js.map +2 -2
- package/dist/config.js +6 -6
- package/dist/config.js.map +1 -1
- package/dist/data.js +6 -6
- package/dist/data.js.map +1 -1
- package/dist/index.js +6 -6
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
package/dist/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/_shims/deno-env.ts", "../../src/core/utils/runtime-guards.ts", "../../src/core/utils/logger/env.ts", "../../src/core/utils/logger/logger.ts", "../../src/core/utils/logger/index.ts", "../../src/core/utils/constants/build.ts", "../../src/core/utils/constants/cache.ts", "../../deno.json", "../../src/platform/compat/runtime.ts", "../../src/platform/compat/process.ts", "../../src/core/utils/version.ts", "../../src/core/utils/constants/cdn.ts", "../../src/core/utils/constants/env.ts", "../../src/core/utils/constants/hash.ts", "../../src/core/utils/constants/http.ts", "../../src/core/utils/constants/hmr.ts", "../../src/core/utils/constants/html.ts", "../../src/core/utils/constants/network.ts", "../../src/core/utils/constants/security.ts", "../../src/core/config/defaults.ts", "../../src/core/utils/constants/server.ts", "../../src/core/utils/constants/index.ts", "../../src/core/utils/paths.ts", "../../src/core/utils/hash-utils.ts", "../../src/core/utils/memoize.ts", "../../src/core/utils/path-utils.ts", "../../src/core/utils/format-utils.ts", "../../src/core/utils/bundle-manifest.ts", "../../src/core/utils/bundle-manifest-init.ts", "../../src/core/utils/feature-flags.ts", "../../src/core/utils/platform.ts", "../../src/core/utils/index.ts", "../../src/core/errors/veryfront-error.ts", "../../src/core/config/schema.ts", "../../src/core/config/loader.ts", "../../src/core/config/define-config.ts", "../../src/core/config/network-defaults.ts", "../../src/core/config/index.ts", "../../src/platform/adapters/deno.ts", "../../src/platform/adapters/shared-watcher.ts", "../../src/platform/adapters/node/filesystem-adapter.ts", "../../src/platform/adapters/node/environment-adapter.ts", "../../../node_modules/ws/lib/constants.js", "../../../node_modules/ws/lib/buffer-util.js", "../../../node_modules/ws/lib/limiter.js", "../../../node_modules/ws/lib/permessage-deflate.js", "../../../node_modules/ws/lib/validation.js", "../../../node_modules/ws/lib/receiver.js", "../../../node_modules/ws/lib/sender.js", "../../../node_modules/ws/lib/event-target.js", "../../../node_modules/ws/lib/extension.js", "../../../node_modules/ws/lib/websocket.js", "../../../node_modules/ws/lib/stream.js", "../../../node_modules/ws/lib/subprotocol.js", "../../../node_modules/ws/lib/websocket-server.js", "../../../node_modules/ws/wrapper.mjs", "../../src/platform/adapters/node/http-server.ts", "../../src/platform/adapters/node/websocket-adapter.ts", "../../src/platform/adapters/node/adapter.ts", "../../src/platform/adapters/node/index.ts", "../../src/platform/adapters/node.ts", "../../src/core/errors/types.ts", "../../src/core/errors/agent-errors.ts", "../../src/core/errors/build-errors.ts", "../../src/core/errors/runtime-errors.ts", "../../src/core/errors/system-errors.ts", "../../src/core/errors/error-handlers.ts", "../../src/core/errors/error-codes.ts", "../../src/core/errors/catalog/factory.ts", "../../src/core/errors/catalog/config-errors.ts", "../../src/core/errors/catalog/build-errors.ts", "../../src/core/errors/catalog/runtime-errors.ts", "../../src/core/errors/catalog/route-errors.ts", "../../src/core/errors/catalog/module-errors.ts", "../../src/core/errors/catalog/server-errors.ts", "../../src/core/errors/catalog/rsc-errors.ts", "../../src/core/errors/catalog/dev-errors.ts", "../../src/core/errors/catalog/deployment-errors.ts", "../../src/core/errors/catalog/general-errors.ts", "../../src/core/errors/catalog/index.ts", "../../src/core/errors/user-friendly/error-catalog.ts", "../../src/platform/compat/console/ansi.ts", "../../src/platform/compat/console/deno.ts", "../../src/platform/compat/console/node.ts", "../../src/platform/compat/console/index.ts", "../../src/core/errors/user-friendly/error-identifier.ts", "../../src/core/errors/user-friendly/error-formatter.ts", "../../src/core/errors/user-friendly/error-wrapper.ts", "../../src/core/errors/user-friendly/index.ts", "../../src/core/errors/index.ts", "../../src/platform/adapters/bun/filesystem-adapter.ts", "../../src/platform/adapters/bun/environment-adapter.ts", "../../src/platform/adapters/bun/websocket-adapter.ts", "../../src/platform/adapters/bun/http-server.ts", "../../src/platform/adapters/bun/adapter.ts", "../../src/platform/adapters/bun/index.ts", "../../src/platform/adapters/bun.ts", "../../src/platform/adapters/mock.ts", "../../src/platform/adapters/registry.ts", "../../src/platform/adapters/detect.ts", "../../src/index.ts", "../../src/react/components/index.ts", "../../src/react/components/AppWrapper.tsx", "../../src/react/components/LayoutComponent.tsx", "../../src/build/transforms/mdx/index.ts", "../../src/core/utils/lru-wrapper.ts", "../../src/core/utils/cache/stores/memory/lru-cache-adapter.ts", "../../src/core/utils/cache/stores/memory/lru-list-manager.ts", "../../src/core/utils/cache/eviction/eviction-manager.ts", "../../src/core/utils/cache/stores/memory/entry-manager.ts", "../../src/core/utils/cache/stores/memory/lru-node.ts", "../../src/build/transforms/mdx/esm-module-loader.ts", "../../src/core/utils/cache/keys/namespace.ts", "../../src/module-system/import-map/index.ts", "../../src/module-system/import-map/loader.ts", "../../src/module-system/import-map/default-import-map.ts", "../../src/module-system/import-map/resolver.ts", "../../src/module-system/import-map/transformer.ts", "../../src/module-system/import-map/merger.ts", "../../src/build/transforms/mdx/parser.ts", "../../src/build/transforms/mdx/module-loader/metadata-extractor.ts", "../../src/build/transforms/mdx/module-loader/string-parser.ts", "../../src/build/transforms/mdx/mdx-cache-adapter.ts", "../../src/react/components/ProviderComponent.tsx", "../../src/react/components/Head.tsx", "../../src/react/components/Link.tsx", "../../src/react/components/MDXProvider.tsx", "../../src/react/components/optimized-image/index.ts", "../../src/react/components/optimized-image/OptimizedImage.tsx", "../../src/react/components/optimized-image/helpers.ts", "../../src/react/components/optimized-image/SimpleOptimizedImage.tsx", "../../src/react/components/optimized-image/OptimizedBackgroundImage.tsx", "../../src/react/components/optimized-image/useOptimizedImage.ts", "../../src/react/components/optimized-image/utils.tsx", "../../src/data/index.ts", "../../src/data/data-fetcher.ts", "../../src/data/data-fetching-cache.ts", "../../src/data/server-data-fetcher.ts", "../../src/data/static-data-fetcher.ts", "../../src/data/static-paths-fetcher.ts", "../../src/data/helpers.ts", "../../src/routing/index.ts", "../../src/routing/matchers/index.ts", "../../src/routing/matchers/pattern-route-matcher.ts", "../../src/routing/matchers/route-parser.ts", "../../src/routing/matchers/route-matcher.ts", "../../src/routing/slug-mapper/index.ts", "../../src/routing/slug-mapper/path-candidate-generator.ts", "../../src/platform/compat/path-helper.ts", "../../src/routing/slug-mapper/dynamic-route-matcher.ts", "../../src/routing/slug-mapper/slug-normalizer.ts", "../../src/routing/client/index.ts", "../../src/routing/client/dom-utils.ts", "../../src/routing/client/navigation-handlers.ts", "../../src/routing/client/page-loader.ts", "../../src/routing/client/page-transition.ts", "../../src/security/client/html-sanitizer.ts", "../../src/routing/client/viewport-prefetch.ts", "../../src/routing/api/index.ts", "../../src/routing/api/handler.ts", "../../src/http/responses.ts", "../../src/security/index.ts", "../../src/security/http/base-handler.ts", "../../src/security/http/response/index.ts", "../../src/security/http/response/constants.ts", "../../src/security/http/response/builder.ts", "../../src/security/http/response/fluent-methods.ts", "../../src/security/http/cors/index.ts", "../../src/security/http/cors/headers.ts", "../../src/security/http/cors/validators.ts", "../../src/observability/index.ts", "../../src/observability/tracing/index.ts", "../../src/observability/tracing/manager.ts", "../../src/observability/tracing/config.ts", "../../src/observability/tracing/span-operations.ts", "../../src/observability/tracing/context-propagation.ts", "../../src/observability/tracing/span-names.ts", "../../src/observability/metrics/index.ts", "../../src/observability/metrics/manager.ts", "../../src/observability/metrics/config.ts", "../../src/observability/instruments/index.ts", "../../src/observability/instruments/instruments-factory.ts", "../../src/observability/instruments/build-instruments.ts", "../../src/observability/instruments/cache-instruments.ts", "../../src/observability/instruments/data-instruments.ts", "../../src/observability/instruments/http-instruments.ts", "../../src/observability/instruments/memory-instruments.ts", "../../src/observability/instruments/render-instruments.ts", "../../src/observability/instruments/rsc-instruments.ts", "../../src/observability/metrics/recorder.ts", "../../src/observability/auto-instrument/index.ts", "../../src/observability/auto-instrument/orchestrator.ts", "../../src/observability/auto-instrument/configurator.ts", "../../src/observability/auto-instrument/http-instrumentation.ts", "../../src/observability/auto-instrument/react-instrumentation.ts", "../../src/observability/auto-instrument/wrappers.ts", "../../src/security/http/cors/preflight.ts", "../../src/security/http/cors/constants.ts", "../../src/security/http/cors/middleware.ts", "../../src/security/http/response/security-handler.ts", "../../src/security/http/response/cache-handler.ts", "../../src/security/http/response/response-methods.ts", "../../src/security/http/response/static-helpers.ts", "../../src/security/input-validation/index.ts", "../../src/security/input-validation/types.ts", "../../src/core/constants/index.ts", "../../src/core/constants/priorities.ts", "../../src/core/constants/retry.ts", "../../src/core/constants/buffers.ts", "../../src/core/constants/limits.ts", "../../src/core/constants/metrics.ts", "../../src/core/constants/crypto.ts", "../../src/security/input-validation/errors.ts", "../../src/security/input-validation/limits.ts", "../../src/security/input-validation/parsers.ts", "../../src/security/input-validation/sanitizers.ts", "../../src/security/input-validation/schemas.ts", "../../src/security/input-validation/handler.ts", "../../src/security/http/handlers-index.ts", "../../src/security/http/auth.ts", "../../src/security/http/config.ts", "../../src/security/http/middleware/index.ts", "../../src/security/http/middleware/config-loader.ts", "../../src/security/http/middleware/cors-handler.ts", "../../src/security/http/middleware/etag.ts", "../../src/security/http/middleware/content-types.ts", "../../src/security/path-validation.ts", "../../src/security/secure-fs.ts", "../../src/routing/api/api-route-matcher.ts", "../../src/routing/api/module-loader/loader.ts", "../../src/routing/api/module-loader/esbuild-plugin.ts", "../../src/routing/api/module-loader/http-validator.ts", "../../src/routing/api/module-loader/security-config.ts", "../../src/platform/compat/fs.ts", "../../src/routing/api/route-discovery.ts", "../../src/core/utils/file-discovery.ts", "../../src/routing/api/route-executor.ts", "../../src/routing/api/context-builder.ts", "../../src/routing/api/method-validator.ts", "../../src/routing/api/error-handler.ts", "../../src/routing/api/responses.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Shim for Deno.env.get() to work in Node.js\n * This provides a proper function that reads from process.env\n */\n\n// Create a shim that matches Deno.env.get(key) signature\nconst denoEnvShim = {\n get(key: string): string | undefined {\n return process.env[key];\n },\n set(key: string, value: string): void {\n process.env[key] = value;\n },\n delete(key: string): void {\n delete process.env[key];\n },\n has(key: string): boolean {\n return key in process.env;\n },\n toObject(): Record<string, string> {\n return { ...process.env } as Record<string, string>;\n },\n};\n\n// Assign to globalThis.Deno if it doesn't exist\nif (typeof globalThis.Deno === \"undefined\") {\n (globalThis as any).Deno = {\n env: denoEnvShim,\n cwd: () => process.cwd(),\n };\n} else if (typeof (globalThis as any).Deno.env === \"undefined\") {\n (globalThis as any).Deno.env = denoEnvShim;\n}\n\nexport { denoEnvShim };\n", "export interface GlobalWithDeno {\n Deno?: {\n env: {\n get(key: string): string | undefined;\n };\n };\n}\n\nexport interface GlobalWithProcess {\n process?: {\n env: Record<string, string | undefined>;\n version?: string;\n versions?: Record<string, string>;\n };\n}\n\nexport interface GlobalWithBun {\n Bun?: {\n version: string;\n };\n}\n\nexport function hasDenoRuntime(global: unknown): global is GlobalWithDeno {\n return (\n typeof global === \"object\" &&\n global !== null &&\n \"Deno\" in global &&\n typeof (global as GlobalWithDeno).Deno?.env?.get === \"function\"\n );\n}\n\nexport function hasNodeProcess(global: unknown): global is GlobalWithProcess {\n return (\n typeof global === \"object\" &&\n global !== null &&\n \"process\" in global &&\n typeof (global as GlobalWithProcess).process?.env === \"object\"\n );\n}\n\nexport function hasBunRuntime(global: unknown): global is GlobalWithBun {\n return (\n typeof global === \"object\" &&\n global !== null &&\n \"Bun\" in global &&\n typeof (global as GlobalWithBun).Bun !== \"undefined\"\n );\n}\n", "import type { GlobalWithDeno, GlobalWithProcess } from \"../runtime-guards.ts\";\nimport { hasDenoRuntime, hasNodeProcess } from \"../runtime-guards.ts\";\n\nexport function getEnvironmentVariable(name: string): string | undefined {\n try {\n if (typeof Deno !== \"undefined\" && hasDenoRuntime(globalThis)) {\n const value = (globalThis as GlobalWithDeno).Deno?.env.get(name);\n return value === \"\" ? undefined : value;\n }\n if (hasNodeProcess(globalThis)) {\n const value = (globalThis as GlobalWithProcess).process?.env[name];\n return value === \"\" ? undefined : value;\n }\n } catch {\n return undefined;\n }\n return undefined;\n}\n\nexport function isTestEnvironment(): boolean {\n return getEnvironmentVariable(\"NODE_ENV\") === \"test\";\n}\n\nexport function isProductionEnvironment(): boolean {\n return getEnvironmentVariable(\"NODE_ENV\") === \"production\";\n}\n\nexport function isDevelopmentEnvironment(): boolean {\n const env = getEnvironmentVariable(\"NODE_ENV\");\n return env === \"development\" || env === undefined;\n}\n", "import { getEnvironmentVariable } from \"./env.ts\";\n\nexport enum LogLevel {\n DEBUG = 0,\n INFO = 1,\n WARN = 2,\n ERROR = 3,\n}\n\nexport interface Logger {\n debug(message: string, ...args: unknown[]): void;\n info(message: string, ...args: unknown[]): void;\n warn(message: string, ...args: unknown[]): void;\n error(message: string, ...args: unknown[]): void;\n time<T>(label: string, fn: () => Promise<T>): Promise<T>;\n}\n\nconst originalConsole = {\n debug: console.debug,\n log: console.log,\n warn: console.warn,\n error: console.error,\n};\n\nlet cachedLogLevel: LogLevel | undefined;\n\nfunction resolveLogLevel(force = false): LogLevel {\n if (force || cachedLogLevel === undefined) {\n cachedLogLevel = getDefaultLevel();\n }\n return cachedLogLevel;\n}\n\nclass ConsoleLogger implements Logger {\n constructor(\n private prefix: string,\n private level: LogLevel = resolveLogLevel(),\n ) {}\n\n setLevel(level: LogLevel): void {\n this.level = level;\n }\n\n getLevel(): LogLevel {\n return this.level;\n }\n\n debug(message: string, ...args: unknown[]): void {\n if (this.level <= LogLevel.DEBUG) {\n console.debug(`[${this.prefix}] DEBUG: ${message}`, ...args);\n }\n }\n\n info(message: string, ...args: unknown[]): void {\n if (this.level <= LogLevel.INFO) {\n console.log(`[${this.prefix}] ${message}`, ...args);\n }\n }\n\n warn(message: string, ...args: unknown[]): void {\n if (this.level <= LogLevel.WARN) {\n console.warn(`[${this.prefix}] WARN: ${message}`, ...args);\n }\n }\n\n error(message: string, ...args: unknown[]): void {\n if (this.level <= LogLevel.ERROR) {\n console.error(`[${this.prefix}] ERROR: ${message}`, ...args);\n }\n }\n\n async time<T>(label: string, fn: () => Promise<T>): Promise<T> {\n const start = performance.now();\n try {\n const result = await fn();\n const end = performance.now();\n this.debug(`${label} completed in ${(end - start).toFixed(2)}ms`);\n return result;\n } catch (error) {\n const end = performance.now();\n this.error(`${label} failed after ${(end - start).toFixed(2)}ms`, error);\n throw error;\n }\n }\n}\n\nfunction parseLogLevel(levelString: string | undefined): LogLevel | undefined {\n if (!levelString) return undefined;\n const upper = levelString.toUpperCase();\n switch (upper) {\n case \"DEBUG\":\n return LogLevel.DEBUG;\n case \"WARN\":\n return LogLevel.WARN;\n case \"ERROR\":\n return LogLevel.ERROR;\n case \"INFO\":\n return LogLevel.INFO;\n default:\n return undefined;\n }\n}\n\nconst getDefaultLevel = (): LogLevel => {\n const envLevel = getEnvironmentVariable(\"LOG_LEVEL\");\n const parsedLevel = parseLogLevel(envLevel);\n if (parsedLevel !== undefined) return parsedLevel;\n\n const debugFlag = getEnvironmentVariable(\"VERYFRONT_DEBUG\");\n if (debugFlag === \"1\" || debugFlag === \"true\") return LogLevel.DEBUG;\n\n return LogLevel.INFO;\n};\n\nconst trackedLoggers = new Set<ConsoleLogger>();\n\nfunction createLogger(prefix: string): ConsoleLogger {\n const logger = new ConsoleLogger(prefix);\n trackedLoggers.add(logger);\n return logger;\n}\n\nexport const cliLogger = createLogger(\"CLI\");\nexport const serverLogger = createLogger(\"SERVER\");\nexport const rendererLogger = createLogger(\"RENDERER\");\nexport const bundlerLogger = createLogger(\"BUNDLER\");\nexport const agentLogger = createLogger(\"AGENT\");\n\nexport const logger = createLogger(\"VERYFRONT\");\n\ntype LoggerResetOptions = {\n restoreConsole?: boolean;\n};\n\nexport function __loggerResetForTests(options: LoggerResetOptions = {}): void {\n const updatedLevel = resolveLogLevel(true);\n for (const instance of trackedLoggers) {\n instance.setLevel(updatedLevel);\n }\n\n if (options.restoreConsole) {\n console.debug = originalConsole.debug;\n console.log = originalConsole.log;\n console.warn = originalConsole.warn;\n console.error = originalConsole.error;\n }\n}\n", "export * from \"./logger.ts\";\nexport * from \"./env.ts\";\n", "export const DEFAULT_BUILD_CONCURRENCY = 4;\n\nexport const IMAGE_OPTIMIZATION = {\n DEFAULT_SIZES: [640, 750, 828, 1080, 1200, 1920, 2048, 3840],\n DEFAULT_QUALITY: 80,\n} as const;\n", "export const SECONDS_PER_MINUTE = 60;\n\nexport const MINUTES_PER_HOUR = 60;\n\nexport const HOURS_PER_DAY = 24;\n\nexport const MS_PER_SECOND = 1000;\n\nexport const DEFAULT_LRU_MAX_ENTRIES = 100;\n\nexport const COMPONENT_LOADER_MAX_ENTRIES = 100;\nexport const COMPONENT_LOADER_TTL_MS = 10 * SECONDS_PER_MINUTE * MS_PER_SECOND;\n\nexport const MDX_RENDERER_MAX_ENTRIES = 200;\nexport const MDX_RENDERER_TTL_MS = 10 * SECONDS_PER_MINUTE * MS_PER_SECOND;\n\nexport const RENDERER_CORE_MAX_ENTRIES = 100;\nexport const RENDERER_CORE_TTL_MS = 5 * SECONDS_PER_MINUTE * MS_PER_SECOND;\n\nexport const TSX_LAYOUT_MAX_ENTRIES = 50;\nexport const TSX_LAYOUT_TTL_MS = 10 * SECONDS_PER_MINUTE * MS_PER_SECOND;\n\nexport const DATA_FETCHING_MAX_ENTRIES = 200;\nexport const DATA_FETCHING_TTL_MS = 10 * SECONDS_PER_MINUTE * MS_PER_SECOND;\n\nexport const MDX_CACHE_TTL_PRODUCTION_MS = HOURS_PER_DAY * MINUTES_PER_HOUR * SECONDS_PER_MINUTE *\n MS_PER_SECOND;\nexport const MDX_CACHE_TTL_DEVELOPMENT_MS = 5 * SECONDS_PER_MINUTE * MS_PER_SECOND;\n\nexport const BUNDLE_CACHE_TTL_PRODUCTION_MS = HOURS_PER_DAY * MINUTES_PER_HOUR *\n SECONDS_PER_MINUTE * MS_PER_SECOND;\nexport const BUNDLE_CACHE_TTL_DEVELOPMENT_MS = 5 * SECONDS_PER_MINUTE * MS_PER_SECOND;\n\nexport const BUNDLE_MANIFEST_PROD_TTL_MS = 7 * HOURS_PER_DAY * MINUTES_PER_HOUR *\n SECONDS_PER_MINUTE * MS_PER_SECOND;\nexport const BUNDLE_MANIFEST_DEV_TTL_MS = MINUTES_PER_HOUR * SECONDS_PER_MINUTE * MS_PER_SECOND;\n\nexport const RSC_MANIFEST_CACHE_TTL_MS = 5000;\n\nexport const SERVER_ACTION_DEFAULT_TTL_SEC = MINUTES_PER_HOUR * SECONDS_PER_MINUTE;\n\nexport const DENO_KV_SAFE_SIZE_LIMIT_BYTES = 64_000;\n\nexport const HTTP_CACHE_SHORT_MAX_AGE_SEC = 60;\nexport const HTTP_CACHE_MEDIUM_MAX_AGE_SEC = 3600;\nexport const HTTP_CACHE_LONG_MAX_AGE_SEC = 31536000;\n\nexport const ONE_DAY_MS = HOURS_PER_DAY * MINUTES_PER_HOUR * SECONDS_PER_MINUTE * MS_PER_SECOND;\n\nexport const CACHE_CLEANUP_INTERVAL_MS = 60000;\n\nexport const LRU_DEFAULT_MAX_ENTRIES = 1000;\n\nexport const LRU_DEFAULT_MAX_SIZE_BYTES = 50 * 1024 * 1024;\n\nexport const CLEANUP_INTERVAL_MULTIPLIER = 2;\n", "{\n \"name\": \"veryfront\",\n \"version\": \"0.0.65\",\n \"nodeModulesDir\": \"auto\",\n \"exclude\": [\n \"npm/\",\n \"dist/\",\n \"coverage/\",\n \"scripts/\",\n \"examples/\",\n \"src/cli/templates/files/\",\n \"src/cli/templates/integrations/\"\n ],\n \"exports\": {\n \".\": \"./src/index.ts\",\n \"./cli\": \"./src/cli/main.ts\",\n \"./server\": \"./src/server/index.ts\",\n \"./middleware\": \"./src/middleware/index.ts\",\n \"./components\": \"./src/react/components/index.ts\",\n \"./data\": \"./src/data/index.ts\",\n \"./config\": \"./src/core/config/index.ts\",\n \"./platform\": \"./src/platform/index.ts\",\n \"./ai\": \"./src/ai/index.ts\",\n \"./ai/client\": \"./src/ai/client.ts\",\n \"./ai/react\": \"./src/ai/react/index.ts\",\n \"./ai/primitives\": \"./src/ai/react/primitives/index.ts\",\n \"./ai/components\": \"./src/ai/react/components/index.ts\",\n \"./ai/production\": \"./src/ai/production/index.ts\",\n \"./ai/dev\": \"./src/ai/dev/index.ts\",\n \"./ai/workflow\": \"./src/ai/workflow/index.ts\",\n \"./ai/workflow/react\": \"./src/ai/workflow/react/index.ts\",\n \"./oauth\": \"./src/core/oauth/index.ts\",\n \"./oauth/providers\": \"./src/core/oauth/providers/index.ts\",\n \"./oauth/handlers\": \"./src/core/oauth/handlers/index.ts\",\n \"./oauth/token-store\": \"./src/core/oauth/token-store/index.ts\"\n },\n \"imports\": {\n \"@veryfront\": \"./src/index.ts\",\n \"@veryfront/\": \"./src/\",\n \"@veryfront/ai\": \"./src/ai/index.ts\",\n \"@veryfront/ai/\": \"./src/ai/\",\n \"@veryfront/platform\": \"./src/platform/index.ts\",\n \"@veryfront/platform/\": \"./src/platform/\",\n \"@veryfront/types\": \"./src/core/types/index.ts\",\n \"@veryfront/types/\": \"./src/core/types/\",\n \"@veryfront/utils\": \"./src/core/utils/index.ts\",\n \"@veryfront/utils/\": \"./src/core/utils/\",\n \"@veryfront/middleware\": \"./src/middleware/index.ts\",\n \"@veryfront/middleware/\": \"./src/middleware/\",\n \"@veryfront/errors\": \"./src/core/errors/index.ts\",\n \"@veryfront/errors/\": \"./src/core/errors/\",\n \"@veryfront/config\": \"./src/core/config/index.ts\",\n \"@veryfront/config/\": \"./src/core/config/\",\n \"@veryfront/observability\": \"./src/observability/index.ts\",\n \"@veryfront/observability/\": \"./src/observability/\",\n \"@veryfront/routing\": \"./src/routing/index.ts\",\n \"@veryfront/routing/\": \"./src/routing/\",\n \"@veryfront/transforms\": \"./src/build/transforms/index.ts\",\n \"@veryfront/transforms/\": \"./src/build/transforms/\",\n \"@veryfront/data\": \"./src/data/index.ts\",\n \"@veryfront/data/\": \"./src/data/\",\n \"@veryfront/security\": \"./src/security/index.ts\",\n \"@veryfront/security/\": \"./src/security/\",\n \"@veryfront/components\": \"./src/react/components/index.ts\",\n \"@veryfront/react\": \"./src/react/index.ts\",\n \"@veryfront/react/\": \"./src/react/\",\n \"@veryfront/html\": \"./src/html/index.ts\",\n \"@veryfront/html/\": \"./src/html/\",\n \"@veryfront/rendering\": \"./src/rendering/index.ts\",\n \"@veryfront/rendering/\": \"./src/rendering/\",\n \"@veryfront/build\": \"./src/build/index.ts\",\n \"@veryfront/build/\": \"./src/build/\",\n \"@veryfront/server\": \"./src/server/index.ts\",\n \"@veryfront/server/\": \"./src/server/\",\n \"@veryfront/modules\": \"./src/module-system/index.ts\",\n \"@veryfront/modules/\": \"./src/module-system/\",\n \"@veryfront/compat/console\": \"./src/platform/compat/console/index.ts\",\n \"@veryfront/compat/\": \"./src/platform/compat/\",\n \"@veryfront/oauth\": \"./src/core/oauth/index.ts\",\n \"@veryfront/oauth/\": \"./src/core/oauth/\",\n \"std/\": \"https://deno.land/std@0.220.0/\",\n \"@std/path\": \"https://deno.land/std@0.220.0/path/mod.ts\",\n \"@std/testing/bdd.ts\": \"https://deno.land/std@0.220.0/testing/bdd.ts\",\n \"@std/expect\": \"https://deno.land/std@0.220.0/expect/mod.ts\",\n \"csstype\": \"https://esm.sh/csstype@3.2.3\",\n \"@types/react\": \"https://esm.sh/@types/react@18.3.27?deps=csstype@3.2.3\",\n \"@types/react-dom\": \"https://esm.sh/@types/react-dom@18.3.7?deps=csstype@3.2.3\",\n \"react\": \"https://esm.sh/react@18.3.1\",\n \"react-dom\": \"https://esm.sh/react-dom@18.3.1\",\n \"react-dom/server\": \"https://esm.sh/react-dom@18.3.1/server\",\n \"react-dom/client\": \"https://esm.sh/react-dom@18.3.1/client\",\n \"react/jsx-runtime\": \"https://esm.sh/react@18.3.1/jsx-runtime\",\n \"react/jsx-dev-runtime\": \"https://esm.sh/react@18.3.1/jsx-dev-runtime\",\n \"@mdx-js/mdx\": \"npm:@mdx-js/mdx@3.0.0\",\n \"@mdx-js/react\": \"npm:@mdx-js/react@3.0.0\",\n \"unist-util-visit\": \"npm:unist-util-visit@5.0.0\",\n \"mdast-util-to-string\": \"npm:mdast-util-to-string@4.0.0\",\n \"github-slugger\": \"npm:github-slugger@2.0.0\",\n \"remark-gfm\": \"npm:remark-gfm@4.0.1\",\n \"remark-frontmatter\": \"npm:remark-frontmatter@5.0.0\",\n \"rehype-highlight\": \"npm:rehype-highlight@7.0.2\",\n \"rehype-slug\": \"npm:rehype-slug@6.0.0\",\n \"esbuild\": \"https://deno.land/x/esbuild@v0.20.1/wasm.js\",\n \"esbuild/mod.js\": \"https://deno.land/x/esbuild@v0.20.1/mod.js\",\n \"es-module-lexer\": \"npm:es-module-lexer@1.5.0\",\n \"zod\": \"npm:zod@3.23.8\",\n \"mime-types\": \"npm:mime-types@2.1.35\",\n \"mdast\": \"npm:@types/mdast@4.0.3\",\n \"hast\": \"npm:@types/hast@3.0.3\",\n \"unist\": \"npm:@types/unist@3.0.2\",\n \"unified\": \"npm:unified@11.0.5\",\n \"ai\": \"https://esm.sh/ai@5.0.108?deps=react@18.3.1,react-dom@18.3.1\",\n \"ai/react\": \"https://esm.sh/@ai-sdk/react@2.0.109?deps=react@18.3.1,react-dom@18.3.1\",\n \"@ai-sdk/react\": \"https://esm.sh/@ai-sdk/react@2.0.109?deps=react@18.3.1,react-dom@18.3.1\",\n \"@ai-sdk/openai\": \"https://esm.sh/@ai-sdk/openai@2.0.80\",\n \"@ai-sdk/anthropic\": \"https://esm.sh/@ai-sdk/anthropic@2.0.54\",\n \"unocss\": \"https://esm.sh/unocss@0.59.0\",\n \"@unocss/core\": \"https://esm.sh/@unocss/core@0.59.0\",\n \"@unocss/preset-wind\": \"https://esm.sh/@unocss/preset-wind@0.59.0\",\n \"redis\": \"npm:redis\",\n \"pg\": \"npm:pg\",\n \"@opentelemetry/api\": \"npm:@opentelemetry/api@1\",\n \"@opentelemetry/core\": \"npm:@opentelemetry/core@1\"\n },\n \"compilerOptions\": {\n \"jsx\": \"react-jsx\",\n \"jsxImportSource\": \"react\",\n \"strict\": true,\n \"noImplicitAny\": true,\n \"noUncheckedIndexedAccess\": true,\n \"types\": [],\n \"lib\": [\n \"deno.window\",\n \"dom\",\n \"dom.iterable\",\n \"dom.asynciterable\",\n \"deno.ns\"\n ]\n },\n \"tasks\": {\n \"setup\": \"deno run --allow-all scripts/setup.ts\",\n \"dev\": \"deno run --allow-all --no-lock --unstable-net --unstable-worker-options src/cli/main.ts dev\",\n \"build\": \"deno compile --allow-all --output ../../bin/veryfront src/cli/main.ts\",\n \"build:npm\": \"deno run -A scripts/build-npm.ts\",\n \"release\": \"deno run -A scripts/release.ts\",\n \"test\": \"DENO_JOBS=1 deno test --parallel --fail-fast --allow-all --unstable-worker-options --unstable-net\",\n \"test:unit\": \"DENO_JOBS=1 deno test --parallel --allow-all --v8-flags=--max-old-space-size=8192 --ignore=tests --unstable-worker-options --unstable-net\",\n \"test:integration\": \"DENO_JOBS=1 deno test --parallel --fail-fast --allow-all tests --unstable-worker-options --unstable-net\",\n \"test:coverage\": \"rm -rf coverage && DENO_JOBS=1 deno test --parallel --fail-fast --allow-all --coverage=coverage --unstable-worker-options --unstable-net || exit 1\",\n \"test:coverage:unit\": \"rm -rf coverage && DENO_JOBS=1 deno test --parallel --fail-fast --allow-all --coverage=coverage --ignore=tests --unstable-worker-options --unstable-net || exit 1\",\n \"test:coverage:integration\": \"rm -rf coverage && DENO_JOBS=1 deno test --parallel --fail-fast --allow-all --coverage=coverage tests --unstable-worker-options --unstable-net || exit 1\",\n \"coverage:report\": \"deno coverage coverage --include=src/ --exclude=tests --exclude=src/**/*_test.ts --exclude=src/**/*_test.tsx --exclude=src/**/*.test.ts --exclude=src/**/*.test.tsx --lcov > coverage/lcov.info && deno run --allow-read scripts/check-coverage.ts 80\",\n \"coverage:html\": \"deno coverage coverage --include=src/ --exclude=tests --exclude=src/**/*_test.ts --exclude=src/**/*_test.tsx --exclude=src/**/*.test.ts --exclude=src/**/*.test.tsx --html\",\n \"lint\": \"DENO_NO_PACKAGE_JSON=1 deno lint src/\",\n \"fmt\": \"deno fmt src/\",\n \"typecheck\": \"deno check src/index.ts src/cli/main.ts src/server/index.ts src/routing/api/index.ts src/rendering/index.ts src/platform/index.ts src/platform/adapters/index.ts src/build/index.ts src/build/production-build/index.ts src/build/transforms/index.ts src/core/config/index.ts src/core/utils/index.ts src/data/index.ts src/security/index.ts src/middleware/index.ts src/server/handlers/dev/index.ts src/server/handlers/request/api/index.ts src/rendering/cache/index.ts src/rendering/cache/stores/index.ts src/rendering/rsc/actions/index.ts src/html/index.ts src/module-system/index.ts\",\n \"docs:check-links\": \"deno run -A scripts/check-doc-links.ts\",\n \"lint:ban-console\": \"deno run --allow-read scripts/ban-console.ts\",\n \"lint:ban-deep-imports\": \"deno run --allow-read scripts/ban-deep-imports.ts\",\n \"lint:ban-internal-root-imports\": \"deno run --allow-read scripts/ban-internal-root-imports.ts\",\n \"lint:check-awaits\": \"deno run --allow-read scripts/check-unawaited-promises.ts\",\n \"lint:platform\": \"deno run --allow-read scripts/lint-platform-agnostic.ts\",\n \"check:circular\": \"deno run -A jsr:@cunarist/deno-circular-deps src/index.ts\"\n },\n \"lint\": {\n \"include\": [\n \"src/**/*.ts\",\n \"src/**/*.tsx\"\n ],\n \"exclude\": [\n \"dist/\",\n \"coverage/\"\n ],\n \"rules\": {\n \"tags\": [\n \"recommended\"\n ],\n \"include\": [\n \"ban-untagged-todo\"\n ],\n \"exclude\": [\n \"no-explicit-any\",\n \"no-process-global\",\n \"no-console\"\n ]\n }\n },\n \"fmt\": {\n \"include\": [\n \"src/**/*.ts\",\n \"src/**/*.tsx\"\n ],\n \"exclude\": [\n \"dist/\",\n \"coverage/\"\n ],\n \"options\": {\n \"useTabs\": false,\n \"lineWidth\": 100,\n \"indentWidth\": 2,\n \"semiColons\": true,\n \"singleQuote\": false,\n \"proseWrap\": \"preserve\"\n }\n }\n}\n", "export const isDeno = typeof Deno !== \"undefined\";\nexport const isNode =\n typeof (globalThis as { process?: { versions?: { node?: string } } }).process !== \"undefined\" &&\n (globalThis as { process?: { versions?: { node?: string } } }).process?.versions?.node !==\n undefined;\nexport const isBun = typeof (globalThis as { Bun?: unknown }).Bun !== \"undefined\";\nexport const isCloudflare = typeof globalThis !== \"undefined\" && \"caches\" in globalThis &&\n \"WebSocketPair\" in globalThis;\n\n/**\n * Detect if running in Node.js (vs Deno)\n * Use this function instead of the constant when runtime detection needs to happen\n * at call time (e.g., when bundled with esbuild's __esm lazy initialization pattern)\n */\nexport function isNodeRuntime(): boolean {\n // deno-lint-ignore no-explicit-any\n const _global = globalThis as any;\n return typeof Deno === \"undefined\" && typeof _global.process !== \"undefined\" &&\n !!_global.process?.versions?.node;\n}\n", "import { isDeno as IS_DENO } from \"./runtime.ts\";\n\nconst nodeProcess = (globalThis as { process?: typeof import(\"node:process\") }).process;\nconst hasNodeProcess = !!nodeProcess?.versions?.node;\n\nexport function getArgs(): string[] {\n if (IS_DENO) {\n return Deno.args;\n }\n if (hasNodeProcess) {\n return nodeProcess!.argv.slice(2);\n }\n return [];\n}\n\nexport function exit(code?: number): never {\n if (IS_DENO) {\n Deno.exit(code);\n }\n if (hasNodeProcess) {\n nodeProcess!.exit(code);\n }\n throw new Error(\"exit() is not supported in this runtime\");\n}\n\nexport function cwd(): string {\n if (IS_DENO) {\n return Deno.cwd();\n }\n if (hasNodeProcess) {\n return nodeProcess!.cwd();\n }\n throw new Error(\"cwd() is not supported in this runtime\");\n}\n\nexport function chdir(directory: string): void {\n if (IS_DENO) {\n Deno.chdir(directory);\n } else {\n if (hasNodeProcess) {\n nodeProcess!.chdir(directory);\n return;\n }\n throw new Error(\"chdir() is not supported in this runtime\");\n }\n}\n\nexport function env(): Record<string, string> {\n if (IS_DENO) {\n return Deno.env.toObject();\n }\n if (hasNodeProcess) {\n return nodeProcess!.env as Record<string, string>;\n }\n return {};\n}\n\nexport function getEnv(key: string): string | undefined {\n if (IS_DENO) {\n return Deno.env.get(key);\n }\n if (hasNodeProcess) {\n return nodeProcess!.env[key];\n }\n return undefined;\n}\n\n/**\n * Get an environment variable or throw if not set\n * @throws Error if the environment variable is not set\n */\nexport function requireEnv(key: string): string {\n const value = getEnv(key);\n if (value === undefined) {\n throw new Error(`Required environment variable \"${key}\" is not set`);\n }\n return value;\n}\n\nexport function setEnv(key: string, value: string): void {\n if (IS_DENO) {\n Deno.env.set(key, value);\n } else {\n if (hasNodeProcess) {\n nodeProcess!.env[key] = value;\n return;\n }\n throw new Error(\"setEnv() is not supported in this runtime\");\n }\n}\n\nexport function deleteEnv(key: string): void {\n if (IS_DENO) {\n Deno.env.delete(key);\n } else {\n if (hasNodeProcess) {\n delete nodeProcess!.env[key];\n return;\n }\n throw new Error(\"deleteEnv() is not supported in this runtime\");\n }\n}\n\nexport function pid(): number {\n if (IS_DENO) {\n return Deno.pid;\n }\n if (hasNodeProcess) {\n return nodeProcess!.pid;\n }\n return 0;\n}\n\nexport function ppid(): number {\n if (IS_DENO && \"ppid\" in Deno) {\n return Deno.ppid || 0;\n }\n if (hasNodeProcess) {\n return nodeProcess!.ppid || 0;\n }\n return 0;\n}\n\nexport function memoryUsage(): {\n rss: number;\n heapTotal: number;\n heapUsed: number;\n external: number;\n} {\n if (IS_DENO) {\n const usage = Deno.memoryUsage();\n return {\n rss: usage.rss,\n heapTotal: usage.heapTotal,\n heapUsed: usage.heapUsed,\n external: usage.external,\n };\n }\n\n if (!hasNodeProcess) {\n throw new Error(\"memoryUsage() is not supported in this runtime\");\n }\n\n const usage = nodeProcess!.memoryUsage();\n return {\n rss: usage.rss,\n heapTotal: usage.heapTotal,\n heapUsed: usage.heapUsed,\n external: usage.external || 0,\n };\n}\n\n/**\n * Check if stdin is a TTY (terminal)\n */\nexport function isInteractive(): boolean {\n if (IS_DENO) {\n return Deno.stdin.isTerminal();\n }\n if (hasNodeProcess) {\n return nodeProcess!.stdin.isTTY ?? false;\n }\n return false;\n}\n\n/**\n * Get network interfaces\n */\nexport async function getNetworkInterfaces(): Promise<\n Array<{ name: string; address: string; family: \"IPv4\" | \"IPv6\" }>\n> {\n if (IS_DENO) {\n const interfaces = Deno.networkInterfaces();\n return interfaces.map((iface) => ({\n name: iface.name,\n address: iface.address,\n family: iface.family as \"IPv4\" | \"IPv6\",\n }));\n }\n\n if (!hasNodeProcess) {\n throw new Error(\"networkInterfaces() is not supported in this runtime\");\n }\n\n const os = await import(\"node:os\");\n const interfaces = os.networkInterfaces();\n const result: Array<{ name: string; address: string; family: \"IPv4\" | \"IPv6\" }> = [];\n\n for (const [name, addrs] of Object.entries(interfaces)) {\n if (!addrs) continue;\n for (const addr of addrs) {\n result.push({\n name,\n address: addr.address,\n family: addr.family as \"IPv4\" | \"IPv6\",\n });\n }\n }\n\n return result;\n}\n\n/**\n * Get runtime version string\n */\nexport function getRuntimeVersion(): string {\n if (IS_DENO) {\n return `Deno ${Deno.version.deno}`;\n }\n if (\"Bun\" in globalThis) {\n return `Bun ${(globalThis as unknown as { Bun: { version: string } }).Bun.version}`;\n }\n if (hasNodeProcess) {\n return `Node.js ${nodeProcess!.version}`;\n }\n return \"unknown\";\n}\n\n/**\n * Register a signal handler (SIGINT, SIGTERM) for graceful shutdown\n */\nexport function onSignal(signal: \"SIGINT\" | \"SIGTERM\", handler: () => void): void {\n if (IS_DENO) {\n Deno.addSignalListener(signal, handler);\n } else if (hasNodeProcess) {\n nodeProcess!.on(signal, handler);\n }\n}\n\n/**\n * Unreference a timer to prevent it from keeping the process alive\n */\nexport function unrefTimer(timerId: ReturnType<typeof setInterval>): void {\n if (IS_DENO) {\n Deno.unrefTimer(timerId as number);\n } else if (timerId && typeof timerId === \"object\" && \"unref\" in timerId) {\n (timerId as { unref: () => void }).unref();\n }\n}\n\n/**\n * Get the executable path of the current runtime\n */\nexport function execPath(): string {\n if (IS_DENO) {\n return Deno.execPath();\n }\n if (hasNodeProcess) {\n return nodeProcess!.execPath;\n }\n return \"\";\n}\n\n/**\n * Get process uptime in seconds\n * Returns OS uptime on Deno, process uptime on Node.js\n */\nexport function uptime(): number {\n if (IS_DENO) {\n // Deno.osUptime() returns system uptime in seconds\n return Deno.osUptime?.() ?? 0;\n }\n if (hasNodeProcess) {\n // process.uptime() returns process uptime in seconds\n return nodeProcess!.uptime?.() ?? 0;\n }\n return 0;\n}\n\n/**\n * Get stdout stream for writing\n * Returns null if not available (e.g., in browser/workers)\n */\nexport function getStdout(): { write: (data: string) => void } | null {\n if (IS_DENO) {\n const encoder = new TextEncoder();\n return {\n write: (data: string) => {\n Deno.stdout.writeSync(encoder.encode(data));\n },\n };\n }\n if (hasNodeProcess && nodeProcess!.stdout) {\n return {\n write: (data: string) => {\n nodeProcess!.stdout.write(data);\n },\n };\n }\n return null;\n}\n\n// Cached Node.js modules for synchronous prompt\nlet cachedNodeFs: typeof import(\"node:fs\") | null = null;\n\n/**\n * Synchronous prompt function that works across Deno and Node.js\n * Displays a message and reads user input from stdin\n */\nexport function promptSync(message?: string): string | null {\n if (IS_DENO) {\n // Deno has a built-in prompt() function\n return prompt(message);\n }\n\n if (hasNodeProcess) {\n // Print the message\n if (message) {\n nodeProcess!.stdout.write(message + \" \");\n }\n\n // Lazy load fs module\n if (!cachedNodeFs) {\n // Dynamic import converted to sync require for bundling\n // @ts-ignore - dynamic require for Node.js\n cachedNodeFs = globalThis.require?.(\"node:fs\") || null;\n if (!cachedNodeFs) {\n // Try alternative approach\n try {\n // @ts-ignore: __require is injected by bundlers for Node.js require\n cachedNodeFs = __require(\"node:fs\");\n } catch {\n return null;\n }\n }\n }\n\n if (!cachedNodeFs) {\n return null;\n }\n\n // Read synchronously using fs\n // This works by reading from file descriptor 0 (stdin)\n // Use Uint8Array for cross-platform compatibility\n const bufferSize = 1024;\n const uint8Array = new Uint8Array(bufferSize);\n let input = \"\";\n\n try {\n // Read from stdin (fd 0) synchronously\n const bytesRead = cachedNodeFs.readSync(0, uint8Array, 0, bufferSize, null);\n if (bytesRead > 0) {\n const decoder = new TextDecoder(\"utf-8\");\n input = decoder.decode(uint8Array.subarray(0, bytesRead)).trim();\n }\n } catch {\n // If stdin is not available or EOF, return null\n return null;\n }\n\n return input || null;\n }\n\n return null;\n}\n", "import denoConfig from \"../../../deno.json\" with { type: \"json\" };\nimport { getEnv } from \"../../platform/compat/process.ts\";\n\nexport const VERSION: string = getEnv(\"VERYFRONT_VERSION\") ||\n (typeof denoConfig.version === \"string\" ? denoConfig.version : \"0.0.0\");\n", "export const ESM_CDN_BASE = \"https://esm.sh\";\n\nexport const JSDELIVR_CDN_BASE = \"https://cdn.jsdelivr.net\";\n\nexport const DENO_STD_BASE = \"https://deno.land\";\n\nexport const REACT_VERSION_17 = \"17.0.2\";\nexport const REACT_VERSION_18_2 = \"18.2.0\";\nexport const REACT_VERSION_18_3 = \"18.3.1\";\nexport const REACT_VERSION_19_RC = \"19.0.0-rc.0\";\nexport const REACT_VERSION_19 = \"19.1.1\";\n\nexport const REACT_DEFAULT_VERSION = REACT_VERSION_18_3;\n\nexport function getReactCDNUrl(version: string = REACT_DEFAULT_VERSION): string {\n return `${ESM_CDN_BASE}/react@${version}`;\n}\n\nexport function getReactDOMCDNUrl(version: string = REACT_DEFAULT_VERSION): string {\n return `${ESM_CDN_BASE}/react-dom@${version}`;\n}\n\nexport function getReactDOMClientCDNUrl(version: string = REACT_DEFAULT_VERSION): string {\n return `${ESM_CDN_BASE}/react-dom@${version}/client`;\n}\n\nexport function getReactDOMServerCDNUrl(version: string = REACT_DEFAULT_VERSION): string {\n return `${ESM_CDN_BASE}/react-dom@${version}/server`;\n}\n\nexport function getReactJSXRuntimeCDNUrl(version: string = REACT_DEFAULT_VERSION): string {\n return `${ESM_CDN_BASE}/react@${version}/jsx-runtime`;\n}\n\nexport function getReactJSXDevRuntimeCDNUrl(version: string = REACT_DEFAULT_VERSION): string {\n return `${ESM_CDN_BASE}/react@${version}/jsx-dev-runtime`;\n}\n\nexport function getReactImportMap(version: string = REACT_DEFAULT_VERSION): Record<string, string> {\n return {\n react: getReactCDNUrl(version),\n \"react-dom\": getReactDOMCDNUrl(version),\n \"react-dom/client\": getReactDOMClientCDNUrl(version),\n \"react-dom/server\": getReactDOMServerCDNUrl(version),\n \"react/jsx-runtime\": getReactJSXRuntimeCDNUrl(version),\n \"react/jsx-dev-runtime\": getReactJSXDevRuntimeCDNUrl(version),\n };\n}\n\nexport const DEFAULT_ALLOWED_CDN_HOSTS = [ESM_CDN_BASE, DENO_STD_BASE];\n\nexport const DENO_STD_VERSION = \"0.220.0\";\n\nexport function getDenoStdNodeBase(): string {\n return `${DENO_STD_BASE}/std@${DENO_STD_VERSION}/node`;\n}\n\n// UnoCSS constants\nexport const UNOCSS_VERSION = \"0.59.0\";\n\nexport function getUnoCSSTailwindResetUrl(): string {\n return `${ESM_CDN_BASE}/@unocss/reset@${UNOCSS_VERSION}/tailwind.css`;\n}\n\n// Veryfront package version - derived from deno.json (single source of truth)\nexport { VERSION as VERYFRONT_VERSION } from \"../version.ts\";\n", "/**\n * Environment variable utilities\n *\n * Centralized utilities for checking environment flags.\n * This ensures consistent behavior across the entire codebase.\n */\n\n/**\n * Environment variable names used by Veryfront\n */\nexport const ENV_VARS = {\n DEBUG: \"VERYFRONT_DEBUG\",\n DEEP_INSPECT: \"VERYFRONT_DEEP_INSPECT\",\n CACHE_DIR: \"VERYFRONT_CACHE_DIR\",\n PORT: \"VERYFRONT_PORT\",\n VERSION: \"VERYFRONT_VERSION\",\n} as const;\n\n/**\n * Check if a debug environment variable value is truthy.\n * Accepts: \"1\", \"true\", \"yes\" (case-insensitive)\n *\n * @param value - The environment variable value to check\n * @returns true if the value indicates debug mode should be enabled\n */\nexport function isTruthyEnvValue(value: string | undefined): boolean {\n if (!value) return false;\n const normalized = value.toLowerCase().trim();\n return normalized === \"1\" || normalized === \"true\" || normalized === \"yes\";\n}\n\n/**\n * Check if debug mode is enabled via environment variable.\n * Works with RuntimeAdapter's env interface.\n *\n * @param env - Environment accessor object with get() method\n * @returns true if VERYFRONT_DEBUG is set to a truthy value\n */\nexport function isDebugEnabled(env: { get(key: string): string | undefined }): boolean {\n return isTruthyEnvValue(env.get(ENV_VARS.DEBUG));\n}\n\n/**\n * Check if deep inspect mode is enabled via environment variable.\n *\n * @param env - Environment accessor object with get() method\n * @returns true if VERYFRONT_DEEP_INSPECT is set to a truthy value\n */\nexport function isDeepInspectEnabled(env: { get(key: string): string | undefined }): boolean {\n return isTruthyEnvValue(env.get(ENV_VARS.DEEP_INSPECT));\n}\n\n/**\n * Check if either debug or deep inspect mode is enabled.\n *\n * @param env - Environment accessor object with get() method\n * @returns true if either debug flag is enabled\n */\nexport function isAnyDebugEnabled(env: { get(key: string): string | undefined }): boolean {\n return isDebugEnabled(env) || isDeepInspectEnabled(env);\n}\n", "export const HASH_SEED_DJB2 = 5381;\n\nexport const HASH_SEED_FNV1A = 2166136261;\n", "export const KB_IN_BYTES = 1024;\n\nexport const HTTP_MODULE_FETCH_TIMEOUT_MS = 2500;\n\nexport const HMR_RECONNECT_DELAY_MS = 1000;\n\nexport const HMR_RELOAD_DELAY_MS = 1000;\n\nexport const HMR_FILE_WATCHER_DEBOUNCE_MS = 100;\n\nexport const HMR_KEEP_ALIVE_INTERVAL_MS = 30000;\n\nexport const DASHBOARD_RECONNECT_DELAY_MS = 3000;\n\nexport const SERVER_FUNCTION_DEFAULT_TIMEOUT_MS = 30000;\n\nexport const PREFETCH_MAX_SIZE_BYTES = 200 * KB_IN_BYTES;\n\nexport const PREFETCH_DEFAULT_TIMEOUT_MS = 10000;\n\nexport const PREFETCH_DEFAULT_DELAY_MS = 200;\n\nexport const HTTP_OK = 200;\n\nexport const HTTP_NO_CONTENT = 204;\n\nexport const HTTP_CREATED = 201;\n\nexport const HTTP_REDIRECT_FOUND = 302;\n\nexport const HTTP_NOT_MODIFIED = 304;\n\nexport const HTTP_BAD_REQUEST = 400;\n\nexport const HTTP_UNAUTHORIZED = 401;\n\nexport const HTTP_FORBIDDEN = 403;\n\nexport const HTTP_NOT_FOUND = 404;\n\nexport const HTTP_METHOD_NOT_ALLOWED = 405;\n\nexport const HTTP_GONE = 410;\n\nexport const HTTP_PAYLOAD_TOO_LARGE = 413;\n\nexport const HTTP_URI_TOO_LONG = 414;\n\nexport const HTTP_TOO_MANY_REQUESTS = 429;\n\nexport const HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE = 431;\n\nexport const HTTP_SERVER_ERROR = 500;\n\nexport const HTTP_INTERNAL_SERVER_ERROR = 500;\n\nexport const HTTP_BAD_GATEWAY = 502;\n\nexport const HTTP_NOT_IMPLEMENTED = 501;\n\nexport const HTTP_UNAVAILABLE = 503;\n\nexport const HTTP_NETWORK_CONNECT_TIMEOUT = 599;\n\nexport const HTTP_STATUS_SUCCESS_MIN = 200;\n\nexport const HTTP_STATUS_REDIRECT_MIN = 300;\n\nexport const HTTP_STATUS_CLIENT_ERROR_MIN = 400;\n\nexport const HTTP_STATUS_SERVER_ERROR_MIN = 500;\n\nexport const HTTP_CONTENT_TYPES = {\n JS: \"application/javascript; charset=utf-8\",\n JSON: \"application/json; charset=utf-8\",\n HTML: \"text/html; charset=utf-8\",\n CSS: \"text/css; charset=utf-8\",\n TEXT: \"text/plain; charset=utf-8\",\n} as const;\n\nimport { MS_PER_SECOND, SECONDS_PER_MINUTE } from \"./cache.ts\";\n\nexport const MS_PER_MINUTE = 60000;\n\nexport { MS_PER_SECOND, SECONDS_PER_MINUTE };\n\nexport const HTTP_CONTENT_TYPE_IMAGE_PNG = \"image/png\";\n\nexport const HTTP_CONTENT_TYPE_IMAGE_JPEG = \"image/jpeg\";\n\nexport const HTTP_CONTENT_TYPE_IMAGE_WEBP = \"image/webp\";\n\nexport const HTTP_CONTENT_TYPE_IMAGE_AVIF = \"image/avif\";\n\nexport const HTTP_CONTENT_TYPE_IMAGE_SVG = \"image/svg+xml\";\n\nexport const HTTP_CONTENT_TYPE_IMAGE_GIF = \"image/gif\";\n\nexport const HTTP_CONTENT_TYPE_IMAGE_ICO = \"image/x-icon\";\n", "import { KB_IN_BYTES } from \"./http.ts\";\n\nexport const HMR_MAX_MESSAGE_SIZE_BYTES = 1024 * KB_IN_BYTES;\n\nexport const HMR_MAX_MESSAGES_PER_MINUTE = 100;\n\nexport const HMR_CLIENT_RELOAD_DELAY_MS = 3000;\n\nexport const HMR_PORT_OFFSET = 1;\n\nexport const HMR_RATE_LIMIT_WINDOW_MS = 60000;\n\nexport const HMR_CLOSE_NORMAL = 1000;\n\nexport const HMR_CLOSE_RATE_LIMIT = 1008;\n\nexport const HMR_CLOSE_MESSAGE_TOO_LARGE = 1009;\n\nexport const HMR_MESSAGE_TYPES = {\n CONNECTED: \"connected\",\n UPDATE: \"update\",\n RELOAD: \"reload\",\n PING: \"ping\",\n PONG: \"pong\",\n} as const;\n\nexport function isValidHMRMessageType(type: string): type is keyof typeof HMR_MESSAGE_TYPES {\n return Object.values(HMR_MESSAGE_TYPES).includes(\n type as typeof HMR_MESSAGE_TYPES[keyof typeof HMR_MESSAGE_TYPES],\n );\n}\n", "export const Z_INDEX_DEV_INDICATOR = 9998;\nexport const Z_INDEX_ERROR_OVERLAY = 9999;\n\nexport const BREAKPOINT_SM = 640;\nexport const BREAKPOINT_MD = 768;\nexport const BREAKPOINT_LG = 1024;\nexport const BREAKPOINT_XL = 1280;\n\nexport const PROSE_MAX_WIDTH = \"65ch\";\n", "export const DEFAULT_DEV_SERVER_PORT = 3000;\nexport const DEFAULT_REDIS_PORT = 6379;\nexport const DEFAULT_API_SERVER_PORT = 8080;\nexport const DEFAULT_PREVIEW_SERVER_PORT = 5000;\nexport const DEFAULT_METRICS_PORT = 9000;\n\nexport const BYTES_PER_KB = 1024;\nexport const BYTES_PER_MB = 1024 * 1024;\n\nexport const DEFAULT_IMAGE_THUMBNAIL_SIZE = 256;\nexport const DEFAULT_IMAGE_SMALL_SIZE = 512;\nexport const DEFAULT_IMAGE_LARGE_SIZE = 2048;\n\nexport const RESPONSIVE_IMAGE_WIDTH_XS = 320;\nexport const RESPONSIVE_IMAGE_WIDTH_SM = 640;\nexport const RESPONSIVE_IMAGE_WIDTH_MD = 1024;\nexport const RESPONSIVE_IMAGE_WIDTH_LG = 1920;\n\nexport const RESPONSIVE_IMAGE_WIDTHS = [\n RESPONSIVE_IMAGE_WIDTH_XS,\n RESPONSIVE_IMAGE_WIDTH_SM,\n RESPONSIVE_IMAGE_WIDTH_MD,\n RESPONSIVE_IMAGE_WIDTH_LG,\n] as const;\n\nexport const MAX_CHUNK_SIZE_KB = 4096;\n\nexport const MIN_PORT = 1;\n\nexport const MAX_PORT = 65535;\n\nexport const DEFAULT_SERVER_PORT = 8000;\n", "export const MAX_PATH_TRAVERSAL_DEPTH = 10;\n\nexport const FORBIDDEN_PATH_PATTERNS = [\n /\\0/, // Null bytes\n];\n\nexport const DIRECTORY_TRAVERSAL_PATTERN = /\\.\\.[\\/\\\\]/;\n\nexport const ABSOLUTE_PATH_PATTERN = /^[\\/\\\\]/;\n\nexport const MAX_PATH_LENGTH = 4096;\n\nexport const DEFAULT_MAX_STRING_LENGTH = 1000;\n", "/**\n * Default port for veryfront dev server.\n * This is the single source of truth for the default port.\n */\nexport const DEFAULT_PORT = 3000;\n\nexport const DEFAULT_TIMEOUT_MS = 5000;\n\nexport const SSR_TIMEOUT_MS = 10000;\n\nexport const SANDBOX_TIMEOUT_MS = 5000;\n\nexport const DEFAULT_CACHE_MAX_SIZE = 100;\n\nexport const defaultConfig = {\n server: {\n port: DEFAULT_PORT,\n hostname: \"0.0.0.0\",\n },\n\n timeouts: {\n default: DEFAULT_TIMEOUT_MS,\n api: 30000,\n ssr: SSR_TIMEOUT_MS,\n hmr: 30000,\n sandbox: SANDBOX_TIMEOUT_MS,\n },\n\n cache: {\n jit: {\n maxSize: DEFAULT_CACHE_MAX_SIZE,\n tempDirPrefix: \"vf-bundle-\",\n },\n },\n\n metrics: {\n ssrBoundaries: [5, 10, 25, 50, 75, 100, 250, 500, 750, 1000, 2500, 5000, 7500, 10000],\n },\n} as const;\n\nexport const DEFAULT_PREFETCH_DELAY_MS = 100;\n\nexport const DEFAULT_METRICS_COLLECT_INTERVAL_MS = 60000;\n\nexport const DURATION_HISTOGRAM_BOUNDARIES_MS = [\n 5,\n 10,\n 25,\n 50,\n 75,\n 100,\n 250,\n 500,\n 750,\n 1000,\n 2500,\n 5000,\n 7500,\n 10000,\n];\n\nexport const SIZE_HISTOGRAM_BOUNDARIES_KB = [\n 1,\n 5,\n 10,\n 25,\n 50,\n 100,\n 250,\n 500,\n 1000,\n 2500,\n 5000,\n 10000,\n];\n\nexport const DEFAULT_REDIS_SCAN_COUNT = 100;\n\nexport const DEFAULT_REDIS_BATCH_DELETE_SIZE = 1000;\n\nexport const PAGE_TRANSITION_DELAY_MS = 150;\n\nexport type DefaultConfig = typeof defaultConfig;\n", "/**\n * Centralized server endpoints and paths registry\n *\n * All internal veryfront URLs should be defined here as the single source of truth.\n * This prevents hardcoding URLs across the codebase and makes refactoring easier.\n */\n\n// Re-export DEFAULT_PORT from config/defaults.ts (the single source of truth)\nexport { DEFAULT_PORT } from \"@veryfront/config/defaults.ts\";\n\n/** Default port for development dashboard */\nexport const DEFAULT_DASHBOARD_PORT = 3002;\n\n/** Internal URL prefix for all veryfront endpoints */\nexport const INTERNAL_PREFIX = \"/_veryfront\" as const;\n\n/**\n * All internal veryfront URL path prefixes (directories)\n */\nexport const INTERNAL_PATH_PREFIXES = {\n /** React Server Components endpoints */\n RSC: `${INTERNAL_PREFIX}/rsc/`,\n /** File system access endpoints (base64 encoded paths) */\n FS: `${INTERNAL_PREFIX}/fs/`,\n /** Virtual module system */\n MODULES: `${INTERNAL_PREFIX}/modules/`,\n /** Generated page modules */\n PAGES: `${INTERNAL_PREFIX}/pages/`,\n /** Data JSON endpoints */\n DATA: `${INTERNAL_PREFIX}/data/`,\n /** Library modules (AI SDK, etc.) */\n LIB: `${INTERNAL_PREFIX}/lib/`,\n /** Chunk assets */\n CHUNKS: `${INTERNAL_PREFIX}/chunks/`,\n /** Client component modules */\n CLIENT: `${INTERNAL_PREFIX}/client/`,\n} as const;\n\n/**\n * Specific internal endpoint URLs\n */\nexport const INTERNAL_ENDPOINTS = {\n // Development endpoints\n HMR_RUNTIME: `${INTERNAL_PREFIX}/hmr-runtime.js`,\n HMR: `${INTERNAL_PREFIX}/hmr.js`,\n HYDRATE: `${INTERNAL_PREFIX}/hydrate.js`,\n ERROR_OVERLAY: `${INTERNAL_PREFIX}/error-overlay.js`,\n DEV_LOADER: `${INTERNAL_PREFIX}/dev-loader.js`,\n CLIENT_LOG: `${INTERNAL_PREFIX}/log`,\n\n // Production endpoints\n CLIENT_JS: `${INTERNAL_PREFIX}/client.js`,\n ROUTER_JS: `${INTERNAL_PREFIX}/router.js`,\n PREFETCH_JS: `${INTERNAL_PREFIX}/prefetch.js`,\n MANIFEST_JSON: `${INTERNAL_PREFIX}/manifest.json`,\n APP_JS: `${INTERNAL_PREFIX}/app.js`,\n\n // RSC endpoints\n RSC_CLIENT: `${INTERNAL_PREFIX}/rsc/client.js`,\n RSC_MANIFEST: `${INTERNAL_PREFIX}/rsc/manifest`,\n RSC_STREAM: `${INTERNAL_PREFIX}/rsc/stream`,\n RSC_PAYLOAD: `${INTERNAL_PREFIX}/rsc/payload`,\n RSC_RENDER: `${INTERNAL_PREFIX}/rsc/render`,\n RSC_PAGE: `${INTERNAL_PREFIX}/rsc/page`,\n RSC_MODULE: `${INTERNAL_PREFIX}/rsc/module`,\n RSC_DOM: `${INTERNAL_PREFIX}/rsc/dom.js`,\n RSC_HYDRATOR: `${INTERNAL_PREFIX}/rsc/hydrator.js`,\n RSC_HYDRATE_CLIENT: `${INTERNAL_PREFIX}/rsc/hydrate-client.js`,\n\n // Library module endpoints\n LIB_AI_REACT: `${INTERNAL_PREFIX}/lib/ai/react.js`,\n LIB_AI_COMPONENTS: `${INTERNAL_PREFIX}/lib/ai/components.js`,\n LIB_AI_PRIMITIVES: `${INTERNAL_PREFIX}/lib/ai/primitives.js`,\n} as const;\n\n/**\n * Build output directory paths (relative)\n */\nexport const BUILD_DIRS = {\n /** Main build output directory */\n ROOT: \"_veryfront\",\n /** Chunks directory */\n CHUNKS: \"_veryfront/chunks\",\n /** Data directory */\n DATA: \"_veryfront/data\",\n /** Assets directory */\n ASSETS: \"_veryfront/assets\",\n} as const;\n\n/**\n * Local project directory paths (relative to project root)\n * These are .gitignore'd directories for caching and temporary files\n */\nexport const PROJECT_DIRS = {\n /** Base veryfront internal directory */\n ROOT: \".veryfront\",\n /** Cache directory for build artifacts, transforms, etc. */\n CACHE: \".veryfront/cache\",\n /** KV store directory */\n KV: \".veryfront/kv\",\n /** Log files directory */\n LOGS: \".veryfront/logs\",\n /** Temporary files directory */\n TMP: \".veryfront/tmp\",\n} as const;\n\n/** Default cache directory path */\nexport const DEFAULT_CACHE_DIR = PROJECT_DIRS.CACHE;\n\n/**\n * Helper to check if a pathname is an internal veryfront endpoint\n */\nexport function isInternalEndpoint(pathname: string): boolean {\n return pathname.startsWith(INTERNAL_PREFIX + \"/\");\n}\n\n/**\n * Helper to check if a pathname is a static asset (has extension or is internal)\n */\nexport function isStaticAsset(pathname: string): boolean {\n return pathname.includes(\".\") || isInternalEndpoint(pathname);\n}\n\n/**\n * Normalize a chunk path to include the base prefix\n */\nexport function normalizeChunkPath(\n filename: string,\n basePath: string = INTERNAL_PATH_PREFIXES.CHUNKS,\n): string {\n if (filename.startsWith(\"/\")) {\n return filename;\n }\n return `${basePath.replace(/\\/$/, \"\")}/${filename}`;\n}\n\n// Re-export for backward compatibility\nexport const DEV_SERVER_ENDPOINTS = {\n HMR_RUNTIME: INTERNAL_ENDPOINTS.HMR_RUNTIME,\n ERROR_OVERLAY: INTERNAL_ENDPOINTS.ERROR_OVERLAY,\n} as const;\n", "export * from \"./build.ts\";\nexport * from \"./cache.ts\";\nexport * from \"./cdn.ts\";\nexport * from \"./env.ts\";\nexport * from \"./hash.ts\";\nexport * from \"./hmr.ts\";\nexport * from \"./html.ts\";\nexport * from \"./http.ts\";\nexport * from \"./network.ts\";\nexport * from \"./security.ts\";\nexport * from \"./server.ts\";\n", "/**\n * Project directory paths and file extensions\n *\n * For internal veryfront URL endpoints, see ./constants/server.ts\n */\n\nimport {\n BUILD_DIRS,\n INTERNAL_ENDPOINTS,\n INTERNAL_PATH_PREFIXES,\n INTERNAL_PREFIX,\n} from \"./constants/server.ts\";\n\nexport const PATHS = {\n PAGES_DIR: \"pages\",\n COMPONENTS_DIR: \"components\",\n PUBLIC_DIR: \"public\",\n STYLES_DIR: \"styles\",\n DIST_DIR: \"dist\",\n CONFIG_FILE: \"veryfront.config.js\",\n} as const;\n\n/**\n * @deprecated Use INTERNAL_PREFIX, INTERNAL_ENDPOINTS, INTERNAL_PATH_PREFIXES from ./constants/server.ts\n */\nexport const VERYFRONT_PATHS = {\n INTERNAL_PREFIX: INTERNAL_PREFIX,\n BUILD_DIR: BUILD_DIRS.ROOT,\n CHUNKS_DIR: BUILD_DIRS.CHUNKS,\n DATA_DIR: BUILD_DIRS.DATA,\n ASSETS_DIR: BUILD_DIRS.ASSETS,\n HMR_RUNTIME: INTERNAL_ENDPOINTS.HMR_RUNTIME,\n CLIENT_JS: INTERNAL_ENDPOINTS.CLIENT_JS,\n ROUTER_JS: INTERNAL_ENDPOINTS.ROUTER_JS,\n ERROR_OVERLAY: INTERNAL_ENDPOINTS.ERROR_OVERLAY,\n} as const;\n\nexport const FILE_EXTENSIONS = {\n MDX: [\".mdx\", \".md\"],\n SCRIPT: [\".tsx\", \".ts\", \".jsx\", \".js\"],\n STYLE: [\".css\", \".scss\", \".sass\"],\n ALL: [\".mdx\", \".md\", \".tsx\", \".ts\", \".jsx\", \".js\", \".css\"],\n} as const;\n\n// Re-export for convenience\nexport { BUILD_DIRS, INTERNAL_ENDPOINTS, INTERNAL_PATH_PREFIXES, INTERNAL_PREFIX };\n", "export async function computeHash(content: string): Promise<string> {\n const encoder = new TextEncoder();\n const data = encoder.encode(content);\n const hashBuffer = await crypto.subtle.digest(\"SHA-256\", data);\n const hashArray = Array.from(new Uint8Array(hashBuffer));\n return hashArray.map((b) => b.toString(16).padStart(2, \"0\")).join(\"\");\n}\n\nexport function getContentHash(content: string): Promise<string> {\n return computeHash(content);\n}\n\nexport function computeContentHash(content: string): Promise<string> {\n return computeHash(content);\n}\n\nexport interface BundleCode {\n code: string;\n css?: string;\n sourceMap?: string;\n}\n\nexport function computeCodeHash(code: BundleCode): Promise<string> {\n const combined = code.code + (code.css || \"\") + (code.sourceMap || \"\");\n return computeHash(combined);\n}\n\nexport function simpleHash(str: string): number {\n let hash = 0;\n for (let i = 0; i < str.length; i++) {\n const char = str.charCodeAt(i);\n hash = ((hash << 5) - hash) + char;\n hash = hash & hash;\n }\n return Math.abs(hash);\n}\n\nexport async function shortHash(content: string): Promise<string> {\n const fullHash = await computeHash(content);\n return fullHash.slice(0, 8);\n}\n", "export class MemoCache<V> {\n private cache = new Map<string, V>();\n\n get(key: string): V | undefined {\n return this.cache.get(key);\n }\n\n set(key: string, value: V): void {\n this.cache.set(key, value);\n }\n\n has(key: string): boolean {\n return this.cache.has(key);\n }\n\n clear(): void {\n this.cache.clear();\n }\n\n size(): number {\n return this.cache.size;\n }\n}\n\nexport function memoizeAsync<Args extends unknown[], Result>(\n fn: (...args: Args) => Promise<Result>,\n keyHasher: (...args: Args) => string,\n): (...args: Args) => Promise<Result> {\n const cache = new MemoCache<Result>();\n\n return async (...args: Args): Promise<Result> => {\n const key = keyHasher(...args);\n if (cache.has(key)) {\n return cache.get(key)!;\n }\n\n const result = await fn(...args);\n cache.set(key, result);\n return result;\n };\n}\n\nexport function memoize<Args extends unknown[], Result>(\n fn: (...args: Args) => Result,\n keyHasher: (...args: Args) => string,\n): (...args: Args) => Result {\n const cache = new MemoCache<Result>();\n\n return (...args: Args): Result => {\n const key = keyHasher(...args);\n if (cache.has(key)) {\n return cache.get(key)!;\n }\n\n const result = fn(...args);\n cache.set(key, result);\n return result;\n };\n}\n\n/**\n * FNV-1a hash algorithm for fast cache key generation.\n * 10-15x faster than JSON.stringify() and uses 70-80% less memory.\n *\n * @param values - Values to hash\n * @returns Hash string\n */\nexport function simpleHash(...values: unknown[]): string {\n const FNV_OFFSET_BASIS = 2166136261;\n const FNV_PRIME = 16777619;\n\n let hash = FNV_OFFSET_BASIS;\n\n for (const value of values) {\n const str = typeof value === \"string\" ? value : String(value);\n\n for (let i = 0; i < str.length; i++) {\n hash ^= str.charCodeAt(i);\n hash = Math.imul(hash, FNV_PRIME);\n }\n }\n\n // Convert to unsigned 32-bit and then to base-36 string\n return (hash >>> 0).toString(36);\n}\n", "import { logger } from \"./logger/logger.ts\";\n\nexport function normalizePath(pathname: string): string {\n pathname = pathname.replace(/\\\\+/g, \"/\").replace(/\\/\\.+\\//g, \"/\");\n\n if (pathname !== \"/\" && pathname.endsWith(\"/\")) {\n pathname = pathname.slice(0, -1);\n }\n\n return pathname;\n}\n\nexport function joinPath(a: string, b: string): string {\n return `${a.replace(/\\/$/, \"\")}/${b.replace(/^\\//, \"\")}`;\n}\n\nexport function isWithinDirectory(root: string, target: string): boolean {\n const normalizedRoot = normalizePath(root);\n const normalizedTarget = normalizePath(target);\n return normalizedTarget.startsWith(`${normalizedRoot}/`) || normalizedTarget === normalizedRoot;\n}\n\nexport function getExtension(path: string): string {\n const lastDot = path.lastIndexOf(\".\");\n if (lastDot === -1 || lastDot === path.length - 1) {\n return \"\";\n }\n return path.slice(lastDot);\n}\n\nexport function getDirectory(path: string): string {\n const normalized = normalizePath(path);\n const lastSlash = normalized.lastIndexOf(\"/\");\n return lastSlash <= 0 ? \"/\" : normalized.slice(0, lastSlash);\n}\n\nexport function hasHashedFilename(path: string): boolean {\n return /\\.[a-f0-9]{8,}\\./.test(path);\n}\n\nexport function isAbsolutePath(path: string): boolean {\n return path.startsWith(\"/\") || /^[A-Za-z]:[\\\\/]/.test(path);\n}\n\nexport function toBase64Url(s: string): string {\n const b64 = btoa(s);\n return b64.replaceAll(\"+\", \"-\").replaceAll(\"/\", \"_\").replaceAll(\"=\", \"\");\n}\n\nexport function fromBase64Url(encoded: string): string {\n const b64 = encoded.replaceAll(\"-\", \"+\").replaceAll(\"_\", \"/\");\n const pad = b64.length % 4 === 2 ? \"==\" : b64.length % 4 === 3 ? \"=\" : \"\";\n try {\n return atob(b64 + pad);\n } catch (error) {\n logger.debug(`Failed to decode base64url string \"${encoded}\":`, error);\n return \"\";\n }\n}\n", "import { logger } from \"./logger/logger.ts\";\n\nexport function formatBytes(bytes: number): string {\n if (bytes === 0) return \"0 Bytes\";\n\n const absBytes = Math.abs(bytes);\n\n if (absBytes < 1) {\n return `${absBytes} Bytes`;\n }\n\n const k = 1024;\n const sizes = [\"Bytes\", \"KB\", \"MB\", \"GB\", \"TB\"];\n const i = Math.floor(Math.log(absBytes) / Math.log(k));\n\n const index = Math.max(0, Math.min(i, sizes.length - 1));\n\n return `${parseFloat((absBytes / Math.pow(k, index)).toFixed(2))} ${sizes[index]}`;\n}\n\nexport function estimateSize(value: unknown): number {\n if (value === null || value === undefined) return 8;\n\n switch (typeof value) {\n case \"boolean\":\n return 4;\n case \"number\":\n return 8;\n case \"string\":\n return value.length * 2; // UTF-16\n case \"function\":\n return 0; // Functions not cached\n case \"object\":\n return estimateObjectSize(value);\n default:\n return 32;\n }\n}\n\nexport function estimateSizeWithCircularHandling(value: unknown): number {\n const seen = new WeakSet();\n const encoder = new TextEncoder();\n\n const json = JSON.stringify(value, (_key, val) => {\n if (typeof val === \"object\" && val !== null) {\n if (seen.has(val as object)) return undefined;\n seen.add(val as object);\n\n if (val instanceof Map) {\n return { __type: \"Map\", entries: Array.from(val.entries()) };\n }\n if (val instanceof Set) {\n return { __type: \"Set\", values: Array.from(val.values()) };\n }\n }\n\n if (typeof val === \"function\") return undefined;\n\n if (val instanceof Uint8Array) {\n return { __type: \"Uint8Array\", length: val.length };\n }\n\n return val;\n });\n\n return encoder.encode(json ?? \"\").length;\n}\n\nfunction estimateObjectSize(value: object): number {\n if (value instanceof ArrayBuffer) return value.byteLength;\n\n if (\n value instanceof Uint8Array || value instanceof Uint16Array ||\n value instanceof Uint32Array || value instanceof Int8Array ||\n value instanceof Int16Array || value instanceof Int32Array\n ) {\n return value.byteLength;\n }\n\n try {\n return JSON.stringify(value).length * 2;\n } catch (error) {\n logger.debug(\"Failed to estimate size of non-serializable object:\", error);\n return 1024; // Default estimate for non-serializable\n }\n}\n\nexport function formatDuration(ms: number): string {\n if (ms < 1000) return `${ms}ms`;\n if (ms < 60000) return `${(ms / 1000).toFixed(1)}s`;\n if (ms < 3600000) return `${Math.floor(ms / 60000)}m ${Math.floor((ms % 60000) / 1000)}s`;\n return `${Math.floor(ms / 3600000)}h ${Math.floor((ms % 3600000) / 60000)}m`;\n}\n\nexport function formatNumber(num: number): string {\n return num.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, \",\");\n}\n\nexport function truncateString(str: string, maxLength: number): string {\n if (str.length <= maxLength) return str;\n return str.slice(0, maxLength - 3) + \"...\";\n}\n", "import { serverLogger as logger } from \"./logger/index.ts\";\n\nexport interface BundleMetadata {\n hash: string;\n codeHash: string;\n size: number;\n compiledAt: number;\n source: string;\n mode: \"development\" | \"production\";\n meta?: {\n type?: \"mdx\" | \"component\" | \"layout\" | \"provider\";\n depsHash?: string;\n reactVersion?: string;\n };\n}\n\nexport interface BundleCode {\n code: string;\n sourceMap?: string;\n css?: string;\n}\n\nexport interface BundleManifestStore {\n getBundleMetadata(key: string): Promise<BundleMetadata | undefined>;\n\n setBundleMetadata(key: string, metadata: BundleMetadata, ttlMs?: number): Promise<void>;\n\n getBundleCode(hash: string): Promise<BundleCode | undefined>;\n\n setBundleCode(hash: string, code: BundleCode, ttlMs?: number): Promise<void>;\n\n deleteBundle(key: string): Promise<void>;\n\n invalidateSource(source: string): Promise<number>;\n\n clear(): Promise<void>;\n\n isAvailable(): Promise<boolean>;\n\n getStats(): Promise<{\n totalBundles: number;\n totalSize: number;\n oldestBundle?: number;\n newestBundle?: number;\n }>;\n}\n\nexport class InMemoryBundleManifestStore implements BundleManifestStore {\n private metadata = new Map<string, { value: BundleMetadata; expiry?: number }>();\n private code = new Map<string, { value: BundleCode; expiry?: number }>();\n private sourceIndex = new Map<string, Set<string>>();\n\n getBundleMetadata(key: string): Promise<BundleMetadata | undefined> {\n const entry = this.metadata.get(key);\n if (!entry) return Promise.resolve(undefined);\n if (entry.expiry && Date.now() > entry.expiry) {\n this.metadata.delete(key);\n return Promise.resolve(undefined);\n }\n return Promise.resolve(entry.value);\n }\n\n setBundleMetadata(key: string, metadata: BundleMetadata, ttlMs?: number): Promise<void> {\n const expiry = ttlMs ? Date.now() + ttlMs : undefined;\n this.metadata.set(key, { value: metadata, expiry });\n\n if (!this.sourceIndex.has(metadata.source)) {\n this.sourceIndex.set(metadata.source, new Set());\n }\n this.sourceIndex.get(metadata.source)!.add(key);\n return Promise.resolve();\n }\n\n getBundleCode(hash: string): Promise<BundleCode | undefined> {\n const entry = this.code.get(hash);\n if (!entry) return Promise.resolve(undefined);\n if (entry.expiry && Date.now() > entry.expiry) {\n this.code.delete(hash);\n return Promise.resolve(undefined);\n }\n return Promise.resolve(entry.value);\n }\n\n setBundleCode(hash: string, code: BundleCode, ttlMs?: number): Promise<void> {\n const expiry = ttlMs ? Date.now() + ttlMs : undefined;\n this.code.set(hash, { value: code, expiry });\n return Promise.resolve();\n }\n\n async deleteBundle(key: string): Promise<void> {\n const metadata = await this.getBundleMetadata(key);\n this.metadata.delete(key);\n if (metadata) {\n this.code.delete(metadata.codeHash);\n const sourceKeys = this.sourceIndex.get(metadata.source);\n if (sourceKeys) {\n sourceKeys.delete(key);\n if (sourceKeys.size === 0) {\n this.sourceIndex.delete(metadata.source);\n }\n }\n }\n }\n\n async invalidateSource(source: string): Promise<number> {\n const keys = this.sourceIndex.get(source);\n if (!keys) return 0;\n\n let count = 0;\n for (const key of Array.from(keys)) {\n await this.deleteBundle(key);\n count++;\n }\n this.sourceIndex.delete(source);\n return count;\n }\n\n clear(): Promise<void> {\n this.metadata.clear();\n this.code.clear();\n this.sourceIndex.clear();\n return Promise.resolve();\n }\n\n isAvailable(): Promise<boolean> {\n return Promise.resolve(true);\n }\n\n getStats(): Promise<{\n totalBundles: number;\n totalSize: number;\n oldestBundle?: number;\n newestBundle?: number;\n }> {\n let totalSize = 0;\n let oldest: number | undefined;\n let newest: number | undefined;\n\n for (const { value } of this.metadata.values()) {\n totalSize += value.size;\n if (!oldest || value.compiledAt < oldest) oldest = value.compiledAt;\n if (!newest || value.compiledAt > newest) newest = value.compiledAt;\n }\n\n return Promise.resolve({\n totalBundles: this.metadata.size,\n totalSize,\n oldestBundle: oldest,\n newestBundle: newest,\n });\n }\n}\n\nlet manifestStore: BundleManifestStore = new InMemoryBundleManifestStore();\n\nexport function setBundleManifestStore(store: BundleManifestStore): void {\n manifestStore = store;\n logger.info(\"[bundle-manifest] Bundle manifest store configured\", {\n type: store.constructor.name,\n });\n}\n\nexport function getBundleManifestStore(): BundleManifestStore {\n return manifestStore;\n}\n\nexport { computeCodeHash, computeContentHash } from \"./hash-utils.ts\";\n", "import type { RuntimeAdapter } from \"@veryfront/platform/adapters/base.ts\";\nimport type { VeryfrontConfig } from \"@veryfront/config\";\nimport { serverLogger as logger } from \"./logger/index.ts\";\nimport {\n type BundleManifestStore,\n InMemoryBundleManifestStore,\n setBundleManifestStore,\n} from \"./bundle-manifest.ts\";\nimport { BUNDLE_MANIFEST_DEV_TTL_MS, BUNDLE_MANIFEST_PROD_TTL_MS } from \"./constants/cache.ts\";\n\nexport async function initializeBundleManifest(\n config: VeryfrontConfig,\n mode: \"development\" | \"production\",\n adapter?: RuntimeAdapter,\n): Promise<void> {\n const manifestConfig = config.cache?.bundleManifest;\n const enabled = manifestConfig?.enabled ?? mode === \"production\";\n\n if (!enabled) {\n logger.info(\"[bundle-manifest] Bundle manifest disabled\");\n setBundleManifestStore(new InMemoryBundleManifestStore());\n return;\n }\n\n const envType = adapter?.env.get(\"VERYFRONT_BUNDLE_MANIFEST_TYPE\");\n const storeType = manifestConfig?.type || envType || \"memory\";\n\n logger.info(\"[bundle-manifest] Initializing bundle manifest\", {\n type: storeType,\n mode,\n });\n\n try {\n let store: BundleManifestStore;\n\n switch (storeType) {\n case \"redis\": {\n const { RedisBundleManifestStore } = await import(\"./bundle-manifest-redis.ts\");\n const redisUrl = manifestConfig?.redisUrl ||\n adapter?.env.get(\"VERYFRONT_BUNDLE_MANIFEST_REDIS_URL\");\n store = new RedisBundleManifestStore(\n {\n url: redisUrl,\n keyPrefix: manifestConfig?.keyPrefix,\n },\n adapter,\n );\n\n const available = await store.isAvailable();\n if (!available) {\n logger.warn(\"[bundle-manifest] Redis not available, falling back to in-memory\");\n store = new InMemoryBundleManifestStore();\n } else {\n logger.info(\"[bundle-manifest] Redis store initialized\");\n }\n break;\n }\n\n case \"kv\": {\n const { KVBundleManifestStore } = await import(\"./bundle-manifest-kv.ts\");\n store = new KVBundleManifestStore({\n keyPrefix: manifestConfig?.keyPrefix,\n });\n\n const available = await store.isAvailable();\n if (!available) {\n logger.warn(\"[bundle-manifest] KV not available, falling back to in-memory\");\n store = new InMemoryBundleManifestStore();\n } else {\n logger.info(\"[bundle-manifest] KV store initialized\");\n }\n break;\n }\n\n case \"memory\":\n default: {\n store = new InMemoryBundleManifestStore();\n logger.info(\"[bundle-manifest] In-memory store initialized\");\n break;\n }\n }\n\n setBundleManifestStore(store);\n\n try {\n const stats = await store.getStats();\n logger.info(\"[bundle-manifest] Store statistics\", stats);\n } catch (error) {\n logger.debug(\"[bundle-manifest] Failed to get stats\", { error });\n }\n } catch (error) {\n logger.error(\"[bundle-manifest] Failed to initialize store, using in-memory fallback\", {\n error,\n });\n setBundleManifestStore(new InMemoryBundleManifestStore());\n }\n}\n\nexport function getBundleManifestTTL(\n config: VeryfrontConfig,\n mode: \"development\" | \"production\",\n): number | undefined {\n const manifestConfig = config.cache?.bundleManifest;\n if (manifestConfig?.ttl) {\n return manifestConfig.ttl;\n }\n\n if (mode === \"production\") {\n return BUNDLE_MANIFEST_PROD_TTL_MS;\n } else {\n return BUNDLE_MANIFEST_DEV_TTL_MS;\n }\n}\n\nexport async function warmupBundleManifest(\n store: BundleManifestStore,\n keys: string[],\n): Promise<void> {\n logger.info(\"[bundle-manifest] Warming up cache\", { keys: keys.length });\n\n let loaded = 0;\n let failed = 0;\n\n for (const key of keys) {\n try {\n const metadata = await store.getBundleMetadata(key);\n if (metadata) {\n await store.getBundleCode(metadata.codeHash);\n loaded++;\n }\n } catch (error) {\n logger.debug(\"[bundle-manifest] Failed to warm up key\", { key, error });\n failed++;\n }\n }\n\n logger.info(\"[bundle-manifest] Cache warmup complete\", { loaded, failed });\n}\n", "declare const process: { env: Record<string, string | undefined> } | undefined;\nimport { getEnv } from \"../../platform/compat/process.ts\";\n\n/**\n * Checks if React Server Components (RSC) are enabled.\n *\n * Priority order:\n * 1. Config file (config.experimental.rsc)\n * 2. Environment variables (VERYFRONT_EXPERIMENTAL_RSC=1)\n * 3. Default (false)\n *\n * @param config - Optional config object to check first\n * @returns true if RSC is enabled, false otherwise\n */\nexport function isRSCEnabled(config?: { experimental?: { rsc?: boolean } }): boolean {\n // 1. Check config first (highest priority)\n if (config?.experimental?.rsc !== undefined) {\n return config.experimental.rsc;\n }\n\n // 2. Fallback to environment variables (backward compatibility)\n return getEnv(\"VERYFRONT_EXPERIMENTAL_RSC\") === \"1\";\n}\n", "/**\n * Platform detection utilities\n */\n\nimport { isDeno } from \"../../platform/compat/runtime.ts\";\nimport { execPath } from \"../../platform/compat/process.ts\";\n\n/**\n * Detect if the code is running in a compiled Deno binary\n * @returns true if running in a compiled binary, false otherwise\n */\nexport function isCompiledBinary(): boolean {\n if (!isDeno) return false;\n\n try {\n const path = execPath();\n return path.includes(\"veryfront\");\n } catch {\n return false;\n }\n}\n", "export * from \"./runtime-guards.ts\";\n\nexport * from \"./logger/index.ts\";\n\nexport * from \"./constants/index.ts\";\nexport { VERSION } from \"./version.ts\";\n\nexport * from \"./paths.ts\";\n\nexport {\n type BundleCode as HashBundleCode, // Alias to avoid conflict with bundle-manifest\n computeCodeHash,\n computeContentHash,\n computeHash,\n getContentHash,\n shortHash,\n simpleHash,\n simpleHash as numericHash, // Alias to avoid conflict with memoize\n} from \"./hash-utils.ts\";\n\nexport {\n MemoCache,\n memoize,\n memoizeAsync,\n simpleHash as memoizeHash, // Alias to distinguish from hash-utils version\n} from \"./memoize.ts\";\n\nexport * from \"./path-utils.ts\";\n\nexport * from \"./format-utils.ts\";\n\nexport * from \"./bundle-manifest.ts\";\nexport * from \"./bundle-manifest-init.ts\";\n\nexport * from \"./feature-flags.ts\";\n\nexport { isCompiledBinary } from \"./platform.ts\";\n", "export interface BuildContext {\n file?: string;\n line?: number;\n column?: number;\n moduleId?: string;\n phase?: \"parse\" | \"transform\" | \"bundle\" | \"optimize\";\n}\n\nexport interface APIContext {\n endpoint?: string;\n method?: string;\n statusCode?: number;\n headers?: Record<string, string>;\n}\n\nexport interface RenderContext {\n component?: string;\n route?: string;\n phase?: \"server\" | \"client\" | \"hydration\";\n props?: unknown;\n}\n\nexport interface ConfigContext {\n configFile?: string;\n field?: string;\n value?: unknown;\n expected?: string;\n}\n\nexport interface AgentContext {\n agentId?: string;\n intent?: string;\n timeout?: number;\n}\n\nexport interface FileContext {\n path?: string;\n operation?: \"read\" | \"write\" | \"delete\" | \"mkdir\";\n permissions?: string;\n}\n\nexport interface NetworkContext {\n url?: string;\n timeout?: number;\n retryCount?: number;\n}\n\nexport type VeryfrontError =\n | { type: \"build\"; message: string; context?: BuildContext }\n | { type: \"api\"; message: string; context?: APIContext }\n | { type: \"render\"; message: string; context?: RenderContext }\n | { type: \"config\"; message: string; context?: ConfigContext }\n | { type: \"agent\"; message: string; context?: AgentContext }\n | { type: \"file\"; message: string; context?: FileContext }\n | { type: \"network\"; message: string; context?: NetworkContext }\n | { type: \"permission\"; message: string; context?: FileContext }\n | { type: \"not_supported\"; message: string; feature?: string };\n\nexport function createError(error: VeryfrontError): VeryfrontError {\n return error;\n}\n\nexport function isBuildError(\n error: VeryfrontError,\n): error is Extract<VeryfrontError, { type: \"build\" }> {\n return error.type === \"build\";\n}\n\nexport function isAPIError(\n error: VeryfrontError,\n): error is Extract<VeryfrontError, { type: \"api\" }> {\n return error.type === \"api\";\n}\n\nexport function isRenderError(\n error: VeryfrontError,\n): error is Extract<VeryfrontError, { type: \"render\" }> {\n return error.type === \"render\";\n}\n\nexport function isConfigError(\n error: VeryfrontError,\n): error is Extract<VeryfrontError, { type: \"config\" }> {\n return error.type === \"config\";\n}\n\nexport function isAgentError(\n error: VeryfrontError,\n): error is Extract<VeryfrontError, { type: \"agent\" }> {\n return error.type === \"agent\";\n}\n\nexport function isFileError(\n error: VeryfrontError,\n): error is Extract<VeryfrontError, { type: \"file\" }> {\n return error.type === \"file\";\n}\n\nexport function isNetworkError(\n error: VeryfrontError,\n): error is Extract<VeryfrontError, { type: \"network\" }> {\n return error.type === \"network\";\n}\n\nexport function toError(veryfrontError: VeryfrontError): Error {\n const error = new Error(veryfrontError.message);\n error.name = `VeryfrontError[${veryfrontError.type}]`;\n Object.defineProperty(error, \"context\", {\n value: veryfrontError,\n enumerable: false,\n configurable: true,\n });\n return error;\n}\n\nexport function fromError(error: unknown): VeryfrontError | null {\n if (error && typeof error === \"object\" && \"context\" in error) {\n // Safe access after 'in' check\n const context = (error as Record<string, unknown>).context;\n if (\n context &&\n typeof context === \"object\" &&\n \"type\" in context &&\n \"message\" in context\n ) {\n return context as VeryfrontError;\n }\n }\n return null;\n}\n\nexport function logError(\n error: VeryfrontError,\n logger?: { error: (msg: string, ...args: unknown[]) => void },\n): void {\n const log = logger || console;\n const context = \"context\" in error ? error.context || {} : {};\n log.error(`[${error.type}] ${error.message}`, context);\n}\n", "import { z } from \"zod\";\nimport type { VeryfrontConfig } from \"./types.ts\";\nimport { type ConfigContext, createError, toError } from \"../errors/veryfront-error.ts\";\n\nconst corsSchema = z.union([z.boolean(), z.object({ origin: z.string().optional() }).strict()]);\n\nexport const veryfrontConfigSchema = z\n .object({\n title: z.string().optional(),\n description: z.string().optional(),\n experimental: z.object({\n esmLayouts: z.boolean().optional(),\n precompileMDX: z.boolean().optional(),\n }).partial().optional(),\n router: z.enum([\"app\", \"pages\"]).optional(),\n defaultLayout: z.string().optional(),\n theme: z\n .object({ colors: z.record(z.string()).optional() })\n .partial()\n .optional(),\n build: z\n .object({\n outDir: z.string().optional(),\n trailingSlash: z.boolean().optional(),\n esbuild: z\n .object({\n wasmURL: z.string().url().optional(),\n worker: z.boolean().optional(),\n })\n .partial()\n .optional(),\n })\n .partial()\n .optional(),\n cache: z\n .object({\n dir: z.string().optional(),\n bundleManifest: z\n .object({\n type: z.enum([\"redis\", \"kv\", \"memory\"]).optional(),\n redisUrl: z.string().optional(),\n keyPrefix: z.string().optional(),\n ttl: z.number().int().positive().optional(),\n enabled: z.boolean().optional(),\n })\n .partial()\n .optional(),\n })\n .partial()\n .optional(),\n dev: z\n .object({\n port: z.number().int().positive().optional(),\n host: z.string().optional(),\n open: z.boolean().optional(),\n hmr: z.boolean().optional(),\n components: z.array(z.string()).optional(),\n })\n .partial()\n .optional(),\n resolve: z\n .object({\n importMap: z\n .object({\n imports: z.record(z.string()).optional(),\n scopes: z.record(z.record(z.string())).optional(),\n })\n .partial()\n .optional(),\n })\n .partial()\n .optional(),\n security: z\n .object({\n csp: z.record(z.array(z.string())).optional(),\n remoteHosts: z.array(z.string().url()).optional(),\n cors: corsSchema.optional(),\n coop: z.enum([\"same-origin\", \"same-origin-allow-popups\", \"unsafe-none\"]).optional(),\n corp: z.enum([\"same-origin\", \"same-site\", \"cross-origin\"]).optional(),\n coep: z.enum([\"require-corp\", \"unsafe-none\"]).optional(),\n })\n .partial()\n .optional(),\n middleware: z\n .object({\n custom: z.array(z.function()).optional(),\n })\n .partial()\n .optional(),\n theming: z\n .object({\n brandName: z.string().optional(),\n logoHtml: z.string().optional(),\n })\n .partial()\n .optional(),\n assetPipeline: z\n .object({\n images: z\n .object({\n enabled: z.boolean().optional(),\n formats: z.array(z.enum([\"webp\", \"avif\", \"jpeg\", \"png\"])).optional(),\n sizes: z.array(z.number().int().positive()).optional(),\n quality: z.number().int().min(1).max(100).optional(),\n inputDir: z.string().optional(),\n outputDir: z.string().optional(),\n preserveOriginal: z.boolean().optional(),\n })\n .partial()\n .optional(),\n css: z\n .object({\n enabled: z.boolean().optional(),\n minify: z.boolean().optional(),\n autoprefixer: z.boolean().optional(),\n purge: z.boolean().optional(),\n criticalCSS: z.boolean().optional(),\n inputDir: z.string().optional(),\n outputDir: z.string().optional(),\n browsers: z.array(z.string()).optional(),\n purgeContent: z.array(z.string()).optional(),\n sourceMap: z.boolean().optional(),\n })\n .partial()\n .optional(),\n })\n .partial()\n .optional(),\n observability: z\n .object({\n tracing: z\n .object({\n enabled: z.boolean().optional(),\n exporter: z.enum([\"jaeger\", \"zipkin\", \"otlp\", \"console\"]).optional(),\n endpoint: z.string().optional(),\n serviceName: z.string().optional(),\n sampleRate: z.number().min(0).max(1).optional(),\n })\n .partial()\n .optional(),\n metrics: z\n .object({\n enabled: z.boolean().optional(),\n exporter: z.enum([\"prometheus\", \"otlp\", \"console\"]).optional(),\n endpoint: z.string().optional(),\n prefix: z.string().optional(),\n collectInterval: z.number().int().positive().optional(),\n })\n .partial()\n .optional(),\n })\n .partial()\n .optional(),\n fs: z\n .object({\n type: z.enum([\"local\", \"veryfront-api\", \"memory\"]).optional(),\n local: z\n .object({\n baseDir: z.string().optional(),\n })\n .partial()\n .optional(),\n veryfront: z\n .object({\n apiBaseUrl: z.string().url(),\n apiToken: z.string(),\n projectSlug: z.string(),\n cache: z\n .object({\n enabled: z.boolean().optional(),\n ttl: z.number().int().positive().optional(),\n maxSize: z.number().int().positive().optional(),\n })\n .partial()\n .optional(),\n retry: z\n .object({\n maxRetries: z.number().int().min(0).optional(),\n initialDelay: z.number().int().positive().optional(),\n maxDelay: z.number().int().positive().optional(),\n })\n .partial()\n .optional(),\n })\n .partial()\n .optional(),\n memory: z\n .object({\n files: z.record(z.union([z.string(), z.instanceof(Uint8Array)])).optional(),\n })\n .partial()\n .optional(),\n })\n .partial()\n .optional(),\n client: z\n .object({\n moduleResolution: z.enum([\"cdn\", \"self-hosted\", \"bundled\"]).optional(),\n cdn: z\n .object({\n provider: z.enum([\"esm.sh\", \"unpkg\", \"jsdelivr\"]).optional(),\n versions: z\n .union([\n z.literal(\"auto\"),\n z.object({\n react: z.string().optional(),\n veryfront: z.string().optional(),\n }),\n ])\n .optional(),\n })\n .partial()\n .optional(),\n })\n .partial()\n .optional(),\n })\n .partial();\n\nexport type VeryfrontConfigInput = z.input<typeof veryfrontConfigSchema>;\n\nexport function validateVeryfrontConfig(input: unknown): VeryfrontConfig {\n const parsed = veryfrontConfigSchema.safeParse(input);\n if (!parsed.success) {\n const first = parsed.error.issues[0];\n const path = first?.path?.length ? first.path.join(\".\") : \"<root>\";\n const expected = first?.message || String(first);\n let hint = \"\";\n if (String(path).includes(\"security.cors\")) {\n hint = \" Expected boolean or { origin?: string }.\";\n }\n\n const context: ConfigContext = {\n field: path,\n expected: expected + hint,\n value: input,\n };\n\n throw toError(\n createError({\n type: \"config\",\n message: `Invalid veryfront.config at ${path}: ${expected}.${hint}`,\n context,\n }),\n );\n }\n return parsed.data as VeryfrontConfig;\n}\n\nexport function findUnknownTopLevelKeys(input: Record<string, unknown>): string[] {\n const known = new Set([\n \"title\",\n \"description\",\n \"experimental\",\n \"router\",\n \"defaultLayout\",\n \"theme\",\n \"build\",\n \"cache\",\n \"dev\",\n \"resolve\",\n \"security\",\n \"middleware\",\n \"theming\",\n \"assetPipeline\",\n \"observability\",\n \"fs\",\n \"client\",\n ]);\n return Object.keys(input).filter((k) => !known.has(k));\n}\n", "import type { VeryfrontConfig } from \"./types.ts\";\nimport { findUnknownTopLevelKeys, validateVeryfrontConfig } from \"./schema.ts\";\nimport { join } from \"std/path/mod.ts\";\nimport type { RuntimeAdapter } from \"@veryfront/platform/adapters/base.ts\";\nimport { serverLogger } from \"@veryfront/utils/logger/logger.ts\";\nimport { getReactImportMap, REACT_DEFAULT_VERSION } from \"@veryfront/utils/constants/cdn.ts\";\nimport { DEFAULT_CACHE_DIR } from \"@veryfront/utils/constants/server.ts\";\nimport { DEFAULT_PORT } from \"./defaults.ts\";\n\nexport type { VeryfrontConfig } from \"./types.ts\";\n\nfunction getDefaultImportMapForConfig() {\n return { imports: getReactImportMap(REACT_DEFAULT_VERSION) };\n}\n\nconst DEFAULT_CONFIG: Partial<VeryfrontConfig> = {\n title: \"Veryfront App\",\n description: \"Built with Veryfront\",\n experimental: {\n esmLayouts: true,\n },\n router: undefined,\n defaultLayout: undefined,\n theme: {\n colors: {\n primary: \"#3B82F6\",\n },\n },\n build: {\n outDir: \"dist\",\n trailingSlash: false,\n esbuild: {\n wasmURL: \"https://deno.land/x/esbuild@v0.20.1/esbuild.wasm\",\n worker: false,\n },\n },\n cache: {\n dir: DEFAULT_CACHE_DIR,\n render: {\n type: \"memory\",\n ttl: undefined,\n maxEntries: 500,\n kvPath: undefined,\n redisUrl: undefined,\n redisKeyPrefix: undefined,\n },\n },\n dev: {\n port: DEFAULT_PORT,\n host: \"localhost\",\n open: false,\n },\n resolve: {\n importMap: getDefaultImportMapForConfig(),\n },\n client: {\n moduleResolution: \"cdn\",\n cdn: {\n provider: \"esm.sh\",\n versions: \"auto\",\n },\n },\n};\n\nconst configCacheByProject = new Map<string, { revision: number; config: VeryfrontConfig }>();\nlet cacheRevision = 0;\n\nfunction validateCorsConfig(userConfig: unknown): void {\n if (!userConfig || typeof userConfig !== \"object\") {\n return;\n }\n const config = userConfig as Record<string, unknown>;\n const security = config.security as Record<string, unknown> | undefined;\n const cors = security?.cors;\n if (!cors || typeof cors !== \"object\" || Array.isArray(cors)) {\n return;\n }\n\n const corsObj = cors as Record<string, unknown>;\n const origin = corsObj.origin;\n if (origin !== undefined && typeof origin !== \"string\") {\n throw new ConfigValidationError(\n \"security.cors.origin must be a string. Expected boolean or { origin?: string }\",\n );\n }\n}\n\nfunction validateConfigShape(userConfig: unknown): void {\n validateVeryfrontConfig(userConfig);\n const unknown = typeof userConfig === \"object\" && userConfig\n ? findUnknownTopLevelKeys(userConfig as Record<string, unknown>)\n : [];\n if (unknown.length > 0) {\n serverLogger.warn(`Unknown config keys: ${unknown.join(\", \")}. These will be ignored.`);\n }\n}\n\nfunction mergeConfigs(userConfig: Partial<VeryfrontConfig>): VeryfrontConfig {\n const merged: VeryfrontConfig = {\n ...DEFAULT_CONFIG,\n ...userConfig,\n dev: {\n ...DEFAULT_CONFIG.dev,\n ...userConfig.dev,\n },\n theme: {\n ...DEFAULT_CONFIG.theme,\n ...userConfig.theme,\n },\n build: {\n ...DEFAULT_CONFIG.build,\n ...userConfig.build,\n },\n cache: {\n ...DEFAULT_CONFIG.cache,\n ...userConfig.cache,\n },\n resolve: {\n ...DEFAULT_CONFIG.resolve,\n ...userConfig.resolve,\n },\n client: {\n ...DEFAULT_CONFIG.client,\n ...userConfig.client,\n cdn: {\n ...DEFAULT_CONFIG.client?.cdn,\n ...userConfig.client?.cdn,\n },\n },\n } as VeryfrontConfig;\n\n if (merged.resolve) {\n const defaultMap = DEFAULT_CONFIG.resolve?.importMap;\n const userMap = userConfig.resolve?.importMap;\n\n if (defaultMap || userMap) {\n merged.resolve.importMap = {\n imports: {\n ...(defaultMap?.imports ?? {}),\n ...(userMap?.imports ?? {}),\n },\n scopes: {\n ...(defaultMap?.scopes ?? {}),\n ...(userMap?.scopes ?? {}),\n },\n };\n }\n }\n\n return merged;\n}\n\nclass ConfigValidationError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"ConfigValidationError\";\n }\n}\n\nasync function loadAndMergeConfig(\n configPath: string,\n projectDir: string,\n): Promise<VeryfrontConfig | null> {\n try {\n const configUrl = `file://${configPath}?t=${Date.now()}-${crypto.randomUUID()}`;\n const configModule = await import(configUrl);\n const userConfig = configModule.default || configModule;\n\n if (userConfig === null || typeof userConfig !== \"object\" || Array.isArray(userConfig)) {\n throw new ConfigValidationError(\n `Expected object, received ${userConfig === null ? \"null\" : typeof userConfig}`,\n );\n }\n\n validateCorsConfig(userConfig);\n validateConfigShape(userConfig);\n\n const merged = mergeConfigs(userConfig);\n configCacheByProject.set(projectDir, { revision: cacheRevision, config: merged });\n return merged;\n } catch (error) {\n if (error instanceof ConfigValidationError) {\n throw error;\n }\n\n if (error instanceof Error && error.message.startsWith(\"Invalid veryfront.config\")) {\n throw error;\n }\n\n throw error;\n }\n}\n\nexport async function getConfig(\n projectDir: string,\n adapter: RuntimeAdapter,\n): Promise<VeryfrontConfig> {\n const cached = configCacheByProject.get(projectDir);\n if (cached && cached.revision === cacheRevision) return cached.config;\n\n const configFiles = [\"veryfront.config.js\", \"veryfront.config.ts\", \"veryfront.config.mjs\"];\n\n for (const configFile of configFiles) {\n const configPath = join(projectDir, configFile);\n\n const exists = await adapter.fs.exists(configPath);\n if (!exists) continue;\n\n try {\n const merged = await loadAndMergeConfig(configPath, projectDir);\n if (merged) return merged;\n } catch (error) {\n if (error instanceof ConfigValidationError) {\n throw error;\n }\n\n if (error instanceof Error && error.message.startsWith(\"Invalid veryfront.config\")) {\n throw error;\n }\n\n // Only log at debug level - this is expected when .ts exists but .js is tried first\n const errorMessage = error instanceof Error ? error.message : String(error);\n serverLogger.debug(`[CONFIG] Failed to load ${configFile}, trying next config file:`, {\n error: errorMessage,\n });\n\n continue;\n }\n }\n\n const defaultConfig = DEFAULT_CONFIG as VeryfrontConfig;\n configCacheByProject.set(projectDir, { revision: cacheRevision, config: defaultConfig });\n return defaultConfig;\n}\n\nexport function clearConfigCache() {\n configCacheByProject.clear();\n cacheRevision++;\n}\n", "import type { VeryfrontConfig } from \"./types.ts\";\nimport { createError, toError } from \"../../core/errors/veryfront-error.ts\";\nimport { getEnv } from \"../../platform/compat/process.ts\";\n\nexport function defineConfig(config: VeryfrontConfig): VeryfrontConfig {\n return config;\n}\n\nexport function defineConfigWithEnv(\n factory: (env: string) => VeryfrontConfig,\n): VeryfrontConfig {\n const env = getEnv(\"NODE_ENV\") || \"development\";\n return factory(env);\n}\n\nexport function mergeConfigs(\n ...configs: Partial<VeryfrontConfig>[]\n): VeryfrontConfig {\n const merged: Partial<VeryfrontConfig> = {};\n\n for (const config of configs) {\n Object.assign(merged, config);\n }\n\n return merged as VeryfrontConfig;\n}\n\nexport async function validateConfig(config: unknown): Promise<void> {\n if (!config || typeof config !== \"object\") {\n throw toError(createError({\n type: \"config\",\n message: \"Configuration must be an object\",\n }));\n }\n\n const cfg = config as Record<string, unknown>;\n\n if (cfg.dev && typeof cfg.dev === \"object\") {\n const dev = cfg.dev as Record<string, unknown>;\n if (dev.port !== undefined) {\n const { MIN_PORT, MAX_PORT } = await import(\"../utils/constants/network.ts\");\n if (typeof dev.port !== \"number\" || dev.port < MIN_PORT || dev.port > MAX_PORT) {\n throw toError(createError({\n type: \"config\",\n message: `dev.port must be a number between ${MIN_PORT} and ${MAX_PORT}`,\n context: {\n field: \"dev.port\",\n value: dev.port,\n expected: `number between ${MIN_PORT} and ${MAX_PORT}`,\n },\n }));\n }\n }\n }\n\n if (cfg.build && typeof cfg.build === \"object\") {\n const build = cfg.build as Record<string, unknown>;\n if (build.outDir !== undefined && typeof build.outDir !== \"string\") {\n throw toError(createError({\n type: \"config\",\n message: \"build.outDir must be a string\",\n context: { field: \"build.outDir\", value: build.outDir, expected: \"string\" },\n }));\n }\n }\n}\n", "export const LOCALHOST = {\n IPV4: \"127.0.0.1\",\n IPV6: \"::1\",\n HOSTNAME: \"localhost\",\n} as const;\n\nexport const HTTP_DEFAULTS = {\n PORT: 3000,\n HOST: \"localhost\",\n PROD_HOST: \"0.0.0.0\",\n} as const;\n\nexport const REDIS_DEFAULTS = {\n URL: \"redis://127.0.0.1:6379\",\n PORT: 6379,\n HOST: \"127.0.0.1\",\n} as const;\n\nexport const DEV_LOCALHOST_ORIGINS = [\n \"http://localhost\",\n \"http://127.0.0.1\",\n \"https://localhost\",\n \"https://127.0.0.1\",\n] as const;\n\nexport const DEV_LOCALHOST_CSP = {\n WS: \"ws://localhost:* wss://localhost:*\",\n HTTP: \"http://localhost\",\n} as const;\n\nexport const LOCALHOST_URLS = {\n HTTP: \"http://localhost\",\n HTTPS: \"https://localhost\",\n HTTP_IPV4: \"http://127.0.0.1\",\n HTTPS_IPV4: \"https://127.0.0.1\",\n} as const;\n\nexport function buildLocalhostUrl(\n port: number,\n protocol: \"http\" | \"https\" = \"http\",\n): string {\n return `${protocol}://${LOCALHOST.HOSTNAME}:${port}`;\n}\n\nexport function buildIpv4Url(\n port: number,\n protocol: \"http\" | \"https\" = \"http\",\n): string {\n return `${protocol}://${LOCALHOST.IPV4}:${port}`;\n}\n", "export { clearConfigCache, getConfig } from \"./loader.ts\";\n\nexport { defineConfig } from \"./define-config.ts\";\n\nexport type { VeryfrontConfig } from \"./types.ts\";\n\nexport {\n findUnknownTopLevelKeys,\n validateVeryfrontConfig,\n veryfrontConfigSchema,\n} from \"./schema.ts\";\n\nexport {\n DEFAULT_CACHE_MAX_SIZE,\n DEFAULT_METRICS_COLLECT_INTERVAL_MS,\n DEFAULT_PORT,\n DEFAULT_PREFETCH_DELAY_MS,\n DEFAULT_REDIS_BATCH_DELETE_SIZE,\n DEFAULT_REDIS_SCAN_COUNT,\n DEFAULT_TIMEOUT_MS,\n type DefaultConfig,\n defaultConfig,\n DURATION_HISTOGRAM_BOUNDARIES_MS,\n PAGE_TRANSITION_DELAY_MS,\n SANDBOX_TIMEOUT_MS,\n SIZE_HISTOGRAM_BOUNDARIES_KB,\n SSR_TIMEOUT_MS,\n} from \"./defaults.ts\";\n\nexport {\n buildIpv4Url,\n buildLocalhostUrl,\n DEV_LOCALHOST_CSP,\n DEV_LOCALHOST_ORIGINS,\n HTTP_DEFAULTS,\n LOCALHOST,\n LOCALHOST_URLS,\n REDIS_DEFAULTS,\n} from \"./network-defaults.ts\";\n", "import { createError, toError } from \"../../core/errors/veryfront-error.ts\";\nimport type {\n DirEntry,\n EnvironmentAdapter,\n FileChangeEvent,\n FileChangeKind,\n FileInfo,\n FileSystemAdapter,\n FileWatcher,\n RuntimeAdapter,\n RuntimeFeatures,\n ServeOptions,\n Server,\n ServerAdapter,\n ShellAdapter,\n WatchOptions,\n WebSocketUpgrade,\n} from \"./base.ts\";\nimport { DEFAULT_PORT } from \"@veryfront/config\";\nimport { serverLogger } from \"@veryfront/utils\";\n\nclass DenoFileSystemAdapter implements FileSystemAdapter {\n async readFile(path: string): Promise<string> {\n return await Deno.readTextFile(path);\n }\n\n async readFileBytes(path: string): Promise<Uint8Array> {\n return await Deno.readFile(path);\n }\n\n async writeFile(path: string, content: string): Promise<void> {\n await Deno.writeTextFile(path, content);\n }\n\n async exists(path: string): Promise<boolean> {\n try {\n await Deno.stat(path);\n return true;\n } catch (_error) {\n return false;\n }\n }\n\n async *readDir(path: string): AsyncIterable<DirEntry> {\n for await (const entry of Deno.readDir(path)) {\n yield {\n name: entry.name,\n isFile: entry.isFile,\n isDirectory: entry.isDirectory,\n isSymlink: entry.isSymlink,\n };\n }\n }\n\n async stat(path: string): Promise<FileInfo> {\n const stat = await Deno.stat(path);\n return {\n size: stat.size,\n isFile: stat.isFile,\n isDirectory: stat.isDirectory,\n isSymlink: stat.isSymlink,\n mtime: stat.mtime,\n };\n }\n\n async mkdir(path: string, options?: { recursive?: boolean }): Promise<void> {\n await Deno.mkdir(path, options);\n }\n\n async remove(path: string, options?: { recursive?: boolean }): Promise<void> {\n await Deno.remove(path, options);\n }\n\n async makeTempDir(prefix: string): Promise<string> {\n return await Deno.makeTempDir({ prefix });\n }\n\n watch(paths: string | string[], options?: WatchOptions): FileWatcher {\n const pathArray = Array.isArray(paths) ? paths : [paths];\n const recursive = options?.recursive ?? true;\n const signal = options?.signal;\n\n const watcher = Deno.watchFs(pathArray, { recursive });\n let closed = false;\n\n const denoIterator = watcher[Symbol.asyncIterator]();\n\n const mapEventKind = (kind: string): FileChangeKind => {\n switch (kind) {\n case \"create\":\n return \"create\";\n case \"modify\":\n return \"modify\";\n case \"remove\":\n return \"delete\";\n default:\n return \"any\";\n }\n };\n\n const iterator: AsyncIterator<FileChangeEvent> = {\n async next(): Promise<IteratorResult<FileChangeEvent>> {\n if (closed || signal?.aborted) {\n return { done: true, value: undefined };\n }\n\n try {\n const result = await denoIterator.next();\n if (result.done) {\n return { done: true, value: undefined };\n }\n\n return {\n done: false,\n value: {\n kind: mapEventKind(result.value.kind),\n paths: result.value.paths,\n },\n };\n } catch (error) {\n if (closed || signal?.aborted) {\n return { done: true, value: undefined };\n }\n throw error;\n }\n },\n\n async return(): Promise<IteratorResult<FileChangeEvent>> {\n closed = true;\n if (denoIterator.return) {\n await denoIterator.return();\n }\n return { done: true, value: undefined };\n },\n };\n\n const cleanup = () => {\n if (closed) return;\n closed = true;\n try {\n if (\"close\" in watcher && typeof watcher.close === \"function\") {\n watcher.close();\n }\n } catch (error) {\n serverLogger.debug(\"[Deno] Filesystem watcher cleanup failed\", { error });\n }\n };\n\n if (signal) {\n signal.addEventListener(\"abort\", cleanup);\n }\n\n return {\n [Symbol.asyncIterator]() {\n return iterator;\n },\n close: cleanup,\n };\n }\n}\n\nclass DenoEnvironmentAdapter implements EnvironmentAdapter {\n get(key: string): string | undefined {\n return Deno.env.get(key);\n }\n\n set(key: string, value: string): void {\n Deno.env.set(key, value);\n }\n\n toObject(): Record<string, string> {\n return Deno.env.toObject();\n }\n}\n\nclass DenoServerAdapter implements ServerAdapter {\n upgradeWebSocket(request: Request): WebSocketUpgrade {\n const { socket, response } = Deno.upgradeWebSocket(request);\n return { socket, response };\n }\n}\n\nclass DenoShellAdapter implements ShellAdapter {\n statSync(path: string): { isFile: boolean; isDirectory: boolean } {\n try {\n const stat = Deno.statSync(path);\n return {\n isFile: stat.isFile,\n isDirectory: stat.isDirectory,\n };\n } catch (error) {\n throw toError(createError({\n type: \"file\",\n message: `Failed to stat file: ${error}`,\n }));\n }\n }\n\n readFileSync(path: string): string {\n try {\n return Deno.readTextFileSync(path);\n } catch (error) {\n throw toError(createError({\n type: \"file\",\n message: `Failed to read file: ${error}`,\n }));\n }\n }\n}\n\nclass DenoServer implements Server {\n constructor(\n private server: Deno.HttpServer,\n private hostname: string,\n private port: number,\n private abortController?: AbortController,\n ) {}\n\n async stop(): Promise<void> {\n try {\n if (this.abortController) {\n this.abortController.abort();\n }\n\n await this.server.shutdown();\n } catch (error) {\n serverLogger.debug(\"[Deno] Server shutdown failed\", { error });\n }\n }\n\n get addr() {\n return { hostname: this.hostname, port: this.port };\n }\n}\n\nexport class DenoAdapter implements RuntimeAdapter {\n readonly id = \"deno\" as const;\n readonly name = \"deno\";\n /** @deprecated Use `id` instead */\n readonly platform = \"deno\" as const;\n\n fs = new DenoFileSystemAdapter();\n env = new DenoEnvironmentAdapter();\n server = new DenoServerAdapter();\n shell = new DenoShellAdapter();\n\n readonly capabilities = {\n typescript: true,\n jsx: true,\n http2: true,\n websocket: true,\n workers: true,\n fileWatching: true,\n shell: true,\n kvStore: true, // Deno KV available\n writableFs: true,\n };\n\n /** @deprecated Use `capabilities` instead */\n readonly features: RuntimeFeatures = {\n websocket: true,\n http2: true,\n workers: true,\n jsx: true,\n typescript: true,\n };\n\n serve(\n handler: (request: Request) => Promise<Response> | Response,\n options: ServeOptions = {},\n ): Promise<Server> {\n const { port = DEFAULT_PORT, hostname = \"localhost\", onListen } = options;\n\n const controller = new AbortController();\n const signal = options.signal || controller.signal;\n\n const server = Deno.serve({\n port,\n hostname,\n signal,\n handler: async (request, _info) => {\n try {\n return await handler(request);\n } catch (error) {\n const { serverLogger } = await import(\"@veryfront/utils\");\n serverLogger.error(\"Request handler error:\", error);\n return new Response(\"Internal Server Error\", { status: 500 });\n }\n },\n onListen: (params) => {\n onListen?.({ hostname: params.hostname, port: params.port });\n },\n });\n\n const controllerToPass = options.signal ? undefined : controller;\n return Promise.resolve(new DenoServer(server, hostname, port, controllerToPass));\n }\n}\n\nexport const denoAdapter = new DenoAdapter();\n", "import type { FileChangeEvent, FileChangeKind, FileWatcher } from \"./base.ts\";\nimport { join } from \"node:path\";\n\nexport async function setupNodeFsWatcher(\n path: string,\n options: {\n recursive: boolean;\n closed: () => boolean;\n signal: AbortSignal | undefined;\n eventQueue: FileChangeEvent[];\n getResolver: () => ((value: IteratorResult<FileChangeEvent>) => void) | null;\n setResolver: (resolver: ((value: IteratorResult<FileChangeEvent>) => void) | null) => void;\n watchers: Array<import(\"node:fs\").FSWatcher>;\n onError: (error: Error, path: string) => void;\n },\n): Promise<void> {\n try {\n const fs = await import(\"node:fs\");\n const fsPromises = await import(\"node:fs/promises\");\n\n const exists = await fsPromises.access(path).then(() => true).catch(() => false);\n if (!exists) return;\n\n const watcher = fs.watch(path, { recursive: options.recursive }, (eventType, filename) => {\n if (options.closed() || options.signal?.aborted) return;\n\n const kind: FileChangeKind = eventType === \"change\" ? \"modify\" : \"any\";\n const fullPath = filename ? join(path, filename) : path;\n\n enqueueWatchEvent(\n { kind, paths: [fullPath] },\n options.eventQueue,\n options.getResolver,\n options.setResolver,\n );\n });\n\n watcher.on(\"error\", (error: Error) => {\n if (!options.closed() && !options.signal?.aborted) {\n options.onError(error, path);\n }\n });\n\n options.watchers.push(watcher);\n } catch (error) {\n options.onError(error as Error, path);\n }\n}\n\nexport function createWatcherIterator(\n eventQueue: FileChangeEvent[],\n _getResolver: () => ((value: IteratorResult<FileChangeEvent>) => void) | null,\n setResolver: (r: ((value: IteratorResult<FileChangeEvent>) => void) | null) => void,\n isClosed: () => boolean,\n isAborted: () => boolean,\n): AsyncIterator<FileChangeEvent> {\n return {\n next(): Promise<IteratorResult<FileChangeEvent>> {\n if (isClosed() || isAborted()) {\n return Promise.resolve({ done: true, value: undefined });\n }\n\n if (eventQueue.length > 0) {\n const event = eventQueue.shift()!;\n return Promise.resolve({ done: false, value: event });\n }\n\n return new Promise((resolve) => {\n if (isClosed() || isAborted()) {\n resolve({ done: true, value: undefined });\n return;\n }\n setResolver(resolve);\n });\n },\n\n return(): Promise<IteratorResult<FileChangeEvent>> {\n return Promise.resolve({ done: true, value: undefined });\n },\n };\n}\n\nexport function enqueueWatchEvent(\n event: FileChangeEvent,\n eventQueue: FileChangeEvent[],\n getResolver: () => ((value: IteratorResult<FileChangeEvent>) => void) | null,\n setResolver: (resolver: ((value: IteratorResult<FileChangeEvent>) => void) | null) => void,\n): void {\n const resolver = getResolver();\n if (resolver) {\n resolver({ done: false, value: event });\n setResolver(null);\n } else {\n eventQueue.push(event);\n }\n}\n\nexport function createFileWatcher(\n iterator: AsyncIterator<FileChangeEvent>,\n cleanup: () => void,\n): FileWatcher {\n return {\n [Symbol.asyncIterator]() {\n return iterator;\n },\n close: cleanup,\n };\n}\n", "import type { DirEntry, FileInfo, FileSystemAdapter, FileWatcher, WatchOptions } from \"../base.ts\";\nimport { createFileWatcher, createWatcherIterator, setupNodeFsWatcher } from \"../shared-watcher.ts\";\nimport { serverLogger } from \"@veryfront/utils\";\nimport type { FileChangeEvent } from \"../base.ts\";\n\nexport class NodeFileSystemAdapter implements FileSystemAdapter {\n async readFile(path: string): Promise<string> {\n const fs = await import(\"node:fs/promises\");\n return await fs.readFile(path, \"utf-8\");\n }\n\n async readFileBytes(path: string): Promise<Uint8Array> {\n const fs = await import(\"node:fs/promises\");\n const buffer = await fs.readFile(path);\n return buffer instanceof Uint8Array ? buffer : new Uint8Array(buffer);\n }\n\n async writeFile(path: string, content: string): Promise<void> {\n const fs = await import(\"node:fs/promises\");\n await fs.writeFile(path, content, \"utf-8\");\n }\n\n async exists(path: string): Promise<boolean> {\n const fs = await import(\"node:fs/promises\");\n try {\n await fs.access(path);\n return true;\n } catch (error) {\n serverLogger.debug(`File access check failed for ${path}:`, error);\n return false;\n }\n }\n\n async *readDir(path: string): AsyncIterable<DirEntry> {\n const fs = await import(\"node:fs/promises\");\n const entries = await fs.readdir(path, { withFileTypes: true });\n\n for (const entry of entries) {\n yield {\n name: entry.name,\n isFile: entry.isFile(),\n isDirectory: entry.isDirectory(),\n isSymlink: entry.isSymbolicLink(),\n };\n }\n }\n\n async stat(path: string): Promise<FileInfo> {\n const fs = await import(\"node:fs/promises\");\n const stats = await fs.stat(path);\n\n return {\n size: stats.size,\n isFile: stats.isFile(),\n isDirectory: stats.isDirectory(),\n isSymlink: stats.isSymbolicLink(),\n mtime: stats.mtime,\n };\n }\n\n async mkdir(path: string, options?: { recursive?: boolean }): Promise<void> {\n const fs = await import(\"node:fs/promises\");\n await fs.mkdir(path, options);\n }\n\n async remove(path: string, options?: { recursive?: boolean }): Promise<void> {\n const fs = await import(\"node:fs/promises\");\n await fs.rm(path, { recursive: options?.recursive, force: true });\n }\n\n async makeTempDir(prefix: string): Promise<string> {\n const { mkdtemp } = await import(\"node:fs/promises\");\n const { join } = await import(\"node:path\");\n const { tmpdir } = await import(\"node:os\");\n return await mkdtemp(join(tmpdir(), prefix));\n }\n\n watch(paths: string | string[], options?: WatchOptions): FileWatcher {\n const pathArray = Array.isArray(paths) ? paths : [paths];\n const recursive = options?.recursive ?? true;\n const signal = options?.signal;\n\n let closed = false;\n const watchers: Array<import(\"node:fs\").FSWatcher> = [];\n const eventQueue: FileChangeEvent[] = [];\n let resolver: ((value: IteratorResult<FileChangeEvent>) => void) | null = null;\n\n Promise.all(\n pathArray.map((path) =>\n setupNodeFsWatcher(path, {\n recursive,\n closed: () => closed,\n signal,\n eventQueue,\n getResolver: () => resolver,\n setResolver: (r) => {\n resolver = r;\n },\n watchers,\n onError: (error, path) => serverLogger.error(`File watcher error for ${path}:`, error),\n })\n ),\n ).catch((error) => {\n serverLogger.error(\"Failed to setup file watchers:\", error);\n });\n\n const iterator = createWatcherIterator(\n eventQueue,\n () => resolver,\n (r) => {\n resolver = r;\n },\n () => closed,\n () => signal?.aborted ?? false,\n );\n\n const cleanup = () => {\n closed = true;\n watchers.forEach((watcher) => {\n try {\n watcher.close();\n } catch (error) {\n serverLogger.debug(\"Error closing file watcher during cleanup:\", error);\n }\n });\n if (resolver) {\n resolver({ done: true, value: undefined });\n resolver = null;\n }\n };\n\n if (signal) {\n signal.addEventListener(\"abort\", cleanup);\n }\n\n return createFileWatcher(iterator, cleanup);\n }\n}\n", "import process from \"node:process\";\nimport type { EnvironmentAdapter } from \"../base.ts\";\n\nexport class NodeEnvironmentAdapter implements EnvironmentAdapter {\n get(key: string): string | undefined {\n return process.env[key];\n }\n\n set(key: string, value: string): void {\n process.env[key] = value;\n }\n\n toObject(): Record<string, string> {\n return { ...process.env } as Record<string, string>;\n }\n}\n", "'use strict';\n\nconst BINARY_TYPES = ['nodebuffer', 'arraybuffer', 'fragments'];\nconst hasBlob = typeof Blob !== 'undefined';\n\nif (hasBlob) BINARY_TYPES.push('blob');\n\nmodule.exports = {\n BINARY_TYPES,\n EMPTY_BUFFER: Buffer.alloc(0),\n GUID: '258EAFA5-E914-47DA-95CA-C5AB0DC85B11',\n hasBlob,\n kForOnEventAttribute: Symbol('kIsForOnEventAttribute'),\n kListener: Symbol('kListener'),\n kStatusCode: Symbol('status-code'),\n kWebSocket: Symbol('websocket'),\n NOOP: () => {}\n};\n", "'use strict';\n\nconst { EMPTY_BUFFER } = require('./constants');\n\nconst FastBuffer = Buffer[Symbol.species];\n\n/**\n * Merges an array of buffers into a new buffer.\n *\n * @param {Buffer[]} list The array of buffers to concat\n * @param {Number} totalLength The total length of buffers in the list\n * @return {Buffer} The resulting buffer\n * @public\n */\nfunction concat(list, totalLength) {\n if (list.length === 0) return EMPTY_BUFFER;\n if (list.length === 1) return list[0];\n\n const target = Buffer.allocUnsafe(totalLength);\n let offset = 0;\n\n for (let i = 0; i < list.length; i++) {\n const buf = list[i];\n target.set(buf, offset);\n offset += buf.length;\n }\n\n if (offset < totalLength) {\n return new FastBuffer(target.buffer, target.byteOffset, offset);\n }\n\n return target;\n}\n\n/**\n * Masks a buffer using the given mask.\n *\n * @param {Buffer} source The buffer to mask\n * @param {Buffer} mask The mask to use\n * @param {Buffer} output The buffer where to store the result\n * @param {Number} offset The offset at which to start writing\n * @param {Number} length The number of bytes to mask.\n * @public\n */\nfunction _mask(source, mask, output, offset, length) {\n for (let i = 0; i < length; i++) {\n output[offset + i] = source[i] ^ mask[i & 3];\n }\n}\n\n/**\n * Unmasks a buffer using the given mask.\n *\n * @param {Buffer} buffer The buffer to unmask\n * @param {Buffer} mask The mask to use\n * @public\n */\nfunction _unmask(buffer, mask) {\n for (let i = 0; i < buffer.length; i++) {\n buffer[i] ^= mask[i & 3];\n }\n}\n\n/**\n * Converts a buffer to an `ArrayBuffer`.\n *\n * @param {Buffer} buf The buffer to convert\n * @return {ArrayBuffer} Converted buffer\n * @public\n */\nfunction toArrayBuffer(buf) {\n if (buf.length === buf.buffer.byteLength) {\n return buf.buffer;\n }\n\n return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.length);\n}\n\n/**\n * Converts `data` to a `Buffer`.\n *\n * @param {*} data The data to convert\n * @return {Buffer} The buffer\n * @throws {TypeError}\n * @public\n */\nfunction toBuffer(data) {\n toBuffer.readOnly = true;\n\n if (Buffer.isBuffer(data)) return data;\n\n let buf;\n\n if (data instanceof ArrayBuffer) {\n buf = new FastBuffer(data);\n } else if (ArrayBuffer.isView(data)) {\n buf = new FastBuffer(data.buffer, data.byteOffset, data.byteLength);\n } else {\n buf = Buffer.from(data);\n toBuffer.readOnly = false;\n }\n\n return buf;\n}\n\nmodule.exports = {\n concat,\n mask: _mask,\n toArrayBuffer,\n toBuffer,\n unmask: _unmask\n};\n\n/* istanbul ignore else */\nif (!process.env.WS_NO_BUFFER_UTIL) {\n try {\n const bufferUtil = require('bufferutil');\n\n module.exports.mask = function (source, mask, output, offset, length) {\n if (length < 48) _mask(source, mask, output, offset, length);\n else bufferUtil.mask(source, mask, output, offset, length);\n };\n\n module.exports.unmask = function (buffer, mask) {\n if (buffer.length < 32) _unmask(buffer, mask);\n else bufferUtil.unmask(buffer, mask);\n };\n } catch (e) {\n // Continue regardless of the error.\n }\n}\n", "'use strict';\n\nconst kDone = Symbol('kDone');\nconst kRun = Symbol('kRun');\n\n/**\n * A very simple job queue with adjustable concurrency. Adapted from\n * https://github.com/STRML/async-limiter\n */\nclass Limiter {\n /**\n * Creates a new `Limiter`.\n *\n * @param {Number} [concurrency=Infinity] The maximum number of jobs allowed\n * to run concurrently\n */\n constructor(concurrency) {\n this[kDone] = () => {\n this.pending--;\n this[kRun]();\n };\n this.concurrency = concurrency || Infinity;\n this.jobs = [];\n this.pending = 0;\n }\n\n /**\n * Adds a job to the queue.\n *\n * @param {Function} job The job to run\n * @public\n */\n add(job) {\n this.jobs.push(job);\n this[kRun]();\n }\n\n /**\n * Removes a job from the queue and runs it if possible.\n *\n * @private\n */\n [kRun]() {\n if (this.pending === this.concurrency) return;\n\n if (this.jobs.length) {\n const job = this.jobs.shift();\n\n this.pending++;\n job(this[kDone]);\n }\n }\n}\n\nmodule.exports = Limiter;\n", "'use strict';\n\nconst zlib = require('zlib');\n\nconst bufferUtil = require('./buffer-util');\nconst Limiter = require('./limiter');\nconst { kStatusCode } = require('./constants');\n\nconst FastBuffer = Buffer[Symbol.species];\nconst TRAILER = Buffer.from([0x00, 0x00, 0xff, 0xff]);\nconst kPerMessageDeflate = Symbol('permessage-deflate');\nconst kTotalLength = Symbol('total-length');\nconst kCallback = Symbol('callback');\nconst kBuffers = Symbol('buffers');\nconst kError = Symbol('error');\n\n//\n// We limit zlib concurrency, which prevents severe memory fragmentation\n// as documented in https://github.com/nodejs/node/issues/8871#issuecomment-250915913\n// and https://github.com/websockets/ws/issues/1202\n//\n// Intentionally global; it's the global thread pool that's an issue.\n//\nlet zlibLimiter;\n\n/**\n * permessage-deflate implementation.\n */\nclass PerMessageDeflate {\n /**\n * Creates a PerMessageDeflate instance.\n *\n * @param {Object} [options] Configuration options\n * @param {(Boolean|Number)} [options.clientMaxWindowBits] Advertise support\n * for, or request, a custom client window size\n * @param {Boolean} [options.clientNoContextTakeover=false] Advertise/\n * acknowledge disabling of client context takeover\n * @param {Number} [options.concurrencyLimit=10] The number of concurrent\n * calls to zlib\n * @param {(Boolean|Number)} [options.serverMaxWindowBits] Request/confirm the\n * use of a custom server window size\n * @param {Boolean} [options.serverNoContextTakeover=false] Request/accept\n * disabling of server context takeover\n * @param {Number} [options.threshold=1024] Size (in bytes) below which\n * messages should not be compressed if context takeover is disabled\n * @param {Object} [options.zlibDeflateOptions] Options to pass to zlib on\n * deflate\n * @param {Object} [options.zlibInflateOptions] Options to pass to zlib on\n * inflate\n * @param {Boolean} [isServer=false] Create the instance in either server or\n * client mode\n * @param {Number} [maxPayload=0] The maximum allowed message length\n */\n constructor(options, isServer, maxPayload) {\n this._maxPayload = maxPayload | 0;\n this._options = options || {};\n this._threshold =\n this._options.threshold !== undefined ? this._options.threshold : 1024;\n this._isServer = !!isServer;\n this._deflate = null;\n this._inflate = null;\n\n this.params = null;\n\n if (!zlibLimiter) {\n const concurrency =\n this._options.concurrencyLimit !== undefined\n ? this._options.concurrencyLimit\n : 10;\n zlibLimiter = new Limiter(concurrency);\n }\n }\n\n /**\n * @type {String}\n */\n static get extensionName() {\n return 'permessage-deflate';\n }\n\n /**\n * Create an extension negotiation offer.\n *\n * @return {Object} Extension parameters\n * @public\n */\n offer() {\n const params = {};\n\n if (this._options.serverNoContextTakeover) {\n params.server_no_context_takeover = true;\n }\n if (this._options.clientNoContextTakeover) {\n params.client_no_context_takeover = true;\n }\n if (this._options.serverMaxWindowBits) {\n params.server_max_window_bits = this._options.serverMaxWindowBits;\n }\n if (this._options.clientMaxWindowBits) {\n params.client_max_window_bits = this._options.clientMaxWindowBits;\n } else if (this._options.clientMaxWindowBits == null) {\n params.client_max_window_bits = true;\n }\n\n return params;\n }\n\n /**\n * Accept an extension negotiation offer/response.\n *\n * @param {Array} configurations The extension negotiation offers/reponse\n * @return {Object} Accepted configuration\n * @public\n */\n accept(configurations) {\n configurations = this.normalizeParams(configurations);\n\n this.params = this._isServer\n ? this.acceptAsServer(configurations)\n : this.acceptAsClient(configurations);\n\n return this.params;\n }\n\n /**\n * Releases all resources used by the extension.\n *\n * @public\n */\n cleanup() {\n if (this._inflate) {\n this._inflate.close();\n this._inflate = null;\n }\n\n if (this._deflate) {\n const callback = this._deflate[kCallback];\n\n this._deflate.close();\n this._deflate = null;\n\n if (callback) {\n callback(\n new Error(\n 'The deflate stream was closed while data was being processed'\n )\n );\n }\n }\n }\n\n /**\n * Accept an extension negotiation offer.\n *\n * @param {Array} offers The extension negotiation offers\n * @return {Object} Accepted configuration\n * @private\n */\n acceptAsServer(offers) {\n const opts = this._options;\n const accepted = offers.find((params) => {\n if (\n (opts.serverNoContextTakeover === false &&\n params.server_no_context_takeover) ||\n (params.server_max_window_bits &&\n (opts.serverMaxWindowBits === false ||\n (typeof opts.serverMaxWindowBits === 'number' &&\n opts.serverMaxWindowBits > params.server_max_window_bits))) ||\n (typeof opts.clientMaxWindowBits === 'number' &&\n !params.client_max_window_bits)\n ) {\n return false;\n }\n\n return true;\n });\n\n if (!accepted) {\n throw new Error('None of the extension offers can be accepted');\n }\n\n if (opts.serverNoContextTakeover) {\n accepted.server_no_context_takeover = true;\n }\n if (opts.clientNoContextTakeover) {\n accepted.client_no_context_takeover = true;\n }\n if (typeof opts.serverMaxWindowBits === 'number') {\n accepted.server_max_window_bits = opts.serverMaxWindowBits;\n }\n if (typeof opts.clientMaxWindowBits === 'number') {\n accepted.client_max_window_bits = opts.clientMaxWindowBits;\n } else if (\n accepted.client_max_window_bits === true ||\n opts.clientMaxWindowBits === false\n ) {\n delete accepted.client_max_window_bits;\n }\n\n return accepted;\n }\n\n /**\n * Accept the extension negotiation response.\n *\n * @param {Array} response The extension negotiation response\n * @return {Object} Accepted configuration\n * @private\n */\n acceptAsClient(response) {\n const params = response[0];\n\n if (\n this._options.clientNoContextTakeover === false &&\n params.client_no_context_takeover\n ) {\n throw new Error('Unexpected parameter \"client_no_context_takeover\"');\n }\n\n if (!params.client_max_window_bits) {\n if (typeof this._options.clientMaxWindowBits === 'number') {\n params.client_max_window_bits = this._options.clientMaxWindowBits;\n }\n } else if (\n this._options.clientMaxWindowBits === false ||\n (typeof this._options.clientMaxWindowBits === 'number' &&\n params.client_max_window_bits > this._options.clientMaxWindowBits)\n ) {\n throw new Error(\n 'Unexpected or invalid parameter \"client_max_window_bits\"'\n );\n }\n\n return params;\n }\n\n /**\n * Normalize parameters.\n *\n * @param {Array} configurations The extension negotiation offers/reponse\n * @return {Array} The offers/response with normalized parameters\n * @private\n */\n normalizeParams(configurations) {\n configurations.forEach((params) => {\n Object.keys(params).forEach((key) => {\n let value = params[key];\n\n if (value.length > 1) {\n throw new Error(`Parameter \"${key}\" must have only a single value`);\n }\n\n value = value[0];\n\n if (key === 'client_max_window_bits') {\n if (value !== true) {\n const num = +value;\n if (!Number.isInteger(num) || num < 8 || num > 15) {\n throw new TypeError(\n `Invalid value for parameter \"${key}\": ${value}`\n );\n }\n value = num;\n } else if (!this._isServer) {\n throw new TypeError(\n `Invalid value for parameter \"${key}\": ${value}`\n );\n }\n } else if (key === 'server_max_window_bits') {\n const num = +value;\n if (!Number.isInteger(num) || num < 8 || num > 15) {\n throw new TypeError(\n `Invalid value for parameter \"${key}\": ${value}`\n );\n }\n value = num;\n } else if (\n key === 'client_no_context_takeover' ||\n key === 'server_no_context_takeover'\n ) {\n if (value !== true) {\n throw new TypeError(\n `Invalid value for parameter \"${key}\": ${value}`\n );\n }\n } else {\n throw new Error(`Unknown parameter \"${key}\"`);\n }\n\n params[key] = value;\n });\n });\n\n return configurations;\n }\n\n /**\n * Decompress data. Concurrency limited.\n *\n * @param {Buffer} data Compressed data\n * @param {Boolean} fin Specifies whether or not this is the last fragment\n * @param {Function} callback Callback\n * @public\n */\n decompress(data, fin, callback) {\n zlibLimiter.add((done) => {\n this._decompress(data, fin, (err, result) => {\n done();\n callback(err, result);\n });\n });\n }\n\n /**\n * Compress data. Concurrency limited.\n *\n * @param {(Buffer|String)} data Data to compress\n * @param {Boolean} fin Specifies whether or not this is the last fragment\n * @param {Function} callback Callback\n * @public\n */\n compress(data, fin, callback) {\n zlibLimiter.add((done) => {\n this._compress(data, fin, (err, result) => {\n done();\n callback(err, result);\n });\n });\n }\n\n /**\n * Decompress data.\n *\n * @param {Buffer} data Compressed data\n * @param {Boolean} fin Specifies whether or not this is the last fragment\n * @param {Function} callback Callback\n * @private\n */\n _decompress(data, fin, callback) {\n const endpoint = this._isServer ? 'client' : 'server';\n\n if (!this._inflate) {\n const key = `${endpoint}_max_window_bits`;\n const windowBits =\n typeof this.params[key] !== 'number'\n ? zlib.Z_DEFAULT_WINDOWBITS\n : this.params[key];\n\n this._inflate = zlib.createInflateRaw({\n ...this._options.zlibInflateOptions,\n windowBits\n });\n this._inflate[kPerMessageDeflate] = this;\n this._inflate[kTotalLength] = 0;\n this._inflate[kBuffers] = [];\n this._inflate.on('error', inflateOnError);\n this._inflate.on('data', inflateOnData);\n }\n\n this._inflate[kCallback] = callback;\n\n this._inflate.write(data);\n if (fin) this._inflate.write(TRAILER);\n\n this._inflate.flush(() => {\n const err = this._inflate[kError];\n\n if (err) {\n this._inflate.close();\n this._inflate = null;\n callback(err);\n return;\n }\n\n const data = bufferUtil.concat(\n this._inflate[kBuffers],\n this._inflate[kTotalLength]\n );\n\n if (this._inflate._readableState.endEmitted) {\n this._inflate.close();\n this._inflate = null;\n } else {\n this._inflate[kTotalLength] = 0;\n this._inflate[kBuffers] = [];\n\n if (fin && this.params[`${endpoint}_no_context_takeover`]) {\n this._inflate.reset();\n }\n }\n\n callback(null, data);\n });\n }\n\n /**\n * Compress data.\n *\n * @param {(Buffer|String)} data Data to compress\n * @param {Boolean} fin Specifies whether or not this is the last fragment\n * @param {Function} callback Callback\n * @private\n */\n _compress(data, fin, callback) {\n const endpoint = this._isServer ? 'server' : 'client';\n\n if (!this._deflate) {\n const key = `${endpoint}_max_window_bits`;\n const windowBits =\n typeof this.params[key] !== 'number'\n ? zlib.Z_DEFAULT_WINDOWBITS\n : this.params[key];\n\n this._deflate = zlib.createDeflateRaw({\n ...this._options.zlibDeflateOptions,\n windowBits\n });\n\n this._deflate[kTotalLength] = 0;\n this._deflate[kBuffers] = [];\n\n this._deflate.on('data', deflateOnData);\n }\n\n this._deflate[kCallback] = callback;\n\n this._deflate.write(data);\n this._deflate.flush(zlib.Z_SYNC_FLUSH, () => {\n if (!this._deflate) {\n //\n // The deflate stream was closed while data was being processed.\n //\n return;\n }\n\n let data = bufferUtil.concat(\n this._deflate[kBuffers],\n this._deflate[kTotalLength]\n );\n\n if (fin) {\n data = new FastBuffer(data.buffer, data.byteOffset, data.length - 4);\n }\n\n //\n // Ensure that the callback will not be called again in\n // `PerMessageDeflate#cleanup()`.\n //\n this._deflate[kCallback] = null;\n\n this._deflate[kTotalLength] = 0;\n this._deflate[kBuffers] = [];\n\n if (fin && this.params[`${endpoint}_no_context_takeover`]) {\n this._deflate.reset();\n }\n\n callback(null, data);\n });\n }\n}\n\nmodule.exports = PerMessageDeflate;\n\n/**\n * The listener of the `zlib.DeflateRaw` stream `'data'` event.\n *\n * @param {Buffer} chunk A chunk of data\n * @private\n */\nfunction deflateOnData(chunk) {\n this[kBuffers].push(chunk);\n this[kTotalLength] += chunk.length;\n}\n\n/**\n * The listener of the `zlib.InflateRaw` stream `'data'` event.\n *\n * @param {Buffer} chunk A chunk of data\n * @private\n */\nfunction inflateOnData(chunk) {\n this[kTotalLength] += chunk.length;\n\n if (\n this[kPerMessageDeflate]._maxPayload < 1 ||\n this[kTotalLength] <= this[kPerMessageDeflate]._maxPayload\n ) {\n this[kBuffers].push(chunk);\n return;\n }\n\n this[kError] = new RangeError('Max payload size exceeded');\n this[kError].code = 'WS_ERR_UNSUPPORTED_MESSAGE_LENGTH';\n this[kError][kStatusCode] = 1009;\n this.removeListener('data', inflateOnData);\n\n //\n // The choice to employ `zlib.reset()` over `zlib.close()` is dictated by the\n // fact that in Node.js versions prior to 13.10.0, the callback for\n // `zlib.flush()` is not called if `zlib.close()` is used. Utilizing\n // `zlib.reset()` ensures that either the callback is invoked or an error is\n // emitted.\n //\n this.reset();\n}\n\n/**\n * The listener of the `zlib.InflateRaw` stream `'error'` event.\n *\n * @param {Error} err The emitted error\n * @private\n */\nfunction inflateOnError(err) {\n //\n // There is no need to call `Zlib#close()` as the handle is automatically\n // closed when an error is emitted.\n //\n this[kPerMessageDeflate]._inflate = null;\n\n if (this[kError]) {\n this[kCallback](this[kError]);\n return;\n }\n\n err[kStatusCode] = 1007;\n this[kCallback](err);\n}\n", "'use strict';\n\nconst { isUtf8 } = require('buffer');\n\nconst { hasBlob } = require('./constants');\n\n//\n// Allowed token characters:\n//\n// '!', '#', '$', '%', '&', ''', '*', '+', '-',\n// '.', 0-9, A-Z, '^', '_', '`', a-z, '|', '~'\n//\n// tokenChars[32] === 0 // ' '\n// tokenChars[33] === 1 // '!'\n// tokenChars[34] === 0 // '\"'\n// ...\n//\n// prettier-ignore\nconst tokenChars = [\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0 - 15\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 16 - 31\n 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, // 32 - 47\n 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, // 48 - 63\n 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 64 - 79\n 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, // 80 - 95\n 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 96 - 111\n 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0 // 112 - 127\n];\n\n/**\n * Checks if a status code is allowed in a close frame.\n *\n * @param {Number} code The status code\n * @return {Boolean} `true` if the status code is valid, else `false`\n * @public\n */\nfunction isValidStatusCode(code) {\n return (\n (code >= 1000 &&\n code <= 1014 &&\n code !== 1004 &&\n code !== 1005 &&\n code !== 1006) ||\n (code >= 3000 && code <= 4999)\n );\n}\n\n/**\n * Checks if a given buffer contains only correct UTF-8.\n * Ported from https://www.cl.cam.ac.uk/%7Emgk25/ucs/utf8_check.c by\n * Markus Kuhn.\n *\n * @param {Buffer} buf The buffer to check\n * @return {Boolean} `true` if `buf` contains only correct UTF-8, else `false`\n * @public\n */\nfunction _isValidUTF8(buf) {\n const len = buf.length;\n let i = 0;\n\n while (i < len) {\n if ((buf[i] & 0x80) === 0) {\n // 0xxxxxxx\n i++;\n } else if ((buf[i] & 0xe0) === 0xc0) {\n // 110xxxxx 10xxxxxx\n if (\n i + 1 === len ||\n (buf[i + 1] & 0xc0) !== 0x80 ||\n (buf[i] & 0xfe) === 0xc0 // Overlong\n ) {\n return false;\n }\n\n i += 2;\n } else if ((buf[i] & 0xf0) === 0xe0) {\n // 1110xxxx 10xxxxxx 10xxxxxx\n if (\n i + 2 >= len ||\n (buf[i + 1] & 0xc0) !== 0x80 ||\n (buf[i + 2] & 0xc0) !== 0x80 ||\n (buf[i] === 0xe0 && (buf[i + 1] & 0xe0) === 0x80) || // Overlong\n (buf[i] === 0xed && (buf[i + 1] & 0xe0) === 0xa0) // Surrogate (U+D800 - U+DFFF)\n ) {\n return false;\n }\n\n i += 3;\n } else if ((buf[i] & 0xf8) === 0xf0) {\n // 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx\n if (\n i + 3 >= len ||\n (buf[i + 1] & 0xc0) !== 0x80 ||\n (buf[i + 2] & 0xc0) !== 0x80 ||\n (buf[i + 3] & 0xc0) !== 0x80 ||\n (buf[i] === 0xf0 && (buf[i + 1] & 0xf0) === 0x80) || // Overlong\n (buf[i] === 0xf4 && buf[i + 1] > 0x8f) ||\n buf[i] > 0xf4 // > U+10FFFF\n ) {\n return false;\n }\n\n i += 4;\n } else {\n return false;\n }\n }\n\n return true;\n}\n\n/**\n * Determines whether a value is a `Blob`.\n *\n * @param {*} value The value to be tested\n * @return {Boolean} `true` if `value` is a `Blob`, else `false`\n * @private\n */\nfunction isBlob(value) {\n return (\n hasBlob &&\n typeof value === 'object' &&\n typeof value.arrayBuffer === 'function' &&\n typeof value.type === 'string' &&\n typeof value.stream === 'function' &&\n (value[Symbol.toStringTag] === 'Blob' ||\n value[Symbol.toStringTag] === 'File')\n );\n}\n\nmodule.exports = {\n isBlob,\n isValidStatusCode,\n isValidUTF8: _isValidUTF8,\n tokenChars\n};\n\nif (isUtf8) {\n module.exports.isValidUTF8 = function (buf) {\n return buf.length < 24 ? _isValidUTF8(buf) : isUtf8(buf);\n };\n} /* istanbul ignore else */ else if (!process.env.WS_NO_UTF_8_VALIDATE) {\n try {\n const isValidUTF8 = require('utf-8-validate');\n\n module.exports.isValidUTF8 = function (buf) {\n return buf.length < 32 ? _isValidUTF8(buf) : isValidUTF8(buf);\n };\n } catch (e) {\n // Continue regardless of the error.\n }\n}\n", "'use strict';\n\nconst { Writable } = require('stream');\n\nconst PerMessageDeflate = require('./permessage-deflate');\nconst {\n BINARY_TYPES,\n EMPTY_BUFFER,\n kStatusCode,\n kWebSocket\n} = require('./constants');\nconst { concat, toArrayBuffer, unmask } = require('./buffer-util');\nconst { isValidStatusCode, isValidUTF8 } = require('./validation');\n\nconst FastBuffer = Buffer[Symbol.species];\n\nconst GET_INFO = 0;\nconst GET_PAYLOAD_LENGTH_16 = 1;\nconst GET_PAYLOAD_LENGTH_64 = 2;\nconst GET_MASK = 3;\nconst GET_DATA = 4;\nconst INFLATING = 5;\nconst DEFER_EVENT = 6;\n\n/**\n * HyBi Receiver implementation.\n *\n * @extends Writable\n */\nclass Receiver extends Writable {\n /**\n * Creates a Receiver instance.\n *\n * @param {Object} [options] Options object\n * @param {Boolean} [options.allowSynchronousEvents=true] Specifies whether\n * any of the `'message'`, `'ping'`, and `'pong'` events can be emitted\n * multiple times in the same tick\n * @param {String} [options.binaryType=nodebuffer] The type for binary data\n * @param {Object} [options.extensions] An object containing the negotiated\n * extensions\n * @param {Boolean} [options.isServer=false] Specifies whether to operate in\n * client or server mode\n * @param {Number} [options.maxPayload=0] The maximum allowed message length\n * @param {Boolean} [options.skipUTF8Validation=false] Specifies whether or\n * not to skip UTF-8 validation for text and close messages\n */\n constructor(options = {}) {\n super();\n\n this._allowSynchronousEvents =\n options.allowSynchronousEvents !== undefined\n ? options.allowSynchronousEvents\n : true;\n this._binaryType = options.binaryType || BINARY_TYPES[0];\n this._extensions = options.extensions || {};\n this._isServer = !!options.isServer;\n this._maxPayload = options.maxPayload | 0;\n this._skipUTF8Validation = !!options.skipUTF8Validation;\n this[kWebSocket] = undefined;\n\n this._bufferedBytes = 0;\n this._buffers = [];\n\n this._compressed = false;\n this._payloadLength = 0;\n this._mask = undefined;\n this._fragmented = 0;\n this._masked = false;\n this._fin = false;\n this._opcode = 0;\n\n this._totalPayloadLength = 0;\n this._messageLength = 0;\n this._fragments = [];\n\n this._errored = false;\n this._loop = false;\n this._state = GET_INFO;\n }\n\n /**\n * Implements `Writable.prototype._write()`.\n *\n * @param {Buffer} chunk The chunk of data to write\n * @param {String} encoding The character encoding of `chunk`\n * @param {Function} cb Callback\n * @private\n */\n _write(chunk, encoding, cb) {\n if (this._opcode === 0x08 && this._state == GET_INFO) return cb();\n\n this._bufferedBytes += chunk.length;\n this._buffers.push(chunk);\n this.startLoop(cb);\n }\n\n /**\n * Consumes `n` bytes from the buffered data.\n *\n * @param {Number} n The number of bytes to consume\n * @return {Buffer} The consumed bytes\n * @private\n */\n consume(n) {\n this._bufferedBytes -= n;\n\n if (n === this._buffers[0].length) return this._buffers.shift();\n\n if (n < this._buffers[0].length) {\n const buf = this._buffers[0];\n this._buffers[0] = new FastBuffer(\n buf.buffer,\n buf.byteOffset + n,\n buf.length - n\n );\n\n return new FastBuffer(buf.buffer, buf.byteOffset, n);\n }\n\n const dst = Buffer.allocUnsafe(n);\n\n do {\n const buf = this._buffers[0];\n const offset = dst.length - n;\n\n if (n >= buf.length) {\n dst.set(this._buffers.shift(), offset);\n } else {\n dst.set(new Uint8Array(buf.buffer, buf.byteOffset, n), offset);\n this._buffers[0] = new FastBuffer(\n buf.buffer,\n buf.byteOffset + n,\n buf.length - n\n );\n }\n\n n -= buf.length;\n } while (n > 0);\n\n return dst;\n }\n\n /**\n * Starts the parsing loop.\n *\n * @param {Function} cb Callback\n * @private\n */\n startLoop(cb) {\n this._loop = true;\n\n do {\n switch (this._state) {\n case GET_INFO:\n this.getInfo(cb);\n break;\n case GET_PAYLOAD_LENGTH_16:\n this.getPayloadLength16(cb);\n break;\n case GET_PAYLOAD_LENGTH_64:\n this.getPayloadLength64(cb);\n break;\n case GET_MASK:\n this.getMask();\n break;\n case GET_DATA:\n this.getData(cb);\n break;\n case INFLATING:\n case DEFER_EVENT:\n this._loop = false;\n return;\n }\n } while (this._loop);\n\n if (!this._errored) cb();\n }\n\n /**\n * Reads the first two bytes of a frame.\n *\n * @param {Function} cb Callback\n * @private\n */\n getInfo(cb) {\n if (this._bufferedBytes < 2) {\n this._loop = false;\n return;\n }\n\n const buf = this.consume(2);\n\n if ((buf[0] & 0x30) !== 0x00) {\n const error = this.createError(\n RangeError,\n 'RSV2 and RSV3 must be clear',\n true,\n 1002,\n 'WS_ERR_UNEXPECTED_RSV_2_3'\n );\n\n cb(error);\n return;\n }\n\n const compressed = (buf[0] & 0x40) === 0x40;\n\n if (compressed && !this._extensions[PerMessageDeflate.extensionName]) {\n const error = this.createError(\n RangeError,\n 'RSV1 must be clear',\n true,\n 1002,\n 'WS_ERR_UNEXPECTED_RSV_1'\n );\n\n cb(error);\n return;\n }\n\n this._fin = (buf[0] & 0x80) === 0x80;\n this._opcode = buf[0] & 0x0f;\n this._payloadLength = buf[1] & 0x7f;\n\n if (this._opcode === 0x00) {\n if (compressed) {\n const error = this.createError(\n RangeError,\n 'RSV1 must be clear',\n true,\n 1002,\n 'WS_ERR_UNEXPECTED_RSV_1'\n );\n\n cb(error);\n return;\n }\n\n if (!this._fragmented) {\n const error = this.createError(\n RangeError,\n 'invalid opcode 0',\n true,\n 1002,\n 'WS_ERR_INVALID_OPCODE'\n );\n\n cb(error);\n return;\n }\n\n this._opcode = this._fragmented;\n } else if (this._opcode === 0x01 || this._opcode === 0x02) {\n if (this._fragmented) {\n const error = this.createError(\n RangeError,\n `invalid opcode ${this._opcode}`,\n true,\n 1002,\n 'WS_ERR_INVALID_OPCODE'\n );\n\n cb(error);\n return;\n }\n\n this._compressed = compressed;\n } else if (this._opcode > 0x07 && this._opcode < 0x0b) {\n if (!this._fin) {\n const error = this.createError(\n RangeError,\n 'FIN must be set',\n true,\n 1002,\n 'WS_ERR_EXPECTED_FIN'\n );\n\n cb(error);\n return;\n }\n\n if (compressed) {\n const error = this.createError(\n RangeError,\n 'RSV1 must be clear',\n true,\n 1002,\n 'WS_ERR_UNEXPECTED_RSV_1'\n );\n\n cb(error);\n return;\n }\n\n if (\n this._payloadLength > 0x7d ||\n (this._opcode === 0x08 && this._payloadLength === 1)\n ) {\n const error = this.createError(\n RangeError,\n `invalid payload length ${this._payloadLength}`,\n true,\n 1002,\n 'WS_ERR_INVALID_CONTROL_PAYLOAD_LENGTH'\n );\n\n cb(error);\n return;\n }\n } else {\n const error = this.createError(\n RangeError,\n `invalid opcode ${this._opcode}`,\n true,\n 1002,\n 'WS_ERR_INVALID_OPCODE'\n );\n\n cb(error);\n return;\n }\n\n if (!this._fin && !this._fragmented) this._fragmented = this._opcode;\n this._masked = (buf[1] & 0x80) === 0x80;\n\n if (this._isServer) {\n if (!this._masked) {\n const error = this.createError(\n RangeError,\n 'MASK must be set',\n true,\n 1002,\n 'WS_ERR_EXPECTED_MASK'\n );\n\n cb(error);\n return;\n }\n } else if (this._masked) {\n const error = this.createError(\n RangeError,\n 'MASK must be clear',\n true,\n 1002,\n 'WS_ERR_UNEXPECTED_MASK'\n );\n\n cb(error);\n return;\n }\n\n if (this._payloadLength === 126) this._state = GET_PAYLOAD_LENGTH_16;\n else if (this._payloadLength === 127) this._state = GET_PAYLOAD_LENGTH_64;\n else this.haveLength(cb);\n }\n\n /**\n * Gets extended payload length (7+16).\n *\n * @param {Function} cb Callback\n * @private\n */\n getPayloadLength16(cb) {\n if (this._bufferedBytes < 2) {\n this._loop = false;\n return;\n }\n\n this._payloadLength = this.consume(2).readUInt16BE(0);\n this.haveLength(cb);\n }\n\n /**\n * Gets extended payload length (7+64).\n *\n * @param {Function} cb Callback\n * @private\n */\n getPayloadLength64(cb) {\n if (this._bufferedBytes < 8) {\n this._loop = false;\n return;\n }\n\n const buf = this.consume(8);\n const num = buf.readUInt32BE(0);\n\n //\n // The maximum safe integer in JavaScript is 2^53 - 1. An error is returned\n // if payload length is greater than this number.\n //\n if (num > Math.pow(2, 53 - 32) - 1) {\n const error = this.createError(\n RangeError,\n 'Unsupported WebSocket frame: payload length > 2^53 - 1',\n false,\n 1009,\n 'WS_ERR_UNSUPPORTED_DATA_PAYLOAD_LENGTH'\n );\n\n cb(error);\n return;\n }\n\n this._payloadLength = num * Math.pow(2, 32) + buf.readUInt32BE(4);\n this.haveLength(cb);\n }\n\n /**\n * Payload length has been read.\n *\n * @param {Function} cb Callback\n * @private\n */\n haveLength(cb) {\n if (this._payloadLength && this._opcode < 0x08) {\n this._totalPayloadLength += this._payloadLength;\n if (this._totalPayloadLength > this._maxPayload && this._maxPayload > 0) {\n const error = this.createError(\n RangeError,\n 'Max payload size exceeded',\n false,\n 1009,\n 'WS_ERR_UNSUPPORTED_MESSAGE_LENGTH'\n );\n\n cb(error);\n return;\n }\n }\n\n if (this._masked) this._state = GET_MASK;\n else this._state = GET_DATA;\n }\n\n /**\n * Reads mask bytes.\n *\n * @private\n */\n getMask() {\n if (this._bufferedBytes < 4) {\n this._loop = false;\n return;\n }\n\n this._mask = this.consume(4);\n this._state = GET_DATA;\n }\n\n /**\n * Reads data bytes.\n *\n * @param {Function} cb Callback\n * @private\n */\n getData(cb) {\n let data = EMPTY_BUFFER;\n\n if (this._payloadLength) {\n if (this._bufferedBytes < this._payloadLength) {\n this._loop = false;\n return;\n }\n\n data = this.consume(this._payloadLength);\n\n if (\n this._masked &&\n (this._mask[0] | this._mask[1] | this._mask[2] | this._mask[3]) !== 0\n ) {\n unmask(data, this._mask);\n }\n }\n\n if (this._opcode > 0x07) {\n this.controlMessage(data, cb);\n return;\n }\n\n if (this._compressed) {\n this._state = INFLATING;\n this.decompress(data, cb);\n return;\n }\n\n if (data.length) {\n //\n // This message is not compressed so its length is the sum of the payload\n // length of all fragments.\n //\n this._messageLength = this._totalPayloadLength;\n this._fragments.push(data);\n }\n\n this.dataMessage(cb);\n }\n\n /**\n * Decompresses data.\n *\n * @param {Buffer} data Compressed data\n * @param {Function} cb Callback\n * @private\n */\n decompress(data, cb) {\n const perMessageDeflate = this._extensions[PerMessageDeflate.extensionName];\n\n perMessageDeflate.decompress(data, this._fin, (err, buf) => {\n if (err) return cb(err);\n\n if (buf.length) {\n this._messageLength += buf.length;\n if (this._messageLength > this._maxPayload && this._maxPayload > 0) {\n const error = this.createError(\n RangeError,\n 'Max payload size exceeded',\n false,\n 1009,\n 'WS_ERR_UNSUPPORTED_MESSAGE_LENGTH'\n );\n\n cb(error);\n return;\n }\n\n this._fragments.push(buf);\n }\n\n this.dataMessage(cb);\n if (this._state === GET_INFO) this.startLoop(cb);\n });\n }\n\n /**\n * Handles a data message.\n *\n * @param {Function} cb Callback\n * @private\n */\n dataMessage(cb) {\n if (!this._fin) {\n this._state = GET_INFO;\n return;\n }\n\n const messageLength = this._messageLength;\n const fragments = this._fragments;\n\n this._totalPayloadLength = 0;\n this._messageLength = 0;\n this._fragmented = 0;\n this._fragments = [];\n\n if (this._opcode === 2) {\n let data;\n\n if (this._binaryType === 'nodebuffer') {\n data = concat(fragments, messageLength);\n } else if (this._binaryType === 'arraybuffer') {\n data = toArrayBuffer(concat(fragments, messageLength));\n } else if (this._binaryType === 'blob') {\n data = new Blob(fragments);\n } else {\n data = fragments;\n }\n\n if (this._allowSynchronousEvents) {\n this.emit('message', data, true);\n this._state = GET_INFO;\n } else {\n this._state = DEFER_EVENT;\n setImmediate(() => {\n this.emit('message', data, true);\n this._state = GET_INFO;\n this.startLoop(cb);\n });\n }\n } else {\n const buf = concat(fragments, messageLength);\n\n if (!this._skipUTF8Validation && !isValidUTF8(buf)) {\n const error = this.createError(\n Error,\n 'invalid UTF-8 sequence',\n true,\n 1007,\n 'WS_ERR_INVALID_UTF8'\n );\n\n cb(error);\n return;\n }\n\n if (this._state === INFLATING || this._allowSynchronousEvents) {\n this.emit('message', buf, false);\n this._state = GET_INFO;\n } else {\n this._state = DEFER_EVENT;\n setImmediate(() => {\n this.emit('message', buf, false);\n this._state = GET_INFO;\n this.startLoop(cb);\n });\n }\n }\n }\n\n /**\n * Handles a control message.\n *\n * @param {Buffer} data Data to handle\n * @return {(Error|RangeError|undefined)} A possible error\n * @private\n */\n controlMessage(data, cb) {\n if (this._opcode === 0x08) {\n if (data.length === 0) {\n this._loop = false;\n this.emit('conclude', 1005, EMPTY_BUFFER);\n this.end();\n } else {\n const code = data.readUInt16BE(0);\n\n if (!isValidStatusCode(code)) {\n const error = this.createError(\n RangeError,\n `invalid status code ${code}`,\n true,\n 1002,\n 'WS_ERR_INVALID_CLOSE_CODE'\n );\n\n cb(error);\n return;\n }\n\n const buf = new FastBuffer(\n data.buffer,\n data.byteOffset + 2,\n data.length - 2\n );\n\n if (!this._skipUTF8Validation && !isValidUTF8(buf)) {\n const error = this.createError(\n Error,\n 'invalid UTF-8 sequence',\n true,\n 1007,\n 'WS_ERR_INVALID_UTF8'\n );\n\n cb(error);\n return;\n }\n\n this._loop = false;\n this.emit('conclude', code, buf);\n this.end();\n }\n\n this._state = GET_INFO;\n return;\n }\n\n if (this._allowSynchronousEvents) {\n this.emit(this._opcode === 0x09 ? 'ping' : 'pong', data);\n this._state = GET_INFO;\n } else {\n this._state = DEFER_EVENT;\n setImmediate(() => {\n this.emit(this._opcode === 0x09 ? 'ping' : 'pong', data);\n this._state = GET_INFO;\n this.startLoop(cb);\n });\n }\n }\n\n /**\n * Builds an error object.\n *\n * @param {function(new:Error|RangeError)} ErrorCtor The error constructor\n * @param {String} message The error message\n * @param {Boolean} prefix Specifies whether or not to add a default prefix to\n * `message`\n * @param {Number} statusCode The status code\n * @param {String} errorCode The exposed error code\n * @return {(Error|RangeError)} The error\n * @private\n */\n createError(ErrorCtor, message, prefix, statusCode, errorCode) {\n this._loop = false;\n this._errored = true;\n\n const err = new ErrorCtor(\n prefix ? `Invalid WebSocket frame: ${message}` : message\n );\n\n Error.captureStackTrace(err, this.createError);\n err.code = errorCode;\n err[kStatusCode] = statusCode;\n return err;\n }\n}\n\nmodule.exports = Receiver;\n", "/* eslint no-unused-vars: [\"error\", { \"varsIgnorePattern\": \"^Duplex\" }] */\n\n'use strict';\n\nconst { Duplex } = require('stream');\nconst { randomFillSync } = require('crypto');\n\nconst PerMessageDeflate = require('./permessage-deflate');\nconst { EMPTY_BUFFER, kWebSocket, NOOP } = require('./constants');\nconst { isBlob, isValidStatusCode } = require('./validation');\nconst { mask: applyMask, toBuffer } = require('./buffer-util');\n\nconst kByteLength = Symbol('kByteLength');\nconst maskBuffer = Buffer.alloc(4);\nconst RANDOM_POOL_SIZE = 8 * 1024;\nlet randomPool;\nlet randomPoolPointer = RANDOM_POOL_SIZE;\n\nconst DEFAULT = 0;\nconst DEFLATING = 1;\nconst GET_BLOB_DATA = 2;\n\n/**\n * HyBi Sender implementation.\n */\nclass Sender {\n /**\n * Creates a Sender instance.\n *\n * @param {Duplex} socket The connection socket\n * @param {Object} [extensions] An object containing the negotiated extensions\n * @param {Function} [generateMask] The function used to generate the masking\n * key\n */\n constructor(socket, extensions, generateMask) {\n this._extensions = extensions || {};\n\n if (generateMask) {\n this._generateMask = generateMask;\n this._maskBuffer = Buffer.alloc(4);\n }\n\n this._socket = socket;\n\n this._firstFragment = true;\n this._compress = false;\n\n this._bufferedBytes = 0;\n this._queue = [];\n this._state = DEFAULT;\n this.onerror = NOOP;\n this[kWebSocket] = undefined;\n }\n\n /**\n * Frames a piece of data according to the HyBi WebSocket protocol.\n *\n * @param {(Buffer|String)} data The data to frame\n * @param {Object} options Options object\n * @param {Boolean} [options.fin=false] Specifies whether or not to set the\n * FIN bit\n * @param {Function} [options.generateMask] The function used to generate the\n * masking key\n * @param {Boolean} [options.mask=false] Specifies whether or not to mask\n * `data`\n * @param {Buffer} [options.maskBuffer] The buffer used to store the masking\n * key\n * @param {Number} options.opcode The opcode\n * @param {Boolean} [options.readOnly=false] Specifies whether `data` can be\n * modified\n * @param {Boolean} [options.rsv1=false] Specifies whether or not to set the\n * RSV1 bit\n * @return {(Buffer|String)[]} The framed data\n * @public\n */\n static frame(data, options) {\n let mask;\n let merge = false;\n let offset = 2;\n let skipMasking = false;\n\n if (options.mask) {\n mask = options.maskBuffer || maskBuffer;\n\n if (options.generateMask) {\n options.generateMask(mask);\n } else {\n if (randomPoolPointer === RANDOM_POOL_SIZE) {\n /* istanbul ignore else */\n if (randomPool === undefined) {\n //\n // This is lazily initialized because server-sent frames must not\n // be masked so it may never be used.\n //\n randomPool = Buffer.alloc(RANDOM_POOL_SIZE);\n }\n\n randomFillSync(randomPool, 0, RANDOM_POOL_SIZE);\n randomPoolPointer = 0;\n }\n\n mask[0] = randomPool[randomPoolPointer++];\n mask[1] = randomPool[randomPoolPointer++];\n mask[2] = randomPool[randomPoolPointer++];\n mask[3] = randomPool[randomPoolPointer++];\n }\n\n skipMasking = (mask[0] | mask[1] | mask[2] | mask[3]) === 0;\n offset = 6;\n }\n\n let dataLength;\n\n if (typeof data === 'string') {\n if (\n (!options.mask || skipMasking) &&\n options[kByteLength] !== undefined\n ) {\n dataLength = options[kByteLength];\n } else {\n data = Buffer.from(data);\n dataLength = data.length;\n }\n } else {\n dataLength = data.length;\n merge = options.mask && options.readOnly && !skipMasking;\n }\n\n let payloadLength = dataLength;\n\n if (dataLength >= 65536) {\n offset += 8;\n payloadLength = 127;\n } else if (dataLength > 125) {\n offset += 2;\n payloadLength = 126;\n }\n\n const target = Buffer.allocUnsafe(merge ? dataLength + offset : offset);\n\n target[0] = options.fin ? options.opcode | 0x80 : options.opcode;\n if (options.rsv1) target[0] |= 0x40;\n\n target[1] = payloadLength;\n\n if (payloadLength === 126) {\n target.writeUInt16BE(dataLength, 2);\n } else if (payloadLength === 127) {\n target[2] = target[3] = 0;\n target.writeUIntBE(dataLength, 4, 6);\n }\n\n if (!options.mask) return [target, data];\n\n target[1] |= 0x80;\n target[offset - 4] = mask[0];\n target[offset - 3] = mask[1];\n target[offset - 2] = mask[2];\n target[offset - 1] = mask[3];\n\n if (skipMasking) return [target, data];\n\n if (merge) {\n applyMask(data, mask, target, offset, dataLength);\n return [target];\n }\n\n applyMask(data, mask, data, 0, dataLength);\n return [target, data];\n }\n\n /**\n * Sends a close message to the other peer.\n *\n * @param {Number} [code] The status code component of the body\n * @param {(String|Buffer)} [data] The message component of the body\n * @param {Boolean} [mask=false] Specifies whether or not to mask the message\n * @param {Function} [cb] Callback\n * @public\n */\n close(code, data, mask, cb) {\n let buf;\n\n if (code === undefined) {\n buf = EMPTY_BUFFER;\n } else if (typeof code !== 'number' || !isValidStatusCode(code)) {\n throw new TypeError('First argument must be a valid error code number');\n } else if (data === undefined || !data.length) {\n buf = Buffer.allocUnsafe(2);\n buf.writeUInt16BE(code, 0);\n } else {\n const length = Buffer.byteLength(data);\n\n if (length > 123) {\n throw new RangeError('The message must not be greater than 123 bytes');\n }\n\n buf = Buffer.allocUnsafe(2 + length);\n buf.writeUInt16BE(code, 0);\n\n if (typeof data === 'string') {\n buf.write(data, 2);\n } else {\n buf.set(data, 2);\n }\n }\n\n const options = {\n [kByteLength]: buf.length,\n fin: true,\n generateMask: this._generateMask,\n mask,\n maskBuffer: this._maskBuffer,\n opcode: 0x08,\n readOnly: false,\n rsv1: false\n };\n\n if (this._state !== DEFAULT) {\n this.enqueue([this.dispatch, buf, false, options, cb]);\n } else {\n this.sendFrame(Sender.frame(buf, options), cb);\n }\n }\n\n /**\n * Sends a ping message to the other peer.\n *\n * @param {*} data The message to send\n * @param {Boolean} [mask=false] Specifies whether or not to mask `data`\n * @param {Function} [cb] Callback\n * @public\n */\n ping(data, mask, cb) {\n let byteLength;\n let readOnly;\n\n if (typeof data === 'string') {\n byteLength = Buffer.byteLength(data);\n readOnly = false;\n } else if (isBlob(data)) {\n byteLength = data.size;\n readOnly = false;\n } else {\n data = toBuffer(data);\n byteLength = data.length;\n readOnly = toBuffer.readOnly;\n }\n\n if (byteLength > 125) {\n throw new RangeError('The data size must not be greater than 125 bytes');\n }\n\n const options = {\n [kByteLength]: byteLength,\n fin: true,\n generateMask: this._generateMask,\n mask,\n maskBuffer: this._maskBuffer,\n opcode: 0x09,\n readOnly,\n rsv1: false\n };\n\n if (isBlob(data)) {\n if (this._state !== DEFAULT) {\n this.enqueue([this.getBlobData, data, false, options, cb]);\n } else {\n this.getBlobData(data, false, options, cb);\n }\n } else if (this._state !== DEFAULT) {\n this.enqueue([this.dispatch, data, false, options, cb]);\n } else {\n this.sendFrame(Sender.frame(data, options), cb);\n }\n }\n\n /**\n * Sends a pong message to the other peer.\n *\n * @param {*} data The message to send\n * @param {Boolean} [mask=false] Specifies whether or not to mask `data`\n * @param {Function} [cb] Callback\n * @public\n */\n pong(data, mask, cb) {\n let byteLength;\n let readOnly;\n\n if (typeof data === 'string') {\n byteLength = Buffer.byteLength(data);\n readOnly = false;\n } else if (isBlob(data)) {\n byteLength = data.size;\n readOnly = false;\n } else {\n data = toBuffer(data);\n byteLength = data.length;\n readOnly = toBuffer.readOnly;\n }\n\n if (byteLength > 125) {\n throw new RangeError('The data size must not be greater than 125 bytes');\n }\n\n const options = {\n [kByteLength]: byteLength,\n fin: true,\n generateMask: this._generateMask,\n mask,\n maskBuffer: this._maskBuffer,\n opcode: 0x0a,\n readOnly,\n rsv1: false\n };\n\n if (isBlob(data)) {\n if (this._state !== DEFAULT) {\n this.enqueue([this.getBlobData, data, false, options, cb]);\n } else {\n this.getBlobData(data, false, options, cb);\n }\n } else if (this._state !== DEFAULT) {\n this.enqueue([this.dispatch, data, false, options, cb]);\n } else {\n this.sendFrame(Sender.frame(data, options), cb);\n }\n }\n\n /**\n * Sends a data message to the other peer.\n *\n * @param {*} data The message to send\n * @param {Object} options Options object\n * @param {Boolean} [options.binary=false] Specifies whether `data` is binary\n * or text\n * @param {Boolean} [options.compress=false] Specifies whether or not to\n * compress `data`\n * @param {Boolean} [options.fin=false] Specifies whether the fragment is the\n * last one\n * @param {Boolean} [options.mask=false] Specifies whether or not to mask\n * `data`\n * @param {Function} [cb] Callback\n * @public\n */\n send(data, options, cb) {\n const perMessageDeflate = this._extensions[PerMessageDeflate.extensionName];\n let opcode = options.binary ? 2 : 1;\n let rsv1 = options.compress;\n\n let byteLength;\n let readOnly;\n\n if (typeof data === 'string') {\n byteLength = Buffer.byteLength(data);\n readOnly = false;\n } else if (isBlob(data)) {\n byteLength = data.size;\n readOnly = false;\n } else {\n data = toBuffer(data);\n byteLength = data.length;\n readOnly = toBuffer.readOnly;\n }\n\n if (this._firstFragment) {\n this._firstFragment = false;\n if (\n rsv1 &&\n perMessageDeflate &&\n perMessageDeflate.params[\n perMessageDeflate._isServer\n ? 'server_no_context_takeover'\n : 'client_no_context_takeover'\n ]\n ) {\n rsv1 = byteLength >= perMessageDeflate._threshold;\n }\n this._compress = rsv1;\n } else {\n rsv1 = false;\n opcode = 0;\n }\n\n if (options.fin) this._firstFragment = true;\n\n const opts = {\n [kByteLength]: byteLength,\n fin: options.fin,\n generateMask: this._generateMask,\n mask: options.mask,\n maskBuffer: this._maskBuffer,\n opcode,\n readOnly,\n rsv1\n };\n\n if (isBlob(data)) {\n if (this._state !== DEFAULT) {\n this.enqueue([this.getBlobData, data, this._compress, opts, cb]);\n } else {\n this.getBlobData(data, this._compress, opts, cb);\n }\n } else if (this._state !== DEFAULT) {\n this.enqueue([this.dispatch, data, this._compress, opts, cb]);\n } else {\n this.dispatch(data, this._compress, opts, cb);\n }\n }\n\n /**\n * Gets the contents of a blob as binary data.\n *\n * @param {Blob} blob The blob\n * @param {Boolean} [compress=false] Specifies whether or not to compress\n * the data\n * @param {Object} options Options object\n * @param {Boolean} [options.fin=false] Specifies whether or not to set the\n * FIN bit\n * @param {Function} [options.generateMask] The function used to generate the\n * masking key\n * @param {Boolean} [options.mask=false] Specifies whether or not to mask\n * `data`\n * @param {Buffer} [options.maskBuffer] The buffer used to store the masking\n * key\n * @param {Number} options.opcode The opcode\n * @param {Boolean} [options.readOnly=false] Specifies whether `data` can be\n * modified\n * @param {Boolean} [options.rsv1=false] Specifies whether or not to set the\n * RSV1 bit\n * @param {Function} [cb] Callback\n * @private\n */\n getBlobData(blob, compress, options, cb) {\n this._bufferedBytes += options[kByteLength];\n this._state = GET_BLOB_DATA;\n\n blob\n .arrayBuffer()\n .then((arrayBuffer) => {\n if (this._socket.destroyed) {\n const err = new Error(\n 'The socket was closed while the blob was being read'\n );\n\n //\n // `callCallbacks` is called in the next tick to ensure that errors\n // that might be thrown in the callbacks behave like errors thrown\n // outside the promise chain.\n //\n process.nextTick(callCallbacks, this, err, cb);\n return;\n }\n\n this._bufferedBytes -= options[kByteLength];\n const data = toBuffer(arrayBuffer);\n\n if (!compress) {\n this._state = DEFAULT;\n this.sendFrame(Sender.frame(data, options), cb);\n this.dequeue();\n } else {\n this.dispatch(data, compress, options, cb);\n }\n })\n .catch((err) => {\n //\n // `onError` is called in the next tick for the same reason that\n // `callCallbacks` above is.\n //\n process.nextTick(onError, this, err, cb);\n });\n }\n\n /**\n * Dispatches a message.\n *\n * @param {(Buffer|String)} data The message to send\n * @param {Boolean} [compress=false] Specifies whether or not to compress\n * `data`\n * @param {Object} options Options object\n * @param {Boolean} [options.fin=false] Specifies whether or not to set the\n * FIN bit\n * @param {Function} [options.generateMask] The function used to generate the\n * masking key\n * @param {Boolean} [options.mask=false] Specifies whether or not to mask\n * `data`\n * @param {Buffer} [options.maskBuffer] The buffer used to store the masking\n * key\n * @param {Number} options.opcode The opcode\n * @param {Boolean} [options.readOnly=false] Specifies whether `data` can be\n * modified\n * @param {Boolean} [options.rsv1=false] Specifies whether or not to set the\n * RSV1 bit\n * @param {Function} [cb] Callback\n * @private\n */\n dispatch(data, compress, options, cb) {\n if (!compress) {\n this.sendFrame(Sender.frame(data, options), cb);\n return;\n }\n\n const perMessageDeflate = this._extensions[PerMessageDeflate.extensionName];\n\n this._bufferedBytes += options[kByteLength];\n this._state = DEFLATING;\n perMessageDeflate.compress(data, options.fin, (_, buf) => {\n if (this._socket.destroyed) {\n const err = new Error(\n 'The socket was closed while data was being compressed'\n );\n\n callCallbacks(this, err, cb);\n return;\n }\n\n this._bufferedBytes -= options[kByteLength];\n this._state = DEFAULT;\n options.readOnly = false;\n this.sendFrame(Sender.frame(buf, options), cb);\n this.dequeue();\n });\n }\n\n /**\n * Executes queued send operations.\n *\n * @private\n */\n dequeue() {\n while (this._state === DEFAULT && this._queue.length) {\n const params = this._queue.shift();\n\n this._bufferedBytes -= params[3][kByteLength];\n Reflect.apply(params[0], this, params.slice(1));\n }\n }\n\n /**\n * Enqueues a send operation.\n *\n * @param {Array} params Send operation parameters.\n * @private\n */\n enqueue(params) {\n this._bufferedBytes += params[3][kByteLength];\n this._queue.push(params);\n }\n\n /**\n * Sends a frame.\n *\n * @param {(Buffer | String)[]} list The frame to send\n * @param {Function} [cb] Callback\n * @private\n */\n sendFrame(list, cb) {\n if (list.length === 2) {\n this._socket.cork();\n this._socket.write(list[0]);\n this._socket.write(list[1], cb);\n this._socket.uncork();\n } else {\n this._socket.write(list[0], cb);\n }\n }\n}\n\nmodule.exports = Sender;\n\n/**\n * Calls queued callbacks with an error.\n *\n * @param {Sender} sender The `Sender` instance\n * @param {Error} err The error to call the callbacks with\n * @param {Function} [cb] The first callback\n * @private\n */\nfunction callCallbacks(sender, err, cb) {\n if (typeof cb === 'function') cb(err);\n\n for (let i = 0; i < sender._queue.length; i++) {\n const params = sender._queue[i];\n const callback = params[params.length - 1];\n\n if (typeof callback === 'function') callback(err);\n }\n}\n\n/**\n * Handles a `Sender` error.\n *\n * @param {Sender} sender The `Sender` instance\n * @param {Error} err The error\n * @param {Function} [cb] The first pending callback\n * @private\n */\nfunction onError(sender, err, cb) {\n callCallbacks(sender, err, cb);\n sender.onerror(err);\n}\n", "'use strict';\n\nconst { kForOnEventAttribute, kListener } = require('./constants');\n\nconst kCode = Symbol('kCode');\nconst kData = Symbol('kData');\nconst kError = Symbol('kError');\nconst kMessage = Symbol('kMessage');\nconst kReason = Symbol('kReason');\nconst kTarget = Symbol('kTarget');\nconst kType = Symbol('kType');\nconst kWasClean = Symbol('kWasClean');\n\n/**\n * Class representing an event.\n */\nclass Event {\n /**\n * Create a new `Event`.\n *\n * @param {String} type The name of the event\n * @throws {TypeError} If the `type` argument is not specified\n */\n constructor(type) {\n this[kTarget] = null;\n this[kType] = type;\n }\n\n /**\n * @type {*}\n */\n get target() {\n return this[kTarget];\n }\n\n /**\n * @type {String}\n */\n get type() {\n return this[kType];\n }\n}\n\nObject.defineProperty(Event.prototype, 'target', { enumerable: true });\nObject.defineProperty(Event.prototype, 'type', { enumerable: true });\n\n/**\n * Class representing a close event.\n *\n * @extends Event\n */\nclass CloseEvent extends Event {\n /**\n * Create a new `CloseEvent`.\n *\n * @param {String} type The name of the event\n * @param {Object} [options] A dictionary object that allows for setting\n * attributes via object members of the same name\n * @param {Number} [options.code=0] The status code explaining why the\n * connection was closed\n * @param {String} [options.reason=''] A human-readable string explaining why\n * the connection was closed\n * @param {Boolean} [options.wasClean=false] Indicates whether or not the\n * connection was cleanly closed\n */\n constructor(type, options = {}) {\n super(type);\n\n this[kCode] = options.code === undefined ? 0 : options.code;\n this[kReason] = options.reason === undefined ? '' : options.reason;\n this[kWasClean] = options.wasClean === undefined ? false : options.wasClean;\n }\n\n /**\n * @type {Number}\n */\n get code() {\n return this[kCode];\n }\n\n /**\n * @type {String}\n */\n get reason() {\n return this[kReason];\n }\n\n /**\n * @type {Boolean}\n */\n get wasClean() {\n return this[kWasClean];\n }\n}\n\nObject.defineProperty(CloseEvent.prototype, 'code', { enumerable: true });\nObject.defineProperty(CloseEvent.prototype, 'reason', { enumerable: true });\nObject.defineProperty(CloseEvent.prototype, 'wasClean', { enumerable: true });\n\n/**\n * Class representing an error event.\n *\n * @extends Event\n */\nclass ErrorEvent extends Event {\n /**\n * Create a new `ErrorEvent`.\n *\n * @param {String} type The name of the event\n * @param {Object} [options] A dictionary object that allows for setting\n * attributes via object members of the same name\n * @param {*} [options.error=null] The error that generated this event\n * @param {String} [options.message=''] The error message\n */\n constructor(type, options = {}) {\n super(type);\n\n this[kError] = options.error === undefined ? null : options.error;\n this[kMessage] = options.message === undefined ? '' : options.message;\n }\n\n /**\n * @type {*}\n */\n get error() {\n return this[kError];\n }\n\n /**\n * @type {String}\n */\n get message() {\n return this[kMessage];\n }\n}\n\nObject.defineProperty(ErrorEvent.prototype, 'error', { enumerable: true });\nObject.defineProperty(ErrorEvent.prototype, 'message', { enumerable: true });\n\n/**\n * Class representing a message event.\n *\n * @extends Event\n */\nclass MessageEvent extends Event {\n /**\n * Create a new `MessageEvent`.\n *\n * @param {String} type The name of the event\n * @param {Object} [options] A dictionary object that allows for setting\n * attributes via object members of the same name\n * @param {*} [options.data=null] The message content\n */\n constructor(type, options = {}) {\n super(type);\n\n this[kData] = options.data === undefined ? null : options.data;\n }\n\n /**\n * @type {*}\n */\n get data() {\n return this[kData];\n }\n}\n\nObject.defineProperty(MessageEvent.prototype, 'data', { enumerable: true });\n\n/**\n * This provides methods for emulating the `EventTarget` interface. It's not\n * meant to be used directly.\n *\n * @mixin\n */\nconst EventTarget = {\n /**\n * Register an event listener.\n *\n * @param {String} type A string representing the event type to listen for\n * @param {(Function|Object)} handler The listener to add\n * @param {Object} [options] An options object specifies characteristics about\n * the event listener\n * @param {Boolean} [options.once=false] A `Boolean` indicating that the\n * listener should be invoked at most once after being added. If `true`,\n * the listener would be automatically removed when invoked.\n * @public\n */\n addEventListener(type, handler, options = {}) {\n for (const listener of this.listeners(type)) {\n if (\n !options[kForOnEventAttribute] &&\n listener[kListener] === handler &&\n !listener[kForOnEventAttribute]\n ) {\n return;\n }\n }\n\n let wrapper;\n\n if (type === 'message') {\n wrapper = function onMessage(data, isBinary) {\n const event = new MessageEvent('message', {\n data: isBinary ? data : data.toString()\n });\n\n event[kTarget] = this;\n callListener(handler, this, event);\n };\n } else if (type === 'close') {\n wrapper = function onClose(code, message) {\n const event = new CloseEvent('close', {\n code,\n reason: message.toString(),\n wasClean: this._closeFrameReceived && this._closeFrameSent\n });\n\n event[kTarget] = this;\n callListener(handler, this, event);\n };\n } else if (type === 'error') {\n wrapper = function onError(error) {\n const event = new ErrorEvent('error', {\n error,\n message: error.message\n });\n\n event[kTarget] = this;\n callListener(handler, this, event);\n };\n } else if (type === 'open') {\n wrapper = function onOpen() {\n const event = new Event('open');\n\n event[kTarget] = this;\n callListener(handler, this, event);\n };\n } else {\n return;\n }\n\n wrapper[kForOnEventAttribute] = !!options[kForOnEventAttribute];\n wrapper[kListener] = handler;\n\n if (options.once) {\n this.once(type, wrapper);\n } else {\n this.on(type, wrapper);\n }\n },\n\n /**\n * Remove an event listener.\n *\n * @param {String} type A string representing the event type to remove\n * @param {(Function|Object)} handler The listener to remove\n * @public\n */\n removeEventListener(type, handler) {\n for (const listener of this.listeners(type)) {\n if (listener[kListener] === handler && !listener[kForOnEventAttribute]) {\n this.removeListener(type, listener);\n break;\n }\n }\n }\n};\n\nmodule.exports = {\n CloseEvent,\n ErrorEvent,\n Event,\n EventTarget,\n MessageEvent\n};\n\n/**\n * Call an event listener\n *\n * @param {(Function|Object)} listener The listener to call\n * @param {*} thisArg The value to use as `this`` when calling the listener\n * @param {Event} event The event to pass to the listener\n * @private\n */\nfunction callListener(listener, thisArg, event) {\n if (typeof listener === 'object' && listener.handleEvent) {\n listener.handleEvent.call(listener, event);\n } else {\n listener.call(thisArg, event);\n }\n}\n", "'use strict';\n\nconst { tokenChars } = require('./validation');\n\n/**\n * Adds an offer to the map of extension offers or a parameter to the map of\n * parameters.\n *\n * @param {Object} dest The map of extension offers or parameters\n * @param {String} name The extension or parameter name\n * @param {(Object|Boolean|String)} elem The extension parameters or the\n * parameter value\n * @private\n */\nfunction push(dest, name, elem) {\n if (dest[name] === undefined) dest[name] = [elem];\n else dest[name].push(elem);\n}\n\n/**\n * Parses the `Sec-WebSocket-Extensions` header into an object.\n *\n * @param {String} header The field value of the header\n * @return {Object} The parsed object\n * @public\n */\nfunction parse(header) {\n const offers = Object.create(null);\n let params = Object.create(null);\n let mustUnescape = false;\n let isEscaping = false;\n let inQuotes = false;\n let extensionName;\n let paramName;\n let start = -1;\n let code = -1;\n let end = -1;\n let i = 0;\n\n for (; i < header.length; i++) {\n code = header.charCodeAt(i);\n\n if (extensionName === undefined) {\n if (end === -1 && tokenChars[code] === 1) {\n if (start === -1) start = i;\n } else if (\n i !== 0 &&\n (code === 0x20 /* ' ' */ || code === 0x09) /* '\\t' */\n ) {\n if (end === -1 && start !== -1) end = i;\n } else if (code === 0x3b /* ';' */ || code === 0x2c /* ',' */) {\n if (start === -1) {\n throw new SyntaxError(`Unexpected character at index ${i}`);\n }\n\n if (end === -1) end = i;\n const name = header.slice(start, end);\n if (code === 0x2c) {\n push(offers, name, params);\n params = Object.create(null);\n } else {\n extensionName = name;\n }\n\n start = end = -1;\n } else {\n throw new SyntaxError(`Unexpected character at index ${i}`);\n }\n } else if (paramName === undefined) {\n if (end === -1 && tokenChars[code] === 1) {\n if (start === -1) start = i;\n } else if (code === 0x20 || code === 0x09) {\n if (end === -1 && start !== -1) end = i;\n } else if (code === 0x3b || code === 0x2c) {\n if (start === -1) {\n throw new SyntaxError(`Unexpected character at index ${i}`);\n }\n\n if (end === -1) end = i;\n push(params, header.slice(start, end), true);\n if (code === 0x2c) {\n push(offers, extensionName, params);\n params = Object.create(null);\n extensionName = undefined;\n }\n\n start = end = -1;\n } else if (code === 0x3d /* '=' */ && start !== -1 && end === -1) {\n paramName = header.slice(start, i);\n start = end = -1;\n } else {\n throw new SyntaxError(`Unexpected character at index ${i}`);\n }\n } else {\n //\n // The value of a quoted-string after unescaping must conform to the\n // token ABNF, so only token characters are valid.\n // Ref: https://tools.ietf.org/html/rfc6455#section-9.1\n //\n if (isEscaping) {\n if (tokenChars[code] !== 1) {\n throw new SyntaxError(`Unexpected character at index ${i}`);\n }\n if (start === -1) start = i;\n else if (!mustUnescape) mustUnescape = true;\n isEscaping = false;\n } else if (inQuotes) {\n if (tokenChars[code] === 1) {\n if (start === -1) start = i;\n } else if (code === 0x22 /* '\"' */ && start !== -1) {\n inQuotes = false;\n end = i;\n } else if (code === 0x5c /* '\\' */) {\n isEscaping = true;\n } else {\n throw new SyntaxError(`Unexpected character at index ${i}`);\n }\n } else if (code === 0x22 && header.charCodeAt(i - 1) === 0x3d) {\n inQuotes = true;\n } else if (end === -1 && tokenChars[code] === 1) {\n if (start === -1) start = i;\n } else if (start !== -1 && (code === 0x20 || code === 0x09)) {\n if (end === -1) end = i;\n } else if (code === 0x3b || code === 0x2c) {\n if (start === -1) {\n throw new SyntaxError(`Unexpected character at index ${i}`);\n }\n\n if (end === -1) end = i;\n let value = header.slice(start, end);\n if (mustUnescape) {\n value = value.replace(/\\\\/g, '');\n mustUnescape = false;\n }\n push(params, paramName, value);\n if (code === 0x2c) {\n push(offers, extensionName, params);\n params = Object.create(null);\n extensionName = undefined;\n }\n\n paramName = undefined;\n start = end = -1;\n } else {\n throw new SyntaxError(`Unexpected character at index ${i}`);\n }\n }\n }\n\n if (start === -1 || inQuotes || code === 0x20 || code === 0x09) {\n throw new SyntaxError('Unexpected end of input');\n }\n\n if (end === -1) end = i;\n const token = header.slice(start, end);\n if (extensionName === undefined) {\n push(offers, token, params);\n } else {\n if (paramName === undefined) {\n push(params, token, true);\n } else if (mustUnescape) {\n push(params, paramName, token.replace(/\\\\/g, ''));\n } else {\n push(params, paramName, token);\n }\n push(offers, extensionName, params);\n }\n\n return offers;\n}\n\n/**\n * Builds the `Sec-WebSocket-Extensions` header field value.\n *\n * @param {Object} extensions The map of extensions and parameters to format\n * @return {String} A string representing the given object\n * @public\n */\nfunction format(extensions) {\n return Object.keys(extensions)\n .map((extension) => {\n let configurations = extensions[extension];\n if (!Array.isArray(configurations)) configurations = [configurations];\n return configurations\n .map((params) => {\n return [extension]\n .concat(\n Object.keys(params).map((k) => {\n let values = params[k];\n if (!Array.isArray(values)) values = [values];\n return values\n .map((v) => (v === true ? k : `${k}=${v}`))\n .join('; ');\n })\n )\n .join('; ');\n })\n .join(', ');\n })\n .join(', ');\n}\n\nmodule.exports = { format, parse };\n", "/* eslint no-unused-vars: [\"error\", { \"varsIgnorePattern\": \"^Duplex|Readable$\", \"caughtErrors\": \"none\" }] */\n\n'use strict';\n\nconst EventEmitter = require('events');\nconst https = require('https');\nconst http = require('http');\nconst net = require('net');\nconst tls = require('tls');\nconst { randomBytes, createHash } = require('crypto');\nconst { Duplex, Readable } = require('stream');\nconst { URL } = require('url');\n\nconst PerMessageDeflate = require('./permessage-deflate');\nconst Receiver = require('./receiver');\nconst Sender = require('./sender');\nconst { isBlob } = require('./validation');\n\nconst {\n BINARY_TYPES,\n EMPTY_BUFFER,\n GUID,\n kForOnEventAttribute,\n kListener,\n kStatusCode,\n kWebSocket,\n NOOP\n} = require('./constants');\nconst {\n EventTarget: { addEventListener, removeEventListener }\n} = require('./event-target');\nconst { format, parse } = require('./extension');\nconst { toBuffer } = require('./buffer-util');\n\nconst closeTimeout = 30 * 1000;\nconst kAborted = Symbol('kAborted');\nconst protocolVersions = [8, 13];\nconst readyStates = ['CONNECTING', 'OPEN', 'CLOSING', 'CLOSED'];\nconst subprotocolRegex = /^[!#$%&'*+\\-.0-9A-Z^_`|a-z~]+$/;\n\n/**\n * Class representing a WebSocket.\n *\n * @extends EventEmitter\n */\nclass WebSocket extends EventEmitter {\n /**\n * Create a new `WebSocket`.\n *\n * @param {(String|URL)} address The URL to which to connect\n * @param {(String|String[])} [protocols] The subprotocols\n * @param {Object} [options] Connection options\n */\n constructor(address, protocols, options) {\n super();\n\n this._binaryType = BINARY_TYPES[0];\n this._closeCode = 1006;\n this._closeFrameReceived = false;\n this._closeFrameSent = false;\n this._closeMessage = EMPTY_BUFFER;\n this._closeTimer = null;\n this._errorEmitted = false;\n this._extensions = {};\n this._paused = false;\n this._protocol = '';\n this._readyState = WebSocket.CONNECTING;\n this._receiver = null;\n this._sender = null;\n this._socket = null;\n\n if (address !== null) {\n this._bufferedAmount = 0;\n this._isServer = false;\n this._redirects = 0;\n\n if (protocols === undefined) {\n protocols = [];\n } else if (!Array.isArray(protocols)) {\n if (typeof protocols === 'object' && protocols !== null) {\n options = protocols;\n protocols = [];\n } else {\n protocols = [protocols];\n }\n }\n\n initAsClient(this, address, protocols, options);\n } else {\n this._autoPong = options.autoPong;\n this._isServer = true;\n }\n }\n\n /**\n * For historical reasons, the custom \"nodebuffer\" type is used by the default\n * instead of \"blob\".\n *\n * @type {String}\n */\n get binaryType() {\n return this._binaryType;\n }\n\n set binaryType(type) {\n if (!BINARY_TYPES.includes(type)) return;\n\n this._binaryType = type;\n\n //\n // Allow to change `binaryType` on the fly.\n //\n if (this._receiver) this._receiver._binaryType = type;\n }\n\n /**\n * @type {Number}\n */\n get bufferedAmount() {\n if (!this._socket) return this._bufferedAmount;\n\n return this._socket._writableState.length + this._sender._bufferedBytes;\n }\n\n /**\n * @type {String}\n */\n get extensions() {\n return Object.keys(this._extensions).join();\n }\n\n /**\n * @type {Boolean}\n */\n get isPaused() {\n return this._paused;\n }\n\n /**\n * @type {Function}\n */\n /* istanbul ignore next */\n get onclose() {\n return null;\n }\n\n /**\n * @type {Function}\n */\n /* istanbul ignore next */\n get onerror() {\n return null;\n }\n\n /**\n * @type {Function}\n */\n /* istanbul ignore next */\n get onopen() {\n return null;\n }\n\n /**\n * @type {Function}\n */\n /* istanbul ignore next */\n get onmessage() {\n return null;\n }\n\n /**\n * @type {String}\n */\n get protocol() {\n return this._protocol;\n }\n\n /**\n * @type {Number}\n */\n get readyState() {\n return this._readyState;\n }\n\n /**\n * @type {String}\n */\n get url() {\n return this._url;\n }\n\n /**\n * Set up the socket and the internal resources.\n *\n * @param {Duplex} socket The network socket between the server and client\n * @param {Buffer} head The first packet of the upgraded stream\n * @param {Object} options Options object\n * @param {Boolean} [options.allowSynchronousEvents=false] Specifies whether\n * any of the `'message'`, `'ping'`, and `'pong'` events can be emitted\n * multiple times in the same tick\n * @param {Function} [options.generateMask] The function used to generate the\n * masking key\n * @param {Number} [options.maxPayload=0] The maximum allowed message size\n * @param {Boolean} [options.skipUTF8Validation=false] Specifies whether or\n * not to skip UTF-8 validation for text and close messages\n * @private\n */\n setSocket(socket, head, options) {\n const receiver = new Receiver({\n allowSynchronousEvents: options.allowSynchronousEvents,\n binaryType: this.binaryType,\n extensions: this._extensions,\n isServer: this._isServer,\n maxPayload: options.maxPayload,\n skipUTF8Validation: options.skipUTF8Validation\n });\n\n const sender = new Sender(socket, this._extensions, options.generateMask);\n\n this._receiver = receiver;\n this._sender = sender;\n this._socket = socket;\n\n receiver[kWebSocket] = this;\n sender[kWebSocket] = this;\n socket[kWebSocket] = this;\n\n receiver.on('conclude', receiverOnConclude);\n receiver.on('drain', receiverOnDrain);\n receiver.on('error', receiverOnError);\n receiver.on('message', receiverOnMessage);\n receiver.on('ping', receiverOnPing);\n receiver.on('pong', receiverOnPong);\n\n sender.onerror = senderOnError;\n\n //\n // These methods may not be available if `socket` is just a `Duplex`.\n //\n if (socket.setTimeout) socket.setTimeout(0);\n if (socket.setNoDelay) socket.setNoDelay();\n\n if (head.length > 0) socket.unshift(head);\n\n socket.on('close', socketOnClose);\n socket.on('data', socketOnData);\n socket.on('end', socketOnEnd);\n socket.on('error', socketOnError);\n\n this._readyState = WebSocket.OPEN;\n this.emit('open');\n }\n\n /**\n * Emit the `'close'` event.\n *\n * @private\n */\n emitClose() {\n if (!this._socket) {\n this._readyState = WebSocket.CLOSED;\n this.emit('close', this._closeCode, this._closeMessage);\n return;\n }\n\n if (this._extensions[PerMessageDeflate.extensionName]) {\n this._extensions[PerMessageDeflate.extensionName].cleanup();\n }\n\n this._receiver.removeAllListeners();\n this._readyState = WebSocket.CLOSED;\n this.emit('close', this._closeCode, this._closeMessage);\n }\n\n /**\n * Start a closing handshake.\n *\n * +----------+ +-----------+ +----------+\n * - - -|ws.close()|-->|close frame|-->|ws.close()|- - -\n * | +----------+ +-----------+ +----------+ |\n * +----------+ +-----------+ |\n * CLOSING |ws.close()|<--|close frame|<--+-----+ CLOSING\n * +----------+ +-----------+ |\n * | | | +---+ |\n * +------------------------+-->|fin| - - - -\n * | +---+ | +---+\n * - - - - -|fin|<---------------------+\n * +---+\n *\n * @param {Number} [code] Status code explaining why the connection is closing\n * @param {(String|Buffer)} [data] The reason why the connection is\n * closing\n * @public\n */\n close(code, data) {\n if (this.readyState === WebSocket.CLOSED) return;\n if (this.readyState === WebSocket.CONNECTING) {\n const msg = 'WebSocket was closed before the connection was established';\n abortHandshake(this, this._req, msg);\n return;\n }\n\n if (this.readyState === WebSocket.CLOSING) {\n if (\n this._closeFrameSent &&\n (this._closeFrameReceived || this._receiver._writableState.errorEmitted)\n ) {\n this._socket.end();\n }\n\n return;\n }\n\n this._readyState = WebSocket.CLOSING;\n this._sender.close(code, data, !this._isServer, (err) => {\n //\n // This error is handled by the `'error'` listener on the socket. We only\n // want to know if the close frame has been sent here.\n //\n if (err) return;\n\n this._closeFrameSent = true;\n\n if (\n this._closeFrameReceived ||\n this._receiver._writableState.errorEmitted\n ) {\n this._socket.end();\n }\n });\n\n setCloseTimer(this);\n }\n\n /**\n * Pause the socket.\n *\n * @public\n */\n pause() {\n if (\n this.readyState === WebSocket.CONNECTING ||\n this.readyState === WebSocket.CLOSED\n ) {\n return;\n }\n\n this._paused = true;\n this._socket.pause();\n }\n\n /**\n * Send a ping.\n *\n * @param {*} [data] The data to send\n * @param {Boolean} [mask] Indicates whether or not to mask `data`\n * @param {Function} [cb] Callback which is executed when the ping is sent\n * @public\n */\n ping(data, mask, cb) {\n if (this.readyState === WebSocket.CONNECTING) {\n throw new Error('WebSocket is not open: readyState 0 (CONNECTING)');\n }\n\n if (typeof data === 'function') {\n cb = data;\n data = mask = undefined;\n } else if (typeof mask === 'function') {\n cb = mask;\n mask = undefined;\n }\n\n if (typeof data === 'number') data = data.toString();\n\n if (this.readyState !== WebSocket.OPEN) {\n sendAfterClose(this, data, cb);\n return;\n }\n\n if (mask === undefined) mask = !this._isServer;\n this._sender.ping(data || EMPTY_BUFFER, mask, cb);\n }\n\n /**\n * Send a pong.\n *\n * @param {*} [data] The data to send\n * @param {Boolean} [mask] Indicates whether or not to mask `data`\n * @param {Function} [cb] Callback which is executed when the pong is sent\n * @public\n */\n pong(data, mask, cb) {\n if (this.readyState === WebSocket.CONNECTING) {\n throw new Error('WebSocket is not open: readyState 0 (CONNECTING)');\n }\n\n if (typeof data === 'function') {\n cb = data;\n data = mask = undefined;\n } else if (typeof mask === 'function') {\n cb = mask;\n mask = undefined;\n }\n\n if (typeof data === 'number') data = data.toString();\n\n if (this.readyState !== WebSocket.OPEN) {\n sendAfterClose(this, data, cb);\n return;\n }\n\n if (mask === undefined) mask = !this._isServer;\n this._sender.pong(data || EMPTY_BUFFER, mask, cb);\n }\n\n /**\n * Resume the socket.\n *\n * @public\n */\n resume() {\n if (\n this.readyState === WebSocket.CONNECTING ||\n this.readyState === WebSocket.CLOSED\n ) {\n return;\n }\n\n this._paused = false;\n if (!this._receiver._writableState.needDrain) this._socket.resume();\n }\n\n /**\n * Send a data message.\n *\n * @param {*} data The message to send\n * @param {Object} [options] Options object\n * @param {Boolean} [options.binary] Specifies whether `data` is binary or\n * text\n * @param {Boolean} [options.compress] Specifies whether or not to compress\n * `data`\n * @param {Boolean} [options.fin=true] Specifies whether the fragment is the\n * last one\n * @param {Boolean} [options.mask] Specifies whether or not to mask `data`\n * @param {Function} [cb] Callback which is executed when data is written out\n * @public\n */\n send(data, options, cb) {\n if (this.readyState === WebSocket.CONNECTING) {\n throw new Error('WebSocket is not open: readyState 0 (CONNECTING)');\n }\n\n if (typeof options === 'function') {\n cb = options;\n options = {};\n }\n\n if (typeof data === 'number') data = data.toString();\n\n if (this.readyState !== WebSocket.OPEN) {\n sendAfterClose(this, data, cb);\n return;\n }\n\n const opts = {\n binary: typeof data !== 'string',\n mask: !this._isServer,\n compress: true,\n fin: true,\n ...options\n };\n\n if (!this._extensions[PerMessageDeflate.extensionName]) {\n opts.compress = false;\n }\n\n this._sender.send(data || EMPTY_BUFFER, opts, cb);\n }\n\n /**\n * Forcibly close the connection.\n *\n * @public\n */\n terminate() {\n if (this.readyState === WebSocket.CLOSED) return;\n if (this.readyState === WebSocket.CONNECTING) {\n const msg = 'WebSocket was closed before the connection was established';\n abortHandshake(this, this._req, msg);\n return;\n }\n\n if (this._socket) {\n this._readyState = WebSocket.CLOSING;\n this._socket.destroy();\n }\n }\n}\n\n/**\n * @constant {Number} CONNECTING\n * @memberof WebSocket\n */\nObject.defineProperty(WebSocket, 'CONNECTING', {\n enumerable: true,\n value: readyStates.indexOf('CONNECTING')\n});\n\n/**\n * @constant {Number} CONNECTING\n * @memberof WebSocket.prototype\n */\nObject.defineProperty(WebSocket.prototype, 'CONNECTING', {\n enumerable: true,\n value: readyStates.indexOf('CONNECTING')\n});\n\n/**\n * @constant {Number} OPEN\n * @memberof WebSocket\n */\nObject.defineProperty(WebSocket, 'OPEN', {\n enumerable: true,\n value: readyStates.indexOf('OPEN')\n});\n\n/**\n * @constant {Number} OPEN\n * @memberof WebSocket.prototype\n */\nObject.defineProperty(WebSocket.prototype, 'OPEN', {\n enumerable: true,\n value: readyStates.indexOf('OPEN')\n});\n\n/**\n * @constant {Number} CLOSING\n * @memberof WebSocket\n */\nObject.defineProperty(WebSocket, 'CLOSING', {\n enumerable: true,\n value: readyStates.indexOf('CLOSING')\n});\n\n/**\n * @constant {Number} CLOSING\n * @memberof WebSocket.prototype\n */\nObject.defineProperty(WebSocket.prototype, 'CLOSING', {\n enumerable: true,\n value: readyStates.indexOf('CLOSING')\n});\n\n/**\n * @constant {Number} CLOSED\n * @memberof WebSocket\n */\nObject.defineProperty(WebSocket, 'CLOSED', {\n enumerable: true,\n value: readyStates.indexOf('CLOSED')\n});\n\n/**\n * @constant {Number} CLOSED\n * @memberof WebSocket.prototype\n */\nObject.defineProperty(WebSocket.prototype, 'CLOSED', {\n enumerable: true,\n value: readyStates.indexOf('CLOSED')\n});\n\n[\n 'binaryType',\n 'bufferedAmount',\n 'extensions',\n 'isPaused',\n 'protocol',\n 'readyState',\n 'url'\n].forEach((property) => {\n Object.defineProperty(WebSocket.prototype, property, { enumerable: true });\n});\n\n//\n// Add the `onopen`, `onerror`, `onclose`, and `onmessage` attributes.\n// See https://html.spec.whatwg.org/multipage/comms.html#the-websocket-interface\n//\n['open', 'error', 'close', 'message'].forEach((method) => {\n Object.defineProperty(WebSocket.prototype, `on${method}`, {\n enumerable: true,\n get() {\n for (const listener of this.listeners(method)) {\n if (listener[kForOnEventAttribute]) return listener[kListener];\n }\n\n return null;\n },\n set(handler) {\n for (const listener of this.listeners(method)) {\n if (listener[kForOnEventAttribute]) {\n this.removeListener(method, listener);\n break;\n }\n }\n\n if (typeof handler !== 'function') return;\n\n this.addEventListener(method, handler, {\n [kForOnEventAttribute]: true\n });\n }\n });\n});\n\nWebSocket.prototype.addEventListener = addEventListener;\nWebSocket.prototype.removeEventListener = removeEventListener;\n\nmodule.exports = WebSocket;\n\n/**\n * Initialize a WebSocket client.\n *\n * @param {WebSocket} websocket The client to initialize\n * @param {(String|URL)} address The URL to which to connect\n * @param {Array} protocols The subprotocols\n * @param {Object} [options] Connection options\n * @param {Boolean} [options.allowSynchronousEvents=true] Specifies whether any\n * of the `'message'`, `'ping'`, and `'pong'` events can be emitted multiple\n * times in the same tick\n * @param {Boolean} [options.autoPong=true] Specifies whether or not to\n * automatically send a pong in response to a ping\n * @param {Function} [options.finishRequest] A function which can be used to\n * customize the headers of each http request before it is sent\n * @param {Boolean} [options.followRedirects=false] Whether or not to follow\n * redirects\n * @param {Function} [options.generateMask] The function used to generate the\n * masking key\n * @param {Number} [options.handshakeTimeout] Timeout in milliseconds for the\n * handshake request\n * @param {Number} [options.maxPayload=104857600] The maximum allowed message\n * size\n * @param {Number} [options.maxRedirects=10] The maximum number of redirects\n * allowed\n * @param {String} [options.origin] Value of the `Origin` or\n * `Sec-WebSocket-Origin` header\n * @param {(Boolean|Object)} [options.perMessageDeflate=true] Enable/disable\n * permessage-deflate\n * @param {Number} [options.protocolVersion=13] Value of the\n * `Sec-WebSocket-Version` header\n * @param {Boolean} [options.skipUTF8Validation=false] Specifies whether or\n * not to skip UTF-8 validation for text and close messages\n * @private\n */\nfunction initAsClient(websocket, address, protocols, options) {\n const opts = {\n allowSynchronousEvents: true,\n autoPong: true,\n protocolVersion: protocolVersions[1],\n maxPayload: 100 * 1024 * 1024,\n skipUTF8Validation: false,\n perMessageDeflate: true,\n followRedirects: false,\n maxRedirects: 10,\n ...options,\n socketPath: undefined,\n hostname: undefined,\n protocol: undefined,\n timeout: undefined,\n method: 'GET',\n host: undefined,\n path: undefined,\n port: undefined\n };\n\n websocket._autoPong = opts.autoPong;\n\n if (!protocolVersions.includes(opts.protocolVersion)) {\n throw new RangeError(\n `Unsupported protocol version: ${opts.protocolVersion} ` +\n `(supported versions: ${protocolVersions.join(', ')})`\n );\n }\n\n let parsedUrl;\n\n if (address instanceof URL) {\n parsedUrl = address;\n } else {\n try {\n parsedUrl = new URL(address);\n } catch (e) {\n throw new SyntaxError(`Invalid URL: ${address}`);\n }\n }\n\n if (parsedUrl.protocol === 'http:') {\n parsedUrl.protocol = 'ws:';\n } else if (parsedUrl.protocol === 'https:') {\n parsedUrl.protocol = 'wss:';\n }\n\n websocket._url = parsedUrl.href;\n\n const isSecure = parsedUrl.protocol === 'wss:';\n const isIpcUrl = parsedUrl.protocol === 'ws+unix:';\n let invalidUrlMessage;\n\n if (parsedUrl.protocol !== 'ws:' && !isSecure && !isIpcUrl) {\n invalidUrlMessage =\n 'The URL\\'s protocol must be one of \"ws:\", \"wss:\", ' +\n '\"http:\", \"https:\", or \"ws+unix:\"';\n } else if (isIpcUrl && !parsedUrl.pathname) {\n invalidUrlMessage = \"The URL's pathname is empty\";\n } else if (parsedUrl.hash) {\n invalidUrlMessage = 'The URL contains a fragment identifier';\n }\n\n if (invalidUrlMessage) {\n const err = new SyntaxError(invalidUrlMessage);\n\n if (websocket._redirects === 0) {\n throw err;\n } else {\n emitErrorAndClose(websocket, err);\n return;\n }\n }\n\n const defaultPort = isSecure ? 443 : 80;\n const key = randomBytes(16).toString('base64');\n const request = isSecure ? https.request : http.request;\n const protocolSet = new Set();\n let perMessageDeflate;\n\n opts.createConnection =\n opts.createConnection || (isSecure ? tlsConnect : netConnect);\n opts.defaultPort = opts.defaultPort || defaultPort;\n opts.port = parsedUrl.port || defaultPort;\n opts.host = parsedUrl.hostname.startsWith('[')\n ? parsedUrl.hostname.slice(1, -1)\n : parsedUrl.hostname;\n opts.headers = {\n ...opts.headers,\n 'Sec-WebSocket-Version': opts.protocolVersion,\n 'Sec-WebSocket-Key': key,\n Connection: 'Upgrade',\n Upgrade: 'websocket'\n };\n opts.path = parsedUrl.pathname + parsedUrl.search;\n opts.timeout = opts.handshakeTimeout;\n\n if (opts.perMessageDeflate) {\n perMessageDeflate = new PerMessageDeflate(\n opts.perMessageDeflate !== true ? opts.perMessageDeflate : {},\n false,\n opts.maxPayload\n );\n opts.headers['Sec-WebSocket-Extensions'] = format({\n [PerMessageDeflate.extensionName]: perMessageDeflate.offer()\n });\n }\n if (protocols.length) {\n for (const protocol of protocols) {\n if (\n typeof protocol !== 'string' ||\n !subprotocolRegex.test(protocol) ||\n protocolSet.has(protocol)\n ) {\n throw new SyntaxError(\n 'An invalid or duplicated subprotocol was specified'\n );\n }\n\n protocolSet.add(protocol);\n }\n\n opts.headers['Sec-WebSocket-Protocol'] = protocols.join(',');\n }\n if (opts.origin) {\n if (opts.protocolVersion < 13) {\n opts.headers['Sec-WebSocket-Origin'] = opts.origin;\n } else {\n opts.headers.Origin = opts.origin;\n }\n }\n if (parsedUrl.username || parsedUrl.password) {\n opts.auth = `${parsedUrl.username}:${parsedUrl.password}`;\n }\n\n if (isIpcUrl) {\n const parts = opts.path.split(':');\n\n opts.socketPath = parts[0];\n opts.path = parts[1];\n }\n\n let req;\n\n if (opts.followRedirects) {\n if (websocket._redirects === 0) {\n websocket._originalIpc = isIpcUrl;\n websocket._originalSecure = isSecure;\n websocket._originalHostOrSocketPath = isIpcUrl\n ? opts.socketPath\n : parsedUrl.host;\n\n const headers = options && options.headers;\n\n //\n // Shallow copy the user provided options so that headers can be changed\n // without mutating the original object.\n //\n options = { ...options, headers: {} };\n\n if (headers) {\n for (const [key, value] of Object.entries(headers)) {\n options.headers[key.toLowerCase()] = value;\n }\n }\n } else if (websocket.listenerCount('redirect') === 0) {\n const isSameHost = isIpcUrl\n ? websocket._originalIpc\n ? opts.socketPath === websocket._originalHostOrSocketPath\n : false\n : websocket._originalIpc\n ? false\n : parsedUrl.host === websocket._originalHostOrSocketPath;\n\n if (!isSameHost || (websocket._originalSecure && !isSecure)) {\n //\n // Match curl 7.77.0 behavior and drop the following headers. These\n // headers are also dropped when following a redirect to a subdomain.\n //\n delete opts.headers.authorization;\n delete opts.headers.cookie;\n\n if (!isSameHost) delete opts.headers.host;\n\n opts.auth = undefined;\n }\n }\n\n //\n // Match curl 7.77.0 behavior and make the first `Authorization` header win.\n // If the `Authorization` header is set, then there is nothing to do as it\n // will take precedence.\n //\n if (opts.auth && !options.headers.authorization) {\n options.headers.authorization =\n 'Basic ' + Buffer.from(opts.auth).toString('base64');\n }\n\n req = websocket._req = request(opts);\n\n if (websocket._redirects) {\n //\n // Unlike what is done for the `'upgrade'` event, no early exit is\n // triggered here if the user calls `websocket.close()` or\n // `websocket.terminate()` from a listener of the `'redirect'` event. This\n // is because the user can also call `request.destroy()` with an error\n // before calling `websocket.close()` or `websocket.terminate()` and this\n // would result in an error being emitted on the `request` object with no\n // `'error'` event listeners attached.\n //\n websocket.emit('redirect', websocket.url, req);\n }\n } else {\n req = websocket._req = request(opts);\n }\n\n if (opts.timeout) {\n req.on('timeout', () => {\n abortHandshake(websocket, req, 'Opening handshake has timed out');\n });\n }\n\n req.on('error', (err) => {\n if (req === null || req[kAborted]) return;\n\n req = websocket._req = null;\n emitErrorAndClose(websocket, err);\n });\n\n req.on('response', (res) => {\n const location = res.headers.location;\n const statusCode = res.statusCode;\n\n if (\n location &&\n opts.followRedirects &&\n statusCode >= 300 &&\n statusCode < 400\n ) {\n if (++websocket._redirects > opts.maxRedirects) {\n abortHandshake(websocket, req, 'Maximum redirects exceeded');\n return;\n }\n\n req.abort();\n\n let addr;\n\n try {\n addr = new URL(location, address);\n } catch (e) {\n const err = new SyntaxError(`Invalid URL: ${location}`);\n emitErrorAndClose(websocket, err);\n return;\n }\n\n initAsClient(websocket, addr, protocols, options);\n } else if (!websocket.emit('unexpected-response', req, res)) {\n abortHandshake(\n websocket,\n req,\n `Unexpected server response: ${res.statusCode}`\n );\n }\n });\n\n req.on('upgrade', (res, socket, head) => {\n websocket.emit('upgrade', res);\n\n //\n // The user may have closed the connection from a listener of the\n // `'upgrade'` event.\n //\n if (websocket.readyState !== WebSocket.CONNECTING) return;\n\n req = websocket._req = null;\n\n const upgrade = res.headers.upgrade;\n\n if (upgrade === undefined || upgrade.toLowerCase() !== 'websocket') {\n abortHandshake(websocket, socket, 'Invalid Upgrade header');\n return;\n }\n\n const digest = createHash('sha1')\n .update(key + GUID)\n .digest('base64');\n\n if (res.headers['sec-websocket-accept'] !== digest) {\n abortHandshake(websocket, socket, 'Invalid Sec-WebSocket-Accept header');\n return;\n }\n\n const serverProt = res.headers['sec-websocket-protocol'];\n let protError;\n\n if (serverProt !== undefined) {\n if (!protocolSet.size) {\n protError = 'Server sent a subprotocol but none was requested';\n } else if (!protocolSet.has(serverProt)) {\n protError = 'Server sent an invalid subprotocol';\n }\n } else if (protocolSet.size) {\n protError = 'Server sent no subprotocol';\n }\n\n if (protError) {\n abortHandshake(websocket, socket, protError);\n return;\n }\n\n if (serverProt) websocket._protocol = serverProt;\n\n const secWebSocketExtensions = res.headers['sec-websocket-extensions'];\n\n if (secWebSocketExtensions !== undefined) {\n if (!perMessageDeflate) {\n const message =\n 'Server sent a Sec-WebSocket-Extensions header but no extension ' +\n 'was requested';\n abortHandshake(websocket, socket, message);\n return;\n }\n\n let extensions;\n\n try {\n extensions = parse(secWebSocketExtensions);\n } catch (err) {\n const message = 'Invalid Sec-WebSocket-Extensions header';\n abortHandshake(websocket, socket, message);\n return;\n }\n\n const extensionNames = Object.keys(extensions);\n\n if (\n extensionNames.length !== 1 ||\n extensionNames[0] !== PerMessageDeflate.extensionName\n ) {\n const message = 'Server indicated an extension that was not requested';\n abortHandshake(websocket, socket, message);\n return;\n }\n\n try {\n perMessageDeflate.accept(extensions[PerMessageDeflate.extensionName]);\n } catch (err) {\n const message = 'Invalid Sec-WebSocket-Extensions header';\n abortHandshake(websocket, socket, message);\n return;\n }\n\n websocket._extensions[PerMessageDeflate.extensionName] =\n perMessageDeflate;\n }\n\n websocket.setSocket(socket, head, {\n allowSynchronousEvents: opts.allowSynchronousEvents,\n generateMask: opts.generateMask,\n maxPayload: opts.maxPayload,\n skipUTF8Validation: opts.skipUTF8Validation\n });\n });\n\n if (opts.finishRequest) {\n opts.finishRequest(req, websocket);\n } else {\n req.end();\n }\n}\n\n/**\n * Emit the `'error'` and `'close'` events.\n *\n * @param {WebSocket} websocket The WebSocket instance\n * @param {Error} The error to emit\n * @private\n */\nfunction emitErrorAndClose(websocket, err) {\n websocket._readyState = WebSocket.CLOSING;\n //\n // The following assignment is practically useless and is done only for\n // consistency.\n //\n websocket._errorEmitted = true;\n websocket.emit('error', err);\n websocket.emitClose();\n}\n\n/**\n * Create a `net.Socket` and initiate a connection.\n *\n * @param {Object} options Connection options\n * @return {net.Socket} The newly created socket used to start the connection\n * @private\n */\nfunction netConnect(options) {\n options.path = options.socketPath;\n return net.connect(options);\n}\n\n/**\n * Create a `tls.TLSSocket` and initiate a connection.\n *\n * @param {Object} options Connection options\n * @return {tls.TLSSocket} The newly created socket used to start the connection\n * @private\n */\nfunction tlsConnect(options) {\n options.path = undefined;\n\n if (!options.servername && options.servername !== '') {\n options.servername = net.isIP(options.host) ? '' : options.host;\n }\n\n return tls.connect(options);\n}\n\n/**\n * Abort the handshake and emit an error.\n *\n * @param {WebSocket} websocket The WebSocket instance\n * @param {(http.ClientRequest|net.Socket|tls.Socket)} stream The request to\n * abort or the socket to destroy\n * @param {String} message The error message\n * @private\n */\nfunction abortHandshake(websocket, stream, message) {\n websocket._readyState = WebSocket.CLOSING;\n\n const err = new Error(message);\n Error.captureStackTrace(err, abortHandshake);\n\n if (stream.setHeader) {\n stream[kAborted] = true;\n stream.abort();\n\n if (stream.socket && !stream.socket.destroyed) {\n //\n // On Node.js >= 14.3.0 `request.abort()` does not destroy the socket if\n // called after the request completed. See\n // https://github.com/websockets/ws/issues/1869.\n //\n stream.socket.destroy();\n }\n\n process.nextTick(emitErrorAndClose, websocket, err);\n } else {\n stream.destroy(err);\n stream.once('error', websocket.emit.bind(websocket, 'error'));\n stream.once('close', websocket.emitClose.bind(websocket));\n }\n}\n\n/**\n * Handle cases where the `ping()`, `pong()`, or `send()` methods are called\n * when the `readyState` attribute is `CLOSING` or `CLOSED`.\n *\n * @param {WebSocket} websocket The WebSocket instance\n * @param {*} [data] The data to send\n * @param {Function} [cb] Callback\n * @private\n */\nfunction sendAfterClose(websocket, data, cb) {\n if (data) {\n const length = isBlob(data) ? data.size : toBuffer(data).length;\n\n //\n // The `_bufferedAmount` property is used only when the peer is a client and\n // the opening handshake fails. Under these circumstances, in fact, the\n // `setSocket()` method is not called, so the `_socket` and `_sender`\n // properties are set to `null`.\n //\n if (websocket._socket) websocket._sender._bufferedBytes += length;\n else websocket._bufferedAmount += length;\n }\n\n if (cb) {\n const err = new Error(\n `WebSocket is not open: readyState ${websocket.readyState} ` +\n `(${readyStates[websocket.readyState]})`\n );\n process.nextTick(cb, err);\n }\n}\n\n/**\n * The listener of the `Receiver` `'conclude'` event.\n *\n * @param {Number} code The status code\n * @param {Buffer} reason The reason for closing\n * @private\n */\nfunction receiverOnConclude(code, reason) {\n const websocket = this[kWebSocket];\n\n websocket._closeFrameReceived = true;\n websocket._closeMessage = reason;\n websocket._closeCode = code;\n\n if (websocket._socket[kWebSocket] === undefined) return;\n\n websocket._socket.removeListener('data', socketOnData);\n process.nextTick(resume, websocket._socket);\n\n if (code === 1005) websocket.close();\n else websocket.close(code, reason);\n}\n\n/**\n * The listener of the `Receiver` `'drain'` event.\n *\n * @private\n */\nfunction receiverOnDrain() {\n const websocket = this[kWebSocket];\n\n if (!websocket.isPaused) websocket._socket.resume();\n}\n\n/**\n * The listener of the `Receiver` `'error'` event.\n *\n * @param {(RangeError|Error)} err The emitted error\n * @private\n */\nfunction receiverOnError(err) {\n const websocket = this[kWebSocket];\n\n if (websocket._socket[kWebSocket] !== undefined) {\n websocket._socket.removeListener('data', socketOnData);\n\n //\n // On Node.js < 14.0.0 the `'error'` event is emitted synchronously. See\n // https://github.com/websockets/ws/issues/1940.\n //\n process.nextTick(resume, websocket._socket);\n\n websocket.close(err[kStatusCode]);\n }\n\n if (!websocket._errorEmitted) {\n websocket._errorEmitted = true;\n websocket.emit('error', err);\n }\n}\n\n/**\n * The listener of the `Receiver` `'finish'` event.\n *\n * @private\n */\nfunction receiverOnFinish() {\n this[kWebSocket].emitClose();\n}\n\n/**\n * The listener of the `Receiver` `'message'` event.\n *\n * @param {Buffer|ArrayBuffer|Buffer[])} data The message\n * @param {Boolean} isBinary Specifies whether the message is binary or not\n * @private\n */\nfunction receiverOnMessage(data, isBinary) {\n this[kWebSocket].emit('message', data, isBinary);\n}\n\n/**\n * The listener of the `Receiver` `'ping'` event.\n *\n * @param {Buffer} data The data included in the ping frame\n * @private\n */\nfunction receiverOnPing(data) {\n const websocket = this[kWebSocket];\n\n if (websocket._autoPong) websocket.pong(data, !this._isServer, NOOP);\n websocket.emit('ping', data);\n}\n\n/**\n * The listener of the `Receiver` `'pong'` event.\n *\n * @param {Buffer} data The data included in the pong frame\n * @private\n */\nfunction receiverOnPong(data) {\n this[kWebSocket].emit('pong', data);\n}\n\n/**\n * Resume a readable stream\n *\n * @param {Readable} stream The readable stream\n * @private\n */\nfunction resume(stream) {\n stream.resume();\n}\n\n/**\n * The `Sender` error event handler.\n *\n * @param {Error} The error\n * @private\n */\nfunction senderOnError(err) {\n const websocket = this[kWebSocket];\n\n if (websocket.readyState === WebSocket.CLOSED) return;\n if (websocket.readyState === WebSocket.OPEN) {\n websocket._readyState = WebSocket.CLOSING;\n setCloseTimer(websocket);\n }\n\n //\n // `socket.end()` is used instead of `socket.destroy()` to allow the other\n // peer to finish sending queued data. There is no need to set a timer here\n // because `CLOSING` means that it is already set or not needed.\n //\n this._socket.end();\n\n if (!websocket._errorEmitted) {\n websocket._errorEmitted = true;\n websocket.emit('error', err);\n }\n}\n\n/**\n * Set a timer to destroy the underlying raw socket of a WebSocket.\n *\n * @param {WebSocket} websocket The WebSocket instance\n * @private\n */\nfunction setCloseTimer(websocket) {\n websocket._closeTimer = setTimeout(\n websocket._socket.destroy.bind(websocket._socket),\n closeTimeout\n );\n}\n\n/**\n * The listener of the socket `'close'` event.\n *\n * @private\n */\nfunction socketOnClose() {\n const websocket = this[kWebSocket];\n\n this.removeListener('close', socketOnClose);\n this.removeListener('data', socketOnData);\n this.removeListener('end', socketOnEnd);\n\n websocket._readyState = WebSocket.CLOSING;\n\n let chunk;\n\n //\n // The close frame might not have been received or the `'end'` event emitted,\n // for example, if the socket was destroyed due to an error. Ensure that the\n // `receiver` stream is closed after writing any remaining buffered data to\n // it. If the readable side of the socket is in flowing mode then there is no\n // buffered data as everything has been already written and `readable.read()`\n // will return `null`. If instead, the socket is paused, any possible buffered\n // data will be read as a single chunk.\n //\n if (\n !this._readableState.endEmitted &&\n !websocket._closeFrameReceived &&\n !websocket._receiver._writableState.errorEmitted &&\n (chunk = websocket._socket.read()) !== null\n ) {\n websocket._receiver.write(chunk);\n }\n\n websocket._receiver.end();\n\n this[kWebSocket] = undefined;\n\n clearTimeout(websocket._closeTimer);\n\n if (\n websocket._receiver._writableState.finished ||\n websocket._receiver._writableState.errorEmitted\n ) {\n websocket.emitClose();\n } else {\n websocket._receiver.on('error', receiverOnFinish);\n websocket._receiver.on('finish', receiverOnFinish);\n }\n}\n\n/**\n * The listener of the socket `'data'` event.\n *\n * @param {Buffer} chunk A chunk of data\n * @private\n */\nfunction socketOnData(chunk) {\n if (!this[kWebSocket]._receiver.write(chunk)) {\n this.pause();\n }\n}\n\n/**\n * The listener of the socket `'end'` event.\n *\n * @private\n */\nfunction socketOnEnd() {\n const websocket = this[kWebSocket];\n\n websocket._readyState = WebSocket.CLOSING;\n websocket._receiver.end();\n this.end();\n}\n\n/**\n * The listener of the socket `'error'` event.\n *\n * @private\n */\nfunction socketOnError() {\n const websocket = this[kWebSocket];\n\n this.removeListener('error', socketOnError);\n this.on('error', NOOP);\n\n if (websocket) {\n websocket._readyState = WebSocket.CLOSING;\n this.destroy();\n }\n}\n", "/* eslint no-unused-vars: [\"error\", { \"varsIgnorePattern\": \"^WebSocket$\" }] */\n'use strict';\n\nconst WebSocket = require('./websocket');\nconst { Duplex } = require('stream');\n\n/**\n * Emits the `'close'` event on a stream.\n *\n * @param {Duplex} stream The stream.\n * @private\n */\nfunction emitClose(stream) {\n stream.emit('close');\n}\n\n/**\n * The listener of the `'end'` event.\n *\n * @private\n */\nfunction duplexOnEnd() {\n if (!this.destroyed && this._writableState.finished) {\n this.destroy();\n }\n}\n\n/**\n * The listener of the `'error'` event.\n *\n * @param {Error} err The error\n * @private\n */\nfunction duplexOnError(err) {\n this.removeListener('error', duplexOnError);\n this.destroy();\n if (this.listenerCount('error') === 0) {\n // Do not suppress the throwing behavior.\n this.emit('error', err);\n }\n}\n\n/**\n * Wraps a `WebSocket` in a duplex stream.\n *\n * @param {WebSocket} ws The `WebSocket` to wrap\n * @param {Object} [options] The options for the `Duplex` constructor\n * @return {Duplex} The duplex stream\n * @public\n */\nfunction createWebSocketStream(ws, options) {\n let terminateOnDestroy = true;\n\n const duplex = new Duplex({\n ...options,\n autoDestroy: false,\n emitClose: false,\n objectMode: false,\n writableObjectMode: false\n });\n\n ws.on('message', function message(msg, isBinary) {\n const data =\n !isBinary && duplex._readableState.objectMode ? msg.toString() : msg;\n\n if (!duplex.push(data)) ws.pause();\n });\n\n ws.once('error', function error(err) {\n if (duplex.destroyed) return;\n\n // Prevent `ws.terminate()` from being called by `duplex._destroy()`.\n //\n // - If the `'error'` event is emitted before the `'open'` event, then\n // `ws.terminate()` is a noop as no socket is assigned.\n // - Otherwise, the error is re-emitted by the listener of the `'error'`\n // event of the `Receiver` object. The listener already closes the\n // connection by calling `ws.close()`. This allows a close frame to be\n // sent to the other peer. If `ws.terminate()` is called right after this,\n // then the close frame might not be sent.\n terminateOnDestroy = false;\n duplex.destroy(err);\n });\n\n ws.once('close', function close() {\n if (duplex.destroyed) return;\n\n duplex.push(null);\n });\n\n duplex._destroy = function (err, callback) {\n if (ws.readyState === ws.CLOSED) {\n callback(err);\n process.nextTick(emitClose, duplex);\n return;\n }\n\n let called = false;\n\n ws.once('error', function error(err) {\n called = true;\n callback(err);\n });\n\n ws.once('close', function close() {\n if (!called) callback(err);\n process.nextTick(emitClose, duplex);\n });\n\n if (terminateOnDestroy) ws.terminate();\n };\n\n duplex._final = function (callback) {\n if (ws.readyState === ws.CONNECTING) {\n ws.once('open', function open() {\n duplex._final(callback);\n });\n return;\n }\n\n // If the value of the `_socket` property is `null` it means that `ws` is a\n // client websocket and the handshake failed. In fact, when this happens, a\n // socket is never assigned to the websocket. Wait for the `'error'` event\n // that will be emitted by the websocket.\n if (ws._socket === null) return;\n\n if (ws._socket._writableState.finished) {\n callback();\n if (duplex._readableState.endEmitted) duplex.destroy();\n } else {\n ws._socket.once('finish', function finish() {\n // `duplex` is not destroyed here because the `'end'` event will be\n // emitted on `duplex` after this `'finish'` event. The EOF signaling\n // `null` chunk is, in fact, pushed when the websocket emits `'close'`.\n callback();\n });\n ws.close();\n }\n };\n\n duplex._read = function () {\n if (ws.isPaused) ws.resume();\n };\n\n duplex._write = function (chunk, encoding, callback) {\n if (ws.readyState === ws.CONNECTING) {\n ws.once('open', function open() {\n duplex._write(chunk, encoding, callback);\n });\n return;\n }\n\n ws.send(chunk, callback);\n };\n\n duplex.on('end', duplexOnEnd);\n duplex.on('error', duplexOnError);\n return duplex;\n}\n\nmodule.exports = createWebSocketStream;\n", "'use strict';\n\nconst { tokenChars } = require('./validation');\n\n/**\n * Parses the `Sec-WebSocket-Protocol` header into a set of subprotocol names.\n *\n * @param {String} header The field value of the header\n * @return {Set} The subprotocol names\n * @public\n */\nfunction parse(header) {\n const protocols = new Set();\n let start = -1;\n let end = -1;\n let i = 0;\n\n for (i; i < header.length; i++) {\n const code = header.charCodeAt(i);\n\n if (end === -1 && tokenChars[code] === 1) {\n if (start === -1) start = i;\n } else if (\n i !== 0 &&\n (code === 0x20 /* ' ' */ || code === 0x09) /* '\\t' */\n ) {\n if (end === -1 && start !== -1) end = i;\n } else if (code === 0x2c /* ',' */) {\n if (start === -1) {\n throw new SyntaxError(`Unexpected character at index ${i}`);\n }\n\n if (end === -1) end = i;\n\n const protocol = header.slice(start, end);\n\n if (protocols.has(protocol)) {\n throw new SyntaxError(`The \"${protocol}\" subprotocol is duplicated`);\n }\n\n protocols.add(protocol);\n start = end = -1;\n } else {\n throw new SyntaxError(`Unexpected character at index ${i}`);\n }\n }\n\n if (start === -1 || end !== -1) {\n throw new SyntaxError('Unexpected end of input');\n }\n\n const protocol = header.slice(start, i);\n\n if (protocols.has(protocol)) {\n throw new SyntaxError(`The \"${protocol}\" subprotocol is duplicated`);\n }\n\n protocols.add(protocol);\n return protocols;\n}\n\nmodule.exports = { parse };\n", "/* eslint no-unused-vars: [\"error\", { \"varsIgnorePattern\": \"^Duplex$\", \"caughtErrors\": \"none\" }] */\n\n'use strict';\n\nconst EventEmitter = require('events');\nconst http = require('http');\nconst { Duplex } = require('stream');\nconst { createHash } = require('crypto');\n\nconst extension = require('./extension');\nconst PerMessageDeflate = require('./permessage-deflate');\nconst subprotocol = require('./subprotocol');\nconst WebSocket = require('./websocket');\nconst { GUID, kWebSocket } = require('./constants');\n\nconst keyRegex = /^[+/0-9A-Za-z]{22}==$/;\n\nconst RUNNING = 0;\nconst CLOSING = 1;\nconst CLOSED = 2;\n\n/**\n * Class representing a WebSocket server.\n *\n * @extends EventEmitter\n */\nclass WebSocketServer extends EventEmitter {\n /**\n * Create a `WebSocketServer` instance.\n *\n * @param {Object} options Configuration options\n * @param {Boolean} [options.allowSynchronousEvents=true] Specifies whether\n * any of the `'message'`, `'ping'`, and `'pong'` events can be emitted\n * multiple times in the same tick\n * @param {Boolean} [options.autoPong=true] Specifies whether or not to\n * automatically send a pong in response to a ping\n * @param {Number} [options.backlog=511] The maximum length of the queue of\n * pending connections\n * @param {Boolean} [options.clientTracking=true] Specifies whether or not to\n * track clients\n * @param {Function} [options.handleProtocols] A hook to handle protocols\n * @param {String} [options.host] The hostname where to bind the server\n * @param {Number} [options.maxPayload=104857600] The maximum allowed message\n * size\n * @param {Boolean} [options.noServer=false] Enable no server mode\n * @param {String} [options.path] Accept only connections matching this path\n * @param {(Boolean|Object)} [options.perMessageDeflate=false] Enable/disable\n * permessage-deflate\n * @param {Number} [options.port] The port where to bind the server\n * @param {(http.Server|https.Server)} [options.server] A pre-created HTTP/S\n * server to use\n * @param {Boolean} [options.skipUTF8Validation=false] Specifies whether or\n * not to skip UTF-8 validation for text and close messages\n * @param {Function} [options.verifyClient] A hook to reject connections\n * @param {Function} [options.WebSocket=WebSocket] Specifies the `WebSocket`\n * class to use. It must be the `WebSocket` class or class that extends it\n * @param {Function} [callback] A listener for the `listening` event\n */\n constructor(options, callback) {\n super();\n\n options = {\n allowSynchronousEvents: true,\n autoPong: true,\n maxPayload: 100 * 1024 * 1024,\n skipUTF8Validation: false,\n perMessageDeflate: false,\n handleProtocols: null,\n clientTracking: true,\n verifyClient: null,\n noServer: false,\n backlog: null, // use default (511 as implemented in net.js)\n server: null,\n host: null,\n path: null,\n port: null,\n WebSocket,\n ...options\n };\n\n if (\n (options.port == null && !options.server && !options.noServer) ||\n (options.port != null && (options.server || options.noServer)) ||\n (options.server && options.noServer)\n ) {\n throw new TypeError(\n 'One and only one of the \"port\", \"server\", or \"noServer\" options ' +\n 'must be specified'\n );\n }\n\n if (options.port != null) {\n this._server = http.createServer((req, res) => {\n const body = http.STATUS_CODES[426];\n\n res.writeHead(426, {\n 'Content-Length': body.length,\n 'Content-Type': 'text/plain'\n });\n res.end(body);\n });\n this._server.listen(\n options.port,\n options.host,\n options.backlog,\n callback\n );\n } else if (options.server) {\n this._server = options.server;\n }\n\n if (this._server) {\n const emitConnection = this.emit.bind(this, 'connection');\n\n this._removeListeners = addListeners(this._server, {\n listening: this.emit.bind(this, 'listening'),\n error: this.emit.bind(this, 'error'),\n upgrade: (req, socket, head) => {\n this.handleUpgrade(req, socket, head, emitConnection);\n }\n });\n }\n\n if (options.perMessageDeflate === true) options.perMessageDeflate = {};\n if (options.clientTracking) {\n this.clients = new Set();\n this._shouldEmitClose = false;\n }\n\n this.options = options;\n this._state = RUNNING;\n }\n\n /**\n * Returns the bound address, the address family name, and port of the server\n * as reported by the operating system if listening on an IP socket.\n * If the server is listening on a pipe or UNIX domain socket, the name is\n * returned as a string.\n *\n * @return {(Object|String|null)} The address of the server\n * @public\n */\n address() {\n if (this.options.noServer) {\n throw new Error('The server is operating in \"noServer\" mode');\n }\n\n if (!this._server) return null;\n return this._server.address();\n }\n\n /**\n * Stop the server from accepting new connections and emit the `'close'` event\n * when all existing connections are closed.\n *\n * @param {Function} [cb] A one-time listener for the `'close'` event\n * @public\n */\n close(cb) {\n if (this._state === CLOSED) {\n if (cb) {\n this.once('close', () => {\n cb(new Error('The server is not running'));\n });\n }\n\n process.nextTick(emitClose, this);\n return;\n }\n\n if (cb) this.once('close', cb);\n\n if (this._state === CLOSING) return;\n this._state = CLOSING;\n\n if (this.options.noServer || this.options.server) {\n if (this._server) {\n this._removeListeners();\n this._removeListeners = this._server = null;\n }\n\n if (this.clients) {\n if (!this.clients.size) {\n process.nextTick(emitClose, this);\n } else {\n this._shouldEmitClose = true;\n }\n } else {\n process.nextTick(emitClose, this);\n }\n } else {\n const server = this._server;\n\n this._removeListeners();\n this._removeListeners = this._server = null;\n\n //\n // The HTTP/S server was created internally. Close it, and rely on its\n // `'close'` event.\n //\n server.close(() => {\n emitClose(this);\n });\n }\n }\n\n /**\n * See if a given request should be handled by this server instance.\n *\n * @param {http.IncomingMessage} req Request object to inspect\n * @return {Boolean} `true` if the request is valid, else `false`\n * @public\n */\n shouldHandle(req) {\n if (this.options.path) {\n const index = req.url.indexOf('?');\n const pathname = index !== -1 ? req.url.slice(0, index) : req.url;\n\n if (pathname !== this.options.path) return false;\n }\n\n return true;\n }\n\n /**\n * Handle a HTTP Upgrade request.\n *\n * @param {http.IncomingMessage} req The request object\n * @param {Duplex} socket The network socket between the server and client\n * @param {Buffer} head The first packet of the upgraded stream\n * @param {Function} cb Callback\n * @public\n */\n handleUpgrade(req, socket, head, cb) {\n socket.on('error', socketOnError);\n\n const key = req.headers['sec-websocket-key'];\n const upgrade = req.headers.upgrade;\n const version = +req.headers['sec-websocket-version'];\n\n if (req.method !== 'GET') {\n const message = 'Invalid HTTP method';\n abortHandshakeOrEmitwsClientError(this, req, socket, 405, message);\n return;\n }\n\n if (upgrade === undefined || upgrade.toLowerCase() !== 'websocket') {\n const message = 'Invalid Upgrade header';\n abortHandshakeOrEmitwsClientError(this, req, socket, 400, message);\n return;\n }\n\n if (key === undefined || !keyRegex.test(key)) {\n const message = 'Missing or invalid Sec-WebSocket-Key header';\n abortHandshakeOrEmitwsClientError(this, req, socket, 400, message);\n return;\n }\n\n if (version !== 13 && version !== 8) {\n const message = 'Missing or invalid Sec-WebSocket-Version header';\n abortHandshakeOrEmitwsClientError(this, req, socket, 400, message, {\n 'Sec-WebSocket-Version': '13, 8'\n });\n return;\n }\n\n if (!this.shouldHandle(req)) {\n abortHandshake(socket, 400);\n return;\n }\n\n const secWebSocketProtocol = req.headers['sec-websocket-protocol'];\n let protocols = new Set();\n\n if (secWebSocketProtocol !== undefined) {\n try {\n protocols = subprotocol.parse(secWebSocketProtocol);\n } catch (err) {\n const message = 'Invalid Sec-WebSocket-Protocol header';\n abortHandshakeOrEmitwsClientError(this, req, socket, 400, message);\n return;\n }\n }\n\n const secWebSocketExtensions = req.headers['sec-websocket-extensions'];\n const extensions = {};\n\n if (\n this.options.perMessageDeflate &&\n secWebSocketExtensions !== undefined\n ) {\n const perMessageDeflate = new PerMessageDeflate(\n this.options.perMessageDeflate,\n true,\n this.options.maxPayload\n );\n\n try {\n const offers = extension.parse(secWebSocketExtensions);\n\n if (offers[PerMessageDeflate.extensionName]) {\n perMessageDeflate.accept(offers[PerMessageDeflate.extensionName]);\n extensions[PerMessageDeflate.extensionName] = perMessageDeflate;\n }\n } catch (err) {\n const message =\n 'Invalid or unacceptable Sec-WebSocket-Extensions header';\n abortHandshakeOrEmitwsClientError(this, req, socket, 400, message);\n return;\n }\n }\n\n //\n // Optionally call external client verification handler.\n //\n if (this.options.verifyClient) {\n const info = {\n origin:\n req.headers[`${version === 8 ? 'sec-websocket-origin' : 'origin'}`],\n secure: !!(req.socket.authorized || req.socket.encrypted),\n req\n };\n\n if (this.options.verifyClient.length === 2) {\n this.options.verifyClient(info, (verified, code, message, headers) => {\n if (!verified) {\n return abortHandshake(socket, code || 401, message, headers);\n }\n\n this.completeUpgrade(\n extensions,\n key,\n protocols,\n req,\n socket,\n head,\n cb\n );\n });\n return;\n }\n\n if (!this.options.verifyClient(info)) return abortHandshake(socket, 401);\n }\n\n this.completeUpgrade(extensions, key, protocols, req, socket, head, cb);\n }\n\n /**\n * Upgrade the connection to WebSocket.\n *\n * @param {Object} extensions The accepted extensions\n * @param {String} key The value of the `Sec-WebSocket-Key` header\n * @param {Set} protocols The subprotocols\n * @param {http.IncomingMessage} req The request object\n * @param {Duplex} socket The network socket between the server and client\n * @param {Buffer} head The first packet of the upgraded stream\n * @param {Function} cb Callback\n * @throws {Error} If called more than once with the same socket\n * @private\n */\n completeUpgrade(extensions, key, protocols, req, socket, head, cb) {\n //\n // Destroy the socket if the client has already sent a FIN packet.\n //\n if (!socket.readable || !socket.writable) return socket.destroy();\n\n if (socket[kWebSocket]) {\n throw new Error(\n 'server.handleUpgrade() was called more than once with the same ' +\n 'socket, possibly due to a misconfiguration'\n );\n }\n\n if (this._state > RUNNING) return abortHandshake(socket, 503);\n\n const digest = createHash('sha1')\n .update(key + GUID)\n .digest('base64');\n\n const headers = [\n 'HTTP/1.1 101 Switching Protocols',\n 'Upgrade: websocket',\n 'Connection: Upgrade',\n `Sec-WebSocket-Accept: ${digest}`\n ];\n\n const ws = new this.options.WebSocket(null, undefined, this.options);\n\n if (protocols.size) {\n //\n // Optionally call external protocol selection handler.\n //\n const protocol = this.options.handleProtocols\n ? this.options.handleProtocols(protocols, req)\n : protocols.values().next().value;\n\n if (protocol) {\n headers.push(`Sec-WebSocket-Protocol: ${protocol}`);\n ws._protocol = protocol;\n }\n }\n\n if (extensions[PerMessageDeflate.extensionName]) {\n const params = extensions[PerMessageDeflate.extensionName].params;\n const value = extension.format({\n [PerMessageDeflate.extensionName]: [params]\n });\n headers.push(`Sec-WebSocket-Extensions: ${value}`);\n ws._extensions = extensions;\n }\n\n //\n // Allow external modification/inspection of handshake headers.\n //\n this.emit('headers', headers, req);\n\n socket.write(headers.concat('\\r\\n').join('\\r\\n'));\n socket.removeListener('error', socketOnError);\n\n ws.setSocket(socket, head, {\n allowSynchronousEvents: this.options.allowSynchronousEvents,\n maxPayload: this.options.maxPayload,\n skipUTF8Validation: this.options.skipUTF8Validation\n });\n\n if (this.clients) {\n this.clients.add(ws);\n ws.on('close', () => {\n this.clients.delete(ws);\n\n if (this._shouldEmitClose && !this.clients.size) {\n process.nextTick(emitClose, this);\n }\n });\n }\n\n cb(ws, req);\n }\n}\n\nmodule.exports = WebSocketServer;\n\n/**\n * Add event listeners on an `EventEmitter` using a map of <event, listener>\n * pairs.\n *\n * @param {EventEmitter} server The event emitter\n * @param {Object.<String, Function>} map The listeners to add\n * @return {Function} A function that will remove the added listeners when\n * called\n * @private\n */\nfunction addListeners(server, map) {\n for (const event of Object.keys(map)) server.on(event, map[event]);\n\n return function removeListeners() {\n for (const event of Object.keys(map)) {\n server.removeListener(event, map[event]);\n }\n };\n}\n\n/**\n * Emit a `'close'` event on an `EventEmitter`.\n *\n * @param {EventEmitter} server The event emitter\n * @private\n */\nfunction emitClose(server) {\n server._state = CLOSED;\n server.emit('close');\n}\n\n/**\n * Handle socket errors.\n *\n * @private\n */\nfunction socketOnError() {\n this.destroy();\n}\n\n/**\n * Close the connection when preconditions are not fulfilled.\n *\n * @param {Duplex} socket The socket of the upgrade request\n * @param {Number} code The HTTP response status code\n * @param {String} [message] The HTTP response body\n * @param {Object} [headers] Additional HTTP response headers\n * @private\n */\nfunction abortHandshake(socket, code, message, headers) {\n //\n // The socket is writable unless the user destroyed or ended it before calling\n // `server.handleUpgrade()` or in the `verifyClient` function, which is a user\n // error. Handling this does not make much sense as the worst that can happen\n // is that some of the data written by the user might be discarded due to the\n // call to `socket.end()` below, which triggers an `'error'` event that in\n // turn causes the socket to be destroyed.\n //\n message = message || http.STATUS_CODES[code];\n headers = {\n Connection: 'close',\n 'Content-Type': 'text/html',\n 'Content-Length': Buffer.byteLength(message),\n ...headers\n };\n\n socket.once('finish', socket.destroy);\n\n socket.end(\n `HTTP/1.1 ${code} ${http.STATUS_CODES[code]}\\r\\n` +\n Object.keys(headers)\n .map((h) => `${h}: ${headers[h]}`)\n .join('\\r\\n') +\n '\\r\\n\\r\\n' +\n message\n );\n}\n\n/**\n * Emit a `'wsClientError'` event on a `WebSocketServer` if there is at least\n * one listener for it, otherwise call `abortHandshake()`.\n *\n * @param {WebSocketServer} server The WebSocket server\n * @param {http.IncomingMessage} req The request object\n * @param {Duplex} socket The socket of the upgrade request\n * @param {Number} code The HTTP response status code\n * @param {String} message The HTTP response body\n * @param {Object} [headers] The HTTP response headers\n * @private\n */\nfunction abortHandshakeOrEmitwsClientError(\n server,\n req,\n socket,\n code,\n message,\n headers\n) {\n if (server.listenerCount('wsClientError')) {\n const err = new Error(message);\n Error.captureStackTrace(err, abortHandshakeOrEmitwsClientError);\n\n server.emit('wsClientError', err, socket, req);\n } else {\n abortHandshake(socket, code, message, headers);\n }\n}\n", "import createWebSocketStream from './lib/stream.js';\nimport Receiver from './lib/receiver.js';\nimport Sender from './lib/sender.js';\nimport WebSocket from './lib/websocket.js';\nimport WebSocketServer from './lib/websocket-server.js';\n\nexport { createWebSocketStream, Receiver, Sender, WebSocket, WebSocketServer };\nexport default WebSocket;\n", "import type { ServeOptions, Server } from \"../base.ts\";\nimport type { NodeHttpServer, WSWebSocket, WSWebSocketServer } from \"./types.ts\";\nimport { DEFAULT_PORT } from \"@veryfront/config\";\n\n// Track pending WebSocket upgrades by request ID\nconst pendingWebSocketUpgrades = new Map<string, {\n resolve: (ws: WSWebSocket) => void;\n reject: (error: Error) => void;\n}>();\n\n// Singleton WebSocket server instance (one per HTTP server)\nlet wsServer: WSWebSocketServer | null = null;\n\nexport class NodeServer implements Server {\n constructor(\n private server: NodeHttpServer,\n private hostname: string,\n private port: number,\n ) {}\n\n stop(): Promise<void> {\n return new Promise((resolve) => {\n // Close WebSocket server first\n if (wsServer) {\n wsServer.close();\n wsServer = null;\n }\n this.server.close(() => resolve());\n });\n }\n\n get addr() {\n return { hostname: this.hostname, port: this.port };\n }\n}\n\n/**\n * Create a request ID for matching WebSocket upgrades\n */\nfunction createRequestId(req: { headers: Record<string, string | string[] | undefined> }): string {\n const key = req.headers[\"sec-websocket-key\"];\n return typeof key === \"string\" ? key : (Array.isArray(key) ? key[0] : \"\") || crypto.randomUUID();\n}\n\n/**\n * Register a pending WebSocket upgrade\n * Called by NodeServerAdapter.upgradeWebSocket\n */\nexport function registerWebSocketUpgrade(requestId: string): Promise<WSWebSocket> {\n return new Promise((resolve, reject) => {\n pendingWebSocketUpgrades.set(requestId, { resolve, reject });\n // Cleanup after timeout (30 seconds)\n setTimeout(() => {\n if (pendingWebSocketUpgrades.has(requestId)) {\n pendingWebSocketUpgrades.delete(requestId);\n reject(new Error(\"WebSocket upgrade timed out\"));\n }\n }, 30000);\n });\n}\n\nexport async function createNodeServer(\n handler: (request: Request) => Promise<Response> | Response,\n options: ServeOptions = {},\n): Promise<Server> {\n const { port = DEFAULT_PORT, hostname = \"localhost\", onListen } = options;\n const { createServer } = await import(\"node:http\");\n\n const server = createServer(async (_req, _res) => {\n try {\n const url = new URL(_req.url || \"/\", `http://${_req.headers.host || hostname}`);\n const body = _req.method === \"GET\" || _req.method === \"HEAD\" ? null : _req;\n\n const headersRecord: Record<string, string> = {};\n for (const [key, value] of Object.entries(_req.headers)) {\n if (typeof value === \"string\") {\n headersRecord[key] = value;\n } else if (Array.isArray(value)) {\n headersRecord[key] = value[0] || \"\";\n }\n }\n\n // Node.js 18+ requires duplex: \"half\" when creating a Request with a streaming body\n const requestInit: RequestInit & { duplex?: string } = {\n method: _req.method,\n headers: headersRecord,\n body: body as BodyInit | null,\n };\n // Only add duplex for requests with a body (POST, PUT, PATCH, etc.)\n if (body !== null) {\n requestInit.duplex = \"half\";\n }\n const request = new Request(url.toString(), requestInit);\n\n const response = await handler(request);\n\n // Check if this is a WebSocket upgrade response (status 101)\n // The actual WebSocket handling is done in the 'upgrade' event\n if (response.status === 101) {\n // Don't end the response - the upgrade handler will take over\n return;\n }\n\n _res.statusCode = response.status;\n _res.statusMessage = response.statusText;\n\n response.headers.forEach((value, key) => {\n _res.setHeader(key, value);\n });\n\n if (response.body) {\n const reader = response.body.getReader();\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n _res.write(value);\n }\n }\n\n _res.end();\n } catch (_error) {\n const { serverLogger } = await import(\"@veryfront/utils\");\n serverLogger.error(\"Request handler error:\", _error);\n _res.statusCode = 500;\n _res.end(\"Internal Server Error\");\n }\n });\n\n // Handle WebSocket upgrades\n server.on(\"upgrade\", async (request, socket, head) => {\n try {\n // Lazy load ws package\n const { WebSocketServer } = await import(\"ws\");\n\n // Create WebSocket server if not exists\n if (!wsServer) {\n wsServer = new WebSocketServer({ noServer: true }) as unknown as WSWebSocketServer;\n }\n\n // Get request ID to match with pending upgrade\n const requestId = createRequestId(request);\n\n // Handle the upgrade\n (wsServer as unknown as {\n handleUpgrade: (\n req: unknown,\n socket: unknown,\n head: unknown,\n callback: (ws: WSWebSocket) => void,\n ) => void;\n })\n .handleUpgrade(request, socket, head, (ws: WSWebSocket) => {\n const pending = pendingWebSocketUpgrades.get(requestId);\n if (pending) {\n pendingWebSocketUpgrades.delete(requestId);\n pending.resolve(ws);\n }\n // Emit connection event\n (wsServer as unknown as { emit: (event: string, ws: WSWebSocket, req: unknown) => void })\n .emit(\"connection\", ws, request);\n });\n } catch (error) {\n const { serverLogger } = await import(\"@veryfront/utils\");\n serverLogger.error(\"WebSocket upgrade error:\", error);\n socket.destroy();\n }\n });\n\n if (options.signal) {\n options.signal.addEventListener(\"abort\", () => {\n if (wsServer) {\n wsServer.close();\n wsServer = null;\n }\n server.close();\n });\n }\n\n return new Promise((resolve) => {\n server.listen(port, hostname, () => {\n onListen?.({ hostname, port });\n resolve(new NodeServer(server as unknown as NodeHttpServer, hostname, port));\n });\n });\n}\n", "import type { ServerAdapter, WebSocketUpgrade } from \"../base.ts\";\nimport type { WSMessageData, WSWebSocket } from \"./types.ts\";\nimport { createError, toError } from \"../../../core/errors/veryfront-error.ts\";\nimport { serverLogger } from \"@veryfront/utils\";\nimport { registerWebSocketUpgrade } from \"./http-server.ts\";\nimport * as crypto from \"node:crypto\";\n\nexport class NodeServerAdapter implements ServerAdapter {\n upgradeWebSocket(request: Request): WebSocketUpgrade {\n const key = request.headers.get(\"sec-websocket-key\");\n const protocol = request.headers.get(\"sec-websocket-protocol\");\n\n if (!key) {\n throw toError(createError({\n type: \"network\",\n message: \"Missing Sec-WebSocket-Key header\",\n }));\n }\n\n // Create a proxy WebSocket that will be connected when the upgrade completes\n const socket = new NodeWebSocket();\n\n // Register the upgrade and connect when complete\n registerWebSocketUpgrade(key).then((ws) => {\n socket._attachRealSocket(ws);\n }).catch((error) => {\n serverLogger.error(\"WebSocket upgrade failed:\", error);\n socket._emitError(error);\n });\n\n // Return 101 response - the http-server upgrade handler will complete the handshake\n const response = new Response(null, {\n status: 101,\n statusText: \"Switching Protocols\",\n headers: {\n \"Upgrade\": \"websocket\",\n \"Connection\": \"Upgrade\",\n \"Sec-WebSocket-Accept\": this.generateAcceptKey(key),\n ...(protocol ? { \"Sec-WebSocket-Protocol\": protocol } : {}),\n },\n });\n\n return { socket: socket as unknown as WebSocket, response };\n }\n\n private generateAcceptKey(key: string): string {\n const GUID = \"258EAFA5-E914-47DA-95CA-C5AB0DC85B11\";\n return crypto.createHash(\"sha1\").update(key + GUID).digest(\"base64\");\n }\n}\n\n/**\n * NodeWebSocket - A WebSocket wrapper that works with Node.js\n * Proxies to the real ws WebSocket once the upgrade completes\n */\nexport class NodeWebSocket {\n private ws: WSWebSocket | null = null;\n public readyState = 0; // CONNECTING\n\n public onopen: ((event: Event) => void) | null = null;\n public onclose: ((event: CloseEvent) => void) | null = null;\n public onerror: ((event: Event) => void) | null = null;\n public onmessage: ((event: MessageEvent) => void) | null = null;\n\n static readonly CONNECTING = 0;\n static readonly OPEN = 1;\n static readonly CLOSING = 2;\n static readonly CLOSED = 3;\n\n // Queue messages sent before the socket is ready\n private pendingMessages: Array<string | ArrayBuffer> = [];\n\n /**\n * Attach the real WebSocket after upgrade completes\n * Called by NodeServerAdapter\n */\n _attachRealSocket(ws: WSWebSocket) {\n this.ws = ws;\n this.readyState = 1; // OPEN\n\n // Set up event handlers\n ws.on(\"open\", () => {\n this.readyState = 1;\n this.onopen?.(new Event(\"open\"));\n });\n\n ws.on(\"message\", (data: WSMessageData) => {\n this.onmessage?.(new MessageEvent(\"message\", { data: data.toString() }));\n });\n\n ws.on(\"close\", () => {\n this.readyState = 3;\n this.onclose?.(new CloseEvent(\"close\"));\n });\n\n ws.on(\"error\", (error: Error) => {\n this.onerror?.(new ErrorEvent(\"error\", { error }));\n });\n\n // Send any pending messages\n for (const msg of this.pendingMessages) {\n ws.send(msg);\n }\n this.pendingMessages = [];\n\n // The socket is already open when we get it from handleUpgrade\n this.onopen?.(new Event(\"open\"));\n }\n\n /**\n * Emit an error when upgrade fails\n * Called by NodeServerAdapter\n */\n _emitError(error: Error) {\n this.readyState = 3; // CLOSED\n this.onerror?.(new ErrorEvent(\"error\", { error }));\n }\n\n send(data: string | ArrayBuffer) {\n if (this.ws && this.readyState === 1) {\n this.ws.send(data);\n } else if (this.readyState === 0) {\n // Queue the message until the socket is ready\n this.pendingMessages.push(data);\n } else {\n throw toError(createError({\n type: \"network\",\n message: \"WebSocket is not open\",\n }));\n }\n }\n\n close(code?: number, reason?: string) {\n if (this.ws) {\n this.ws.close(code, reason);\n }\n this.readyState = 2; // CLOSING\n }\n\n // WebSocket standard interface\n addEventListener(type: string, listener: EventListener) {\n switch (type) {\n case \"open\":\n this.onopen = listener as (event: Event) => void;\n break;\n case \"close\":\n this.onclose = listener as (event: CloseEvent) => void;\n break;\n case \"error\":\n this.onerror = listener as (event: Event) => void;\n break;\n case \"message\":\n this.onmessage = listener as (event: MessageEvent) => void;\n break;\n }\n }\n\n removeEventListener(_type: string, _listener: EventListener) {\n // Simplified - just null out the handler\n switch (_type) {\n case \"open\":\n this.onopen = null;\n break;\n case \"close\":\n this.onclose = null;\n break;\n case \"error\":\n this.onerror = null;\n break;\n case \"message\":\n this.onmessage = null;\n break;\n }\n }\n}\n", "import type {\n RuntimeAdapter,\n RuntimeCapabilities,\n RuntimeFeatures,\n ServeOptions,\n Server,\n} from \"../base.ts\";\nimport { NodeFileSystemAdapter } from \"./filesystem-adapter.ts\";\nimport { NodeEnvironmentAdapter } from \"./environment-adapter.ts\";\nimport { NodeServerAdapter } from \"./websocket-adapter.ts\";\nimport { createNodeServer } from \"./http-server.ts\";\n\nexport class NodeAdapter implements RuntimeAdapter {\n readonly id = \"node\" as const;\n readonly name = \"node\";\n /** @deprecated Use `id` instead */\n readonly platform = \"node\" as const;\n\n fs = new NodeFileSystemAdapter();\n env = new NodeEnvironmentAdapter();\n server = new NodeServerAdapter();\n\n readonly capabilities: RuntimeCapabilities = {\n typescript: false, // Requires compilation\n jsx: false, // Requires compilation\n http2: true,\n websocket: true,\n workers: true,\n fileWatching: true,\n shell: true,\n kvStore: false,\n writableFs: true,\n };\n\n /** @deprecated Use `capabilities` instead */\n readonly features: RuntimeFeatures = {\n websocket: true,\n http2: true,\n workers: true,\n jsx: false,\n typescript: false,\n };\n\n serve(\n handler: (request: Request) => Promise<Response> | Response,\n options: ServeOptions = {},\n ): Promise<Server> {\n return createNodeServer(handler, options);\n }\n}\n\nexport const nodeAdapter = new NodeAdapter();\n", "export { NodeAdapter, nodeAdapter } from \"./adapter.ts\";\nexport { NodeFileSystemAdapter } from \"./filesystem-adapter.ts\";\nexport { NodeEnvironmentAdapter } from \"./environment-adapter.ts\";\nexport { NodeServerAdapter, NodeWebSocket } from \"./websocket-adapter.ts\";\nexport { createNodeServer, NodeServer } from \"./http-server.ts\";\nexport type {\n NodeHttpServer,\n NodeIncomingMessage,\n NodeServerResponse,\n WSMessageData,\n WSWebSocket,\n} from \"./types.ts\";\n", "export {\n createNodeServer,\n NodeAdapter,\n nodeAdapter,\n NodeEnvironmentAdapter,\n NodeFileSystemAdapter,\n NodeServer,\n NodeServerAdapter,\n NodeWebSocket,\n} from \"./node/index.ts\";\n\nexport type {\n NodeHttpServer,\n NodeIncomingMessage,\n NodeServerResponse,\n WSMessageData,\n WSWebSocket,\n} from \"./node/index.ts\";\n", "export enum ErrorCode {\n FILE_NOT_FOUND = \"FILE_NOT_FOUND\",\n BUILD_ERROR = \"BUILD_ERROR\",\n CONFIG_ERROR = \"CONFIG_ERROR\",\n COMPILATION_ERROR = \"COMPILATION_ERROR\",\n NETWORK_ERROR = \"NETWORK_ERROR\",\n PERMISSION_ERROR = \"PERMISSION_ERROR\",\n RENDER_ERROR = \"RENDER_ERROR\",\n INITIALIZATION_ERROR = \"INITIALIZATION_ERROR\",\n AGENT_ERROR = \"AGENT_ERROR\",\n AGENT_NOT_FOUND = \"AGENT_NOT_FOUND\",\n AGENT_TIMEOUT = \"AGENT_TIMEOUT\",\n AGENT_INTENT_ERROR = \"AGENT_INTENT_ERROR\",\n ORCHESTRATION_ERROR = \"ORCHESTRATION_ERROR\",\n NOT_SUPPORTED = \"NOT_SUPPORTED\",\n}\n\nexport class VeryfrontError extends Error {\n public code: ErrorCode;\n public context?: unknown;\n\n constructor(message: string, code: ErrorCode, context?: unknown) {\n super(message);\n this.name = \"VeryfrontError\";\n this.code = code;\n this.context = context;\n }\n}\n", "import { ErrorCode, VeryfrontError } from \"./types.ts\";\n\nexport class AgentError extends VeryfrontError {\n constructor(message: string, context?: unknown) {\n super(message, ErrorCode.AGENT_ERROR, context);\n this.name = \"AgentError\";\n }\n}\n\nexport class AgentNotFoundError extends VeryfrontError {\n constructor(agentId: string, context?: unknown) {\n super(`Agent with ID '${agentId}' not found`, ErrorCode.AGENT_NOT_FOUND, {\n agentId,\n ...(context as Record<string, unknown> | undefined),\n });\n this.name = \"AgentNotFoundError\";\n }\n}\n\nexport class AgentTimeoutError extends VeryfrontError {\n constructor(message: string, context?: unknown) {\n super(message, ErrorCode.AGENT_TIMEOUT, context);\n this.name = \"AgentTimeoutError\";\n }\n}\n\nexport class AgentIntentError extends VeryfrontError {\n constructor(message: string, context?: unknown) {\n super(message, ErrorCode.AGENT_INTENT_ERROR, context);\n this.name = \"AgentIntentError\";\n }\n}\n\nexport class OrchestrationError extends VeryfrontError {\n constructor(message: string, context?: unknown) {\n super(message, ErrorCode.ORCHESTRATION_ERROR, context);\n this.name = \"OrchestrationError\";\n }\n}\n", "import { ErrorCode, VeryfrontError } from \"./types.ts\";\n\nexport class BuildError extends VeryfrontError {\n constructor(message: string, context?: unknown) {\n super(message, ErrorCode.BUILD_ERROR, context);\n this.name = \"BuildError\";\n }\n}\n\nexport class CompilationError extends VeryfrontError {\n constructor(message: string, context?: unknown) {\n super(message, ErrorCode.COMPILATION_ERROR, context);\n this.name = \"CompilationError\";\n }\n}\n", "import { ErrorCode, VeryfrontError } from \"./types.ts\";\n\nexport class RuntimeError extends VeryfrontError {\n constructor(message: string, context?: unknown) {\n super(message, ErrorCode.RENDER_ERROR, context);\n this.name = \"RuntimeError\";\n }\n}\n\nexport class RenderError extends VeryfrontError {\n constructor(message: string, context?: unknown) {\n super(message, ErrorCode.RENDER_ERROR, context);\n this.name = \"RenderError\";\n }\n}\n", "import { ErrorCode, VeryfrontError } from \"./types.ts\";\n\nexport class FileSystemError extends VeryfrontError {\n constructor(message: string, context?: unknown) {\n super(message, ErrorCode.FILE_NOT_FOUND, context);\n this.name = \"FileSystemError\";\n }\n}\n\nexport class ConfigError extends VeryfrontError {\n constructor(message: string, context?: unknown) {\n super(message, ErrorCode.CONFIG_ERROR, context);\n this.name = \"ConfigError\";\n }\n}\n\nexport class NetworkError extends VeryfrontError {\n constructor(message: string, context?: unknown) {\n super(message, ErrorCode.NETWORK_ERROR, context);\n this.name = \"NetworkError\";\n }\n}\n\nexport class PermissionError extends VeryfrontError {\n constructor(message: string, context?: unknown) {\n super(message, ErrorCode.PERMISSION_ERROR, context);\n this.name = \"PermissionError\";\n }\n}\n\nexport class NotSupportedError extends VeryfrontError {\n constructor(message: string, context?: unknown) {\n super(message, ErrorCode.NOT_SUPPORTED, context);\n this.name = \"NotSupportedError\";\n }\n}\n", "import { serverLogger } from \"@veryfront/utils/logger/logger.ts\";\nimport { ErrorCode, VeryfrontError } from \"./types.ts\";\n\n/** Default max retries for retry operations */\nconst DEFAULT_MAX_RETRIES = 3;\n\n/** Default initial delay for exponential backoff (100ms) */\nconst DEFAULT_INITIAL_DELAY_MS = 100;\n\n/** Default max delay cap for exponential backoff (5 seconds) */\nconst DEFAULT_MAX_DELAY_MS = 5000;\n\nfunction safeLog(logFn: () => void): void {\n try {\n logFn();\n } catch (error) {\n try {\n serverLogger.warn(\"[errors] Logging failed:\", error);\n } catch {\n // Silently ignore if even warning fails\n }\n }\n}\n\nexport function handleError(error: Error): void {\n safeLog(() => serverLogger.error(`Error: ${error.message}`));\n\n if (error instanceof VeryfrontError && error.context) {\n safeLog(() => serverLogger.error(\"Context:\", error.context));\n }\n\n if (error.stack) {\n safeLog(() => serverLogger.error(error.stack as string));\n }\n}\n\nexport function wrapError(\n error: unknown,\n message: string,\n context?: unknown,\n): VeryfrontError {\n const originalError = error instanceof Error ? error : new Error(String(error));\n const errorMessage = `${message}: ${originalError.message}`;\n\n const wrappedContext = {\n originalError: {\n name: originalError.name,\n message: originalError.message,\n stack: originalError.stack,\n },\n ...(context as Record<string, unknown> | undefined),\n };\n\n const errorCode = error instanceof VeryfrontError ? error.code : ErrorCode.RENDER_ERROR;\n\n return new VeryfrontError(errorMessage, errorCode, wrappedContext);\n}\n\nexport function logAndThrow(\n error: unknown,\n message?: string,\n logger: typeof serverLogger = serverLogger,\n): never {\n const errorObj = error instanceof Error ? error : new Error(String(error));\n const logMessage = message ? `${message}: ${errorObj.message}` : errorObj.message;\n\n safeLog(() => logger.error(logMessage, error));\n\n if (error instanceof Error) {\n throw error;\n }\n throw errorObj;\n}\n\nexport async function handleErrorWithFallback<T>(\n fn: () => T | Promise<T>,\n fallback: T,\n logger: typeof serverLogger = serverLogger,\n): Promise<T> {\n try {\n return await fn();\n } catch (error) {\n safeLog(() => logger.warn(\"Operation failed, using fallback\", error));\n return fallback;\n }\n}\n\nexport function handleErrorWithFallbackSync<T>(\n fn: () => T,\n fallback: T,\n logger: typeof serverLogger = serverLogger,\n): T {\n try {\n return fn();\n } catch (error) {\n safeLog(() => logger.warn(\"Operation failed, using fallback\", error));\n return fallback;\n }\n}\n\nexport async function retryWithBackoff<T>(\n fn: () => Promise<T>,\n options: {\n maxRetries?: number;\n initialDelay?: number;\n maxDelay?: number;\n logger?: typeof serverLogger;\n } = {},\n): Promise<T> {\n const {\n maxRetries = DEFAULT_MAX_RETRIES,\n initialDelay = DEFAULT_INITIAL_DELAY_MS,\n maxDelay = DEFAULT_MAX_DELAY_MS,\n logger: log = serverLogger,\n } = options;\n\n let lastError: unknown;\n let delay = initialDelay;\n\n for (let attempt = 0; attempt < maxRetries; attempt++) {\n try {\n return await fn();\n } catch (error) {\n lastError = error;\n safeLog(() => log.warn(`Attempt ${attempt + 1} failed, retrying...`, error));\n\n if (attempt < maxRetries - 1) {\n await new Promise((resolve) => setTimeout(resolve, delay));\n delay = Math.min(delay * 2, maxDelay);\n }\n }\n }\n\n throw lastError;\n}\n", "export const ErrorCode = {\n CONFIG_NOT_FOUND: \"VF001\",\n CONFIG_INVALID: \"VF002\",\n CONFIG_PARSE_ERROR: \"VF003\",\n CONFIG_VALIDATION_ERROR: \"VF004\",\n CONFIG_TYPE_ERROR: \"VF005\",\n IMPORT_MAP_INVALID: \"VF006\",\n CORS_CONFIG_INVALID: \"VF007\",\n\n BUILD_FAILED: \"VF100\",\n BUNDLE_ERROR: \"VF101\",\n TYPESCRIPT_ERROR: \"VF102\",\n MDX_COMPILE_ERROR: \"VF103\",\n ASSET_OPTIMIZATION_ERROR: \"VF104\",\n SSG_GENERATION_ERROR: \"VF105\",\n SOURCEMAP_ERROR: \"VF106\",\n\n HYDRATION_MISMATCH: \"VF200\",\n RENDER_ERROR: \"VF201\",\n COMPONENT_ERROR: \"VF202\",\n LAYOUT_NOT_FOUND: \"VF203\",\n PAGE_NOT_FOUND: \"VF204\",\n API_ERROR: \"VF205\",\n MIDDLEWARE_ERROR: \"VF206\",\n\n ROUTE_CONFLICT: \"VF300\",\n INVALID_ROUTE_FILE: \"VF301\",\n ROUTE_HANDLER_INVALID: \"VF302\",\n DYNAMIC_ROUTE_ERROR: \"VF303\",\n ROUTE_PARAMS_ERROR: \"VF304\",\n API_ROUTE_ERROR: \"VF305\",\n\n MODULE_NOT_FOUND: \"VF400\",\n IMPORT_RESOLUTION_ERROR: \"VF401\",\n CIRCULAR_DEPENDENCY: \"VF402\",\n INVALID_IMPORT: \"VF403\",\n DEPENDENCY_MISSING: \"VF404\",\n VERSION_MISMATCH: \"VF405\",\n\n PORT_IN_USE: \"VF500\",\n SERVER_START_ERROR: \"VF501\",\n HMR_ERROR: \"VF502\",\n CACHE_ERROR: \"VF503\",\n FILE_WATCH_ERROR: \"VF504\",\n REQUEST_ERROR: \"VF505\",\n\n CLIENT_BOUNDARY_VIOLATION: \"VF600\",\n SERVER_ONLY_IN_CLIENT: \"VF601\",\n CLIENT_ONLY_IN_SERVER: \"VF602\",\n INVALID_USE_CLIENT: \"VF603\",\n INVALID_USE_SERVER: \"VF604\",\n RSC_PAYLOAD_ERROR: \"VF605\",\n\n DEV_SERVER_ERROR: \"VF700\",\n FAST_REFRESH_ERROR: \"VF701\",\n ERROR_OVERLAY_ERROR: \"VF702\",\n SOURCE_MAP_ERROR: \"VF703\",\n\n DEPLOYMENT_ERROR: \"VF800\",\n PLATFORM_ERROR: \"VF801\",\n ENV_VAR_MISSING: \"VF802\",\n PRODUCTION_BUILD_REQUIRED: \"VF803\",\n\n UNKNOWN_ERROR: \"VF900\",\n PERMISSION_DENIED: \"VF901\",\n FILE_NOT_FOUND: \"VF902\",\n INVALID_ARGUMENT: \"VF903\",\n TIMEOUT_ERROR: \"VF904\",\n} as const;\n\nexport type ErrorCodeType = typeof ErrorCode[keyof typeof ErrorCode];\n\nexport function getErrorDocsUrl(code: ErrorCodeType): string {\n return `https://veryfront.com/docs/errors/${code}`;\n}\n\nexport function inferErrorCode(error: Error): ErrorCodeType | null {\n const message = error.message.toLowerCase();\n\n if (message.includes(\"config\") && message.includes(\"not found\")) {\n return ErrorCode.CONFIG_NOT_FOUND;\n }\n if (message.includes(\"config\") && message.includes(\"invalid\")) return ErrorCode.CONFIG_INVALID;\n if (message.includes(\"cors\")) return ErrorCode.CORS_CONFIG_INVALID;\n\n if (message.includes(\"route\") && message.includes(\"conflict\")) return ErrorCode.ROUTE_CONFLICT;\n if (message.includes(\"route\") && message.includes(\"invalid\")) return ErrorCode.INVALID_ROUTE_FILE;\n\n if (message.includes(\"client\") && message.includes(\"boundary\")) {\n return ErrorCode.CLIENT_BOUNDARY_VIOLATION;\n }\n if (message.includes(\"server-only\") && message.includes(\"client\")) {\n return ErrorCode.SERVER_ONLY_IN_CLIENT;\n }\n\n if (message.includes(\"module not found\") || message.includes(\"cannot find module\")) {\n return ErrorCode.MODULE_NOT_FOUND;\n }\n if (message.includes(\"import\") || message.includes(\"resolve\")) {\n return ErrorCode.IMPORT_RESOLUTION_ERROR;\n }\n if (message.includes(\"react\") && message.includes(\"not found\")) {\n return ErrorCode.DEPENDENCY_MISSING;\n }\n\n if (message.includes(\"port\") && (message.includes(\"in use\") || message.includes(\"eaddrinuse\"))) {\n return ErrorCode.PORT_IN_USE;\n }\n if (message.includes(\"hydration\")) return ErrorCode.HYDRATION_MISMATCH;\n\n if (message.includes(\"build\") && message.includes(\"fail\")) return ErrorCode.BUILD_FAILED;\n if (message.includes(\"mdx\")) return ErrorCode.MDX_COMPILE_ERROR;\n if (message.includes(\"typescript\")) return ErrorCode.TYPESCRIPT_ERROR;\n\n return null;\n}\n", "import type { ErrorCodeType } from \"../error-codes.ts\";\nimport { getErrorDocsUrl } from \"../error-codes.ts\";\nimport type { ErrorSolution } from \"./types.ts\";\n\nexport function createErrorSolution(\n code: ErrorCodeType,\n config: Omit<ErrorSolution, \"code\" | \"docs\"> & { docs?: string },\n): ErrorSolution {\n return {\n code,\n ...config,\n docs: config.docs ?? getErrorDocsUrl(code),\n };\n}\n\nexport function createSimpleError(\n code: ErrorCodeType,\n title: string,\n message: string,\n steps: string[],\n): ErrorSolution {\n return createErrorSolution(code, { title, message, steps });\n}\n", "import { ErrorCode } from \"../error-codes.ts\";\nimport type { PartialErrorCatalog } from \"./types.ts\";\nimport { createErrorSolution, createSimpleError } from \"./factory.ts\";\n\nexport const CONFIG_ERROR_CATALOG: PartialErrorCatalog = {\n [ErrorCode.CONFIG_NOT_FOUND]: createErrorSolution(ErrorCode.CONFIG_NOT_FOUND, {\n title: \"Configuration file not found\",\n message: \"Veryfront could not find veryfront.config.js in your project root.\",\n steps: [\n \"Create veryfront.config.js in your project root directory\",\n \"Run 'veryfront init' to generate a default configuration\",\n \"Or copy from an example project\",\n ],\n example: `// veryfront.config.js\nexport default {\n title: \"My App\",\n dev: { port: 3002 }\n}`,\n tips: [\"You can use .ts or .mjs extensions too\", \"Config is optional for simple projects\"],\n }),\n\n [ErrorCode.CONFIG_INVALID]: createErrorSolution(ErrorCode.CONFIG_INVALID, {\n title: \"Invalid configuration\",\n message: \"Your configuration file has invalid values or structure.\",\n steps: [\n \"Check that the config exports a default object\",\n \"Ensure all values are valid JavaScript types\",\n \"Remove any trailing commas\",\n \"Verify property names match the schema\",\n ],\n example: `// \u2713 Valid config\nexport default {\n title: \"My App\",\n dev: {\n port: 3002,\n open: true\n }\n}`,\n }),\n\n [ErrorCode.CONFIG_PARSE_ERROR]: createSimpleError(\n ErrorCode.CONFIG_PARSE_ERROR,\n \"Configuration parse error\",\n \"Failed to parse your configuration file.\",\n [\n \"Check for syntax errors (missing brackets, quotes, etc.)\",\n \"Ensure the file has valid JavaScript/TypeScript syntax\",\n \"Look for the specific parse error in the output above\",\n ],\n ),\n\n [ErrorCode.CONFIG_VALIDATION_ERROR]: createSimpleError(\n ErrorCode.CONFIG_VALIDATION_ERROR,\n \"Configuration validation failed\",\n \"Configuration values do not pass validation.\",\n [\n \"Check that port numbers are between 1-65535\",\n \"Ensure boolean flags are true/false (not strings)\",\n \"Verify URLs are properly formatted\",\n \"Check array/object structures match expected format\",\n ],\n ),\n\n [ErrorCode.CONFIG_TYPE_ERROR]: createSimpleError(\n ErrorCode.CONFIG_TYPE_ERROR,\n \"Configuration type error\",\n \"A configuration value has the wrong type.\",\n [\n \"Check that numbers are not in quotes\",\n 'Ensure booleans are true/false, not \"true\"/\"false\"',\n \"Verify arrays use [] brackets\",\n \"Check objects use {} braces\",\n ],\n ),\n\n [ErrorCode.IMPORT_MAP_INVALID]: createErrorSolution(ErrorCode.IMPORT_MAP_INVALID, {\n title: \"Invalid import map\",\n message: \"The import map in your configuration is invalid.\",\n steps: [\n \"Check import map structure: { imports: {}, scopes: {} }\",\n \"Ensure URLs are valid and accessible\",\n \"Verify package names are correct\",\n ],\n example: `resolve: {\n importMap: {\n imports: {\n \"react\": \"https://esm.sh/react@19\",\n \"@/utils\": \"./src/utils/index.ts\"\n }\n }\n}`,\n }),\n\n [ErrorCode.CORS_CONFIG_INVALID]: createErrorSolution(ErrorCode.CORS_CONFIG_INVALID, {\n title: \"Invalid CORS configuration\",\n message: \"The CORS configuration is invalid.\",\n steps: [\n \"Use true for default CORS settings\",\n \"Or provide an object with origin, methods, headers\",\n \"Ensure origin is a string, not an array\",\n ],\n example: `security: {\n cors: true // or { origin: \"https://example.com\" }\n}`,\n }),\n};\n", "import { ErrorCode } from \"../error-codes.ts\";\nimport type { PartialErrorCatalog } from \"./types.ts\";\nimport { createErrorSolution, createSimpleError } from \"./factory.ts\";\n\nexport const BUILD_ERROR_CATALOG: PartialErrorCatalog = {\n [ErrorCode.BUILD_FAILED]: createErrorSolution(ErrorCode.BUILD_FAILED, {\n title: \"Build failed\",\n message: \"The build process encountered errors.\",\n steps: [\n \"Check the error messages above for specific issues\",\n \"Fix any TypeScript or syntax errors\",\n \"Ensure all imports can be resolved\",\n \"Run 'veryfront doctor' to check your environment\",\n ],\n tips: [\"Try running with --verbose for more details\", \"Check build logs for warnings\"],\n }),\n\n [ErrorCode.BUNDLE_ERROR]: createSimpleError(\n ErrorCode.BUNDLE_ERROR,\n \"Bundle generation failed\",\n \"Failed to generate JavaScript bundles.\",\n [\n \"Check for circular dependencies\",\n \"Ensure all imports are valid\",\n \"Try clearing cache: veryfront clean\",\n ],\n ),\n\n [ErrorCode.TYPESCRIPT_ERROR]: createSimpleError(\n ErrorCode.TYPESCRIPT_ERROR,\n \"TypeScript compilation error\",\n \"TypeScript found errors in your code.\",\n [\n \"Fix the TypeScript errors shown above\",\n \"Check your tsconfig.json configuration\",\n \"Ensure all types are properly imported\",\n ],\n ),\n\n [ErrorCode.MDX_COMPILE_ERROR]: createErrorSolution(ErrorCode.MDX_COMPILE_ERROR, {\n title: \"MDX compilation failed\",\n message: \"Failed to compile MDX file.\",\n steps: [\n \"Check for syntax errors in your MDX file\",\n \"Ensure frontmatter YAML is valid\",\n \"Verify JSX components are properly imported\",\n \"Check for unclosed tags or brackets\",\n ],\n example: `---\ntitle: My Post\n---\n\nimport Button from './components/Button.jsx'\n\n# Hello World\n\n<Button>Click me</Button>`,\n }),\n\n [ErrorCode.ASSET_OPTIMIZATION_ERROR]: createSimpleError(\n ErrorCode.ASSET_OPTIMIZATION_ERROR,\n \"Asset optimization failed\",\n \"Failed to optimize assets (images, CSS, etc.).\",\n [\n \"Check that asset files are valid\",\n \"Ensure file paths are correct\",\n \"Try disabling optimization temporarily\",\n ],\n ),\n\n [ErrorCode.SSG_GENERATION_ERROR]: createSimpleError(\n ErrorCode.SSG_GENERATION_ERROR,\n \"Static site generation failed\",\n \"Failed to generate static pages.\",\n [\n \"Check that all routes are valid\",\n \"Ensure getStaticData functions return correctly\",\n \"Verify no dynamic content requires runtime\",\n ],\n ),\n\n [ErrorCode.SOURCEMAP_ERROR]: createSimpleError(\n ErrorCode.SOURCEMAP_ERROR,\n \"Source map generation failed\",\n \"Failed to generate source maps.\",\n [\n \"Try disabling source maps temporarily\",\n \"Check for very large files that might cause issues\",\n ],\n ),\n};\n", "import { ErrorCode } from \"../error-codes.ts\";\nimport type { PartialErrorCatalog } from \"./types.ts\";\nimport { createErrorSolution, createSimpleError } from \"./factory.ts\";\n\nexport const RUNTIME_ERROR_CATALOG: PartialErrorCatalog = {\n [ErrorCode.HYDRATION_MISMATCH]: createErrorSolution(ErrorCode.HYDRATION_MISMATCH, {\n title: \"Hydration mismatch\",\n message: \"Client-side HTML does not match server-rendered HTML.\",\n steps: [\n \"Check for random values or timestamps in render\",\n \"Ensure Date() calls are consistent\",\n \"Avoid using browser-only APIs during SSR\",\n \"Check for white space or formatting differences\",\n ],\n example: `// \u274C Wrong - random on each render\n<div>{Math.random()}</div>\n\nconst [random, setRandom] = useState(0)\nuseEffect(() => setRandom(Math.random()), [])\n<div>{random}</div>`,\n relatedErrors: [ErrorCode.RENDER_ERROR],\n }),\n\n [ErrorCode.RENDER_ERROR]: createSimpleError(\n ErrorCode.RENDER_ERROR,\n \"Render error\",\n \"Failed to render component.\",\n [\n \"Check the component for errors\",\n \"Ensure all props are valid\",\n \"Look for null/undefined access\",\n \"Check error boundaries\",\n ],\n ),\n\n [ErrorCode.COMPONENT_ERROR]: createSimpleError(\n ErrorCode.COMPONENT_ERROR,\n \"Component error\",\n \"Error in component lifecycle or render.\",\n [\n \"Check component code for errors\",\n \"Ensure hooks follow Rules of Hooks\",\n \"Verify props are passed correctly\",\n ],\n ),\n\n [ErrorCode.LAYOUT_NOT_FOUND]: createErrorSolution(ErrorCode.LAYOUT_NOT_FOUND, {\n title: \"Layout file not found\",\n message: \"Required layout file is missing.\",\n steps: [\n \"Create app/layout.tsx in App Router\",\n \"Or create layouts/default.mdx for Pages Router\",\n \"Check file path and name are correct\",\n ],\n example: `// app/layout.tsx\nexport default function RootLayout({ children }) {\n return (\n <html lang=\"en\">\n <body>{children}</body>\n </html>\n )\n}`,\n }),\n\n [ErrorCode.PAGE_NOT_FOUND]: createSimpleError(\n ErrorCode.PAGE_NOT_FOUND,\n \"Page not found\",\n \"The requested page does not exist.\",\n [\n \"Check that the page file exists\",\n \"Verify file name matches route\",\n \"Ensure file extension is correct (.tsx, .jsx, .mdx)\",\n ],\n ),\n\n [ErrorCode.API_ERROR]: createSimpleError(\n ErrorCode.API_ERROR,\n \"API handler error\",\n \"Error in API route handler.\",\n [\n \"Check API handler code for errors\",\n \"Ensure proper error handling\",\n \"Verify request/response format\",\n ],\n ),\n\n [ErrorCode.MIDDLEWARE_ERROR]: createSimpleError(\n ErrorCode.MIDDLEWARE_ERROR,\n \"Middleware error\",\n \"Error in middleware execution.\",\n [\n \"Check middleware code for errors\",\n \"Ensure middleware returns Response\",\n \"Verify middleware is properly exported\",\n ],\n ),\n};\n", "import { ErrorCode } from \"../error-codes.ts\";\nimport type { PartialErrorCatalog } from \"./types.ts\";\nimport { createErrorSolution, createSimpleError } from \"./factory.ts\";\n\nexport const ROUTE_ERROR_CATALOG: PartialErrorCatalog = {\n [ErrorCode.ROUTE_CONFLICT]: createSimpleError(\n ErrorCode.ROUTE_CONFLICT,\n \"Route conflict\",\n \"Multiple files are trying to handle the same route.\",\n [\n \"Check for duplicate route files\",\n \"Remove conflicting routes\",\n \"Use dynamic routes [id] carefully\",\n ],\n ),\n\n [ErrorCode.INVALID_ROUTE_FILE]: createErrorSolution(ErrorCode.INVALID_ROUTE_FILE, {\n title: \"Invalid route file\",\n message: \"Route file has invalid structure or exports.\",\n steps: [\n \"API routes must export GET, POST, etc. functions\",\n \"Page routes must export default component\",\n \"Check for syntax errors\",\n ],\n example: `// app/api/users/route.ts\nexport async function GET() {\n return Response.json({ users: [] })\n}`,\n }),\n\n [ErrorCode.ROUTE_HANDLER_INVALID]: createSimpleError(\n ErrorCode.ROUTE_HANDLER_INVALID,\n \"Invalid route handler\",\n \"Route handler does not return Response.\",\n [\n \"Ensure handler returns Response object\",\n \"Use Response.json() for JSON responses\",\n \"Check for missing return statement\",\n ],\n ),\n\n [ErrorCode.DYNAMIC_ROUTE_ERROR]: createSimpleError(\n ErrorCode.DYNAMIC_ROUTE_ERROR,\n \"Dynamic route error\",\n \"Error in dynamic route handling.\",\n [\n \"Check [param] syntax is correct\",\n \"Ensure params are accessed properly\",\n \"Verify dynamic segment names\",\n ],\n ),\n\n [ErrorCode.ROUTE_PARAMS_ERROR]: createSimpleError(\n ErrorCode.ROUTE_PARAMS_ERROR,\n \"Route parameters error\",\n \"Error accessing route parameters.\",\n [\n \"Check params object structure\",\n \"Ensure parameter names match route\",\n \"Verify params are strings\",\n ],\n ),\n\n [ErrorCode.API_ROUTE_ERROR]: createSimpleError(\n ErrorCode.API_ROUTE_ERROR,\n \"API route error\",\n \"Error in API route execution.\",\n [\n \"Check API handler code\",\n \"Ensure proper error handling\",\n \"Verify request parsing\",\n ],\n ),\n};\n", "import { ErrorCode } from \"../error-codes.ts\";\nimport type { PartialErrorCatalog } from \"./types.ts\";\nimport { createErrorSolution, createSimpleError } from \"./factory.ts\";\n\nexport const MODULE_ERROR_CATALOG: PartialErrorCatalog = {\n [ErrorCode.MODULE_NOT_FOUND]: createErrorSolution(ErrorCode.MODULE_NOT_FOUND, {\n title: \"Module not found\",\n message: \"Cannot find the imported module.\",\n steps: [\n \"Check that the file path is correct\",\n \"Ensure the module is installed or exists\",\n \"Add missing module to import map\",\n \"Check for typos in import statement\",\n ],\n example: `// Add to veryfront.config.js\nresolve: {\n importMap: {\n imports: {\n \"missing-lib\": \"https://esm.sh/missing-lib@1.0.0\"\n }\n }\n}`,\n }),\n\n [ErrorCode.IMPORT_RESOLUTION_ERROR]: createSimpleError(\n ErrorCode.IMPORT_RESOLUTION_ERROR,\n \"Import resolution failed\",\n \"Failed to resolve import specifier.\",\n [\n \"Check import paths are correct\",\n \"Ensure modules are in import map\",\n \"Verify network connectivity for remote imports\",\n ],\n ),\n\n [ErrorCode.CIRCULAR_DEPENDENCY]: createSimpleError(\n ErrorCode.CIRCULAR_DEPENDENCY,\n \"Circular dependency detected\",\n \"Files are importing each other in a circle.\",\n [\n \"Identify the circular import chain\",\n \"Extract shared code to separate file\",\n \"Use dependency injection or lazy imports\",\n ],\n ),\n\n [ErrorCode.INVALID_IMPORT]: createSimpleError(\n ErrorCode.INVALID_IMPORT,\n \"Invalid import statement\",\n \"Import statement has invalid syntax.\",\n [\n 'Check import syntax: import X from \"y\"',\n \"Ensure quotes are properly closed\",\n \"Verify export exists in target module\",\n ],\n ),\n\n [ErrorCode.DEPENDENCY_MISSING]: createErrorSolution(ErrorCode.DEPENDENCY_MISSING, {\n title: \"Required dependency not found\",\n message: \"A required dependency is missing.\",\n steps: [\n \"Add React to your import map\",\n \"Ensure all peer dependencies are included\",\n \"Run 'veryfront doctor' to verify setup\",\n ],\n example: `// Minimum required imports\nresolve: {\n importMap: {\n imports: {\n \"react\": \"https://esm.sh/react@19\",\n \"react-dom\": \"https://esm.sh/react-dom@19\"\n }\n }\n}`,\n }),\n\n [ErrorCode.VERSION_MISMATCH]: createSimpleError(\n ErrorCode.VERSION_MISMATCH,\n \"Dependency version mismatch\",\n \"Incompatible versions of dependencies detected.\",\n [\n \"Ensure React and React-DOM versions match\",\n \"Check for multiple React instances\",\n \"Update dependencies to compatible versions\",\n ],\n ),\n};\n", "import { ErrorCode } from \"../error-codes.ts\";\nimport type { PartialErrorCatalog } from \"./types.ts\";\nimport { createErrorSolution, createSimpleError } from \"./factory.ts\";\n\nexport const SERVER_ERROR_CATALOG: PartialErrorCatalog = {\n [ErrorCode.PORT_IN_USE]: createErrorSolution(ErrorCode.PORT_IN_USE, {\n title: \"Port already in use\",\n message: \"Another process is using the specified port.\",\n steps: [\n \"Stop the other process: lsof -i :PORT\",\n \"Use a different port: veryfront dev --port 3003\",\n \"Add port to config file\",\n ],\n example: `// veryfront.config.js\ndev: {\n port: 3003\n}`,\n }),\n\n [ErrorCode.SERVER_START_ERROR]: createSimpleError(\n ErrorCode.SERVER_START_ERROR,\n \"Server failed to start\",\n \"Development server could not start.\",\n [\n \"Check for port conflicts\",\n \"Ensure file permissions are correct\",\n \"Verify configuration is valid\",\n ],\n ),\n\n [ErrorCode.HMR_ERROR]: createSimpleError(\n ErrorCode.HMR_ERROR,\n \"Hot Module Replacement error\",\n \"HMR failed to update module.\",\n [\n \"Try refreshing the page\",\n \"Check for syntax errors\",\n \"Restart dev server if persistent\",\n ],\n ),\n\n [ErrorCode.CACHE_ERROR]: createSimpleError(\n ErrorCode.CACHE_ERROR,\n \"Cache operation failed\",\n \"Error reading or writing cache.\",\n [\n \"Clear cache: veryfront clean --cache\",\n \"Check disk space\",\n \"Verify file permissions\",\n ],\n ),\n\n [ErrorCode.FILE_WATCH_ERROR]: createSimpleError(\n ErrorCode.FILE_WATCH_ERROR,\n \"File watching failed\",\n \"Could not watch files for changes.\",\n [\n \"Check system file watch limits\",\n \"Reduce number of watched files\",\n \"Try restarting dev server\",\n ],\n ),\n\n [ErrorCode.REQUEST_ERROR]: createSimpleError(\n ErrorCode.REQUEST_ERROR,\n \"Request handling error\",\n \"Error processing HTTP request.\",\n [\n \"Check request format and headers\",\n \"Verify route handler code\",\n \"Check for middleware errors\",\n ],\n ),\n};\n", "import { ErrorCode } from \"../error-codes.ts\";\nimport type { PartialErrorCatalog } from \"./types.ts\";\nimport { createErrorSolution, createSimpleError } from \"./factory.ts\";\n\nexport const RSC_ERROR_CATALOG: PartialErrorCatalog = {\n [ErrorCode.CLIENT_BOUNDARY_VIOLATION]: createErrorSolution(\n ErrorCode.CLIENT_BOUNDARY_VIOLATION,\n {\n title: \"Client/Server boundary violation\",\n message: \"Server-only code used in Client Component.\",\n steps: [\n \"Move server-only imports to Server Components\",\n \"Use 'use server' for server actions\",\n \"Split component into server and client parts\",\n ],\n example: `// \u2713 Correct pattern\nimport { db } from './database'\nexport default async function ServerComponent() {\n const data = await db.query('...')\n return <ClientComponent data={data} />\n}\n\n'use client'\nexport default function ClientComponent({ data }) {\n return <div>{data}</div>\n}`,\n },\n ),\n\n [ErrorCode.SERVER_ONLY_IN_CLIENT]: createSimpleError(\n ErrorCode.SERVER_ONLY_IN_CLIENT,\n \"Server-only module in Client Component\",\n \"Cannot use server-only module in client code.\",\n [\n \"Move server logic to Server Component\",\n \"Use API routes for client data fetching\",\n \"Pass data as props from server\",\n ],\n ),\n\n [ErrorCode.CLIENT_ONLY_IN_SERVER]: createSimpleError(\n ErrorCode.CLIENT_ONLY_IN_SERVER,\n \"Client-only code in Server Component\",\n \"Cannot use browser APIs in Server Component.\",\n [\n \"Add 'use client' directive\",\n \"Move client-only code to Client Component\",\n \"Use useEffect for client-side logic\",\n ],\n ),\n\n [ErrorCode.INVALID_USE_CLIENT]: createErrorSolution(ErrorCode.INVALID_USE_CLIENT, {\n title: \"Invalid 'use client' directive\",\n message: \"'use client' directive is not properly placed.\",\n steps: [\n \"Place 'use client' at the very top of file\",\n \"Must be before any imports\",\n 'Use exact string: \"use client\"',\n ],\n example: `'use client' // Must be first line\n\nimport React from 'react'`,\n }),\n\n [ErrorCode.INVALID_USE_SERVER]: createSimpleError(\n ErrorCode.INVALID_USE_SERVER,\n \"Invalid 'use server' directive\",\n \"'use server' directive is not properly placed.\",\n [\n \"Place 'use server' at top of function\",\n \"Or at top of file for all functions\",\n 'Use exact string: \"use server\"',\n ],\n ),\n\n [ErrorCode.RSC_PAYLOAD_ERROR]: createSimpleError(\n ErrorCode.RSC_PAYLOAD_ERROR,\n \"RSC payload error\",\n \"Error serializing Server Component payload.\",\n [\n \"Ensure props are JSON-serializable\",\n \"Avoid passing functions as props\",\n \"Check for circular references\",\n ],\n ),\n};\n", "import { ErrorCode } from \"../error-codes.ts\";\nimport type { PartialErrorCatalog } from \"./types.ts\";\nimport { createSimpleError } from \"./factory.ts\";\n\nexport const DEV_ERROR_CATALOG: PartialErrorCatalog = {\n [ErrorCode.DEV_SERVER_ERROR]: createSimpleError(\n ErrorCode.DEV_SERVER_ERROR,\n \"Development server error\",\n \"Error in development server.\",\n [\n \"Check server logs for details\",\n \"Try restarting dev server\",\n \"Clear cache and restart\",\n ],\n ),\n\n [ErrorCode.FAST_REFRESH_ERROR]: createSimpleError(\n ErrorCode.FAST_REFRESH_ERROR,\n \"Fast Refresh error\",\n \"React Fast Refresh failed.\",\n [\n \"Check for syntax errors\",\n \"Ensure components follow Fast Refresh rules\",\n \"Try full page refresh\",\n ],\n ),\n\n [ErrorCode.ERROR_OVERLAY_ERROR]: createSimpleError(\n ErrorCode.ERROR_OVERLAY_ERROR,\n \"Error overlay failed\",\n \"Could not display error overlay.\",\n [\n \"Check browser console for details\",\n \"Try disabling browser extensions\",\n \"Refresh the page\",\n ],\n ),\n\n [ErrorCode.SOURCE_MAP_ERROR]: createSimpleError(\n ErrorCode.SOURCE_MAP_ERROR,\n \"Source map error\",\n \"Error loading or parsing source map.\",\n [\n \"Check that source maps are enabled\",\n \"Try rebuilding the project\",\n \"Check for corrupted build files\",\n ],\n ),\n};\n", "import { ErrorCode } from \"../error-codes.ts\";\nimport type { PartialErrorCatalog } from \"./types.ts\";\nimport { createSimpleError } from \"./factory.ts\";\n\nexport const DEPLOYMENT_ERROR_CATALOG: PartialErrorCatalog = {\n [ErrorCode.DEPLOYMENT_ERROR]: createSimpleError(\n ErrorCode.DEPLOYMENT_ERROR,\n \"Deployment failed\",\n \"Failed to deploy application.\",\n [\n \"Check deployment logs for details\",\n \"Verify platform credentials\",\n \"Ensure build succeeded first\",\n ],\n ),\n\n [ErrorCode.PLATFORM_ERROR]: createSimpleError(\n ErrorCode.PLATFORM_ERROR,\n \"Platform error\",\n \"Deployment platform returned an error.\",\n [\n \"Check platform status page\",\n \"Verify API keys and credentials\",\n \"Try deploying again\",\n ],\n ),\n\n [ErrorCode.ENV_VAR_MISSING]: createSimpleError(\n ErrorCode.ENV_VAR_MISSING,\n \"Environment variable missing\",\n \"Required environment variable is not set.\",\n [\n \"Add variable to .env file\",\n \"Set variable in deployment platform\",\n \"Check variable name is correct\",\n ],\n ),\n\n [ErrorCode.PRODUCTION_BUILD_REQUIRED]: createSimpleError(\n ErrorCode.PRODUCTION_BUILD_REQUIRED,\n \"Production build required\",\n \"Must build project before deploying.\",\n [\n \"Run 'veryfront build' first\",\n \"Check that dist/ directory exists\",\n \"Verify build completed successfully\",\n ],\n ),\n};\n", "import { ErrorCode } from \"../error-codes.ts\";\nimport type { PartialErrorCatalog } from \"./types.ts\";\nimport { createSimpleError } from \"./factory.ts\";\n\nexport const GENERAL_ERROR_CATALOG: PartialErrorCatalog = {\n [ErrorCode.UNKNOWN_ERROR]: createSimpleError(\n ErrorCode.UNKNOWN_ERROR,\n \"Unknown error\",\n \"An unexpected error occurred.\",\n [\n \"Check error details above\",\n \"Run 'veryfront doctor' to diagnose\",\n \"Try restarting the operation\",\n \"Check GitHub issues for similar problems\",\n ],\n ),\n\n [ErrorCode.PERMISSION_DENIED]: createSimpleError(\n ErrorCode.PERMISSION_DENIED,\n \"Permission denied\",\n \"Insufficient permissions to perform operation.\",\n [\n \"Check file/directory permissions\",\n \"Run with appropriate permissions\",\n \"Verify user has write access\",\n ],\n ),\n\n [ErrorCode.FILE_NOT_FOUND]: createSimpleError(\n ErrorCode.FILE_NOT_FOUND,\n \"File not found\",\n \"Required file does not exist.\",\n [\n \"Check that file path is correct\",\n \"Verify file exists in project\",\n \"Check for typos in file name\",\n ],\n ),\n\n [ErrorCode.INVALID_ARGUMENT]: createSimpleError(\n ErrorCode.INVALID_ARGUMENT,\n \"Invalid argument\",\n \"Command received invalid argument.\",\n [\n \"Check command syntax\",\n \"Verify argument values\",\n \"Run 'veryfront help <command>' for usage\",\n ],\n ),\n\n [ErrorCode.TIMEOUT_ERROR]: createSimpleError(\n ErrorCode.TIMEOUT_ERROR,\n \"Operation timed out\",\n \"Operation took too long to complete.\",\n [\n \"Check network connectivity\",\n \"Try increasing timeout if available\",\n \"Check for very large files\",\n ],\n ),\n};\n", "import type { ErrorCodeType } from \"../error-codes.ts\";\nimport type { ErrorCatalog, ErrorSolution } from \"./types.ts\";\n\nimport { CONFIG_ERROR_CATALOG } from \"./config-errors.ts\";\nimport { BUILD_ERROR_CATALOG } from \"./build-errors.ts\";\nimport { RUNTIME_ERROR_CATALOG } from \"./runtime-errors.ts\";\nimport { ROUTE_ERROR_CATALOG } from \"./route-errors.ts\";\nimport { MODULE_ERROR_CATALOG } from \"./module-errors.ts\";\nimport { SERVER_ERROR_CATALOG } from \"./server-errors.ts\";\nimport { RSC_ERROR_CATALOG } from \"./rsc-errors.ts\";\nimport { DEV_ERROR_CATALOG } from \"./dev-errors.ts\";\nimport { DEPLOYMENT_ERROR_CATALOG } from \"./deployment-errors.ts\";\nimport { GENERAL_ERROR_CATALOG } from \"./general-errors.ts\";\n\nexport const ERROR_CATALOG = {\n ...CONFIG_ERROR_CATALOG,\n ...BUILD_ERROR_CATALOG,\n ...RUNTIME_ERROR_CATALOG,\n ...ROUTE_ERROR_CATALOG,\n ...MODULE_ERROR_CATALOG,\n ...SERVER_ERROR_CATALOG,\n ...RSC_ERROR_CATALOG,\n ...DEV_ERROR_CATALOG,\n ...DEPLOYMENT_ERROR_CATALOG,\n ...GENERAL_ERROR_CATALOG,\n} as ErrorCatalog;\n\nexport function getErrorSolution(code: ErrorCodeType): ErrorSolution | null {\n return ERROR_CATALOG[code] || null;\n}\n\nexport function searchErrors(query: string): ErrorSolution[] {\n const lowerQuery = query.toLowerCase();\n return Object.values(ERROR_CATALOG).filter(\n (error) =>\n error.title.toLowerCase().includes(lowerQuery) ||\n error.message.toLowerCase().includes(lowerQuery) ||\n error.steps?.some((step) => step.toLowerCase().includes(lowerQuery)),\n );\n}\n\nexport type { ErrorCatalog, ErrorSolution, PartialErrorCatalog } from \"./types.ts\";\n\nexport { createErrorSolution, createSimpleError } from \"./factory.ts\";\n\nexport {\n BUILD_ERROR_CATALOG,\n CONFIG_ERROR_CATALOG,\n DEPLOYMENT_ERROR_CATALOG,\n DEV_ERROR_CATALOG,\n GENERAL_ERROR_CATALOG,\n MODULE_ERROR_CATALOG,\n ROUTE_ERROR_CATALOG,\n RSC_ERROR_CATALOG,\n RUNTIME_ERROR_CATALOG,\n SERVER_ERROR_CATALOG,\n};\n", "export interface ErrorSolution {\n message: string;\n steps?: string[];\n example?: string;\n docs?: string;\n}\n\nexport const ERROR_SOLUTIONS: Record<string, ErrorSolution> = {\n \"missing-config\": {\n message: \"No veryfront.config.js found in project directory\",\n steps: [\n \"Create a veryfront.config.js file in your project root\",\n \"Run 'veryfront init' to generate a default config\",\n \"Or create one manually with minimal configuration\",\n ],\n example: `export default {\n title: \"My App\",\n dev: { port: 3002 }\n};`,\n },\n\n \"invalid-config\": {\n message: \"Invalid configuration in veryfront.config.js\",\n steps: [\n \"Check that your config exports a default object\",\n \"Ensure all values are valid JavaScript\",\n \"Remove any trailing commas in objects\",\n ],\n example: `export default {\n title: \"My App\", // \u2713 Valid string\n dev: {\n port: 3002, // \u2713 Valid number\n open: true // \u2713 No trailing comma\n }\n};`,\n },\n\n \"invalid-route\": {\n message: \"Invalid route file format\",\n steps: [\n \"Route files must export handler functions (GET, POST, etc.)\",\n \"Each handler must return a Response object\",\n \"Check for syntax errors in your route file\",\n ],\n example: `// app/api/users/route.ts\nexport async function GET() {\n return Response.json({ users: [] });\n}\n\nexport async function POST(request: Request) {\n const body = await request.json();\n return Response.json({ created: true });\n}`,\n },\n\n \"client-boundary\": {\n message: \"Server-only code used in Client Component\",\n steps: [\n \"Move server-only imports to Server Components\",\n \"Use 'use server' directive for server actions\",\n \"Split component into server and client parts\",\n ],\n example: `// \u274C Wrong - database import in client component\n'use client';\nimport { db } from './database'; // Error!\n\nimport { db } from './database';\nexport default async function ServerComponent() {\n const data = await db.query('...');\n return <ClientComponent data={data} />;\n}\n\n'use client';\nexport default function ClientComponent({ data }) {\n}`,\n docs: \"https://github.com/veryfront/veryfront/docs/rsc-boundaries\",\n },\n\n \"import-not-found\": {\n message: \"Failed to resolve import\",\n steps: [\n \"Check that the file path is correct\",\n \"Ensure the module is installed or available\",\n \"For remote imports, check network connectivity\",\n \"Add missing imports to veryfront.config.js importMap\",\n ],\n example: `// veryfront.config.js\nresolve: {\n importMap: {\n imports: {\n \"my-lib\": \"https://esm.sh/my-lib@1.0.0\",\n \"@/utils\": \"./src/utils/index.ts\"\n }\n }\n}`,\n },\n\n \"port-in-use\": {\n message: \"Port is already in use\",\n steps: [\n \"Stop any other servers running on this port\",\n \"Use a different port with --port flag\",\n \"Check for zombie processes: lsof -i :PORT\",\n ],\n example: `veryfront dev --port 3003`,\n },\n\n \"build-failed\": {\n message: \"Build failed with errors\",\n steps: [\n \"Check the error messages above for details\",\n \"Fix any TypeScript or syntax errors\",\n \"Ensure all imports can be resolved\",\n \"Run 'veryfront doctor' to check system\",\n ],\n },\n\n \"missing-deps\": {\n message: \"Required dependencies not found\",\n steps: [\n \"Check that React is in your import map\",\n \"Ensure all peer dependencies are included\",\n \"Run 'veryfront doctor' to verify setup\",\n ],\n example: `// Minimum required imports\n\"react\": \"https://esm.sh/react@19.1.1\",\n\"react-dom\": \"https://esm.sh/react-dom@19.1.1\"`,\n },\n};\n", "/**\n * Pure ANSI escape code colors for npm/Node.js builds\n *\n * This file provides a zero-dependency color implementation using ANSI codes.\n * It's used in npm builds where std/fmt/colors.ts isn't available.\n */\n\nimport type { ColorFunction, ConsoleStyler } from \"./types.ts\";\n\nconst ansi = (open: number, close: number): ColorFunction => (text: string) =>\n `\\x1b[${open}m${text}\\x1b[${close}m`;\n\nexport const red: ColorFunction = ansi(31, 39);\nexport const green: ColorFunction = ansi(32, 39);\nexport const yellow: ColorFunction = ansi(33, 39);\nexport const blue: ColorFunction = ansi(34, 39);\nexport const magenta: ColorFunction = ansi(35, 39);\nexport const cyan: ColorFunction = ansi(36, 39);\nexport const white: ColorFunction = ansi(37, 39);\nexport const gray: ColorFunction = ansi(90, 39);\nexport const bold: ColorFunction = ansi(1, 22);\nexport const dim: ColorFunction = ansi(2, 22);\nexport const italic: ColorFunction = ansi(3, 23);\nexport const underline: ColorFunction = ansi(4, 24);\nexport const strikethrough: ColorFunction = ansi(9, 29);\nexport const reset: ColorFunction = (text: string) => `\\x1b[0m${text}`;\n\nexport const colors: ConsoleStyler = {\n red,\n green,\n yellow,\n blue,\n cyan,\n magenta,\n white,\n gray,\n bold,\n dim,\n italic,\n underline,\n strikethrough,\n reset,\n};\n", "/**\n * Deno console styling implementation using std/fmt/colors.ts\n */\n\nimport {\n blue,\n bold,\n cyan,\n dim,\n gray,\n green,\n italic,\n magenta,\n red,\n reset,\n strikethrough,\n underline,\n white,\n yellow,\n} from \"std/fmt/colors.ts\";\n\nimport type { ConsoleStyler } from \"./types.ts\";\n\nexport const colors: ConsoleStyler = {\n red,\n green,\n yellow,\n blue,\n cyan,\n magenta,\n white,\n gray,\n bold,\n dim,\n italic,\n underline,\n strikethrough,\n reset,\n};\n\nexport {\n blue,\n bold,\n cyan,\n dim,\n gray,\n green,\n italic,\n magenta,\n red,\n reset,\n strikethrough,\n underline,\n white,\n yellow,\n};\n", "/**\n * Node.js console styling implementation using picocolors\n */\n\nimport type { ConsoleStyler } from \"./types.ts\";\n\n// Lazy-loaded picocolors instance\ntype PicoColors = {\n red: (s: string) => string;\n green: (s: string) => string;\n yellow: (s: string) => string;\n blue: (s: string) => string;\n cyan: (s: string) => string;\n magenta: (s: string) => string;\n white: (s: string) => string;\n gray: (s: string) => string;\n bold: (s: string) => string;\n dim: (s: string) => string;\n italic: (s: string) => string;\n underline: (s: string) => string;\n strikethrough: (s: string) => string;\n reset: (s: string) => string;\n};\n\nlet pc: PicoColors | null = null;\n\nasync function ensurePc(): Promise<PicoColors> {\n if (pc) return pc;\n // Construct module name dynamically to prevent Deno static analyzer\n // from trying to resolve this npm package during lint/check\n const picocolorsModule = [\"npm:\", \"picocolors\"].join(\"\");\n const mod = await import(picocolorsModule);\n pc = mod.default as PicoColors;\n return pc;\n}\n\n// Lazy wrapper that falls back to identity if not loaded\nconst lazyColor = (fn: keyof PicoColors) => (s: string) => pc?.[fn]?.(s) ?? s;\n\nexport const colors: ConsoleStyler = {\n red: lazyColor(\"red\"),\n green: lazyColor(\"green\"),\n yellow: lazyColor(\"yellow\"),\n blue: lazyColor(\"blue\"),\n cyan: lazyColor(\"cyan\"),\n magenta: lazyColor(\"magenta\"),\n white: lazyColor(\"white\"),\n gray: lazyColor(\"gray\"),\n bold: lazyColor(\"bold\"),\n dim: lazyColor(\"dim\"),\n italic: lazyColor(\"italic\"),\n underline: lazyColor(\"underline\"),\n strikethrough: lazyColor(\"strikethrough\"),\n reset: lazyColor(\"reset\"),\n};\n\nexport const red = lazyColor(\"red\");\nexport const green = lazyColor(\"green\");\nexport const yellow = lazyColor(\"yellow\");\nexport const blue = lazyColor(\"blue\");\nexport const cyan = lazyColor(\"cyan\");\nexport const magenta = lazyColor(\"magenta\");\nexport const white = lazyColor(\"white\");\nexport const gray = lazyColor(\"gray\");\nexport const bold = lazyColor(\"bold\");\nexport const dim = lazyColor(\"dim\");\nexport const italic = lazyColor(\"italic\");\nexport const underline = lazyColor(\"underline\");\nexport const strikethrough = lazyColor(\"strikethrough\");\nexport const reset = lazyColor(\"reset\");\n\n// Initialize picocolors on first use\nexport async function initColors(): Promise<void> {\n await ensurePc();\n}\n", "/**\n * Cross-runtime console styling\n *\n * Provides terminal colors that work in Deno, Node.js, and Bun.\n * Falls back to no-op functions in environments without terminal support.\n */\n\nimport { isDeno } from \"../runtime.ts\";\nimport type { ColorFunction, ConsoleStyler } from \"./types.ts\";\n\nexport type { ColorFunction, ConsoleStyler } from \"./types.ts\";\n\nconst noOp: ColorFunction = (text: string) => text;\n\nconst fallbackColors: ConsoleStyler = {\n red: noOp,\n green: noOp,\n yellow: noOp,\n blue: noOp,\n cyan: noOp,\n magenta: noOp,\n white: noOp,\n gray: noOp,\n bold: noOp,\n dim: noOp,\n italic: noOp,\n underline: noOp,\n strikethrough: noOp,\n reset: noOp,\n};\n\nlet _colors: ConsoleStyler | null = null;\n\nasync function loadColors(): Promise<ConsoleStyler> {\n if (_colors) return _colors;\n\n try {\n if (isDeno) {\n const mod = await import(\"./deno.ts\");\n _colors = mod.colors;\n } else {\n const mod = await import(\"./node.ts\");\n _colors = mod.colors;\n }\n } catch {\n _colors = fallbackColors;\n }\n\n return _colors;\n}\n\nconst colorsPromise = loadColors();\n\nfunction getColors(): ConsoleStyler {\n return _colors ?? fallbackColors;\n}\n\nexport const red: ColorFunction = (text) => getColors().red(text);\nexport const green: ColorFunction = (text) => getColors().green(text);\nexport const yellow: ColorFunction = (text) => getColors().yellow(text);\nexport const blue: ColorFunction = (text) => getColors().blue(text);\nexport const cyan: ColorFunction = (text) => getColors().cyan(text);\nexport const magenta: ColorFunction = (text) => getColors().magenta(text);\nexport const white: ColorFunction = (text) => getColors().white(text);\nexport const gray: ColorFunction = (text) => getColors().gray(text);\nexport const bold: ColorFunction = (text) => getColors().bold(text);\nexport const dim: ColorFunction = (text) => getColors().dim(text);\nexport const italic: ColorFunction = (text) => getColors().italic(text);\nexport const underline: ColorFunction = (text) => getColors().underline(text);\nexport const strikethrough: ColorFunction = (text) => getColors().strikethrough(text);\nexport const reset: ColorFunction = (text) => getColors().reset(text);\n\nexport const colors = {\n red,\n green,\n yellow,\n blue,\n cyan,\n magenta,\n white,\n gray,\n bold,\n dim,\n italic,\n underline,\n strikethrough,\n reset,\n} satisfies ConsoleStyler;\n\nexport { colorsPromise };\n", "export function identifyError(error: Error): string {\n const message = error.message.toLowerCase();\n\n if (message.includes(\"veryfront.config\") && message.includes(\"not found\")) {\n return \"missing-config\";\n }\n if (message.includes(\"config\") && (message.includes(\"invalid\") || message.includes(\"parse\"))) {\n return \"invalid-config\";\n }\n\n if (message.includes(\"route\") && (message.includes(\"invalid\") || message.includes(\"export\"))) {\n return \"invalid-route\";\n }\n\n if (message.includes(\"client\") && (message.includes(\"boundary\") || message.includes(\"server\"))) {\n return \"client-boundary\";\n }\n\n if (\n message.includes(\"import\") ||\n message.includes(\"module not found\") ||\n message.includes(\"resolve\")\n ) {\n return \"import-not-found\";\n }\n\n if (message.includes(\"port\") && (message.includes(\"in use\") || message.includes(\"eaddrinuse\"))) {\n return \"port-in-use\";\n }\n\n if (message.includes(\"build\") && message.includes(\"fail\")) {\n return \"build-failed\";\n }\n\n if (message.includes(\"react\") && message.includes(\"not found\")) {\n return \"missing-deps\";\n }\n\n return \"unknown\";\n}\n", "import { bold, cyan, dim, red, yellow } from \"@veryfront/compat/console\";\nimport { ERROR_SOLUTIONS } from \"./error-catalog.ts\";\nimport { identifyError } from \"./error-identifier.ts\";\n\nexport function formatUserError(error: Error): string {\n const output: string[] = [];\n\n output.push(\"\");\n output.push(red(bold(\"\u2716 Error: \")) + bold(error.message));\n output.push(\"\");\n\n const errorKey = identifyError(error);\n const solution = ERROR_SOLUTIONS[errorKey];\n\n if (solution) {\n if (solution.message) {\n output.push(yellow(\"Problem: \") + solution.message);\n output.push(\"\");\n }\n\n if (solution.steps && solution.steps.length > 0) {\n output.push(cyan(\"How to fix:\"));\n solution.steps.forEach((step, i) => {\n output.push(` ${dim(`${i + 1}.`)} ${step}`);\n });\n output.push(\"\");\n }\n\n if (solution.example) {\n output.push(cyan(\"Example:\"));\n output.push(\"\");\n solution.example.split(\"\\n\").forEach((line) => {\n output.push(` ${dim(line)}`);\n });\n output.push(\"\");\n }\n\n if (solution.docs) {\n output.push(dim(\"Learn more: \") + cyan(solution.docs));\n output.push(\"\");\n }\n } else {\n if (error.stack) {\n output.push(yellow(\"Stack trace:\"));\n const stackLines = error.stack.split(\"\\n\").slice(1, 4);\n stackLines.forEach((line) => {\n output.push(dim(` ${line.trim()}`));\n });\n output.push(\"\");\n }\n\n output.push(dim(\"For help, run: \") + cyan(\"veryfront doctor\"));\n output.push(\"\");\n }\n\n return output.join(\"\\n\");\n}\n", "import { red } from \"@veryfront/compat/console\";\nimport { exit } from \"@veryfront/platform/compat/process.ts\";\nimport { cliLogger } from \"@veryfront/utils/logger/logger.ts\";\nimport { formatUserError } from \"./error-formatter.ts\";\n\nexport function wrapErrorHandler<TArgs extends unknown[], TReturn>(\n fn: (...args: TArgs) => Promise<TReturn>,\n): (...args: TArgs) => Promise<TReturn> {\n return async (...args: TArgs): Promise<TReturn> => {\n try {\n return await fn(...args);\n } catch (error) {\n if (error instanceof Error) {\n cliLogger.error(formatUserError(error));\n } else {\n cliLogger.error(red(\"\u2716 Unknown error:\"), error);\n }\n if (import.meta.main) {\n exit(1);\n }\n throw error;\n }\n };\n}\n", "export { ERROR_SOLUTIONS, type ErrorSolution } from \"./error-catalog.ts\";\nexport { formatUserError } from \"./error-formatter.ts\";\nexport { identifyError } from \"./error-identifier.ts\";\nexport { wrapErrorHandler } from \"./error-wrapper.ts\";\n", "export { ErrorCode, VeryfrontError } from \"./types.ts\";\n\nexport {\n AgentError,\n AgentIntentError,\n AgentNotFoundError,\n AgentTimeoutError,\n OrchestrationError,\n} from \"./agent-errors.ts\";\n\nexport { BuildError, CompilationError } from \"./build-errors.ts\";\n\nexport { RenderError, RuntimeError } from \"./runtime-errors.ts\";\n\nexport {\n ConfigError,\n FileSystemError,\n NetworkError,\n NotSupportedError,\n PermissionError,\n} from \"./system-errors.ts\";\n\nexport {\n handleError,\n handleErrorWithFallback,\n handleErrorWithFallbackSync,\n logAndThrow,\n retryWithBackoff,\n wrapError,\n} from \"./error-handlers.ts\";\n\nexport {\n BUILD_ERROR_CATALOG,\n CONFIG_ERROR_CATALOG,\n createErrorSolution,\n createSimpleError,\n DEPLOYMENT_ERROR_CATALOG,\n DEV_ERROR_CATALOG,\n ERROR_CATALOG,\n GENERAL_ERROR_CATALOG,\n getErrorSolution,\n MODULE_ERROR_CATALOG,\n ROUTE_ERROR_CATALOG,\n RSC_ERROR_CATALOG,\n RUNTIME_ERROR_CATALOG,\n searchErrors,\n SERVER_ERROR_CATALOG,\n} from \"./catalog/index.ts\";\n\nexport type { ErrorCatalog, ErrorSolution, PartialErrorCatalog } from \"./catalog/index.ts\";\n\nexport {\n ERROR_SOLUTIONS,\n formatUserError,\n identifyError,\n wrapErrorHandler,\n} from \"./user-friendly/index.ts\";\n\nexport type { ErrorSolution as UserFriendlyErrorSolution } from \"./user-friendly/index.ts\";\n\nexport type { ErrorCodeType } from \"./error-codes.ts\";\n", "import { FileSystemError } from \"@veryfront/errors\";\nimport { createError, toError } from \"../../../core/errors/veryfront-error.ts\";\nimport type {\n DirEntry,\n FileChangeEvent,\n FileChangeKind,\n FileInfo,\n FileSystemAdapter,\n FileWatcher,\n WatchOptions,\n} from \"../base.ts\";\n\nimport { createFileWatcher, createWatcherIterator, enqueueWatchEvent } from \"../shared-watcher.ts\";\nimport type { BunFSWatcher, BunWatchEvent } from \"./types.ts\";\nimport { serverLogger } from \"@veryfront/utils\";\n\nexport class BunFileSystemAdapter implements FileSystemAdapter {\n async readFile(path: string): Promise<string> {\n const file = Bun.file(path);\n return await file.text();\n }\n\n async readFileBytes(path: string): Promise<Uint8Array> {\n const file = Bun.file(path);\n // deno-lint-ignore no-explicit-any\n const buffer = await (file as any).arrayBuffer();\n return new Uint8Array(buffer);\n }\n\n async writeFile(path: string, content: string): Promise<void> {\n await Bun.write(path, content);\n }\n\n async exists(path: string): Promise<boolean> {\n const file = Bun.file(path);\n return await file.exists();\n }\n\n async *readDir(path: string): AsyncIterable<DirEntry> {\n const { readdir } = await import(\"node:fs/promises\");\n const entries = await readdir(path, { withFileTypes: true });\n\n for (const entry of entries) {\n yield {\n name: entry.name,\n isFile: entry.isFile(),\n isDirectory: entry.isDirectory(),\n isSymlink: entry.isSymbolicLink(),\n };\n }\n }\n\n async stat(path: string): Promise<FileInfo> {\n const file = Bun.file(path);\n const exists = await file.exists();\n if (!exists) {\n throw new FileSystemError(`File not found: ${path}`, { path });\n }\n\n const { stat } = await import(\"node:fs/promises\");\n const stats = await stat(path);\n\n return {\n size: file.size,\n isFile: stats.isFile(),\n isDirectory: stats.isDirectory(),\n isSymlink: stats.isSymbolicLink(),\n mtime: stats.mtime,\n };\n }\n\n async mkdir(path: string, options?: { recursive?: boolean }): Promise<void> {\n const { mkdir } = await import(\"node:fs/promises\");\n await mkdir(path, options);\n }\n\n async remove(path: string, options?: { recursive?: boolean }): Promise<void> {\n const { rm } = await import(\"node:fs/promises\");\n await rm(path, { recursive: options?.recursive, force: true });\n }\n\n async makeTempDir(prefix: string): Promise<string> {\n const { mkdtemp } = await import(\"node:fs/promises\");\n const { join } = await import(\"node:path\");\n const { tmpdir } = await import(\"node:os\");\n return await mkdtemp(join(tmpdir(), prefix));\n }\n\n watch(paths: string | string[], options?: WatchOptions): FileWatcher {\n const pathArray = Array.isArray(paths) ? paths : [paths];\n const recursive = options?.recursive ?? true;\n const signal = options?.signal;\n\n let closed = false;\n const watchers: Array<BunFSWatcher | import(\"node:fs\").FSWatcher> = [];\n const eventQueue: FileChangeEvent[] = [];\n let resolver: ((value: IteratorResult<FileChangeEvent>) => void) | null = null;\n\n const mapBunEventKind = (type: string): FileChangeKind => {\n switch (type) {\n case \"create\":\n return \"create\";\n case \"change\":\n return \"modify\";\n case \"delete\":\n return \"delete\";\n default:\n return \"any\";\n }\n };\n\n const setupWatcher = (path: string) => {\n try {\n if (typeof Bun !== \"undefined\" && Bun.watch) {\n const watcher = Bun.watch(path, {\n recursive,\n onChange: (event: BunWatchEvent) => {\n if (closed || signal?.aborted) return;\n\n enqueueWatchEvent(\n { kind: mapBunEventKind(event.type), paths: [event.path] },\n eventQueue,\n () => resolver,\n (r) => {\n resolver = r;\n },\n );\n },\n });\n watchers.push(watcher);\n } else {\n throw toError(createError({\n type: \"not_supported\",\n message: \"Bun.watch is not available in this environment\",\n feature: \"Bun.watch\",\n }));\n }\n } catch (error) {\n serverLogger.error(`Failed to watch ${path}:`, error);\n }\n };\n\n Promise.all(pathArray.map(setupWatcher)).catch((error) => {\n serverLogger.error(\"Failed to setup Bun file watchers:\", error);\n });\n\n const iterator = createWatcherIterator(\n eventQueue,\n () => resolver,\n (r) => {\n resolver = r;\n },\n () => closed,\n () => signal?.aborted ?? false,\n );\n\n const cleanup = () => {\n closed = true;\n watchers.forEach((watcher) => {\n try {\n if (\"stop\" in watcher && typeof watcher.stop === \"function\") {\n watcher.stop();\n } else if (\"close\" in watcher && typeof watcher.close === \"function\") {\n watcher.close();\n }\n } catch (error) {\n serverLogger.debug(\"Error closing Bun file watcher during cleanup:\", error);\n }\n });\n if (resolver) {\n resolver({ done: true, value: undefined });\n resolver = null;\n }\n };\n\n if (signal) {\n signal.addEventListener(\"abort\", cleanup);\n }\n\n return createFileWatcher(iterator, cleanup);\n }\n}\n", "import type { EnvironmentAdapter } from \"../base.ts\";\n\nexport class BunEnvironmentAdapter implements EnvironmentAdapter {\n get(key: string): string | undefined {\n return Bun.env[key];\n }\n\n set(key: string, value: string): void {\n Bun.env[key] = value;\n }\n\n toObject(): Record<string, string> {\n return { ...Bun.env };\n }\n}\n", "import type { ServerAdapter, WebSocketUpgrade } from \"../base.ts\";\nimport { createError, toError } from \"../../../core/errors/veryfront-error.ts\";\n\nexport class BunServerAdapter implements ServerAdapter {\n upgradeWebSocket(request: Request): WebSocketUpgrade {\n const success = Bun.upgrade(request);\n\n if (!success) {\n throw toError(createError({\n type: \"network\",\n message: \"Failed to upgrade WebSocket connection\",\n }));\n }\n\n const socket = new BunWebSocket();\n const response = new Response(null, {\n status: 101,\n statusText: \"Switching Protocols\",\n });\n\n return { socket: socket as unknown as WebSocket, response };\n }\n}\n\nexport class BunWebSocket {\n public readyState = 1;\n\n public onopen: ((event: Event) => void) | null = null;\n public onclose: ((event: Event) => void) | null = null;\n public onerror: ((event: Event) => void) | null = null;\n public onmessage: ((event: MessageEvent) => void) | null = null;\n\n static readonly CONNECTING = 0;\n static readonly OPEN = 1;\n static readonly CLOSING = 2;\n static readonly CLOSED = 3;\n\n send(_data: string | ArrayBuffer) {\n throw toError(createError({\n type: \"network\",\n message: \"WebSocket send called on placeholder - use Bun.serve websocket handlers\",\n }));\n }\n\n close(_code?: number, _reason?: string) {\n this.readyState = 3;\n }\n}\n", "import type { ServeOptions, Server } from \"../base.ts\";\nimport type { BunServer as BunServerType } from \"./types.ts\";\nimport { DEFAULT_PORT } from \"@veryfront/config\";\nimport { serverLogger } from \"@veryfront/utils\";\n\nexport class BunServer implements Server {\n constructor(\n private server: BunServerType,\n private hostname: string,\n private port: number,\n ) {}\n\n stop(): Promise<void> {\n this.server.stop();\n return Promise.resolve();\n }\n\n get addr() {\n return { hostname: this.hostname, port: this.port };\n }\n}\n\nexport function createBunServer(\n handler: (request: Request) => Promise<Response> | Response,\n options: ServeOptions = {},\n): Promise<Server> {\n const { port = DEFAULT_PORT, hostname = \"localhost\", onListen } = options;\n\n const server = Bun.serve({\n port,\n hostname,\n async fetch(request: Request) {\n try {\n return await handler(request);\n } catch (error) {\n serverLogger.error(\"Request handler error:\", error);\n return new Response(\"Internal Server Error\", { status: 500 });\n }\n },\n });\n\n onListen?.({ hostname, port });\n\n return Promise.resolve(new BunServer(server, hostname, port));\n}\n", "import type {\n RuntimeAdapter,\n RuntimeCapabilities,\n RuntimeFeatures,\n ServeOptions,\n Server,\n} from \"../base.ts\";\nimport { BunFileSystemAdapter } from \"./filesystem-adapter.ts\";\nimport { BunEnvironmentAdapter } from \"./environment-adapter.ts\";\nimport { BunServerAdapter } from \"./websocket-adapter.ts\";\nimport { createBunServer } from \"./http-server.ts\";\n\nexport class BunAdapter implements RuntimeAdapter {\n readonly id = \"bun\" as const;\n readonly name = \"bun\";\n /** @deprecated Use `id` instead */\n readonly platform = \"bun\" as const;\n\n fs = new BunFileSystemAdapter();\n env = new BunEnvironmentAdapter();\n server = new BunServerAdapter();\n\n readonly capabilities: RuntimeCapabilities = {\n typescript: true,\n jsx: true,\n http2: false, // Bun's HTTP/2 support is experimental\n websocket: true,\n workers: true,\n fileWatching: true,\n shell: true,\n kvStore: false,\n writableFs: true,\n };\n\n /** @deprecated Use `capabilities` instead */\n readonly features: RuntimeFeatures = {\n websocket: true,\n http2: false,\n workers: true,\n jsx: true,\n typescript: true,\n };\n\n serve(\n handler: (request: Request) => Promise<Response> | Response,\n options: ServeOptions = {},\n ): Promise<Server> {\n return createBunServer(handler, options);\n }\n}\n\nexport const bunAdapter = new BunAdapter();\n", "export { BunAdapter, bunAdapter } from \"./adapter.ts\";\nexport { BunFileSystemAdapter } from \"./filesystem-adapter.ts\";\nexport { BunEnvironmentAdapter } from \"./environment-adapter.ts\";\nexport { BunServerAdapter, BunWebSocket } from \"./websocket-adapter.ts\";\nexport { BunServer, createBunServer } from \"./http-server.ts\";\nexport type {\n BunFile,\n BunFSWatcher,\n BunNamespace,\n BunServeOptions,\n BunServer as BunServerType,\n BunWatchEvent,\n BunWatchOptions,\n} from \"./types.ts\";\n", "export {\n BunAdapter,\n bunAdapter,\n BunEnvironmentAdapter,\n BunFileSystemAdapter,\n BunServer,\n BunServerAdapter,\n BunWebSocket,\n createBunServer,\n} from \"./bun/index.ts\";\n\nexport type {\n BunFile,\n BunFSWatcher,\n BunNamespace,\n BunServeOptions,\n BunServerType,\n BunWatchEvent,\n BunWatchOptions,\n} from \"./bun/index.ts\";\n", "import { createError, toError } from \"../../core/errors/veryfront-error.ts\";\nimport type { RuntimeAdapter } from \"./base.ts\";\n\nexport interface MockRuntimeAdapter extends RuntimeAdapter {\n fs: RuntimeAdapter[\"fs\"] & {\n files: Map<string, string>;\n directories: Set<string>;\n };\n}\n\n/**\n * Mock RuntimeAdapter for testing\n *\n * Provides an in-memory filesystem and environment for unit testing.\n * This adapter is useful for testing code that depends on the filesystem\n * without requiring actual file I/O.\n *\n * @example\n * ```typescript\n * const adapter = createMockAdapter();\n * adapter.fs.files.set(\"/project/pages/index.tsx\", \"export default () => <div>Home</div>\");\n * const content = await adapter.fs.readFile(\"/project/pages/index.tsx\");\n * ```\n */\n\n/**\n * Creates a mock RuntimeAdapter for testing\n *\n * The mock adapter uses in-memory Map and Set for file storage:\n * - `files`: Map<string, string> for file contents\n * - `directories`: Set<string> for tracking directories\n * - `envVars`: Map<string, string> for environment variables\n */\nexport function createMockAdapter(): MockRuntimeAdapter {\n const files = new Map<string, string>();\n const directories = new Set<string>();\n const envVars = new Map<string, string>();\n\n return {\n id: \"memory\" as const,\n name: \"mock\",\n /** @deprecated Use `id` instead */\n platform: \"memory\" as const,\n capabilities: {\n typescript: false,\n jsx: false,\n http2: false,\n websocket: false,\n workers: false,\n fileWatching: false,\n shell: false,\n kvStore: false,\n writableFs: true, // In-memory writes work\n },\n serve: (_handler, _options) => {\n return Promise.resolve({\n stop: () => Promise.resolve(),\n addr: { hostname: \"localhost\", port: 8000 },\n });\n },\n fs: {\n files,\n directories,\n readFile: (path: string) => {\n const content = files.get(path);\n if (!content) {\n throw toError(createError({\n type: \"file\",\n message: `File not found: ${path}`,\n }));\n }\n return Promise.resolve(content);\n },\n readFileBytes: (path: string) => {\n const content = files.get(path);\n if (!content) {\n throw toError(createError({\n type: \"file\",\n message: `File not found: ${path}`,\n }));\n }\n return Promise.resolve(new TextEncoder().encode(content));\n },\n writeFile: (path: string, content: string) => {\n files.set(path, content);\n return Promise.resolve();\n },\n exists: (path: string) => {\n if (files.has(path)) return Promise.resolve(true);\n if (directories.has(path)) return Promise.resolve(true);\n for (const filePath of files.keys()) {\n if (filePath.startsWith(path + \"/\")) return Promise.resolve(true);\n }\n return Promise.resolve(false);\n },\n readDir: async function* (path: string) {\n const entries = new Map<string, { isFile: boolean; isDirectory: boolean }>();\n\n for (const filePath of files.keys()) {\n if (filePath.startsWith(path + \"/\")) {\n const relativePath = filePath.slice(path.length + 1);\n const parts = relativePath.split(\"/\");\n const name = parts[0]!;\n\n if (!entries.has(name)) {\n entries.set(name, {\n isFile: parts.length === 1,\n isDirectory: parts.length > 1,\n });\n }\n }\n }\n\n for (const [name, meta] of entries.entries()) {\n yield { name, ...meta, isSymlink: false };\n }\n },\n stat: (path: string) => {\n if (files.has(path)) {\n const content = files.get(path)!;\n return Promise.resolve({\n size: content.length,\n isFile: true,\n isDirectory: false,\n isSymlink: false,\n mtime: new Date(),\n });\n }\n\n if (directories.has(path)) {\n return Promise.resolve({\n size: 0,\n isFile: false,\n isDirectory: true,\n isSymlink: false,\n mtime: new Date(),\n });\n }\n\n for (const filePath of files.keys()) {\n if (filePath.startsWith(path + \"/\")) {\n return Promise.resolve({\n size: 0,\n isFile: false,\n isDirectory: true,\n isSymlink: false,\n mtime: new Date(),\n });\n }\n }\n\n return Promise.reject(new Error(`Path not found: ${path}`));\n },\n mkdir: (_path: string) => Promise.resolve(),\n remove: (_path: string) => Promise.resolve(),\n makeTempDir: (prefix: string) =>\n Promise.resolve(`/tmp/${prefix}-${Math.random().toString(36).slice(2)}`),\n watch: () => ({\n async *[Symbol.asyncIterator]() {\n yield { kind: \"any\", paths: [] };\n },\n close: () => {},\n }),\n },\n env: {\n get: (key: string) => envVars.get(key),\n set: (key: string, value: string) => envVars.set(key, value),\n toObject: () => Object.fromEntries(envVars),\n },\n server: {\n upgradeWebSocket: (_request) => {\n throw new Error(\n \"WebSocket upgrade not available in mock adapter. \" +\n \"The mock adapter is designed for unit testing filesystem and environment operations. \" +\n \"For WebSocket testing, use integration tests with the actual Deno/Node/Bun adapter, \" +\n \"or mock the WebSocket behavior at a higher level in your tests.\",\n );\n },\n },\n features: {\n websocket: false,\n http2: false,\n workers: false,\n jsx: false,\n typescript: false,\n },\n };\n}\n", "/**\n * Adapter Registry - Singleton management for RuntimeAdapter\n *\n * Provides a centralized way to access and configure the runtime adapter.\n * Supports auto-detection, manual configuration, and testing overrides.\n *\n * @example\n * ```ts\n * // Auto-detect and get adapter\n * const adapter = await runtime.get();\n *\n * // Manual configuration (e.g., Cloudflare Workers)\n * await runtime.set(createCloudflareAdapter(env));\n *\n * // Testing override\n * await runtime.set(createMockAdapter());\n * ```\n */\n\nimport type { RuntimeAdapter, RuntimeId } from \"./base.ts\";\n\ntype AdapterLoader = () => Promise<RuntimeAdapter>;\n\n/**\n * Registry for managing RuntimeAdapter singleton\n */\nclass AdapterRegistry {\n private instance: RuntimeAdapter | null = null;\n private initialized = false;\n private loaders: Map<RuntimeId, AdapterLoader> = new Map();\n\n constructor() {\n // Register default loaders (lazy imports to avoid bundling unused adapters)\n this.loaders.set(\"deno\", async () => {\n const { denoAdapter } = await import(\"./deno.ts\");\n return denoAdapter;\n });\n\n this.loaders.set(\"node\", async () => {\n const { nodeAdapter } = await import(\"./node.ts\");\n return nodeAdapter;\n });\n\n this.loaders.set(\"bun\", async () => {\n const { bunAdapter } = await import(\"./bun.ts\");\n return bunAdapter;\n });\n\n // Note: Cloudflare requires manual initialization with env context\n // this.loaders.set(\"cloudflare\", ...) - not auto-detectable\n\n this.loaders.set(\"memory\", async () => {\n const { createMockAdapter } = await import(\"./mock.ts\");\n return createMockAdapter();\n });\n }\n\n /**\n * Get the current adapter, auto-detecting if needed\n */\n async get(): Promise<RuntimeAdapter> {\n if (this.instance) {\n return this.instance;\n }\n\n // Auto-detect runtime\n const runtimeId = this.detectRuntime();\n const loader = this.loaders.get(runtimeId);\n\n if (!loader) {\n throw new Error(\n `Unsupported runtime: ${runtimeId}. ` +\n `Supported runtimes: ${[...this.loaders.keys()].join(\", \")}. ` +\n `For Cloudflare Workers, use runtime.set(createCloudflareAdapter(env)).`,\n );\n }\n\n this.instance = await loader();\n await this.initialize();\n return this.instance;\n }\n\n /**\n * Manually set the adapter (for Cloudflare Workers, testing, etc.)\n */\n async set(adapter: RuntimeAdapter): Promise<void> {\n // Shutdown existing adapter if any\n if (this.instance && this.initialized) {\n await this.instance.shutdown?.();\n }\n\n this.instance = adapter;\n this.initialized = false;\n await this.initialize();\n }\n\n /**\n * Get adapter synchronously (throws if not initialized)\n */\n getSync(): RuntimeAdapter {\n if (!this.instance) {\n throw new Error(\n \"RuntimeAdapter not initialized. Call `await runtime.get()` first, \" +\n \"or use `await runtime.set(adapter)` to configure manually.\",\n );\n }\n return this.instance;\n }\n\n /**\n * Check if adapter is initialized\n */\n isInitialized(): boolean {\n return this.instance !== null && this.initialized;\n }\n\n /**\n * Reset the registry (for testing)\n */\n async reset(): Promise<void> {\n if (this.instance && this.initialized) {\n await this.instance.shutdown?.();\n }\n this.instance = null;\n this.initialized = false;\n }\n\n /**\n * Register a custom adapter loader\n */\n registerLoader(id: RuntimeId, loader: AdapterLoader): void {\n this.loaders.set(id, loader);\n }\n\n /**\n * Detect current runtime\n */\n private detectRuntime(): RuntimeId {\n // Deno\n if (typeof Deno !== \"undefined\" && typeof Deno.version === \"object\") {\n return \"deno\";\n }\n\n // Bun\n if (\"Bun\" in globalThis) {\n return \"bun\";\n }\n\n // Node.js\n if (typeof process !== \"undefined\" && process.versions?.node) {\n return \"node\";\n }\n\n // Cloudflare Workers (detected but requires manual init)\n if (\"caches\" in globalThis && \"WebSocketPair\" in globalThis) {\n throw new Error(\n \"Cloudflare Workers detected but requires manual initialization. \" +\n \"Use: await runtime.set(createCloudflareAdapter(env))\",\n );\n }\n\n throw new Error(\n \"Unsupported runtime detected. Supported runtimes: deno, node, bun. \" +\n \"For Cloudflare Workers, call runtime.set(createCloudflareAdapter(env)).\",\n );\n }\n\n /**\n * Initialize the adapter\n */\n private async initialize(): Promise<void> {\n if (!this.instance || this.initialized) {\n return;\n }\n\n await this.instance.initialize?.();\n this.initialized = true;\n }\n}\n\n/**\n * Global runtime adapter registry\n *\n * @example\n * ```ts\n * import { runtime } from \"@veryfront/platform/adapters/registry.ts\";\n *\n * // Get adapter (auto-detects runtime)\n * const adapter = await runtime.get();\n *\n * // Use filesystem\n * const content = await adapter.fs.readFile(\"./config.json\");\n * ```\n */\nexport const runtime = new AdapterRegistry();\n\n// Re-export for convenience\nexport type { RuntimeAdapter, RuntimeId } from \"./base.ts\";\n", "import { logger } from \"@veryfront/utils\";\nimport type { RuntimeAdapter, RuntimeId } from \"./base.ts\";\nimport { createError, toError } from \"../../core/errors/veryfront-error.ts\";\n\n// Re-export the registry for convenient access\nexport { runtime } from \"./registry.ts\";\n\ninterface DenoGlobal {\n Deno: {\n version: { deno: string };\n [key: string]: unknown;\n };\n}\n\ninterface BunGlobal {\n Bun: {\n version: string;\n [key: string]: unknown;\n };\n}\n\ninterface CloudflareGlobal {\n caches: unknown;\n WebSocketPair: unknown;\n}\n\nfunction isDeno(global: typeof globalThis): global is typeof globalThis & DenoGlobal {\n return \"Deno\" in global && typeof (global as DenoGlobal).Deno === \"object\";\n}\n\nfunction isBun(global: typeof globalThis): global is typeof globalThis & BunGlobal {\n return \"Bun\" in global && typeof (global as BunGlobal).Bun === \"object\";\n}\n\nfunction isCloudflare(global: typeof globalThis): global is typeof globalThis & CloudflareGlobal {\n return \"caches\" in global && \"WebSocketPair\" in global;\n}\n\n/**\n * Detect the current runtime environment\n * @returns Runtime identifier\n */\nexport function detectRuntime(): RuntimeId | \"unknown\" {\n if (isDeno(globalThis)) {\n return \"deno\";\n }\n\n if (isBun(globalThis)) {\n return \"bun\";\n }\n\n const globalProcess = (globalThis as { process?: { versions?: { node?: string } } }).process;\n if (globalProcess?.versions?.node) {\n return \"node\";\n }\n\n if (isCloudflare(globalThis)) {\n return \"cloudflare\";\n }\n\n return \"unknown\";\n}\n\n/**\n * Get the runtime adapter for the current environment\n *\n * @deprecated Use `runtime.get()` from `./registry.ts` instead for singleton management\n *\n * @example\n * ```ts\n * // Old way (deprecated)\n * const adapter = await getAdapter();\n *\n * // New way (recommended)\n * import { runtime } from \"@veryfront/platform/adapters/registry.ts\";\n * const adapter = await runtime.get();\n * ```\n */\nexport async function getAdapter(): Promise<RuntimeAdapter> {\n const runtimeId = detectRuntime();\n\n switch (runtimeId) {\n case \"deno\": {\n const { denoAdapter } = await import(\"./deno.ts\");\n return denoAdapter;\n }\n\n case \"bun\": {\n const { bunAdapter } = await import(\"./bun.ts\");\n return bunAdapter;\n }\n\n case \"node\": {\n const { nodeAdapter } = await import(\"./node.ts\");\n return nodeAdapter;\n }\n\n case \"cloudflare\": {\n const errorMsg = \"Cloudflare adapter requires manual initialization with environment. \" +\n \"Please use createCloudflareAdapter() with your environment context.\";\n logger.error(\"[Adapter Detection]\", errorMsg);\n throw toError(createError({\n type: \"config\",\n message: errorMsg,\n }));\n }\n\n default: {\n const supportedRuntimes = [\"deno\", \"bun\", \"node\", \"cloudflare\"];\n const errorMsg = `Unsupported runtime: ${runtimeId}. Supported runtimes: ${\n supportedRuntimes.join(\", \")\n }`;\n logger.error(\"[Adapter Detection]\", errorMsg);\n throw toError(createError({\n type: \"config\",\n message: errorMsg,\n }));\n }\n }\n}\n\nexport { denoAdapter } from \"./deno.ts\";\nexport { nodeAdapter } from \"./node.ts\";\nexport { bunAdapter } from \"./bun.ts\";\n\nexport type {\n EnvironmentAdapter,\n FileSystemAdapter,\n RuntimeAdapter,\n RuntimeCapabilities,\n RuntimeFeatures,\n RuntimeId,\n} from \"./base.ts\";\n", "/**\n * Veryfront - Main Package\n *\n * This is the core API for building Veryfront applications.\n *\n * ## Subpath Exports (Advanced Use)\n * - `veryfront/server` \u2192 Server APIs (startUniversalServer, createDevServer)\n * - `veryfront/middleware` \u2192 Middleware system\n * - `veryfront/components` \u2192 All React components (including OptimizedImage)\n * - `veryfront/data` \u2192 Data fetching utilities\n * - `veryfront/config` \u2192 Configuration utilities\n */\n\n// ============================================================================\n// React Components (Most Common)\n// ============================================================================\n\nexport { Link } from \"@veryfront/components\";\nexport type { LinkProps } from \"@veryfront/components\";\n\nexport { Head } from \"@veryfront/components\";\n\nexport { MDXProvider, useMDXComponents } from \"@veryfront/components\";\nexport type { MDXProviderProps } from \"@veryfront/components\";\n\n// Optimized Images\nexport {\n OptimizedBackgroundImage,\n OptimizedImage,\n SimpleOptimizedImage,\n} from \"@veryfront/components\";\nexport type { OptimizedImageProps } from \"@veryfront/components\";\n\n// ============================================================================\n// Data Fetching\n// ============================================================================\n\nexport type {\n DataContext,\n InferGetServerDataProps,\n PageWithData,\n StaticPathsResult,\n} from \"@veryfront/data\";\n\n// Data helpers (notFound/redirect for getServerData)\nexport { notFound, redirect } from \"@veryfront/data\";\n\n// ============================================================================\n// API Routes\n// ============================================================================\n\nexport type { APIContext, APIHandler, APIResponse, APIRoute } from \"@veryfront/routing\";\n\n// Response helpers\nexport {\n badRequest,\n forbidden,\n json,\n notFound as apiNotFound,\n redirect as apiRedirect,\n serverError,\n unauthorized,\n} from \"@veryfront/routing\";\n\n// Input validation (for API routes)\nexport {\n CommonSchemas,\n createValidatedHandler,\n parseFormData,\n parseJsonBody,\n parseQueryParams,\n sanitizeData,\n type ValidatedHandlerConfig,\n type ValidatedHandlerFunction,\n ValidationError,\n} from \"@veryfront/security\";\n\n// ============================================================================\n// Configuration\n// ============================================================================\n\nexport { defineConfig } from \"@veryfront/config\";\nexport type { VeryfrontConfig } from \"@veryfront/config\";\n\n// ============================================================================\n// Common Types\n// ============================================================================\n\nexport type { ComponentProps, MDXFrontmatter, PageContext } from \"@veryfront/types\";\n", "export { AppWrapper } from \"./AppWrapper.tsx\";\nexport type { AppWrapperProps } from \"./AppWrapper.tsx\";\n\nexport { Head } from \"./Head.tsx\";\n\nexport { LayoutComponent } from \"./LayoutComponent.tsx\";\nexport type { LayoutComponentProps } from \"./LayoutComponent.tsx\";\n\nexport { Link } from \"./Link.tsx\";\nexport type { LinkProps } from \"./Link.tsx\";\n\nexport { MDXProvider, useMDXComponents } from \"./MDXProvider.tsx\";\nexport type { MDXProviderProps } from \"./MDXProvider.tsx\";\n\nexport { ProviderComponent } from \"./ProviderComponent.tsx\";\nexport type { ProviderComponentProps } from \"./ProviderComponent.tsx\";\n\nexport * from \"./optimized-image/index.ts\";\n", "import type * as React from \"react\";\nimport type { MDXComponents, PageContext as TypedPageContext } from \"@veryfront/types\";\nimport type { MdxBundle } from \"./LayoutComponent.tsx\";\nimport { LayoutComponent } from \"./LayoutComponent.tsx\";\nimport { ProviderComponent } from \"./ProviderComponent.tsx\";\n\nexport interface AppWrapperProps {\n children: React.ReactNode;\n providers?: MdxBundle[];\n layout?: MdxBundle;\n components?: MDXComponents;\n mode?: string;\n studioEnabled?: boolean;\n pageContext?: TypedPageContext;\n}\n\nexport function AppWrapper({\n children,\n providers = [],\n layout,\n components = {},\n mode: _mode,\n studioEnabled: _studioEnabled,\n pageContext,\n}: AppWrapperProps) {\n let content = children;\n\n if (layout) {\n content = (\n <LayoutComponent mdxBundle={layout} components={components} pageContext={pageContext}>\n {content}\n </LayoutComponent>\n );\n }\n\n for (const provider of [...providers].reverse()) {\n content = (\n <ProviderComponent mdxBundle={provider} components={components}>\n {content}\n </ProviderComponent>\n );\n }\n\n return content;\n}\n", "import type React from \"react\";\nimport { useMemo, useRef } from \"react\";\nimport { mdxRenderer } from \"@veryfront/transforms/mdx/index.ts\";\nimport type { MdxBundle, MDXComponents, PageContext as TypedPageContext } from \"@veryfront/types\";\nimport { rendererLogger as logger } from \"@veryfront/utils\";\n\nexport type { MdxBundle } from \"@veryfront/types\";\n\nexport interface LayoutComponentProps {\n mdxBundle: MdxBundle;\n children: React.ReactNode;\n components?: MDXComponents;\n pageContext?: TypedPageContext;\n}\n\nfunction useStableObject<T>(obj: T): T {\n const ref = useRef(obj);\n const serialized = JSON.stringify(obj);\n const prevSerialized = useRef(serialized);\n\n if (prevSerialized.current !== serialized) {\n ref.current = obj;\n prevSerialized.current = serialized;\n }\n\n return ref.current;\n}\n\nexport function LayoutComponent({\n mdxBundle,\n children,\n components = {},\n pageContext,\n}: LayoutComponentProps) {\n const stableFrontmatter = useStableObject(mdxBundle.frontmatter);\n const stablePageContext = useStableObject(pageContext);\n\n const element = useMemo(() => {\n try {\n return mdxRenderer.render(mdxBundle.compiledCode, {\n components,\n frontmatter: { ...(stableFrontmatter || {}), pageContext: stablePageContext },\n globals: mdxBundle.globals,\n extractLayout: true,\n children,\n });\n } catch (error) {\n logger.error(\"[LayoutComponent] Render failed:\", error);\n return <>{children}</>;\n }\n }, [\n mdxBundle.compiledCode,\n stableFrontmatter,\n components,\n children,\n stablePageContext,\n mdxBundle.globals,\n ]);\n\n if (!element) return <>{children}</>;\n return element as React.ReactElement;\n}\n", "import { rendererLogger as logger } from \"@veryfront/utils\";\nimport { LRUCache } from \"@veryfront/utils/lru-wrapper.ts\";\nimport React from \"react\";\nimport { MDX_RENDERER_MAX_ENTRIES, MDX_RENDERER_TTL_MS } from \"@veryfront/utils/constants/cache.ts\";\nimport { type ESMLoaderContext, loadModuleESM } from \"./esm-module-loader.ts\";\nimport {\n executeModule as _executeModule,\n selectComponent as _selectComponent,\n} from \"./module-executor.ts\";\nimport { type ParsedMDX, parseMDXCode } from \"./parser.ts\";\nimport type { MDXComponents, MDXFrontmatter, MDXGlobals, MDXModule } from \"./types.ts\";\n\nexport interface MDXRenderOptions {\n components?: MDXComponents;\n frontmatter?: MDXFrontmatter;\n globals?: MDXGlobals;\n extractLayout?: boolean;\n children?: React.ReactNode;\n}\n\nexport class MDXRenderer {\n private esmCacheDir?: string;\n private moduleCache: LRUCache<string, MDXModule> = new LRUCache({\n maxEntries: MDX_RENDERER_MAX_ENTRIES,\n ttlMs: MDX_RENDERER_TTL_MS,\n });\n\n constructor() {\n }\n\n async clearCache() {\n this.moduleCache.destroy();\n\n if (this.esmCacheDir) {\n try {\n const { getAdapter } = await import(\"@veryfront/platform/adapters/detect.ts\");\n const adapter = await getAdapter();\n await adapter.fs.remove(this.esmCacheDir, { recursive: true });\n } catch (_error) {\n void _error;\n }\n this.esmCacheDir = undefined;\n }\n }\n\n async loadModuleESM(compiledProgramCode: string): Promise<MDXModule> {\n const context: ESMLoaderContext = {\n esmCacheDir: this.esmCacheDir,\n moduleCache: this.moduleCache,\n };\n const result = await loadModuleESM(compiledProgramCode, context);\n this.esmCacheDir = context.esmCacheDir;\n return result;\n }\n\n render(\n _compiledCode: string,\n _options: MDXRenderOptions = {},\n ): React.ReactElement {\n logger.error(\n \"[MDX] Synchronous render() called but string-based factories are disabled for security. \" +\n \"Please use: await mdxRenderer.loadModuleESM(compiledCode) instead.\",\n );\n\n return React.createElement(\n \"div\",\n {\n style: {\n padding: \"1rem\",\n backgroundColor: \"#fff3cd\",\n border: \"1px solid #ffc107\",\n borderRadius: \"0.375rem\",\n color: \"#856404\",\n },\n },\n React.createElement(\"strong\", {}, \"Migration Required: \"),\n \"Synchronous render() is no longer supported for security reasons. \",\n React.createElement(\"br\"),\n \"Please update to: \",\n React.createElement(\"code\", {}, \"await mdxRenderer.loadModuleESM(compiledCode)\"),\n );\n }\n\n private parseMDXCode(compiledCode: string): ParsedMDX {\n return parseMDXCode(compiledCode);\n }\n}\n\nlet _mdxRendererInstance: MDXRenderer | undefined;\n\nfunction getMDXRendererInstance(): MDXRenderer {\n if (!_mdxRendererInstance) {\n _mdxRendererInstance = new MDXRenderer();\n }\n return _mdxRendererInstance;\n}\n\nexport const mdxRenderer = new Proxy({} as MDXRenderer, {\n get(_target, prop) {\n const instance = getMDXRendererInstance();\n const value = instance[prop as keyof MDXRenderer];\n if (typeof value === \"function\") {\n return value.bind(instance);\n }\n return value;\n },\n set(_target, prop, value) {\n const instance = getMDXRendererInstance();\n (instance as any)[prop] = value;\n return true;\n },\n has(_target, prop) {\n const instance = getMDXRendererInstance();\n return prop in instance;\n },\n ownKeys(_target) {\n const instance = getMDXRendererInstance();\n return Reflect.ownKeys(instance);\n },\n getOwnPropertyDescriptor(_target, prop) {\n const instance = getMDXRendererInstance();\n return Reflect.getOwnPropertyDescriptor(instance, prop);\n },\n});\n\nexport async function clearMDXRendererCache() {\n await getMDXRendererInstance().clearCache();\n}\n\nexport {\n MDXCacheAdapter,\n type MDXCacheAdapterOptions,\n type MDXCompilationResult,\n} from \"./mdx-cache-adapter.ts\";\n", "import { LRUCacheAdapter } from \"./cache/stores/memory/lru-cache-adapter.ts\";\nimport type { LRUCacheOptions } from \"./cache/stores/memory/types.ts\";\nimport { DEFAULT_LRU_MAX_ENTRIES } from \"@veryfront/utils\";\nimport { getEnv } from \"../../platform/compat/process.ts\";\n\nexport interface LRUOptions {\n maxEntries?: number;\n ttlMs?: number;\n cleanupIntervalMs?: number;\n}\n\nexport class LRUCache<K, V> {\n private adapter: LRUCacheAdapter;\n private cleanupTimer?: ReturnType<typeof setInterval>;\n private cleanupIntervalMs: number;\n private ttlMs?: number;\n\n constructor(options: LRUOptions = {}) {\n const adapterOptions: LRUCacheOptions = {\n maxEntries: options.maxEntries ?? DEFAULT_LRU_MAX_ENTRIES,\n ttlMs: options.ttlMs,\n };\n\n this.adapter = new LRUCacheAdapter(adapterOptions);\n this.ttlMs = options.ttlMs;\n this.cleanupIntervalMs = options.cleanupIntervalMs ?? 60000;\n\n if (this.ttlMs && this.ttlMs > 0) {\n this.startPeriodicCleanup();\n }\n }\n\n private startPeriodicCleanup(): void {\n if (shouldDisableInterval()) {\n return;\n }\n if (this.cleanupTimer) {\n clearInterval(this.cleanupTimer);\n }\n\n const timer = setInterval(() => {\n this.adapter.cleanupExpired();\n }, this.cleanupIntervalMs);\n this.cleanupTimer = timer;\n }\n\n private toStringKey(key: K): string {\n if (typeof key === \"string\") {\n return key;\n }\n return String(key);\n }\n\n get size(): number {\n return this.adapter.getStats().entries;\n }\n\n has(key: K): boolean {\n return this.adapter.get(this.toStringKey(key)) !== undefined;\n }\n\n get(key: K): V | undefined {\n return this.adapter.get<V>(this.toStringKey(key));\n }\n\n set(key: K, value: V): void {\n this.adapter.set(this.toStringKey(key), value);\n }\n\n delete(key: K): boolean {\n const stringKey = this.toStringKey(key);\n const had = this.adapter.get(stringKey) !== undefined;\n this.adapter.delete(stringKey);\n return had;\n }\n\n clear(): void {\n this.adapter.clear();\n }\n\n cleanup(): void {\n this.adapter.cleanupExpired();\n }\n\n destroy(): void {\n if (this.cleanupTimer) {\n clearInterval(this.cleanupTimer);\n this.cleanupTimer = undefined;\n }\n\n this.adapter.clear();\n }\n\n keys(): IterableIterator<K> {\n return this.adapter.keys() as IterableIterator<K>;\n }\n}\n\nfunction shouldDisableInterval(): boolean {\n if ((globalThis as Record<string, unknown>).__vfDisableLruInterval === true) {\n return true;\n }\n try {\n return getEnv(\"VF_DISABLE_LRU_INTERVAL\") === \"1\";\n } catch {\n return false;\n }\n}\n", "import type { CacheAdapter, LRUCacheOptions, LRUCacheStats, LRUEntry } from \"./types.ts\";\nimport { LRUNode } from \"./lru-node.ts\";\nimport { LRUListManager } from \"./lru-list-manager.ts\";\nimport { EvictionManager } from \"../../eviction/eviction-manager.ts\";\nimport { EntryManager } from \"./entry-manager.ts\";\n\nfunction defaultSizeEstimator(value: unknown): number {\n if (value === null || value === undefined) return 0;\n if (typeof value === \"string\") return value.length * 2;\n if (typeof value === \"number\" || typeof value === \"bigint\") return 8;\n if (typeof value === \"boolean\") return 4;\n if (value instanceof Uint8Array || ArrayBuffer.isView(value)) return value.byteLength;\n if (value instanceof ArrayBuffer) return value.byteLength;\n if (typeof Blob !== \"undefined\" && value instanceof Blob) return value.size;\n\n try {\n return JSON.stringify(value).length * 2;\n } catch {\n return 0;\n }\n}\n\nexport class LRUCacheAdapter implements CacheAdapter {\n private readonly store = new Map<string, LRUNode<unknown>>();\n private readonly tagIndex = new Map<string, Set<string>>();\n private readonly listManager = new LRUListManager<unknown>();\n private readonly evictionManager: EvictionManager<LRUEntry<unknown>>;\n private readonly entryManager: EntryManager;\n private currentSize = 0;\n private readonly maxEntries: number;\n private readonly maxSizeBytes: number;\n private readonly defaultTtlMs?: number;\n private readonly onEvict?: (key: string, value: unknown) => void;\n\n constructor(options: LRUCacheOptions = {}) {\n this.maxEntries = options.maxEntries || 1000;\n this.maxSizeBytes = options.maxSizeBytes || 50 * 1024 * 1024; // 50MB default\n this.defaultTtlMs = options.ttlMs;\n this.onEvict = options.onEvict;\n\n const estimateSizeOf = options.estimateSizeOf || defaultSizeEstimator;\n\n this.evictionManager = new EvictionManager({\n onEvict: this.onEvict,\n loggerContext: \"MemoryCache\",\n });\n this.entryManager = new EntryManager(estimateSizeOf);\n }\n\n get<T>(key: string): T | undefined {\n const node = this.store.get(key);\n if (!node) return undefined;\n\n if (this.evictionManager.isExpired(node.entry)) {\n this.delete(key);\n return undefined;\n }\n\n this.listManager.moveToFront(node);\n return node.entry.value as T;\n }\n\n set<T>(key: string, value: T, ttlMs?: number, tags?: string[]): void {\n const existingNode = this.store.get(key);\n\n if (existingNode) {\n const sizeDelta = this.entryManager.updateExistingEntry(\n existingNode,\n value,\n ttlMs,\n tags,\n this.defaultTtlMs,\n this.listManager,\n this.tagIndex,\n key,\n );\n this.currentSize += sizeDelta;\n } else {\n const [_node, size] = this.entryManager.createNewEntry(\n key,\n value,\n ttlMs,\n tags,\n this.defaultTtlMs,\n this.listManager,\n this.store,\n );\n this.currentSize += size;\n }\n\n if (tags && tags.length > 0) {\n this.entryManager.updateTagIndex(tags, key, this.tagIndex);\n }\n\n this.currentSize = this.evictionManager.enforceMemoryLimits(\n this.listManager,\n this.store,\n this.tagIndex,\n this.currentSize,\n this.maxEntries,\n this.maxSizeBytes,\n );\n }\n\n delete(key: string): void {\n const node = this.store.get(key);\n if (!node) return;\n\n this.listManager.removeNode(node);\n this.store.delete(key);\n this.currentSize -= node.entry.size;\n\n if (node.entry.tags) {\n this.entryManager.cleanupTags(node.entry.tags, key, this.tagIndex);\n }\n\n if (this.onEvict) {\n this.onEvict(key, node.entry.value);\n }\n }\n\n invalidateTag(tag: string): number {\n const set = this.tagIndex.get(tag);\n if (!set) return 0;\n\n let count = 0;\n for (const key of set) {\n this.delete(key);\n count++;\n }\n this.tagIndex.delete(tag);\n return count;\n }\n\n clear(): void {\n if (this.onEvict) {\n for (const [key, node] of this.store) {\n this.onEvict(key, node.entry.value);\n }\n }\n\n this.store.clear();\n this.tagIndex.clear();\n this.listManager.clear();\n this.currentSize = 0;\n }\n\n getStats(): LRUCacheStats {\n return {\n entries: this.store.size,\n sizeBytes: this.currentSize,\n maxEntries: this.maxEntries,\n maxSizeBytes: this.maxSizeBytes,\n tags: this.tagIndex.size,\n };\n }\n\n cleanupExpired(): number {\n const now = Date.now();\n let cleaned = 0;\n\n for (const [key, node] of this.store) {\n if (typeof node.entry.expiry === \"number\" && now > node.entry.expiry) {\n this.delete(key);\n cleaned++;\n }\n }\n\n return cleaned;\n }\n\n keys(): IterableIterator<string> {\n return this.store.keys();\n }\n\n has(key: string): boolean {\n return this.get(key) !== undefined;\n }\n}\n", "import type { LRUNode } from \"./lru-node.ts\";\n\nexport class LRUListManager<T> {\n private head: LRUNode<T> | null = null;\n private tail: LRUNode<T> | null = null;\n\n getHead(): LRUNode<T> | null {\n return this.head;\n }\n\n getTail(): LRUNode<T> | null {\n return this.tail;\n }\n\n moveToFront(node: LRUNode<T>): void {\n if (node === this.head) {\n node.entry.lastAccessed = Date.now();\n return;\n }\n\n this.removeNode(node);\n\n this.addToFront(node);\n }\n\n addToFront(node: LRUNode<T>): void {\n node.next = this.head;\n node.prev = null;\n if (this.head) {\n this.head.prev = node;\n }\n this.head = node;\n if (!this.tail) {\n this.tail = node;\n }\n node.entry.lastAccessed = Date.now();\n }\n\n removeNode(node: LRUNode<T>): void {\n if (node.prev) {\n node.prev.next = node.next;\n }\n if (node.next) {\n node.next.prev = node.prev;\n }\n if (node === this.head) {\n this.head = node.next;\n }\n if (node === this.tail) {\n this.tail = node.prev;\n }\n }\n\n clear(): void {\n this.head = null;\n this.tail = null;\n }\n}\n", "export interface EvictableEntry {\n size: number;\n timestamp?: number;\n expiry?: number;\n value?: unknown;\n tags?: string[];\n}\n\nexport interface LRUTrackerInterface {\n getLRU(): string | undefined;\n remove(key: string): void;\n}\n\nexport interface LRUNodeInterface<T> {\n key: string;\n entry: T;\n prev: LRUNodeInterface<T> | null;\n next: LRUNodeInterface<T> | null;\n}\n\nexport interface LRUListManagerInterface<T> {\n getTail(): LRUNodeInterface<T> | null;\n removeNode(node: LRUNodeInterface<T>): void;\n}\n\nexport interface EvictionManagerOptions {\n onEvict?: (key: string, value: unknown) => void;\n loggerContext?: string;\n}\n\nexport class EvictionManager<TEntry extends EvictableEntry> {\n private readonly onEvict?: (key: string, value: unknown) => void;\n\n constructor(options: EvictionManagerOptions = {}) {\n this.onEvict = options.onEvict;\n }\n\n evictIfNeeded(\n cache: Map<string, TEntry>,\n lruTracker: LRUTrackerInterface,\n newEntrySize: number,\n maxSize: number,\n maxMemory: number,\n ): void {\n while (cache.size >= maxSize) {\n this.evictLRU(cache, lruTracker);\n }\n\n let memoryUsed = Array.from(cache.values()).reduce((sum, entry) => sum + entry.size, 0);\n\n while (memoryUsed + newEntrySize > maxMemory && cache.size > 0) {\n const evictedSize = this.evictLRU(cache, lruTracker);\n memoryUsed -= evictedSize;\n }\n }\n\n evictLRU(cache: Map<string, TEntry>, lruTracker: LRUTrackerInterface): number {\n const keyToEvict = lruTracker.getLRU();\n\n if (!keyToEvict) {\n return 0;\n }\n\n const entry = cache.get(keyToEvict);\n const size = entry?.size || 0;\n const value = entry?.value;\n\n cache.delete(keyToEvict);\n lruTracker.remove(keyToEvict);\n\n if (this.onEvict && entry) {\n this.onEvict(keyToEvict, value);\n }\n\n return size;\n }\n\n evictLRUFromList<T extends TEntry>(\n listManager: LRUListManagerInterface<T>,\n store: Map<string, LRUNodeInterface<T>>,\n tagIndex: Map<string, Set<string>>,\n currentSize: number,\n ): number {\n const tail = listManager.getTail();\n if (!tail) return currentSize;\n\n const node = tail;\n listManager.removeNode(node);\n store.delete(node.key);\n const newSize = currentSize - node.entry.size;\n\n if (node.entry.tags) {\n this.cleanupTags(node.entry.tags, node.key, tagIndex);\n }\n\n if (this.onEvict) {\n this.onEvict(node.key, node.entry.value);\n }\n\n return newSize;\n }\n\n enforceMemoryLimits<T extends TEntry>(\n listManager: LRUListManagerInterface<T>,\n store: Map<string, LRUNodeInterface<T>>,\n tagIndex: Map<string, Set<string>>,\n currentSize: number,\n maxEntries: number,\n maxSizeBytes: number,\n ): number {\n let size = currentSize;\n while ((store.size > maxEntries || size > maxSizeBytes) && listManager.getTail()) {\n size = this.evictLRUFromList(listManager, store, tagIndex, size);\n }\n return size;\n }\n\n private cleanupTags(tags: string[], key: string, tagIndex: Map<string, Set<string>>): void {\n for (const tag of tags) {\n const set = tagIndex.get(tag);\n if (set) {\n set.delete(key);\n if (set.size === 0) {\n tagIndex.delete(tag);\n }\n }\n }\n }\n\n evictExpired(cache: Map<string, TEntry>, lruTracker: LRUTrackerInterface, ttl: number): number {\n const now = Date.now();\n let evicted = 0;\n\n for (const [key, entry] of cache.entries()) {\n if (this.isExpired(entry, ttl, now)) {\n cache.delete(key);\n lruTracker.remove(key);\n evicted++;\n }\n }\n\n return evicted;\n }\n\n isExpired(entry: TEntry, ttl?: number, now: number = Date.now()): boolean {\n if (typeof entry.expiry === \"number\") {\n return now > entry.expiry;\n }\n\n if (typeof entry.timestamp === \"number\" && typeof ttl === \"number\") {\n const age = now - entry.timestamp;\n return age > ttl;\n }\n\n return false;\n }\n}\n", "import type { LRUEntry } from \"./types.ts\";\nimport { LRUNode } from \"./lru-node.ts\";\nimport type { LRUListManager } from \"./lru-list-manager.ts\";\n\nexport class EntryManager {\n constructor(\n private readonly estimateSizeOf: (value: unknown) => number,\n ) {}\n\n updateExistingEntry<T>(\n node: LRUNode<unknown>,\n value: T,\n ttlMs: number | undefined,\n tags: string[] | undefined,\n defaultTtlMs: number | undefined,\n listManager: LRUListManager<unknown>,\n tagIndex: Map<string, Set<string>>,\n key: string,\n ): number {\n const oldSize = node.entry.size;\n const newSize = this.estimateSizeOf(value);\n const expiry = this.calculateExpiry(ttlMs, defaultTtlMs);\n\n if (node.entry.tags) {\n this.cleanupTags(node.entry.tags, key, tagIndex);\n }\n\n node.entry = {\n value,\n size: newSize,\n expiry,\n tags,\n lastAccessed: Date.now(),\n };\n\n listManager.moveToFront(node);\n\n return newSize - oldSize;\n }\n\n createNewEntry<T>(\n key: string,\n value: T,\n ttlMs: number | undefined,\n tags: string[] | undefined,\n defaultTtlMs: number | undefined,\n listManager: LRUListManager<unknown>,\n store: Map<string, LRUNode<unknown>>,\n ): [LRUNode<unknown>, number] {\n const size = this.estimateSizeOf(value);\n const expiry = this.calculateExpiry(ttlMs, defaultTtlMs);\n\n const entry: LRUEntry<unknown> = {\n value,\n size,\n expiry,\n tags,\n lastAccessed: Date.now(),\n };\n\n const node = new LRUNode(key, entry);\n store.set(key, node);\n listManager.addToFront(node);\n\n return [node, size];\n }\n\n updateTagIndex(\n tags: string[],\n key: string,\n tagIndex: Map<string, Set<string>>,\n ): void {\n for (const tag of tags) {\n if (!tagIndex.has(tag)) {\n tagIndex.set(tag, new Set());\n }\n tagIndex.get(tag)?.add(key);\n }\n }\n\n cleanupTags(\n tags: string[],\n key: string,\n tagIndex: Map<string, Set<string>>,\n ): void {\n for (const tag of tags) {\n const set = tagIndex.get(tag);\n if (set) {\n set.delete(key);\n if (set.size === 0) {\n tagIndex.delete(tag);\n }\n }\n }\n }\n\n private calculateExpiry(\n ttlMs: number | undefined,\n defaultTtlMs: number | undefined,\n ): number | undefined {\n if (typeof ttlMs === \"number\") {\n return Date.now() + ttlMs;\n }\n if (defaultTtlMs) {\n return Date.now() + defaultTtlMs;\n }\n return undefined;\n }\n}\n", "import type { LRUEntry } from \"./types.ts\";\n\nexport class LRUNode<T> {\n constructor(\n public key: string,\n public entry: LRUEntry<T>,\n public prev: LRUNode<T> | null = null,\n public next: LRUNode<T> | null = null,\n ) {}\n}\n", "import { rendererLogger as logger } from \"@veryfront/utils\";\nimport { LRUCache } from \"@veryfront/utils/lru-wrapper.ts\";\nimport React from \"react\";\nimport { getCacheNamespace } from \"@veryfront/utils/cache/keys/namespace.ts\";\nimport {\n getDefaultImportMap,\n transformImportsWithMap,\n} from \"@veryfront/modules/import-map/index.ts\";\nimport type { MDXFrontmatter, MDXModule } from \"./types.ts\";\nimport { join } from \"https://deno.land/std@0.220.0/path/mod.ts\";\nimport { isDeno, isNode } from \"../../../platform/compat/runtime.ts\";\nimport { cwd } from \"../../../platform/compat/process.ts\";\n\n// True Node.js runtime (not Deno with Node.js compat)\nconst IS_TRUE_NODE = isNode && !isDeno;\n\n// Constants\nconst LOG_PREFIX_MDX_LOADER = \"[mdx-loader]\";\nconst LOG_PREFIX_MDX_RENDERER = \"[mdx-renderer]\";\nconst JSX_IMPORT_PATTERN = /import\\s+([^'\"]+)\\s+from\\s+['\"]file:\\/\\/([^'\"]+\\.(jsx|tsx))['\"];?/g;\nconst REACT_IMPORT_PATTERN = /import\\s+.*React.*\\s+from\\s+['\"]react['\"]/;\nconst HTTP_IMPORT_PATTERN = /['\"]https?:\\/\\/[^'\"]+['\"]/;\nconst ESBUILD_JSX_FACTORY = \"React.createElement\";\nconst ESBUILD_JSX_FRAGMENT = \"React.Fragment\";\nconst HTTP_MODULE_FETCH_TIMEOUT_MS = 30000;\n\n// Cache for resolved react package paths (Node.js only)\nconst _resolvedPaths: Record<string, string | null> = {};\n\n/**\n * Resolve a Node.js package path using require.resolve\n * Returns null if resolution fails\n */\nasync function resolveNodePackage(packageSpec: string): Promise<string | null> {\n if (!IS_TRUE_NODE) return null;\n if (packageSpec in _resolvedPaths) return _resolvedPaths[packageSpec]!;\n\n try {\n // Use Node.js createRequire to resolve the package from THIS file's location\n // This ensures react is found from veryfront's node_modules, not the project's\n const { createRequire } = await import(\"node:module\");\n const require = createRequire(import.meta.url);\n const resolved = require.resolve(packageSpec);\n _resolvedPaths[packageSpec] = resolved;\n return resolved;\n } catch {\n _resolvedPaths[packageSpec] = null;\n return null;\n }\n}\n\n/**\n * Transform react imports to absolute file:// paths for Node.js.\n * This is needed because MDX modules are cached in arbitrary directories\n * (like temp dirs) where Node.js cannot resolve bare 'react' imports.\n */\nasync function transformReactImportsToAbsolute(code: string): Promise<string> {\n if (!IS_TRUE_NODE) return code;\n\n // Resolve the actual react package paths\n const reactPath = await resolveNodePackage(\"react\");\n const reactJsxPath = await resolveNodePackage(\"react/jsx-runtime\");\n const reactJsxDevPath = await resolveNodePackage(\"react/jsx-dev-runtime\");\n const reactDomPath = await resolveNodePackage(\"react-dom\");\n\n let result = code;\n\n // Replace bare react imports with absolute file:// paths\n if (reactJsxPath) {\n result = result.replace(\n /from\\s+['\"]react\\/jsx-runtime['\"]/g,\n `from \"file://${reactJsxPath}\"`,\n );\n }\n if (reactJsxDevPath) {\n result = result.replace(\n /from\\s+['\"]react\\/jsx-dev-runtime['\"]/g,\n `from \"file://${reactJsxDevPath}\"`,\n );\n }\n if (reactDomPath) {\n result = result.replace(\n /from\\s+['\"]react-dom['\"]/g,\n `from \"file://${reactDomPath}\"`,\n );\n }\n if (reactPath) {\n result = result.replace(\n /from\\s+['\"]react['\"]/g,\n `from \"file://${reactPath}\"`,\n );\n }\n\n return result;\n}\n\nexport interface ESMLoaderContext {\n esmCacheDir?: string;\n moduleCache: LRUCache<string, MDXModule>;\n}\n\nexport function hashString(input: string): string {\n const HASH_SEED_FNV1A = 2166136261;\n let hash = HASH_SEED_FNV1A >>> 0; // FNV-1a\n for (let i = 0; i < input.length; i++) {\n hash ^= input.charCodeAt(i);\n hash = Math.imul(hash, 16777619);\n }\n return (hash >>> 0).toString(16);\n}\n\n/**\n * Creates an esbuild plugin to fetch and bundle HTTP/HTTPS imports.\n * This allows Node.js to use remote imports via esbuild bundling.\n */\nfunction createHTTPPluginForMDX(): import(\"esbuild\").Plugin {\n return {\n name: \"vf-mdx-http-fetch\",\n setup(build) {\n // Intercept HTTP/HTTPS imports\n build.onResolve({ filter: /^(http|https):\\/\\// }, (args) => ({\n path: args.path,\n namespace: \"http-url\",\n }));\n\n // Resolve relative imports within HTTP modules\n build.onResolve({ filter: /.*/, namespace: \"http-url\" }, (args) => {\n if (args.path.startsWith(\"http://\") || args.path.startsWith(\"https://\")) {\n return { path: args.path, namespace: \"http-url\" };\n }\n try {\n const resolved = new URL(args.path, args.importer).toString();\n return { path: resolved, namespace: \"http-url\" };\n } catch {\n return undefined;\n }\n });\n\n // Fetch and return HTTP module contents\n build.onLoad({ filter: /.*/, namespace: \"http-url\" }, async (args) => {\n let requestUrl = args.path;\n try {\n const u = new URL(args.path);\n // Optimize esm.sh URLs\n if (u.hostname === \"esm.sh\") {\n if (u.pathname.includes(\"/denonext/\")) {\n u.pathname = u.pathname.replace(\"/denonext/\", \"/\");\n }\n u.searchParams.set(\"target\", \"es2020\");\n u.searchParams.set(\"bundle\", \"true\");\n requestUrl = u.toString();\n }\n } catch {\n // Use original URL if parsing fails\n }\n\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), HTTP_MODULE_FETCH_TIMEOUT_MS);\n try {\n const res = await fetch(requestUrl, {\n headers: { \"user-agent\": \"Mozilla/5.0 Veryfront/1.0\" },\n signal: controller.signal,\n });\n clearTimeout(timeout);\n\n if (!res.ok) {\n return {\n errors: [{ text: `Failed to fetch ${args.path}: ${res.status}` }],\n };\n }\n\n const text = await res.text();\n return { contents: text, loader: \"js\" };\n } catch (e) {\n clearTimeout(timeout);\n return {\n errors: [{\n text: `Failed to fetch ${args.path}: ${e instanceof Error ? e.message : String(e)}`,\n }],\n };\n }\n });\n },\n };\n}\n\nexport async function loadModuleESM(\n compiledProgramCode: string,\n context: ESMLoaderContext,\n): Promise<MDXModule> {\n try {\n const { getAdapter } = await import(\"@veryfront/platform/adapters/detect.ts\");\n const adapter = await getAdapter();\n\n if (!context.esmCacheDir) {\n if (IS_TRUE_NODE) {\n // On Node.js, use a cache dir inside the project so module resolution works\n // Node.js resolves bare imports relative to the file location\n const projectCacheDir = join(\n cwd(),\n \"node_modules\",\n \".cache\",\n \"veryfront-mdx\",\n );\n await adapter.fs.mkdir(projectCacheDir, { recursive: true });\n context.esmCacheDir = projectCacheDir;\n } else {\n // On Deno, system temp dir is fine\n context.esmCacheDir = await adapter.fs.makeTempDir(\"veryfront-mdx-esm-\");\n }\n }\n\n // Transform imports with import map\n let rewritten: string;\n if (IS_TRUE_NODE) {\n // On Node.js, transform react imports to absolute file:// paths\n // This is needed because MDX modules are cached in temp directories\n // where Node.js cannot resolve bare imports\n rewritten = await transformReactImportsToAbsolute(compiledProgramCode);\n } else {\n // On Deno/browser, transform to esm.sh URLs\n rewritten = transformImportsWithMap(\n compiledProgramCode,\n getDefaultImportMap(),\n undefined,\n { resolveBare: true },\n );\n }\n\n // Transform JSX/TSX imports using esbuild\n // This handles user components that use JSX syntax\n let jsxMatch;\n const jsxTransforms: Array<{ original: string; transformed: string }> = [];\n\n // Import esbuild once outside the loop for better performance\n const { transform } = await import(\"esbuild/mod.js\");\n\n while ((jsxMatch = JSX_IMPORT_PATTERN.exec(rewritten)) !== null) {\n const [fullMatch, importClause, filePath, ext] = jsxMatch;\n\n if (!filePath) {\n logger.warn(`${LOG_PREFIX_MDX_LOADER} Skipping JSX import with undefined file path`, {\n fullMatch,\n });\n continue;\n }\n\n try {\n // Read the JSX file (filePath already includes full path)\n const jsxCode = await adapter.fs.readFile(filePath);\n\n // Use esbuild to transform JSX to JavaScript\n const result = await transform(jsxCode as string, {\n loader: ext === \"tsx\" ? \"tsx\" : \"jsx\",\n jsx: \"transform\",\n jsxFactory: ESBUILD_JSX_FACTORY,\n jsxFragment: ESBUILD_JSX_FRAGMENT,\n format: \"esm\",\n });\n\n let transformed = result.code;\n\n // Add React import if not present\n if (!REACT_IMPORT_PATTERN.test(transformed)) {\n transformed = `import React from 'react';\\n${transformed}`;\n }\n\n // Write transformed code to temp file\n const transformedFileName = `jsx-${hashString(filePath)}.mjs`;\n const transformedPath = join(context.esmCacheDir!, transformedFileName);\n await adapter.fs.writeFile(transformedPath, transformed);\n\n jsxTransforms.push({\n original: fullMatch,\n transformed: `import ${importClause} from \"file://${transformedPath}\";`,\n });\n\n logger.info(\n `${LOG_PREFIX_MDX_LOADER} Transformed JSX import using esbuild: ${filePath} -> ${transformedPath}`,\n );\n } catch (error) {\n logger.warn(`${LOG_PREFIX_MDX_LOADER} Failed to transform JSX import: ${filePath}`, error);\n // Keep original import if transformation fails\n }\n }\n\n // Apply all JSX transformations\n for (const { original, transformed } of jsxTransforms) {\n rewritten = rewritten.replace(original, transformed);\n }\n\n if (/\\bconst\\s+MDXLayout\\b/.test(rewritten) && !/export\\s+\\{[^}]*MDXLayout/.test(rewritten)) {\n rewritten += \"\\nexport { MDXLayout as __vfLayout };\\n\";\n }\n\n // On Node.js, bundle HTTP imports via esbuild instead of trying to import them directly\n if (IS_TRUE_NODE && HTTP_IMPORT_PATTERN.test(rewritten)) {\n logger.info(`${LOG_PREFIX_MDX_LOADER} Bundling HTTP imports via esbuild for Node.js`);\n const { build } = await import(\"esbuild/mod.js\");\n\n // Write temp source file for esbuild to process\n const tempSourcePath = join(context.esmCacheDir!, `temp-${hashString(rewritten)}.mjs`);\n await adapter.fs.writeFile(tempSourcePath, rewritten);\n\n try {\n const result = await build({\n entryPoints: [tempSourcePath],\n bundle: true,\n format: \"esm\",\n platform: \"neutral\",\n target: \"es2020\",\n write: false,\n plugins: [createHTTPPluginForMDX()],\n // Mark npm packages as external so they're not bundled\n external: [\"react\", \"react-dom\", \"react/jsx-runtime\", \"react/jsx-dev-runtime\"],\n });\n\n const bundledCode = result.outputFiles?.[0]?.text;\n if (bundledCode) {\n rewritten = bundledCode;\n logger.info(`${LOG_PREFIX_MDX_LOADER} Successfully bundled HTTP imports`);\n }\n } catch (bundleError) {\n logger.warn(\n `${LOG_PREFIX_MDX_LOADER} Failed to bundle HTTP imports, falling back to original code`,\n bundleError,\n );\n // Keep original code if bundling fails\n } finally {\n // Clean up temp file (use unlink since rm may not exist on all adapters)\n try {\n // deno-lint-ignore no-explicit-any\n const fsAny = adapter.fs as any;\n if (typeof fsAny.rm === \"function\") {\n await fsAny.rm(tempSourcePath);\n } else if (typeof fsAny.unlink === \"function\") {\n await fsAny.unlink(tempSourcePath);\n }\n // If neither exists, just leave the temp file (it's in a cache dir anyway)\n } catch {\n // Ignore cleanup errors\n }\n }\n }\n\n const codeHash = hashString(rewritten);\n const namespace = getCacheNamespace() || \"default\";\n const compositeKey = `${namespace}:${codeHash}`;\n\n const cached = context.moduleCache.get(compositeKey);\n if (cached) return cached as MDXModule;\n\n const nsDir = join(context.esmCacheDir, namespace);\n try {\n await adapter.fs.mkdir(nsDir, { recursive: true });\n } catch (e) {\n logger.debug(\n `${LOG_PREFIX_MDX_RENDERER} mkdir nsDir failed`,\n e instanceof Error ? e : String(e),\n );\n }\n\n const filePath = join(nsDir, `${codeHash}.mjs`);\n try {\n const stat = await adapter.fs.stat(filePath);\n if (!stat?.isFile) {\n await adapter.fs.writeFile(filePath, rewritten);\n }\n } catch (error) {\n logger.debug(`${LOG_PREFIX_MDX_RENDERER} Writing temporary MDX module file:`, error);\n await adapter.fs.writeFile(filePath, rewritten);\n }\n\n logger.info(`${LOG_PREFIX_MDX_RENDERER} Loading MDX module`, {\n filePath,\n codePreview: rewritten.substring(0, 300),\n });\n const mod = await import(`file://${filePath}?v=${codeHash}`) as Record<string, unknown> & {\n __vfLayout?: React.ComponentType;\n };\n\n const result: MDXModule = {\n ...mod,\n default: mod?.default as React.ComponentType<unknown> | undefined,\n MDXContent: mod?.MDXContent as React.ComponentType<unknown> | undefined,\n frontmatter: mod?.frontmatter as MDXFrontmatter | undefined,\n headings: mod?.headings as Array<{ text: string; level: number }> | undefined,\n title: mod?.title as string | undefined,\n description: mod?.description as string | undefined,\n layout: mod?.layout as string | boolean | React.ComponentType | undefined,\n MDXLayout: (mod?.MDXLayout || mod?.__vfLayout) as React.ComponentType<unknown> | undefined,\n MainLayout: mod?.MainLayout as React.ComponentType<unknown> | undefined,\n };\n context.moduleCache.set(compositeKey, result);\n return result;\n } catch (error) {\n logger.error(`${LOG_PREFIX_MDX_RENDERER} MDX ESM load failed:`, error);\n throw error;\n }\n}\n", "import { serverLogger as logger } from \"../../logger/logger.ts\";\nimport { getEnvironmentVariable } from \"../../logger/env.ts\";\nimport type { GlobalWithVeryFrontCache } from \"@veryfront/types/global-guards.ts\";\n\nlet cacheNamespace: string | undefined =\n (globalThis as GlobalWithVeryFrontCache).__VF_CACHE_NAMESPACE__ ||\n getEnvironmentVariable(\"VF_CACHE_NAMESPACE\");\n\nexport function setCacheNamespace(namespace?: string): void {\n cacheNamespace = namespace || undefined;\n try {\n (globalThis as GlobalWithVeryFrontCache).__VF_CACHE_NAMESPACE__ = cacheNamespace;\n } catch (e) {\n logger.debug(\"[cache] setCacheNamespace failed\", e);\n }\n}\n\nexport function getCacheNamespace(): string | undefined {\n return cacheNamespace;\n}\n", "export { loadImportMap } from \"./loader.ts\";\nexport { getDefaultImportMap } from \"./default-import-map.ts\";\nexport { resolveImport } from \"./resolver.ts\";\nexport { transformImportsWithMap } from \"./transformer.ts\";\nexport { mergeImportMaps } from \"./merger.ts\";\n\nexport type { ImportMapConfig, TransformOptions } from \"./types.ts\";\n", "import { rendererLogger as logger } from \"@veryfront/utils\";\nimport { dirname, join } from \"std/path/mod.ts\";\nimport type { RuntimeAdapter } from \"@veryfront/platform/adapters/base.ts\";\nimport { getConfig } from \"@veryfront/config\";\nimport type { ImportMapConfig } from \"./types.ts\";\nimport { getDefaultImportMap } from \"./default-import-map.ts\";\n\nexport async function loadImportMap(\n startPath: string,\n adapter?: RuntimeAdapter,\n): Promise<ImportMapConfig> {\n let runtimeAdapter = adapter;\n if (!runtimeAdapter) {\n const { getAdapter } = await import(\"@veryfront/platform/adapters/detect.ts\");\n runtimeAdapter = await getAdapter();\n }\n\n try {\n const cfg = await getConfig(startPath, runtimeAdapter!);\n if (cfg?.resolve?.importMap && typeof cfg.resolve.importMap === \"object\") {\n return {\n imports: cfg.resolve.importMap.imports ?? {},\n scopes: cfg.resolve.importMap.scopes ?? {},\n };\n }\n } catch {\n // Config not found or invalid, fall through to file-based discovery\n }\n\n let currentPath = startPath;\n\n while (currentPath !== \"/\" && currentPath !== \"\") {\n const denoJsonPath = join(currentPath, \"deno.json\");\n\n try {\n const content = await runtimeAdapter!.fs.readFile(denoJsonPath);\n const config = JSON.parse(content);\n\n if (config.imports || config.scopes) {\n logger.debug(`Loaded import map from ${denoJsonPath}`);\n return {\n imports: config.imports ?? {},\n scopes: config.scopes ?? {},\n };\n }\n } catch {\n // deno.json not found in this directory, continue searching\n }\n\n const parent = dirname(currentPath);\n if (parent === currentPath) break; // Reached root\n currentPath = parent;\n }\n\n return getDefaultImportMap();\n}\n", "import { getReactImportMap, REACT_DEFAULT_VERSION } from \"@veryfront/utils\";\nimport type { ImportMapConfig } from \"./types.ts\";\n\nexport function getDefaultImportMap(): ImportMapConfig {\n const reactVersion = REACT_DEFAULT_VERSION;\n\n const importMap = getReactImportMap(reactVersion);\n importMap[\"react/\"] = `https://esm.sh/react@${reactVersion}/`;\n\n return { imports: importMap };\n}\n", "import type { ImportMapConfig } from \"./types.ts\";\n\nexport function resolveImport(\n specifier: string,\n importMap: ImportMapConfig,\n scope?: string,\n): string {\n if (scope && importMap.scopes?.[scope]?.[specifier]) {\n return importMap.scopes[scope][specifier];\n }\n\n if (importMap.imports?.[specifier]) {\n return importMap.imports[specifier];\n }\n\n if (\n specifier.endsWith(\".js\") || specifier.endsWith(\".mjs\") ||\n specifier.endsWith(\".cjs\")\n ) {\n const base = specifier.replace(/\\.(m|c)?js$/, \"\");\n if (importMap.imports?.[base]) {\n return importMap.imports[base];\n }\n }\n\n if (importMap.imports) {\n for (const [key, value] of Object.entries(importMap.imports)) {\n if (key.endsWith(\"/\") && specifier.startsWith(key)) {\n return value + specifier.slice(key.length);\n }\n }\n }\n\n return specifier;\n}\n", "import type { ImportMapConfig, TransformOptions } from \"./types.ts\";\nimport { resolveImport } from \"./resolver.ts\";\n\nexport function transformImportsWithMap(\n code: string,\n importMap: ImportMapConfig,\n scope?: string,\n options?: TransformOptions,\n): string {\n let transformedCode = code;\n\n transformedCode = transformedCode.replace(\n /((?:import|export)\\s+(?:[\\w,{}\\s*]+\\s+from\\s+)?|export\\s+(?:\\*|\\{[^}]+\\})\\s+from\\s+)[\"']([^\"']+)[\"']/g,\n (_match, prefix, specifier) => {\n const isBare = !specifier.startsWith(\"http\") &&\n !specifier.startsWith(\"/\") &&\n !specifier.startsWith(\".\");\n if (isBare && !options?.resolveBare) {\n return `${prefix}\"${specifier}\"`;\n }\n const resolved = resolveImport(specifier, importMap, scope);\n return `${prefix}\"${resolved}\"`;\n },\n );\n\n transformedCode = transformedCode.replace(\n /from\\s+[\"']([^\"']+)[\"']/g,\n (match, specifier) => {\n const isBare = !specifier.startsWith(\"http\") &&\n !specifier.startsWith(\"/\") &&\n !specifier.startsWith(\".\");\n if (isBare && !options?.resolveBare) {\n return match;\n }\n const resolved = resolveImport(specifier, importMap, scope);\n return `from \"${resolved}\"`;\n },\n );\n\n transformedCode = transformedCode.replace(\n /import\\s*\\(\\s*[\"']([^\"']+)[\"']\\s*\\)/g,\n (_match, specifier) => {\n const resolved = resolveImport(specifier, importMap, scope);\n return `import(\"${resolved}\")`;\n },\n );\n\n return transformedCode;\n}\n", "import type { ImportMapConfig } from \"./types.ts\";\n\nexport function mergeImportMaps(...maps: ImportMapConfig[]): ImportMapConfig {\n const merged: ImportMapConfig = {\n imports: {},\n scopes: {},\n };\n\n for (const map of maps) {\n if (map.imports) {\n Object.assign(merged.imports!, map.imports);\n }\n\n if (map.scopes) {\n for (const [scope, imports] of Object.entries(map.scopes)) {\n if (!merged.scopes![scope]) {\n merged.scopes![scope] = {};\n }\n Object.assign(merged.scopes![scope], imports);\n }\n }\n }\n\n return merged;\n}\n", "import { rendererLogger as logger } from \"@veryfront/utils\";\nimport type { MDXExports, MDXImportInfo, ParsedMDX } from \"./types.ts\";\nimport { extractFrontmatter, extractMetadata } from \"./module-loader/metadata-extractor.ts\";\n\nexport type { ParsedMDX };\n\nexport function parseMDXCode(compiledCode: string): ParsedMDX {\n logger.debug(\"Parsing MDX code, first 200 chars:\", compiledCode.substring(0, 200));\n const importRegex = /^\\s*import\\s+(?:{([^}]+)}|(\\w+))\\s+from\\s+['\"]([^'\"]+)['\"]\\s*;?\\s*$/gm;\n const imports = new Map<string, MDXImportInfo>();\n let match: RegExpExecArray | null;\n\n while ((match = importRegex.exec(compiledCode)) !== null) {\n if (match[1]) {\n const names = match[1].split(\",\").map((n: string) => n.trim());\n names.forEach((name: string) => {\n if (match?.[3]) {\n imports.set(name, { name, path: match[3], isDefault: false });\n }\n });\n } else if (match[2]) {\n if (match[2] && match[3]) {\n imports.set(match[2], {\n name: match[2],\n path: match[3],\n isDefault: true,\n });\n }\n }\n }\n\n const cleanedCode = compiledCode\n .replace(importRegex, \"\") // Remove top-level imports\n .replace(/^\\s*export\\s+\\{[\\s\\S]*?\\};?\\s*$/gm, \"\") // Remove named exports (including multi-line)\n .replace(/^\\s*export\\s+default\\s+function/gm, \"function\") // Convert default export function\n .replace(/^\\s*export\\s+default\\s+/gm, \"\") // Remove other default exports\n .replace(/^\\s*export\\s+const\\s+/gm, \"const \") // Convert export const to const\n .replace(/^\\s*export\\s+function\\s+/gm, \"function \") // Convert export function to function\n .replace(/^\\s*const\\s+React\\s*=.*?;?\\s*$/gm, \"\") // Remove React declarations\n .replace(/^\\s*import\\s+React\\s+from.*?;?\\s*$/gm, \"\") // Remove React imports\n .replace(/^\\s*const\\s+(Fragment|Fragment2)\\s*=.*?;?\\s*$/gm, \"\") // Remove Fragment declarations\n .replace(/^\\s*const\\s+(jsx|jsx2)\\s*=.*?;?\\s*$/gm, \"\") // Remove jsx declarations\n .replace(/^\\s*const\\s+(jsxs|jsxs2)\\s*=.*?;?\\s*$/gm, \"\"); // Remove jsxs declarations\n\n if (cleanedCode.includes(\"import React\")) {\n logger.warn(\"Import React still in cleaned code\");\n }\n if (cleanedCode.includes(\"const React\") || cleanedCode.includes(\"var React\")) {\n logger.warn(\"React declaration found in cleaned code\");\n logger.debug(\"Code snippet:\", cleanedCode.substring(0, 200));\n }\n\n const exports: MDXExports = {};\n\n const frontmatter = extractFrontmatter(cleanedCode);\n if (frontmatter) {\n exports.frontmatter = frontmatter;\n }\n\n const metadata = extractMetadata(cleanedCode);\n for (const [key, value] of Object.entries(metadata)) {\n if (value !== undefined) {\n (exports as Record<string, unknown>)[key] = value;\n }\n }\n\n return { code: cleanedCode, imports, exports };\n}\n", "import { rendererLogger as logger } from \"@veryfront/utils\";\nimport type { FrontmatterMetadata, LogContext, MDXModule } from \"./types.ts\";\nimport { extractBalancedBlock, parseJsonish } from \"./string-parser.ts\";\n\nexport function extractFrontmatter(moduleCode: string): FrontmatterMetadata | undefined {\n try {\n const fmIndex = moduleCode.search(/(?:export\\s+)?const\\s+frontmatter\\s*=\\s*/);\n if (fmIndex < 0) return undefined;\n\n const braceStart = moduleCode.indexOf(\"{\", fmIndex);\n if (braceStart < 0) return undefined;\n\n const raw = extractBalancedBlock(moduleCode, braceStart, \"{\", \"}\");\n if (!raw) return undefined;\n\n const jsonish = raw\n .replace(/([^\\s\"{[:,]+)\\s*:/g, '\"$1\":')\n .replace(/'([^']*)'/g, '\"$1\"');\n\n try {\n return JSON.parse(jsonish) as FrontmatterMetadata;\n } catch (e) {\n logger.debug(\"[mdx] frontmatter JSON parse failed\", e as LogContext);\n return undefined;\n }\n } catch (e) {\n logger.debug(\"[mdx] frontmatter extraction failed\", e as LogContext);\n return undefined;\n }\n}\n\ninterface MetadataPattern {\n regex: RegExp;\n key: string;\n}\n\nconst METADATA_PATTERNS: MetadataPattern[] = [\n { regex: /(?:export\\s+)?const\\s+title\\s*=\\s*[\"']([^\"']+)[\"']/, key: \"title\" },\n { regex: /(?:export\\s+)?const\\s+description\\s*=\\s*[\"']([^\"']+)[\"']/, key: \"description\" },\n { regex: /(?:export\\s+)?const\\s+layout\\s*=\\s*(true|false|[\"'][^\"']+[\"'])/, key: \"layout\" },\n { regex: /(?:export\\s+)?const\\s+headings\\s*=\\s*(\\[[\\s\\S]*?\\])/, key: \"headings\" },\n { regex: /(?:export\\s+)?const\\s+nested\\s*=\\s*({[\\s\\S]*?})/, key: \"nested\" },\n { regex: /(?:export\\s+)?const\\s+tags\\s*=\\s*(\\[[\\s\\S]*?\\])/, key: \"tags\" },\n { regex: /(?:export\\s+)?const\\s+date\\s*=\\s*[\"']([^\"']+)[\"']/, key: \"date\" },\n { regex: /(?:export\\s+)?const\\s+draft\\s*=\\s*(true|false)/, key: \"draft\" },\n];\n\nexport function extractMetadata(moduleCode: string): Partial<MDXModule> {\n const exports: Partial<MDXModule> = {};\n\n METADATA_PATTERNS.forEach(({ regex, key }) => {\n const match = moduleCode.match(regex);\n if (!match) return;\n\n const value = match[1] as string;\n\n switch (key) {\n case \"title\":\n case \"description\":\n case \"date\":\n exports[key] = value;\n break;\n\n case \"layout\":\n exports[key] = value === \"true\"\n ? true\n : value === \"false\"\n ? false\n : String(value).replace(/^\"|\"$/g, \"\");\n break;\n\n case \"headings\":\n case \"tags\":\n case \"nested\":\n try {\n exports[key] = parseJsonish(value) as never;\n } catch (e) {\n logger.warn(`Failed to parse ${key}`, e);\n }\n break;\n\n case \"draft\":\n exports[key] = value === \"true\";\n break;\n }\n });\n\n return exports;\n}\n\nexport function mergeFrontmatter(result: MDXModule): void {\n result.frontmatter = result.frontmatter || {};\n\n const keys = [\"title\", \"description\", \"layout\", \"headings\", \"tags\", \"date\", \"draft\", \"nested\"];\n for (const key of keys) {\n if (result[key] !== undefined && result.frontmatter[key] === undefined) {\n result.frontmatter[key] = result[key];\n }\n }\n}\n", "export function extractBalancedBlock(\n source: string,\n startIndex: number,\n open: \"{\" | \"[\" | \"(\",\n close?: \"}\" | \"]\" | \")\",\n): string {\n const closeCh = close || (open === \"{\" ? \"}\" : open === \"[\" ? \"]\" : \")\");\n let depth = 0;\n let i = startIndex;\n\n while (i < source.length) {\n const ch = source[i] as string;\n\n if (ch === '\"' || ch === \"'\") {\n const quote = ch;\n i++;\n while (i < source.length) {\n const q = source[i] as string;\n if (q === \"\\\\\") {\n i += 2;\n continue;\n }\n if (q === quote) {\n i++;\n break;\n }\n i++;\n }\n continue;\n }\n\n if (ch === open) depth++;\n if (ch === closeCh) {\n depth--;\n if (depth === 0) {\n return source.slice(startIndex, i + 1);\n }\n }\n i++;\n }\n\n return \"\";\n}\n\nexport function cleanModuleCode(moduleCode: string): string {\n return moduleCode\n .replace(/import\\s+.*?from\\s+['\"][^'\"]+['\"];?\\s*/gm, \"\")\n .replace(/export\\s+\\{[\\s\\S]*?\\};?$/gm, \"\")\n .replace(/export\\s+default\\s+/gm, \"\")\n .replace(/export\\s+const\\s+/gm, \"const \")\n .replace(/export\\s+function\\s+/gm, \"function \");\n}\n\nexport function parseJsonish(value: string): unknown {\n const jsonish = value\n .replace(/'([^']*)'/g, '\"$1\"')\n .replace(/([{,]\\s*)([A-Za-z_$][\\w$]*)\\s*:/g, '$1\"$2\":');\n return JSON.parse(jsonish);\n}\n", "import { rendererLogger as logger } from \"@veryfront/utils\";\nimport { wrapError as _wrapError } from \"@veryfront/errors\";\nimport {\n type BundleCode,\n type BundleMetadata,\n computeCodeHash,\n computeContentHash,\n getBundleManifestStore,\n getBundleManifestTTL,\n} from \"@veryfront/utils\";\nimport type { VeryfrontConfig } from \"@veryfront/config\";\nimport type { MdxBundle } from \"@veryfront/types\";\n\nexport interface MDXCompilationResult extends MdxBundle {\n headings?: Array<{ id: string; text: string; level: number }>;\n nodeMap?: Map<number, unknown>;\n}\n\nexport interface MDXCacheAdapterOptions {\n config: VeryfrontConfig;\n mode: \"development\" | \"production\";\n}\n\nexport class MDXCacheAdapter {\n private config: VeryfrontConfig;\n private mode: \"development\" | \"production\";\n private manifestStore = getBundleManifestStore();\n\n constructor(options: MDXCacheAdapterOptions) {\n this.config = options.config;\n this.mode = options.mode;\n }\n\n private getCacheKey(contentHash: string): string {\n return `mdx:${this.mode}:${contentHash}`;\n }\n\n private getTTL(): number | undefined {\n return getBundleManifestTTL(this.config, this.mode);\n }\n\n async computeHash(content: string): Promise<string> {\n return await computeContentHash(content);\n }\n\n async getCachedBundle(\n content: string,\n frontmatter?: Record<string, unknown>,\n filePath?: string,\n ): Promise<MDXCompilationResult | undefined> {\n try {\n const contentHash = await this.computeHash(content);\n const cacheKey = this.getCacheKey(contentHash);\n\n const metadata = await this.manifestStore.getBundleMetadata(cacheKey);\n if (!metadata) {\n return undefined;\n }\n\n const bundleCode = await this.manifestStore.getBundleCode(metadata.codeHash);\n if (!bundleCode) {\n logger.debug(\"[mdx-cache] Metadata found but code missing\", {\n filePath,\n codeHash: metadata.codeHash,\n });\n return undefined;\n }\n\n logger.debug(\"[mdx-cache] Cache hit for MDX compilation\", {\n filePath,\n codeHash: metadata.codeHash,\n size: metadata.size,\n });\n\n return {\n compiledCode: bundleCode.code,\n frontmatter: (frontmatter || {}) as Record<string, string | number | boolean | string[]>,\n headings: [],\n nodeMap: new Map(),\n };\n } catch (error) {\n logger.debug(\"[mdx-cache] Failed to retrieve cached bundle\", {\n error,\n filePath,\n });\n return undefined;\n }\n }\n\n async setCachedBundle(\n content: string,\n bundle: MDXCompilationResult,\n filePath?: string,\n ): Promise<void> {\n if (!bundle.compiledCode) {\n logger.debug(\"[mdx-cache] No compiled code to cache\", { filePath });\n return;\n }\n\n try {\n const contentHash = await this.computeHash(content);\n const cacheKey = this.getCacheKey(contentHash);\n\n const bundleCode: BundleCode = {\n code: bundle.compiledCode,\n };\n\n const codeHash = await computeCodeHash(bundleCode);\n\n const encoder = new TextEncoder();\n const size = encoder.encode(bundle.compiledCode).length;\n\n const metadata: BundleMetadata = {\n hash: contentHash,\n codeHash,\n size,\n compiledAt: Date.now(),\n source: filePath || \"unknown\",\n mode: this.mode,\n meta: {\n type: \"mdx\",\n reactVersion: (await import(\"react\")).version,\n },\n };\n\n const ttl = this.getTTL();\n\n await this.manifestStore.setBundleCode(codeHash, bundleCode, ttl);\n await this.manifestStore.setBundleMetadata(cacheKey, metadata, ttl);\n\n logger.debug(\"[mdx-cache] Cached compiled MDX\", {\n filePath,\n cacheKey,\n codeHash,\n size,\n ttl,\n });\n } catch (error) {\n logger.debug(\"[mdx-cache] Failed to cache bundle\", {\n error,\n filePath,\n });\n }\n }\n\n async invalidateBundle(content: string): Promise<void> {\n try {\n const contentHash = await this.computeHash(content);\n const cacheKey = this.getCacheKey(contentHash);\n await this.manifestStore.deleteBundle(cacheKey);\n logger.debug(\"[mdx-cache] Invalidated cached bundle\", { cacheKey });\n } catch (error) {\n logger.debug(\"[mdx-cache] Failed to invalidate bundle\", { error });\n }\n }\n\n async invalidateSource(source: string): Promise<number> {\n try {\n const count = await this.manifestStore.invalidateSource(source);\n logger.debug(\"[mdx-cache] Invalidated bundles for source\", {\n source,\n count,\n });\n return count;\n } catch (error) {\n logger.debug(\"[mdx-cache] Failed to invalidate source\", {\n error,\n source,\n });\n return 0;\n }\n }\n\n async clearAll(): Promise<void> {\n try {\n await this.manifestStore.clear();\n logger.debug(\"[mdx-cache] Cleared all cached bundles\");\n } catch (error) {\n logger.debug(\"[mdx-cache] Failed to clear cache\", { error });\n }\n }\n\n async getStats(): Promise<{\n totalBundles: number;\n totalSize: number;\n oldestBundle?: number;\n newestBundle?: number;\n }> {\n try {\n return await this.manifestStore.getStats();\n } catch (error) {\n logger.debug(\"[mdx-cache] Failed to get stats\", { error });\n return {\n totalBundles: 0,\n totalSize: 0,\n };\n }\n }\n}\n", "import type * as React from \"react\";\nimport { useMemo, useRef } from \"react\";\nimport { mdxRenderer } from \"@veryfront/transforms/mdx/index.ts\";\nimport type { MDXComponents } from \"@veryfront/types\";\nimport type { MdxBundle } from \"./LayoutComponent.tsx\";\nimport { rendererLogger as logger } from \"@veryfront/utils\";\n\nexport interface ProviderComponentProps {\n mdxBundle: MdxBundle;\n children: React.ReactNode;\n components?: MDXComponents;\n}\n\nfunction useStableFrontmatter(frontmatter: MdxBundle[\"frontmatter\"]): MdxBundle[\"frontmatter\"] {\n const ref = useRef(frontmatter);\n const serialized = JSON.stringify(frontmatter);\n const prevSerialized = useRef(serialized);\n\n if (prevSerialized.current !== serialized) {\n ref.current = frontmatter;\n prevSerialized.current = serialized;\n }\n\n return ref.current;\n}\n\nexport function ProviderComponent({\n mdxBundle,\n children,\n components = {},\n}: ProviderComponentProps) {\n const stableFrontmatter = useStableFrontmatter(mdxBundle.frontmatter);\n\n const element = useMemo(() => {\n try {\n return mdxRenderer.render(mdxBundle.compiledCode, {\n components,\n frontmatter: stableFrontmatter,\n globals: mdxBundle.globals,\n extractLayout: true,\n children,\n });\n } catch (error) {\n logger.error(\"[ProviderComponent] Render failed:\", error);\n return <>{children}</>;\n }\n }, [mdxBundle.compiledCode, stableFrontmatter, components, children, mdxBundle.globals]);\n\n if (!element) return <>{children}</>;\n return element as React.ReactElement;\n}\n", "import React from \"react\";\n\nexport function Head({ children }: { children: React.ReactNode }) {\n return React.createElement(\n \"div\",\n {\n \"data-veryfront-head\": \"1\",\n style: { display: \"none\" },\n },\n children,\n );\n}\n", "import React from \"react\";\n\nexport type LinkProps = React.AnchorHTMLAttributes<HTMLAnchorElement> & {\n prefetch?: boolean;\n};\n\nexport function Link({ prefetch = true, children, ...rest }: LinkProps) {\n const props: React.AnchorHTMLAttributes<HTMLAnchorElement> = {\n ...rest,\n ...(prefetch ? { \"data-prefetch\": \"true\" } : {}),\n };\n return <a {...props}>{children}</a>;\n}\n", "import type React from \"react\";\nimport { createContext, useContext } from \"react\";\nimport type { MDXComponents } from \"@veryfront/types\";\n\nconst MDXContext = createContext<MDXComponents>({});\n\nexport interface MDXProviderProps {\n components?: MDXComponents;\n children: React.ReactNode;\n}\n\nexport function MDXProvider({\n components = {},\n children,\n}: MDXProviderProps) {\n return <MDXContext.Provider value={components}>{children}</MDXContext.Provider>;\n}\n\nexport function useMDXComponents(components?: MDXComponents): MDXComponents {\n const contextComponents = useContext(MDXContext);\n return { ...contextComponents, ...components };\n}\n", "export { OptimizedImage } from \"./OptimizedImage.tsx\";\nexport type { OptimizedImageProps } from \"./OptimizedImage.tsx\";\nexport { SimpleOptimizedImage } from \"./SimpleOptimizedImage.tsx\";\nexport { OptimizedBackgroundImage } from \"./OptimizedBackgroundImage.tsx\";\nexport { useOptimizedImage } from \"./useOptimizedImage.ts\";\nexport { generateBlurDataURL, getAspectRatioPadding, ResponsiveImageContainer } from \"./utils.tsx\";\n", "import React from \"react\";\nimport { RESPONSIVE_IMAGE_WIDTH_LG, RESPONSIVE_IMAGE_WIDTHS } from \"@veryfront/utils\";\nimport { generateSrcSet, getExtension, getOptimizedPath } from \"./helpers.ts\";\n\nexport interface OptimizedImageProps {\n src: string;\n alt: string;\n width?: number;\n height?: number;\n sizes?: string;\n formats?: (\"avif\" | \"webp\" | \"jpeg\" | \"png\")[];\n quality?: number;\n loading?: \"lazy\" | \"eager\";\n priority?: boolean;\n className?: string;\n style?: React.CSSProperties;\n placeholder?: \"blur\" | \"empty\";\n blurDataURL?: string;\n onClick?: (event: React.MouseEvent<HTMLImageElement>) => void;\n onLoad?: (event: React.SyntheticEvent<HTMLImageElement>) => void;\n onError?: (event: React.SyntheticEvent<HTMLImageElement>) => void;\n}\n\nconst DEFAULT_SIZES = [...RESPONSIVE_IMAGE_WIDTHS];\nconst DEFAULT_FORMATS: (\"avif\" | \"webp\" | \"jpeg\")[] = [\"avif\", \"webp\", \"jpeg\"];\n\nexport function OptimizedImage({\n src,\n alt,\n width,\n height,\n sizes = \"100vw\",\n formats = DEFAULT_FORMATS,\n quality = 80,\n loading,\n priority = false,\n className,\n style,\n placeholder = \"empty\",\n blurDataURL,\n onClick,\n onLoad,\n onError,\n}: OptimizedImageProps) {\n const loadingStrategy = priority ? \"eager\" : loading || \"lazy\";\n\n const originalFormat = getExtension(src);\n\n const imgStyle: React.CSSProperties = {\n ...style,\n ...(placeholder === \"blur\" && blurDataURL\n ? { backgroundImage: `url(${blurDataURL})`, backgroundSize: \"cover\" }\n : {}),\n };\n\n return (\n <picture>\n {formats.map((format) => (\n <source\n key={format}\n type={`image/${format}`}\n srcSet={generateSrcSet(src, format, DEFAULT_SIZES, quality)}\n sizes={sizes}\n />\n ))}\n\n <img\n src={getOptimizedPath(src, originalFormat, width || RESPONSIVE_IMAGE_WIDTH_LG, quality)}\n alt={alt}\n width={width}\n height={height}\n loading={loadingStrategy}\n decoding=\"async\"\n className={className}\n style={imgStyle}\n onClick={onClick}\n onLoad={onLoad}\n onError={onError}\n />\n </picture>\n );\n}\n", "export function getOptimizedPath(\n src: string,\n format: string,\n size: number,\n _quality: number = 80,\n): string {\n const basePath = src.replace(/\\.[^.]+$/, \"\");\n const optimizedDir = \".veryfront/optimized-images\";\n\n return `/${optimizedDir}${basePath}-${size}w.${format}`;\n}\n\nexport function generateSrcSet(\n src: string,\n format: string,\n sizes: number[],\n quality: number,\n): string {\n return sizes\n .map((size) => {\n const path = getOptimizedPath(src, format, size, quality);\n return `${path} ${size}w`;\n })\n .join(\", \");\n}\n\nexport function getExtension(src: string): string {\n const match = src.match(/\\.([^.]+)$/);\n const extension = match?.[1];\n return extension ? extension.toLowerCase() : \"jpeg\";\n}\n", "import React from \"react\";\nimport type { OptimizedImageProps } from \"./OptimizedImage.tsx\";\nimport { RESPONSIVE_IMAGE_WIDTH_LG, RESPONSIVE_IMAGE_WIDTHS } from \"@veryfront/utils\";\nimport { generateSrcSet, getOptimizedPath } from \"./helpers.ts\";\n\nconst DEFAULT_SIZES = [...RESPONSIVE_IMAGE_WIDTHS];\n\nexport function SimpleOptimizedImage({\n src,\n alt,\n width,\n height,\n format = \"webp\",\n quality = 80,\n loading = \"lazy\",\n className,\n style,\n onClick,\n onLoad,\n onError,\n}: Omit<OptimizedImageProps, \"formats\" | \"sizes\" | \"priority\" | \"placeholder\" | \"blurDataURL\"> & {\n format?: \"webp\" | \"avif\" | \"jpeg\" | \"png\";\n}) {\n const srcSet = generateSrcSet(src, format, DEFAULT_SIZES, quality);\n\n return (\n <img\n src={getOptimizedPath(src, format, width || RESPONSIVE_IMAGE_WIDTH_LG, quality)}\n srcSet={srcSet}\n alt={alt}\n width={width}\n height={height}\n loading={loading}\n decoding=\"async\"\n className={className}\n style={style as React.CSSProperties}\n onClick={onClick}\n onLoad={onLoad}\n onError={onError}\n />\n );\n}\n", "import React from \"react\";\nimport { RESPONSIVE_IMAGE_WIDTH_LG } from \"@veryfront/utils/constants/network.ts\";\nimport { getOptimizedPath } from \"./helpers.ts\";\n\nexport function OptimizedBackgroundImage({\n src,\n children,\n format = \"webp\",\n quality = 80,\n size = RESPONSIVE_IMAGE_WIDTH_LG,\n className,\n style,\n}: {\n src: string;\n children?: React.ReactNode;\n format?: \"webp\" | \"avif\" | \"jpeg\" | \"png\";\n quality?: number;\n size?: number;\n className?: string;\n style?: React.CSSProperties;\n}) {\n const optimizedSrc = getOptimizedPath(src, format, size, quality);\n\n const bgStyle: React.CSSProperties = {\n backgroundImage: `url(${optimizedSrc})`,\n backgroundSize: \"cover\",\n backgroundPosition: \"center\",\n backgroundRepeat: \"no-repeat\",\n ...style,\n };\n\n return (\n <div className={className} style={bgStyle}>\n {children}\n </div>\n );\n}\n", "import { RESPONSIVE_IMAGE_WIDTH_LG, RESPONSIVE_IMAGE_WIDTHS } from \"@veryfront/utils\";\nimport { generateSrcSet, getExtension, getOptimizedPath } from \"./helpers.ts\";\n\nconst DEFAULT_SIZES = [...RESPONSIVE_IMAGE_WIDTHS];\nconst DEFAULT_FORMATS: (\"avif\" | \"webp\" | \"jpeg\")[] = [\"avif\", \"webp\", \"jpeg\"];\n\nexport function useOptimizedImage(\n src: string,\n options: {\n formats?: (\"avif\" | \"webp\" | \"jpeg\" | \"png\")[];\n quality?: number;\n } = {},\n) {\n const formats = options.formats || DEFAULT_FORMATS;\n const quality = options.quality || 80;\n\n const sources = formats.map((format) => ({\n format,\n srcSet: generateSrcSet(src, format, DEFAULT_SIZES, quality),\n type: `image/${format}`,\n }));\n\n const fallback = getOptimizedPath(\n src,\n getExtension(src),\n RESPONSIVE_IMAGE_WIDTH_LG,\n quality,\n );\n\n return {\n sources,\n fallback,\n };\n}\n", "import React from \"react\";\n\nexport function generateBlurDataURL(\n width: number = 10,\n height: number = 10,\n color: string = \"#cccccc\",\n): string {\n const svg = `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 ${width} ${height}\">\n <rect width=\"${width}\" height=\"${height}\" fill=\"${color}\"/>\n </svg>\n `;\n\n return `data:image/svg+xml;base64,${btoa(svg)}`;\n}\n\nexport function getAspectRatioPadding(width: number, height: number): string {\n return `${(height / width) * 100}%`;\n}\n\nexport function ResponsiveImageContainer({\n width,\n height,\n children,\n className,\n style,\n}: {\n width: number;\n height: number;\n children: React.ReactNode;\n className?: string;\n style?: React.CSSProperties;\n}) {\n const containerStyle = {\n position: \"relative\" as const,\n width: \"100%\",\n paddingBottom: getAspectRatioPadding(width, height),\n ...style,\n };\n\n const contentStyle = {\n position: \"absolute\",\n top: 0,\n left: 0,\n width: \"100%\",\n height: \"100%\",\n } as const;\n\n return (\n <div className={className} style={containerStyle}>\n <div style={contentStyle}>{children}</div>\n </div>\n );\n}\n", "export type {\n CacheEntry,\n DataContext,\n DataResult,\n InferGetServerDataProps,\n PageWithData,\n StaticPathsResult,\n} from \"./types.ts\";\n\nexport { DataFetcher } from \"./data-fetcher.ts\";\nexport { notFound, redirect } from \"./helpers.ts\";\n", "import type { RuntimeAdapter } from \"@veryfront/platform/adapters/index.ts\";\nimport { CacheManager } from \"./data-fetching-cache.ts\";\nimport { ServerDataFetcher } from \"./server-data-fetcher.ts\";\nimport { StaticDataFetcher } from \"./static-data-fetcher.ts\";\nimport { StaticPathsFetcher } from \"./static-paths-fetcher.ts\";\nimport type { DataContext, DataResult, PageWithData, StaticPathsResult } from \"./types.ts\";\n\nexport class DataFetcher {\n private cacheManager: CacheManager;\n private serverFetcher: ServerDataFetcher;\n private staticFetcher: StaticDataFetcher;\n private pathsFetcher: StaticPathsFetcher;\n\n constructor(adapter?: RuntimeAdapter) {\n this.cacheManager = new CacheManager();\n this.serverFetcher = new ServerDataFetcher(adapter);\n this.staticFetcher = new StaticDataFetcher(this.cacheManager, adapter);\n this.pathsFetcher = new StaticPathsFetcher();\n }\n\n async fetchData(\n pageModule: PageWithData,\n context: DataContext,\n mode: \"development\" | \"production\" = \"development\",\n ): Promise<DataResult> {\n if (!pageModule.getServerData && !pageModule.getStaticData) {\n return { props: {} };\n }\n\n if (mode === \"development\" && pageModule.getServerData) {\n return await this.serverFetcher.fetch(pageModule, context);\n }\n\n if (pageModule.getStaticData) {\n return await this.staticFetcher.fetch(pageModule, context);\n }\n\n if (pageModule.getServerData) {\n return await this.serverFetcher.fetch(pageModule, context);\n }\n\n return { props: {} };\n }\n\n async getStaticPaths(pageModule: PageWithData): Promise<StaticPathsResult | null> {\n return await this.pathsFetcher.fetch(pageModule);\n }\n\n clearCache(pattern?: string): void {\n if (pattern) {\n this.cacheManager.clearPattern(pattern);\n } else {\n this.cacheManager.clear();\n }\n }\n}\n", "import { LRUCache } from \"@veryfront/utils/lru-wrapper.ts\";\nimport {\n DATA_FETCHING_MAX_ENTRIES,\n DATA_FETCHING_TTL_MS,\n} from \"@veryfront/utils/constants/cache.ts\";\nimport type { CacheEntry, DataContext } from \"./types.ts\";\nimport { getEnv } from \"../platform/compat/process.ts\";\n\nfunction isLruIntervalDisabled(): boolean {\n if ((globalThis as Record<string, unknown>).__vfDisableLruInterval === true) {\n return true;\n }\n try {\n return getEnv(\"VF_DISABLE_LRU_INTERVAL\") === \"1\";\n } catch {\n return false;\n }\n}\n\nexport class CacheManager {\n private cache = new LRUCache<string, CacheEntry>({\n maxEntries: DATA_FETCHING_MAX_ENTRIES,\n ttlMs: isLruIntervalDisabled() ? undefined : DATA_FETCHING_TTL_MS,\n });\n private cacheKeys = new Set<string>();\n\n get(key: string): CacheEntry | null {\n const entry = this.cache.get(key);\n return entry ?? null;\n }\n\n set(key: string, entry: CacheEntry): void {\n this.cache.set(key, entry);\n this.cacheKeys.add(key);\n }\n\n delete(key: string): void {\n this.cache.delete(key);\n this.cacheKeys.delete(key);\n }\n\n clear(): void {\n this.cache.clear();\n this.cacheKeys.clear();\n }\n\n clearPattern(pattern: string): void {\n for (const key of this.cacheKeys) {\n if (key.includes(pattern)) {\n this.delete(key);\n }\n }\n }\n\n shouldRevalidate(entry: CacheEntry): boolean {\n if (entry.revalidate === false) {\n return false;\n }\n\n if (typeof entry.revalidate === \"number\") {\n const age = Date.now() - entry.timestamp;\n return age > entry.revalidate * 1000;\n }\n\n return false;\n }\n\n createCacheKey(context: DataContext): string {\n const params = JSON.stringify(context.params);\n const pathname = context.url.pathname;\n return `${pathname}::${params}`;\n }\n}\n", "import type { RuntimeAdapter } from \"@veryfront/platform/adapters/index.ts\";\nimport type { DataContext, DataResult, PageWithData } from \"./types.ts\";\nimport { serverLogger } from \"@veryfront/utils\";\n\nexport class ServerDataFetcher {\n constructor(private adapter?: RuntimeAdapter) {}\n\n async fetch(pageModule: PageWithData, context: DataContext): Promise<DataResult> {\n if (!pageModule.getServerData) {\n return { props: {} };\n }\n\n try {\n const result = await pageModule.getServerData(context);\n\n if (result.redirect) {\n return { redirect: result.redirect };\n }\n\n if (result.notFound) {\n return { notFound: true };\n }\n\n return {\n props: result.props ?? {},\n revalidate: result.revalidate,\n };\n } catch (error) {\n this.logError(\"Error in getServerData:\", error);\n throw error;\n }\n }\n\n private logError(message: string, error: unknown): void {\n const debugEnabled = this.adapter?.env.get(\"VERYFRONT_DEBUG\");\n if (debugEnabled) {\n serverLogger.error(message, error);\n }\n }\n}\n", "import type { RuntimeAdapter } from \"@veryfront/platform/adapters/index.ts\";\nimport type { CacheManager } from \"./data-fetching-cache.ts\";\nimport type { DataContext, DataResult, PageWithData } from \"./types.ts\";\nimport { serverLogger } from \"@veryfront/utils\";\n\nexport class StaticDataFetcher {\n private pendingRevalidations = new Map<string, Promise<void>>();\n\n constructor(\n private cacheManager: CacheManager,\n private adapter?: RuntimeAdapter,\n ) {}\n\n async fetch(pageModule: PageWithData, context: DataContext): Promise<DataResult> {\n if (!pageModule.getStaticData) {\n return { props: {} };\n }\n\n const cacheKey = this.cacheManager.createCacheKey(context);\n const cached = this.cacheManager.get(cacheKey);\n\n if (cached && !this.cacheManager.shouldRevalidate(cached)) {\n return cached.data;\n }\n\n if (cached && this.cacheManager.shouldRevalidate(cached)) {\n if (!this.pendingRevalidations.has(cacheKey)) {\n this.pendingRevalidations.set(\n cacheKey,\n this.revalidateInBackground(pageModule, context, cacheKey),\n );\n }\n return cached.data;\n }\n\n return await this.fetchFresh(pageModule, context, cacheKey);\n }\n\n private async fetchFresh(\n pageModule: PageWithData,\n context: DataContext,\n cacheKey: string,\n ): Promise<DataResult> {\n if (!pageModule.getStaticData) {\n return { props: {} };\n }\n\n try {\n const result = await pageModule.getStaticData({\n params: context.params,\n url: context.url,\n });\n\n this.cacheManager.set(cacheKey, {\n data: result,\n timestamp: Date.now(),\n revalidate: result.revalidate,\n });\n\n return result;\n } catch (error) {\n this.logError(\"Error in getStaticData:\", error);\n throw error;\n }\n }\n\n private async revalidateInBackground(\n pageModule: PageWithData,\n context: DataContext,\n cacheKey: string,\n ): Promise<void> {\n try {\n if (!pageModule.getStaticData) {\n return;\n }\n\n const result = await pageModule.getStaticData({\n params: context.params,\n url: context.url,\n });\n\n this.cacheManager.set(cacheKey, {\n data: result,\n timestamp: Date.now(),\n revalidate: result.revalidate,\n });\n } catch (error) {\n this.logError(\"Error revalidating data:\", error);\n } finally {\n this.pendingRevalidations.delete(cacheKey);\n }\n }\n\n private logError(message: string, error: unknown): void {\n const debugEnabled = this.adapter?.env.get(\"VERYFRONT_DEBUG\");\n if (debugEnabled) {\n serverLogger.error(message, error);\n }\n }\n}\n", "import type { PageWithData, StaticPathsResult } from \"./types.ts\";\nimport { serverLogger } from \"@veryfront/utils\";\n\nexport class StaticPathsFetcher {\n async fetch(pageModule: PageWithData): Promise<StaticPathsResult | null> {\n if (!pageModule.getStaticPaths) {\n return null;\n }\n\n try {\n return await pageModule.getStaticPaths();\n } catch (error) {\n this.logError(\"Error in getStaticPaths:\", error);\n throw error;\n }\n }\n\n private logError(message: string, error: unknown): void {\n serverLogger.error(message, error);\n }\n}\n", "import type { DataResult } from \"./types.ts\";\n\nexport const redirect = (destination: string, permanent = false): DataResult => ({\n redirect: { destination, permanent },\n});\n\nexport const notFound = (): DataResult => ({\n notFound: true,\n});\n", "export type { Route, RouteMatch } from \"./matchers/index.ts\";\nexport {\n DynamicRouter,\n getSpecificityScore,\n matchRoute,\n normalizePath,\n parseRoute,\n} from \"./matchers/index.ts\";\n\nexport type { PathCandidates, RouteParams } from \"./slug-mapper/index.ts\";\nexport {\n extractParams,\n getPathCandidates,\n getSlugFromPath,\n getSupportedExtensions,\n isDynamicRoute,\n matchesPattern,\n normalizeSlug,\n pathToSlug,\n slugToPath,\n} from \"./slug-mapper/index.ts\";\n\nexport type { RouteData } from \"./client/index.ts\";\nexport {\n extractPageDataFromScript,\n NavigationHandlers,\n PageLoader,\n PageTransition,\n ViewportPrefetch,\n} from \"./client/index.ts\";\n\nexport type { APIContext, APIHandler, APIResponse, APIRoute } from \"./api/index.ts\";\nexport {\n APIRouteHandler,\n applyCORSHeaders,\n badRequest,\n createContext,\n forbidden,\n handleCORSPreflight,\n json,\n normalizeParams,\n notFound,\n parseCookies,\n redirect,\n serverError,\n unauthorized,\n} from \"./api/index.ts\";\n", "export type { Route, RouteMatch } from \"./types.ts\";\n\nexport { DynamicRouter } from \"./pattern-route-matcher.ts\";\n\nexport { getSpecificityScore, parseRoute } from \"./route-parser.ts\";\nexport { matchRoute } from \"./route-matcher.ts\";\nexport { normalizePath } from \"@veryfront/utils\";\n", "import type { Route, RouteMatch } from \"./types.ts\";\nimport { getSpecificityScore, parseRoute } from \"./route-parser.ts\";\nimport { matchRoute } from \"./route-matcher.ts\";\nimport { normalizePath } from \"@veryfront/utils/path-utils.ts\";\n\nexport class DynamicRouter {\n private routes: Route[] = [];\n private cache = new Map<string, RouteMatch | null>();\n\n addRoute(pattern: string, page: string): void {\n const route = parseRoute(pattern, page);\n this.routes.push(route);\n this.routes.sort((a, b) => {\n const aScore = getSpecificityScore(a);\n const bScore = getSpecificityScore(b);\n return bScore - aScore;\n });\n }\n\n match(pathname: string): RouteMatch | null {\n if (this.cache.has(pathname)) {\n return this.cache.get(pathname)!;\n }\n\n pathname = normalizePath(pathname);\n\n for (const route of this.routes) {\n const match = matchRoute(pathname, route);\n if (match) {\n this.cache.set(pathname, match);\n return match;\n }\n }\n\n this.cache.set(pathname, null);\n return null;\n }\n\n clearCache(): void {\n this.cache.clear();\n }\n\n getRoutes(): Route[] {\n return [...this.routes];\n }\n}\n", "import type { Route } from \"./types.ts\";\n\nexport function parseRoute(pattern: string, page: string): Route {\n const orderedParamNames: string[] = [];\n let isCatchAll = false;\n let isOptionalCatchAll = false;\n\n for (const match of pattern.matchAll(/\\[\\[\\.\\.\\.(\\w+)\\]\\]|\\[\\.\\.\\.(\\w+)\\]|\\[(\\w+)\\]/g)) {\n if (match[1]) {\n const name = match[1];\n orderedParamNames.push(name);\n isOptionalCatchAll = true;\n isCatchAll = true;\n } else if (match[2]) {\n const name = match[2];\n orderedParamNames.push(name);\n isCatchAll = true;\n } else if (match[3]) {\n orderedParamNames.push(match[3]);\n }\n }\n\n let regexPattern = pattern;\n\n regexPattern = regexPattern.replace(/\\[\\[\\.\\.\\.(\\w+)\\]\\]/g, () => {\n return \"___OPTIONAL_CATCHALL___\";\n });\n\n regexPattern = regexPattern.replace(/\\[\\.\\.\\.(\\w+)\\]/g, () => {\n return \"___CATCHALL___\";\n });\n\n regexPattern = regexPattern.replace(/\\[(\\w+)\\]/g, () => {\n return \"___PARAM___\";\n });\n\n regexPattern = regexPattern.replace(/[-/\\\\^$*+?.()|[\\]{}]/g, \"\\\\$&\");\n\n regexPattern = regexPattern\n .replace(/___OPTIONAL_CATCHALL___/g, \"(.*)\")\n .replace(/___CATCHALL___/g, \"(.+)\")\n .replace(/___PARAM___/g, \"([^/]+)\");\n\n if (isOptionalCatchAll) {\n regexPattern = regexPattern.replace(/\\\\\\/\\(\\.\\*\\)$/, \"(?:\\\\/(.*))?\");\n }\n\n return {\n pattern,\n page,\n regex: new RegExp(`^${regexPattern}$`),\n paramNames: orderedParamNames,\n isCatchAll,\n isOptionalCatchAll,\n };\n}\n\nexport function getSpecificityScore(route: Route): number {\n let score = 0;\n const segments = route.pattern.split(\"/\").filter(Boolean);\n\n for (const segment of segments) {\n if (segment.includes(\"[[...\")) {\n score += 1; // Optional catch-all - lowest priority\n } else if (segment.includes(\"[...\")) {\n score += 2; // Catch-all\n } else if (segment.includes(\"[\")) {\n score += 3; // Dynamic segment\n } else {\n score += 4; // Static segment - highest priority\n }\n }\n\n score += segments.length * 0.1;\n\n return score;\n}\n", "import type { Route, RouteMatch } from \"./types.ts\";\n\nexport function matchRoute(pathname: string, route: Route): RouteMatch | null {\n const match = pathname.match(route.regex!);\n if (!match) return null;\n\n const params: Record<string, string | string[]> = {};\n\n const catchAllParamNames = new Set<string>();\n if (route.pattern) {\n route.pattern.replace(/\\[\\[\\.\\.\\.(\\w+)\\]\\]/g, (_, paramName: string) => {\n catchAllParamNames.add(paramName);\n return \"\";\n });\n route.pattern.replace(/\\[\\.\\.\\.(\\w+)\\]/g, (_, paramName: string) => {\n catchAllParamNames.add(paramName);\n return \"\";\n });\n }\n\n route.paramNames?.forEach((name, index) => {\n const value = match[index + 1];\n\n if (catchAllParamNames.has(name)) {\n const segments = value ? value.split(\"/\").filter((segment) => segment.length > 0) : [];\n params[name] = segments.map((segment) => decodeURIComponent(segment));\n } else {\n params[name] = decodeURIComponent(value || \"\");\n }\n });\n\n return { params, route };\n}\n", "export type { PathCandidates, RouteParams } from \"./types.ts\";\n\nexport { getPathCandidates, getSupportedExtensions } from \"./path-candidate-generator.ts\";\nexport { extractParams, isDynamicRoute, matchesPattern } from \"./dynamic-route-matcher.ts\";\nexport { getSlugFromPath, normalizeSlug, pathToSlug, slugToPath } from \"./slug-normalizer.ts\";\n", "import { join } from \"../../platform/compat/path-helper.ts\";\nimport type { PathCandidates } from \"./types.ts\";\n\nconst SUPPORTED_EXTENSIONS = [\".mdx\", \".tsx\", \".jsx\", \".ts\", \".js\"];\n\nexport function generateAppRouterCandidates(\n projectDir: string,\n normalizedSlug: string,\n): string[] {\n const candidates: string[] = [];\n\n if (normalizedSlug) {\n const base = join(projectDir, \"app\", normalizedSlug);\n\n for (const ext of SUPPORTED_EXTENSIONS) {\n candidates.push(`${base}/page${ext}`);\n }\n\n for (const ext of SUPPORTED_EXTENSIONS) {\n candidates.push(`${base}${ext}`);\n }\n } else {\n const appBase = join(projectDir, \"app\");\n for (const ext of SUPPORTED_EXTENSIONS) {\n candidates.push(`${appBase}/page${ext}`);\n }\n }\n\n return candidates;\n}\n\nexport function generatePagesRouterCandidates(\n projectDir: string,\n normalizedSlug: string,\n): string[] {\n const candidates: string[] = [];\n\n if (normalizedSlug === \"\" || normalizedSlug === \"index\") {\n for (const ext of SUPPORTED_EXTENSIONS) {\n candidates.push(join(projectDir, \"pages\", `index${ext}`));\n candidates.push(join(projectDir, `index${ext}`));\n }\n } else {\n for (const ext of SUPPORTED_EXTENSIONS) {\n candidates.push(join(projectDir, \"pages\", `${normalizedSlug}${ext}`));\n\n candidates.push(\n join(projectDir, \"pages\", normalizedSlug, `index${ext}`),\n );\n\n candidates.push(join(projectDir, `${normalizedSlug}${ext}`));\n }\n }\n\n return candidates;\n}\n\nexport function getPathCandidates(\n projectDir: string,\n slug: string,\n): PathCandidates {\n const normalizedSlug = slug || \"\";\n\n return {\n appRouter: generateAppRouterCandidates(projectDir, normalizedSlug),\n pagesRouter: generatePagesRouterCandidates(projectDir, normalizedSlug),\n };\n}\n\nexport function getSupportedExtensions(): string[] {\n return [...SUPPORTED_EXTENSIONS];\n}\n", "// Conditional imports for path module\nimport nodePath from \"node:path\";\nimport type { PlatformPath } from \"node:path\";\n\n// Use node:path for Node.js or import Deno's std/path for Deno\nlet pathMod: PlatformPath | null = null;\n\n// Initialize path module synchronously for Node.js\n// @ts-ignore - Deno global\nif (typeof Deno === \"undefined\") {\n pathMod = nodePath;\n} else {\n // Deno environment - start loading asynchronously but don't await\n // @ts-ignore - Deno global\n import(\"std/path/mod.ts\").then((mod) => {\n pathMod = mod as unknown as PlatformPath;\n });\n}\n\n// Helper to get path module, ensuring it's loaded\nfunction getPathMod(): PlatformPath {\n if (pathMod) return pathMod;\n // In Deno, if pathMod is not yet loaded, use Node.js path as temporary fallback\n // This should rarely happen as the import is fast\n return nodePath;\n}\n\n// Re-export common path functions with proper types\nexport const basename = (path: string, suffix?: string): string =>\n getPathMod().basename(path, suffix);\nexport const dirname = (path: string): string => getPathMod().dirname(path);\nexport const fromFileUrl = (url: string | URL): string => {\n const mod = getPathMod();\n // @ts-ignore - Deno path module has fromFileUrl\n if (mod && typeof (mod as any).fromFileUrl === \"function\") {\n // @ts-ignore - Deno path module has fromFileUrl\n return (mod as any).fromFileUrl(url);\n }\n // Fallback for Node.js where fromFileUrl might not be directly available\n // This uses URL parsing which is generally cross-platform\n const urlObj = typeof url === \"string\" ? new URL(url) : url;\n return urlObj.pathname;\n};\nexport const join = (...paths: string[]): string => getPathMod().join(...paths);\nexport const relative = (from: string, to: string): string => getPathMod().relative(from, to);\nexport const resolve = (...paths: string[]): string => getPathMod().resolve(...paths);\nexport const extname = (path: string): string => getPathMod().extname(path);\nexport const isAbsolute = (path: string): boolean => getPathMod().isAbsolute(path);\n// Export sep - uses getter function to ensure pathMod is resolved\nexport const sep: string = nodePath.sep;\n", "import type { RouteParams } from \"./types.ts\";\n\nexport function isDynamicRoute(pattern: string): boolean {\n return /\\[[\\w.]+\\]/.test(pattern);\n}\n\nexport function extractParams(\n pattern: string,\n slug: string,\n): RouteParams | null {\n const patternParts = pattern.split(\"/\").filter(Boolean);\n const slugParts = slug.split(\"/\").filter(Boolean);\n\n const params: RouteParams = {};\n\n let hasSpreadParam = false;\n for (const part of patternParts) {\n if (part.startsWith(\"[...\") && part.endsWith(\"]\")) {\n hasSpreadParam = true;\n break;\n }\n }\n\n if (!hasSpreadParam && patternParts.length !== slugParts.length) {\n return null;\n }\n\n let slugIndex = 0;\n\n for (let i = 0; i < patternParts.length; i++) {\n const patternPart = patternParts[i];\n if (!patternPart) continue;\n\n if (patternPart.startsWith(\"[...\") && patternPart.endsWith(\"]\")) {\n const paramName = patternPart.slice(4, -1);\n const remainingParts = slugParts.slice(slugIndex);\n params[paramName] = remainingParts;\n return params;\n }\n\n if (patternPart.startsWith(\"[\") && patternPart.endsWith(\"]\")) {\n const paramName = patternPart.slice(1, -1);\n if (slugIndex >= slugParts.length) {\n return null;\n }\n const slugPart = slugParts[slugIndex];\n if (slugPart !== undefined) {\n params[paramName] = slugPart;\n }\n slugIndex++;\n continue;\n }\n\n if (slugIndex >= slugParts.length || slugParts[slugIndex] !== patternPart) {\n return null;\n }\n slugIndex++;\n }\n\n if (slugIndex < slugParts.length) {\n return null;\n }\n\n return params;\n}\n\nexport function matchesPattern(pattern: string, slug: string): boolean {\n return extractParams(pattern, slug) !== null;\n}\n", "export function normalizeSlug(slug: string): string {\n return slug\n .split(\"/\")\n .filter((part) => part.length > 0)\n .join(\"/\");\n}\n\nexport function slugToPath(slug: string): string {\n const normalized = normalizeSlug(slug);\n return normalized ? `/${normalized}` : \"/\";\n}\n\nexport function pathToSlug(path: string): string {\n return normalizeSlug(path.replace(/^\\//, \"\"));\n}\n\nexport function getSlugFromPath(filePath: string): string {\n const parts = filePath.split(\"/\");\n const fileName = parts[parts.length - 1] || \"\";\n\n const slug = fileName.replace(/\\.(mdx?|tsx?|jsx?|ts|js)$/, \"\");\n\n if (slug === \"index\" || slug === \"page\") {\n const parentDir = parts[parts.length - 2];\n return parentDir === \"pages\" || parentDir === \"app\" ? \"\" : parentDir || \"\";\n }\n\n return slug;\n}\n", "export {\n applyHeadDirectives,\n executeScripts,\n extractPageDataFromScript,\n findAnchorElement,\n isInternalLink,\n manageFocus,\n parsePageDataFromHTML,\n updateMetaTags,\n} from \"./dom-utils.ts\";\n\nexport { NavigationHandlers } from \"./navigation-handlers.ts\";\nexport type { NavigationCallbacks } from \"./navigation-handlers.ts\";\n\nexport { PageLoader } from \"./page-loader.ts\";\nexport type { ComponentMap, FrontmatterData, PageData, RouteData } from \"./page-loader.ts\";\n\nexport { PageTransition } from \"./page-transition.ts\";\n\nexport { ViewportPrefetch } from \"./viewport-prefetch.ts\";\n", "import { rendererLogger as logger } from \"@veryfront/utils\";\nimport type { FrontmatterData, PageData } from \"./types.ts\";\n\nexport function isInternalLink(target: HTMLAnchorElement): boolean {\n const href = target.getAttribute(\"href\");\n\n if (!href) return false;\n if (href.startsWith(\"http\") || href.startsWith(\"mailto:\")) return false;\n if (href.startsWith(\"#\")) return false;\n if (target.getAttribute(\"target\") === \"_blank\" || target.getAttribute(\"download\")) {\n return false;\n }\n\n return true;\n}\n\nexport function findAnchorElement(element: HTMLElement | null): HTMLAnchorElement | null {\n let current = element;\n while (current && current.tagName !== \"A\") {\n current = current.parentElement;\n }\n\n if (!current || !(current instanceof HTMLAnchorElement)) {\n return null;\n }\n\n return current;\n}\n\nexport function updateMetaTags(frontmatter: FrontmatterData): void {\n if (frontmatter.description) {\n updateMetaTag('meta[name=\"description\"]', \"name\", \"description\", frontmatter.description);\n }\n\n if (frontmatter.ogTitle) {\n updateMetaTag('meta[property=\"og:title\"]', \"property\", \"og:title\", frontmatter.ogTitle);\n }\n}\n\nfunction updateMetaTag(\n selector: string,\n attributeName: string,\n attributeValue: string,\n content: string,\n): void {\n let metaTag = document.querySelector(selector);\n if (!metaTag) {\n metaTag = document.createElement(\"meta\");\n metaTag.setAttribute(attributeName, attributeValue);\n document.head.appendChild(metaTag);\n }\n metaTag.setAttribute(\"content\", content);\n}\n\nexport function executeScripts(container: HTMLElement): void {\n const scripts = container.querySelectorAll(\"script\");\n scripts.forEach((oldScript) => {\n const newScript = document.createElement(\"script\");\n Array.from(oldScript.attributes).forEach((attribute) => {\n newScript.setAttribute(attribute.name, attribute.value);\n });\n newScript.textContent = oldScript.textContent;\n oldScript.parentNode?.replaceChild(newScript, oldScript);\n });\n}\n\nexport function applyHeadDirectives(container: HTMLElement): void {\n const nodes = container.querySelectorAll('[data-veryfront-head=\"1\"], vf-head');\n if (nodes.length > 0) {\n cleanManagedHeadTags();\n }\n\n nodes.forEach((wrapper) => {\n processHeadWrapper(wrapper);\n wrapper.parentElement?.removeChild(wrapper);\n });\n}\n\nfunction cleanManagedHeadTags(): void {\n document.head\n .querySelectorAll('[data-veryfront-managed=\"1\"]')\n .forEach((element) => element.parentElement?.removeChild(element));\n}\n\nfunction processHeadWrapper(wrapper: Element): void {\n wrapper.childNodes.forEach((node) => {\n if (!(node instanceof Element)) return;\n\n const tagName = node.tagName.toLowerCase();\n if (tagName === \"title\") {\n document.title = node.textContent || document.title;\n return;\n }\n\n const clone = document.createElement(tagName);\n for (const attribute of Array.from(node.attributes)) {\n clone.setAttribute(attribute.name, attribute.value);\n }\n if (node.textContent && !clone.hasAttribute(\"src\")) {\n clone.textContent = node.textContent;\n }\n clone.setAttribute(\"data-veryfront-managed\", \"1\");\n document.head.appendChild(clone);\n });\n}\n\nexport function manageFocus(container: HTMLElement): void {\n try {\n const focusElement = (container.querySelector(\"[data-router-focus]\") ||\n container.querySelector(\"main\") ||\n container.querySelector(\"h1\")) as HTMLElement | null;\n\n if (focusElement && focusElement instanceof HTMLElement && \"focus\" in focusElement) {\n focusElement.focus({ preventScroll: true });\n }\n } catch (error) {\n logger.warn(\"[router] focus management failed\", error);\n }\n}\n\nexport function extractPageDataFromScript(): PageData | null {\n const pageDataScript = document.querySelector(\"script[data-veryfront-page]\");\n if (!pageDataScript) return null;\n\n try {\n const content = pageDataScript.textContent;\n if (!content) {\n logger.warn(\"[dom-utils] Page data script has no content\");\n return {};\n }\n return JSON.parse(content) as PageData;\n } catch (error) {\n logger.error(\"[dom-utils] Failed to parse page data:\", error);\n return null;\n }\n}\n\nexport function parsePageDataFromHTML(html: string): {\n content: string;\n pageData: PageData;\n} {\n const parser = new DOMParser();\n const doc = parser.parseFromString(html, \"text/html\");\n\n const root = doc.getElementById(\"root\");\n let content = \"\";\n\n if (root) {\n content = root.innerHTML || \"\";\n } else {\n logger.warn(\"[dom-utils] No root element found in HTML\");\n }\n\n const pageDataScript = doc.querySelector(\"script[data-veryfront-page]\");\n let pageData: PageData = {};\n\n if (pageDataScript) {\n try {\n const content = pageDataScript.textContent;\n if (!content) {\n logger.warn(\"[dom-utils] Page data script in HTML has no content\");\n } else {\n pageData = JSON.parse(content) as PageData;\n }\n } catch (error) {\n logger.error(\"[dom-utils] Failed to parse page data from HTML:\", error);\n }\n }\n\n return { content, pageData };\n}\n", "import { rendererLogger as logger } from \"@veryfront/utils\";\nimport { DEFAULT_PREFETCH_DELAY_MS } from \"@veryfront/config\";\nimport { findAnchorElement, isInternalLink } from \"./dom-utils.ts\";\n\nexport interface NavigationCallbacks {\n onNavigate: (url: string) => Promise<void>;\n onPrefetch: (url: string) => void;\n}\n\nexport class NavigationHandlers {\n private prefetchQueue = new Set<string>();\n private scrollPositions = new Map<string, number>();\n private isPopStateNav = false;\n private prefetchDelay: number;\n private prefetchOptions: {\n hover?: boolean;\n viewport?: boolean;\n };\n\n constructor(\n prefetchDelay = DEFAULT_PREFETCH_DELAY_MS,\n prefetchOptions: { hover?: boolean; viewport?: boolean } = {},\n ) {\n this.prefetchDelay = prefetchDelay;\n this.prefetchOptions = prefetchOptions;\n }\n\n createClickHandler(callbacks: NavigationCallbacks) {\n return (event: MouseEvent) => {\n const anchor = findAnchorElement(event.target as HTMLElement);\n if (!anchor || !isInternalLink(anchor)) return;\n\n const href = anchor.getAttribute(\"href\")!;\n event.preventDefault();\n callbacks.onNavigate(href);\n };\n }\n\n createPopStateHandler(callbacks: NavigationCallbacks) {\n return (_event: PopStateEvent) => {\n const path = globalThis.location.pathname;\n this.isPopStateNav = true;\n callbacks.onNavigate(path);\n };\n }\n\n createMouseOverHandler(callbacks: NavigationCallbacks) {\n return (event: MouseEvent) => {\n const target = event.target as HTMLElement;\n if (target.tagName !== \"A\") return;\n\n const href = target.getAttribute(\"href\");\n if (!href || href.startsWith(\"http\") || href.startsWith(\"#\")) return;\n\n if (!this.shouldPrefetchOnHover(target)) return;\n\n if (!this.prefetchQueue.has(href)) {\n this.prefetchQueue.add(href);\n setTimeout(() => {\n callbacks.onPrefetch(href);\n this.prefetchQueue.delete(href);\n }, this.prefetchDelay);\n }\n };\n }\n\n private shouldPrefetchOnHover(target: HTMLElement): boolean {\n const prefetchAttribute = target.getAttribute(\"data-prefetch\");\n const isHoverEnabled = Boolean(this.prefetchOptions.hover);\n\n if (prefetchAttribute === \"false\") return false;\n\n return prefetchAttribute === \"true\" || isHoverEnabled;\n }\n\n saveScrollPosition(path: string): void {\n try {\n const scrollY = globalThis.scrollY;\n if (typeof scrollY === \"number\") {\n this.scrollPositions.set(path, scrollY);\n } else {\n logger.debug(\"[router] No valid scrollY value available\");\n this.scrollPositions.set(path, 0);\n }\n } catch (error) {\n logger.warn(\"[router] failed to record scroll position\", error);\n }\n }\n\n getScrollPosition(path: string): number {\n const position = this.scrollPositions.get(path);\n if (position === undefined) {\n logger.debug(`[router] No scroll position stored for ${path}`);\n return 0;\n }\n return position;\n }\n\n isPopState(): boolean {\n return this.isPopStateNav;\n }\n\n clearPopStateFlag(): void {\n this.isPopStateNav = false;\n }\n\n clear(): void {\n this.prefetchQueue.clear();\n this.scrollPositions.clear();\n this.isPopStateNav = false;\n }\n}\n", "import { rendererLogger as logger } from \"@veryfront/utils\";\nimport { NetworkError } from \"@veryfront/errors/index.ts\";\nimport { parsePageDataFromHTML } from \"./dom-utils.ts\";\n\nexport type { ComponentMap, FrontmatterData, PageData, RouteData } from \"./types.ts\";\nimport type { RouteData } from \"./types.ts\";\n\nexport class PageLoader {\n private cache = new Map<string, RouteData>();\n\n getCached(path: string): RouteData | undefined {\n return this.cache.get(path);\n }\n\n isCached(path: string): boolean {\n return this.cache.has(path);\n }\n\n setCache(path: string, data: RouteData): void {\n this.cache.set(path, data);\n }\n\n clearCache(): void {\n this.cache.clear();\n }\n\n async fetchPageData(path: string): Promise<RouteData> {\n const jsonData = await this.tryFetchJSON(path);\n if (jsonData) return jsonData;\n\n return this.fetchAndParseHTML(path);\n }\n\n private async tryFetchJSON(path: string): Promise<RouteData | null> {\n try {\n const response = await fetch(`/_veryfront/data${path}.json`, {\n headers: { \"X-Veryfront-Navigation\": \"client\" },\n });\n\n if (response.ok) {\n return await response.json();\n }\n } catch (error) {\n logger.debug(`[PageLoader] RSC fetch failed for ${path}, falling back to HTML:`, error);\n }\n\n return null;\n }\n\n private async fetchAndParseHTML(path: string): Promise<RouteData> {\n const response = await fetch(path, {\n headers: { \"X-Veryfront-Navigation\": \"client\" },\n });\n\n if (!response.ok) {\n throw new NetworkError(`Failed to fetch ${path}`, {\n status: response.status,\n path,\n });\n }\n\n const html = await response.text();\n const { content, pageData } = parsePageDataFromHTML(html);\n\n return {\n html: content,\n ...pageData,\n };\n }\n\n async loadPage(path: string): Promise<RouteData> {\n const cachedData = this.getCached(path);\n if (cachedData) {\n logger.debug(`Loading ${path} from cache`);\n return cachedData;\n }\n\n const data = await this.fetchPageData(path);\n this.setCache(path, data);\n\n return data;\n }\n\n async prefetch(path: string): Promise<void> {\n if (this.isCached(path)) return;\n\n logger.debug(`Prefetching ${path}`);\n\n try {\n const data = await this.fetchPageData(path);\n this.setCache(path, data);\n } catch (error) {\n logger.warn(`Failed to prefetch ${path}`, error as Error);\n }\n }\n}\n", "import { rendererLogger as logger } from \"@veryfront/utils\";\nimport { PAGE_TRANSITION_DELAY_MS } from \"@veryfront/config\";\nimport { applyHeadDirectives, executeScripts, manageFocus, updateMetaTags } from \"./dom-utils.ts\";\nimport { validateTrustedHtml } from \"@veryfront/security/client/html-sanitizer.ts\";\nimport type { RouteData } from \"./page-loader.ts\";\n\nexport class PageTransition {\n private setupViewportPrefetch: (root: Document | HTMLElement) => void;\n private pendingTransitionTimeout?: number;\n\n constructor(setupViewportPrefetch: (root: Document | HTMLElement) => void) {\n this.setupViewportPrefetch = setupViewportPrefetch;\n }\n\n destroy(): void {\n if (this.pendingTransitionTimeout !== undefined) {\n clearTimeout(this.pendingTransitionTimeout);\n this.pendingTransitionTimeout = undefined;\n }\n }\n\n updatePage(data: RouteData, isPopState: boolean, scrollY: number): void {\n if (data.frontmatter?.title) {\n document.title = data.frontmatter.title;\n }\n\n updateMetaTags(data.frontmatter ?? {});\n\n const rootElement = document.getElementById(\"root\");\n if (rootElement && (data.html ?? \"\") !== \"\") {\n this.performTransition(rootElement, data, isPopState, scrollY);\n }\n }\n\n private performTransition(\n rootElement: HTMLElement,\n data: RouteData,\n isPopState: boolean,\n scrollY: number,\n ): void {\n if (this.pendingTransitionTimeout !== undefined) {\n clearTimeout(this.pendingTransitionTimeout);\n }\n\n rootElement.style.opacity = \"0\";\n\n this.pendingTransitionTimeout = setTimeout(() => {\n this.pendingTransitionTimeout = undefined;\n // Server-rendered RSC HTML is trusted; validateTrustedHtml provides defense-in-depth\n rootElement.innerHTML = validateTrustedHtml(String(data.html ?? \"\"));\n rootElement.style.opacity = \"1\";\n\n executeScripts(rootElement);\n applyHeadDirectives(rootElement);\n this.setupViewportPrefetch(rootElement);\n manageFocus(rootElement);\n this.handleScroll(isPopState, scrollY);\n }, PAGE_TRANSITION_DELAY_MS);\n }\n\n private handleScroll(isPopState: boolean, scrollY: number): void {\n try {\n globalThis.scrollTo(0, isPopState ? scrollY : 0);\n } catch (error) {\n logger.warn(\"[router] scroll handling failed\", error);\n }\n }\n\n showError(error: Error): void {\n const rootElement = document.getElementById(\"root\");\n if (!rootElement) return;\n\n const errorDiv = document.createElement(\"div\");\n errorDiv.className = \"veryfront-error-page\";\n\n const heading = document.createElement(\"h1\");\n heading.textContent = \"Oops! Something went wrong\";\n\n const message = document.createElement(\"p\");\n message.textContent = error.message;\n\n const button = document.createElement(\"button\");\n button.type = \"button\";\n button.textContent = \"Reload Page\";\n button.onclick = () => globalThis.location.reload();\n\n errorDiv.appendChild(heading);\n errorDiv.appendChild(message);\n errorDiv.appendChild(button);\n\n rootElement.innerHTML = \"\";\n rootElement.appendChild(errorDiv);\n }\n\n setLoadingState(loading: boolean): void {\n const indicator = document.getElementById(\"veryfront-loading\");\n if (indicator) {\n indicator.style.display = loading ? \"block\" : \"none\";\n }\n\n document.body.classList.toggle(\"veryfront-loading\", loading);\n }\n}\n", "/**\n * Lightweight HTML sanitizer for client-side use.\n *\n * Security model:\n * - RSC HTML from React's renderToString() is trusted (auto-escapes user content)\n * - Error messages and debug info are untrusted and must be escaped\n * - validateTrustedHtml() provides defense-in-depth for server HTML\n */\n\n/**\n * Escape HTML entities to prevent XSS.\n * Use for untrusted strings that will be inserted into HTML.\n */\nexport function escapeHtml(str: string): string {\n return str\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/\"/g, \""\")\n .replace(/'/g, \"'\");\n}\n\n/**\n * Create text node safely (alternative to innerHTML for simple text).\n */\nexport function createSafeTextNode(text: string): Text {\n return document.createTextNode(text);\n}\n\n/**\n * Set text content safely (never interprets HTML).\n */\nexport function setSafeTextContent(element: HTMLElement, text: string): void {\n element.textContent = text;\n}\n\n/**\n * Patterns that RSC should never generate.\n * These indicate potential server compromise or misconfiguration.\n */\nconst SUSPICIOUS_PATTERNS = [\n { pattern: /<script[^>]*>[\\s\\S]*?<\\/script>/gi, name: \"inline script\" },\n { pattern: /javascript:/gi, name: \"javascript: URL\" },\n { pattern: /\\bon\\w+\\s*=/gi, name: \"event handler attribute\" },\n { pattern: /data:\\s*text\\/html/gi, name: \"data: HTML URL\" },\n];\n\n// Check if we're in development mode\nfunction isDevMode(): boolean {\n if (typeof globalThis !== \"undefined\") {\n // deno-lint-ignore no-explicit-any\n const g = globalThis as any;\n return g.__VERYFRONT_DEV__ === true || g.Deno?.env?.get?.(\"VERYFRONT_ENV\") === \"development\";\n }\n return false;\n}\n\nexport interface ValidateTrustedHtmlOptions {\n /** Throw on suspicious patterns even in dev mode */\n strict?: boolean;\n /** Log warnings for suspicious patterns */\n warn?: boolean;\n}\n\n/**\n * Validate trusted HTML from server (defense-in-depth).\n *\n * This is NOT a full sanitizer - server-rendered RSC content is trusted.\n * This catches scenarios where the server might be compromised or misconfigured.\n *\n * @param html - HTML string from server\n * @param options - Validation options\n * @returns The original HTML if valid\n * @throws Error if suspicious patterns detected in strict mode or production\n */\nexport function validateTrustedHtml(\n html: string,\n options: ValidateTrustedHtmlOptions = {},\n): string {\n const { strict = false, warn = true } = options;\n\n for (const { pattern, name } of SUSPICIOUS_PATTERNS) {\n // Reset regex state for global patterns\n pattern.lastIndex = 0;\n\n if (pattern.test(html)) {\n const message = `[Security] Suspicious ${name} detected in server HTML`;\n\n if (warn) {\n console.warn(message);\n }\n\n // In strict mode or production, throw\n if (strict || !isDevMode()) {\n throw new Error(`Potentially unsafe HTML: ${name} detected`);\n }\n }\n }\n\n return html;\n}\n\n/**\n * Create an error display element safely using DOM APIs.\n * Use this instead of innerHTML for displaying error messages.\n */\nexport function createErrorDisplay(options: {\n title: string;\n message: string;\n details?: string;\n style?: Partial<CSSStyleDeclaration>;\n}): HTMLDivElement {\n const { title, message, details, style } = options;\n\n const container = document.createElement(\"div\");\n\n // Apply default error styling\n Object.assign(container.style, {\n color: \"red\",\n border: \"2px solid red\",\n padding: \"10px\",\n margin: \"5px\",\n fontFamily: \"monospace\",\n fontSize: \"14px\",\n backgroundColor: \"#fff0f0\",\n ...style,\n });\n\n // Title\n const titleEl = document.createElement(\"strong\");\n titleEl.textContent = title;\n container.appendChild(titleEl);\n container.appendChild(document.createElement(\"br\"));\n\n // Message\n const messageEl = document.createElement(\"span\");\n messageEl.textContent = message;\n container.appendChild(messageEl);\n\n // Details (optional)\n if (details) {\n container.appendChild(document.createElement(\"br\"));\n const detailsEl = document.createElement(\"pre\");\n detailsEl.style.cssText = \"margin: 5px 0; white-space: pre-wrap; word-break: break-word;\";\n detailsEl.textContent = details;\n container.appendChild(detailsEl);\n }\n\n return container;\n}\n", "import { rendererLogger as logger } from \"@veryfront/utils\";\n\nexport class ViewportPrefetch {\n private observer: IntersectionObserver | null = null;\n private prefetchCallback: (path: string) => void;\n private prefetchOptions: {\n hover?: boolean;\n viewport?: boolean;\n };\n\n constructor(\n prefetchCallback: (path: string) => void,\n prefetchOptions: { hover?: boolean; viewport?: boolean } = {},\n ) {\n this.prefetchCallback = prefetchCallback;\n this.prefetchOptions = prefetchOptions;\n }\n\n setup(root: Document | HTMLElement): void {\n try {\n if (!(\"IntersectionObserver\" in globalThis)) return;\n\n if (this.observer) this.observer.disconnect();\n\n this.createObserver();\n this.observeLinks(root);\n } catch (error) {\n logger.debug(\"[router] setupViewportPrefetch failed\", error);\n }\n }\n\n private createObserver(): void {\n this.observer = new IntersectionObserver(\n (entries) => {\n for (const entry of entries) {\n if (entry.isIntersecting) {\n const isAnchor = typeof HTMLAnchorElement !== \"undefined\"\n ? entry.target instanceof HTMLAnchorElement\n : (entry.target as any).tagName === \"A\";\n\n if (isAnchor) {\n const href = (entry.target as HTMLAnchorElement).getAttribute(\"href\");\n if (href) {\n this.prefetchCallback(href);\n }\n this.observer?.unobserve(entry.target);\n }\n }\n }\n },\n { rootMargin: \"200px\" },\n );\n }\n\n private observeLinks(root: Document | HTMLElement): void {\n const anchors: NodeListOf<HTMLAnchorElement> =\n root.querySelectorAll?.('a[href]:not([target=\"_blank\"])') ??\n document.createDocumentFragment().querySelectorAll(\"a\");\n const isViewportEnabled = Boolean(this.prefetchOptions.viewport);\n\n anchors.forEach((anchor) => {\n if (this.shouldObserveAnchor(anchor, isViewportEnabled)) {\n this.observer?.observe(anchor);\n }\n });\n }\n\n private shouldObserveAnchor(anchor: HTMLAnchorElement, isViewportEnabled: boolean): boolean {\n const href = anchor.getAttribute(\"href\") || \"\";\n if (\n !href || href.startsWith(\"http\") || href.startsWith(\"#\") || anchor.getAttribute(\"download\")\n ) {\n return false;\n }\n\n const prefetchAttribute = anchor.getAttribute(\"data-prefetch\");\n if (prefetchAttribute === \"false\") return false;\n\n return prefetchAttribute === \"viewport\" || isViewportEnabled;\n }\n\n disconnect(): void {\n if (this.observer) {\n try {\n this.observer.disconnect();\n } catch (error) {\n logger.warn(\"[router] prefetchObserver.disconnect failed\", error);\n }\n this.observer = null;\n }\n }\n}\n", "export { APIRouteHandler } from \"./handler.ts\";\nexport type { APIContext, APIHandler, APIResponse, APIRoute } from \"./handler.ts\";\n\nexport { DynamicRouter } from \"./api-route-matcher.ts\";\nexport type { Route, RouteMatch } from \"./api-route-matcher.ts\";\n\nexport {\n badRequest,\n forbidden,\n json,\n notFound,\n redirect,\n serverError,\n unauthorized,\n} from \"./responses.ts\";\n\nexport { applyCORSHeaders, handleCORSPreflight } from \"@veryfront/security\";\n\nexport type { APIContext as APIContextType } from \"./context-builder.ts\";\nexport { createContext, normalizeParams, parseCookies } from \"./context-builder.ts\";\n", "import { serverLogger as logger } from \"@veryfront/utils\";\nimport { join } from \"std/path/mod.ts\";\nimport type { RuntimeAdapter } from \"@veryfront/platform/adapters/base.ts\";\nimport { getConfig } from \"@veryfront/config\";\nimport { LRUCache } from \"@veryfront/utils/lru-wrapper.ts\";\nimport { createError, toError } from \"../../core/errors/veryfront-error.ts\";\nimport { badGateway, internalServerError, notFound } from \"../../http/responses.ts\";\nimport type { CORSConfig } from \"@veryfront/security\";\nimport { applyCORSHeaders, handleCORSPreflight } from \"@veryfront/security\";\nimport { type APIContext } from \"./context-builder.ts\";\nimport { DynamicRouter, type RouteMatch } from \"./api-route-matcher.ts\";\nimport type { APIRoute } from \"./module-loader/types.ts\";\nimport { loadHandlerModule } from \"./module-loader/loader.ts\";\nimport { discoverAppRoutes, discoverPagesRoutes } from \"./route-discovery.ts\";\nimport { executeAppRoute, executePagesRoute } from \"./route-executor.ts\";\n\nexport type { APIContext, APIRoute };\n\nexport interface APIResponse {\n body?: unknown;\n status?: number;\n headers?: HeadersInit;\n}\n\nexport type APIHandler = (ctx: APIContext) => Promise<Response> | Response;\n\nexport class APIRouteHandler {\n private router: DynamicRouter;\n private routeCache = new LRUCache<string, APIRoute>({\n maxEntries: 256,\n });\n private lastErrorMessage: string | null = null;\n private adapter: RuntimeAdapter | null;\n private adapterPromise: Promise<RuntimeAdapter> | null = null;\n private corsConfig: boolean | CORSConfig | null = null;\n private corsConfigLoaded = false;\n private corsConfigPromise: Promise<void> | null = null;\n private config: Awaited<ReturnType<typeof getConfig>> | null = null;\n private configPromise: Promise<void> | null = null;\n\n constructor(\n private projectDir: string,\n adapter?: RuntimeAdapter,\n ) {\n this.router = new DynamicRouter();\n this.adapter = adapter ?? null;\n if (adapter) {\n this.adapterPromise = Promise.resolve(adapter);\n }\n }\n\n async initialize(): Promise<void> {\n const adapter = await this.ensureAdapter();\n await this.ensureConfig(adapter);\n\n const pagesDir = this.config?.directories?.pages || \"pages\";\n const apiDir = join(this.projectDir, pagesDir, \"api\");\n const apiDirExists = await adapter.fs.exists(apiDir);\n\n if (apiDirExists) {\n await discoverPagesRoutes(this.router, apiDir, \"/api\", adapter);\n }\n\n const appDirName = this.config?.directories?.app || \"app\";\n const appDir = join(this.projectDir, appDirName);\n const appDirExists = await adapter.fs.exists(appDir);\n\n if (appDirExists) {\n await discoverAppRoutes(this.router, appDir, \"\", adapter);\n }\n\n await this.ensureCorsConfig(adapter);\n }\n\n async handle(request: Request): Promise<Response | null> {\n const adapter = await this.ensureAdapter();\n const url = new URL(request.url);\n const pathname = url.pathname;\n\n if (request.method.toUpperCase() === \"OPTIONS\") {\n await this.ensureCorsConfig(adapter);\n return await handleCORSPreflight({\n request,\n config: this.corsConfig ?? undefined,\n });\n }\n\n await this.ensureCorsConfig(adapter);\n\n const match = this.router.match(pathname);\n\n if (!match) {\n if (pathname === \"/api\" || pathname.startsWith(\"/api/\")) {\n return notFound();\n }\n return null;\n }\n\n const handler = await this.loadHandler(match);\n\n if (!handler) {\n try {\n logger.error(`[API] handler module failed to load: ${match.route.page}`);\n } catch (e) {\n logger.warn(\"API error log failed\", e);\n }\n const msg = this.lastErrorMessage ?? \"Handler not found\";\n if (msg.includes(\"Remote import blocked by allow-list\")) {\n return badGateway(msg);\n }\n return internalServerError(\"Handler not found\");\n }\n\n const isAppRoute = /\\/(app)\\//.test(match.route.page);\n const response = isAppRoute\n ? await executeAppRoute(handler, request, match, pathname, adapter)\n : await executePagesRoute(handler, request, match, pathname, adapter);\n\n const corsResponse = await applyCORSHeaders({\n request,\n response,\n config: this.corsConfig ?? undefined,\n });\n return corsResponse ?? response;\n }\n\n private async loadHandler(match: RouteMatch): Promise<APIRoute | null> {\n const adapter = await this.ensureAdapter();\n await this.ensureConfig(adapter);\n const modulePath = match.route.page;\n\n const cached = this.routeCache.get(modulePath);\n if (cached) {\n return cached;\n }\n\n try {\n const handler = await loadHandlerModule({\n projectDir: this.projectDir,\n modulePath,\n adapter,\n config: this.config ?? undefined,\n });\n\n if (handler) {\n this.routeCache.set(modulePath, handler);\n }\n\n return handler;\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n this.lastErrorMessage = msg;\n return null;\n }\n }\n\n clearCache(): void {\n this.routeCache.clear();\n this.router.clearCache();\n }\n\n destroy(): void {\n this.routeCache.destroy();\n this.router.destroy();\n }\n\n private async ensureAdapter(): Promise<RuntimeAdapter> {\n if (this.adapter) return this.adapter;\n if (!this.adapterPromise) {\n const { getAdapter } = await import(\"@veryfront/platform/adapters/detect.ts\");\n\n this.adapterPromise = getAdapter();\n }\n this.adapter = await this.adapterPromise;\n if (!this.adapter) {\n throw toError(createError({\n type: \"api\",\n message: \"Failed to initialize runtime adapter\",\n }));\n }\n return this.adapter;\n }\n\n private async ensureCorsConfig(adapter: RuntimeAdapter): Promise<void> {\n if (this.corsConfigLoaded) return;\n if (!this.corsConfigPromise) {\n this.corsConfigPromise = this.loadCorsConfig(adapter);\n }\n await this.corsConfigPromise;\n }\n\n private async loadCorsConfig(adapter: RuntimeAdapter): Promise<void> {\n try {\n const config = await getConfig(this.projectDir, adapter);\n this.corsConfig = config.security?.cors ?? null;\n } catch (error) {\n this.corsConfig = null;\n try {\n logger.warn(\"Failed to load CORS configuration\", error);\n } catch (logError) {\n logger.error(\"Failed to log CORS config error:\", logError);\n }\n } finally {\n this.corsConfigLoaded = true;\n this.corsConfigPromise = null;\n }\n }\n\n private async ensureConfig(adapter: RuntimeAdapter): Promise<void> {\n if (this.config) return;\n if (!this.configPromise) {\n this.configPromise = this.loadFullConfig(adapter);\n }\n await this.configPromise;\n }\n\n private async loadFullConfig(adapter: RuntimeAdapter): Promise<void> {\n try {\n this.config = await getConfig(this.projectDir, adapter);\n } catch (error) {\n this.config = null;\n try {\n logger.warn(\"Failed to load config\", error);\n } catch (logError) {\n logger.error(\"Failed to log config error:\", logError);\n }\n } finally {\n this.configPromise = null;\n }\n }\n}\n\nexport {\n badRequest,\n forbidden,\n internalServerError as serverError,\n jsonResponse as json,\n notFound,\n redirectResponse as redirect,\n unauthorized,\n} from \"../../http/responses.ts\";\n", "/**\n * Centralized HTTP response factory for clean, consistent error handling.\n * Follows clean code principles: DRY, single responsibility, and clear naming.\n */\n\n/** HTTP Status codes as named constants for clarity */\nexport const HttpStatus = {\n OK: 200,\n CREATED: 201,\n NO_CONTENT: 204,\n MOVED_PERMANENTLY: 301,\n FOUND: 302,\n NOT_MODIFIED: 304,\n BAD_REQUEST: 400,\n UNAUTHORIZED: 401,\n FORBIDDEN: 403,\n NOT_FOUND: 404,\n METHOD_NOT_ALLOWED: 405,\n CONFLICT: 409,\n UNPROCESSABLE_ENTITY: 422,\n TOO_MANY_REQUESTS: 429,\n INTERNAL_SERVER_ERROR: 500,\n NOT_IMPLEMENTED: 501,\n BAD_GATEWAY: 502,\n SERVICE_UNAVAILABLE: 503,\n GATEWAY_TIMEOUT: 504,\n} as const;\n\nexport type HttpStatusCode = typeof HttpStatus[keyof typeof HttpStatus];\n\n/** Response options for additional headers and metadata */\ninterface ResponseOptions extends ResponseInit {\n headers?: HeadersInit;\n correlationId?: string;\n}\n\n/**\n * Creates a standardized error response.\n * Simple, clear, and consistent across the application.\n */\nexport function errorResponse(\n status: HttpStatusCode,\n message?: string,\n options?: ResponseOptions,\n): Response {\n const statusText = getStatusText(status);\n const body = message || statusText;\n\n const headers = new Headers(options?.headers);\n headers.set(\"Content-Type\", \"text/plain; charset=utf-8\");\n\n if (options?.correlationId) {\n headers.set(\"X-Correlation-Id\", options.correlationId);\n }\n\n return new Response(body, {\n ...options,\n status,\n statusText,\n headers,\n });\n}\n\n/**\n * Creates a JSON response with proper content type.\n * Handles serialization errors gracefully.\n */\nexport function jsonResponse<T>(\n data: T,\n status: HttpStatusCode = HttpStatus.OK,\n options?: ResponseOptions,\n): Response {\n const headers = new Headers(options?.headers);\n headers.set(\"Content-Type\", \"application/json; charset=utf-8\");\n\n try {\n const body = JSON.stringify(data);\n return new Response(body, {\n ...options,\n status,\n headers,\n });\n } catch {\n return errorResponse(\n HttpStatus.INTERNAL_SERVER_ERROR,\n \"Failed to serialize response data\",\n );\n }\n}\n\n/**\n * Creates a redirect response.\n * Validates URL to prevent open redirect vulnerabilities.\n */\nexport function redirectResponse(\n url: string,\n permanent = false,\n options?: ResponseOptions,\n): Response {\n // Simple URL validation to prevent open redirects\n if (!isValidRedirectUrl(url)) {\n return errorResponse(\n HttpStatus.BAD_REQUEST,\n \"Invalid redirect URL\",\n );\n }\n\n const status = permanent ? HttpStatus.MOVED_PERMANENTLY : HttpStatus.FOUND;\n const headers = new Headers(options?.headers);\n headers.set(\"Location\", url);\n\n return new Response(null, {\n ...options,\n status,\n headers,\n });\n}\n\n// Convenience methods for common responses\nexport const notFound = (message?: string, options?: ResponseOptions) =>\n errorResponse(HttpStatus.NOT_FOUND, message, options);\n\nexport const badRequest = (message?: string, options?: ResponseOptions) =>\n errorResponse(HttpStatus.BAD_REQUEST, message, options);\n\nexport const unauthorized = (message?: string, options?: ResponseOptions) =>\n errorResponse(HttpStatus.UNAUTHORIZED, message, options);\n\nexport const forbidden = (message?: string, options?: ResponseOptions) =>\n errorResponse(HttpStatus.FORBIDDEN, message, options);\n\nexport const internalServerError = (message?: string, options?: ResponseOptions) =>\n errorResponse(HttpStatus.INTERNAL_SERVER_ERROR, message, options);\n\nexport const badGateway = (message?: string, options?: ResponseOptions) =>\n errorResponse(HttpStatus.BAD_GATEWAY, message, options);\n\nexport const serviceUnavailable = (message?: string, options?: ResponseOptions) =>\n errorResponse(HttpStatus.SERVICE_UNAVAILABLE, message, options);\n\nexport const methodNotAllowed = (allowed: string[], options?: ResponseOptions) => {\n const headers = new Headers(options?.headers);\n headers.set(\"Allow\", allowed.join(\", \"));\n return errorResponse(\n HttpStatus.METHOD_NOT_ALLOWED,\n `Method not allowed. Allowed methods: ${allowed.join(\", \")}`,\n { ...options, headers },\n );\n};\n\nexport const ok = <T>(data?: T, options?: ResponseOptions) =>\n data === undefined\n ? new Response(null, { status: HttpStatus.OK, ...options })\n : jsonResponse(data, HttpStatus.OK, options);\n\nexport const created = <T>(data?: T, location?: string, options?: ResponseOptions) => {\n const headers = new Headers(options?.headers);\n if (location) {\n headers.set(\"Location\", location);\n }\n return data === undefined\n ? new Response(null, { status: HttpStatus.CREATED, headers, ...options })\n : jsonResponse(data, HttpStatus.CREATED, { ...options, headers });\n};\n\nexport const noContent = (options?: ResponseOptions) =>\n new Response(null, { status: HttpStatus.NO_CONTENT, ...options });\n\n/**\n * Helper function to get human-readable status text.\n * Keeps the mapping simple and maintainable.\n */\nfunction getStatusText(status: HttpStatusCode): string {\n const statusTexts: Record<HttpStatusCode, string> = {\n [HttpStatus.OK]: \"OK\",\n [HttpStatus.CREATED]: \"Created\",\n [HttpStatus.NO_CONTENT]: \"No Content\",\n [HttpStatus.MOVED_PERMANENTLY]: \"Moved Permanently\",\n [HttpStatus.FOUND]: \"Found\",\n [HttpStatus.NOT_MODIFIED]: \"Not Modified\",\n [HttpStatus.BAD_REQUEST]: \"Bad Request\",\n [HttpStatus.UNAUTHORIZED]: \"Unauthorized\",\n [HttpStatus.FORBIDDEN]: \"Forbidden\",\n [HttpStatus.NOT_FOUND]: \"Not Found\",\n [HttpStatus.METHOD_NOT_ALLOWED]: \"Method Not Allowed\",\n [HttpStatus.CONFLICT]: \"Conflict\",\n [HttpStatus.UNPROCESSABLE_ENTITY]: \"Unprocessable Entity\",\n [HttpStatus.TOO_MANY_REQUESTS]: \"Too Many Requests\",\n [HttpStatus.INTERNAL_SERVER_ERROR]: \"Internal Server Error\",\n [HttpStatus.NOT_IMPLEMENTED]: \"Not Implemented\",\n [HttpStatus.BAD_GATEWAY]: \"Bad Gateway\",\n [HttpStatus.SERVICE_UNAVAILABLE]: \"Service Unavailable\",\n [HttpStatus.GATEWAY_TIMEOUT]: \"Gateway Timeout\",\n };\n\n return statusTexts[status] || \"Unknown Status\";\n}\n\n/**\n * Simple URL validation for redirect safety.\n * Prevents open redirect vulnerabilities.\n */\nfunction isValidRedirectUrl(url: string): boolean {\n try {\n const parsed = new URL(url, \"http://localhost\"); // Base URL for relative URLs\n\n // Allow relative URLs and same-origin absolute URLs\n if (url.startsWith(\"/\") || url.startsWith(\"./\") || url.startsWith(\"../\")) {\n return true;\n }\n\n // For absolute URLs, could add domain whitelist here if needed\n return parsed.protocol === \"http:\" || parsed.protocol === \"https:\";\n } catch {\n return false;\n }\n}\n", "/**\n * Security Module - Comprehensive HTTP Security & Response System\n *\n * Provides security features including:\n * - Input validation and sanitization\n * - HTTP security headers (CSP, CORS, etc.)\n * - Authentication handlers\n * - Security middleware\n * - Response building with security best practices\n *\n * @module security\n */\n\n// Base Handler\nexport { BaseHandler } from \"./http/base-handler.ts\";\n\n// Input Validation (from input-validation/)\nexport type {\n ParseFormOptions,\n ParseJsonOptions,\n RequestLimits,\n ValidatedData,\n ValidatedHandlerConfig,\n ValidatedHandlerFunction,\n} from \"./input-validation/index.ts\";\n\nexport {\n CommonSchemas,\n createValidatedHandler,\n DEFAULT_LIMITS,\n parseFormData,\n parseJsonBody,\n parseQueryParams,\n readBodyWithLimit,\n sanitizeData,\n validateRequestLimits,\n ValidationError,\n} from \"./input-validation/index.ts\";\n\n// HTTP Security (from http/)\nexport type { CORSConfig, CSPDirectives, SecurityConfig } from \"./http/handlers-index.ts\";\n\nexport {\n AuthHandler,\n loadSecurityConfig,\n SecurityConfigLoader,\n setCors,\n} from \"./http/handlers-index.ts\";\n\n// Additional HTTP Security Utilities (from http/middleware/)\nexport { computeEtag, CONTENT_TYPES, isValidSecurityConfig } from \"./http/middleware/index.ts\";\n\n// CORS (from http/cors/ - merged from cors package)\nexport type {\n CORSConfig as CORSOptions,\n CORSHeaderOptions,\n CORSPreflightOptions,\n CORSValidationResult,\n OriginValidator,\n} from \"./http/cors/index.ts\";\nexport {\n applyCORSHeaders,\n applyCORSHeadersSync,\n cors,\n corsSimple,\n DEFAULT_HEADERS as DEFAULT_CORS_HEADERS,\n DEFAULT_MAX_AGE as CORS_MAX_AGE,\n DEFAULT_METHODS as DEFAULT_CORS_METHODS,\n handleCORSPreflight,\n isPreflightRequest,\n shouldApplyCORS,\n validateCORSConfig,\n validateOrigin,\n validateOriginSync,\n} from \"./http/cors/index.ts\";\n\n// Response Builder (from http/response/ - merged from response-builder package)\nexport type { CacheStrategy, ResponseBuilderConfig } from \"./http/response/index.ts\";\nexport {\n applySecurityHeaders,\n buildCacheControl,\n CACHE_DURATIONS,\n createResponseBuilder,\n generateNonce,\n getSecurityHeader,\n ResponseBuilder,\n} from \"./http/response/index.ts\";\n\n// Path validation and traversal protection\nexport {\n createValidator,\n PathValidationError,\n sanitizePathForDisplay,\n validatePath,\n validatePathSync,\n ValidationPresets,\n} from \"./path-validation.ts\";\nexport type { ValidationLevel, ValidationOptions, ValidationResult } from \"./path-validation.ts\";\n\n// Secure filesystem wrapper\nexport { createSecureFs, SecureFs, SecurityError, wrapAdapterWithSecurity } from \"./secure-fs.ts\";\nexport type { SecureFsConfig, SecurityContext, SecurityEvent } from \"./secure-fs.ts\";\n", "/**\n * Base handler abstract class\n * Provides common functionality for all handlers\n */\n\nimport type {\n Handler,\n HandlerContext,\n HandlerMetadata,\n HandlerResult,\n RoutePattern,\n} from \"@veryfront/types\";\nimport { ResponseBuilder } from \"./response/index.ts\";\nimport { serverLogger } from \"@veryfront/utils\";\n\nexport abstract class BaseHandler implements Handler {\n abstract metadata: HandlerMetadata;\n\n /**\n * Main handler method to be implemented by subclasses\n */\n abstract handle(req: Request, ctx: HandlerContext): Promise<HandlerResult>;\n\n /**\n * Check if this handler should process the request\n */\n protected shouldHandle(req: Request, ctx: HandlerContext): boolean {\n // Check if handler is enabled\n if (this.metadata.enabled && !this.metadata.enabled(ctx)) {\n return false;\n }\n\n // If no patterns specified, handler decides internally\n if (!this.metadata.patterns || this.metadata.patterns.length === 0) {\n return true;\n }\n\n const url = new URL(req.url);\n const pathname = url.pathname;\n const method = req.method.toUpperCase();\n\n // Check each pattern\n for (const pattern of this.metadata.patterns) {\n if (this.matchesPattern(pathname, method, pattern)) {\n return true;\n }\n }\n\n return false;\n }\n\n /**\n * Check if request matches a pattern\n */\n private matchesPattern(pathname: string, method: string, pattern: RoutePattern): boolean {\n // Check method if specified\n if (pattern.method) {\n const methods = Array.isArray(pattern.method) ? pattern.method : [pattern.method];\n if (!methods.map((m) => m.toUpperCase()).includes(method)) {\n return false;\n }\n }\n\n // Check path pattern\n if (typeof pattern.pattern === \"string\") {\n if (pattern.exact) {\n return pathname === pattern.pattern;\n } else if (pattern.prefix) {\n return pathname.startsWith(pattern.pattern);\n } else {\n // Default to exact match for strings\n return pathname === pattern.pattern;\n }\n } else if (pattern.pattern instanceof RegExp) {\n return pattern.pattern.test(pathname);\n }\n\n return false;\n }\n\n /**\n * Create a response builder with context\n * @param ctx - Handler context\n * @param nonce - Optional pre-generated nonce for CSP consistency\n */\n protected createResponseBuilder(ctx: HandlerContext, nonce?: string): ResponseBuilder {\n return new ResponseBuilder({\n securityConfig: ctx.securityConfig ?? undefined,\n isDev: ctx.mode === \"development\",\n cspUserHeader: ctx.cspUserHeader,\n adapter: ctx.adapter,\n nonce, // Pass through the nonce if provided\n });\n }\n\n /**\n * Log debug message if debug mode is enabled\n */\n protected logDebug(message: string, extra?: Record<string, unknown>, ctx?: HandlerContext): void {\n if (ctx?.debug || ctx?.adapter.env.get(\"VERYFRONT_DEBUG\")) {\n serverLogger.debug(`[${this.metadata.name}] ${message}`, extra || undefined);\n }\n }\n\n /**\n * Helper to extract error message safely\n */\n protected getErrorMessage(error: unknown): string {\n if (error instanceof Error) return error.message;\n return String(error);\n }\n\n /**\n * Continue to next handler\n */\n protected continue(): HandlerResult {\n return { continue: true };\n }\n\n /**\n * Return a response and stop the chain\n */\n protected respond(response: Response, metadata?: Record<string, unknown>): HandlerResult {\n return { response, continue: false, metadata };\n }\n}\n", "/**\n * Response Builder - Public API\n * Fluent API for constructing HTTP responses with common patterns\n */\n\n// Re-export types\nexport type { CacheStrategy, CORSConfig, ResponseBuilderConfig, SecurityConfig } from \"./types.ts\";\n\n// Re-export constants\nexport { CACHE_DURATIONS, CONTENT_TYPES } from \"./constants.ts\";\n\n// Re-export main builder\nexport { createResponseBuilder, ResponseBuilder } from \"./builder.ts\";\n\n// Re-export handler utilities (for advanced usage)\nexport { applyCORSHeaders, shouldApplyCORS } from \"../cors/index.ts\";\nexport {\n applySecurityHeaders,\n buildCSP,\n generateNonce,\n getSecurityHeader,\n} from \"./security-handler.ts\";\nexport { buildCacheControl } from \"./cache-handler.ts\";\n", "/**\n * Response Builder Constants\n * Content types and cache duration constants\n */\n\n/**\n * Content type constants\n */\nexport const CONTENT_TYPES = {\n JSON: \"application/json; charset=utf-8\",\n HTML: \"text/html; charset=utf-8\",\n TEXT: \"text/plain; charset=utf-8\",\n JAVASCRIPT: \"application/javascript; charset=utf-8\",\n CSS: \"text/css; charset=utf-8\",\n XML: \"application/xml; charset=utf-8\",\n} as const;\n\n/**\n * Cache duration constants (in seconds)\n */\nexport const CACHE_DURATIONS = {\n SHORT: 60,\n MEDIUM: 3600,\n LONG: 31536000,\n} as const;\n", "/**\n * ResponseBuilder - Main builder class\n * Fluent API for constructing HTTP responses with common patterns\n */\n\nimport type { ResponseBuilderConfig, SecurityConfig } from \"./types.ts\";\nimport * as fluentMethods from \"./fluent-methods.ts\";\nimport type { FluentMethodsContext } from \"./fluent-methods.ts\";\nimport * as responseMethods from \"./response-methods.ts\";\nimport type { ResponseMethodsContext } from \"./response-methods.ts\";\nimport * as staticHelpers from \"./static-helpers.ts\";\nimport { generateNonce } from \"./security-handler.ts\";\n\n/**\n * ResponseBuilder class for fluent response construction\n * Combines fluent methods and response methods into a cohesive builder API\n */\nexport class ResponseBuilder implements FluentMethodsContext, ResponseMethodsContext {\n public headers: Headers;\n public status: number;\n public securityConfig: SecurityConfig | null;\n public isDev: boolean;\n public nonce: string;\n public cspUserHeader: string | null;\n public adapter: import(\"@veryfront/platform/adapters/base.ts\").RuntimeAdapter | undefined;\n\n constructor(config?: ResponseBuilderConfig) {\n this.headers = new Headers();\n this.status = 200;\n this.securityConfig = config?.securityConfig ?? null;\n this.isDev = config?.isDev ?? false;\n this.nonce = config?.nonce ?? generateNonce();\n this.cspUserHeader = config?.cspUserHeader ?? null;\n this.adapter = config?.adapter;\n }\n\n withCORS = fluentMethods.withCORS;\n withCORSAsync = fluentMethods.withCORSAsync;\n withSecurity = fluentMethods.withSecurity;\n withCache = fluentMethods.withCache;\n withETag = fluentMethods.withETag;\n withHeaders = fluentMethods.withHeaders;\n withStatus = fluentMethods.withStatus;\n withAllow = fluentMethods.withAllow;\n\n json = responseMethods.json;\n text = responseMethods.text;\n html = responseMethods.html;\n javascript = responseMethods.javascript;\n withContentType = responseMethods.withContentType;\n build = responseMethods.build;\n notModified = responseMethods.notModified;\n\n static error = staticHelpers.error;\n static json = staticHelpers.json;\n static html = staticHelpers.html;\n static preflight = staticHelpers.preflight;\n static stream = staticHelpers.stream;\n}\n\n// Initialize the ResponseBuilder class reference in static-helpers\nstaticHelpers.setResponseBuilderClass(\n ResponseBuilder as unknown as Parameters<typeof staticHelpers.setResponseBuilderClass>[0],\n);\n\n/**\n * Factory function for creating preconfigured builders\n */\nexport function createResponseBuilder(\n config?: ResponseBuilderConfig,\n): ResponseBuilder {\n return new ResponseBuilder(config);\n}\n", "/**\n * ResponseBuilder - Fluent Builder Methods\n * Fluent methods for configuring response builder state\n */\n\nimport { applyCORSHeaders, applyCORSHeadersSync } from \"../cors/index.ts\";\nimport { applySecurityHeaders } from \"./security-handler.ts\";\nimport { buildCacheControl } from \"./cache-handler.ts\";\nimport type { CacheStrategy, CORSConfig, SecurityConfig } from \"./types.ts\";\n\n/**\n * Internal state interface for fluent methods\n */\nexport interface FluentMethodsContext {\n headers: Headers;\n status: number;\n securityConfig: SecurityConfig | null;\n isDev: boolean;\n nonce: string;\n cspUserHeader: string | null;\n adapter: import(\"@veryfront/platform/adapters/base.ts\").RuntimeAdapter | undefined;\n}\n\n/**\n * Apply CORS headers based on configuration\n */\nexport function withCORS<T extends FluentMethodsContext>(\n this: T,\n req: Request,\n corsConfig?: boolean | CORSConfig,\n): T {\n const config = corsConfig ?? this.securityConfig?.cors;\n applyCORSHeadersSync({\n request: req,\n headers: this.headers,\n config,\n });\n return this;\n}\n\n/**\n * Apply CORS headers asynchronously (for loading config)\n */\nexport function withCORSAsync<T extends FluentMethodsContext>(\n this: T,\n req: Request,\n): Promise<T> {\n return applyCORSHeaders({\n request: req,\n headers: this.headers,\n config: this.securityConfig?.cors,\n }).then(() => this);\n}\n\n/**\n * Apply security headers (CSP, COOP, CORP, COEP)\n */\nexport function withSecurity<T extends FluentMethodsContext>(\n this: T,\n config?: SecurityConfig,\n): T {\n const cfg = config ?? this.securityConfig;\n applySecurityHeaders(\n this.headers,\n this.isDev,\n this.nonce,\n this.cspUserHeader,\n cfg,\n this.adapter,\n );\n return this;\n}\n\n/**\n * Apply cache control headers based on strategy\n */\nexport function withCache<T extends FluentMethodsContext>(\n this: T,\n strategy: CacheStrategy,\n): T {\n const cacheControl = buildCacheControl(strategy);\n this.headers.set(\"cache-control\", cacheControl);\n return this;\n}\n\n/**\n * Set ETag header\n */\nexport function withETag<T extends FluentMethodsContext>(\n this: T,\n etag: string,\n): T {\n this.headers.set(\"ETag\", etag);\n return this;\n}\n\n/**\n * Set custom headers\n */\nexport function withHeaders<T extends FluentMethodsContext>(\n this: T,\n headers: HeadersInit | Record<string, string>,\n): T {\n if (headers instanceof Headers) {\n headers.forEach((value, key) => {\n this.headers.set(key, value);\n });\n } else if (Array.isArray(headers)) {\n headers.forEach(([key, value]) => {\n this.headers.set(key, value);\n });\n } else {\n Object.entries(headers).forEach(([key, value]) => {\n this.headers.set(key, value);\n });\n }\n return this;\n}\n\n/**\n * Set response status\n */\nexport function withStatus<T extends FluentMethodsContext>(\n this: T,\n status: number,\n): T {\n this.status = status;\n return this;\n}\n\n/**\n * Set Allow header for OPTIONS requests\n */\nexport function withAllow<T extends FluentMethodsContext>(\n this: T,\n methods: string | string[],\n): T {\n const methodStr = Array.isArray(methods) ? methods.join(\", \") : methods;\n this.headers.set(\"Allow\", methodStr);\n this.headers.set(\"Access-Control-Allow-Methods\", methodStr);\n return this;\n}\n", "/**\n * CORS Module\n * Consolidated CORS handling for the Veryfront framework\n *\n * This module provides a unified, secure, and feature-complete CORS implementation\n * that replaces multiple scattered CORS handlers throughout the codebase.\n *\n * Features:\n * - Secure by default (no CORS without explicit configuration)\n * - Complete preflight handling with proper error responses\n * - Origin validation (string, array, function)\n * - Credentials support with security validations\n * - Configurable methods, headers, and cache duration\n * - Comprehensive logging for debugging\n *\n * @module core/cors\n */\n\nimport { applyCORSHeaders, applyCORSHeadersSync, shouldApplyCORS } from \"./headers.ts\";\nimport { validateCORSConfig, validateOrigin, validateOriginSync } from \"./validators.ts\";\n\n// Main exports for CORS functionality\nexport { handleCORSPreflight, isPreflightRequest } from \"./preflight.ts\";\nexport {\n applyCORSHeaders,\n applyCORSHeadersSync,\n shouldApplyCORS,\n validateCORSConfig,\n validateOrigin,\n validateOriginSync,\n};\nexport { cors, corsSimple } from \"./middleware.ts\";\n\n// Type exports\nexport type {\n CORSConfig,\n CORSHeaderOptions,\n CORSPreflightOptions,\n CORSValidationResult,\n OriginValidator,\n} from \"./types.ts\";\n\n// Constant exports (excluding DEV_LOCALHOST_ORIGINS to avoid conflict with config/network-defaults)\nexport {\n DEFAULT_HEADERS,\n DEFAULT_MAX_AGE,\n DEFAULT_METHODS,\n HTTP_FORBIDDEN,\n HTTP_NO_CONTENT,\n isProductionMode,\n} from \"./constants.ts\";\n", "/**\n * CORS Headers\n * Functions for applying CORS headers to responses\n *\n * @module core/cors/headers\n */\n\nimport type { CORSConfig, CORSHeaderOptions } from \"./types.ts\";\nimport { validateOrigin, validateOriginSync } from \"./validators.ts\";\n\n/**\n * Apply CORS headers to a response or headers object\n * Adds appropriate CORS headers based on configuration\n *\n * @param options - Header application options\n * @returns New Response with CORS headers or modified Headers object\n */\nexport async function applyCORSHeaders(options: CORSHeaderOptions): Promise<Response | void> {\n const { request, response, headers: headersObj, config } = options;\n\n // Validate origin\n const validation = await validateOrigin(request.headers.get(\"origin\"), config);\n\n // No CORS headers if origin not allowed\n if (!validation.allowedOrigin) {\n return response;\n }\n\n // Determine which headers object to modify\n const headers = headersObj || (response ? new Headers(response.headers) : new Headers());\n\n // Set allowed origin\n headers.set(\"Access-Control-Allow-Origin\", validation.allowedOrigin);\n\n // Add Vary header for non-wildcard origins\n if (validation.allowedOrigin !== \"*\") {\n const existingVary = headers.get(\"Vary\");\n const varyValues = existingVary ? existingVary.split(\",\").map((v) => v.trim()) : [];\n if (!varyValues.includes(\"Origin\")) {\n varyValues.push(\"Origin\");\n headers.set(\"Vary\", varyValues.join(\", \"));\n }\n }\n\n // Add credentials if allowed\n if (validation.allowCredentials && validation.allowedOrigin !== \"*\") {\n headers.set(\"Access-Control-Allow-Credentials\", \"true\");\n }\n\n // Add exposed headers if configured\n const corsConfig = typeof config === \"object\" ? config : null;\n if (corsConfig?.exposedHeaders && corsConfig.exposedHeaders.length > 0) {\n headers.set(\"Access-Control-Expose-Headers\", corsConfig.exposedHeaders.join(\", \"));\n }\n\n // If modifying an existing response, return new response with updated headers\n if (response) {\n return new Response(response.body, {\n status: response.status,\n statusText: response.statusText,\n headers,\n });\n }\n\n // If only modifying headers object, changes are made in place\n return;\n}\n\n/**\n * Synchronous variant of applyCORSHeaders for contexts that require\n * immediate execution (e.g., fluent builder chains). Async origin validators\n * are not supported and will be ignored.\n */\nexport function applyCORSHeadersSync(options: CORSHeaderOptions): Response | void {\n const { request, response, headers: headersObj, config } = options;\n const validation = validateOriginSync(request.headers.get(\"origin\"), config);\n\n if (!validation.allowedOrigin) {\n return response;\n }\n\n const headers = headersObj || (response ? new Headers(response.headers) : new Headers());\n\n headers.set(\"Access-Control-Allow-Origin\", validation.allowedOrigin);\n\n if (validation.allowedOrigin !== \"*\") {\n const existingVary = headers.get(\"Vary\");\n const varyValues = existingVary ? existingVary.split(\",\").map((v) => v.trim()) : [];\n if (!varyValues.includes(\"Origin\")) {\n varyValues.push(\"Origin\");\n headers.set(\"Vary\", varyValues.join(\", \"));\n }\n }\n\n if (validation.allowCredentials && validation.allowedOrigin !== \"*\") {\n headers.set(\"Access-Control-Allow-Credentials\", \"true\");\n }\n\n const corsConfig = typeof config === \"object\" ? config : null;\n if (corsConfig?.exposedHeaders && corsConfig.exposedHeaders.length > 0) {\n headers.set(\"Access-Control-Expose-Headers\", corsConfig.exposedHeaders.join(\", \"));\n }\n\n if (response) {\n return new Response(response.body, {\n status: response.status,\n statusText: response.statusText,\n headers,\n });\n }\n\n return;\n}\n\n/**\n * Determine if CORS headers should be applied\n * Quick check without full validation\n *\n * @param request - The incoming request\n * @param config - CORS configuration\n * @returns True if CORS headers should be added\n */\nexport function shouldApplyCORS(request: Request, config?: boolean | CORSConfig): boolean {\n // No config = no CORS\n if (!config) {\n return false;\n }\n\n // Boolean true = always apply\n if (config === true) {\n return true;\n }\n\n // Check if origin header is present\n const origin = request.headers.get(\"origin\");\n if (!origin) {\n // No origin header - only apply for wildcard\n return config.origin === \"*\";\n }\n\n // Has origin and config - will validate in applyCORSHeaders\n return true;\n}\n", "/**\n * CORS Validators\n * Origin validation logic for CORS handling\n *\n * @module core/cors/validators\n */\n\nimport type { CORSConfig, CORSValidationResult } from \"./types.ts\";\nimport { serverLogger } from \"@veryfront/utils/logger/logger.ts\";\nimport { recordCorsRejection } from \"@veryfront/observability\";\n\n/**\n * Validate origin against CORS configuration\n * Returns the allowed origin or null if not allowed\n *\n * This is the main validation entry point that coordinates\n * all origin validation strategies.\n *\n * @param requestOrigin - The origin from the request header\n * @param config - CORS configuration\n * @returns Validation result with allowed origin and credentials\n */\nexport async function validateOrigin(\n requestOrigin: string | null,\n config?: boolean | CORSConfig,\n): Promise<CORSValidationResult> {\n // Secure by default: no CORS without explicit configuration\n if (!config) {\n return { allowedOrigin: null, allowCredentials: false };\n }\n\n // Simple boolean true = allow all origins\n if (config === true) {\n const origin = requestOrigin || \"*\";\n return { allowedOrigin: origin, allowCredentials: false };\n }\n\n // Object configuration\n const corsConfig = config as CORSConfig;\n\n // No origin configuration = no CORS\n if (!corsConfig.origin) {\n return { allowedOrigin: null, allowCredentials: false };\n }\n\n // No origin header (same-origin request or non-browser client)\n if (!requestOrigin) {\n // For wildcard, return wildcard even without origin header\n if (corsConfig.origin === \"*\") {\n return { allowedOrigin: \"*\", allowCredentials: false };\n }\n // For other configurations, no CORS headers for missing origin\n return { allowedOrigin: null, allowCredentials: false };\n }\n\n // Wildcard origin\n if (corsConfig.origin === \"*\") {\n // Security: Cannot use credentials with wildcard\n if (corsConfig.credentials) {\n serverLogger.warn(\"[CORS] Cannot use credentials with wildcard origin - denying\");\n return {\n allowedOrigin: null,\n allowCredentials: false,\n error: \"Cannot use credentials with wildcard origin\",\n };\n }\n return { allowedOrigin: \"*\", allowCredentials: false };\n }\n\n // Function-based validation\n if (typeof corsConfig.origin === \"function\") {\n try {\n const result = await corsConfig.origin(requestOrigin);\n\n // Function returned specific origin string\n if (typeof result === \"string\") {\n return {\n allowedOrigin: result,\n allowCredentials: corsConfig.credentials ?? false,\n };\n }\n\n // Function returned boolean\n const allowed = result === true;\n return {\n allowedOrigin: allowed ? requestOrigin : null,\n allowCredentials: allowed && (corsConfig.credentials ?? false),\n error: allowed ? undefined : \"Origin rejected by validation function\",\n };\n } catch (error) {\n serverLogger.error(\"[CORS] Origin validation function error\", error);\n return {\n allowedOrigin: null,\n allowCredentials: false,\n error: \"Origin validation error\",\n };\n }\n }\n\n // Array of allowed origins\n if (Array.isArray(corsConfig.origin)) {\n const allowed = corsConfig.origin.includes(requestOrigin);\n if (!allowed) {\n recordCorsRejection();\n serverLogger.warn(\"[CORS] Origin not in allowlist\", {\n requestOrigin,\n allowedOrigins: corsConfig.origin,\n });\n }\n return {\n allowedOrigin: allowed ? requestOrigin : null,\n allowCredentials: allowed && (corsConfig.credentials ?? false),\n error: allowed ? undefined : \"Origin not in allowlist\",\n };\n }\n\n // Single origin string\n if (typeof corsConfig.origin === \"string\") {\n const allowed = corsConfig.origin === requestOrigin;\n if (!allowed) {\n recordCorsRejection();\n serverLogger.warn(\"[CORS] Origin does not match\", {\n requestOrigin,\n expectedOrigin: corsConfig.origin,\n });\n }\n return {\n allowedOrigin: allowed ? requestOrigin : null,\n allowCredentials: allowed && (corsConfig.credentials ?? false),\n error: allowed ? undefined : \"Origin does not match\",\n };\n }\n\n // Should never reach here\n return {\n allowedOrigin: null,\n allowCredentials: false,\n error: \"Invalid origin configuration\",\n };\n}\n\n/**\n * Synchronous origin validation helper for environments that require\n * immediate header evaluation (e.g., fluent response builders).\n * Async origin validators are NOT supported here.\n */\nexport function validateOriginSync(\n requestOrigin: string | null,\n config?: boolean | CORSConfig,\n): CORSValidationResult {\n if (!config) {\n return { allowedOrigin: null, allowCredentials: false };\n }\n\n if (config === true) {\n const origin = requestOrigin || \"*\";\n return { allowedOrigin: origin, allowCredentials: false };\n }\n\n const corsConfig = config as CORSConfig;\n\n if (!corsConfig.origin) {\n return { allowedOrigin: null, allowCredentials: false };\n }\n\n if (!requestOrigin) {\n if (corsConfig.origin === \"*\") {\n return { allowedOrigin: \"*\", allowCredentials: false };\n }\n return { allowedOrigin: null, allowCredentials: false };\n }\n\n if (corsConfig.origin === \"*\") {\n if (corsConfig.credentials) {\n serverLogger.warn(\"[CORS] Cannot use credentials with wildcard origin - denying\");\n return {\n allowedOrigin: null,\n allowCredentials: false,\n error: \"Cannot use credentials with wildcard origin\",\n };\n }\n return { allowedOrigin: \"*\", allowCredentials: false };\n }\n\n if (typeof corsConfig.origin === \"function\") {\n try {\n const result = corsConfig.origin(requestOrigin);\n if (result instanceof Promise) {\n serverLogger.warn(\n \"[CORS] Async origin validators are not supported in synchronous contexts\",\n );\n return {\n allowedOrigin: null,\n allowCredentials: false,\n error: \"Async origin validators not supported\",\n };\n }\n if (typeof result === \"string\") {\n return {\n allowedOrigin: result,\n allowCredentials: corsConfig.credentials ?? false,\n };\n }\n const allowed = result === true;\n return {\n allowedOrigin: allowed ? requestOrigin : null,\n allowCredentials: allowed && (corsConfig.credentials ?? false),\n error: allowed ? undefined : \"Origin rejected by validation function\",\n };\n } catch (error) {\n serverLogger.error(\"[CORS] Origin validation function error\", error);\n return {\n allowedOrigin: null,\n allowCredentials: false,\n error: \"Origin validation error\",\n };\n }\n }\n\n if (Array.isArray(corsConfig.origin)) {\n const allowed = corsConfig.origin.includes(requestOrigin);\n if (!allowed) {\n recordCorsRejection();\n serverLogger.warn(\"[CORS] Origin not in allowlist (sync)\", {\n requestOrigin,\n allowedOrigins: corsConfig.origin,\n });\n }\n return {\n allowedOrigin: allowed ? requestOrigin : null,\n allowCredentials: allowed && (corsConfig.credentials ?? false),\n error: allowed ? undefined : \"Origin not in allowlist\",\n };\n }\n\n if (typeof corsConfig.origin === \"string\") {\n const allowed = corsConfig.origin === requestOrigin;\n if (!allowed) {\n recordCorsRejection();\n serverLogger.warn(\"[CORS] Origin does not match (sync)\", {\n requestOrigin,\n expectedOrigin: corsConfig.origin,\n });\n }\n return {\n allowedOrigin: allowed ? requestOrigin : null,\n allowCredentials: allowed && (corsConfig.credentials ?? false),\n error: allowed ? undefined : \"Origin does not match\",\n };\n }\n\n return {\n allowedOrigin: null,\n allowCredentials: false,\n error: \"Invalid origin configuration\",\n };\n}\n\n/**\n * Validate CORS configuration for security issues\n * Prevents dangerous combinations\n *\n * @param config - CORS configuration to validate\n * @returns Validation result with error if invalid\n */\nexport function validateCORSConfig(config?: boolean | CORSConfig): {\n valid: boolean;\n error?: string;\n} {\n if (!config || config === true) {\n return { valid: true };\n }\n\n const corsConfig = config as CORSConfig;\n\n // Cannot use credentials with wildcard origin\n if (corsConfig.origin === \"*\" && corsConfig.credentials) {\n return {\n valid: false,\n error: \"Cannot use credentials with wildcard origin (*)\",\n };\n }\n\n // Validate methods array if provided\n if (corsConfig.methods && corsConfig.methods.length === 0) {\n return {\n valid: false,\n error: \"methods array cannot be empty\",\n };\n }\n\n // Validate headers arrays\n if (corsConfig.allowedHeaders && corsConfig.allowedHeaders.length === 0) {\n return {\n valid: false,\n error: \"allowedHeaders array cannot be empty\",\n };\n }\n\n if (corsConfig.exposedHeaders && corsConfig.exposedHeaders.length === 0) {\n return {\n valid: false,\n error: \"exposedHeaders array cannot be empty\",\n };\n }\n\n // Validate maxAge is positive\n if (corsConfig.maxAge !== undefined && corsConfig.maxAge < 0) {\n return {\n valid: false,\n error: \"maxAge must be a positive number\",\n };\n }\n\n return { valid: true };\n}\n", "/**\n * Veryfront Observability\n *\n * Comprehensive OpenTelemetry integration for distributed tracing and metrics\n */\n\n// Export tracing utilities\nexport {\n addSpanEvent,\n createChildSpan,\n endSpan,\n extractContext,\n getActiveContext,\n initTracing,\n injectContext,\n isTracingEnabled,\n setSpanAttributes,\n shutdownTracing,\n SpanNames,\n type SpanOptions,\n startSpan,\n type TracingConfig,\n withActiveSpan,\n withSpan,\n withSpanSync,\n} from \"./tracing/index.ts\";\n\n// Export metrics utilities\nexport {\n getMetricsState,\n initMetrics,\n isMetricsEnabled,\n type MetricsConfig,\n recordBuild,\n recordBundle,\n recordCacheGet,\n recordCacheInvalidate,\n recordCacheSet,\n recordCorsRejection,\n recordDataFetch,\n recordDataFetchError,\n recordHttpRequest,\n recordHttpRequestComplete,\n recordRender,\n recordRenderError,\n recordRSCError,\n recordRSCRender,\n recordRSCRequest,\n recordRSCStream,\n recordSecurityHeaders,\n setCacheSize,\n shutdownMetrics,\n} from \"./metrics/index.ts\";\n\nexport {\n type AutoInstrumentConfig,\n initAutoInstrumentation,\n instrument,\n instrumentBatch,\n instrumentErrorHandler,\n instrumentFetch,\n instrumentHttpHandler,\n instrumentReactRender,\n instrumentSync,\n isAutoInstrumentEnabled,\n} from \"./auto-instrument/index.ts\";\n", "import type { RuntimeAdapter } from \"@veryfront/platform/adapters/base.ts\";\nimport { tracingManager } from \"./manager.ts\";\nimport type { Context, Span, SpanOptions, TracingConfig } from \"./types.ts\";\n\nexport type { Context, Span, SpanOptions, TracingConfig } from \"./types.ts\";\nexport { loadConfig } from \"./config.ts\";\nexport { SpanOperations } from \"./span-operations.ts\";\nexport { ContextPropagation } from \"./context-propagation.ts\";\nexport { SpanNames } from \"./span-names.ts\";\n\nexport async function initTracing(\n config: Partial<TracingConfig> = {},\n adapter?: RuntimeAdapter,\n): Promise<void> {\n await tracingManager.initialize(config, adapter);\n}\n\nexport function isTracingEnabled(): boolean {\n return tracingManager.isEnabled();\n}\n\nexport function shutdownTracing(): void {\n tracingManager.shutdown();\n}\n\nexport function getTracingState() {\n return tracingManager.getState();\n}\n\nconst getSpanOps = () => tracingManager.getSpanOperations();\nconst getContextProp = () => tracingManager.getContextPropagation();\n\nexport function startSpan(name: string, options: SpanOptions = {}): Span | null {\n return getSpanOps()?.startSpan(name, options) ?? null;\n}\n\nexport function endSpan(span: Span | null, error?: Error): void {\n getSpanOps()?.endSpan(span, error);\n}\n\nexport function setSpanAttributes(\n span: Span | null,\n attributes: Record<string, string | number | boolean>,\n): void {\n getSpanOps()?.setAttributes(span, attributes);\n}\n\nexport function addSpanEvent(\n span: Span | null,\n name: string,\n attributes?: Record<string, string | number | boolean>,\n): void {\n getSpanOps()?.addEvent(span, name, attributes);\n}\n\nexport function createChildSpan(\n parentSpan: Span | null,\n name: string,\n options: SpanOptions = {},\n): Span | null {\n return getSpanOps()?.createChildSpan(parentSpan, name, options) ?? null;\n}\n\nexport function extractContext(headers: Headers): Context | undefined {\n return getContextProp()?.extractContext(headers);\n}\n\nexport function injectContext(context: Context, headers: Headers): void {\n getContextProp()?.injectContext(context, headers);\n}\n\nexport function getActiveContext(): Context | undefined {\n return getContextProp()?.getActiveContext();\n}\n\nexport async function withActiveSpan<T>(span: Span | null, fn: () => Promise<T>): Promise<T> {\n const contextProp = getContextProp();\n if (!contextProp) return await fn();\n return await contextProp.withActiveSpan(span, fn);\n}\n\nexport async function withSpan<T>(\n name: string,\n fn: (span: Span | null) => Promise<T>,\n options: SpanOptions = {},\n): Promise<T> {\n const contextProp = getContextProp();\n const spanOps = getSpanOps();\n\n if (!contextProp || !spanOps) return await fn(null);\n\n return await contextProp.withSpanAsync(\n name,\n fn,\n (n) => spanOps.startSpan(n, options),\n (s, e) => spanOps.endSpan(s, e),\n );\n}\n\nexport function withSpanSync<T>(\n name: string,\n fn: (span: Span | null) => T,\n options: SpanOptions = {},\n): T {\n const contextProp = getContextProp();\n const spanOps = getSpanOps();\n\n if (!contextProp || !spanOps) return fn(null);\n\n return contextProp.withSpan(\n name,\n fn,\n (n) => spanOps.startSpan(n, options),\n (s, e) => spanOps.endSpan(s, e),\n );\n}\n\nexport { tracingManager } from \"./manager.ts\";\n", "import { serverLogger as logger } from \"@veryfront/utils\";\nimport type { RuntimeAdapter } from \"@veryfront/platform/adapters/base.ts\";\nimport type { OpenTelemetryAPI, TracingConfig, TracingState } from \"./types.ts\";\nimport { loadConfig } from \"./config.ts\";\nimport { SpanOperations } from \"./span-operations.ts\";\nimport { ContextPropagation } from \"./context-propagation.ts\";\n\nclass TracingManager {\n private state: TracingState = {\n initialized: false,\n tracer: null,\n api: null,\n propagator: null,\n };\n\n private spanOps: SpanOperations | null = null;\n private contextProp: ContextPropagation | null = null;\n\n async initialize(config: Partial<TracingConfig> = {}, adapter?: RuntimeAdapter): Promise<void> {\n if (this.state.initialized) {\n logger.debug(\"[tracing] Already initialized\");\n return;\n }\n\n const finalConfig = loadConfig(config, adapter);\n\n if (!finalConfig.enabled) {\n logger.debug(\"[tracing] Tracing disabled\");\n this.state.initialized = true;\n return;\n }\n\n try {\n await this.initializeTracer(finalConfig);\n this.state.initialized = true;\n\n logger.info(\"[tracing] OpenTelemetry tracing initialized\", {\n exporter: finalConfig.exporter,\n serviceName: finalConfig.serviceName,\n endpoint: finalConfig.endpoint,\n });\n } catch (error) {\n logger.warn(\"[tracing] Failed to initialize OpenTelemetry tracing\", error);\n this.state.initialized = true;\n }\n }\n\n private async initializeTracer(config: TracingConfig): Promise<void> {\n const api = await import(\"@opentelemetry/api\") as OpenTelemetryAPI;\n this.state.api = api;\n\n this.state.tracer = api.trace.getTracer(config.serviceName || \"veryfront\", \"0.1.0\");\n\n const { W3CTraceContextPropagator } = await import(\"@opentelemetry/core\");\n const propagator = new W3CTraceContextPropagator();\n this.state.propagator = propagator;\n api.propagation.setGlobalPropagator(propagator);\n\n if (this.state.api && this.state.tracer) {\n this.spanOps = new SpanOperations(this.state.api, this.state.tracer);\n }\n\n if (this.state.api && this.state.propagator) {\n this.contextProp = new ContextPropagation(this.state.api, this.state.propagator);\n }\n }\n\n isEnabled(): boolean {\n return this.state.initialized && this.state.tracer !== null;\n }\n\n getSpanOperations(): SpanOperations | null {\n return this.spanOps;\n }\n\n getContextPropagation(): ContextPropagation | null {\n return this.contextProp;\n }\n\n getState(): TracingState {\n return this.state;\n }\n\n shutdown(): void {\n if (!this.state.initialized) return;\n\n try {\n logger.info(\"[tracing] Tracing shutdown initiated\");\n } catch (error) {\n logger.warn(\"[tracing] Error during tracing shutdown\", error);\n }\n }\n}\n\nexport const tracingManager = new TracingManager();\n", "import type { RuntimeAdapter } from \"@veryfront/platform/adapters/base.ts\";\nimport type { TracingConfig } from \"./types.ts\";\nimport { getEnv } from \"../../platform/compat/process.ts\";\n\nconst DEFAULT_CONFIG: TracingConfig = {\n enabled: false,\n exporter: \"console\",\n serviceName: \"veryfront\",\n sampleRate: 1.0,\n debug: false,\n};\n\nexport function loadConfig(\n config: Partial<TracingConfig> = {},\n adapter?: RuntimeAdapter,\n): TracingConfig {\n const finalConfig = { ...DEFAULT_CONFIG, ...config };\n\n if (adapter?.env) {\n applyEnvFromAdapter(finalConfig, adapter.env);\n } else {\n applyEnvFromDeno(finalConfig);\n }\n\n return finalConfig;\n}\n\nfunction applyEnvFromAdapter(\n config: TracingConfig,\n envAdapter: RuntimeAdapter[\"env\"],\n): void {\n if (!envAdapter) return;\n\n const otelEnabled = envAdapter.get(\"OTEL_TRACES_ENABLED\");\n const veryfrontOtel = envAdapter.get(\"VERYFRONT_OTEL\");\n const serviceName = envAdapter.get(\"OTEL_SERVICE_NAME\");\n\n config.enabled = otelEnabled === \"true\" ||\n veryfrontOtel === \"1\" ||\n config.enabled;\n\n if (serviceName) config.serviceName = serviceName;\n\n const otlpEndpoint = envAdapter.get(\"OTEL_EXPORTER_OTLP_ENDPOINT\");\n const tracesEndpoint = envAdapter.get(\"OTEL_EXPORTER_OTLP_TRACES_ENDPOINT\");\n config.endpoint = otlpEndpoint || tracesEndpoint || config.endpoint;\n\n const exporterType = envAdapter.get(\"OTEL_TRACES_EXPORTER\");\n if (isValidExporter(exporterType)) {\n config.exporter = exporterType;\n }\n}\n\nfunction applyEnvFromDeno(config: TracingConfig): void {\n try {\n // Use platform abstraction for cross-platform env access\n config.enabled = getEnv(\"OTEL_TRACES_ENABLED\") === \"true\" ||\n getEnv(\"VERYFRONT_OTEL\") === \"1\" ||\n config.enabled;\n\n config.serviceName = getEnv(\"OTEL_SERVICE_NAME\") || config.serviceName;\n config.endpoint = getEnv(\"OTEL_EXPORTER_OTLP_ENDPOINT\") ||\n getEnv(\"OTEL_EXPORTER_OTLP_TRACES_ENDPOINT\") ||\n config.endpoint;\n\n const exporterType = getEnv(\"OTEL_TRACES_EXPORTER\");\n if (isValidExporter(exporterType)) {\n config.exporter = exporterType;\n }\n } catch {\n // Environment access may fail in some runtimes\n }\n}\n\nfunction isValidExporter(value: string | undefined): value is TracingConfig[\"exporter\"] {\n return value === \"jaeger\" || value === \"zipkin\" || value === \"otlp\" || value === \"console\";\n}\n", "import { serverLogger as logger } from \"@veryfront/utils\";\nimport type { Span, SpanKind } from \"./types.ts\";\nimport type { OpenTelemetryAPI, SpanOptions } from \"./types.ts\";\n\nexport class SpanOperations {\n constructor(\n private api: OpenTelemetryAPI,\n private tracer: import(\"./types.ts\").Tracer,\n ) {}\n\n startSpan(name: string, options: SpanOptions = {}): Span | null {\n try {\n const spanKind = this.mapSpanKind(options.kind);\n\n const span = this.tracer.startSpan(name, {\n kind: spanKind,\n attributes: options.attributes || {},\n }, options.parent as import(\"./types.ts\").Context | undefined);\n\n return span;\n } catch (error) {\n logger.debug(\"[tracing] Failed to start span\", { name, error });\n return null;\n }\n }\n\n endSpan(span: Span | null, error?: Error): void {\n if (!span) return;\n\n try {\n if (error) {\n span.recordException(error);\n span.setStatus({\n code: this.api.SpanStatusCode.ERROR,\n message: error.message,\n });\n } else {\n span.setStatus({ code: this.api.SpanStatusCode.OK });\n }\n span.end();\n } catch (err) {\n logger.debug(\"[tracing] Failed to end span\", err);\n }\n }\n\n setAttributes(span: Span | null, attributes: Record<string, string | number | boolean>): void {\n if (!span) return;\n\n try {\n span.setAttributes(attributes);\n } catch (error) {\n logger.debug(\"[tracing] Failed to set span attributes\", error);\n }\n }\n\n addEvent(\n span: Span | null,\n name: string,\n attributes?: Record<string, string | number | boolean>,\n ): void {\n if (!span) return;\n\n try {\n span.addEvent(name, attributes);\n } catch (error) {\n logger.debug(\"[tracing] Failed to add span event\", error);\n }\n }\n\n createChildSpan(parentSpan: Span | null, name: string, options: SpanOptions = {}): Span | null {\n if (!parentSpan) return this.startSpan(name, options);\n\n try {\n const parentContext = this.api.trace.setSpan(this.api.context.active(), parentSpan);\n return this.startSpan(name, { ...options, parent: parentContext });\n } catch (error) {\n logger.debug(\"[tracing] Failed to create child span\", error);\n return null;\n }\n }\n\n private mapSpanKind(kind?: SpanOptions[\"kind\"]): SpanKind {\n if (!kind) return this.api.SpanKind.INTERNAL;\n\n const kindMap: Record<string, SpanKind> = {\n \"internal\": this.api.SpanKind.INTERNAL,\n \"server\": this.api.SpanKind.SERVER,\n \"client\": this.api.SpanKind.CLIENT,\n \"producer\": this.api.SpanKind.PRODUCER,\n \"consumer\": this.api.SpanKind.CONSUMER,\n };\n\n return kindMap[kind.toLowerCase()] || this.api.SpanKind.INTERNAL;\n }\n}\n", "import { serverLogger as logger } from \"@veryfront/utils\";\nimport type { Context, OpenTelemetryAPI, Span, TextMapPropagator } from \"./types.ts\";\n\nexport class ContextPropagation {\n constructor(\n private api: OpenTelemetryAPI,\n private propagator: TextMapPropagator,\n ) {}\n\n extractContext(headers: Headers): Context | undefined {\n try {\n const carrier: Record<string, string> = {};\n headers.forEach((value, key) => {\n carrier[key] = value;\n });\n\n return this.api.propagation.extract(this.api.context.active(), carrier);\n } catch (error) {\n logger.debug(\"[tracing] Failed to extract context from headers\", error);\n return undefined;\n }\n }\n\n injectContext(context: Context, headers: Headers): void {\n try {\n const carrier: Record<string, string> = {};\n this.api.propagation.inject(context, carrier);\n\n for (const [key, value] of Object.entries(carrier)) {\n headers.set(key, value);\n }\n } catch (error) {\n logger.debug(\"[tracing] Failed to inject context into headers\", error);\n }\n }\n\n getActiveContext(): Context | undefined {\n try {\n return this.api.context.active();\n } catch (error) {\n logger.debug(\"[tracing] Failed to get active context\", error);\n return undefined;\n }\n }\n\n async withActiveSpan<T>(span: Span | null, fn: () => Promise<T>): Promise<T> {\n if (!span) return await fn();\n\n return await this.api.context.with(\n this.api.trace.setSpan(this.api.context.active(), span),\n fn,\n );\n }\n\n withSpan<T>(\n name: string,\n fn: (span: Span | null) => T,\n startSpan: (name: string) => Span | null,\n endSpan: (span: Span | null, error?: Error) => void,\n ): T {\n const span = startSpan(name);\n\n try {\n const result = fn(span);\n endSpan(span);\n return result;\n } catch (error) {\n endSpan(span, error as Error);\n throw error;\n }\n }\n\n async withSpanAsync<T>(\n name: string,\n fn: (span: Span | null) => Promise<T>,\n startSpan: (name: string) => Span | null,\n endSpan: (span: Span | null, error?: Error) => void,\n ): Promise<T> {\n const span = startSpan(name);\n\n try {\n const result = await fn(span);\n endSpan(span);\n return result;\n } catch (error) {\n endSpan(span, error as Error);\n throw error;\n }\n }\n}\n", "export const SpanNames = {\n HTTP_REQUEST: \"http.request\",\n HTTP_HANDLER: \"http.handler\",\n\n RENDER_PAGE: \"render.page\",\n RENDER_COMPONENT: \"render.component\",\n RENDER_LAYOUT: \"render.layout\",\n RENDER_SSR: \"render.ssr\",\n RENDER_RSC: \"render.rsc\",\n\n DATA_FETCH: \"data.fetch\",\n DATA_CACHE_GET: \"data.cache.get\",\n DATA_CACHE_SET: \"data.cache.set\",\n\n BUILD_BUNDLE: \"build.bundle\",\n BUILD_SPLIT: \"build.split\",\n BUILD_OPTIMIZE: \"build.optimize\",\n BUILD_COMPILE: \"build.compile\",\n\n RSC_RENDER: \"rsc.render\",\n RSC_SERIALIZE: \"rsc.serialize\",\n RSC_STREAM: \"rsc.stream\",\n\n ROUTER_MATCH: \"router.match\",\n ROUTER_RESOLVE: \"router.resolve\",\n} as const;\n", "/**\n * OpenTelemetry Metrics - Public API\n *\n * Comprehensive OpenTelemetry integration for Veryfront:\n * - Custom metrics: request count, latency, cache hits\n * - Histogram buckets for latency distribution\n * - Gauges for active connections, memory usage\n * - Export to Prometheus, CloudWatch, OTLP, etc.\n */\n\nimport type { RuntimeAdapter } from \"@veryfront/platform/adapters/base.ts\";\nimport { metricsManager } from \"./manager.ts\";\n\n// Re-export types\nexport type { MemoryUsage, MetricsConfig } from \"./types.ts\";\n\n// Re-export utilities (for advanced usage)\nexport { getMemoryUsage, loadConfig } from \"./config.ts\";\n// Removed: deleted module - export { initializeInstruments } from \"./instruments.ts\";\nexport { MetricsRecorder } from \"./recorder.ts\";\n\n/**\n * Initialize OpenTelemetry metrics\n */\nexport async function initMetrics(\n config: Parameters<typeof metricsManager.initialize>[0] = {},\n adapter?: RuntimeAdapter,\n): Promise<void> {\n await metricsManager.initialize(config, adapter);\n}\n\n/**\n * Check if metrics collection is enabled\n */\nexport function isMetricsEnabled(): boolean {\n return metricsManager.isEnabled();\n}\n\n/**\n * Shutdown metrics (for graceful shutdown)\n */\nexport async function shutdownMetrics(): Promise<void> {\n await metricsManager.shutdown();\n}\n\n/**\n * Export runtime state for testing/debugging\n */\nexport function getMetricsState() {\n return metricsManager.getState();\n}\n\n// Convenience API - delegates to recorder\nconst getRecorder = () => metricsManager.getRecorder();\n\n// HTTP Metrics API\nexport function recordHttpRequest(attributes?: Record<string, string>): void {\n getRecorder()?.recordHttpRequest(attributes);\n}\n\nexport function recordHttpRequestComplete(\n durationMs: number,\n attributes?: Record<string, string>,\n): void {\n getRecorder()?.recordHttpRequestComplete(durationMs, attributes);\n}\n\n// Cache Metrics API\nexport function recordCacheGet(\n hit: boolean,\n attributes?: Record<string, string>,\n): void {\n getRecorder()?.recordCacheGet(hit, attributes);\n}\n\nexport function recordCacheSet(attributes?: Record<string, string>): void {\n getRecorder()?.recordCacheSet(attributes);\n}\n\nexport function recordCacheInvalidate(\n count: number,\n attributes?: Record<string, string>,\n): void {\n getRecorder()?.recordCacheInvalidate(count, attributes);\n}\n\nexport function setCacheSize(size: number): void {\n getRecorder()?.setCacheSize(size);\n}\n\n// Render Metrics API\nexport function recordRender(\n durationMs: number,\n attributes?: Record<string, string>,\n): void {\n getRecorder()?.recordRender(durationMs, attributes);\n}\n\nexport function recordRenderError(attributes?: Record<string, string>): void {\n getRecorder()?.recordRenderError(attributes);\n}\n\n// RSC Metrics API\nexport function recordRSCRender(\n durationMs: number,\n attributes?: Record<string, string>,\n): void {\n getRecorder()?.recordRSCRender(durationMs, attributes);\n}\n\nexport function recordRSCStream(\n durationMs: number,\n attributes?: Record<string, string>,\n): void {\n getRecorder()?.recordRSCStream(durationMs, attributes);\n}\n\nexport function recordRSCRequest(\n type: \"manifest\" | \"page\" | \"stream\" | \"action\",\n attributes?: Record<string, string>,\n): void {\n getRecorder()?.recordRSCRequest(type, attributes);\n}\n\nexport function recordRSCError(attributes?: Record<string, string>): void {\n getRecorder()?.recordRSCError(attributes);\n}\n\n// Build Metrics API\nexport function recordBuild(\n durationMs: number,\n attributes?: Record<string, string>,\n): void {\n getRecorder()?.recordBuild(durationMs, attributes);\n}\n\nexport function recordBundle(\n sizeKb: number,\n attributes?: Record<string, string>,\n): void {\n getRecorder()?.recordBundle(sizeKb, attributes);\n}\n\n// Data Fetching Metrics API\nexport function recordDataFetch(\n durationMs: number,\n attributes?: Record<string, string>,\n): void {\n getRecorder()?.recordDataFetch(durationMs, attributes);\n}\n\nexport function recordDataFetchError(\n attributes?: Record<string, string>,\n): void {\n getRecorder()?.recordDataFetchError(attributes);\n}\n\n// Security Metrics API\nexport function recordCorsRejection(attributes?: Record<string, string>): void {\n getRecorder()?.recordCorsRejection?.(attributes);\n}\n\nexport function recordSecurityHeaders(attributes?: Record<string, string>): void {\n getRecorder()?.recordSecurityHeaders?.(attributes);\n}\n\n// Export singleton for advanced usage\nexport { metricsManager } from \"./manager.ts\";\n", "/**\n * Metrics Manager\n * Main OpenTelemetry metrics initialization and management\n */\n\nimport type { Meter } from \"@opentelemetry/api\";\nimport { serverLogger as logger } from \"@veryfront/utils\";\nimport type { RuntimeAdapter } from \"@veryfront/platform/adapters/base.ts\";\nimport { loadConfig } from \"./config.ts\";\nimport { initializeInstruments } from \"../instruments/index.ts\";\nimport { MetricsRecorder } from \"./recorder.ts\";\nimport type { MetricsConfig, MetricsInstruments, OpenTelemetryAPI, RuntimeState } from \"./types.ts\";\n\n/**\n * Metrics manager singleton state\n */\nclass MetricsManager {\n private initialized = false;\n private meter: Meter | null = null;\n private api: OpenTelemetryAPI | null = null;\n private instruments: MetricsInstruments;\n private runtimeState: RuntimeState;\n private recorder: MetricsRecorder | null = null;\n\n constructor() {\n this.instruments = this.createEmptyInstruments();\n this.runtimeState = {\n cacheSize: 0,\n activeRequests: 0,\n };\n // Create recorder immediately so state tracking works even before initialization\n // The recorder gracefully handles null instruments (optional chaining)\n this.recorder = new MetricsRecorder(this.instruments, this.runtimeState);\n }\n\n private createEmptyInstruments(): MetricsInstruments {\n return {\n httpRequestCounter: null,\n httpRequestDuration: null,\n httpActiveRequests: null,\n cacheGetCounter: null,\n cacheHitCounter: null,\n cacheMissCounter: null,\n cacheSetCounter: null,\n cacheInvalidateCounter: null,\n cacheSizeGauge: null,\n renderDuration: null,\n renderCounter: null,\n renderErrorCounter: null,\n rscRenderDuration: null,\n rscStreamDuration: null,\n rscManifestCounter: null,\n rscPageCounter: null,\n rscStreamCounter: null,\n rscActionCounter: null,\n rscErrorCounter: null,\n buildDuration: null,\n bundleSizeHistogram: null,\n bundleCounter: null,\n dataFetchDuration: null,\n dataFetchCounter: null,\n dataFetchErrorCounter: null,\n corsRejectionCounter: null,\n securityHeadersCounter: null,\n memoryUsageGauge: null,\n heapUsageGauge: null,\n };\n }\n\n async initialize(\n config: Partial<MetricsConfig> = {},\n adapter?: RuntimeAdapter,\n ): Promise<void> {\n if (this.initialized) {\n logger.debug(\"[metrics] Already initialized\");\n return;\n }\n\n const finalConfig = loadConfig(config, adapter);\n\n if (!finalConfig.enabled) {\n logger.debug(\"[metrics] Metrics collection disabled\");\n this.initialized = true;\n return;\n }\n\n try {\n // Load OpenTelemetry API\n this.api = await import(\"@opentelemetry/api\");\n\n // Get or create meter\n this.meter = this.api.metrics.getMeter(finalConfig.prefix, \"0.1.0\");\n\n // Initialize all metric instruments\n this.instruments = await initializeInstruments(\n this.meter,\n finalConfig,\n this.runtimeState,\n );\n\n // Update recorder with initialized instruments\n // Recorder was already created in constructor, just update its instruments reference\n if (this.recorder) {\n (this.recorder as any).instruments = this.instruments;\n }\n\n this.initialized = true;\n logger.info(\"[metrics] OpenTelemetry metrics initialized\", {\n exporter: finalConfig.exporter,\n endpoint: finalConfig.endpoint,\n prefix: finalConfig.prefix,\n });\n } catch (error) {\n logger.warn(\"[metrics] Failed to initialize OpenTelemetry metrics\", error);\n this.initialized = true; // Mark as initialized to prevent retry loops\n }\n }\n\n isEnabled(): boolean {\n return this.initialized && this.meter !== null;\n }\n\n getRecorder(): MetricsRecorder | null {\n return this.recorder;\n }\n\n getState() {\n return {\n initialized: this.initialized,\n cacheSize: this.runtimeState.cacheSize,\n activeRequests: this.runtimeState.activeRequests,\n };\n }\n\n shutdown(): void {\n if (!this.initialized) return;\n\n try {\n logger.info(\"[metrics] Metrics shutdown initiated\");\n } catch (error) {\n logger.warn(\"[metrics] Error during metrics shutdown\", error);\n }\n }\n}\n\n// Export singleton instance\nexport const metricsManager = new MetricsManager();\n", "/**\n * Metrics Configuration\n * Configuration loading and defaults for metrics system\n */\n\nimport type { RuntimeAdapter } from \"@veryfront/platform/adapters/base.ts\";\nimport type { MetricsConfig } from \"./types.ts\";\nimport { getEnv } from \"../../platform/compat/process.ts\";\nimport { memoryUsage as platformMemoryUsage } from \"../../platform/compat/process.ts\";\n\n/**\n * Default metrics collect interval in milliseconds (60 seconds)\n * Inlined to avoid circular dependency with @veryfront/config\n */\nconst DEFAULT_METRICS_COLLECT_INTERVAL_MS = 60000;\n\n/**\n * Default metrics configuration\n */\nexport const DEFAULT_CONFIG: MetricsConfig = {\n enabled: false,\n exporter: \"console\",\n prefix: \"veryfront\",\n collectInterval: DEFAULT_METRICS_COLLECT_INTERVAL_MS,\n debug: false,\n};\n\n/**\n * Load metrics configuration from environment and options\n */\nexport function loadConfig(\n config: Partial<MetricsConfig>,\n adapter?: RuntimeAdapter,\n): MetricsConfig {\n const finalConfig = { ...DEFAULT_CONFIG, ...config };\n\n // Check environment variables for configuration\n if (adapter?.env) {\n const envAdapter = adapter.env;\n const otelEnabled = envAdapter.get(\"OTEL_METRICS_ENABLED\");\n const veryfrontOtel = envAdapter.get(\"VERYFRONT_OTEL\");\n\n finalConfig.enabled = otelEnabled === \"true\" ||\n veryfrontOtel === \"1\" ||\n finalConfig.enabled;\n\n const otlpEndpoint = envAdapter.get(\"OTEL_EXPORTER_OTLP_ENDPOINT\");\n const metricsEndpoint = envAdapter.get(\n \"OTEL_EXPORTER_OTLP_METRICS_ENDPOINT\",\n );\n finalConfig.endpoint = otlpEndpoint || metricsEndpoint ||\n finalConfig.endpoint;\n\n const exporterType = envAdapter.get(\"OTEL_METRICS_EXPORTER\");\n if (\n exporterType === \"prometheus\" || exporterType === \"otlp\" ||\n exporterType === \"console\"\n ) {\n finalConfig.exporter = exporterType;\n }\n } else {\n // Fallback to platform getEnv for cross-platform compatibility\n try {\n finalConfig.enabled = getEnv(\"OTEL_METRICS_ENABLED\") === \"true\" ||\n getEnv(\"VERYFRONT_OTEL\") === \"1\" ||\n finalConfig.enabled;\n finalConfig.endpoint = getEnv(\"OTEL_EXPORTER_OTLP_ENDPOINT\") ||\n getEnv(\"OTEL_EXPORTER_OTLP_METRICS_ENDPOINT\") ||\n finalConfig.endpoint;\n const exporterType = getEnv(\"OTEL_METRICS_EXPORTER\");\n if (\n exporterType === \"prometheus\" || exporterType === \"otlp\" ||\n exporterType === \"console\"\n ) {\n finalConfig.exporter = exporterType;\n }\n } catch {\n // getEnv access may fail, silently continue\n }\n }\n\n return finalConfig;\n}\n\n/**\n * Get memory usage from runtime (Deno or Node.js)\n */\nexport function getMemoryUsage(): {\n rss: number;\n heapUsed: number;\n heapTotal: number;\n} | null {\n try {\n // Use platform abstraction for cross-platform compatibility\n return platformMemoryUsage();\n } catch {\n return null;\n }\n}\n", "/**\n * Metrics Instruments Module\n * Barrel exports for all metric instruments\n *\n * @module\n */\n\nexport { initializeInstruments } from \"./instruments-factory.ts\";\nexport type { HttpInstruments } from \"./http-instruments.ts\";\nexport type { CacheInstruments } from \"./cache-instruments.ts\";\nexport type { RenderInstruments } from \"./render-instruments.ts\";\nexport type { RscInstruments } from \"./rsc-instruments.ts\";\nexport type { BuildInstruments } from \"./build-instruments.ts\";\nexport type { DataInstruments } from \"./data-instruments.ts\";\nexport type { MemoryInstruments } from \"./memory-instruments.ts\";\n", "/**\n * Metrics Instruments Factory\n * Main orchestrator for initializing all metric instruments\n *\n * @module\n */\n\nimport type { Meter } from \"@opentelemetry/api\";\nimport { serverLogger as logger } from \"@veryfront/utils\";\nimport type { MetricsConfig, MetricsInstruments, RuntimeState } from \"../metrics/types.ts\";\nimport { createBuildInstruments } from \"./build-instruments.ts\";\nimport { createCacheInstruments } from \"./cache-instruments.ts\";\nimport { createDataInstruments } from \"./data-instruments.ts\";\nimport { createHttpInstruments } from \"./http-instruments.ts\";\nimport { createMemoryInstruments } from \"./memory-instruments.ts\";\nimport { createRenderInstruments } from \"./render-instruments.ts\";\nimport { createRscInstruments } from \"./rsc-instruments.ts\";\n\n/**\n * Initialize all metric instruments\n *\n * This function creates all OpenTelemetry metric instruments organized by category:\n * - HTTP metrics (requests, duration, active requests)\n * - Cache metrics (hits, misses, size)\n * - Render metrics (duration, count, errors)\n * - RSC metrics (render, stream, actions)\n * - Build metrics (duration, bundle size)\n * - Data fetching metrics (duration, count, errors)\n * - Memory metrics (usage, heap)\n *\n * Note: This function is async to maintain backward compatibility with the original API,\n * even though current implementation is synchronous.\n *\n * @param meter - OpenTelemetry meter instance\n * @param config - Metrics configuration\n * @param runtimeState - Runtime state for observable metrics\n * @returns Promise resolving to all metric instruments\n *\n * @example\n * ```ts\n * const instruments = await initializeInstruments(meter, config, runtimeState);\n * instruments.httpRequestCounter?.add(1, { method: \"GET\", status: 200 });\n * ```\n */\nexport function initializeInstruments(\n meter: Meter,\n config: MetricsConfig,\n runtimeState: RuntimeState,\n): Promise<MetricsInstruments> {\n const instruments: MetricsInstruments = {\n httpRequestCounter: null,\n httpRequestDuration: null,\n httpActiveRequests: null,\n cacheGetCounter: null,\n cacheHitCounter: null,\n cacheMissCounter: null,\n cacheSetCounter: null,\n cacheInvalidateCounter: null,\n cacheSizeGauge: null,\n renderDuration: null,\n renderCounter: null,\n renderErrorCounter: null,\n rscRenderDuration: null,\n rscStreamDuration: null,\n rscManifestCounter: null,\n rscPageCounter: null,\n rscStreamCounter: null,\n rscActionCounter: null,\n rscErrorCounter: null,\n buildDuration: null,\n bundleSizeHistogram: null,\n bundleCounter: null,\n dataFetchDuration: null,\n dataFetchCounter: null,\n dataFetchErrorCounter: null,\n corsRejectionCounter: null,\n securityHeadersCounter: null,\n memoryUsageGauge: null,\n heapUsageGauge: null,\n };\n\n try {\n // Create HTTP metrics\n const httpInstruments = createHttpInstruments(meter, config);\n Object.assign(instruments, httpInstruments);\n\n // Create cache metrics\n const cacheInstruments = createCacheInstruments(meter, config, runtimeState);\n Object.assign(instruments, cacheInstruments);\n\n // Create render metrics\n const renderInstruments = createRenderInstruments(meter, config);\n Object.assign(instruments, renderInstruments);\n\n // Create RSC metrics\n const rscInstruments = createRscInstruments(meter, config);\n Object.assign(instruments, rscInstruments);\n\n // Create build metrics\n const buildInstruments = createBuildInstruments(meter, config);\n Object.assign(instruments, buildInstruments);\n\n // Create data fetching metrics\n const dataInstruments = createDataInstruments(meter, config);\n Object.assign(instruments, dataInstruments);\n\n // Create memory metrics\n const memoryInstruments = createMemoryInstruments(meter, config);\n Object.assign(instruments, memoryInstruments);\n } catch (error) {\n logger.warn(\"[metrics] Failed to initialize metric instruments\", error);\n }\n\n return Promise.resolve(instruments);\n}\n", "/**\n * Build Metrics Instruments\n * Creation of build-related metric instruments\n *\n * @module\n */\n\nimport type { Counter, Histogram, Meter } from \"@opentelemetry/api\";\nimport { DURATION_HISTOGRAM_BOUNDARIES_MS, SIZE_HISTOGRAM_BOUNDARIES_KB } from \"@veryfront/config\";\nimport type { MetricsConfig } from \"../metrics/types.ts\";\n\n/**\n * Build metric instruments\n */\nexport interface BuildInstruments {\n buildDuration: Histogram | null;\n bundleSizeHistogram: Histogram | null;\n bundleCounter: Counter | null;\n}\n\n/**\n * Create build metric instruments\n *\n * @param meter - OpenTelemetry meter instance\n * @param config - Metrics configuration\n * @returns Build metric instruments\n *\n * @example\n * ```ts\n * const buildInstruments = createBuildInstruments(meter, config);\n * buildInstruments.bundleCounter?.add(1);\n * ```\n */\nexport function createBuildInstruments(\n meter: Meter,\n config: MetricsConfig,\n): BuildInstruments {\n const buildDuration = meter.createHistogram(\n `${config.prefix}.build.duration`,\n {\n description: \"Build operation duration\",\n unit: \"ms\",\n advice: { explicitBucketBoundaries: DURATION_HISTOGRAM_BOUNDARIES_MS },\n },\n );\n\n const bundleSizeHistogram = meter.createHistogram(\n `${config.prefix}.build.bundle.size`,\n {\n description: \"Bundle size distribution\",\n unit: \"kb\",\n advice: { explicitBucketBoundaries: SIZE_HISTOGRAM_BOUNDARIES_KB },\n },\n );\n\n const bundleCounter = meter.createCounter(\n `${config.prefix}.build.bundles`,\n {\n description: \"Total number of bundles created\",\n unit: \"bundles\",\n },\n );\n\n return {\n buildDuration,\n bundleSizeHistogram,\n bundleCounter,\n };\n}\n", "/**\n * Cache Metrics Instruments\n * Creation of cache-related metric instruments\n *\n * @module\n */\n\nimport type { Counter, Meter, ObservableGauge, ObservableResult } from \"@opentelemetry/api\";\nimport type { MetricsConfig, RuntimeState } from \"../metrics/types.ts\";\n\n/**\n * Cache metric instruments\n */\nexport interface CacheInstruments {\n cacheGetCounter: Counter | null;\n cacheHitCounter: Counter | null;\n cacheMissCounter: Counter | null;\n cacheSetCounter: Counter | null;\n cacheInvalidateCounter: Counter | null;\n cacheSizeGauge: ObservableGauge | null;\n}\n\n/**\n * Create cache metric instruments\n *\n * @param meter - OpenTelemetry meter instance\n * @param config - Metrics configuration\n * @param runtimeState - Runtime state for observable metrics\n * @returns Cache metric instruments\n *\n * @example\n * ```ts\n * const cacheInstruments = createCacheInstruments(meter, config, runtimeState);\n * cacheInstruments.cacheHitCounter?.add(1);\n * ```\n */\nexport function createCacheInstruments(\n meter: Meter,\n config: MetricsConfig,\n runtimeState: RuntimeState,\n): CacheInstruments {\n const cacheGetCounter = meter.createCounter(\n `${config.prefix}.cache.gets`,\n {\n description: \"Total number of cache get operations\",\n unit: \"operations\",\n },\n );\n\n const cacheHitCounter = meter.createCounter(\n `${config.prefix}.cache.hits`,\n {\n description: \"Total number of cache hits\",\n unit: \"hits\",\n },\n );\n\n const cacheMissCounter = meter.createCounter(\n `${config.prefix}.cache.misses`,\n {\n description: \"Total number of cache misses\",\n unit: \"misses\",\n },\n );\n\n const cacheSetCounter = meter.createCounter(\n `${config.prefix}.cache.sets`,\n {\n description: \"Total number of cache set operations\",\n unit: \"operations\",\n },\n );\n\n const cacheInvalidateCounter = meter.createCounter(\n `${config.prefix}.cache.invalidations`,\n {\n description: \"Total number of cache invalidations\",\n unit: \"operations\",\n },\n );\n\n const cacheSizeGauge = meter.createObservableGauge(\n `${config.prefix}.cache.size`,\n {\n description: \"Current cache size\",\n unit: \"entries\",\n },\n );\n cacheSizeGauge.addCallback((result: ObservableResult) => {\n result.observe(runtimeState.cacheSize);\n });\n\n return {\n cacheGetCounter,\n cacheHitCounter,\n cacheMissCounter,\n cacheSetCounter,\n cacheInvalidateCounter,\n cacheSizeGauge,\n };\n}\n", "/**\n * Data Fetching Metrics Instruments\n * Creation of data fetching metric instruments\n *\n * @module\n */\n\nimport type { Counter, Histogram, Meter } from \"@opentelemetry/api\";\nimport { DURATION_HISTOGRAM_BOUNDARIES_MS } from \"@veryfront/config\";\nimport type { MetricsConfig } from \"../metrics/types.ts\";\n\n/**\n * Data fetching metric instruments\n */\nexport interface DataInstruments {\n dataFetchDuration: Histogram | null;\n dataFetchCounter: Counter | null;\n dataFetchErrorCounter: Counter | null;\n}\n\n/**\n * Create data fetching metric instruments\n *\n * @param meter - OpenTelemetry meter instance\n * @param config - Metrics configuration\n * @returns Data fetching metric instruments\n *\n * @example\n * ```ts\n * const dataInstruments = createDataInstruments(meter, config);\n * dataInstruments.dataFetchCounter?.add(1);\n * ```\n */\nexport function createDataInstruments(\n meter: Meter,\n config: MetricsConfig,\n): DataInstruments {\n const dataFetchDuration = meter.createHistogram(\n `${config.prefix}.data.fetch.duration`,\n {\n description: \"Data fetch duration\",\n unit: \"ms\",\n advice: { explicitBucketBoundaries: DURATION_HISTOGRAM_BOUNDARIES_MS },\n },\n );\n\n const dataFetchCounter = meter.createCounter(\n `${config.prefix}.data.fetch.count`,\n {\n description: \"Total number of data fetches\",\n unit: \"fetches\",\n },\n );\n\n const dataFetchErrorCounter = meter.createCounter(\n `${config.prefix}.data.fetch.errors`,\n {\n description: \"Data fetch errors\",\n unit: \"errors\",\n },\n );\n\n return {\n dataFetchDuration,\n dataFetchCounter,\n dataFetchErrorCounter,\n };\n}\n", "/**\n * HTTP Metrics Instruments\n * Creation of HTTP-related metric instruments\n *\n * @module\n */\n\nimport type { Counter, Histogram, Meter, UpDownCounter } from \"@opentelemetry/api\";\nimport { DURATION_HISTOGRAM_BOUNDARIES_MS } from \"@veryfront/config\";\nimport type { MetricsConfig } from \"../metrics/types.ts\";\n\n/**\n * HTTP metric instruments\n */\nexport interface HttpInstruments {\n httpRequestCounter: Counter | null;\n httpRequestDuration: Histogram | null;\n httpActiveRequests: UpDownCounter | null;\n}\n\n/**\n * Create HTTP metric instruments\n *\n * @param meter - OpenTelemetry meter instance\n * @param config - Metrics configuration\n * @returns HTTP metric instruments\n *\n * @example\n * ```ts\n * const httpInstruments = createHttpInstruments(meter, config);\n * httpInstruments.httpRequestCounter?.add(1);\n * ```\n */\nexport function createHttpInstruments(\n meter: Meter,\n config: MetricsConfig,\n): HttpInstruments {\n const httpRequestCounter = meter.createCounter(\n `${config.prefix}.http.requests`,\n {\n description: \"Total number of HTTP requests\",\n unit: \"requests\",\n },\n );\n\n const httpRequestDuration = meter.createHistogram(\n `${config.prefix}.http.request.duration`,\n {\n description: \"HTTP request duration\",\n unit: \"ms\",\n advice: { explicitBucketBoundaries: DURATION_HISTOGRAM_BOUNDARIES_MS },\n },\n );\n\n const httpActiveRequests = meter.createUpDownCounter(\n `${config.prefix}.http.requests.active`,\n {\n description: \"Number of active HTTP requests\",\n unit: \"requests\",\n },\n );\n\n return {\n httpRequestCounter,\n httpRequestDuration,\n httpActiveRequests,\n };\n}\n", "/**\n * Memory Metrics Instruments\n * Creation of memory-related metric instruments\n *\n * @module\n */\n\nimport type { Meter, ObservableGauge, ObservableResult } from \"@opentelemetry/api\";\nimport { getMemoryUsage } from \"../metrics/config.ts\";\nimport type { MetricsConfig } from \"../metrics/types.ts\";\n\n/**\n * Memory metric instruments\n */\nexport interface MemoryInstruments {\n memoryUsageGauge: ObservableGauge | null;\n heapUsageGauge: ObservableGauge | null;\n}\n\n/**\n * Create memory metric instruments\n *\n * @param meter - OpenTelemetry meter instance\n * @param config - Metrics configuration\n * @returns Memory metric instruments\n *\n * @example\n * ```ts\n * const memoryInstruments = createMemoryInstruments(meter, config);\n * // Observables automatically track memory usage\n * ```\n */\nexport function createMemoryInstruments(\n meter: Meter,\n config: MetricsConfig,\n): MemoryInstruments {\n const memoryUsageGauge = meter.createObservableGauge(\n `${config.prefix}.memory.usage`,\n {\n description: \"Memory usage\",\n unit: \"bytes\",\n },\n );\n memoryUsageGauge.addCallback((result: ObservableResult) => {\n const memoryUsage = getMemoryUsage();\n if (memoryUsage) {\n result.observe(memoryUsage.rss);\n }\n });\n\n const heapUsageGauge = meter.createObservableGauge(\n `${config.prefix}.memory.heap`,\n {\n description: \"Heap memory usage\",\n unit: \"bytes\",\n },\n );\n heapUsageGauge.addCallback((result: ObservableResult) => {\n const memoryUsage = getMemoryUsage();\n if (memoryUsage) {\n result.observe(memoryUsage.heapUsed);\n }\n });\n\n return {\n memoryUsageGauge,\n heapUsageGauge,\n };\n}\n", "/**\n * Render Metrics Instruments\n * Creation of render-related metric instruments\n *\n * @module\n */\n\nimport type { Counter, Histogram, Meter } from \"@opentelemetry/api\";\nimport { DURATION_HISTOGRAM_BOUNDARIES_MS } from \"@veryfront/config\";\nimport type { MetricsConfig } from \"../metrics/types.ts\";\n\n/**\n * Render metric instruments\n */\nexport interface RenderInstruments {\n renderDuration: Histogram | null;\n renderCounter: Counter | null;\n renderErrorCounter: Counter | null;\n}\n\n/**\n * Create render metric instruments\n *\n * @param meter - OpenTelemetry meter instance\n * @param config - Metrics configuration\n * @returns Render metric instruments\n *\n * @example\n * ```ts\n * const renderInstruments = createRenderInstruments(meter, config);\n * renderInstruments.renderCounter?.add(1);\n * ```\n */\nexport function createRenderInstruments(\n meter: Meter,\n config: MetricsConfig,\n): RenderInstruments {\n const renderDuration = meter.createHistogram(\n `${config.prefix}.render.duration`,\n {\n description: \"Page render duration\",\n unit: \"ms\",\n advice: { explicitBucketBoundaries: DURATION_HISTOGRAM_BOUNDARIES_MS },\n },\n );\n\n const renderCounter = meter.createCounter(\n `${config.prefix}.render.count`,\n {\n description: \"Total number of page renders\",\n unit: \"renders\",\n },\n );\n\n const renderErrorCounter = meter.createCounter(\n `${config.prefix}.render.errors`,\n {\n description: \"Total number of render errors\",\n unit: \"errors\",\n },\n );\n\n return {\n renderDuration,\n renderCounter,\n renderErrorCounter,\n };\n}\n", "/**\n * RSC Metrics Instruments\n * Creation of React Server Components metric instruments\n *\n * @module\n */\n\nimport type { Counter, Histogram, Meter } from \"@opentelemetry/api\";\nimport { DURATION_HISTOGRAM_BOUNDARIES_MS } from \"@veryfront/config\";\nimport type { MetricsConfig } from \"../metrics/types.ts\";\n\n/**\n * RSC metric instruments\n */\nexport interface RscInstruments {\n rscRenderDuration: Histogram | null;\n rscStreamDuration: Histogram | null;\n rscManifestCounter: Counter | null;\n rscPageCounter: Counter | null;\n rscStreamCounter: Counter | null;\n rscActionCounter: Counter | null;\n rscErrorCounter: Counter | null;\n}\n\n/**\n * Create RSC metric instruments\n *\n * @param meter - OpenTelemetry meter instance\n * @param config - Metrics configuration\n * @returns RSC metric instruments\n *\n * @example\n * ```ts\n * const rscInstruments = createRscInstruments(meter, config);\n * rscInstruments.rscPageCounter?.add(1);\n * ```\n */\nexport function createRscInstruments(\n meter: Meter,\n config: MetricsConfig,\n): RscInstruments {\n const rscRenderDuration = meter.createHistogram(\n `${config.prefix}.rsc.render.duration`,\n {\n description: \"RSC render duration\",\n unit: \"ms\",\n advice: { explicitBucketBoundaries: DURATION_HISTOGRAM_BOUNDARIES_MS },\n },\n );\n\n const rscStreamDuration = meter.createHistogram(\n `${config.prefix}.rsc.stream.duration`,\n {\n description: \"RSC stream duration\",\n unit: \"ms\",\n advice: { explicitBucketBoundaries: DURATION_HISTOGRAM_BOUNDARIES_MS },\n },\n );\n\n const rscManifestCounter = meter.createCounter(\n `${config.prefix}.rsc.manifest`,\n {\n description: \"RSC manifest requests\",\n unit: \"requests\",\n },\n );\n\n const rscPageCounter = meter.createCounter(\n `${config.prefix}.rsc.page`,\n {\n description: \"RSC page requests\",\n unit: \"requests\",\n },\n );\n\n const rscStreamCounter = meter.createCounter(\n `${config.prefix}.rsc.stream`,\n {\n description: \"RSC stream requests\",\n unit: \"requests\",\n },\n );\n\n const rscActionCounter = meter.createCounter(\n `${config.prefix}.rsc.action`,\n {\n description: \"RSC action requests\",\n unit: \"requests\",\n },\n );\n\n const rscErrorCounter = meter.createCounter(\n `${config.prefix}.rsc.errors`,\n {\n description: \"RSC errors\",\n unit: \"errors\",\n },\n );\n\n return {\n rscRenderDuration,\n rscStreamDuration,\n rscManifestCounter,\n rscPageCounter,\n rscStreamCounter,\n rscActionCounter,\n rscErrorCounter,\n };\n}\n", "/**\n * Metrics Recorder\n * Functions for recording metrics across all categories\n */\n\nimport type { MetricsInstruments, RuntimeState } from \"./types.ts\";\n\nexport class MetricsRecorder {\n constructor(\n private instruments: MetricsInstruments,\n private runtimeState: RuntimeState,\n ) {}\n\n recordHttpRequest(attributes?: Record<string, string>): void {\n this.instruments.httpRequestCounter?.add(1, attributes);\n this.instruments.httpActiveRequests?.add(1, attributes);\n this.runtimeState.activeRequests++;\n }\n\n recordHttpRequestComplete(\n durationMs: number,\n attributes?: Record<string, string>,\n ): void {\n this.instruments.httpRequestDuration?.record(durationMs, attributes);\n this.instruments.httpActiveRequests?.add(-1, attributes);\n this.runtimeState.activeRequests--;\n }\n\n recordCacheGet(hit: boolean, attributes?: Record<string, string>): void {\n this.instruments.cacheGetCounter?.add(1, attributes);\n if (hit) {\n this.instruments.cacheHitCounter?.add(1, attributes);\n } else {\n this.instruments.cacheMissCounter?.add(1, attributes);\n }\n }\n\n recordCacheSet(attributes?: Record<string, string>): void {\n this.instruments.cacheSetCounter?.add(1, attributes);\n this.runtimeState.cacheSize++;\n }\n\n recordCacheInvalidate(\n count: number,\n attributes?: Record<string, string>,\n ): void {\n this.instruments.cacheInvalidateCounter?.add(count, attributes);\n this.runtimeState.cacheSize = Math.max(\n 0,\n this.runtimeState.cacheSize - count,\n );\n }\n\n setCacheSize(size: number): void {\n this.runtimeState.cacheSize = size;\n }\n\n // Render Metrics\n recordRender(durationMs: number, attributes?: Record<string, string>): void {\n this.instruments.renderDuration?.record(durationMs, attributes);\n this.instruments.renderCounter?.add(1, attributes);\n }\n\n recordRenderError(attributes?: Record<string, string>): void {\n this.instruments.renderErrorCounter?.add(1, attributes);\n }\n\n // RSC Metrics\n recordRSCRender(\n durationMs: number,\n attributes?: Record<string, string>,\n ): void {\n this.instruments.rscRenderDuration?.record(durationMs, attributes);\n }\n\n recordRSCStream(\n durationMs: number,\n attributes?: Record<string, string>,\n ): void {\n this.instruments.rscStreamDuration?.record(durationMs, attributes);\n }\n\n recordRSCRequest(\n type: \"manifest\" | \"page\" | \"stream\" | \"action\",\n attributes?: Record<string, string>,\n ): void {\n switch (type) {\n case \"manifest\":\n this.instruments.rscManifestCounter?.add(1, attributes);\n break;\n case \"page\":\n this.instruments.rscPageCounter?.add(1, attributes);\n break;\n case \"stream\":\n this.instruments.rscStreamCounter?.add(1, attributes);\n break;\n case \"action\":\n this.instruments.rscActionCounter?.add(1, attributes);\n break;\n }\n }\n\n recordRSCError(attributes?: Record<string, string>): void {\n this.instruments.rscErrorCounter?.add(1, attributes);\n }\n\n // Build Metrics\n recordBuild(durationMs: number, attributes?: Record<string, string>): void {\n this.instruments.buildDuration?.record(durationMs, attributes);\n }\n\n recordBundle(sizeKb: number, attributes?: Record<string, string>): void {\n this.instruments.bundleSizeHistogram?.record(sizeKb, attributes);\n this.instruments.bundleCounter?.add(1, attributes);\n }\n\n // Data Fetching Metrics\n recordDataFetch(\n durationMs: number,\n attributes?: Record<string, string>,\n ): void {\n this.instruments.dataFetchDuration?.record(durationMs, attributes);\n this.instruments.dataFetchCounter?.add(1, attributes);\n }\n\n recordDataFetchError(attributes?: Record<string, string>): void {\n this.instruments.dataFetchErrorCounter?.add(1, attributes);\n }\n\n // Security Metrics\n recordCorsRejection(attributes?: Record<string, string>): void {\n this.instruments.corsRejectionCounter?.add(1, attributes);\n }\n\n recordSecurityHeaders(attributes?: Record<string, string>): void {\n this.instruments.securityHeadersCounter?.add(1, attributes);\n }\n}\n", "export type { AutoInstrumentConfig } from \"./types.ts\";\n\nexport {\n __resetAutoInstrumentForTests,\n initAutoInstrumentation,\n isAutoInstrumentEnabled,\n} from \"./orchestrator.ts\";\n\nexport { createInstrumentedFetch, instrumentHttpHandler } from \"./http-instrumentation.ts\";\n\n// Backward compatibility alias (DEPRECATED)\nexport { createInstrumentedFetch as instrumentFetch } from \"./http-instrumentation.ts\";\n\nexport { instrumentErrorHandler, instrumentReactRender } from \"./react-instrumentation.ts\";\n\nexport { instrument, instrumentBatch, instrumentSync } from \"./wrappers.ts\";\n", "import { serverLogger as logger } from \"@veryfront/utils\";\nimport type { RuntimeAdapter } from \"@veryfront/platform/adapters/base.ts\";\nimport { initTracing } from \"../tracing/index.ts\";\nimport { initMetrics } from \"../metrics/index.ts\";\nimport type { AutoInstrumentConfig } from \"./types.ts\";\nimport { mergeConfig } from \"./configurator.ts\";\n\nlet initialized = false;\n\nexport async function initAutoInstrumentation(\n config: AutoInstrumentConfig = {},\n adapter?: RuntimeAdapter,\n): Promise<void> {\n if (initialized) {\n logger.debug(\"[auto-instrument] Already initialized\");\n return;\n }\n\n const finalConfig = mergeConfig(config);\n\n try {\n await initializeTracing(finalConfig, adapter);\n await initializeMetrics(finalConfig, adapter);\n\n initialized = true;\n logInitialization(finalConfig);\n } catch (error) {\n logger.warn(\"[auto-instrument] Failed to initialize auto-instrumentation\", error);\n initialized = true;\n }\n}\n\nexport function isAutoInstrumentEnabled(): boolean {\n return initialized;\n}\n\n/**\n * Reset initialization state (for testing only)\n * @internal\n */\nexport function __resetAutoInstrumentForTests(): void {\n initialized = false;\n}\n\nasync function initializeTracing(\n config: AutoInstrumentConfig,\n adapter?: RuntimeAdapter,\n): Promise<void> {\n if (config.tracing?.enabled) {\n await initTracing(config.tracing, adapter);\n }\n}\n\nasync function initializeMetrics(\n config: AutoInstrumentConfig,\n adapter?: RuntimeAdapter,\n): Promise<void> {\n if (config.metrics?.enabled) {\n await initMetrics(config.metrics, adapter);\n }\n}\n\nfunction logInitialization(config: AutoInstrumentConfig): void {\n logger.info(\"[auto-instrument] Auto-instrumentation initialized\", {\n tracing: config.tracing?.enabled || false,\n metrics: config.metrics?.enabled || false,\n http: config.instrumentHttp,\n fetch: config.instrumentFetch,\n react: config.instrumentReact,\n });\n}\n", "import type { AutoInstrumentConfig } from \"./types.ts\";\n\nexport const DEFAULT_CONFIG: AutoInstrumentConfig = {\n instrumentHttp: true,\n instrumentFetch: true,\n instrumentReact: true,\n captureErrors: true,\n};\n\nexport function mergeConfig(config: AutoInstrumentConfig = {}): AutoInstrumentConfig {\n return { ...DEFAULT_CONFIG, ...config };\n}\n", "import { serverLogger as logger } from \"@veryfront/utils\";\nimport {\n context as otContext,\n propagation,\n type Span,\n SpanKind,\n SpanStatusCode,\n trace,\n} from \"@opentelemetry/api\";\nimport type { ErrorAttributes, HttpAttributes } from \"./types.ts\";\n\nconst tracer = trace.getTracer(\"veryfront-http\");\n\nconst headersGetter = {\n keys(carrier: Headers): string[] {\n return [...carrier.keys()];\n },\n get(carrier: Headers, key: string): string | undefined {\n return carrier.get(key) ?? undefined;\n },\n};\n\nfunction extractParentContext(headers: Headers) {\n try {\n return propagation.extract(otContext.active(), headers, headersGetter);\n } catch (error) {\n logger.debug(\"[auto-instrument] Failed to extract parent context\", error);\n return otContext.active();\n }\n}\n\nexport function instrumentHttpHandler(\n handler: (request: Request) => Promise<Response> | Response,\n): (request: Request) => Promise<Response> {\n return async (request: Request): Promise<Response> => {\n const startTime = performance.now();\n const url = new URL(request.url);\n const httpAttrs = buildHttpAttributes(request, url);\n const parentContext = extractParentContext(request.headers);\n\n try {\n const response = await tracer.startActiveSpan(\n \"http.server.request\",\n {\n kind: SpanKind.SERVER,\n attributes: httpAttrs,\n },\n parentContext,\n async (span) => {\n try {\n const response = await handler(request);\n const duration = performance.now() - startTime;\n recordResponseSuccess(span, response, duration, httpAttrs);\n return response;\n } catch (error) {\n const duration = performance.now() - startTime;\n recordResponseError(span, error, duration, httpAttrs);\n throw error;\n } finally {\n span.end();\n }\n },\n );\n return response as Response;\n } catch (error) {\n logger.debug(\n \"[auto-instrument] HTTP handler span failed, falling back to raw handler\",\n error,\n );\n return await handler(request);\n }\n };\n}\n\n/**\n * Create an instrumented fetch function without mutating globals\n * Returns a wrapped fetch that adds OpenTelemetry spans\n *\n * @param baseFetch - The fetch function to instrument (defaults to globalThis.fetch)\n * @returns Instrumented fetch function\n *\n * @example\n * ```ts\n * const instrumentedFetch = createInstrumentedFetch()\n * const response = await instrumentedFetch('https://api.example.com')\n * ```\n */\nexport function createInstrumentedFetch(\n baseFetch: typeof fetch = globalThis.fetch,\n): typeof fetch {\n return async function instrumentedFetch(\n input: RequestInfo | URL,\n init?: RequestInit,\n ): Promise<Response> {\n const startTime = performance.now();\n const urlString = extractFetchUrl(input);\n const method = init?.method || \"GET\";\n const fetchAttrs: HttpAttributes = {\n \"http.method\": method,\n \"http.url\": urlString,\n \"http.target\": urlString,\n \"http.host\": \"\",\n \"http.scheme\": \"\",\n };\n\n try {\n const parsed = new URL(urlString);\n fetchAttrs[\"http.target\"] = parsed.pathname;\n fetchAttrs[\"http.host\"] = parsed.host;\n fetchAttrs[\"http.scheme\"] = parsed.protocol.replace(\":\", \"\");\n } catch {\n // Relative URLs are fine; leave defaults\n }\n\n try {\n const response = await tracer.startActiveSpan(\n \"http.client.fetch\",\n {\n kind: SpanKind.CLIENT,\n attributes: fetchAttrs,\n },\n async (span) => {\n try {\n // Inject trace context into headers\n const headers = new Headers(init?.headers);\n propagation.inject(otContext.active(), headers, {\n set: (h, k, v) => h.set(k, v),\n });\n\n const updatedInit = { ...init, headers };\n const response = await baseFetch(input, updatedInit);\n const duration = performance.now() - startTime;\n recordResponseSuccess(span, response, duration, fetchAttrs);\n return response;\n } catch (error) {\n const duration = performance.now() - startTime;\n recordResponseError(span, error, duration, fetchAttrs);\n throw error;\n } finally {\n span.end();\n }\n },\n );\n return response as Response;\n } catch (error) {\n logger.debug(\"[auto-instrument] Fetch span failed, falling back to base fetch\", error);\n return await baseFetch(input, init);\n }\n };\n}\n\nfunction buildHttpAttributes(request: Request, url: URL): HttpAttributes {\n return {\n \"http.method\": request.method,\n \"http.url\": request.url,\n \"http.target\": url.pathname,\n \"http.host\": url.host,\n \"http.scheme\": url.protocol.replace(\":\", \"\"),\n };\n}\n\nfunction recordResponseSuccess(\n span: Span | null,\n response: Response,\n duration: number,\n httpAttrs: HttpAttributes,\n): void {\n if (!span) return;\n\n const attributes: Record<string, number | string> = {\n \"http.status_code\": response.status,\n \"http.response.size\": Number(response.headers.get(\"content-length\") || 0),\n \"http.duration_ms\": Math.round(duration),\n };\n\n span.setAttributes(attributes);\n\n if (response.status >= 500) {\n span.setStatus({ code: SpanStatusCode.ERROR });\n } else if (response.status >= 400) {\n span.setStatus({ code: SpanStatusCode.UNSET, message: `HTTP ${response.status}` });\n } else {\n span.setStatus({ code: SpanStatusCode.OK });\n }\n\n // Preserve original request method/path for downstream analysis\n span.setAttributes({\n \"http.method\": httpAttrs[\"http.method\"],\n \"http.target\": httpAttrs[\"http.target\"],\n });\n}\n\nfunction recordResponseError(\n span: Span | null,\n error: unknown,\n duration: number,\n httpAttrs: HttpAttributes,\n): void {\n if (!span) return;\n\n span.recordException(error as Error);\n span.setAttributes({\n ...buildErrorAttributes(error),\n \"http.duration_ms\": Math.round(duration),\n \"http.method\": httpAttrs[\"http.method\"],\n \"http.target\": httpAttrs[\"http.target\"],\n });\n span.setStatus({\n code: SpanStatusCode.ERROR,\n message: error instanceof Error ? error.message : String(error),\n });\n}\n\nfunction extractFetchUrl(input: RequestInfo | URL): string {\n if (typeof input === \"string\") return input;\n if (input instanceof URL) return input.href;\n return input.url;\n}\n\nfunction buildErrorAttributes(error: unknown): ErrorAttributes {\n return {\n \"error\": \"true\",\n \"error.type\": error instanceof Error ? error.constructor.name : \"Unknown\",\n \"error.message\": error instanceof Error ? error.message : String(error),\n };\n}\n", "import type { Span } from \"@opentelemetry/api\";\nimport { endSpan, setSpanAttributes, SpanNames, startSpan, withSpan } from \"../tracing/index.ts\";\nimport { recordRenderError } from \"../metrics/index.ts\";\n\nexport function instrumentReactRender<T>(\n renderFn: () => Promise<T> | T,\n componentName: string,\n): Promise<T> {\n return withSpan(\n SpanNames.RENDER_COMPONENT,\n async (span) => {\n const startTime = performance.now();\n try {\n const result = renderFn();\n\n if (result instanceof Promise) {\n return await handleAsyncRender(result, span, startTime);\n }\n\n return handleSyncRender(result, span, startTime);\n } catch (error) {\n handleRenderError(span, error, componentName);\n throw error;\n }\n },\n {\n kind: \"internal\",\n attributes: { \"component.name\": componentName },\n },\n );\n}\n\nexport function instrumentErrorHandler(\n handler: (error: Error, request?: Request) => Promise<Response> | Response,\n captureToSpan = true,\n): (error: Error, request?: Request) => Promise<Response> | Response {\n return (error: Error, request?: Request): Promise<Response> | Response => {\n if (captureToSpan) {\n captureErrorToSpan(error, request);\n }\n\n return handler(error, request);\n };\n}\n\nasync function handleAsyncRender<T>(\n result: Promise<T>,\n span: Span | null,\n startTime: number,\n): Promise<T> {\n const resolved = await result;\n recordRenderDuration(span, startTime);\n return resolved;\n}\n\nfunction handleSyncRender<T>(result: T, span: Span | null, startTime: number): T {\n recordRenderDuration(span, startTime);\n return result;\n}\n\nfunction handleRenderError(span: Span | null, error: unknown, componentName: string): void {\n recordRenderError({ component: componentName });\n // endSpan is handled by withActiveSpan automatically,\n // but we need to record the exception and status\n if (span) {\n span.recordException(error as Error);\n span.setStatus({ code: 2, message: String(error) }); // 2 = ERROR\n }\n}\n\nfunction recordRenderDuration(span: Span | null, startTime: number): void {\n const duration = performance.now() - startTime;\n setSpanAttributes(span, { \"render.duration_ms\": Math.floor(duration) });\n}\n\nfunction captureErrorToSpan(error: Error, request?: Request): void {\n const span = startSpan(\"error.handler\", {\n kind: \"internal\",\n attributes: {\n \"error.type\": error.constructor.name,\n \"error.message\": error.message,\n \"error.stack\": error.stack || \"\",\n },\n });\n\n if (request) {\n const url = new URL(request.url);\n setSpanAttributes(span, {\n \"http.method\": request.method,\n \"http.url\": request.url,\n \"http.path\": url.pathname,\n });\n }\n\n endSpan(span, error);\n}\n", "import type { Span } from \"@opentelemetry/api\";\nimport { endSpan, setSpanAttributes, type SpanOptions, startSpan } from \"../tracing/index.ts\";\nimport type { BatchOptions, InstrumentOptions } from \"./types.ts\";\n\nexport function instrument<T extends (...args: any[]) => Promise<any>>(\n fn: T,\n spanName: string,\n options?: InstrumentOptions,\n): T {\n return (async (...args: Parameters<T>): Promise<ReturnType<T>> => {\n const span = createSpan(spanName, args, options);\n const startTime = performance.now();\n\n try {\n const result = await fn(...args);\n recordDuration(span, startTime);\n endSpan(span);\n return result as ReturnType<T>;\n } catch (error) {\n endSpan(span, error as Error);\n throw error;\n }\n }) as T;\n}\n\nexport function instrumentSync<T extends (...args: any[]) => any>(\n fn: T,\n spanName: string,\n options?: InstrumentOptions,\n): T {\n return ((...args: Parameters<T>): ReturnType<T> => {\n const span = createSpan(spanName, args, options);\n const startTime = performance.now();\n\n try {\n const result = fn(...args);\n recordDuration(span, startTime);\n endSpan(span);\n return result as ReturnType<T>;\n } catch (error) {\n endSpan(span, error as Error);\n throw error;\n }\n }) as T;\n}\n\nexport async function instrumentBatch<T>(\n operationName: string,\n items: T[],\n processor: (item: T, index: number) => Promise<void>,\n options?: BatchOptions,\n): Promise<void> {\n const batchSize = options?.batchSize || 10;\n const totalBatches = Math.ceil(items.length / batchSize);\n\n const batchSpan = startSpan(operationName, {\n kind: \"internal\",\n attributes: {\n \"batch.total_items\": items.length,\n \"batch.size\": batchSize,\n \"batch.total_batches\": totalBatches,\n ...(options?.attributes || {}),\n },\n });\n\n try {\n await processBatches(items, batchSize, totalBatches, processor, operationName);\n endSpan(batchSpan);\n } catch (error) {\n endSpan(batchSpan, error as Error);\n throw error;\n }\n}\n\nfunction createSpan(spanName: string, args: unknown[], options?: InstrumentOptions): Span | null {\n const spanOptions: SpanOptions = {\n kind: options?.kind || \"internal\",\n attributes: options?.attributes?.(args) || {},\n };\n\n return startSpan(spanName, spanOptions);\n}\n\nfunction recordDuration(span: Span | null, startTime: number): void {\n const duration = performance.now() - startTime;\n setSpanAttributes(span, { \"duration_ms\": Math.floor(duration) });\n}\n\nasync function processBatches<T>(\n items: T[],\n batchSize: number,\n totalBatches: number,\n processor: (item: T, index: number) => Promise<void>,\n operationName: string,\n): Promise<void> {\n for (let batchIndex = 0; batchIndex < totalBatches; batchIndex++) {\n await processSingleBatch(items, batchSize, batchIndex, processor, operationName);\n }\n}\n\nasync function processSingleBatch<T>(\n items: T[],\n batchSize: number,\n batchIndex: number,\n processor: (item: T, index: number) => Promise<void>,\n operationName: string,\n): Promise<void> {\n const start = batchIndex * batchSize;\n const end = Math.min(start + batchSize, items.length);\n const batch = items.slice(start, end);\n\n const batchItemSpan = startSpan(`${operationName}.batch`, {\n kind: \"internal\",\n attributes: {\n \"batch.index\": batchIndex,\n \"batch.items\": batch.length,\n },\n });\n\n try {\n await Promise.all(batch.map((item, index) => processor(item, start + index)));\n endSpan(batchItemSpan);\n } catch (error) {\n endSpan(batchItemSpan, error as Error);\n throw error;\n }\n}\n", "/**\n * CORS Preflight Handler\n * Handles OPTIONS preflight requests for CORS\n *\n * @module core/cors/preflight\n */\n\nimport type { CORSPreflightOptions } from \"./types.ts\";\nimport { validateOrigin } from \"./validators.ts\";\nimport {\n DEFAULT_HEADERS,\n DEFAULT_MAX_AGE,\n DEFAULT_METHODS,\n HTTP_FORBIDDEN,\n HTTP_NO_CONTENT,\n} from \"./constants.ts\";\nimport { serverLogger } from \"@veryfront/utils/logger/logger.ts\";\n\n/**\n * Handle CORS preflight request\n * Returns appropriate response for OPTIONS requests\n *\n * @param options - Preflight handling options\n * @returns Response with CORS headers or error\n */\nexport async function handleCORSPreflight(options: CORSPreflightOptions): Promise<Response> {\n const { request, config, allowMethods, allowHeaders } = options;\n\n // Validate origin\n const validation = await validateOrigin(request.headers.get(\"origin\"), config);\n\n // If origin not allowed but no config provided, return success without CORS headers (secure-by-default)\n // This allows OPTIONS requests to succeed but doesn't expose CORS capabilities\n if (!validation.allowedOrigin) {\n // No config = allow OPTIONS but no CORS headers (secure-by-default)\n if (!config) {\n return new Response(null, {\n status: HTTP_NO_CONTENT,\n });\n }\n\n // Config exists but origin not allowed = reject\n serverLogger.warn(\"[CORS] Preflight rejected\", {\n origin: request.headers.get(\"origin\"),\n error: validation.error,\n });\n\n return new Response(validation.error || \"CORS policy: Origin not allowed\", {\n status: HTTP_FORBIDDEN,\n headers: {\n \"X-CORS-Error\": validation.error || \"Origin not allowed\",\n },\n });\n }\n\n // Build preflight response headers\n const headers = new Headers();\n\n // Set allowed origin\n headers.set(\"Access-Control-Allow-Origin\", validation.allowedOrigin);\n\n // Add Vary header for non-wildcard origins\n if (validation.allowedOrigin !== \"*\") {\n headers.set(\"Vary\", \"Origin\");\n }\n\n // Determine allowed methods\n const corsConfig = typeof config === \"object\" ? config : null;\n const methods = allowMethods ||\n (corsConfig?.methods?.length ? corsConfig.methods.join(\", \") : DEFAULT_METHODS.join(\", \"));\n headers.set(\"Access-Control-Allow-Methods\", methods);\n\n // Determine allowed headers\n let allowedHeaders = allowHeaders;\n if (!allowedHeaders) {\n // Check if specific headers were requested\n const requestedHeaders = request.headers.get(\"access-control-request-headers\");\n if (requestedHeaders) {\n allowedHeaders = requestedHeaders;\n } else if (corsConfig?.allowedHeaders?.length) {\n allowedHeaders = corsConfig.allowedHeaders.join(\", \");\n } else {\n allowedHeaders = DEFAULT_HEADERS.join(\", \");\n }\n }\n headers.set(\"Access-Control-Allow-Headers\", allowedHeaders);\n\n // Set max age for preflight caching\n const maxAge = corsConfig?.maxAge ?? DEFAULT_MAX_AGE;\n headers.set(\"Access-Control-Max-Age\", String(maxAge));\n\n // Add credentials if configured and allowed\n if (validation.allowCredentials && validation.allowedOrigin !== \"*\") {\n headers.set(\"Access-Control-Allow-Credentials\", \"true\");\n }\n\n return new Response(null, {\n status: HTTP_NO_CONTENT,\n headers,\n });\n}\n\n/**\n * Check if request is a CORS preflight request\n *\n * @param request - The incoming request\n * @returns True if this is a preflight request\n */\nexport function isPreflightRequest(request: Request): boolean {\n return request.method === \"OPTIONS\" &&\n (request.headers.has(\"access-control-request-method\") ||\n request.headers.has(\"access-control-request-headers\"));\n}\n", "/**\n * CORS Constants\n * Default values and constants for CORS handling\n *\n * @module core/cors/constants\n */\n\nimport { DEV_LOCALHOST_ORIGINS } from \"@veryfront/config\";\nimport { getEnv } from \"../../../platform/compat/process.ts\";\n\n/**\n * Default allowed HTTP methods for CORS\n */\nexport const DEFAULT_METHODS = [\"GET\", \"POST\", \"PUT\", \"PATCH\", \"DELETE\", \"OPTIONS\"];\n\n/**\n * Default allowed headers for CORS\n */\nexport const DEFAULT_HEADERS = [\"Content-Type\", \"Authorization\"];\n\n/**\n * Default max age for preflight cache (24 hours in seconds)\n */\nexport const DEFAULT_MAX_AGE = 86400;\n\n/**\n * Development-only localhost origins\n * Re-exported from config/network-defaults for convenience\n *\n * Security Note: These are ONLY used in development mode.\n * Production mode requires explicit origin configuration.\n */\nexport { DEV_LOCALHOST_ORIGINS };\n\n/**\n * HTTP status codes\n */\nexport const HTTP_NO_CONTENT = 204;\nexport const HTTP_FORBIDDEN = 403;\n\n/**\n * Check if running in production mode\n * Checks multiple environment variables for robustness\n *\n * @returns true if in production, false if in development\n *\n * Security Note: Defaults to production (true) for fail-secure behavior.\n */\nexport function isProductionMode(): boolean {\n try {\n const veryfrontEnv = getEnv(\"VERYFRONT_ENV\");\n const nodeEnv = getEnv(\"NODE_ENV\");\n const denoEnv = getEnv(\"DENO_ENV\");\n\n // Check for explicit development mode\n if (\n veryfrontEnv === \"development\" ||\n nodeEnv === \"development\" ||\n denoEnv === \"development\"\n ) {\n return false;\n }\n\n return true;\n } catch {\n // Default to production for safety (fail-secure)\n return true;\n }\n}\n", "/**\n * CORS Middleware\n * Middleware implementation for CORS handling\n *\n * @module core/cors/middleware\n */\n\nimport type { Context, MiddlewareHandler } from \"@veryfront/middleware/core/index.ts\";\nimport type { CORSConfig } from \"./types.ts\";\nimport { handleCORSPreflight, isPreflightRequest } from \"./preflight.ts\";\nimport { applyCORSHeaders } from \"./headers.ts\";\nimport { validateCORSConfig } from \"./validators.ts\";\nimport { createError, toError } from \"../../../core/errors/veryfront-error.ts\";\n\n/**\n * Create CORS middleware\n * Full-featured CORS middleware with security validations\n *\n * @param config - CORS configuration\n * @returns Middleware handler function\n *\n * @example\n * ```typescript\n * // Allow specific origins\n * app.use('*', cors({\n * origin: ['https://example.com', 'https://app.example.com'],\n * credentials: true\n * }))\n *\n * // Dynamic origin validation\n * app.use('*', cors({\n * origin: (origin) => origin.endsWith('.example.com'),\n * methods: ['GET', 'POST'],\n * maxAge: 3600\n * }))\n *\n * // Simple wildcard (not recommended for production)\n * app.use('*', cors({ origin: '*' }))\n * ```\n */\nexport function cors(config?: boolean | CORSConfig): MiddlewareHandler {\n // Validate configuration at middleware creation time\n const validation = validateCORSConfig(config);\n if (!validation.valid) {\n throw toError(createError({\n type: \"config\",\n message: `[CORS] Invalid configuration: ${validation.error}`,\n }));\n }\n\n return async (c: Context, next: () => Promise<Response | undefined> | Response) => {\n const request = c.req;\n\n // Handle preflight OPTIONS request\n if (isPreflightRequest(request)) {\n const response = await handleCORSPreflight({\n request,\n config,\n });\n\n // Set response on context\n return response;\n }\n\n // For actual requests, continue to next middleware\n const response = await next();\n\n // Add CORS headers to response\n if (response) {\n const corsResponse = await applyCORSHeaders({\n request,\n response,\n config,\n });\n\n return corsResponse || response;\n }\n\n return response;\n };\n}\n\n/**\n * Simple CORS middleware for basic use cases\n * Provides minimal CORS support without advanced features\n *\n * @param origin - Origin string or wildcard\n * @returns Middleware handler function\n *\n * @example\n * ```typescript\n * // Allow all origins (development only)\n * app.use('*', corsSimple('*'))\n *\n * // Allow specific origin\n * app.use('*', corsSimple('https://example.com'))\n * ```\n */\nexport function corsSimple(origin: string = \"*\"): MiddlewareHandler {\n return cors({\n origin,\n credentials: false,\n methods: [\"GET\", \"POST\", \"PUT\", \"PATCH\", \"DELETE\", \"OPTIONS\"],\n });\n}\n", "/**\n * Security Handler\n * Handles security headers (CSP, COOP, CORP, COEP) with nonce-based CSP\n */\n\nimport type { SecurityConfig } from \"./types.ts\";\nimport type { RuntimeAdapter } from \"@veryfront/platform/adapters/base.ts\";\nimport { recordSecurityHeaders } from \"@veryfront/observability\";\n\n/**\n * Generate cryptographic nonce for CSP\n */\nexport function generateNonce(): string {\n const array = new Uint8Array(16);\n crypto.getRandomValues(array);\n return btoa(String.fromCharCode(...array));\n}\n\n/**\n * Build Content Security Policy header with nonce\n *\n * @param isDev - Development mode flag\n * @param nonce - Cryptographic nonce for inline scripts/styles\n * @param cspUserHeader - User-provided CSP header\n * @param config - Security configuration\n * @param adapter - Runtime adapter for environment variables\n * @returns CSP header string\n */\nexport function buildCSP(\n isDev: boolean,\n nonce: string,\n cspUserHeader: string | null,\n config?: SecurityConfig | null,\n adapter?: RuntimeAdapter,\n): string {\n const envCsp = adapter?.env?.get?.(\"VERYFRONT_CSP\");\n if (envCsp?.trim()) return envCsp.replace(/{NONCE}/g, nonce);\n\n // Development CSP - relaxed for HMR and dev tools\n // Note: unsafe-eval allowed in dev only for source maps and dev tools\n // Note: 'self' covers /_vf_modules/ (same-origin module server)\n // Note: Nonces REQUIRED for inline module scripts - 'unsafe-inline' doesn't work for modules\n const defaultCsp = isDev\n ? [\n \"default-src 'self'\",\n `style-src 'self' 'unsafe-inline' https://esm.sh https://cdnjs.cloudflare.com https://cdn.veryfront.com https://cdn.jsdelivr.net https://cdn.tailwindcss.com`,\n \"img-src 'self' data: https://cdn.veryfront.com https://cdnjs.cloudflare.com\",\n `script-src 'self' 'nonce-${nonce}' 'unsafe-eval' https://esm.sh https://cdn.tailwindcss.com`,\n \"connect-src 'self' https://esm.sh ws://localhost:* wss://localhost:*\",\n \"font-src 'self' data: https://cdnjs.cloudflare.com\",\n ].join(\"; \")\n : [\n \"default-src 'self'\",\n `style-src 'self' 'nonce-${nonce}'`,\n \"img-src 'self' data:\",\n `script-src 'self' 'nonce-${nonce}'`,\n \"connect-src 'self'\",\n ].join(\"; \");\n\n if (cspUserHeader?.trim()) {\n return `${cspUserHeader.replace(/{NONCE}/g, nonce)}; ${defaultCsp}`;\n }\n\n // If config has CSP directives, merge them\n const cfgCsp = config?.csp;\n if (cfgCsp && typeof cfgCsp === \"object\") {\n const pieces: string[] = [];\n for (const [k, v] of Object.entries(cfgCsp)) {\n if (v === undefined) continue;\n const key = String(k).replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`);\n const val = Array.isArray(v) ? v.join(\" \") : String(v);\n pieces.push(`${key} ${val}`.replace(/{NONCE}/g, nonce));\n }\n if (pieces.length > 0) {\n return `${pieces.join(\"; \")}; ${defaultCsp}`;\n }\n }\n\n return defaultCsp;\n}\n\n/**\n * Get security header value from config or environment\n *\n * @param headerName - Header name (COOP, CORP, COEP)\n * @param defaultValue - Default value if not configured\n * @param config - Security configuration\n * @param adapter - Runtime adapter for environment variables\n * @returns Header value\n */\nexport function getSecurityHeader(\n headerName: string,\n defaultValue: string,\n config?: SecurityConfig | null,\n adapter?: RuntimeAdapter,\n): string {\n const configKey = headerName.toLowerCase();\n const configValue = config?.[configKey as keyof SecurityConfig];\n const envValue = adapter?.env?.get?.(`VERYFRONT_${headerName}`);\n return (typeof configValue === \"string\" ? configValue : undefined) || envValue || defaultValue;\n}\n\n/**\n * Apply security headers to Headers object with nonce\n *\n * @param headers - Headers object to modify\n * @param isDev - Development mode flag\n * @param nonce - Cryptographic nonce for CSP\n * @param cspUserHeader - User-provided CSP header\n * @param config - Security configuration\n * @param adapter - Runtime adapter for environment variables\n */\nexport function applySecurityHeaders(\n headers: Headers,\n isDev: boolean,\n nonce: string,\n cspUserHeader: string | null,\n config?: SecurityConfig | null,\n adapter?: RuntimeAdapter,\n): void {\n const getHeaderOverride = (name: string): string | undefined => {\n const overrides = config?.headers;\n if (!overrides) return undefined;\n const lower = name.toLowerCase();\n for (const [key, value] of Object.entries(overrides)) {\n if (key.toLowerCase() === lower) {\n return value;\n }\n }\n return undefined;\n };\n\n // Always set basic security headers\n const contentTypeOptions = getHeaderOverride(\"x-content-type-options\") ?? \"nosniff\";\n headers.set(\"X-Content-Type-Options\", contentTypeOptions);\n\n const frameOptions = getHeaderOverride(\"x-frame-options\") ?? \"DENY\";\n headers.set(\"X-Frame-Options\", frameOptions);\n\n const xssProtection = getHeaderOverride(\"x-xss-protection\") ?? \"1; mode=block\";\n headers.set(\"X-XSS-Protection\", xssProtection);\n\n // Build and set CSP with nonce\n const csp = buildCSP(isDev, nonce, cspUserHeader, config, adapter);\n if (csp) {\n headers.set(\"Content-Security-Policy\", csp);\n }\n\n // Set HSTS (Strict-Transport-Security) for HTTPS connections\n // Only set in production to enforce HTTPS\n if (!isDev) {\n const hstsMaxAge = config?.hsts?.maxAge ?? 31536000; // 1 year default\n const hstsIncludeSubDomains = config?.hsts?.includeSubDomains ?? true;\n const hstsPreload = config?.hsts?.preload ?? false;\n\n let hstsValue = `max-age=${hstsMaxAge}`;\n if (hstsIncludeSubDomains) {\n hstsValue += \"; includeSubDomains\";\n }\n if (hstsPreload) {\n hstsValue += \"; preload\";\n }\n\n const hstsOverride = getHeaderOverride(\"strict-transport-security\");\n headers.set(\"Strict-Transport-Security\", hstsOverride ?? hstsValue);\n }\n\n // Set COOP, CORP, COEP\n const coop = getSecurityHeader(\"COOP\", \"same-origin\", config, adapter);\n const corp = getSecurityHeader(\"CORP\", \"same-origin\", config, adapter);\n const coep = getSecurityHeader(\"COEP\", \"\", config, adapter);\n\n headers.set(\"Cross-Origin-Opener-Policy\", coop);\n headers.set(\"Cross-Origin-Resource-Policy\", corp);\n if (coep) {\n headers.set(\"Cross-Origin-Embedder-Policy\", coep);\n }\n\n if (config?.headers) {\n for (const [key, value] of Object.entries(config.headers)) {\n if (value === undefined) continue;\n headers.set(key, value);\n }\n }\n\n // Record metrics for security headers application\n recordSecurityHeaders();\n}\n", "/**\n * Cache Handler\n * Handles cache control header generation\n */\n\nimport { CACHE_DURATIONS } from \"./constants.ts\";\nimport type { CacheStrategy } from \"./types.ts\";\n\n/**\n * Build cache control header value from strategy\n *\n * @param strategy - Cache strategy configuration\n * @returns Cache-Control header value\n */\nexport function buildCacheControl(strategy: CacheStrategy): string {\n let cacheControl: string;\n\n if (typeof strategy === \"string\") {\n switch (strategy) {\n case \"no-cache\":\n cacheControl = \"no-cache, no-store, must-revalidate\";\n break;\n case \"no-store\":\n cacheControl = \"no-store\";\n break;\n case \"short\":\n cacheControl = `public, max-age=${CACHE_DURATIONS.SHORT}`;\n break;\n case \"medium\":\n cacheControl = `public, max-age=${CACHE_DURATIONS.MEDIUM}`;\n break;\n case \"long\":\n cacheControl = `public, max-age=${CACHE_DURATIONS.LONG}`;\n break;\n case \"immutable\":\n cacheControl = `public, max-age=${CACHE_DURATIONS.LONG}, immutable`;\n break;\n case \"none\":\n // Prevent all caching - used in development to avoid nonce mismatches\n cacheControl = \"no-cache, no-store, must-revalidate\";\n break;\n default:\n cacheControl = \"public, max-age=0\";\n }\n } else {\n const parts = [];\n parts.push(strategy.public !== false ? \"public\" : \"private\");\n parts.push(`max-age=${strategy.maxAge}`);\n if (strategy.immutable) parts.push(\"immutable\");\n if (strategy.mustRevalidate) parts.push(\"must-revalidate\");\n cacheControl = parts.join(\", \");\n }\n\n return cacheControl;\n}\n", "/**\n * ResponseBuilder - Response Creation Methods\n * Methods for creating different types of HTTP responses\n */\n\nimport { CONTENT_TYPES } from \"./constants.ts\";\n\n/**\n * Internal state interface for response methods\n */\nexport interface ResponseMethodsContext {\n headers: Headers;\n status: number;\n}\n\n/**\n * Build JSON response\n */\nexport function json(\n this: ResponseMethodsContext,\n data: unknown,\n status?: number,\n): Response {\n this.headers.set(\"content-type\", CONTENT_TYPES.JSON);\n return new Response(JSON.stringify(data), {\n status: status ?? this.status,\n headers: this.headers,\n });\n}\n\n/**\n * Build text response\n */\nexport function text(\n this: ResponseMethodsContext,\n body: string,\n status?: number,\n): Response {\n this.headers.set(\"content-type\", CONTENT_TYPES.TEXT);\n return new Response(body, {\n status: status ?? this.status,\n headers: this.headers,\n });\n}\n\n/**\n * Build HTML response\n */\nexport function html(\n this: ResponseMethodsContext,\n body: string,\n status?: number,\n): Response {\n this.headers.set(\"content-type\", CONTENT_TYPES.HTML);\n return new Response(body, {\n status: status ?? this.status,\n headers: this.headers,\n });\n}\n\n/**\n * Build JavaScript response\n */\nexport function javascript(\n this: ResponseMethodsContext,\n code: string,\n status?: number,\n): Response {\n this.headers.set(\"content-type\", CONTENT_TYPES.JAVASCRIPT);\n return new Response(code, {\n status: status ?? this.status,\n headers: this.headers,\n });\n}\n\n/**\n * Build response with custom content type\n */\nexport function withContentType(\n this: ResponseMethodsContext,\n contentType: string,\n body: BodyInit | null,\n status?: number,\n): Response {\n this.headers.set(\"content-type\", contentType);\n return new Response(body, {\n status: status ?? this.status,\n headers: this.headers,\n });\n}\n\n/**\n * Build response with body and current headers\n */\nexport function build(\n this: ResponseMethodsContext,\n body: BodyInit | null = null,\n status?: number,\n): Response {\n return new Response(body, {\n status: status ?? this.status,\n headers: this.headers,\n });\n}\n\n/**\n * Build 304 Not Modified response\n */\nexport function notModified(\n this: ResponseMethodsContext,\n etag?: string,\n): Response {\n if (etag) {\n this.headers.set(\"ETag\", etag);\n }\n return new Response(null, {\n status: 304,\n headers: this.headers,\n });\n}\n", "/**\n * ResponseBuilder - Static Helper Methods\n * Static utility methods for common response patterns\n */\n\nimport { CONTENT_TYPES } from \"./constants.ts\";\nimport type { CacheStrategy, CORSConfig, SecurityConfig } from \"./types.ts\";\nimport { createError, toError } from \"../../../core/errors/veryfront-error.ts\";\n\n/**\n * Type definition for ResponseBuilder constructor\n * Using a minimal interface to avoid circular dependency\n */\ninterface ResponseBuilderConstructor {\n new (config?: {\n securityConfig?: SecurityConfig | null;\n isDev?: boolean;\n cspUserHeader?: string | null;\n adapter?: import(\"@veryfront/platform/adapters/base.ts\").RuntimeAdapter;\n }): ResponseBuilderInstance;\n}\n\n/**\n * Type definition for ResponseBuilder instance\n */\ninterface ResponseBuilderInstance {\n headers: Headers;\n status: number;\n withCORS(req: Request, corsConfig?: boolean | CORSConfig): ResponseBuilderInstance;\n withSecurity(config?: SecurityConfig): ResponseBuilderInstance;\n withCache(strategy: CacheStrategy): ResponseBuilderInstance;\n withETag(etag: string): ResponseBuilderInstance;\n withAllow(methods: string | string[]): ResponseBuilderInstance;\n json(data: unknown, status?: number): Response;\n html(body: string, status?: number): Response;\n text(message: string, status?: number): Response;\n withContentType(contentType: string, body?: BodyInit | null): Response;\n build(body?: BodyInit | null, status?: number): Response;\n}\n\n// Forward declaration - will be set by builder.ts to avoid circular dependency\nlet ResponseBuilderClass: ResponseBuilderConstructor | null = null;\n\n/**\n * Set the ResponseBuilder class reference\n * This is called by builder.ts to avoid circular dependencies\n */\nexport function setResponseBuilderClass(builderClass: ResponseBuilderConstructor): void {\n ResponseBuilderClass = builderClass;\n}\n\n/**\n * Static helper for error responses\n */\nexport function error(\n status: number,\n message: string,\n req: Request,\n config?: {\n securityConfig?: SecurityConfig | null;\n corsConfig?: boolean | CORSConfig;\n contentType?: string;\n },\n): Response {\n if (!ResponseBuilderClass) {\n throw toError(createError({\n type: \"config\",\n message: \"ResponseBuilder class not initialized\",\n }));\n }\n const builder = new ResponseBuilderClass(config);\n builder.withCORS(req, config?.corsConfig);\n if (config?.securityConfig !== undefined) {\n builder.withSecurity(config.securityConfig ?? undefined);\n }\n\n const contentType = config?.contentType ?? CONTENT_TYPES.TEXT;\n if (contentType === CONTENT_TYPES.JSON) {\n return builder.json({ error: message }, status);\n } else if (contentType === CONTENT_TYPES.HTML) {\n return builder.html(message, status);\n }\n return builder.text(message, status);\n}\n\n/**\n * Static helper for JSON responses\n */\nexport function json(\n data: unknown,\n req: Request,\n config?: {\n status?: number;\n securityConfig?: SecurityConfig | null;\n corsConfig?: boolean | CORSConfig;\n cache?: CacheStrategy;\n etag?: string;\n },\n): Response {\n if (!ResponseBuilderClass) {\n throw toError(createError({\n type: \"config\",\n message: \"ResponseBuilder class not initialized\",\n }));\n }\n const builder = new ResponseBuilderClass(config);\n builder.withCORS(req, config?.corsConfig);\n if (config?.securityConfig !== undefined) {\n builder.withSecurity(config.securityConfig ?? undefined);\n }\n if (config?.cache) {\n builder.withCache(config.cache);\n }\n if (config?.etag) {\n builder.withETag(config.etag);\n }\n return builder.json(data, config?.status);\n}\n\n/**\n * Static helper for HTML responses\n */\nexport function html(\n body: string,\n req: Request,\n config?: {\n status?: number;\n securityConfig?: SecurityConfig | null;\n corsConfig?: boolean | CORSConfig;\n cache?: CacheStrategy;\n etag?: string;\n },\n): Response {\n if (!ResponseBuilderClass) {\n throw toError(createError({\n type: \"config\",\n message: \"ResponseBuilder class not initialized\",\n }));\n }\n const builder = new ResponseBuilderClass(config);\n builder.withCORS(req, config?.corsConfig);\n if (config?.securityConfig !== undefined) {\n builder.withSecurity(config.securityConfig ?? undefined);\n }\n if (config?.cache) {\n builder.withCache(config.cache);\n }\n if (config?.etag) {\n builder.withETag(config.etag);\n }\n return builder.html(body, config?.status);\n}\n\n/**\n * Static helper for OPTIONS preflight responses\n */\nexport function preflight(\n req: Request,\n config?: {\n allowMethods?: string | string[];\n allowHeaders?: string | string[];\n securityConfig?: SecurityConfig | null;\n corsConfig?: boolean | CORSConfig;\n },\n): Response {\n if (!ResponseBuilderClass) {\n throw toError(createError({\n type: \"config\",\n message: \"ResponseBuilder class not initialized\",\n }));\n }\n const builder = new ResponseBuilderClass(config);\n builder.withCORS(req, config?.corsConfig);\n if (config?.securityConfig !== undefined) {\n builder.withSecurity(config.securityConfig ?? undefined);\n }\n\n const methods = config?.allowMethods ?? \"GET,POST,PUT,PATCH,DELETE,OPTIONS\";\n builder.withAllow(methods);\n\n const headers = config?.allowHeaders ??\n req.headers.get(\"access-control-request-headers\") ??\n \"Content-Type,Authorization\";\n builder.headers.set(\n \"Access-Control-Allow-Headers\",\n Array.isArray(headers) ? headers.join(\", \") : headers,\n );\n\n return builder.build(null, 204);\n}\n\n/**\n * Static helper for streaming responses\n */\nexport function stream(\n streamData: ReadableStream,\n req: Request,\n config?: {\n contentType?: string;\n securityConfig?: SecurityConfig | null;\n corsConfig?: boolean | CORSConfig;\n cache?: CacheStrategy;\n },\n): Response {\n if (!ResponseBuilderClass) {\n throw toError(createError({\n type: \"config\",\n message: \"ResponseBuilder class not initialized\",\n }));\n }\n const builder = new ResponseBuilderClass(config);\n builder.withCORS(req, config?.corsConfig);\n if (config?.securityConfig !== undefined) {\n builder.withSecurity(config.securityConfig ?? undefined);\n }\n if (config?.cache) {\n builder.withCache(config.cache);\n }\n const contentType = config?.contentType ?? \"application/octet-stream\";\n return builder.withContentType(contentType, streamData);\n}\n", "/**\n * Input Validation Module\n * Comprehensive input validation system for API handlers\n *\n * @module @veryfront/security/input-validation\n */\n\n// Types\nexport type { ParseFormOptions, ParseJsonOptions, RequestLimits, ValidatedData } from \"./types.ts\";\nexport { DEFAULT_LIMITS } from \"./types.ts\";\n\n// Errors\nexport { ValidationError } from \"./errors.ts\";\n\n// Limit validators\nexport { readBodyWithLimit, validateRequestLimits } from \"./limits.ts\";\n\n// Parsers\nexport { parseFormData, parseJsonBody, parseQueryParams } from \"./parsers.ts\";\n\n// Sanitizers\nexport { sanitizeData } from \"./sanitizers.ts\";\n\n// Common schemas\nexport { CommonSchemas } from \"./schemas.ts\";\n\n// Handler factory\nexport {\n createValidatedHandler,\n type ValidatedHandlerConfig,\n type ValidatedHandlerFunction,\n} from \"./handler.ts\";\n", "/**\n * Input Validation Types\n * Type definitions for input validation system\n */\n\nimport {\n DEFAULT_MAX_BODY_SIZE_BYTES,\n DEFAULT_MAX_FILE_SIZE_BYTES,\n DEFAULT_MAX_HEADER_SIZE_BYTES,\n DEFAULT_MAX_URL_LENGTH_BYTES,\n} from \"@veryfront/core/constants/index.ts\";\n\n/**\n * Request size limits configuration\n */\nexport interface RequestLimits {\n maxBodySize?: number;\n maxUrlLength?: number;\n maxHeaderSize?: number;\n maxFileSize?: number;\n}\n\n/**\n * Default size limits (conservative for security)\n */\nexport const DEFAULT_LIMITS: Required<RequestLimits> = {\n maxBodySize: DEFAULT_MAX_BODY_SIZE_BYTES, // 1MB\n maxUrlLength: DEFAULT_MAX_URL_LENGTH_BYTES, // 2KB\n maxHeaderSize: DEFAULT_MAX_HEADER_SIZE_BYTES, // 8KB\n maxFileSize: DEFAULT_MAX_FILE_SIZE_BYTES, // 5MB\n};\n\n/**\n * Validation options for JSON body parsing\n */\nexport interface ParseJsonOptions {\n limits?: RequestLimits;\n sanitize?: boolean;\n}\n\n/**\n * Validation options for form data parsing\n */\nexport interface ParseFormOptions {\n limits?: RequestLimits;\n}\n\n/**\n * Validated data container\n */\nexport interface ValidatedData<TBody = unknown, TQuery = unknown> {\n body?: TBody;\n query?: TQuery;\n}\n", "/**\n * Core constants module - centralized magic numbers and strings\n *\n * This module consolidates all magic values used throughout the codebase\n * into well-organized, self-documenting constants. This improves:\n * - Maintainability: Change values in one place\n * - Consistency: Same values used everywhere\n * - Clarity: Named constants explain their purpose\n *\n * @module core/constants\n */\n\n// Re-export all existing constants from utils/constants\nexport * from \"../utils/constants/index.ts\";\n\n// Handler priorities - defines execution order in middleware pipeline\nexport * from \"./priorities.ts\";\n\n// Retry and error handling constants\nexport * from \"./retry.ts\";\n\n// Buffer and memory size constants\nexport * from \"./buffers.ts\";\n\n// String truncation and display limits\nexport * from \"./limits.ts\";\n\n// Metrics boundaries and histogram buckets\nexport * from \"./metrics.ts\";\n\n// Hash algorithm identifiers\nexport * from \"./crypto.ts\";\n", "/**\n * Handler priority constants\n *\n * These constants define the execution order of handlers in the middleware pipeline.\n * Lower numbers run first, higher numbers run last.\n *\n * Priority Levels:\n * - CRITICAL (0): Security, authentication - must run first\n * - VERY_HIGH (50): CORS, security headers - run very early\n * - HIGH (100-300): Health checks, monitoring, dev tools\n * - MEDIUM (400-700): File serving, API routes, RSC endpoints\n * - LOW (1000): SSR - catch-all for pages\n * - FALLBACK (10000): 404 handler - absolute last resort\n */\n\n/** CRITICAL priority - Security and authentication handlers (runs first) */\nexport const PRIORITY_CRITICAL = 0;\n\n/** VERY_HIGH priority - CORS and security headers */\nexport const PRIORITY_VERY_HIGH = 50;\n\n/** HIGH priority - Health checks and monitoring endpoints */\nexport const PRIORITY_HIGH = 100;\n\n/** HIGH priority - Client-side logging (dev mode) */\nexport const PRIORITY_HIGH_CLIENT_LOG = 200;\n\n/** HIGH priority - Dev endpoints (dev mode) */\nexport const PRIORITY_HIGH_DEV = 300;\n\n/** MEDIUM priority - Dev file handler */\nexport const PRIORITY_MEDIUM_DEV_FILES = 400;\n\n/** MEDIUM priority - Static file serving */\nexport const PRIORITY_MEDIUM_STATIC = 500;\n\n/** MEDIUM priority - Self-hosted lib modules (veryfront/ai/*) */\nexport const PRIORITY_MEDIUM_LIB_MODULES = 550;\n\n/** MEDIUM priority - RSC, module, and static handlers */\nexport const PRIORITY_MEDIUM = 600;\n\n/** MEDIUM priority - API route handlers */\nexport const PRIORITY_MEDIUM_API = 700;\n\n/** LOW priority - SSR handler (catch-all for pages) */\nexport const PRIORITY_LOW = 1000;\n\n/** FALLBACK priority - 404 handler (runs last) */\nexport const PRIORITY_FALLBACK = 10000;\n\n/**\n * Priority level definitions for better readability in code\n */\nexport const HANDLER_PRIORITIES = {\n CRITICAL: PRIORITY_CRITICAL,\n VERY_HIGH: PRIORITY_VERY_HIGH,\n HIGH: PRIORITY_HIGH,\n HIGH_CLIENT_LOG: PRIORITY_HIGH_CLIENT_LOG,\n HIGH_DEV: PRIORITY_HIGH_DEV,\n MEDIUM_DEV_FILES: PRIORITY_MEDIUM_DEV_FILES,\n MEDIUM_STATIC: PRIORITY_MEDIUM_STATIC,\n MEDIUM_LIB_MODULES: PRIORITY_MEDIUM_LIB_MODULES,\n MEDIUM: PRIORITY_MEDIUM,\n MEDIUM_API: PRIORITY_MEDIUM_API,\n LOW: PRIORITY_LOW,\n FALLBACK: PRIORITY_FALLBACK,\n} as const;\n", "/**\n * Retry and error handling constants\n *\n * These constants define default retry behavior for various operations\n * that may fail temporarily (network requests, file I/O, etc.)\n */\n\n/** Default number of retry attempts before giving up */\nexport const DEFAULT_RETRY_MAX_ATTEMPTS = 3;\n\n/** Initial delay between retry attempts (in milliseconds) */\nexport const DEFAULT_RETRY_INITIAL_DELAY_MS = 100;\n\n/** Maximum delay between retry attempts (in milliseconds) */\nexport const DEFAULT_RETRY_MAX_DELAY_MS = 5000;\n\n/** Exponential backoff multiplier (delay *= this value each retry) */\nexport const DEFAULT_RETRY_BACKOFF_MULTIPLIER = 2;\n\n/**\n * API client retry configuration defaults\n */\nexport const API_RETRY_MAX_ATTEMPTS = 3;\nexport const API_RETRY_INITIAL_DELAY_MS = 1000;\nexport const API_RETRY_MAX_DELAY_MS = 10000;\n\n/**\n * File system operation retry defaults\n */\nexport const FS_RETRY_MAX_ATTEMPTS = 3;\nexport const FS_RETRY_INITIAL_DELAY_MS = 1000;\nexport const FS_RETRY_MAX_DELAY_MS = 10000;\n\n/**\n * WebSocket reconnection defaults\n */\nexport const WS_RECONNECT_MAX_ATTEMPTS = 5;\nexport const WS_RECONNECT_INITIAL_DELAY_MS = 1000;\nexport const WS_RECONNECT_MAX_DELAY_MS = 30000;\n", "/**\n * Buffer size and memory-related constants\n *\n * These constants define buffer sizes for various I/O operations,\n * memory limits, and chunk sizes for streaming data.\n */\n\n/** Standard buffer sizes (powers of 2 for optimal memory alignment) */\nexport const BUFFER_SIZE_256_BYTES = 256;\nexport const BUFFER_SIZE_512_BYTES = 512;\nexport const BUFFER_SIZE_1_KB = 1024;\nexport const BUFFER_SIZE_2_KB = 2048;\nexport const BUFFER_SIZE_4_KB = 4096;\nexport const BUFFER_SIZE_8_KB = 8192;\nexport const BUFFER_SIZE_16_KB = 16384;\nexport const BUFFER_SIZE_32_KB = 32768;\nexport const BUFFER_SIZE_64_KB = 65536;\n\n/**\n * RSC file reading buffer (2KB)\n * Used to read file headers to detect 'use client' and 'use server' directives\n */\nexport const RSC_FILE_READ_BUFFER_SIZE_BYTES = BUFFER_SIZE_2_KB;\n\n/**\n * Default maximum body size for input validation (1MB)\n */\nexport const DEFAULT_MAX_BODY_SIZE_BYTES = 1024 * 1024;\n\n/**\n * Default maximum URL length for input validation (2KB)\n */\nexport const DEFAULT_MAX_URL_LENGTH_BYTES = BUFFER_SIZE_2_KB;\n\n/**\n * Default maximum HTTP header size (8KB)\n * Standard limit used by many web servers (nginx, Apache)\n */\nexport const DEFAULT_MAX_HEADER_SIZE_BYTES = BUFFER_SIZE_8_KB;\n\n/**\n * Default maximum file upload size (5MB)\n */\nexport const DEFAULT_MAX_FILE_SIZE_BYTES = 5 * 1024 * 1024;\n\n/**\n * Prefetch queue maximum size (1MB)\n * Total size of all prefetched resources in memory\n */\nexport const PREFETCH_QUEUE_MAX_SIZE_BYTES = 1024 * 1024;\n\n/**\n * Maximum chunk size for bundling (4MB)\n */\nexport const MAX_BUNDLE_CHUNK_SIZE_BYTES = 4096 * 1024;\n", "/**\n * Display limits and truncation constants\n *\n * These constants define how much data to show in logs, error messages,\n * debug output, and other user-facing displays to prevent overwhelming\n * output or memory issues.\n */\n\n/** Maximum string length for general display purposes */\nexport const MAX_STRING_DISPLAY_LENGTH = 1000;\n\n/** Maximum characters to show in log preview (e.g., request body) */\nexport const LOG_PREVIEW_MAX_LENGTH_CHARS = 500;\n\n/** Maximum characters for short log preview (e.g., WebSocket data) */\nexport const LOG_PREVIEW_SHORT_LENGTH_CHARS = 100;\n\n/** Maximum characters for code preview in error messages */\nexport const CODE_PREVIEW_MAX_LENGTH_CHARS = 200;\n\n/** Maximum number of stack trace lines to show */\nexport const MAX_STACK_TRACE_LINES = 100;\n\n/** Maximum characters in span/trace names before truncation */\nexport const MAX_SPAN_NAME_LENGTH = 1000;\n\n/** Maximum size of attribute values in traces (10KB) */\nexport const MAX_TRACE_ATTRIBUTE_VALUE_SIZE = 10000;\n\n/** Maximum number of events per span before truncation */\nexport const MAX_EVENTS_PER_SPAN = 100;\n\n/** Maximum number of links per span before truncation */\nexport const MAX_LINKS_PER_SPAN = 100;\n\n/** Maximum action arguments for RSC server actions */\nexport const MAX_SERVER_ACTION_ARGS = 50;\n\n/** Maximum test iterations for performance tests */\nexport const MAX_TEST_ITERATIONS = 100;\n\n/** Maximum cache entries for various caches */\nexport const CACHE_MAX_ENTRIES_SMALL = 50;\nexport const CACHE_MAX_ENTRIES_MEDIUM = 200;\nexport const CACHE_MAX_ENTRIES_LARGE = 500;\nexport const CACHE_MAX_ENTRIES_XLARGE = 1000;\n\n/** API route matcher cache size */\nexport const API_ROUTE_CACHE_MAX_ENTRIES = 500;\n\n/** Handler cache size */\nexport const HANDLER_CACHE_MAX_ENTRIES = 256;\n\n/** Maximum path length for security validation */\nexport const MAX_PATH_LENGTH_CHARS = 4096;\n\n/** Maximum port number (valid TCP port range) */\nexport const MAX_PORT_NUMBER = 65535;\n\n/** Minimum port number (valid TCP port range) */\nexport const MIN_PORT_NUMBER = 1;\n\n/** Maximum URL length for schema validation */\nexport const MAX_URL_LENGTH_FOR_VALIDATION = 2048;\n", "/**\n * Metrics and observability constants\n *\n * These constants define histogram boundaries, time buckets,\n * and other metrics-related configuration values.\n */\n\n/**\n * SSR render time histogram boundaries (in milliseconds)\n * Used to bucket SSR rendering times for performance analysis\n *\n * Buckets: 5ms, 10ms, 25ms, 50ms, 75ms, 100ms, 250ms, 500ms, 750ms,\n * 1s, 2.5s, 5s, 7.5s, 10s\n */\nexport const SSR_RENDER_TIME_BOUNDARIES_MS = [\n 5,\n 10,\n 25,\n 50,\n 75,\n 100,\n 250,\n 500,\n 750,\n 1000,\n 2500,\n 5000,\n 7500,\n 10000,\n];\n\n/**\n * HTTP request duration histogram boundaries (in milliseconds)\n * Similar buckets for general HTTP request timing\n */\nexport const HTTP_REQUEST_DURATION_BOUNDARIES_MS = SSR_RENDER_TIME_BOUNDARIES_MS;\n\n/**\n * RSC stream duration boundaries (in milliseconds)\n */\nexport const RSC_STREAM_DURATION_BOUNDARIES_MS = [\n 10,\n 25,\n 50,\n 100,\n 200,\n 500,\n 1000,\n 2000,\n 5000,\n];\n\n/**\n * Default metrics collection interval (60 seconds)\n * How often to collect and export metrics\n */\nexport const DEFAULT_METRICS_COLLECTION_INTERVAL_MS = 60000;\n\n/**\n * Default rate limiter settings\n */\nexport const DEFAULT_RATE_LIMIT_REQUESTS = 100;\nexport const DEFAULT_RATE_LIMIT_WINDOW_MS = 60000;\n\n/**\n * Cache statistics sample size for metrics\n */\nexport const CACHE_METRICS_SAMPLE_SIZE = 100;\n", "/**\n * Cryptographic algorithm and hash constants\n *\n * These constants define algorithm identifiers and related\n * cryptographic configuration values.\n */\n\n/** SHA-256 algorithm identifier */\nexport const HASH_ALGORITHM_SHA256 = \"SHA-256\";\n\n/** SHA-1 algorithm identifier (legacy, avoid for security) */\nexport const HASH_ALGORITHM_SHA1 = \"SHA-1\";\n\n/** MD5 algorithm identifier (legacy, avoid for security) */\nexport const HASH_ALGORITHM_MD5 = \"MD5\";\n\n/** Expected length of SHA-256 hex string (64 characters) */\nexport const SHA256_HEX_LENGTH = 64;\n\n/** Expected length of SHA-1 hex string (40 characters) */\nexport const SHA1_HEX_LENGTH = 40;\n\n/** Expected length of MD5 hex string (32 characters) */\nexport const MD5_HEX_LENGTH = 32;\n\n/**\n * FNV-1a hash prime multiplier (32-bit)\n */\nexport const FNV1A_PRIME_32 = 16777619;\n\n/**\n * Nonce length for CSP (Content Security Policy)\n * Typical length is 16-32 bytes (128-256 bits)\n */\nexport const CSP_NONCE_LENGTH_BYTES = 16;\n", "/**\n * Input Validation Errors\n * Custom error classes for validation failures\n */\n\n/**\n * Custom validation error with details\n */\nexport class ValidationError extends Error {\n constructor(\n message: string,\n public readonly details?: unknown,\n ) {\n super(message);\n this.name = \"ValidationError\";\n }\n}\n", "/**\n * Request Limit Validators\n * Functions for validating request size limits\n */\n\nimport { ValidationError } from \"./errors.ts\";\nimport { DEFAULT_LIMITS, type RequestLimits } from \"./types.ts\";\n\n/**\n * Validate request size limits (URL, headers, body)\n *\n * @param request - Request object to validate\n * @param limits - Optional custom size limits\n * @throws ValidationError if any limit is exceeded\n *\n * @example\n * ```ts\n * validateRequestLimits(request, {\n * maxUrlLength: 1024,\n * maxBodySize: 512 * 1024\n * })\n * ```\n */\nexport function validateRequestLimits(\n request: Request,\n limits: RequestLimits = {},\n): void {\n const config = { ...DEFAULT_LIMITS, ...limits };\n\n validateUrlLength(request.url, config.maxUrlLength);\n validateContentLength(request, config.maxBodySize);\n validateHeaderSize(request, config.maxHeaderSize);\n}\n\n/**\n * Validate URL length\n *\n * @param url - URL to validate\n * @param maxLength - Maximum allowed URL length\n * @throws ValidationError if URL is too long\n */\nfunction validateUrlLength(url: string, maxLength: number): void {\n if (url.length > maxLength) {\n throw new ValidationError(\"URL too long\", {\n maxLength,\n actualLength: url.length,\n });\n }\n}\n\n/**\n * Validate Content-Length header\n *\n * @param request - Request object with headers\n * @param maxSize - Maximum allowed body size\n * @throws ValidationError if Content-Length is invalid or too large\n */\nfunction validateContentLength(request: Request, maxSize: number): void {\n const contentLength = request.headers.get(\"content-length\");\n if (!contentLength) return;\n\n const size = parseInt(contentLength, 10);\n if (isNaN(size)) {\n throw new ValidationError(\"Invalid Content-Length header\");\n }\n\n if (size > maxSize) {\n throw new ValidationError(\"Request body too large\", {\n maxSize,\n actualSize: size,\n });\n }\n}\n\n/**\n * Validate total header size (approximate)\n *\n * @param request - Request object with headers\n * @param maxSize - Maximum allowed header size\n * @throws ValidationError if headers are too large\n */\nfunction validateHeaderSize(request: Request, maxSize: number): void {\n let headerSize = 0;\n\n request.headers.forEach((value, key) => {\n headerSize += key.length + value.length + 4; // \": \" and \"\\r\\n\"\n });\n\n if (headerSize > maxSize) {\n throw new ValidationError(\"Headers too large\", {\n maxSize,\n actualSize: headerSize,\n });\n }\n}\n\n/**\n * Read request body with size limit enforcement\n *\n * @param request - Request object with body stream\n * @param maxSize - Maximum allowed body size\n * @returns Body content as string\n * @throws ValidationError if body exceeds size limit\n *\n * @example\n * ```ts\n * const body = await readBodyWithLimit(request, 1024 * 1024) // 1MB limit\n * ```\n */\nexport async function readBodyWithLimit(\n request: Request,\n maxSize: number = DEFAULT_LIMITS.maxBodySize,\n): Promise<string> {\n const reader = request.body?.getReader();\n if (!reader) {\n throw new ValidationError(\"No request body\");\n }\n\n const chunks: Uint8Array[] = [];\n let totalSize = 0;\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n totalSize += value.length;\n if (totalSize > maxSize) {\n throw new ValidationError(\"Request body exceeds size limit\", {\n maxSize,\n bytesRead: totalSize,\n });\n }\n\n chunks.push(value);\n }\n } finally {\n reader.releaseLock();\n }\n\n // Combine chunks and decode\n const combined = new Uint8Array(totalSize);\n let offset = 0;\n for (const chunk of chunks) {\n combined.set(chunk, offset);\n offset += chunk.length;\n }\n\n return new TextDecoder().decode(combined);\n}\n", "/**\n * Request Parsers\n * Functions for parsing and validating different request body types\n */\n\nimport { z } from \"zod\";\nimport { ValidationError } from \"./errors.ts\";\nimport { readBodyWithLimit, validateRequestLimits } from \"./limits.ts\";\nimport { sanitizeData } from \"./sanitizers.ts\";\nimport { DEFAULT_LIMITS, type ParseFormOptions, type ParseJsonOptions } from \"./types.ts\";\n\n/**\n * Parse and validate JSON body with schema\n *\n * @param request - Request object with JSON body\n * @param schema - Zod schema to validate against\n * @param options - Optional parsing configuration\n * @returns Validated and optionally sanitized data\n * @throws ValidationError if parsing or validation fails\n *\n * @example\n * ```ts\n * const userSchema = z.object({\n * name: z.string(),\n * email: z.string().email()\n * })\n *\n * const user = await parseJsonBody(request, userSchema, { sanitize: true })\n * ```\n */\nexport async function parseJsonBody<T>(\n request: Request,\n schema: z.ZodSchema<T>,\n options?: ParseJsonOptions,\n): Promise<T> {\n // Validate request limits first\n validateRequestLimits(request, options?.limits);\n\n let data: unknown;\n try {\n // Parse JSON with size limit enforcement\n const text = await readBodyWithLimit(request, options?.limits?.maxBodySize);\n data = JSON.parse(text);\n } catch (error) {\n if (error instanceof ValidationError) throw error;\n throw new ValidationError(\"Invalid JSON in request body\", {\n error: error instanceof Error ? error.message : \"Parse error\",\n });\n }\n\n // Validate against schema\n try {\n const validated = await schema.parseAsync(data);\n\n // Optional sanitization\n if (options?.sanitize) {\n return sanitizeData(validated) as T;\n }\n\n return validated;\n } catch (error) {\n if (error instanceof z.ZodError) {\n throw new ValidationError(\"Validation failed\", {\n errors: error.errors.map((e) => ({\n path: e.path.join(\".\"),\n message: e.message,\n code: e.code,\n })),\n });\n }\n throw error;\n }\n}\n\n/**\n * Parse and validate form data\n *\n * @param request - Request object with form data body\n * @param schema - Zod schema to validate against\n * @param options - Optional parsing configuration\n * @returns Validated form data\n * @throws ValidationError if parsing or validation fails\n *\n * @example\n * ```ts\n * const uploadSchema = z.object({\n * file: z.instanceof(File),\n * description: z.string()\n * })\n *\n * const data = await parseFormData(request, uploadSchema)\n * ```\n */\nexport async function parseFormData<T>(\n request: Request,\n schema: z.ZodSchema<T>,\n options?: ParseFormOptions,\n): Promise<T> {\n validateRequestLimits(request, options?.limits);\n\n try {\n const formData = await request.formData();\n const data: Record<string, unknown> = {};\n\n // Convert FormData to object\n for (const [key, value] of formData.entries()) {\n if (value instanceof File) {\n // Validate file size\n const maxFileSize = options?.limits?.maxFileSize || DEFAULT_LIMITS.maxFileSize;\n if (value.size > maxFileSize) {\n throw new ValidationError(`File ${key} too large`, {\n maxSize: maxFileSize,\n actualSize: value.size,\n });\n }\n data[key] = value;\n } else {\n data[key] = value;\n }\n }\n\n return await schema.parseAsync(data);\n } catch (error) {\n if (error instanceof z.ZodError) {\n throw new ValidationError(\"Form validation failed\", {\n errors: error.errors,\n });\n }\n throw error;\n }\n}\n\n/**\n * Parse URL search params with validation\n *\n * @param request - Request object with URL search params\n * @param schema - Zod schema to validate against\n * @returns Validated query parameters\n * @throws ValidationError if validation fails\n *\n * @example\n * ```ts\n * const querySchema = z.object({\n * page: z.coerce.number(),\n * search: z.string().optional()\n * })\n *\n * const params = parseQueryParams(request, querySchema)\n * ```\n */\nexport function parseQueryParams<T>(\n request: Request,\n schema: z.ZodSchema<T>,\n): T {\n const url = new URL(request.url);\n const params: Record<string, unknown> = {};\n\n // Convert URLSearchParams to object\n url.searchParams.forEach((value, key) => {\n // Handle array parameters (e.g., ?tags=a&tags=b)\n if (params[key]) {\n if (Array.isArray(params[key])) {\n (params[key] as unknown[]).push(value);\n } else {\n params[key] = [params[key], value];\n }\n } else {\n params[key] = value;\n }\n });\n\n try {\n return schema.parse(params);\n } catch (error) {\n if (error instanceof z.ZodError) {\n throw new ValidationError(\"Query parameter validation failed\", {\n errors: error.errors,\n });\n }\n throw error;\n }\n}\n", "/**\n * Input Sanitizers\n * Functions for sanitizing and cleaning untrusted input\n */\n\n/**\n * Sanitize data to prevent XSS and injection attacks\n *\n * @param data - Data to sanitize (can be string, array, object, or primitive)\n * @returns Sanitized data with HTML entities encoded and dangerous keys removed\n *\n * @example\n * ```ts\n * sanitizeData('<script>alert(\"xss\")</script>')\n * // Returns: '<script>alert("xss")</script>'\n *\n * sanitizeData({ __proto__: 'malicious', safe: 'value' })\n * // Returns: { safe: 'value' } (prototype pollution prevented)\n * ```\n */\nexport function sanitizeData(data: unknown): unknown {\n if (typeof data === \"string\") {\n return sanitizeString(data);\n }\n\n if (Array.isArray(data)) {\n return data.map(sanitizeData);\n }\n\n if (data && typeof data === \"object\") {\n return sanitizeObject(data as Record<string, unknown>);\n }\n\n return data;\n}\n\n/**\n * Sanitize a string by encoding HTML entities\n *\n * @param str - String to sanitize\n * @returns String with HTML entities encoded\n */\nfunction sanitizeString(str: string): string {\n return str\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/\"/g, \""\")\n .replace(/'/g, \"'\")\n .replace(/\\//g, \"/\");\n}\n\n/**\n * Sanitize an object by cleaning keys and recursively sanitizing values\n *\n * @param obj - Object to sanitize\n * @returns Sanitized object with dangerous keys removed\n */\nfunction sanitizeObject(obj: Record<string, unknown>): Record<string, unknown> {\n const sanitized: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(obj)) {\n // Sanitize keys too (prevent prototype pollution)\n const safeKey = sanitizeKey(key);\n if (isAllowedKey(safeKey)) {\n sanitized[safeKey] = sanitizeData(value);\n }\n }\n\n return sanitized;\n}\n\n/**\n * Sanitize an object key by removing non-word characters\n *\n * @param key - Object key to sanitize\n * @returns Sanitized key\n */\nfunction sanitizeKey(key: string): string {\n return key.replace(/[^\\w.-]/g, \"\");\n}\n\n/**\n * Check if a key is allowed (not a dangerous prototype property)\n *\n * @param key - Object key to check\n * @returns True if key is safe to use\n */\nfunction isAllowedKey(key: string): boolean {\n return key !== \"__proto__\" && key !== \"constructor\" && key !== \"prototype\";\n}\n", "/**\n * Common Validation Schemas\n * Reusable Zod schemas for common validation patterns\n */\n\nimport { z } from \"zod\";\nimport { MAX_URL_LENGTH_FOR_VALIDATION } from \"@veryfront/core/constants/index.ts\";\n\n/**\n * Collection of commonly used validation schemas\n */\nexport const CommonSchemas = {\n /**\n * Valid email address (RFC-compliant, max 255 chars)\n */\n email: z.string().email().max(255),\n\n /**\n * Valid UUID v4 identifier\n */\n uuid: z.string().uuid(),\n\n /**\n * URL-safe slug (lowercase alphanumeric with hyphens)\n */\n slug: z.string().regex(/^[a-z0-9-]+$/).min(1).max(100),\n\n /**\n * Valid HTTP/HTTPS URL (max 2048 chars)\n */\n url: z.string().url().max(MAX_URL_LENGTH_FOR_VALIDATION),\n\n /**\n * International phone number (E.164 format)\n */\n phoneNumber: z.string().regex(/^\\+?[1-9]\\d{1,14}$/),\n\n /**\n * Pagination parameters with defaults\n */\n pagination: z.object({\n page: z.coerce.number().int().positive().default(1),\n limit: z.coerce.number().int().positive().max(100).default(10),\n sort: z.string().optional(),\n order: z.enum([\"asc\", \"desc\"]).optional(),\n }),\n\n /**\n * Date range with validation\n */\n dateRange: z.object({\n from: z.string().datetime(),\n to: z.string().datetime(),\n }).refine((data) => new Date(data.from) <= new Date(data.to), {\n message: \"From date must be before or equal to To date\",\n }),\n\n /**\n * Strong password requirements\n * - Minimum 8 characters\n * - At least one uppercase letter\n * - At least one lowercase letter\n * - At least one number\n * - At least one special character\n */\n strongPassword: z.string()\n .min(8, \"Password must be at least 8 characters\")\n .regex(/[A-Z]/, \"Password must contain at least one uppercase letter\")\n .regex(/[a-z]/, \"Password must contain at least one lowercase letter\")\n .regex(/[0-9]/, \"Password must contain at least one number\")\n .regex(/[^A-Za-z0-9]/, \"Password must contain at least one special character\"),\n};\n", "/**\n * Validated Handler Factory\n * Higher-order function for creating validated API handlers\n */\n\nimport { z } from \"zod\";\nimport { ValidationError } from \"./errors.ts\";\nimport { parseJsonBody, parseQueryParams } from \"./parsers.ts\";\nimport { type RequestLimits, type ValidatedData } from \"./types.ts\";\n\n/**\n * Configuration for validated handler\n */\nexport interface ValidatedHandlerConfig<TBody = unknown, TQuery = unknown> {\n body?: z.ZodSchema<TBody>;\n query?: z.ZodSchema<TQuery>;\n limits?: RequestLimits;\n}\n\n/**\n * Handler function type that receives validated data\n */\nexport type ValidatedHandlerFunction<TBody = unknown, TQuery = unknown> = (\n request: Request,\n validated: ValidatedData<TBody, TQuery>,\n) => Promise<Response> | Response;\n\n/**\n * Create a validated API handler wrapper\n *\n * This higher-order function wraps an API handler to automatically validate\n * request body and query parameters according to provided Zod schemas.\n * Validation errors are automatically converted to 400 responses.\n *\n * @param config - Configuration specifying validation schemas and limits\n * @param handler - Handler function that receives validated data\n * @returns Wrapped handler that performs automatic validation\n *\n * @example\n * ```ts\n * const createUserHandler = createValidatedHandler(\n * {\n * body: z.object({\n * name: z.string(),\n * email: z.string().email()\n * }),\n * query: z.object({\n * sendEmail: z.coerce.boolean().optional()\n * })\n * },\n * async (request, { body, query }) => {\n * // body and query are fully typed and validated\n * const user = await createUser(body)\n * if (query?.sendEmail) {\n * await sendWelcomeEmail(user.email)\n * }\n * return new Response(JSON.stringify(user), { status: 201 })\n * }\n * )\n * ```\n */\nexport function createValidatedHandler<TBody = unknown, TQuery = unknown>(\n config: ValidatedHandlerConfig<TBody, TQuery>,\n handler: ValidatedHandlerFunction<TBody, TQuery>,\n) {\n return async (request: Request): Promise<Response> => {\n try {\n const validated: ValidatedData<TBody, TQuery> = {};\n\n if (config.body) {\n validated.body = await parseJsonBody(request, config.body, { limits: config.limits });\n }\n\n if (config.query) {\n validated.query = parseQueryParams(request, config.query);\n }\n\n return await handler(request, validated);\n } catch (error) {\n if (error instanceof ValidationError) {\n return new Response(\n JSON.stringify({\n error: error.message,\n details: error.details,\n }),\n {\n status: 400,\n headers: { \"Content-Type\": \"application/json\" },\n },\n );\n }\n throw error;\n }\n };\n}\n", "/**\n * Security Handlers\n * Export all security-related handlers and utilities\n */\n\nexport { AuthHandler } from \"./auth.ts\";\nexport { SecurityConfigLoader } from \"./config.ts\";\n\n// Export security middleware functions\nexport { loadSecurityConfig, setCors } from \"./middleware/index.ts\";\n\n// Export security types\nexport type { CORSConfig, CSPDirectives, SecurityConfig } from \"./middleware/index.ts\";\n", "/**\n * Authentication Handler\n * Handles Basic and Bearer authentication\n */\n\nimport { BaseHandler } from \"./base-handler.ts\";\nimport { createError, toError } from \"../../core/errors/veryfront-error.ts\";\nimport type {\n HandlerContext,\n HandlerMetadata,\n HandlerPriority,\n HandlerResult,\n} from \"@veryfront/types\";\n\nfunction encodeBase64(value: string): string {\n if (typeof globalThis.btoa === \"function\") {\n try {\n return globalThis.btoa(value);\n } catch {\n // Fallback for non-Latin1 strings\n const bytes = new TextEncoder().encode(value);\n let binary = \"\";\n for (const byte of bytes) binary += String.fromCharCode(byte);\n return globalThis.btoa(binary);\n }\n }\n\n const bufferCtor = (globalThis as {\n Buffer?: { from(input: string, encoding: string): { toString(encoding: string): string } };\n }).Buffer;\n if (bufferCtor) {\n return bufferCtor.from(value, \"utf8\").toString(\"base64\");\n }\n\n throw toError(createError({\n type: \"not_supported\",\n message: \"Base64 encoding is not supported in this runtime\",\n feature: \"Base64 encoding\",\n }));\n}\n\nexport class AuthHandler extends BaseHandler {\n metadata: HandlerMetadata = {\n name: \"AuthHandler\",\n priority: 0 as HandlerPriority, // CRITICAL priority - runs first\n patterns: [], // Checks all requests\n };\n\n private basicUser: string | null = null;\n private basicPass: string | null = null;\n private bearerToken: string | null = null;\n\n handle(req: Request, ctx: HandlerContext): Promise<HandlerResult> {\n // Load auth config from environment\n this.loadAuthConfig(ctx);\n\n // Skip auth for OPTIONS requests\n if (req.method.toUpperCase() === \"OPTIONS\") {\n return Promise.resolve(this.continue());\n }\n\n // Check Basic Auth\n if (this.shouldUseBasic()) {\n const result = this.checkBasicAuth(req);\n if (result) return Promise.resolve(result);\n }\n\n // Check Bearer Auth\n if (this.shouldUseBearer()) {\n const result = this.checkBearerAuth(req);\n if (result) return Promise.resolve(result);\n }\n\n return Promise.resolve(this.continue());\n }\n\n private loadAuthConfig(ctx: HandlerContext): void {\n this.basicUser = ctx.adapter.env.get(\"VERYFRONT_BASIC_USER\") || \"\";\n this.basicPass = ctx.adapter.env.get(\"VERYFRONT_BASIC_PASS\") || \"\";\n this.bearerToken = ctx.adapter.env.get(\"VERYFRONT_BEARER_TOKEN\") || \"\";\n }\n\n private shouldUseBasic(): boolean {\n return !!(this.basicUser && this.basicPass);\n }\n\n private shouldUseBearer(): boolean {\n return !!this.bearerToken;\n }\n\n private checkBasicAuth(req: Request): HandlerResult | null {\n const expected = `Basic ${encodeBase64(`${this.basicUser}:${this.basicPass}`)}`;\n const auth = req.headers.get(\"authorization\") || \"\";\n\n if (auth !== expected) {\n const response = new Response(\"Unauthorized\", {\n status: 401,\n headers: { \"WWW-Authenticate\": 'Basic realm=\"Secure Area\"' },\n });\n return this.respond(response);\n }\n\n return null;\n }\n\n private checkBearerAuth(req: Request): HandlerResult | null {\n const auth = req.headers.get(\"authorization\") || \"\";\n\n if (!auth.startsWith(\"Bearer \") || auth.slice(7) !== this.bearerToken) {\n const response = new Response(\"Unauthorized\", { status: 401 });\n return this.respond(response);\n }\n\n return null;\n }\n}\n", "/**\n * Security Configuration Loader\n * Loads and caches security configuration from veryfront.config.ts\n */\n\nimport type { RuntimeAdapter } from \"@veryfront/platform/adapters/index.ts\";\nimport type { SecurityConfig } from \"@veryfront/types\";\nimport type { VeryfrontConfig } from \"@veryfront/config\";\nimport { getConfig } from \"@veryfront/config\";\nimport { serverLogger } from \"@veryfront/utils\";\nimport { buildCSP, generateNonce } from \"./response/security-handler.ts\";\n\nexport class SecurityConfigLoader {\n private securityConfig: SecurityConfig | null = null;\n private cspUserHeader: string | null = null;\n private isLoaded = false;\n private loadPromise: Promise<void> | null = null;\n\n constructor(\n private projectDir: string,\n private adapter: RuntimeAdapter,\n ) {}\n\n /**\n * Ensure security config is loaded (singleton pattern)\n */\n async ensureLoaded(): Promise<void> {\n if (this.isLoaded) {\n return;\n }\n\n // If already loading, wait for it\n if (this.loadPromise) {\n return this.loadPromise;\n }\n\n // Start loading\n this.loadPromise = this.load();\n await this.loadPromise;\n }\n\n /**\n * Load security configuration\n */\n private async load(): Promise<void> {\n try {\n const cfg = await getConfig(this.projectDir, this.adapter) as VeryfrontConfig;\n\n const baseSecurity = cfg?.security\n ? { ...cfg.security } as SecurityConfig\n : {} as SecurityConfig;\n\n if (baseSecurity.headers) {\n baseSecurity.headers = { ...baseSecurity.headers };\n }\n\n if (baseSecurity.cors === undefined) {\n baseSecurity.cors = true;\n }\n\n this.securityConfig = baseSecurity;\n\n // Parse CSP from config\n const cfgCsp = this.securityConfig?.csp;\n if (cfgCsp && typeof cfgCsp === \"object\") {\n const pieces: string[] = [];\n for (const [k, v] of Object.entries(cfgCsp)) {\n if (v === undefined) continue;\n const key = String(k).replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`);\n const val = Array.isArray(v) ? v.join(\" \") : String(v);\n pieces.push(`${key} ${val}`);\n }\n if (pieces.length > 0) {\n this.cspUserHeader = pieces.join(\"; \");\n }\n }\n\n this.isLoaded = true;\n } catch (error) {\n // Config is optional, so we don't throw\n serverLogger.debug(\"[SecurityConfigLoader] Failed to load config:\", error);\n this.isLoaded = true; // Mark as loaded even on error to prevent retry\n }\n }\n\n /**\n * Get security configuration\n */\n getSecurityConfig(): SecurityConfig | null {\n return this.securityConfig;\n }\n\n /**\n * Get CSP header from config\n */\n getCspUserHeader(): string | null {\n return this.cspUserHeader;\n }\n\n /**\n * Get CORS configuration\n */\n getCorsConfig(): SecurityConfig[\"cors\"] {\n return this.securityConfig?.cors;\n }\n\n /**\n * Build complete CSP header\n */\n buildCsp(isDev: boolean, nonce: string = generateNonce()): string {\n return buildCSP(\n isDev,\n nonce,\n this.cspUserHeader,\n this.securityConfig,\n this.adapter,\n );\n }\n\n /**\n * Get security header value\n */\n getSecurityHeader(headerName: string, defaultValue: string): string {\n const configKey = headerName.toLowerCase();\n const configValue = this.securityConfig?.[configKey as keyof SecurityConfig];\n const envValue = this.adapter.env.get(`VERYFRONT_${headerName}`);\n return (typeof configValue === \"string\" ? configValue : undefined) || envValue || defaultValue;\n }\n\n /**\n * Reset the loader (mainly for testing)\n */\n reset(): void {\n this.securityConfig = null;\n this.cspUserHeader = null;\n this.isLoaded = false;\n this.loadPromise = null;\n }\n}\n", "/**\n * Security middleware - barrel exports\n *\n * @module security/middleware\n */\n\n// Types\nexport type { CORSConfig, CSPDirectives, SecurityConfig } from \"./types.ts\";\n\n// Config loader\nexport { isValidSecurityConfig, loadSecurityConfig } from \"./config-loader.ts\";\n\n// CORS handler\nexport { setCors } from \"./cors-handler.ts\";\n\n// ETag utilities\nexport { computeEtag } from \"./etag.ts\";\n\n// Content types\nexport { CONTENT_TYPES } from \"./content-types.ts\";\n", "/**\n * Security configuration loader\n *\n * @module security/middleware/config-loader\n */\n\nimport type { RuntimeAdapter } from \"@veryfront/platform/adapters/index.ts\";\nimport type { SecurityConfig } from \"./types.ts\";\nimport { serverLogger } from \"@veryfront/utils\";\n\n/**\n * Validates security configuration structure\n *\n * @param config - Unknown configuration to validate\n * @returns True if configuration is valid SecurityConfig\n *\n * @example\n * ```ts\n * const valid = isValidSecurityConfig({ csp: {}, cors: true })\n * console.log(valid) // true\n * ```\n */\nexport function isValidSecurityConfig(config: unknown): config is SecurityConfig {\n if (!config || typeof config !== \"object\") return false;\n const cfg = config as Record<string, unknown>;\n\n // Validate CSP if present\n if (cfg.csp !== undefined && typeof cfg.csp !== \"object\") return false;\n\n // Validate CORS if present\n if (cfg.cors !== undefined) {\n if (typeof cfg.cors !== \"boolean\" && typeof cfg.cors !== \"object\") return false;\n }\n\n // Validate string fields\n if (cfg.coop !== undefined && typeof cfg.coop !== \"string\") return false;\n if (cfg.corp !== undefined && typeof cfg.corp !== \"string\") return false;\n if (cfg.coep !== undefined && typeof cfg.coep !== \"string\") return false;\n\n return true;\n}\n\n/**\n * Load security configuration from project config\n *\n * @param projectDir - Project directory path\n * @param adapter - Runtime adapter for environment access\n * @returns Security configuration or null if not found/invalid\n *\n * @example\n * ```ts\n * const config = await loadSecurityConfig('/path/to/project', adapter)\n * if (config) {\n * console.log('CSP:', config.csp)\n * }\n * ```\n */\nexport async function loadSecurityConfig(\n projectDir: string,\n adapter: RuntimeAdapter,\n): Promise<SecurityConfig | null> {\n try {\n const { getConfig } = await import(\"@veryfront/config\");\n const cfg = await getConfig(projectDir, adapter);\n const securityConfig = (cfg as Record<string, unknown>)?.security;\n\n if (!securityConfig) return null;\n if (!isValidSecurityConfig(securityConfig)) {\n serverLogger.warn(\"Invalid security configuration structure, ignoring\");\n return null;\n }\n\n return securityConfig;\n } catch {\n return null;\n }\n}\n", "/**\n * CORS header handler\n *\n * @module security/middleware/cors-handler\n */\n\nimport type { SecurityConfig } from \"./types.ts\";\nimport { validateOriginSync } from \"../cors/validators.ts\";\n\n/**\n * Set CORS headers on response\n *\n * Uses consolidated origin validation to determine allowed origin.\n * Reflects request origin if configured, or uses configured value.\n * Always sets Vary: Origin header for proper caching.\n *\n * @param headers - Response headers object to modify\n * @param req - Incoming request\n * @param securityConfig - Security configuration from project\n *\n * @example\n * ```ts\n * const headers = new Headers()\n * setCors(headers, request, securityConfig)\n * // headers now include Access-Control-Allow-Origin and Vary\n * ```\n */\nexport function setCors(headers: Headers, req: Request, securityConfig: SecurityConfig | null) {\n const conf = securityConfig?.cors;\n\n // Use consolidated validator for origin determination\n const validation = validateOriginSync(req.headers.get(\"origin\"), conf);\n\n // Set the allowed origin if validation succeeded\n if (validation.allowedOrigin) {\n headers.set(\"Access-Control-Allow-Origin\", validation.allowedOrigin);\n }\n\n // Always add Vary header for proper caching when origin is not wildcard\n if (validation.allowedOrigin && validation.allowedOrigin !== \"*\") {\n headers.set(\"Vary\", \"Origin\");\n }\n}\n", "/**\n * ETag computation utilities\n *\n * @module security/middleware/etag\n */\n\nimport { HASH_SEED_DJB2 } from \"@veryfront/utils/constants/hash.ts\";\n\n/**\n * Compute ETag for content using DJB2 hash algorithm\n *\n * Generates a weak ETag (W/\"...\") using a fast DJB2 hash.\n * This is suitable for caching validation but not cryptographic purposes.\n *\n * @param text - Content to hash\n * @returns Weak ETag header value\n *\n * @example\n * ```ts\n * const etag = computeEtag('<html>...</html>')\n * headers.set('ETag', etag)\n * // ETag: W/\"a3f2d1c4\"\n * ```\n */\nexport function computeEtag(text: string): string {\n let h = HASH_SEED_DJB2;\n for (let i = 0; i < text.length; i++) {\n h = ((h << 5) + h) ^ text.charCodeAt(i);\n }\n return `W/\"${(h >>> 0).toString(16)}\"`;\n}\n", "/**\n * Content type mappings\n *\n * @module security/middleware/content-types\n */\n\nimport {\n HTTP_CONTENT_TYPE_IMAGE_GIF,\n HTTP_CONTENT_TYPE_IMAGE_ICO,\n HTTP_CONTENT_TYPE_IMAGE_JPEG,\n HTTP_CONTENT_TYPE_IMAGE_PNG,\n HTTP_CONTENT_TYPE_IMAGE_SVG,\n HTTP_CONTENT_TYPE_IMAGE_WEBP,\n} from \"@veryfront/utils/constants/http.ts\";\n\n/**\n * MIME type mappings for common file extensions\n *\n * Maps file extensions (with leading dot) to their MIME types.\n * Includes charset for text-based formats.\n *\n * @example\n * ```ts\n * const contentType = CONTENT_TYPES['.html']\n * console.log(contentType) // 'text/html; charset=utf-8'\n * ```\n */\nexport const CONTENT_TYPES: Record<string, string> = {\n // Text formats\n \".html\": \"text/html; charset=utf-8\",\n \".css\": \"text/css; charset=utf-8\",\n \".txt\": \"text/plain; charset=utf-8\",\n\n // JavaScript\n \".js\": \"application/javascript; charset=utf-8\",\n \".mjs\": \"application/javascript; charset=utf-8\",\n\n // Data formats\n \".json\": \"application/json; charset=utf-8\",\n\n // Images\n \".png\": HTTP_CONTENT_TYPE_IMAGE_PNG,\n \".jpg\": HTTP_CONTENT_TYPE_IMAGE_JPEG,\n \".jpeg\": HTTP_CONTENT_TYPE_IMAGE_JPEG,\n \".gif\": HTTP_CONTENT_TYPE_IMAGE_GIF,\n \".svg\": HTTP_CONTENT_TYPE_IMAGE_SVG,\n \".ico\": HTTP_CONTENT_TYPE_IMAGE_ICO,\n \".webp\": HTTP_CONTENT_TYPE_IMAGE_WEBP,\n\n // Fonts\n \".woff\": \"font/woff\",\n \".woff2\": \"font/woff2\",\n \".ttf\": \"font/ttf\",\n \".otf\": \"font/otf\",\n};\n", "/**\n * Path Traversal Protection\n *\n * Centralized path validation to prevent directory traversal attacks.\n * Implements OWASP security guidelines and defense-in-depth principles.\n *\n * Features:\n * - Canonical path resolution (resolves .., symlinks)\n * - Whitelist-based validation\n * - Null byte and special character detection\n * - Cross-platform support (Windows, Unix)\n * - Multiple security levels\n *\n * @module security/path-validation\n */\n\nimport {\n FORBIDDEN_PATH_PATTERNS,\n MAX_PATH_LENGTH,\n MAX_PATH_TRAVERSAL_DEPTH,\n} from \"@veryfront/utils\";\nimport type { RuntimeAdapter } from \"@veryfront/platform/adapters/base.ts\";\n\n/**\n * Security validation level\n *\n * - strict: Maximum security, strict whitelist enforcement\n * - normal: Standard security for most operations\n * - permissive: More lenient, for build-time operations\n */\nexport type ValidationLevel = \"strict\" | \"normal\" | \"permissive\";\n\n/**\n * Path validation result\n */\nexport interface ValidationResult {\n valid: boolean;\n canonicalPath?: string;\n error?: string;\n code?: string;\n}\n\n/**\n * Path validation options\n */\nexport interface ValidationOptions {\n /** Security level */\n level?: ValidationLevel;\n\n /** Base directory to restrict access to */\n baseDir: string;\n\n /** Additional allowed directories (relative to baseDir) */\n allowedDirs?: string[];\n\n /** Whether to follow symlinks */\n followSymlinks?: boolean;\n\n /** Whether to check file existence */\n checkExists?: boolean;\n\n /** Runtime adapter for filesystem operations */\n adapter?: RuntimeAdapter;\n\n /** Whether to allow absolute paths outside baseDir */\n allowAbsolute?: boolean;\n}\n\n/**\n * Path validation error codes\n */\nexport const PathValidationError = {\n NULL_BYTE: \"NULL_BYTE\",\n PATH_TOO_LONG: \"PATH_TOO_LONG\",\n EXCESSIVE_TRAVERSAL: \"EXCESSIVE_TRAVERSAL\",\n FORBIDDEN_PATTERN: \"FORBIDDEN_PATTERN\",\n OUTSIDE_BASE: \"OUTSIDE_BASE\",\n NOT_IN_ALLOWLIST: \"NOT_IN_ALLOWLIST\",\n FILE_NOT_FOUND: \"FILE_NOT_FOUND\",\n SYMLINK_DETECTED: \"SYMLINK_DETECTED\",\n INVALID_PATH: \"INVALID_PATH\",\n ABSOLUTE_PATH_DENIED: \"ABSOLUTE_PATH_DENIED\",\n} as const;\n\n/**\n * Normalize path separators to forward slashes\n * Handles Windows backslashes and mixed separators\n */\nfunction normalizeSeparators(path: string): string {\n return path.replace(/\\\\+/g, \"/\");\n}\n\n/**\n * Check if path is absolute\n * Supports Unix (/path) and Windows (C:\\path, \\\\UNC\\path)\n */\nfunction isAbsolutePath(path: string): boolean {\n // Unix absolute path\n if (path.startsWith(\"/\")) return true;\n\n // Windows drive letter (C:\\ or C:/)\n if (/^[A-Za-z]:[\\/\\\\]/.test(path)) return true;\n\n // Windows UNC path (\\\\server\\share)\n if (/^\\\\\\\\[^\\\\]+\\\\[^\\\\]+/.test(path)) return true;\n\n return false;\n}\n\n/**\n * Resolve .. and . in path without filesystem access\n * This is a pure string operation for initial validation\n */\nfunction resolvePathSegments(path: string): string {\n const normalized = normalizeSeparators(path);\n const parts = normalized.split(\"/\").filter((p) => p.length > 0);\n const resolved: string[] = [];\n\n for (const part of parts) {\n if (part === \".\") {\n continue;\n } else if (part === \"..\") {\n if (resolved.length > 0) {\n resolved.pop();\n }\n } else {\n resolved.push(part);\n }\n }\n\n // Preserve leading slash for absolute paths\n const isAbs = normalized.startsWith(\"/\");\n return isAbs ? `/${resolved.join(\"/\")}` : resolved.join(\"/\");\n}\n\n/**\n * Join two paths safely\n */\nfunction joinPaths(base: string, relative: string): string {\n const normalizedBase = normalizeSeparators(base).replace(/\\/$/, \"\");\n const normalizedRelative = normalizeSeparators(relative).replace(/^\\//, \"\");\n return `${normalizedBase}/${normalizedRelative}`;\n}\n\n/**\n * Check if target path is within base directory\n * Compares normalized paths (string comparison)\n */\nfunction isWithinDirectory(baseDir: string, targetPath: string): boolean {\n const normalizedBase = normalizeSeparators(baseDir).replace(/\\/$/, \"\");\n const normalizedTarget = normalizeSeparators(targetPath).replace(/\\/$/, \"\");\n\n return normalizedTarget === normalizedBase ||\n normalizedTarget.startsWith(`${normalizedBase}/`);\n}\n\n/**\n * Validate path for security issues (basic checks)\n */\nfunction validatePathBasics(path: string): ValidationResult {\n // Check for null bytes\n // deno-lint-ignore no-control-regex\n if (path.includes(\"\\0\") || /\\x00/.test(path)) {\n return {\n valid: false,\n error: \"Path contains null bytes\",\n code: PathValidationError.NULL_BYTE,\n };\n }\n\n // Check path length\n if (path.length > MAX_PATH_LENGTH) {\n return {\n valid: false,\n error: `Path exceeds maximum length of ${MAX_PATH_LENGTH}`,\n code: PathValidationError.PATH_TOO_LONG,\n };\n }\n\n // Check forbidden patterns\n for (const pattern of FORBIDDEN_PATH_PATTERNS) {\n if (pattern.test(path)) {\n return {\n valid: false,\n error: `Path contains forbidden pattern: ${pattern}`,\n code: PathValidationError.FORBIDDEN_PATTERN,\n };\n }\n }\n\n // Check for excessive directory traversal\n const parts = normalizeSeparators(path).split(\"/\");\n let depth = 0;\n let maxDepth = 0;\n\n for (const part of parts) {\n if (part === \"..\") {\n depth++;\n maxDepth = Math.max(maxDepth, depth);\n } else if (part !== \".\" && part !== \"\") {\n depth = 0;\n }\n }\n\n if (maxDepth > MAX_PATH_TRAVERSAL_DEPTH) {\n return {\n valid: false,\n error: `Path has excessive traversal depth (${maxDepth} > ${MAX_PATH_TRAVERSAL_DEPTH})`,\n code: PathValidationError.EXCESSIVE_TRAVERSAL,\n };\n }\n\n return { valid: true };\n}\n\n/**\n * Get canonical path by resolving symlinks\n * Falls back to path resolution if adapter not available\n */\nasync function getCanonicalPath(\n path: string,\n adapter?: RuntimeAdapter,\n followSymlinks = false,\n): Promise<{ path: string; isSymlink: boolean }> {\n // If no adapter or not following symlinks, just resolve path segments\n if (!adapter || !followSymlinks) {\n return {\n path: resolvePathSegments(path),\n isSymlink: false,\n };\n }\n\n try {\n const stat = await adapter.fs.stat(path);\n\n if (stat.isSymlink) {\n return {\n path: resolvePathSegments(path),\n isSymlink: true,\n };\n }\n\n return {\n path: resolvePathSegments(path),\n isSymlink: false,\n };\n } catch {\n return {\n path: resolvePathSegments(path),\n isSymlink: false,\n };\n }\n}\n\n/**\n * Validate path against allowed directories\n */\nfunction validateAllowedDirs(\n canonicalPath: string,\n baseDir: string,\n allowedDirs: string[],\n): ValidationResult {\n const normalizedBase = normalizeSeparators(baseDir).replace(/\\/$/, \"\");\n const normalizedPath = normalizeSeparators(canonicalPath).replace(/\\/$/, \"\");\n\n // Path must be within base directory\n if (!isWithinDirectory(normalizedBase, normalizedPath)) {\n return {\n valid: false,\n error: `Path is outside base directory: ${baseDir}`,\n code: PathValidationError.OUTSIDE_BASE,\n };\n }\n\n // If no allowed dirs specified, any path in base is OK\n if (!allowedDirs || allowedDirs.length === 0) {\n return { valid: true, canonicalPath };\n }\n\n // Check if path is in one of the allowed directories\n const relativePath = normalizedPath === normalizedBase\n ? \"\"\n : normalizedPath.slice(normalizedBase.length + 1);\n\n if (!relativePath) {\n // Base directory itself is always allowed\n return { valid: true, canonicalPath };\n }\n\n const topLevelDir = relativePath.split(\"/\")[0] ?? \"\";\n\n if (!topLevelDir || !allowedDirs.includes(topLevelDir)) {\n return {\n valid: false,\n error: `Access to directory '${topLevelDir}' not allowed. Allowed: ${allowedDirs.join(\", \")}`,\n code: PathValidationError.NOT_IN_ALLOWLIST,\n };\n }\n\n return { valid: true, canonicalPath };\n}\n\n/**\n * Validate a file path for security\n *\n * This is the main validation function that should be used for all file operations.\n * It implements defense-in-depth with multiple layers of validation.\n *\n * @param path - Path to validate (can be relative or absolute)\n * @param options - Validation options\n * @returns Validation result with canonical path if valid\n *\n * @example\n * ```typescript\n * const result = await validatePath(\"../../../etc/passwd\", {\n * baseDir: \"/project\",\n * allowedDirs: [\"app\", \"pages\", \"public\"],\n * });\n *\n * if (!result.valid) {\n * console.error(`Invalid path: ${result.error}`);\n * }\n * ```\n */\nexport async function validatePath(\n path: string,\n options: ValidationOptions,\n): Promise<ValidationResult> {\n const {\n level = \"normal\",\n baseDir,\n allowedDirs = [],\n followSymlinks = false,\n checkExists = false,\n adapter,\n allowAbsolute = false,\n } = options;\n\n // Basic validation\n const basicResult = validatePathBasics(path);\n if (!basicResult.valid) {\n return basicResult;\n }\n\n // Normalize path\n const normalized = normalizeSeparators(path);\n\n // Handle absolute paths\n let targetPath: string;\n if (isAbsolutePath(normalized)) {\n if (!allowAbsolute && level === \"strict\") {\n return {\n valid: false,\n error: \"Absolute paths not allowed in strict mode\",\n code: PathValidationError.ABSOLUTE_PATH_DENIED,\n };\n }\n targetPath = normalized;\n } else {\n // Relative path - join with base directory\n targetPath = joinPaths(baseDir, normalized);\n }\n\n // Get canonical path (resolve .., symlinks if enabled)\n const { path: canonicalPath, isSymlink } = await getCanonicalPath(\n targetPath,\n adapter,\n followSymlinks,\n );\n\n // In strict mode, reject symlinks\n if (isSymlink && level === \"strict\") {\n return {\n valid: false,\n error: \"Symlinks not allowed in strict mode\",\n code: PathValidationError.SYMLINK_DETECTED,\n };\n }\n\n // Validate against allowed directories\n const allowResult = validateAllowedDirs(canonicalPath, baseDir, allowedDirs);\n if (!allowResult.valid) {\n return allowResult;\n }\n\n // Check file existence if requested\n if (checkExists && adapter) {\n try {\n await adapter.fs.stat(canonicalPath);\n } catch {\n return {\n valid: false,\n error: `File not found: ${canonicalPath}`,\n code: PathValidationError.FILE_NOT_FOUND,\n };\n }\n }\n\n return {\n valid: true,\n canonicalPath,\n };\n}\n\n/**\n * Validate a path synchronously (without filesystem access)\n *\n * This is faster but less secure than validatePath() as it cannot\n * resolve symlinks or check file existence. Use for pre-validation\n * before filesystem operations.\n *\n * @param path - Path to validate\n * @param options - Validation options (adapter is ignored)\n * @returns Validation result\n */\nexport function validatePathSync(\n path: string,\n options: ValidationOptions,\n): ValidationResult {\n const {\n level = \"normal\",\n baseDir,\n allowedDirs = [],\n allowAbsolute = false,\n } = options;\n\n // Basic validation\n const basicResult = validatePathBasics(path);\n if (!basicResult.valid) {\n return basicResult;\n }\n\n // Normalize and resolve path\n const normalized = normalizeSeparators(path);\n\n let targetPath: string;\n if (isAbsolutePath(normalized)) {\n if (!allowAbsolute && level === \"strict\") {\n return {\n valid: false,\n error: \"Absolute paths not allowed in strict mode\",\n code: PathValidationError.ABSOLUTE_PATH_DENIED,\n };\n }\n targetPath = normalized;\n } else {\n targetPath = joinPaths(baseDir, normalized);\n }\n\n const canonicalPath = resolvePathSegments(targetPath);\n\n // Validate against allowed directories\n return validateAllowedDirs(canonicalPath, baseDir, allowedDirs);\n}\n\n/**\n * Create a validation function with preset options\n *\n * Useful for creating validators for specific contexts.\n *\n * @param defaultOptions - Default validation options\n * @returns Validation function\n *\n * @example\n * ```typescript\n * const validateAppPath = createValidator({\n * baseDir: \"/project\",\n * allowedDirs: [\"app\", \"components\", \"lib\"],\n * level: \"strict\",\n * });\n *\n * const result = await validateAppPath(\"app/page.tsx\");\n * ```\n */\nexport function createValidator(defaultOptions: ValidationOptions) {\n return (path: string, overrides?: Partial<ValidationOptions>): Promise<ValidationResult> => {\n return validatePath(path, { ...defaultOptions, ...overrides });\n };\n}\n\n/**\n * Common validation presets for different contexts\n */\nexport const ValidationPresets = {\n /**\n * Strict validation for user-provided paths\n */\n userInput: (baseDir: string): ValidationOptions => ({\n baseDir,\n level: \"strict\",\n allowedDirs: [\"app\", \"pages\", \"public\", \"components\", \"lib\"],\n followSymlinks: false,\n checkExists: true,\n allowAbsolute: false,\n }),\n\n /**\n * Normal validation for internal operations\n */\n internal: (baseDir: string): ValidationOptions => ({\n baseDir,\n level: \"normal\",\n followSymlinks: false,\n checkExists: false,\n allowAbsolute: false,\n }),\n\n /**\n * Permissive validation for build operations\n */\n build: (baseDir: string): ValidationOptions => ({\n baseDir,\n level: \"permissive\",\n followSymlinks: true,\n checkExists: false,\n allowAbsolute: true,\n }),\n\n /**\n * Static file serving validation\n */\n static: (baseDir: string): ValidationOptions => ({\n baseDir,\n level: \"normal\",\n allowedDirs: [\"dist\", \"public\"],\n followSymlinks: false,\n checkExists: true,\n allowAbsolute: false,\n }),\n};\n\n/**\n * Sanitize a path for safe use in error messages\n * Removes potentially sensitive information\n */\nexport function sanitizePathForDisplay(path: string, baseDir: string): string {\n const normalized = normalizeSeparators(path);\n const normalizedBase = normalizeSeparators(baseDir);\n\n if (normalized.startsWith(normalizedBase)) {\n return normalized.slice(normalizedBase.length).replace(/^\\//, \"\");\n }\n\n // For paths outside base, show only filename\n const parts = normalized.split(\"/\");\n return parts[parts.length - 1] || normalized;\n}\n", "/**\n * Secure Filesystem Wrapper\n *\n * Provides automatic path validation for all filesystem operations.\n * Wraps RuntimeAdapter filesystem methods with security checks.\n *\n * Features:\n * - Automatic path validation before all operations\n * - Configurable validation levels per context\n * - Protection against path traversal attacks\n * - Audit logging for security events\n * - Drop-in replacement for adapter.fs\n *\n * @module security/secure-fs\n */\n\nimport type {\n DirEntry,\n FileInfo,\n FileWatcher,\n RuntimeAdapter,\n} from \"@veryfront/platform/adapters/base.ts\";\nimport { logger } from \"@veryfront/utils\";\nimport {\n sanitizePathForDisplay,\n validatePath,\n validatePathSync,\n type ValidationOptions,\n ValidationPresets,\n type ValidationResult,\n} from \"./path-validation.ts\";\n\n/**\n * Security context for filesystem operations\n */\nexport type SecurityContext =\n | \"user-input\" // User-provided paths (strict)\n | \"static-serving\" // Static file serving\n | \"build\" // Build-time operations (permissive)\n | \"internal\" // Internal framework operations\n | \"route-discovery\" // Route discovery operations\n | \"module-loading\"; // Module loading operations\n\n/**\n * Secure filesystem wrapper configuration\n */\nexport interface SecureFsConfig {\n /** Base directory to restrict operations to */\n baseDir: string;\n\n /** Runtime adapter to wrap */\n adapter: RuntimeAdapter;\n\n /** Security context (determines validation strictness) */\n context?: SecurityContext;\n\n /** Custom validation options (overrides context preset) */\n validationOptions?: Partial<ValidationOptions>;\n\n /** Whether to throw on validation errors (default: true) */\n throwOnError?: boolean;\n\n /** Callback for security events */\n onSecurityEvent?: (event: SecurityEvent) => void;\n}\n\n/**\n * Security event for auditing\n */\nexport interface SecurityEvent {\n type: \"validation-failed\" | \"validation-passed\" | \"operation-blocked\";\n operation: string;\n path: string;\n error?: string;\n code?: string;\n timestamp: Date;\n}\n\n/**\n * Get validation options for a security context\n */\nfunction getContextValidationOptions(\n context: SecurityContext,\n baseDir: string,\n): ValidationOptions {\n switch (context) {\n case \"user-input\":\n return ValidationPresets.userInput(baseDir);\n case \"static-serving\":\n return ValidationPresets.static(baseDir);\n case \"build\":\n return ValidationPresets.build(baseDir);\n case \"route-discovery\":\n return {\n baseDir,\n level: \"normal\",\n allowedDirs: [\"app\", \"pages\", \"routes\", \"api\"],\n followSymlinks: false,\n allowAbsolute: false,\n };\n case \"module-loading\":\n return {\n baseDir,\n level: \"normal\",\n allowedDirs: [\n \"app\",\n \"pages\",\n \"components\",\n \"lib\",\n \"modules\",\n \"server\",\n \"client\",\n \"shared\",\n \"islands\",\n ],\n followSymlinks: false,\n allowAbsolute: true, // Allow node_modules, etc.\n };\n case \"internal\":\n default:\n return ValidationPresets.internal(baseDir);\n }\n}\n\n/**\n * Secure filesystem wrapper\n *\n * Drop-in replacement for adapter.fs with automatic path validation.\n */\nexport class SecureFs {\n private config: Required<SecureFsConfig>;\n private validationOptions: ValidationOptions;\n\n constructor(config: SecureFsConfig) {\n this.config = {\n context: \"internal\",\n throwOnError: true,\n onSecurityEvent: () => {},\n validationOptions: {},\n ...config,\n };\n\n const contextOptions = getContextValidationOptions(\n this.config.context,\n this.config.baseDir,\n );\n\n this.validationOptions = {\n ...contextOptions,\n ...this.config.validationOptions,\n baseDir: this.config.baseDir,\n adapter: this.config.adapter,\n };\n }\n\n /**\n * Validate a path before operation\n */\n private async validatePathForOperation(\n path: string,\n operation: string,\n ): Promise<ValidationResult> {\n const result = await validatePath(path, this.validationOptions);\n\n // Emit security event\n this.config.onSecurityEvent({\n type: result.valid ? \"validation-passed\" : \"validation-failed\",\n operation,\n path: sanitizePathForDisplay(path, this.config.baseDir),\n error: result.error,\n code: result.code,\n timestamp: new Date(),\n });\n\n // Throw if validation failed and throwOnError is true\n if (!result.valid && this.config.throwOnError) {\n throw new SecurityError(\n `Path validation failed for ${operation}: ${result.error}`,\n result.code,\n path,\n );\n }\n\n return result;\n }\n\n /**\n * Validate a path synchronously\n */\n private validatePathSync(path: string, operation: string): ValidationResult {\n const result = validatePathSync(path, this.validationOptions);\n\n // Emit security event\n this.config.onSecurityEvent({\n type: result.valid ? \"validation-passed\" : \"validation-failed\",\n operation,\n path: sanitizePathForDisplay(path, this.config.baseDir),\n error: result.error,\n code: result.code,\n timestamp: new Date(),\n });\n\n // Throw if validation failed and throwOnError is true\n if (!result.valid && this.config.throwOnError) {\n throw new SecurityError(\n `Path validation failed for ${operation}: ${result.error}`,\n result.code,\n path,\n );\n }\n\n return result;\n }\n\n async readFile(path: string): Promise<string> {\n const validation = await this.validatePathForOperation(path, \"readFile\");\n if (!validation.valid || !validation.canonicalPath) {\n throw new SecurityError(\"Invalid path\", validation.code, path);\n }\n return await this.config.adapter.fs.readFile(validation.canonicalPath);\n }\n\n async readFileBytes(path: string): Promise<Uint8Array> {\n const validation = await this.validatePathForOperation(path, \"readFileBytes\");\n if (!validation.valid || !validation.canonicalPath) {\n throw new SecurityError(\"Invalid path\", validation.code, path);\n }\n\n const reader = this.config.adapter.fs.readFileBytes;\n if (reader) {\n return await reader.call(this.config.adapter.fs, validation.canonicalPath);\n }\n\n const content = await this.config.adapter.fs.readFile(validation.canonicalPath);\n return new TextEncoder().encode(content);\n }\n\n async writeFile(path: string, content: string): Promise<void> {\n const validation = await this.validatePathForOperation(path, \"writeFile\");\n if (!validation.valid || !validation.canonicalPath) {\n throw new SecurityError(\"Invalid path\", validation.code, path);\n }\n await this.config.adapter.fs.writeFile(validation.canonicalPath, content);\n }\n\n async stat(path: string): Promise<FileInfo> {\n const validation = await this.validatePathForOperation(path, \"stat\");\n if (!validation.valid || !validation.canonicalPath) {\n throw new SecurityError(\"Invalid path\", validation.code, path);\n }\n return await this.config.adapter.fs.stat(validation.canonicalPath);\n }\n\n async mkdir(path: string, options?: { recursive?: boolean }): Promise<void> {\n const validation = await this.validatePathForOperation(path, \"mkdir\");\n if (!validation.valid || !validation.canonicalPath) {\n throw new SecurityError(\"Invalid path\", validation.code, path);\n }\n await this.config.adapter.fs.mkdir(validation.canonicalPath, options);\n }\n\n async remove(path: string, options?: { recursive?: boolean }): Promise<void> {\n const validation = await this.validatePathForOperation(path, \"remove\");\n if (!validation.valid || !validation.canonicalPath) {\n throw new SecurityError(\"Invalid path\", validation.code, path);\n }\n await this.config.adapter.fs.remove(validation.canonicalPath, options);\n }\n\n async exists(path: string): Promise<boolean> {\n const validation = await this.validatePathForOperation(path, \"exists\");\n if (!validation.valid || !validation.canonicalPath) {\n return false;\n }\n return await this.config.adapter.fs.exists(validation.canonicalPath);\n }\n\n readDir(path: string): AsyncIterable<DirEntry> {\n const validation = this.validatePathSync(path, \"readDir\");\n if (!validation.valid || !validation.canonicalPath) {\n throw new SecurityError(\"Invalid path\", validation.code, path);\n }\n return this.config.adapter.fs.readDir(validation.canonicalPath);\n }\n\n async makeTempDir(prefix: string): Promise<string> {\n return await this.config.adapter.fs.makeTempDir(prefix);\n }\n\n watch(\n paths: string | string[],\n options?: { recursive?: boolean; signal?: AbortSignal },\n ): FileWatcher {\n const pathArray = Array.isArray(paths) ? paths : [paths];\n const validatedPaths: string[] = [];\n\n for (const path of pathArray) {\n const validation = this.validatePathSync(path, \"watch\");\n if (validation.valid && validation.canonicalPath) {\n validatedPaths.push(validation.canonicalPath);\n } else if (this.config.throwOnError) {\n throw new SecurityError(\"Invalid path\", validation.code, path);\n }\n }\n\n if (validatedPaths.length === 0) {\n throw new SecurityError(\n \"No valid paths to watch\",\n \"NO_VALID_PATHS\",\n paths.toString(),\n );\n }\n\n return this.config.adapter.fs.watch(\n validatedPaths.length === 1 ? validatedPaths[0]! : validatedPaths,\n options,\n );\n }\n\n /**\n * Get underlying adapter (use with caution)\n * This bypasses security checks\n */\n getUnsafeAdapter(): RuntimeAdapter {\n logger.warn(\n \"[SecureFs] Using unsafe adapter - security checks bypassed!\",\n );\n return this.config.adapter;\n }\n\n /**\n * Update validation options at runtime\n */\n updateValidationOptions(options: Partial<ValidationOptions>): void {\n this.validationOptions = {\n ...this.validationOptions,\n ...options,\n };\n }\n\n /**\n * Change security context\n */\n setContext(context: SecurityContext): void {\n const contextOptions = getContextValidationOptions(\n context,\n this.config.baseDir,\n );\n this.validationOptions = {\n ...contextOptions,\n ...this.config.validationOptions,\n adapter: this.config.adapter,\n };\n this.config.context = context;\n }\n}\n\n/**\n * Security error thrown by SecureFs\n */\nexport class SecurityError extends Error {\n constructor(\n message: string,\n public code?: string,\n public path?: string,\n ) {\n super(message);\n this.name = \"SecurityError\";\n }\n}\n\n/**\n * Create a secure filesystem wrapper\n *\n * @example\n * ```typescript\n * const secureFs = createSecureFs({\n * baseDir: ctx.projectDir,\n * adapter: ctx.adapter,\n * context: \"user-input\",\n * onSecurityEvent: (event) => {\n * if (event.type === \"validation-failed\") {\n * console.error(`Security: Blocked ${event.operation} on ${event.path}`);\n * }\n * }\n * });\n *\n * // Use like adapter.fs but with automatic validation\n * const content = await secureFs.readFile(\"app/page.tsx\");\n * ```\n */\nexport function createSecureFs(config: SecureFsConfig): SecureFs {\n return new SecureFs(config);\n}\n\n/**\n * Wrap an existing adapter with security\n *\n * @example\n * ```typescript\n * const originalAdapter = ctx.adapter;\n * const secureAdapter = wrapAdapterWithSecurity(originalAdapter, {\n * baseDir: ctx.projectDir,\n * context: \"build\",\n * });\n *\n * // secureAdapter.fs is now a SecureFs instance\n * ```\n */\nexport function wrapAdapterWithSecurity(\n adapter: RuntimeAdapter,\n options: Omit<SecureFsConfig, \"adapter\">,\n): RuntimeAdapter & { secureFs: SecureFs } {\n const secureFs = createSecureFs({\n ...options,\n adapter,\n });\n\n // Create a new adapter with secure fs\n return {\n ...adapter,\n fs: secureFs,\n secureFs, // Keep reference to SecureFs for advanced usage\n };\n}\n", "import type { Route, RouteMatch } from \"@veryfront/routing/matchers/types.ts\";\nimport { getEnv } from \"../../platform/compat/process.ts\";\nimport { LRUCache } from \"@veryfront/utils/lru-wrapper.ts\";\n\nexport type { Route, RouteMatch };\n\nexport class DynamicRouter {\n private routes: Map<\n string,\n {\n regex: RegExp;\n route: Route;\n paramNames: string[];\n isOptionalCatchAll: boolean;\n isCatchAll: boolean;\n }\n > = new Map();\n private routeCache: LRUCache<string, RouteMatch | null>;\n\n constructor() {\n const disableIntervals = shouldDisableLruInterval();\n this.routeCache = new LRUCache<string, RouteMatch | null>({\n maxEntries: 500,\n ttlMs: disableIntervals ? undefined : 5 * 60 * 1000,\n });\n }\n\n addRoute(pattern: string, page: string): void {\n const originalPattern = pattern;\n let regex = pattern;\n let isOptionalCatchAll = false;\n let isCatchAll = false;\n\n const orderedParamNames: string[] = [];\n for (\n const match of originalPattern.matchAll(/\\[\\[\\.\\.\\.(\\w+)\\]\\]|\\[\\.\\.\\.(\\w+)\\]|\\[(\\w+)\\]/g)\n ) {\n if (match[1]) {\n const name = match[1];\n orderedParamNames.push(name);\n isOptionalCatchAll = true;\n isCatchAll = true;\n } else if (match[2]) {\n const name = match[2];\n orderedParamNames.push(name);\n isCatchAll = true;\n } else if (match[3]) {\n orderedParamNames.push(match[3]);\n }\n }\n const paramNames = orderedParamNames;\n\n regex = regex.replace(/\\/?\\[\\[\\.\\.\\.([^\\]]+)\\]\\]/g, () => {\n return \"(?:/(.+))?\";\n });\n\n regex = regex.replace(/\\[\\.\\.\\.([^\\]]+)\\]/g, () => {\n return \"(.+)\";\n });\n\n regex = regex.replace(/\\[([^\\]]+)\\]/g, () => {\n return \"([^/]+)\";\n });\n\n if (pattern !== \"/\" && pattern.endsWith(\"/\")) {\n pattern = pattern.slice(0, -1);\n if (regex.endsWith(\"/\")) {\n regex = regex.slice(0, -1);\n }\n }\n\n const route: Route = { pattern, page };\n this.routes.set(pattern, {\n regex: new RegExp(`^${regex}$`),\n route,\n paramNames,\n isOptionalCatchAll,\n isCatchAll,\n });\n }\n\n private normalizePathname(path: string): string {\n return path !== \"/\" && path.endsWith(\"/\") ? path.slice(0, -1) : path;\n }\n\n private sortRoutesByPriority(): Array<\n [\n string,\n {\n regex: RegExp;\n route: Route;\n paramNames: string[];\n isOptionalCatchAll: boolean;\n isCatchAll: boolean;\n },\n ]\n > {\n return Array.from(this.routes.entries()).sort(([patternA], [patternB]) => {\n const hasParamsA = patternA.includes(\"[\");\n const hasParamsB = patternB.includes(\"[\");\n const isCatchAllA = patternA.includes(\"[...\");\n const isCatchAllB = patternB.includes(\"[...\");\n\n if (!hasParamsA && hasParamsB) return -1;\n if (hasParamsA && !hasParamsB) return 1;\n if (!isCatchAllA && isCatchAllB) return -1;\n if (isCatchAllA && !isCatchAllB) return 1;\n\n return patternB.split(\"/\").length - patternA.split(\"/\").length;\n });\n }\n\n match(path: string): RouteMatch | null {\n const normalizedPath = this.normalizePathname(path);\n\n const cached = this.routeCache.get(normalizedPath);\n if (cached !== undefined) {\n return cached;\n }\n\n const sortedRoutes = this.sortRoutesByPriority();\n\n for (const [, routeData] of sortedRoutes) {\n const match = normalizedPath.match(routeData.regex);\n if (match) {\n const params = this.extractParams(\n match,\n routeData.paramNames,\n routeData.route,\n );\n const result = { params, route: routeData.route };\n this.routeCache.set(normalizedPath, result);\n return result;\n }\n }\n\n this.routeCache.set(normalizedPath, null);\n return null;\n }\n\n private extractParams(\n match: RegExpMatchArray,\n paramNames: string[],\n route: Route,\n ): Record<string, string | string[]> {\n const params: Record<string, string | string[]> = {};\n\n const catchAllParamNames = new Set<string>();\n route.pattern.replace(/\\[\\[\\.\\.\\.(\\w+)\\]\\]/g, (_, paramName: string) => {\n catchAllParamNames.add(paramName);\n return \"\";\n });\n route.pattern.replace(/\\[\\.\\.\\.(\\w+)\\]/g, (_, paramName: string) => {\n catchAllParamNames.add(paramName);\n return \"\";\n });\n\n for (let i = 0; i < paramNames.length; i++) {\n const paramName = paramNames[i] as string;\n const value = match[i + 1];\n\n if (catchAllParamNames.has(paramName)) {\n const segments = value ? value.split(\"/\").filter((segment) => segment.length > 0) : [];\n params[paramName] = segments.map((segment) => decodeURIComponent(segment));\n } else {\n params[paramName] = decodeURIComponent(value ?? \"\");\n }\n }\n\n return params;\n }\n\n listRoutes(): Route[] {\n return Array.from(this.routes.values()).map(({ route }) => route);\n }\n\n clear(): void {\n this.routes.clear();\n this.routeCache.destroy();\n }\n\n clearCache(): void {\n this.routeCache.clear();\n }\n\n destroy(): void {\n this.clear();\n }\n}\n\nfunction shouldDisableLruInterval(): boolean {\n if ((globalThis as Record<string, unknown>).__vfDisableLruInterval === true) {\n return true;\n }\n try {\n return getEnv(\"VF_DISABLE_LRU_INTERVAL\") === \"1\";\n } catch (_error) {\n return false;\n }\n}\n", "import { serverLogger as logger } from \"@veryfront/utils\";\nimport type { BuildResult, Plugin } from \"esbuild\";\nimport type { RuntimeAdapter } from \"@veryfront/platform/adapters/index.ts\";\nimport type { VeryfrontConfig } from \"@veryfront/config\";\nimport { createHTTPPlugin } from \"./esbuild-plugin.ts\";\nimport { validateHTTPImports } from \"./http-validator.ts\";\nimport { loadSecurityConfig } from \"./security-config.ts\";\nimport type { APIRoute, LoadModuleOptions } from \"./types.ts\";\nimport { createError, toError } from \"../../../core/errors/veryfront-error.ts\";\nimport { createFileSystem, FileSystem } from \"../../../platform/compat/fs.ts\";\nimport * as pathHelper from \"../../../platform/compat/path-helper.ts\";\nimport { isDeno, isNode } from \"../../../platform/compat/runtime.ts\";\n\nexport async function loadHandlerModule(options: LoadModuleOptions): Promise<APIRoute | null> {\n const { projectDir, modulePath, adapter, config } = options;\n const fs = createFileSystem();\n\n try {\n let module: APIRoute;\n\n if (modulePath.endsWith(\".js\")) {\n // JS files can be loaded directly\n module = await loadJSModule(modulePath);\n } else if (isDeno) {\n // In Deno, directly import TypeScript files without bundling\n // This allows modules to share the same runtime context (including singletons like agentRegistry)\n module = await loadTSModuleDirect(modulePath);\n } else {\n // In Node.js, use esbuild to transpile TypeScript\n // Singletons are shared via globalThis pattern (see src/ai/agent/composition.ts etc.)\n module = await loadAndTranspileModule(modulePath, projectDir, adapter, fs, config);\n }\n\n return extractAPIRouteHandlers(module);\n } catch (error: unknown) {\n const errorMsg = error instanceof Error ? error.message : String(error);\n logger.error(`Failed to load API handler ${modulePath}:`, error);\n throw toError(createError({\n type: \"api\",\n message: `Failed to load API handler: ${errorMsg}`,\n }));\n }\n}\n\n/**\n * Directly import a TypeScript module in Deno without bundling.\n * This allows the module to share the same runtime context as the dev server,\n * enabling auto-discovery features like agentRegistry to work.\n */\nasync function loadTSModuleDirect(modulePath: string): Promise<APIRoute> {\n // Add cache buster for HMR\n const cacheBuster = `?v=${Date.now()}`;\n const url = modulePath.startsWith(\"file://\")\n ? `${modulePath}${cacheBuster}`\n : `file://${modulePath}${cacheBuster}`;\n\n logger.debug(`[API] Direct import (Deno): ${url}`);\n return await import(url);\n}\n\nasync function loadJSModule(modulePath: string): Promise<APIRoute> {\n return await import(`file://${modulePath}`);\n}\n\nfunction createImportMapPlugin(\n projectDir: string,\n adapter: RuntimeAdapter,\n config?: VeryfrontConfig,\n): Plugin {\n const importMap = config?.resolve?.importMap?.imports || {};\n const hasImportMap = Object.keys(importMap).length > 0;\n\n if (!hasImportMap) {\n return {\n name: \"import-map\",\n setup() {},\n };\n }\n\n logger.info(`[API] Using import map with ${Object.keys(importMap).length} entries`);\n\n return {\n name: \"import-map\",\n setup(build) {\n build.onResolve({ filter: /.*/ }, (args) => {\n if (args.path.startsWith(\"http://\") || args.path.startsWith(\"https://\")) {\n return undefined;\n }\n\n if (args.path.startsWith(\"node:\")) {\n return { path: args.path, external: true };\n }\n\n if (args.path === \"ai/react\" || args.path.startsWith(\"ai/react/\")) {\n return { path: args.path, external: true };\n }\n\n if (\n args.path.includes(\"bundle-manifest-kv\") ||\n args.path.includes(\"bundle-manifest-redis\")\n ) {\n return { path: args.path, external: true };\n }\n\n if (args.namespace === \"import-map\" && args.path.startsWith(\".\")) {\n const importerDir = pathHelper.dirname(args.importer);\n const absolutePath = pathHelper.resolve(importerDir, args.path);\n\n logger.debug(\n `[API] Import map relative resolve: ${args.path} (from ${args.importer}) -> ${absolutePath}`,\n );\n\n return {\n path: absolutePath,\n namespace: \"import-map\",\n };\n }\n\n if (pathHelper.isAbsolute(args.path) && args.namespace !== \"import-map\") {\n return undefined;\n }\n\n let resolvedPath: string | undefined;\n\n if (importMap[args.path]) {\n resolvedPath = importMap[args.path];\n } else {\n for (const [key, value] of Object.entries(importMap)) {\n if (key.endsWith(\"/\") && args.path.startsWith(key)) {\n const suffix = args.path.slice(key.length);\n resolvedPath = value + suffix;\n break;\n }\n }\n }\n\n if (resolvedPath) {\n if (resolvedPath.startsWith(\"http://\") || resolvedPath.startsWith(\"https://\")) {\n logger.debug(`[API] Import map resolved to HTTP URL: ${args.path} -> ${resolvedPath}`);\n return undefined;\n }\n\n const absolutePath = pathHelper.isAbsolute(resolvedPath)\n ? resolvedPath\n : pathHelper.resolve(projectDir, resolvedPath);\n\n logger.debug(`[API] Import map resolved: ${args.path} -> ${absolutePath}`);\n\n return {\n path: absolutePath,\n namespace: \"import-map\",\n };\n }\n\n return undefined;\n });\n\n build.onLoad({ filter: /.*/, namespace: \"import-map\" }, async (args) => {\n try {\n let filePath = args.path;\n let contents = \"\";\n\n try {\n contents = await adapter.fs.readFile(filePath);\n } catch {\n const extensions = [\".ts\", \".tsx\", \".js\", \".jsx\", \".mjs\"];\n let found = false;\n\n for (const ext of extensions) {\n try {\n const pathWithExt = filePath + ext;\n contents = await adapter.fs.readFile(pathWithExt);\n filePath = pathWithExt;\n found = true;\n break;\n } catch {\n // Ignore error, try next extension\n }\n }\n\n if (!found) {\n throw toError(createError({\n type: \"file\",\n message: `File not found: ${filePath}`,\n }));\n }\n }\n\n const ext = filePath.split(\".\").pop() || \"\";\n const loader = ext === \"tsx\"\n ? \"tsx\"\n : ext === \"jsx\"\n ? \"jsx\"\n : ext === \"ts\"\n ? \"ts\"\n : ext === \"js\"\n ? \"js\"\n : ext === \"json\"\n ? \"json\"\n : \"js\";\n\n return {\n contents,\n loader,\n resolveDir: pathHelper.dirname(filePath),\n };\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n logger.error(`[API] Failed to load file via import map: ${args.path}`, error);\n return {\n errors: [{ text: `Failed to load: ${msg}` }],\n };\n }\n });\n },\n };\n}\n\nasync function loadAndTranspileModule(\n modulePath: string,\n projectDir: string,\n adapter: RuntimeAdapter,\n fs: FileSystem, // Pass fs compat instance\n config?: VeryfrontConfig,\n): Promise<APIRoute> {\n // Try to resolve the module path with various extensions if not found\n let resolvedPath = modulePath;\n let source: string | undefined;\n\n try {\n source = await adapter.fs.readFile(modulePath);\n } catch {\n // If file not found, try with common extensions\n const extensions = [\".ts\", \".tsx\", \".js\", \".jsx\", \".mjs\"];\n\n for (const ext of extensions) {\n try {\n const pathWithExt = modulePath + ext;\n source = await adapter.fs.readFile(pathWithExt);\n resolvedPath = pathWithExt;\n break;\n } catch {\n // Continue trying other extensions\n }\n }\n\n if (source === undefined) {\n throw toError(createError({\n type: \"file\",\n message: `File not found: ${modulePath} (tried extensions: ${extensions.join(\", \")})`,\n }));\n }\n }\n\n const isTsx = resolvedPath.endsWith(\".tsx\");\n const isJsx = resolvedPath.endsWith(\".jsx\");\n const loader = isTsx ? \"tsx\" : isJsx ? \"jsx\" : resolvedPath.endsWith(\".ts\") ? \"ts\" : \"js\";\n\n const allowedHosts = await loadSecurityConfig(projectDir, adapter);\n validateHTTPImports(source, allowedHosts);\n\n const { build } = await import(\"esbuild\");\n\n const plugins = [\n createImportMapPlugin(projectDir, adapter, config),\n createHTTPPlugin(allowedHosts),\n ];\n\n const externalPackages = [\n \"ai\",\n \"ai/*\",\n \"ai/react\",\n \"@ai-sdk/*\",\n \"zod\",\n \"node:*\",\n // Veryfront packages - should use runtime resolution, not bundled\n \"veryfront\",\n \"veryfront/*\",\n // OpenTelemetry packages used by veryfront/ai\n \"@opentelemetry/*\",\n // Path module - Node.js built-in\n \"path\",\n ];\n\n // Use the directory containing the source file as resolveDir\n // This allows relative imports like ../../../ai/agents to resolve correctly\n const resolveDir = pathHelper.dirname(resolvedPath);\n\n const result: BuildResult = await build({\n bundle: true,\n write: false,\n format: \"esm\",\n platform: \"neutral\",\n target: \"es2022\",\n jsx: \"automatic\",\n jsxImportSource: \"react\",\n resolveExtensions: [\".ts\", \".tsx\", \".js\", \".jsx\", \".mjs\"],\n external: externalPackages,\n stdin: {\n contents: source,\n loader,\n resolveDir,\n sourcefile: resolvedPath,\n },\n plugins,\n });\n\n if (result.errors && result.errors.length > 0) {\n const first = result.errors[0]?.text || \"unknown error\";\n throw toError(createError({\n type: \"api\",\n message: `[API] handler build failed: ${first}`,\n }));\n }\n\n logger.info(`[API] built handler ${resolvedPath}`);\n const js = result.outputFiles?.[0]?.text ?? \"export {}\";\n logger.debug(`[API] transpiled size ${js.length} bytes`);\n\n return await loadModuleFromCode(js, adapter, projectDir, fs);\n}\n\nasync function loadModuleFromCode(\n code: string,\n _adapter: RuntimeAdapter,\n projectDir: string,\n fs: FileSystem,\n): Promise<APIRoute> {\n const tempDir = await fs.makeTempDir({ prefix: \"vf-api-\" });\n const tempFile = pathHelper.join(tempDir, \"handler.mjs\");\n\n const transformedCode = await rewriteExternalImports(code, projectDir, fs);\n\n await fs.writeTextFile(tempFile, transformedCode);\n\n try {\n return await import(`file://${tempFile}?v=${Date.now()}`);\n } catch (e: unknown) {\n const errorMessage = e instanceof Error && e.stack ? e.stack : String(e);\n logger.error(`[API] dynamic import failed ${tempFile}: ${errorMessage}`);\n throw e;\n } finally {\n await fs.remove(tempDir, { recursive: true });\n }\n}\n\nasync function rewriteExternalImports(\n code: string,\n projectDir: string,\n fs: FileSystem,\n): Promise<string> {\n let transformed = code;\n\n // In Node.js, resolve external imports to absolute paths\n // since the temp file is outside the project's node_modules\n if (isNode) {\n try {\n const { pathToFileURL } = await import(\"node:url\");\n\n logger.debug(`[API] Rewriting external imports for Node.js, projectDir: ${projectDir}`);\n\n // Helper to resolve a package to absolute file:// URL\n const resolvePackageToFileUrl = async (packageName: string): Promise<string | null> => {\n const packagePath = pathHelper.join(projectDir, \"node_modules\", packageName);\n const packageJsonPath = pathHelper.join(packagePath, \"package.json\");\n\n try {\n const pkgJson = JSON.parse(await fs.readTextFile(packageJsonPath));\n // Try exports[\".\"].import, exports[\".\"].default, main, module in that order\n let entryPoint: string | undefined;\n\n if (pkgJson.exports) {\n const dotExport = pkgJson.exports[\".\"];\n if (typeof dotExport === \"string\") {\n entryPoint = dotExport;\n } else if (dotExport?.import) {\n entryPoint = dotExport.import;\n } else if (dotExport?.default) {\n entryPoint = dotExport.default;\n }\n }\n\n if (!entryPoint) {\n entryPoint = pkgJson.module || pkgJson.main || \"index.js\";\n }\n\n if (!entryPoint) {\n return null;\n }\n\n const resolvedPath = pathHelper.join(packagePath, entryPoint);\n return pathToFileURL(resolvedPath).href;\n } catch {\n return null;\n }\n };\n\n // List of external packages that need to be resolved to absolute paths\n const externalPackagesToResolve = [\n \"zod\",\n \"ai\",\n \"@ai-sdk/anthropic\",\n \"@ai-sdk/openai\",\n \"@ai-sdk/google\",\n \"@ai-sdk/mistral\",\n \"@ai-sdk/provider\",\n \"@ai-sdk/provider-utils\",\n ];\n\n // Resolve external packages to absolute paths\n for (const pkg of externalPackagesToResolve) {\n const escapedPkg = pkg.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n\n // Match static imports: from \"package\"\n const staticImportRegex = new RegExp(`from\\\\s+[\"']${escapedPkg}[\"']`, \"g\");\n if (staticImportRegex.test(transformed)) {\n const resolvedUrl = await resolvePackageToFileUrl(pkg);\n if (resolvedUrl) {\n transformed = transformed.replace(staticImportRegex, `from \"${resolvedUrl}\"`);\n logger.debug(`[API] Resolved ${pkg} -> ${resolvedUrl}`);\n }\n }\n\n // Match dynamic imports: import(\"package\")\n const dynamicImportRegex = new RegExp(`import\\\\s*\\\\(\\\\s*[\"']${escapedPkg}[\"']\\\\s*\\\\)`, \"g\");\n if (dynamicImportRegex.test(transformed)) {\n const resolvedUrl = await resolvePackageToFileUrl(pkg);\n if (resolvedUrl) {\n transformed = transformed.replace(dynamicImportRegex, `import(\"${resolvedUrl}\")`);\n logger.debug(`[API] Resolved dynamic import ${pkg} -> ${resolvedUrl}`);\n }\n }\n }\n\n // Manual resolution for veryfront using package.json exports\n // This is more reliable than createRequire for subpath exports\n const vfPackagePath = pathHelper.join(projectDir, \"node_modules\", \"veryfront\");\n const vfPackageJsonPath = pathHelper.join(vfPackagePath, \"package.json\");\n\n let exportsMap: Record<string, { import?: string }> = {};\n try {\n const pkgJson = JSON.parse(await fs.readTextFile(vfPackageJsonPath));\n exportsMap = pkgJson.exports || {};\n } catch (err) {\n logger.debug(`[API] Could not read veryfront package.json: ${err}`);\n }\n\n // Resolve veryfront subpath imports (e.g., veryfront/ai)\n transformed = transformed.replace(\n /from\\s+[\"'](veryfront\\/[^\"']+)[\"']/g,\n (_match, fullSpecifier: string) => {\n const subpath = \"./\" + fullSpecifier.replace(\"veryfront/\", \"\");\n const exportEntry = exportsMap[subpath];\n if (exportEntry?.import) {\n const resolvedPath = pathHelper.join(vfPackagePath, exportEntry.import);\n logger.debug(`[API] Resolved ${fullSpecifier} -> ${resolvedPath}`);\n return `from \"${pathToFileURL(resolvedPath).href}\"`;\n }\n logger.warn(`[API] No export found for ${subpath}`);\n return _match;\n },\n );\n\n // Resolve bare veryfront import\n transformed = transformed.replace(\n /from\\s+[\"']veryfront[\"']/g,\n () => {\n const exportEntry = exportsMap[\".\"];\n if (exportEntry?.import) {\n const resolvedPath = pathHelper.join(vfPackagePath, exportEntry.import);\n logger.debug(`[API] Resolved veryfront -> ${resolvedPath}`);\n return `from \"${pathToFileURL(resolvedPath).href}\"`;\n }\n return 'from \"veryfront\"';\n },\n );\n } catch (e) {\n // If node:module import fails, we're not in Node.js or something went wrong\n logger.warn(`[API] Failed to import node:module: ${e}`);\n // Fall through to Deno handling\n }\n }\n\n // For Deno, use npm: specifiers for selected packages\n // For Node.js, these are typically resolved via node_modules\n // This list should only include packages that are externalized by esbuild but need explicit npm: specifiers in Deno\n const externalPackages = [\n { pattern: /from\\s+[\"']ai[\"']/g, replacement: 'from \"npm:ai@latest\"' },\n {\n pattern: /from\\s+[\"']@ai-sdk\\/anthropic[\"']/g,\n replacement: 'from \"npm:@ai-sdk/anthropic@latest\"',\n },\n { pattern: /from\\s+[\"']@ai-sdk\\/openai[\"']/g, replacement: 'from \"npm:@ai-sdk/openai@latest\"' },\n { pattern: /from\\s+[\"']@ai-sdk\\/google[\"']/g, replacement: 'from \"npm:@ai-sdk/google@latest\"' },\n {\n pattern: /from\\s+[\"']@ai-sdk\\/mistral[\"']/g,\n replacement: 'from \"npm:@ai-sdk/mistral@latest\"',\n },\n {\n pattern: /from\\s+[\"']@ai-sdk\\/provider[\"']/g,\n replacement: 'from \"npm:@ai-sdk/provider@latest\"',\n },\n {\n pattern: /from\\s+[\"']@ai-sdk\\/provider-utils[\"']/g,\n replacement: 'from \"npm:@ai-sdk/provider-utils@latest\"',\n },\n { pattern: /from\\s+[\"']zod[\"']/g, replacement: 'from \"npm:zod@latest\"' },\n { pattern: /import\\s*\\(\\s*[\"']ai[\"']\\s*\\)/g, replacement: 'import(\"npm:ai@latest\")' },\n {\n pattern: /import\\s*\\(\\s*[\"']@ai-sdk\\/anthropic[\"']\\s*\\)/g,\n replacement: 'import(\"npm:@ai-sdk/anthropic@latest\")',\n },\n {\n pattern: /import\\s*\\(\\s*[\"']@ai-sdk\\/openai[\"']\\s*\\)/g,\n replacement: 'import(\"npm:@ai-sdk/openai@latest\")',\n },\n {\n pattern: /import\\s*\\(\\s*[\"']@ai-sdk\\/google[\"']\\s*\\)/g,\n replacement: 'import(\"npm:@ai-sdk/google@latest\")',\n },\n {\n pattern: /import\\s*\\(\\s*[\"']@ai-sdk\\/mistral[\"']\\s*\\)/g,\n replacement: 'import(\"npm:@ai-sdk/mistral@latest\")',\n },\n {\n pattern: /import\\s*\\(\\s*[\"']@ai-sdk\\/provider[\"']\\s*\\)/g,\n replacement: 'import(\"npm:@ai-sdk/provider@latest\")',\n },\n {\n pattern: /import\\s*\\(\\s*[\"']@ai-sdk\\/provider-utils[\"']\\s*\\)/g,\n replacement: 'import(\"npm:@ai-sdk/provider-utils@latest\")',\n },\n { pattern: /import\\s*\\(\\s*[\"']zod[\"']\\s*\\)/g, replacement: 'import(\"npm:zod@latest\")' },\n ];\n\n // Apply npm: specifier rewrites only if not in Node.js (i.e., in Deno)\n if (isDeno) {\n for (const { pattern, replacement } of externalPackages) {\n transformed = transformed.replace(pattern, replacement);\n }\n }\n\n return transformed;\n}\n\nfunction extractAPIRouteHandlers(module: unknown): APIRoute {\n const handler: APIRoute = {};\n\n if (!module || typeof module !== \"object\") {\n return handler;\n }\n\n const mod = module as Record<string, unknown>;\n\n if (typeof mod.GET === \"function\") handler.GET = mod.GET as APIRoute[\"GET\"];\n if (typeof mod.POST === \"function\") handler.POST = mod.POST as APIRoute[\"POST\"];\n if (typeof mod.PUT === \"function\") handler.PUT = mod.PUT as APIRoute[\"PUT\"];\n if (typeof mod.PATCH === \"function\") handler.PATCH = mod.PATCH as APIRoute[\"PATCH\"];\n if (typeof mod.DELETE === \"function\") handler.DELETE = mod.DELETE as APIRoute[\"DELETE\"];\n if (typeof mod.HEAD === \"function\") handler.HEAD = mod.HEAD as APIRoute[\"HEAD\"];\n if (typeof mod.OPTIONS === \"function\") handler.OPTIONS = mod.OPTIONS as APIRoute[\"OPTIONS\"];\n\n if (typeof mod.default === \"function\") {\n handler.default = mod.default as APIRoute[\"default\"];\n }\n\n return handler;\n}\n", "import { serverLogger as logger } from \"@veryfront/utils\";\nimport type { Message, Plugin } from \"esbuild\";\nimport { getDenoStdNodeBase } from \"@veryfront/utils\";\nimport { HTTP_MODULE_FETCH_TIMEOUT_MS, HTTP_NETWORK_CONNECT_TIMEOUT } from \"@veryfront/utils\";\n\nexport function createHTTPPlugin(allowedHosts: string[]): Plugin {\n return {\n name: \"vf-api-http-fetch\",\n setup(build: Parameters<Plugin[\"setup\"]>[0]) {\n const stdNodeBase = getDenoStdNodeBase();\n const resolvedUrls: string[] = [];\n const nodeMapped: Array<{ from: string; to: string }> = [];\n\n const mapNodeCore = (spec: string): string | null => {\n if (spec.startsWith(\"node:\")) {\n const sub = spec.slice(5);\n return `${stdNodeBase}/${sub}.ts`;\n }\n if (spec === \"buffer\") return `${stdNodeBase}/buffer.ts`;\n if (spec === \"path\") return `${stdNodeBase}/path.ts`;\n if (spec === \"fs\") return `${stdNodeBase}/fs.ts`;\n return null;\n };\n\n build.onResolve({ filter: /^(http|https):\\/\\// }, (args) => ({\n path: args.path,\n namespace: \"http-url\",\n }));\n\n build.onResolve({ filter: /^react\\/(jsx-runtime|jsx-dev-runtime)$/ }, (args) => {\n const reactUrl = `https://esm.sh/react@18/${args.path.split(\"/\")[1]}`;\n logger.debug(`[API][http] map '${args.path}' -> '${reactUrl}'`);\n return { path: reactUrl, namespace: \"http-url\" };\n });\n\n build.onResolve({ filter: /^(node:|buffer$|path$|fs$)/ }, (args) => {\n const mapped = mapNodeCore(args.path);\n if (mapped) {\n nodeMapped.push({ from: args.path, to: mapped });\n logger.debug(`[API][http] map '${args.path}' -> '${mapped}'`);\n return { path: mapped, namespace: \"http-url\" };\n }\n return undefined;\n });\n\n build.onResolve({ filter: /.*/ }, (args) => {\n if (args.namespace === \"http-url\") {\n try {\n const resolved = new URL(args.path, args.importer).toString();\n resolvedUrls.push(resolved);\n return { path: resolved, namespace: \"http-url\" };\n } catch {\n return undefined;\n }\n }\n return undefined;\n });\n\n build.onLoad({ filter: /.*/, namespace: \"http-url\" }, async (args) => {\n let requestUrl = args.path;\n try {\n const u = new URL(args.path);\n if (allowedHosts && allowedHosts.length > 0) {\n const hostUrl = `${u.protocol}//${u.host}`;\n const isAllowed = allowedHosts.some((h) => hostUrl.startsWith(h));\n if (!isAllowed) {\n const remediation =\n `Add \"${hostUrl}\" to security.remoteHosts in veryfront.config.(ts|js) or replace with an approved CDN (e.g., https://esm.sh).`;\n return {\n errors: [\n {\n text: `Remote import blocked by allow-list: ${hostUrl}. ${remediation}`,\n } as Message,\n ],\n };\n }\n }\n if (u.hostname === \"esm.sh\") {\n if (u.pathname.includes(\"/denonext/\")) {\n u.pathname = u.pathname.replace(\"/denonext/\", \"/\");\n }\n u.searchParams.set(\"target\", \"es2020\");\n u.searchParams.set(\"bundle\", \"true\");\n logger.debug(`[API][http] esm.sh rewrite: ${args.path} -> ${u.toString()}`);\n requestUrl = u.toString();\n }\n } catch (e) {\n logger.warn(\"API URL parse failed\", e);\n }\n\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), HTTP_MODULE_FETCH_TIMEOUT_MS);\n const res = await fetch(requestUrl, {\n headers: { \"user-agent\": \"Mozilla/5.0 Veryfront/1.0\" },\n signal: controller.signal,\n })\n .catch((e) => {\n return new Response(String(e?.message || e), { status: HTTP_NETWORK_CONNECT_TIMEOUT });\n })\n .finally(() => clearTimeout(timeout));\n\n if (!res.ok) {\n logger.error(`[API][http] fetch failed ${requestUrl} ${res.status}`);\n return {\n errors: [\n {\n text: `Failed to fetch ${args.path}: ${res.status}`,\n } as Message,\n ],\n };\n }\n\n const text = await res.text();\n return { contents: text, loader: \"js\" } as const;\n });\n\n logger.debug(\n `[API][http] resolvedUrls: ${resolvedUrls.length}, nodeMapped: ${nodeMapped.length}`,\n );\n },\n };\n}\n", "import { createError, toError } from \"../../../core/errors/veryfront-error.ts\";\n\nexport function validateHTTPImports(source: string, allowedHosts: string[]): void {\n const importRegex = /import\\s+(?:[\\w\\s{},*]+\\s+from\\s+)?['\"]https?:\\/\\/[^'\"]+['\"]/g;\n const dynamicImportRegex = /import\\s*\\(['\"]https?:\\/\\/[^'\"]+['\"]\\)/g;\n\n const matches = [\n ...source.matchAll(importRegex),\n ...source.matchAll(dynamicImportRegex),\n ];\n\n for (const match of matches) {\n const urlMatch = match[0].match(/https?:\\/\\/[^'\"]+/);\n if (!urlMatch) continue;\n\n const fullUrl = urlMatch[0];\n try {\n const u = new URL(fullUrl);\n const hostUrl = `${u.protocol}//${u.host}`;\n\n if (allowedHosts && allowedHosts.length > 0) {\n const isAllowed = allowedHosts.some((h) => hostUrl.startsWith(h));\n if (!isAllowed) {\n const remediation =\n `Add \"${hostUrl}\" to security.remoteHosts in veryfront.config.(ts|js) or replace with an approved CDN (e.g., https://esm.sh).`;\n throw toError(createError({\n type: \"api\",\n message:\n `[API] handler build failed: Remote import blocked by allow-list: ${hostUrl}. ${remediation}`,\n }));\n }\n }\n } catch (e) {\n if (e instanceof Error && e.message.includes(\"Remote import blocked\")) {\n throw e;\n }\n }\n }\n}\n", "import { serverLogger as logger } from \"@veryfront/utils\";\nimport type { RuntimeAdapter } from \"@veryfront/platform/adapters/index.ts\";\nimport type { VeryfrontConfig } from \"@veryfront/config\";\nimport { DEFAULT_ALLOWED_CDN_HOSTS } from \"@veryfront/utils\";\n\nexport async function loadSecurityConfig(\n projectDir: string,\n adapter: RuntimeAdapter,\n): Promise<string[]> {\n try {\n const { getConfig } = await import(\"@veryfront/config\");\n const cfg: VeryfrontConfig = await getConfig(projectDir, adapter);\n const remote = cfg?.security?.remoteHosts;\n if (Array.isArray(remote)) return remote;\n } catch (e) {\n logger.warn(\"Failed to load security.remoteHosts\", e);\n }\n return DEFAULT_ALLOWED_CDN_HOSTS;\n}\n", "/**\n * Cross-platform filesystem abstraction for CLI commands and standalone utilities.\n *\n * This module provides a synchronous-style API for filesystem operations that works\n * across Deno, Node.js, and Bun runtimes. It's designed for CLI commands and scripts\n * where you don't have access to a RuntimeAdapter context.\n *\n * For server/rendering contexts where you have an adapter, prefer using adapter.fs directly:\n * ```ts\n * const adapter = await getAdapter();\n * const content = await adapter.fs.readFile(path);\n * ```\n *\n * For CLI commands and standalone utilities, use createFileSystem():\n * ```ts\n * import { createFileSystem } from \"@veryfront/platform/compat/fs.ts\";\n * const fs = createFileSystem();\n * const content = await fs.readTextFile(path);\n * ```\n *\n * @module\n */\n\nimport type { FileInfo } from \"@veryfront/platform/adapters/base.ts\";\nimport { createError, toError } from \"../../core/errors/veryfront-error.ts\";\nimport { isDeno, isNode } from \"./runtime.ts\";\n\n/**\n * Cross-platform filesystem interface for CLI commands and standalone utilities.\n * Compatible with RuntimeAdapter.fs (FileSystemAdapter) for easy interoperability.\n */\nexport interface FileSystem {\n readTextFile(path: string): Promise<string>;\n readFile(path: string): Promise<Uint8Array>; // Changed to Uint8Array for binary\n writeTextFile(path: string, data: string): Promise<void>;\n writeFile(path: string, data: Uint8Array): Promise<void>; // Changed to Uint8Array for binary\n exists(path: string): Promise<boolean>;\n stat(path: string): Promise<FileInfo>;\n mkdir(path: string, options?: { recursive?: boolean }): Promise<void>;\n readDir(path: string): AsyncIterable<{ name: string; isFile: boolean; isDirectory: boolean }>;\n remove(path: string, options?: { recursive?: boolean }): Promise<void>;\n makeTempDir(options?: { prefix?: string }): Promise<string>; // New for temp dirs\n}\n\n// ============================================================================\n// Node.js Implementation\n// ============================================================================\n\ninterface NodeFsPromises {\n readFile(\n path: string,\n options?: { encoding?: string; flag?: string } | string,\n ): Promise<string | Uint8Array>;\n writeFile(\n path: string,\n data: string | Uint8Array,\n options?: { encoding?: string; flag?: string } | string,\n ): Promise<void>;\n access(path: string, mode?: number): Promise<void>;\n stat(path: string): Promise<{\n isFile(): boolean;\n isDirectory(): boolean;\n isSymbolicLink(): boolean;\n size: number;\n mtime: Date;\n }>;\n mkdir(path: string, options?: { recursive?: boolean }): Promise<void>;\n readdir(path: string, options: { withFileTypes: true }): Promise<\n Array<{\n name: string;\n isFile(): boolean;\n isDirectory(): boolean;\n isSymbolicLink(): boolean;\n }>\n >;\n rm(path: string, options?: { recursive?: boolean; force?: boolean }): Promise<void>;\n}\n\nclass NodeFileSystem implements FileSystem {\n private fs: NodeFsPromises | null = null;\n private os: typeof import(\"node:os\") | null = null;\n private path: typeof import(\"node:path\") | null = null;\n private initialized = false;\n\n private async ensureInitialized(): Promise<void> {\n if (this.initialized) return;\n\n if (!isNode) {\n throw toError(createError({\n type: \"not_supported\",\n message: \"Node.js fs modules not available\",\n feature: \"Node.js\",\n }));\n }\n\n // Use dynamic ESM imports for Node.js modules\n const [fsModule, osModule, pathModule] = await Promise.all([\n import(\"node:fs/promises\"),\n import(\"node:os\"),\n import(\"node:path\"),\n ]);\n\n this.fs = fsModule as unknown as NodeFsPromises;\n this.os = osModule;\n this.path = pathModule;\n this.initialized = true;\n }\n\n async readTextFile(path: string): Promise<string> {\n await this.ensureInitialized();\n return await (this.fs!.readFile(path, { encoding: \"utf8\" }) as Promise<string>);\n }\n\n async readFile(path: string): Promise<Uint8Array> {\n await this.ensureInitialized();\n return await (this.fs!.readFile(path) as Promise<Uint8Array>);\n }\n\n async writeTextFile(path: string, data: string): Promise<void> {\n await this.ensureInitialized();\n await this.fs!.writeFile(path, data, { encoding: \"utf8\" });\n }\n\n async writeFile(path: string, data: Uint8Array): Promise<void> {\n await this.ensureInitialized();\n await this.fs!.writeFile(path, data);\n }\n\n async exists(path: string): Promise<boolean> {\n await this.ensureInitialized();\n try {\n await this.fs!.access(path);\n return true;\n } catch (error: any) {\n if (error.code === \"ENOENT\") {\n return false;\n }\n throw error;\n }\n }\n\n async stat(path: string): Promise<FileInfo> {\n await this.ensureInitialized();\n const stat = await this.fs!.stat(path);\n return {\n isFile: stat.isFile(),\n isDirectory: stat.isDirectory(),\n isSymlink: stat.isSymbolicLink(),\n size: stat.size,\n mtime: stat.mtime,\n };\n }\n\n async mkdir(path: string, options?: { recursive?: boolean }): Promise<void> {\n await this.ensureInitialized();\n await this.fs!.mkdir(path, { recursive: options?.recursive ?? false });\n }\n\n async *readDir(\n path: string,\n ): AsyncIterable<{ name: string; isFile: boolean; isDirectory: boolean }> {\n await this.ensureInitialized();\n const entries = await this.fs!.readdir(path, { withFileTypes: true });\n for (const entry of entries) {\n yield {\n name: entry.name,\n isFile: entry.isFile(),\n isDirectory: entry.isDirectory(),\n };\n }\n }\n\n async remove(path: string, options?: { recursive?: boolean }): Promise<void> {\n await this.ensureInitialized();\n // Node.js fs.rm requires force for recursive deletion of non-empty directories\n await this.fs!.rm(path, {\n recursive: options?.recursive ?? false,\n force: options?.recursive ?? false,\n });\n }\n\n async makeTempDir(options?: { prefix?: string }): Promise<string> {\n await this.ensureInitialized();\n const tempDir = this.path!.join(\n this.os!.tmpdir(),\n `${options?.prefix ?? \"tmp-\"}${Math.random().toString(36).substring(2, 8)}`,\n );\n await this.fs!.mkdir(tempDir, { recursive: true });\n return tempDir;\n }\n}\n\n// ============================================================================\n// Deno Implementation\n// ============================================================================\n\nclass DenoFileSystem implements FileSystem {\n async readTextFile(path: string): Promise<string> {\n // @ts-ignore - Deno global\n return await Deno.readTextFile(path);\n }\n\n async readFile(path: string): Promise<Uint8Array> {\n // @ts-ignore - Deno global\n return await Deno.readFile(path);\n }\n\n async writeTextFile(path: string, data: string): Promise<void> {\n // @ts-ignore - Deno global\n await Deno.writeTextFile(path, data);\n }\n\n async writeFile(path: string, data: Uint8Array): Promise<void> {\n // @ts-ignore - Deno global\n await Deno.writeFile(path, data);\n }\n\n async exists(path: string): Promise<boolean> {\n try {\n // @ts-ignore - Deno global\n await Deno.stat(path);\n return true;\n } catch (error: any) {\n // @ts-ignore - Deno global\n if (error instanceof Deno.errors.NotFound) {\n return false;\n }\n throw error;\n }\n }\n\n async stat(path: string): Promise<FileInfo> {\n // @ts-ignore - Deno global\n const stat = await Deno.stat(path);\n return {\n isFile: stat.isFile,\n isDirectory: stat.isDirectory,\n isSymlink: stat.isSymlink,\n size: stat.size,\n mtime: stat.mtime,\n };\n }\n\n async mkdir(path: string, options?: { recursive?: boolean }): Promise<void> {\n // @ts-ignore - Deno global\n await Deno.mkdir(path, { recursive: options?.recursive ?? false });\n }\n\n async *readDir(\n path: string,\n ): AsyncIterable<{ name: string; isFile: boolean; isDirectory: boolean }> {\n // @ts-ignore - Deno global\n for await (const entry of Deno.readDir(path)) {\n yield {\n name: entry.name,\n isFile: entry.isFile,\n isDirectory: entry.isDirectory,\n };\n }\n }\n\n async remove(path: string, options?: { recursive?: boolean }): Promise<void> {\n // @ts-ignore - Deno global\n await Deno.remove(path, { recursive: options?.recursive ?? false });\n }\n\n async makeTempDir(options?: { prefix?: string }): Promise<string> {\n // @ts-ignore - Deno global\n return await Deno.makeTempDir({ prefix: options?.prefix });\n }\n}\n\n/**\n * Create a cross-platform filesystem instance for CLI commands and standalone utilities.\n *\n * Use this for CLI commands that don't have access to a RuntimeAdapter context:\n * ```ts\n * const fs = createFileSystem();\n * const content = await fs.readTextFile(path);\n * await fs.writeTextFile(outputPath, result);\n * ```\n *\n * For server/rendering contexts, prefer using adapter.fs directly.\n *\n * Note: For npm package, always uses Node.js fs APIs for cross-platform compatibility.\n */\nexport function createFileSystem(): FileSystem {\n if (isDeno) {\n return new DenoFileSystem();\n } else {\n // Node.js or Bun\n return new NodeFileSystem();\n }\n}\n", "import { relative } from \"std/path/mod.ts\";\nimport type { RuntimeAdapter } from \"@veryfront/platform/adapters/base.ts\";\nimport type { DynamicRouter } from \"./api-route-matcher.ts\";\nimport { discoverFiles } from \"@veryfront/core/utils/file-discovery.ts\";\n\nexport async function discoverPagesRoutes(\n router: DynamicRouter,\n dir: string,\n prefix: string,\n adapter: RuntimeAdapter,\n): Promise<void> {\n for await (\n const file of discoverFiles({\n baseDir: dir,\n extensions: [\".ts\", \".js\", \".tsx\", \".jsx\"],\n adapter,\n })\n ) {\n const relativePath = relative(dir, file.path);\n const routePath = `${prefix}/${relativePath.replace(/\\.(ts|js|tsx|jsx)$/, \"\")}`;\n\n let pattern = routePath.replace(/\\/index$/, \"\");\n\n if (pattern === prefix && file.name.replace(/\\.(ts|js|tsx|jsx)$/, \"\") === \"index\") {\n pattern = prefix;\n }\n\n router.addRoute(pattern, file.path);\n }\n}\n\nexport async function discoverAppRoutes(\n router: DynamicRouter,\n dir: string,\n prefix: string,\n adapter: RuntimeAdapter,\n): Promise<void> {\n for await (\n const file of discoverFiles({\n baseDir: dir,\n extensions: [\".ts\", \".js\", \".tsx\", \".jsx\"],\n patterns: [\"route\"],\n recursive: false,\n adapter,\n })\n ) {\n if (file.isFile && /^route\\.(ts|js|tsx|jsx)$/.test(file.name)) {\n const pattern = prefix === \"\" ? \"/\" : prefix;\n router.addRoute(pattern, file.path);\n }\n }\n\n for await (\n const dir_entry of discoverFiles({\n baseDir: dir,\n includeDirs: true,\n recursive: false,\n adapter,\n })\n ) {\n if (dir_entry.isDirectory) {\n const dirPrefix = `${prefix}/${dir_entry.name}`;\n await discoverAppRoutes(router, dir_entry.path, dirPrefix, adapter);\n }\n }\n}\n", "/**\n * Consolidated file discovery utility\n *\n * Provides unified file walking, filtering, and pattern matching\n * for route discovery, build asset scanning, and module discovery.\n */\n\nimport { join } from \"std/path/mod.ts\";\nimport type { RuntimeAdapter } from \"@veryfront/platform/adapters/base.ts\";\nimport { denoAdapter } from \"@veryfront/platform/adapters/deno.ts\";\n\nexport interface FileDiscoveryOptions {\n /**\n * Base directory to start searching from\n */\n baseDir: string;\n\n /**\n * File extensions to include (e.g., [\".ts\", \".tsx\", \".mdx\"])\n * If not specified, all files are included\n */\n extensions?: string[];\n\n /**\n * File name patterns to match (e.g., [\"page\", \"layout\", \"route\"])\n * Files must match at least one pattern if specified\n */\n patterns?: string[];\n\n /**\n * Whether to recursively traverse subdirectories\n * @default true\n */\n recursive?: boolean;\n\n /**\n * Maximum depth for recursive traversal\n * @default Infinity\n */\n maxDepth?: number;\n\n /**\n * Directory or file name patterns to ignore (e.g., [\"node_modules\", \".git\"])\n */\n ignorePatterns?: string[];\n\n /**\n * Include directories in the results\n * @default false\n */\n includeDirs?: boolean;\n\n /**\n * Follow symbolic links\n * @default false\n */\n followSymlinks?: boolean;\n\n /**\n * Runtime adapter for filesystem operations\n * If not provided, uses the default Deno adapter (for backward compatibility)\n */\n adapter?: RuntimeAdapter;\n}\n\nexport interface FileDiscoveryResult {\n /**\n * Absolute path to the file or directory\n */\n path: string;\n\n /**\n * File or directory name\n */\n name: string;\n\n /**\n * Whether this is a file\n */\n isFile: boolean;\n\n /**\n * Whether this is a directory\n */\n isDirectory: boolean;\n\n /**\n * Current depth from base directory\n */\n depth: number;\n}\n\n/**\n * Check if a file matches the given extensions\n */\nfunction matchesExtensions(fileName: string, extensions: string[] | undefined): boolean {\n if (!extensions || extensions.length === 0) {\n return true;\n }\n return extensions.some((ext) => fileName.endsWith(ext));\n}\n\n/**\n * Check if a file matches the given patterns\n */\nfunction matchesPatterns(fileName: string, patterns: string[] | undefined): boolean {\n if (!patterns || patterns.length === 0) {\n return true;\n }\n return patterns.some((pattern) => fileName.includes(pattern));\n}\n\n/**\n * Check if a path should be ignored\n */\nfunction shouldIgnore(name: string, ignorePatterns: string[] | undefined): boolean {\n if (!ignorePatterns || ignorePatterns.length === 0) {\n return false;\n }\n return ignorePatterns.some((pattern) => name.includes(pattern));\n}\n\n/**\n * Discover files matching the given criteria\n *\n * @example\n * ```ts\n * // Find all TypeScript route files\n * for await (const file of discoverFiles({\n * baseDir: \"./app\",\n * extensions: [\".ts\", \".tsx\"],\n * patterns: [\"route\"],\n * })) {\n * console.log(file.path);\n * }\n * ```\n */\nexport async function* discoverFiles(\n options: FileDiscoveryOptions,\n): AsyncGenerator<FileDiscoveryResult> {\n const {\n baseDir,\n extensions,\n patterns,\n recursive = true,\n maxDepth = Infinity,\n ignorePatterns,\n includeDirs = false,\n followSymlinks = false,\n adapter = denoAdapter,\n } = options;\n\n yield* walkDirectory(\n baseDir,\n 0,\n maxDepth,\n extensions,\n patterns,\n ignorePatterns,\n includeDirs,\n recursive,\n followSymlinks,\n adapter,\n );\n}\n\n/**\n * Internal recursive directory walker\n */\nasync function* walkDirectory(\n dir: string,\n currentDepth: number,\n maxDepth: number,\n extensions: string[] | undefined,\n patterns: string[] | undefined,\n ignorePatterns: string[] | undefined,\n includeDirs: boolean,\n recursive: boolean,\n followSymlinks: boolean,\n adapter: RuntimeAdapter,\n): AsyncGenerator<FileDiscoveryResult> {\n // Check depth limit\n if (currentDepth > maxDepth) {\n return;\n }\n\n try {\n // Use adapter for cross-platform filesystem access\n const entries = adapter.fs.readDir(dir);\n\n for await (const entry of entries) {\n const fullPath = join(dir, entry.name);\n\n // Check if should be ignored\n if (shouldIgnore(entry.name, ignorePatterns)) {\n continue;\n }\n\n // Handle directories\n if (entry.isDirectory) {\n // Yield directory if requested\n if (includeDirs) {\n yield {\n path: fullPath,\n name: entry.name,\n isFile: false,\n isDirectory: true,\n depth: currentDepth,\n };\n }\n\n // Recurse into directory if enabled\n if (recursive) {\n yield* walkDirectory(\n fullPath,\n currentDepth + 1,\n maxDepth,\n extensions,\n patterns,\n ignorePatterns,\n includeDirs,\n recursive,\n followSymlinks,\n adapter,\n );\n }\n } // Handle files\n else if (entry.isFile) {\n // Check extension and pattern matches\n if (\n matchesExtensions(entry.name, extensions) &&\n matchesPatterns(entry.name, patterns)\n ) {\n yield {\n path: fullPath,\n name: entry.name,\n isFile: true,\n isDirectory: false,\n depth: currentDepth,\n };\n }\n } // Handle symlinks (if following is enabled)\n else if (entry.isSymlink && followSymlinks) {\n // For symlinks, we need to check what they point to\n try {\n const stat = await adapter.fs.stat(fullPath);\n\n if (stat.isDirectory && recursive) {\n yield* walkDirectory(\n fullPath,\n currentDepth + 1,\n maxDepth,\n extensions,\n patterns,\n ignorePatterns,\n includeDirs,\n recursive,\n followSymlinks,\n adapter,\n );\n } else if (stat.isFile) {\n if (\n matchesExtensions(entry.name, extensions) &&\n matchesPatterns(entry.name, patterns)\n ) {\n yield {\n path: fullPath,\n name: entry.name,\n isFile: true,\n isDirectory: false,\n depth: currentDepth,\n };\n }\n }\n } catch {\n // Ignore broken symlinks\n }\n }\n }\n } catch {\n // Directory doesn't exist or not accessible\n // Silently skip - this is expected behavior for optional directories\n }\n}\n\n/**\n * Collect all files matching criteria into an array\n *\n * @example\n * ```ts\n * const mdxFiles = await collectFiles({\n * baseDir: \"./pages\",\n * extensions: [\".mdx\"],\n * });\n * ```\n */\nexport async function collectFiles(\n options: FileDiscoveryOptions,\n): Promise<FileDiscoveryResult[]> {\n const results: FileDiscoveryResult[] = [];\n for await (const file of discoverFiles(options)) {\n results.push(file);\n }\n return results;\n}\n\n/**\n * Check if a directory has files matching criteria\n *\n * @example\n * ```ts\n * const hasRoutes = await hasMatchingFiles({\n * baseDir: \"./app\",\n * patterns: [\"page\", \"layout\"],\n * });\n * ```\n */\nexport async function hasMatchingFiles(\n options: FileDiscoveryOptions,\n): Promise<boolean> {\n for await (const _file of discoverFiles(options)) {\n return true; // Found at least one matching file\n }\n return false;\n}\n\n/**\n * Count files matching criteria\n */\nexport async function countFiles(options: FileDiscoveryOptions): Promise<number> {\n let count = 0;\n for await (const _file of discoverFiles(options)) {\n count++;\n }\n return count;\n}\n", "import type { RuntimeAdapter } from \"@veryfront/platform/adapters/base.ts\";\nimport { createContext, normalizeParams } from \"./context-builder.ts\";\nimport type { RouteMatch } from \"./api-route-matcher.ts\";\nimport { createError, toError } from \"../../core/errors/veryfront-error.ts\";\nimport type {\n APIRoute,\n AppRouteContext,\n AppRouteHandler,\n PagesRouteHandler,\n} from \"./module-loader/types.ts\";\nimport {\n createAppRouteMethodNotAllowed,\n createPagesRouteMethodNotAllowed,\n} from \"./method-validator.ts\";\nimport { handleAPIError } from \"./error-handler.ts\";\n\ntype HTTPMethod = \"GET\" | \"POST\" | \"PUT\" | \"DELETE\" | \"PATCH\" | \"HEAD\" | \"OPTIONS\";\n\nexport async function executeAppRoute(\n handler: APIRoute,\n request: Request,\n match: RouteMatch,\n pathname: string,\n adapter: RuntimeAdapter,\n): Promise<Response> {\n const method = request.method.toUpperCase() as HTTPMethod;\n const handlerModule = handler as Record<string, unknown>;\n const handlerFn = handlerModule[method] as PagesRouteHandler | AppRouteHandler | undefined;\n const defaultFn = handlerModule.default as PagesRouteHandler | AppRouteHandler | undefined;\n let resolvedFn = handlerFn || defaultFn;\n const appContext: AppRouteContext = { params: normalizeParams(match.params) };\n\n if (!resolvedFn && method === \"HEAD\") {\n const getFn = handlerModule.GET as PagesRouteHandler | AppRouteHandler | undefined;\n if (typeof getFn === \"function\") {\n resolvedFn = getFn;\n }\n }\n\n if (!resolvedFn) {\n return createAppRouteMethodNotAllowed(handlerModule);\n }\n\n try {\n const response: Response = await (resolvedFn as AppRouteHandler)(\n request,\n appContext,\n );\n\n if (!(response instanceof Response)) {\n throw toError(createError({\n type: \"api\",\n message: \"API handler must return a Response\",\n }));\n }\n\n if (method === \"HEAD\") {\n return new Response(null, {\n status: response.status,\n headers: response.headers,\n });\n }\n\n return response;\n } catch (error) {\n return handleAPIError(error, pathname, adapter);\n }\n}\n\nexport async function executePagesRoute(\n handler: APIRoute,\n request: Request,\n match: RouteMatch,\n pathname: string,\n adapter: RuntimeAdapter,\n): Promise<Response> {\n const ctx = createContext(request, match);\n const method = request.method as keyof APIRoute;\n const methodHandler = handler[method] || handler.default;\n\n if (!methodHandler) {\n return createPagesRouteMethodNotAllowed(handler as Record<string, unknown>);\n }\n\n try {\n const response = await (methodHandler as PagesRouteHandler)(ctx);\n\n if (!(response instanceof Response)) {\n throw toError(createError({\n type: \"api\",\n message: \"API handler must return a Response\",\n }));\n }\n\n return response;\n } catch (error) {\n return handleAPIError(error, pathname, adapter);\n }\n}\n", "import type { RouteMatch } from \"./api-route-matcher.ts\";\n\nexport interface APIContext {\n request: Request;\n params: Record<string, string | string[]>;\n query: URLSearchParams;\n cookies: Record<string, string>;\n headers: Headers;\n url: URL;\n}\n\nexport function parseCookies(cookieHeader: string): Record<string, string> {\n const cookies: Record<string, string> = {};\n\n if (!cookieHeader) return cookies;\n\n cookieHeader.split(\";\").forEach((cookie) => {\n const trimmed = cookie.trim();\n if (!trimmed) return;\n const separatorIndex = trimmed.indexOf(\"=\");\n if (separatorIndex <= 0) return;\n const name = trimmed.slice(0, separatorIndex).trim();\n const value = trimmed.slice(separatorIndex + 1);\n if (!name) return;\n cookies[name] = decodeURIComponent(value);\n });\n\n return cookies;\n}\n\nexport function createContext(request: Request, match: RouteMatch): APIContext {\n const url = new URL(request.url);\n\n return {\n request,\n params: match.params,\n query: url.searchParams,\n cookies: parseCookies(request.headers.get(\"cookie\") ?? \"\"),\n headers: request.headers,\n url,\n };\n}\n\nexport function normalizeParams(params: Record<string, string | string[]>): Record<string, string> {\n const out: Record<string, string> = {};\n for (const [k, v] of Object.entries(params)) {\n out[k] = Array.isArray(v) ? v.join(\"/\") : v;\n }\n return out;\n}\n", "import { HTTP_METHOD_NOT_ALLOWED } from \"@veryfront/utils\";\n\ntype HTTPMethod = \"GET\" | \"POST\" | \"PUT\" | \"DELETE\" | \"PATCH\" | \"HEAD\" | \"OPTIONS\";\n\nexport function createAppRouteMethodNotAllowed(\n handlerModule: Record<string, unknown>,\n): Response {\n const candidates: HTTPMethod[] = [\"GET\", \"POST\", \"PUT\", \"PATCH\", \"DELETE\", \"HEAD\", \"OPTIONS\"];\n const implemented = candidates.filter((m) => typeof handlerModule[m] === \"function\");\n const allow = implemented.join(\", \");\n return new Response(\"Method not allowed\", {\n status: HTTP_METHOD_NOT_ALLOWED,\n headers: { Allow: allow },\n });\n}\n\nexport function createPagesRouteMethodNotAllowed(\n handler: Record<string, unknown>,\n): Response {\n const allowedMethods = Object.keys(handler)\n .filter((m) => m !== \"default\" && typeof handler[m] === \"function\")\n .join(\", \");\n return new Response(\"Method not allowed\", {\n status: HTTP_METHOD_NOT_ALLOWED,\n headers: { Allow: allowedMethods },\n });\n}\n", "import { serverLogger as logger } from \"@veryfront/utils\";\nimport type { RuntimeAdapter } from \"@veryfront/platform/adapters/base.ts\";\nimport { HTTP_INTERNAL_SERVER_ERROR } from \"@veryfront/utils\";\nimport { getEnvironmentVariable } from \"@veryfront/utils\";\n\nexport function handleAPIError(\n error: unknown,\n pathname: string,\n adapter: RuntimeAdapter,\n): Response {\n logger.error(`API route error in ${pathname}:`, error);\n\n const envFromAdapter = adapter.env.get(\"MODE\") ??\n adapter.env.get(\"NODE_ENV\") ??\n adapter.env.get(\"DENO_ENV\");\n const envFromRuntime = getEnvironmentVariable(\"MODE\") ??\n getEnvironmentVariable(\"NODE_ENV\") ??\n getEnvironmentVariable(\"DENO_ENV\");\n const environment = (envFromAdapter ?? envFromRuntime ?? \"development\").toLowerCase();\n const isDevelopment = environment === \"development\" || environment === \"dev\";\n\n if (isDevelopment) {\n return Response.json(\n {\n error: error instanceof Error ? error.message : \"Internal server error\",\n stack: error instanceof Error ? error.stack : undefined,\n },\n { status: HTTP_INTERNAL_SERVER_ERROR },\n );\n }\n\n return new Response(\"Internal server error\", {\n status: HTTP_INTERNAL_SERVER_ERROR,\n });\n}\n", "/**\n * Re-export from centralized HTTP response factory.\n * This file exists for backward compatibility.\n *\n * @deprecated Use imports from \"../../http/responses.ts\" directly\n * Will be removed in v1.0.0\n */\nexport {\n badRequest,\n forbidden,\n internalServerError as serverError,\n jsonResponse as json,\n notFound,\n redirectResponse as redirect,\n unauthorized,\n} from \"../../http/responses.ts\";\n"],
|
|
4
|
+
"sourcesContent": ["/**\n * Shim for Deno.env.get() to work in Node.js\n * This provides a proper function that reads from process.env\n */\n\n// Create a shim that matches Deno.env.get(key) signature\nconst denoEnvShim = {\n get(key: string): string | undefined {\n return process.env[key];\n },\n set(key: string, value: string): void {\n process.env[key] = value;\n },\n delete(key: string): void {\n delete process.env[key];\n },\n has(key: string): boolean {\n return key in process.env;\n },\n toObject(): Record<string, string> {\n return { ...process.env } as Record<string, string>;\n },\n};\n\n// Assign to globalThis.Deno if it doesn't exist\nif (typeof globalThis.Deno === \"undefined\") {\n (globalThis as any).Deno = {\n env: denoEnvShim,\n cwd: () => process.cwd(),\n };\n} else if (typeof (globalThis as any).Deno.env === \"undefined\") {\n (globalThis as any).Deno.env = denoEnvShim;\n}\n\nexport { denoEnvShim };\n", "export interface GlobalWithDeno {\n Deno?: {\n env: {\n get(key: string): string | undefined;\n };\n };\n}\n\nexport interface GlobalWithProcess {\n process?: {\n env: Record<string, string | undefined>;\n version?: string;\n versions?: Record<string, string>;\n };\n}\n\nexport interface GlobalWithBun {\n Bun?: {\n version: string;\n };\n}\n\nexport function hasDenoRuntime(global: unknown): global is GlobalWithDeno {\n return (\n typeof global === \"object\" &&\n global !== null &&\n \"Deno\" in global &&\n typeof (global as GlobalWithDeno).Deno?.env?.get === \"function\"\n );\n}\n\nexport function hasNodeProcess(global: unknown): global is GlobalWithProcess {\n return (\n typeof global === \"object\" &&\n global !== null &&\n \"process\" in global &&\n typeof (global as GlobalWithProcess).process?.env === \"object\"\n );\n}\n\nexport function hasBunRuntime(global: unknown): global is GlobalWithBun {\n return (\n typeof global === \"object\" &&\n global !== null &&\n \"Bun\" in global &&\n typeof (global as GlobalWithBun).Bun !== \"undefined\"\n );\n}\n", "import type { GlobalWithDeno, GlobalWithProcess } from \"../runtime-guards.ts\";\nimport { hasDenoRuntime, hasNodeProcess } from \"../runtime-guards.ts\";\n\nexport function getEnvironmentVariable(name: string): string | undefined {\n try {\n if (typeof Deno !== \"undefined\" && hasDenoRuntime(globalThis)) {\n const value = (globalThis as GlobalWithDeno).Deno?.env.get(name);\n return value === \"\" ? undefined : value;\n }\n if (hasNodeProcess(globalThis)) {\n const value = (globalThis as GlobalWithProcess).process?.env[name];\n return value === \"\" ? undefined : value;\n }\n } catch {\n return undefined;\n }\n return undefined;\n}\n\nexport function isTestEnvironment(): boolean {\n return getEnvironmentVariable(\"NODE_ENV\") === \"test\";\n}\n\nexport function isProductionEnvironment(): boolean {\n return getEnvironmentVariable(\"NODE_ENV\") === \"production\";\n}\n\nexport function isDevelopmentEnvironment(): boolean {\n const env = getEnvironmentVariable(\"NODE_ENV\");\n return env === \"development\" || env === undefined;\n}\n", "import { getEnvironmentVariable } from \"./env.ts\";\n\nexport enum LogLevel {\n DEBUG = 0,\n INFO = 1,\n WARN = 2,\n ERROR = 3,\n}\n\nexport interface Logger {\n debug(message: string, ...args: unknown[]): void;\n info(message: string, ...args: unknown[]): void;\n warn(message: string, ...args: unknown[]): void;\n error(message: string, ...args: unknown[]): void;\n time<T>(label: string, fn: () => Promise<T>): Promise<T>;\n}\n\nconst originalConsole = {\n debug: console.debug,\n log: console.log,\n warn: console.warn,\n error: console.error,\n};\n\nlet cachedLogLevel: LogLevel | undefined;\n\nfunction resolveLogLevel(force = false): LogLevel {\n if (force || cachedLogLevel === undefined) {\n cachedLogLevel = getDefaultLevel();\n }\n return cachedLogLevel;\n}\n\nclass ConsoleLogger implements Logger {\n constructor(\n private prefix: string,\n private level: LogLevel = resolveLogLevel(),\n ) {}\n\n setLevel(level: LogLevel): void {\n this.level = level;\n }\n\n getLevel(): LogLevel {\n return this.level;\n }\n\n debug(message: string, ...args: unknown[]): void {\n if (this.level <= LogLevel.DEBUG) {\n console.debug(`[${this.prefix}] DEBUG: ${message}`, ...args);\n }\n }\n\n info(message: string, ...args: unknown[]): void {\n if (this.level <= LogLevel.INFO) {\n console.log(`[${this.prefix}] ${message}`, ...args);\n }\n }\n\n warn(message: string, ...args: unknown[]): void {\n if (this.level <= LogLevel.WARN) {\n console.warn(`[${this.prefix}] WARN: ${message}`, ...args);\n }\n }\n\n error(message: string, ...args: unknown[]): void {\n if (this.level <= LogLevel.ERROR) {\n console.error(`[${this.prefix}] ERROR: ${message}`, ...args);\n }\n }\n\n async time<T>(label: string, fn: () => Promise<T>): Promise<T> {\n const start = performance.now();\n try {\n const result = await fn();\n const end = performance.now();\n this.debug(`${label} completed in ${(end - start).toFixed(2)}ms`);\n return result;\n } catch (error) {\n const end = performance.now();\n this.error(`${label} failed after ${(end - start).toFixed(2)}ms`, error);\n throw error;\n }\n }\n}\n\nfunction parseLogLevel(levelString: string | undefined): LogLevel | undefined {\n if (!levelString) return undefined;\n const upper = levelString.toUpperCase();\n switch (upper) {\n case \"DEBUG\":\n return LogLevel.DEBUG;\n case \"WARN\":\n return LogLevel.WARN;\n case \"ERROR\":\n return LogLevel.ERROR;\n case \"INFO\":\n return LogLevel.INFO;\n default:\n return undefined;\n }\n}\n\nconst getDefaultLevel = (): LogLevel => {\n const envLevel = getEnvironmentVariable(\"LOG_LEVEL\");\n const parsedLevel = parseLogLevel(envLevel);\n if (parsedLevel !== undefined) return parsedLevel;\n\n const debugFlag = getEnvironmentVariable(\"VERYFRONT_DEBUG\");\n if (debugFlag === \"1\" || debugFlag === \"true\") return LogLevel.DEBUG;\n\n return LogLevel.INFO;\n};\n\nconst trackedLoggers = new Set<ConsoleLogger>();\n\nfunction createLogger(prefix: string): ConsoleLogger {\n const logger = new ConsoleLogger(prefix);\n trackedLoggers.add(logger);\n return logger;\n}\n\nexport const cliLogger = createLogger(\"CLI\");\nexport const serverLogger = createLogger(\"SERVER\");\nexport const rendererLogger = createLogger(\"RENDERER\");\nexport const bundlerLogger = createLogger(\"BUNDLER\");\nexport const agentLogger = createLogger(\"AGENT\");\n\nexport const logger = createLogger(\"VERYFRONT\");\n\ntype LoggerResetOptions = {\n restoreConsole?: boolean;\n};\n\nexport function __loggerResetForTests(options: LoggerResetOptions = {}): void {\n const updatedLevel = resolveLogLevel(true);\n for (const instance of trackedLoggers) {\n instance.setLevel(updatedLevel);\n }\n\n if (options.restoreConsole) {\n console.debug = originalConsole.debug;\n console.log = originalConsole.log;\n console.warn = originalConsole.warn;\n console.error = originalConsole.error;\n }\n}\n", "export * from \"./logger.ts\";\nexport * from \"./env.ts\";\n", "export const DEFAULT_BUILD_CONCURRENCY = 4;\n\nexport const IMAGE_OPTIMIZATION = {\n DEFAULT_SIZES: [640, 750, 828, 1080, 1200, 1920, 2048, 3840],\n DEFAULT_QUALITY: 80,\n} as const;\n", "export const SECONDS_PER_MINUTE = 60;\n\nexport const MINUTES_PER_HOUR = 60;\n\nexport const HOURS_PER_DAY = 24;\n\nexport const MS_PER_SECOND = 1000;\n\nexport const DEFAULT_LRU_MAX_ENTRIES = 100;\n\nexport const COMPONENT_LOADER_MAX_ENTRIES = 100;\nexport const COMPONENT_LOADER_TTL_MS = 10 * SECONDS_PER_MINUTE * MS_PER_SECOND;\n\nexport const MDX_RENDERER_MAX_ENTRIES = 200;\nexport const MDX_RENDERER_TTL_MS = 10 * SECONDS_PER_MINUTE * MS_PER_SECOND;\n\nexport const RENDERER_CORE_MAX_ENTRIES = 100;\nexport const RENDERER_CORE_TTL_MS = 5 * SECONDS_PER_MINUTE * MS_PER_SECOND;\n\nexport const TSX_LAYOUT_MAX_ENTRIES = 50;\nexport const TSX_LAYOUT_TTL_MS = 10 * SECONDS_PER_MINUTE * MS_PER_SECOND;\n\nexport const DATA_FETCHING_MAX_ENTRIES = 200;\nexport const DATA_FETCHING_TTL_MS = 10 * SECONDS_PER_MINUTE * MS_PER_SECOND;\n\nexport const MDX_CACHE_TTL_PRODUCTION_MS = HOURS_PER_DAY * MINUTES_PER_HOUR * SECONDS_PER_MINUTE *\n MS_PER_SECOND;\nexport const MDX_CACHE_TTL_DEVELOPMENT_MS = 5 * SECONDS_PER_MINUTE * MS_PER_SECOND;\n\nexport const BUNDLE_CACHE_TTL_PRODUCTION_MS = HOURS_PER_DAY * MINUTES_PER_HOUR *\n SECONDS_PER_MINUTE * MS_PER_SECOND;\nexport const BUNDLE_CACHE_TTL_DEVELOPMENT_MS = 5 * SECONDS_PER_MINUTE * MS_PER_SECOND;\n\nexport const BUNDLE_MANIFEST_PROD_TTL_MS = 7 * HOURS_PER_DAY * MINUTES_PER_HOUR *\n SECONDS_PER_MINUTE * MS_PER_SECOND;\nexport const BUNDLE_MANIFEST_DEV_TTL_MS = MINUTES_PER_HOUR * SECONDS_PER_MINUTE * MS_PER_SECOND;\n\nexport const RSC_MANIFEST_CACHE_TTL_MS = 5000;\n\nexport const SERVER_ACTION_DEFAULT_TTL_SEC = MINUTES_PER_HOUR * SECONDS_PER_MINUTE;\n\nexport const DENO_KV_SAFE_SIZE_LIMIT_BYTES = 64_000;\n\nexport const HTTP_CACHE_SHORT_MAX_AGE_SEC = 60;\nexport const HTTP_CACHE_MEDIUM_MAX_AGE_SEC = 3600;\nexport const HTTP_CACHE_LONG_MAX_AGE_SEC = 31536000;\n\nexport const ONE_DAY_MS = HOURS_PER_DAY * MINUTES_PER_HOUR * SECONDS_PER_MINUTE * MS_PER_SECOND;\n\nexport const CACHE_CLEANUP_INTERVAL_MS = 60000;\n\nexport const LRU_DEFAULT_MAX_ENTRIES = 1000;\n\nexport const LRU_DEFAULT_MAX_SIZE_BYTES = 50 * 1024 * 1024;\n\nexport const CLEANUP_INTERVAL_MULTIPLIER = 2;\n", "{\n \"name\": \"veryfront\",\n \"version\": \"0.0.66\",\n \"nodeModulesDir\": \"auto\",\n \"exclude\": [\n \"npm/\",\n \"dist/\",\n \"coverage/\",\n \"scripts/\",\n \"examples/\",\n \"src/cli/templates/files/\",\n \"src/cli/templates/integrations/\"\n ],\n \"exports\": {\n \".\": \"./src/index.ts\",\n \"./cli\": \"./src/cli/main.ts\",\n \"./server\": \"./src/server/index.ts\",\n \"./middleware\": \"./src/middleware/index.ts\",\n \"./components\": \"./src/react/components/index.ts\",\n \"./data\": \"./src/data/index.ts\",\n \"./config\": \"./src/core/config/index.ts\",\n \"./platform\": \"./src/platform/index.ts\",\n \"./ai\": \"./src/ai/index.ts\",\n \"./ai/client\": \"./src/ai/client.ts\",\n \"./ai/react\": \"./src/ai/react/index.ts\",\n \"./ai/primitives\": \"./src/ai/react/primitives/index.ts\",\n \"./ai/components\": \"./src/ai/react/components/index.ts\",\n \"./ai/production\": \"./src/ai/production/index.ts\",\n \"./ai/dev\": \"./src/ai/dev/index.ts\",\n \"./ai/workflow\": \"./src/ai/workflow/index.ts\",\n \"./ai/workflow/react\": \"./src/ai/workflow/react/index.ts\",\n \"./oauth\": \"./src/core/oauth/index.ts\",\n \"./oauth/providers\": \"./src/core/oauth/providers/index.ts\",\n \"./oauth/handlers\": \"./src/core/oauth/handlers/index.ts\",\n \"./oauth/token-store\": \"./src/core/oauth/token-store/index.ts\"\n },\n \"imports\": {\n \"@veryfront\": \"./src/index.ts\",\n \"@veryfront/\": \"./src/\",\n \"@veryfront/ai\": \"./src/ai/index.ts\",\n \"@veryfront/ai/\": \"./src/ai/\",\n \"@veryfront/platform\": \"./src/platform/index.ts\",\n \"@veryfront/platform/\": \"./src/platform/\",\n \"@veryfront/types\": \"./src/core/types/index.ts\",\n \"@veryfront/types/\": \"./src/core/types/\",\n \"@veryfront/utils\": \"./src/core/utils/index.ts\",\n \"@veryfront/utils/\": \"./src/core/utils/\",\n \"@veryfront/middleware\": \"./src/middleware/index.ts\",\n \"@veryfront/middleware/\": \"./src/middleware/\",\n \"@veryfront/errors\": \"./src/core/errors/index.ts\",\n \"@veryfront/errors/\": \"./src/core/errors/\",\n \"@veryfront/config\": \"./src/core/config/index.ts\",\n \"@veryfront/config/\": \"./src/core/config/\",\n \"@veryfront/observability\": \"./src/observability/index.ts\",\n \"@veryfront/observability/\": \"./src/observability/\",\n \"@veryfront/routing\": \"./src/routing/index.ts\",\n \"@veryfront/routing/\": \"./src/routing/\",\n \"@veryfront/transforms\": \"./src/build/transforms/index.ts\",\n \"@veryfront/transforms/\": \"./src/build/transforms/\",\n \"@veryfront/data\": \"./src/data/index.ts\",\n \"@veryfront/data/\": \"./src/data/\",\n \"@veryfront/security\": \"./src/security/index.ts\",\n \"@veryfront/security/\": \"./src/security/\",\n \"@veryfront/components\": \"./src/react/components/index.ts\",\n \"@veryfront/react\": \"./src/react/index.ts\",\n \"@veryfront/react/\": \"./src/react/\",\n \"@veryfront/html\": \"./src/html/index.ts\",\n \"@veryfront/html/\": \"./src/html/\",\n \"@veryfront/rendering\": \"./src/rendering/index.ts\",\n \"@veryfront/rendering/\": \"./src/rendering/\",\n \"@veryfront/build\": \"./src/build/index.ts\",\n \"@veryfront/build/\": \"./src/build/\",\n \"@veryfront/server\": \"./src/server/index.ts\",\n \"@veryfront/server/\": \"./src/server/\",\n \"@veryfront/modules\": \"./src/module-system/index.ts\",\n \"@veryfront/modules/\": \"./src/module-system/\",\n \"@veryfront/compat/console\": \"./src/platform/compat/console/index.ts\",\n \"@veryfront/compat/\": \"./src/platform/compat/\",\n \"@veryfront/oauth\": \"./src/core/oauth/index.ts\",\n \"@veryfront/oauth/\": \"./src/core/oauth/\",\n \"std/\": \"https://deno.land/std@0.220.0/\",\n \"@std/path\": \"https://deno.land/std@0.220.0/path/mod.ts\",\n \"@std/testing/bdd.ts\": \"https://deno.land/std@0.220.0/testing/bdd.ts\",\n \"@std/expect\": \"https://deno.land/std@0.220.0/expect/mod.ts\",\n \"csstype\": \"https://esm.sh/csstype@3.2.3\",\n \"@types/react\": \"https://esm.sh/@types/react@18.3.27?deps=csstype@3.2.3\",\n \"@types/react-dom\": \"https://esm.sh/@types/react-dom@18.3.7?deps=csstype@3.2.3\",\n \"react\": \"https://esm.sh/react@18.3.1\",\n \"react-dom\": \"https://esm.sh/react-dom@18.3.1\",\n \"react-dom/server\": \"https://esm.sh/react-dom@18.3.1/server\",\n \"react-dom/client\": \"https://esm.sh/react-dom@18.3.1/client\",\n \"react/jsx-runtime\": \"https://esm.sh/react@18.3.1/jsx-runtime\",\n \"react/jsx-dev-runtime\": \"https://esm.sh/react@18.3.1/jsx-dev-runtime\",\n \"@mdx-js/mdx\": \"npm:@mdx-js/mdx@3.0.0\",\n \"@mdx-js/react\": \"npm:@mdx-js/react@3.0.0\",\n \"unist-util-visit\": \"npm:unist-util-visit@5.0.0\",\n \"mdast-util-to-string\": \"npm:mdast-util-to-string@4.0.0\",\n \"github-slugger\": \"npm:github-slugger@2.0.0\",\n \"remark-gfm\": \"npm:remark-gfm@4.0.1\",\n \"remark-frontmatter\": \"npm:remark-frontmatter@5.0.0\",\n \"rehype-highlight\": \"npm:rehype-highlight@7.0.2\",\n \"rehype-slug\": \"npm:rehype-slug@6.0.0\",\n \"esbuild\": \"https://deno.land/x/esbuild@v0.20.1/wasm.js\",\n \"esbuild/mod.js\": \"https://deno.land/x/esbuild@v0.20.1/mod.js\",\n \"es-module-lexer\": \"npm:es-module-lexer@1.5.0\",\n \"zod\": \"npm:zod@3.23.8\",\n \"mime-types\": \"npm:mime-types@2.1.35\",\n \"mdast\": \"npm:@types/mdast@4.0.3\",\n \"hast\": \"npm:@types/hast@3.0.3\",\n \"unist\": \"npm:@types/unist@3.0.2\",\n \"unified\": \"npm:unified@11.0.5\",\n \"ai\": \"https://esm.sh/ai@5.0.76?deps=react@18.3.1,react-dom@18.3.1\",\n \"ai/react\": \"https://esm.sh/@ai-sdk/react@2.0.1?deps=react@18.3.1,react-dom@18.3.1\",\n \"@ai-sdk/react\": \"https://esm.sh/@ai-sdk/react@2.0.1?deps=react@18.3.1,react-dom@18.3.1\",\n \"@ai-sdk/openai\": \"https://esm.sh/@ai-sdk/openai@2.0.1\",\n \"@ai-sdk/anthropic\": \"https://esm.sh/@ai-sdk/anthropic@2.0.1\",\n \"unocss\": \"https://esm.sh/unocss@0.59.0\",\n \"@unocss/core\": \"https://esm.sh/@unocss/core@0.59.0\",\n \"@unocss/preset-wind\": \"https://esm.sh/@unocss/preset-wind@0.59.0\",\n \"redis\": \"npm:redis\",\n \"pg\": \"npm:pg\",\n \"@opentelemetry/api\": \"npm:@opentelemetry/api@1\",\n \"@opentelemetry/core\": \"npm:@opentelemetry/core@1\"\n },\n \"compilerOptions\": {\n \"jsx\": \"react-jsx\",\n \"jsxImportSource\": \"react\",\n \"strict\": true,\n \"noImplicitAny\": true,\n \"noUncheckedIndexedAccess\": true,\n \"types\": [],\n \"lib\": [\n \"deno.window\",\n \"dom\",\n \"dom.iterable\",\n \"dom.asynciterable\",\n \"deno.ns\"\n ]\n },\n \"tasks\": {\n \"setup\": \"deno run --allow-all scripts/setup.ts\",\n \"dev\": \"deno run --allow-all --no-lock --unstable-net --unstable-worker-options src/cli/main.ts dev\",\n \"build\": \"deno compile --allow-all --output ../../bin/veryfront src/cli/main.ts\",\n \"build:npm\": \"deno run -A scripts/build-npm.ts\",\n \"release\": \"deno run -A scripts/release.ts\",\n \"test\": \"DENO_JOBS=1 deno test --parallel --fail-fast --allow-all --unstable-worker-options --unstable-net\",\n \"test:unit\": \"DENO_JOBS=1 deno test --parallel --allow-all --v8-flags=--max-old-space-size=8192 --ignore=tests --unstable-worker-options --unstable-net\",\n \"test:integration\": \"DENO_JOBS=1 deno test --parallel --fail-fast --allow-all tests --unstable-worker-options --unstable-net\",\n \"test:coverage\": \"rm -rf coverage && DENO_JOBS=1 deno test --parallel --fail-fast --allow-all --coverage=coverage --unstable-worker-options --unstable-net || exit 1\",\n \"test:coverage:unit\": \"rm -rf coverage && DENO_JOBS=1 deno test --parallel --fail-fast --allow-all --coverage=coverage --ignore=tests --unstable-worker-options --unstable-net || exit 1\",\n \"test:coverage:integration\": \"rm -rf coverage && DENO_JOBS=1 deno test --parallel --fail-fast --allow-all --coverage=coverage tests --unstable-worker-options --unstable-net || exit 1\",\n \"coverage:report\": \"deno coverage coverage --include=src/ --exclude=tests --exclude=src/**/*_test.ts --exclude=src/**/*_test.tsx --exclude=src/**/*.test.ts --exclude=src/**/*.test.tsx --lcov > coverage/lcov.info && deno run --allow-read scripts/check-coverage.ts 80\",\n \"coverage:html\": \"deno coverage coverage --include=src/ --exclude=tests --exclude=src/**/*_test.ts --exclude=src/**/*_test.tsx --exclude=src/**/*.test.ts --exclude=src/**/*.test.tsx --html\",\n \"lint\": \"DENO_NO_PACKAGE_JSON=1 deno lint src/\",\n \"fmt\": \"deno fmt src/\",\n \"typecheck\": \"deno check src/index.ts src/cli/main.ts src/server/index.ts src/routing/api/index.ts src/rendering/index.ts src/platform/index.ts src/platform/adapters/index.ts src/build/index.ts src/build/production-build/index.ts src/build/transforms/index.ts src/core/config/index.ts src/core/utils/index.ts src/data/index.ts src/security/index.ts src/middleware/index.ts src/server/handlers/dev/index.ts src/server/handlers/request/api/index.ts src/rendering/cache/index.ts src/rendering/cache/stores/index.ts src/rendering/rsc/actions/index.ts src/html/index.ts src/module-system/index.ts\",\n \"docs:check-links\": \"deno run -A scripts/check-doc-links.ts\",\n \"lint:ban-console\": \"deno run --allow-read scripts/ban-console.ts\",\n \"lint:ban-deep-imports\": \"deno run --allow-read scripts/ban-deep-imports.ts\",\n \"lint:ban-internal-root-imports\": \"deno run --allow-read scripts/ban-internal-root-imports.ts\",\n \"lint:check-awaits\": \"deno run --allow-read scripts/check-unawaited-promises.ts\",\n \"lint:platform\": \"deno run --allow-read scripts/lint-platform-agnostic.ts\",\n \"check:circular\": \"deno run -A jsr:@cunarist/deno-circular-deps src/index.ts\"\n },\n \"lint\": {\n \"include\": [\n \"src/**/*.ts\",\n \"src/**/*.tsx\"\n ],\n \"exclude\": [\n \"dist/\",\n \"coverage/\"\n ],\n \"rules\": {\n \"tags\": [\n \"recommended\"\n ],\n \"include\": [\n \"ban-untagged-todo\"\n ],\n \"exclude\": [\n \"no-explicit-any\",\n \"no-process-global\",\n \"no-console\"\n ]\n }\n },\n \"fmt\": {\n \"include\": [\n \"src/**/*.ts\",\n \"src/**/*.tsx\"\n ],\n \"exclude\": [\n \"dist/\",\n \"coverage/\"\n ],\n \"options\": {\n \"useTabs\": false,\n \"lineWidth\": 100,\n \"indentWidth\": 2,\n \"semiColons\": true,\n \"singleQuote\": false,\n \"proseWrap\": \"preserve\"\n }\n }\n}\n", "export const isDeno = typeof Deno !== \"undefined\";\nexport const isNode =\n typeof (globalThis as { process?: { versions?: { node?: string } } }).process !== \"undefined\" &&\n (globalThis as { process?: { versions?: { node?: string } } }).process?.versions?.node !==\n undefined;\nexport const isBun = typeof (globalThis as { Bun?: unknown }).Bun !== \"undefined\";\nexport const isCloudflare = typeof globalThis !== \"undefined\" && \"caches\" in globalThis &&\n \"WebSocketPair\" in globalThis;\n\n/**\n * Detect if running in Node.js (vs Deno)\n * Use this function instead of the constant when runtime detection needs to happen\n * at call time (e.g., when bundled with esbuild's __esm lazy initialization pattern)\n */\nexport function isNodeRuntime(): boolean {\n // deno-lint-ignore no-explicit-any\n const _global = globalThis as any;\n return typeof Deno === \"undefined\" && typeof _global.process !== \"undefined\" &&\n !!_global.process?.versions?.node;\n}\n", "import { isDeno as IS_DENO } from \"./runtime.ts\";\n\nconst nodeProcess = (globalThis as { process?: typeof import(\"node:process\") }).process;\nconst hasNodeProcess = !!nodeProcess?.versions?.node;\n\nexport function getArgs(): string[] {\n if (IS_DENO) {\n return Deno.args;\n }\n if (hasNodeProcess) {\n return nodeProcess!.argv.slice(2);\n }\n return [];\n}\n\nexport function exit(code?: number): never {\n if (IS_DENO) {\n Deno.exit(code);\n }\n if (hasNodeProcess) {\n nodeProcess!.exit(code);\n }\n throw new Error(\"exit() is not supported in this runtime\");\n}\n\nexport function cwd(): string {\n if (IS_DENO) {\n return Deno.cwd();\n }\n if (hasNodeProcess) {\n return nodeProcess!.cwd();\n }\n throw new Error(\"cwd() is not supported in this runtime\");\n}\n\nexport function chdir(directory: string): void {\n if (IS_DENO) {\n Deno.chdir(directory);\n } else {\n if (hasNodeProcess) {\n nodeProcess!.chdir(directory);\n return;\n }\n throw new Error(\"chdir() is not supported in this runtime\");\n }\n}\n\nexport function env(): Record<string, string> {\n if (IS_DENO) {\n return Deno.env.toObject();\n }\n if (hasNodeProcess) {\n return nodeProcess!.env as Record<string, string>;\n }\n return {};\n}\n\nexport function getEnv(key: string): string | undefined {\n if (IS_DENO) {\n return Deno.env.get(key);\n }\n if (hasNodeProcess) {\n return nodeProcess!.env[key];\n }\n return undefined;\n}\n\n/**\n * Get an environment variable or throw if not set\n * @throws Error if the environment variable is not set\n */\nexport function requireEnv(key: string): string {\n const value = getEnv(key);\n if (value === undefined) {\n throw new Error(`Required environment variable \"${key}\" is not set`);\n }\n return value;\n}\n\nexport function setEnv(key: string, value: string): void {\n if (IS_DENO) {\n Deno.env.set(key, value);\n } else {\n if (hasNodeProcess) {\n nodeProcess!.env[key] = value;\n return;\n }\n throw new Error(\"setEnv() is not supported in this runtime\");\n }\n}\n\nexport function deleteEnv(key: string): void {\n if (IS_DENO) {\n Deno.env.delete(key);\n } else {\n if (hasNodeProcess) {\n delete nodeProcess!.env[key];\n return;\n }\n throw new Error(\"deleteEnv() is not supported in this runtime\");\n }\n}\n\nexport function pid(): number {\n if (IS_DENO) {\n return Deno.pid;\n }\n if (hasNodeProcess) {\n return nodeProcess!.pid;\n }\n return 0;\n}\n\nexport function ppid(): number {\n if (IS_DENO && \"ppid\" in Deno) {\n return Deno.ppid || 0;\n }\n if (hasNodeProcess) {\n return nodeProcess!.ppid || 0;\n }\n return 0;\n}\n\nexport function memoryUsage(): {\n rss: number;\n heapTotal: number;\n heapUsed: number;\n external: number;\n} {\n if (IS_DENO) {\n const usage = Deno.memoryUsage();\n return {\n rss: usage.rss,\n heapTotal: usage.heapTotal,\n heapUsed: usage.heapUsed,\n external: usage.external,\n };\n }\n\n if (!hasNodeProcess) {\n throw new Error(\"memoryUsage() is not supported in this runtime\");\n }\n\n const usage = nodeProcess!.memoryUsage();\n return {\n rss: usage.rss,\n heapTotal: usage.heapTotal,\n heapUsed: usage.heapUsed,\n external: usage.external || 0,\n };\n}\n\n/**\n * Check if stdin is a TTY (terminal)\n */\nexport function isInteractive(): boolean {\n if (IS_DENO) {\n return Deno.stdin.isTerminal();\n }\n if (hasNodeProcess) {\n return nodeProcess!.stdin.isTTY ?? false;\n }\n return false;\n}\n\n/**\n * Get network interfaces\n */\nexport async function getNetworkInterfaces(): Promise<\n Array<{ name: string; address: string; family: \"IPv4\" | \"IPv6\" }>\n> {\n if (IS_DENO) {\n const interfaces = Deno.networkInterfaces();\n return interfaces.map((iface) => ({\n name: iface.name,\n address: iface.address,\n family: iface.family as \"IPv4\" | \"IPv6\",\n }));\n }\n\n if (!hasNodeProcess) {\n throw new Error(\"networkInterfaces() is not supported in this runtime\");\n }\n\n const os = await import(\"node:os\");\n const interfaces = os.networkInterfaces();\n const result: Array<{ name: string; address: string; family: \"IPv4\" | \"IPv6\" }> = [];\n\n for (const [name, addrs] of Object.entries(interfaces)) {\n if (!addrs) continue;\n for (const addr of addrs) {\n result.push({\n name,\n address: addr.address,\n family: addr.family as \"IPv4\" | \"IPv6\",\n });\n }\n }\n\n return result;\n}\n\n/**\n * Get runtime version string\n */\nexport function getRuntimeVersion(): string {\n if (IS_DENO) {\n return `Deno ${Deno.version.deno}`;\n }\n if (\"Bun\" in globalThis) {\n return `Bun ${(globalThis as unknown as { Bun: { version: string } }).Bun.version}`;\n }\n if (hasNodeProcess) {\n return `Node.js ${nodeProcess!.version}`;\n }\n return \"unknown\";\n}\n\n/**\n * Register a signal handler (SIGINT, SIGTERM) for graceful shutdown\n */\nexport function onSignal(signal: \"SIGINT\" | \"SIGTERM\", handler: () => void): void {\n if (IS_DENO) {\n Deno.addSignalListener(signal, handler);\n } else if (hasNodeProcess) {\n nodeProcess!.on(signal, handler);\n }\n}\n\n/**\n * Unreference a timer to prevent it from keeping the process alive\n */\nexport function unrefTimer(timerId: ReturnType<typeof setInterval>): void {\n if (IS_DENO) {\n Deno.unrefTimer(timerId as number);\n } else if (timerId && typeof timerId === \"object\" && \"unref\" in timerId) {\n (timerId as { unref: () => void }).unref();\n }\n}\n\n/**\n * Get the executable path of the current runtime\n */\nexport function execPath(): string {\n if (IS_DENO) {\n return Deno.execPath();\n }\n if (hasNodeProcess) {\n return nodeProcess!.execPath;\n }\n return \"\";\n}\n\n/**\n * Get process uptime in seconds\n * Returns OS uptime on Deno, process uptime on Node.js\n */\nexport function uptime(): number {\n if (IS_DENO) {\n // Deno.osUptime() returns system uptime in seconds\n return Deno.osUptime?.() ?? 0;\n }\n if (hasNodeProcess) {\n // process.uptime() returns process uptime in seconds\n return nodeProcess!.uptime?.() ?? 0;\n }\n return 0;\n}\n\n/**\n * Get stdout stream for writing\n * Returns null if not available (e.g., in browser/workers)\n */\nexport function getStdout(): { write: (data: string) => void } | null {\n if (IS_DENO) {\n const encoder = new TextEncoder();\n return {\n write: (data: string) => {\n Deno.stdout.writeSync(encoder.encode(data));\n },\n };\n }\n if (hasNodeProcess && nodeProcess!.stdout) {\n return {\n write: (data: string) => {\n nodeProcess!.stdout.write(data);\n },\n };\n }\n return null;\n}\n\n// Cached Node.js modules for synchronous prompt\nlet cachedNodeFs: typeof import(\"node:fs\") | null = null;\n\n/**\n * Synchronous prompt function that works across Deno and Node.js\n * Displays a message and reads user input from stdin\n */\nexport function promptSync(message?: string): string | null {\n if (IS_DENO) {\n // Deno has a built-in prompt() function\n return prompt(message);\n }\n\n if (hasNodeProcess) {\n // Print the message\n if (message) {\n nodeProcess!.stdout.write(message + \" \");\n }\n\n // Lazy load fs module\n if (!cachedNodeFs) {\n // Dynamic import converted to sync require for bundling\n // @ts-ignore - dynamic require for Node.js\n cachedNodeFs = globalThis.require?.(\"node:fs\") || null;\n if (!cachedNodeFs) {\n // Try alternative approach\n try {\n // @ts-ignore: __require is injected by bundlers for Node.js require\n cachedNodeFs = __require(\"node:fs\");\n } catch {\n return null;\n }\n }\n }\n\n if (!cachedNodeFs) {\n return null;\n }\n\n // Read synchronously using fs\n // This works by reading from file descriptor 0 (stdin)\n // Use Uint8Array for cross-platform compatibility\n const bufferSize = 1024;\n const uint8Array = new Uint8Array(bufferSize);\n let input = \"\";\n\n try {\n // Read from stdin (fd 0) synchronously\n const bytesRead = cachedNodeFs.readSync(0, uint8Array, 0, bufferSize, null);\n if (bytesRead > 0) {\n const decoder = new TextDecoder(\"utf-8\");\n input = decoder.decode(uint8Array.subarray(0, bytesRead)).trim();\n }\n } catch {\n // If stdin is not available or EOF, return null\n return null;\n }\n\n return input || null;\n }\n\n return null;\n}\n", "import denoConfig from \"../../../deno.json\" with { type: \"json\" };\nimport { getEnv } from \"../../platform/compat/process.ts\";\n\nexport const VERSION: string = getEnv(\"VERYFRONT_VERSION\") ||\n (typeof denoConfig.version === \"string\" ? denoConfig.version : \"0.0.0\");\n", "export const ESM_CDN_BASE = \"https://esm.sh\";\n\nexport const JSDELIVR_CDN_BASE = \"https://cdn.jsdelivr.net\";\n\nexport const DENO_STD_BASE = \"https://deno.land\";\n\nexport const REACT_VERSION_17 = \"17.0.2\";\nexport const REACT_VERSION_18_2 = \"18.2.0\";\nexport const REACT_VERSION_18_3 = \"18.3.1\";\nexport const REACT_VERSION_19_RC = \"19.0.0-rc.0\";\nexport const REACT_VERSION_19 = \"19.1.1\";\n\nexport const REACT_DEFAULT_VERSION = REACT_VERSION_18_3;\n\nexport function getReactCDNUrl(version: string = REACT_DEFAULT_VERSION): string {\n return `${ESM_CDN_BASE}/react@${version}`;\n}\n\nexport function getReactDOMCDNUrl(version: string = REACT_DEFAULT_VERSION): string {\n return `${ESM_CDN_BASE}/react-dom@${version}`;\n}\n\nexport function getReactDOMClientCDNUrl(version: string = REACT_DEFAULT_VERSION): string {\n return `${ESM_CDN_BASE}/react-dom@${version}/client`;\n}\n\nexport function getReactDOMServerCDNUrl(version: string = REACT_DEFAULT_VERSION): string {\n return `${ESM_CDN_BASE}/react-dom@${version}/server`;\n}\n\nexport function getReactJSXRuntimeCDNUrl(version: string = REACT_DEFAULT_VERSION): string {\n return `${ESM_CDN_BASE}/react@${version}/jsx-runtime`;\n}\n\nexport function getReactJSXDevRuntimeCDNUrl(version: string = REACT_DEFAULT_VERSION): string {\n return `${ESM_CDN_BASE}/react@${version}/jsx-dev-runtime`;\n}\n\nexport function getReactImportMap(version: string = REACT_DEFAULT_VERSION): Record<string, string> {\n return {\n react: getReactCDNUrl(version),\n \"react-dom\": getReactDOMCDNUrl(version),\n \"react-dom/client\": getReactDOMClientCDNUrl(version),\n \"react-dom/server\": getReactDOMServerCDNUrl(version),\n \"react/jsx-runtime\": getReactJSXRuntimeCDNUrl(version),\n \"react/jsx-dev-runtime\": getReactJSXDevRuntimeCDNUrl(version),\n };\n}\n\nexport const DEFAULT_ALLOWED_CDN_HOSTS = [ESM_CDN_BASE, DENO_STD_BASE];\n\nexport const DENO_STD_VERSION = \"0.220.0\";\n\nexport function getDenoStdNodeBase(): string {\n return `${DENO_STD_BASE}/std@${DENO_STD_VERSION}/node`;\n}\n\n// UnoCSS constants\nexport const UNOCSS_VERSION = \"0.59.0\";\n\nexport function getUnoCSSTailwindResetUrl(): string {\n return `${ESM_CDN_BASE}/@unocss/reset@${UNOCSS_VERSION}/tailwind.css`;\n}\n\n// Veryfront package version - derived from deno.json (single source of truth)\nexport { VERSION as VERYFRONT_VERSION } from \"../version.ts\";\n", "/**\n * Environment variable utilities\n *\n * Centralized utilities for checking environment flags.\n * This ensures consistent behavior across the entire codebase.\n */\n\n/**\n * Environment variable names used by Veryfront\n */\nexport const ENV_VARS = {\n DEBUG: \"VERYFRONT_DEBUG\",\n DEEP_INSPECT: \"VERYFRONT_DEEP_INSPECT\",\n CACHE_DIR: \"VERYFRONT_CACHE_DIR\",\n PORT: \"VERYFRONT_PORT\",\n VERSION: \"VERYFRONT_VERSION\",\n} as const;\n\n/**\n * Check if a debug environment variable value is truthy.\n * Accepts: \"1\", \"true\", \"yes\" (case-insensitive)\n *\n * @param value - The environment variable value to check\n * @returns true if the value indicates debug mode should be enabled\n */\nexport function isTruthyEnvValue(value: string | undefined): boolean {\n if (!value) return false;\n const normalized = value.toLowerCase().trim();\n return normalized === \"1\" || normalized === \"true\" || normalized === \"yes\";\n}\n\n/**\n * Check if debug mode is enabled via environment variable.\n * Works with RuntimeAdapter's env interface.\n *\n * @param env - Environment accessor object with get() method\n * @returns true if VERYFRONT_DEBUG is set to a truthy value\n */\nexport function isDebugEnabled(env: { get(key: string): string | undefined }): boolean {\n return isTruthyEnvValue(env.get(ENV_VARS.DEBUG));\n}\n\n/**\n * Check if deep inspect mode is enabled via environment variable.\n *\n * @param env - Environment accessor object with get() method\n * @returns true if VERYFRONT_DEEP_INSPECT is set to a truthy value\n */\nexport function isDeepInspectEnabled(env: { get(key: string): string | undefined }): boolean {\n return isTruthyEnvValue(env.get(ENV_VARS.DEEP_INSPECT));\n}\n\n/**\n * Check if either debug or deep inspect mode is enabled.\n *\n * @param env - Environment accessor object with get() method\n * @returns true if either debug flag is enabled\n */\nexport function isAnyDebugEnabled(env: { get(key: string): string | undefined }): boolean {\n return isDebugEnabled(env) || isDeepInspectEnabled(env);\n}\n", "export const HASH_SEED_DJB2 = 5381;\n\nexport const HASH_SEED_FNV1A = 2166136261;\n", "export const KB_IN_BYTES = 1024;\n\nexport const HTTP_MODULE_FETCH_TIMEOUT_MS = 2500;\n\nexport const HMR_RECONNECT_DELAY_MS = 1000;\n\nexport const HMR_RELOAD_DELAY_MS = 1000;\n\nexport const HMR_FILE_WATCHER_DEBOUNCE_MS = 100;\n\nexport const HMR_KEEP_ALIVE_INTERVAL_MS = 30000;\n\nexport const DASHBOARD_RECONNECT_DELAY_MS = 3000;\n\nexport const SERVER_FUNCTION_DEFAULT_TIMEOUT_MS = 30000;\n\nexport const PREFETCH_MAX_SIZE_BYTES = 200 * KB_IN_BYTES;\n\nexport const PREFETCH_DEFAULT_TIMEOUT_MS = 10000;\n\nexport const PREFETCH_DEFAULT_DELAY_MS = 200;\n\nexport const HTTP_OK = 200;\n\nexport const HTTP_NO_CONTENT = 204;\n\nexport const HTTP_CREATED = 201;\n\nexport const HTTP_REDIRECT_FOUND = 302;\n\nexport const HTTP_NOT_MODIFIED = 304;\n\nexport const HTTP_BAD_REQUEST = 400;\n\nexport const HTTP_UNAUTHORIZED = 401;\n\nexport const HTTP_FORBIDDEN = 403;\n\nexport const HTTP_NOT_FOUND = 404;\n\nexport const HTTP_METHOD_NOT_ALLOWED = 405;\n\nexport const HTTP_GONE = 410;\n\nexport const HTTP_PAYLOAD_TOO_LARGE = 413;\n\nexport const HTTP_URI_TOO_LONG = 414;\n\nexport const HTTP_TOO_MANY_REQUESTS = 429;\n\nexport const HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE = 431;\n\nexport const HTTP_SERVER_ERROR = 500;\n\nexport const HTTP_INTERNAL_SERVER_ERROR = 500;\n\nexport const HTTP_BAD_GATEWAY = 502;\n\nexport const HTTP_NOT_IMPLEMENTED = 501;\n\nexport const HTTP_UNAVAILABLE = 503;\n\nexport const HTTP_NETWORK_CONNECT_TIMEOUT = 599;\n\nexport const HTTP_STATUS_SUCCESS_MIN = 200;\n\nexport const HTTP_STATUS_REDIRECT_MIN = 300;\n\nexport const HTTP_STATUS_CLIENT_ERROR_MIN = 400;\n\nexport const HTTP_STATUS_SERVER_ERROR_MIN = 500;\n\nexport const HTTP_CONTENT_TYPES = {\n JS: \"application/javascript; charset=utf-8\",\n JSON: \"application/json; charset=utf-8\",\n HTML: \"text/html; charset=utf-8\",\n CSS: \"text/css; charset=utf-8\",\n TEXT: \"text/plain; charset=utf-8\",\n} as const;\n\nimport { MS_PER_SECOND, SECONDS_PER_MINUTE } from \"./cache.ts\";\n\nexport const MS_PER_MINUTE = 60000;\n\nexport { MS_PER_SECOND, SECONDS_PER_MINUTE };\n\nexport const HTTP_CONTENT_TYPE_IMAGE_PNG = \"image/png\";\n\nexport const HTTP_CONTENT_TYPE_IMAGE_JPEG = \"image/jpeg\";\n\nexport const HTTP_CONTENT_TYPE_IMAGE_WEBP = \"image/webp\";\n\nexport const HTTP_CONTENT_TYPE_IMAGE_AVIF = \"image/avif\";\n\nexport const HTTP_CONTENT_TYPE_IMAGE_SVG = \"image/svg+xml\";\n\nexport const HTTP_CONTENT_TYPE_IMAGE_GIF = \"image/gif\";\n\nexport const HTTP_CONTENT_TYPE_IMAGE_ICO = \"image/x-icon\";\n", "import { KB_IN_BYTES } from \"./http.ts\";\n\nexport const HMR_MAX_MESSAGE_SIZE_BYTES = 1024 * KB_IN_BYTES;\n\nexport const HMR_MAX_MESSAGES_PER_MINUTE = 100;\n\nexport const HMR_CLIENT_RELOAD_DELAY_MS = 3000;\n\nexport const HMR_PORT_OFFSET = 1;\n\nexport const HMR_RATE_LIMIT_WINDOW_MS = 60000;\n\nexport const HMR_CLOSE_NORMAL = 1000;\n\nexport const HMR_CLOSE_RATE_LIMIT = 1008;\n\nexport const HMR_CLOSE_MESSAGE_TOO_LARGE = 1009;\n\nexport const HMR_MESSAGE_TYPES = {\n CONNECTED: \"connected\",\n UPDATE: \"update\",\n RELOAD: \"reload\",\n PING: \"ping\",\n PONG: \"pong\",\n} as const;\n\nexport function isValidHMRMessageType(type: string): type is keyof typeof HMR_MESSAGE_TYPES {\n return Object.values(HMR_MESSAGE_TYPES).includes(\n type as typeof HMR_MESSAGE_TYPES[keyof typeof HMR_MESSAGE_TYPES],\n );\n}\n", "export const Z_INDEX_DEV_INDICATOR = 9998;\nexport const Z_INDEX_ERROR_OVERLAY = 9999;\n\nexport const BREAKPOINT_SM = 640;\nexport const BREAKPOINT_MD = 768;\nexport const BREAKPOINT_LG = 1024;\nexport const BREAKPOINT_XL = 1280;\n\nexport const PROSE_MAX_WIDTH = \"65ch\";\n", "export const DEFAULT_DEV_SERVER_PORT = 3000;\nexport const DEFAULT_REDIS_PORT = 6379;\nexport const DEFAULT_API_SERVER_PORT = 8080;\nexport const DEFAULT_PREVIEW_SERVER_PORT = 5000;\nexport const DEFAULT_METRICS_PORT = 9000;\n\nexport const BYTES_PER_KB = 1024;\nexport const BYTES_PER_MB = 1024 * 1024;\n\nexport const DEFAULT_IMAGE_THUMBNAIL_SIZE = 256;\nexport const DEFAULT_IMAGE_SMALL_SIZE = 512;\nexport const DEFAULT_IMAGE_LARGE_SIZE = 2048;\n\nexport const RESPONSIVE_IMAGE_WIDTH_XS = 320;\nexport const RESPONSIVE_IMAGE_WIDTH_SM = 640;\nexport const RESPONSIVE_IMAGE_WIDTH_MD = 1024;\nexport const RESPONSIVE_IMAGE_WIDTH_LG = 1920;\n\nexport const RESPONSIVE_IMAGE_WIDTHS = [\n RESPONSIVE_IMAGE_WIDTH_XS,\n RESPONSIVE_IMAGE_WIDTH_SM,\n RESPONSIVE_IMAGE_WIDTH_MD,\n RESPONSIVE_IMAGE_WIDTH_LG,\n] as const;\n\nexport const MAX_CHUNK_SIZE_KB = 4096;\n\nexport const MIN_PORT = 1;\n\nexport const MAX_PORT = 65535;\n\nexport const DEFAULT_SERVER_PORT = 8000;\n", "export const MAX_PATH_TRAVERSAL_DEPTH = 10;\n\nexport const FORBIDDEN_PATH_PATTERNS = [\n /\\0/, // Null bytes\n];\n\nexport const DIRECTORY_TRAVERSAL_PATTERN = /\\.\\.[\\/\\\\]/;\n\nexport const ABSOLUTE_PATH_PATTERN = /^[\\/\\\\]/;\n\nexport const MAX_PATH_LENGTH = 4096;\n\nexport const DEFAULT_MAX_STRING_LENGTH = 1000;\n", "/**\n * Default port for veryfront dev server.\n * This is the single source of truth for the default port.\n */\nexport const DEFAULT_PORT = 3000;\n\nexport const DEFAULT_TIMEOUT_MS = 5000;\n\nexport const SSR_TIMEOUT_MS = 10000;\n\nexport const SANDBOX_TIMEOUT_MS = 5000;\n\nexport const DEFAULT_CACHE_MAX_SIZE = 100;\n\nexport const defaultConfig = {\n server: {\n port: DEFAULT_PORT,\n hostname: \"0.0.0.0\",\n },\n\n timeouts: {\n default: DEFAULT_TIMEOUT_MS,\n api: 30000,\n ssr: SSR_TIMEOUT_MS,\n hmr: 30000,\n sandbox: SANDBOX_TIMEOUT_MS,\n },\n\n cache: {\n jit: {\n maxSize: DEFAULT_CACHE_MAX_SIZE,\n tempDirPrefix: \"vf-bundle-\",\n },\n },\n\n metrics: {\n ssrBoundaries: [5, 10, 25, 50, 75, 100, 250, 500, 750, 1000, 2500, 5000, 7500, 10000],\n },\n} as const;\n\nexport const DEFAULT_PREFETCH_DELAY_MS = 100;\n\nexport const DEFAULT_METRICS_COLLECT_INTERVAL_MS = 60000;\n\nexport const DURATION_HISTOGRAM_BOUNDARIES_MS = [\n 5,\n 10,\n 25,\n 50,\n 75,\n 100,\n 250,\n 500,\n 750,\n 1000,\n 2500,\n 5000,\n 7500,\n 10000,\n];\n\nexport const SIZE_HISTOGRAM_BOUNDARIES_KB = [\n 1,\n 5,\n 10,\n 25,\n 50,\n 100,\n 250,\n 500,\n 1000,\n 2500,\n 5000,\n 10000,\n];\n\nexport const DEFAULT_REDIS_SCAN_COUNT = 100;\n\nexport const DEFAULT_REDIS_BATCH_DELETE_SIZE = 1000;\n\nexport const PAGE_TRANSITION_DELAY_MS = 150;\n\nexport type DefaultConfig = typeof defaultConfig;\n", "/**\n * Centralized server endpoints and paths registry\n *\n * All internal veryfront URLs should be defined here as the single source of truth.\n * This prevents hardcoding URLs across the codebase and makes refactoring easier.\n */\n\n// Re-export DEFAULT_PORT from config/defaults.ts (the single source of truth)\nexport { DEFAULT_PORT } from \"@veryfront/config/defaults.ts\";\n\n/** Default port for development dashboard */\nexport const DEFAULT_DASHBOARD_PORT = 3002;\n\n/** Internal URL prefix for all veryfront endpoints */\nexport const INTERNAL_PREFIX = \"/_veryfront\" as const;\n\n/**\n * All internal veryfront URL path prefixes (directories)\n */\nexport const INTERNAL_PATH_PREFIXES = {\n /** React Server Components endpoints */\n RSC: `${INTERNAL_PREFIX}/rsc/`,\n /** File system access endpoints (base64 encoded paths) */\n FS: `${INTERNAL_PREFIX}/fs/`,\n /** Virtual module system */\n MODULES: `${INTERNAL_PREFIX}/modules/`,\n /** Generated page modules */\n PAGES: `${INTERNAL_PREFIX}/pages/`,\n /** Data JSON endpoints */\n DATA: `${INTERNAL_PREFIX}/data/`,\n /** Library modules (AI SDK, etc.) */\n LIB: `${INTERNAL_PREFIX}/lib/`,\n /** Chunk assets */\n CHUNKS: `${INTERNAL_PREFIX}/chunks/`,\n /** Client component modules */\n CLIENT: `${INTERNAL_PREFIX}/client/`,\n} as const;\n\n/**\n * Specific internal endpoint URLs\n */\nexport const INTERNAL_ENDPOINTS = {\n // Development endpoints\n HMR_RUNTIME: `${INTERNAL_PREFIX}/hmr-runtime.js`,\n HMR: `${INTERNAL_PREFIX}/hmr.js`,\n HYDRATE: `${INTERNAL_PREFIX}/hydrate.js`,\n ERROR_OVERLAY: `${INTERNAL_PREFIX}/error-overlay.js`,\n DEV_LOADER: `${INTERNAL_PREFIX}/dev-loader.js`,\n CLIENT_LOG: `${INTERNAL_PREFIX}/log`,\n\n // Production endpoints\n CLIENT_JS: `${INTERNAL_PREFIX}/client.js`,\n ROUTER_JS: `${INTERNAL_PREFIX}/router.js`,\n PREFETCH_JS: `${INTERNAL_PREFIX}/prefetch.js`,\n MANIFEST_JSON: `${INTERNAL_PREFIX}/manifest.json`,\n APP_JS: `${INTERNAL_PREFIX}/app.js`,\n\n // RSC endpoints\n RSC_CLIENT: `${INTERNAL_PREFIX}/rsc/client.js`,\n RSC_MANIFEST: `${INTERNAL_PREFIX}/rsc/manifest`,\n RSC_STREAM: `${INTERNAL_PREFIX}/rsc/stream`,\n RSC_PAYLOAD: `${INTERNAL_PREFIX}/rsc/payload`,\n RSC_RENDER: `${INTERNAL_PREFIX}/rsc/render`,\n RSC_PAGE: `${INTERNAL_PREFIX}/rsc/page`,\n RSC_MODULE: `${INTERNAL_PREFIX}/rsc/module`,\n RSC_DOM: `${INTERNAL_PREFIX}/rsc/dom.js`,\n RSC_HYDRATOR: `${INTERNAL_PREFIX}/rsc/hydrator.js`,\n RSC_HYDRATE_CLIENT: `${INTERNAL_PREFIX}/rsc/hydrate-client.js`,\n\n // Library module endpoints\n LIB_AI_REACT: `${INTERNAL_PREFIX}/lib/ai/react.js`,\n LIB_AI_COMPONENTS: `${INTERNAL_PREFIX}/lib/ai/components.js`,\n LIB_AI_PRIMITIVES: `${INTERNAL_PREFIX}/lib/ai/primitives.js`,\n} as const;\n\n/**\n * Build output directory paths (relative)\n */\nexport const BUILD_DIRS = {\n /** Main build output directory */\n ROOT: \"_veryfront\",\n /** Chunks directory */\n CHUNKS: \"_veryfront/chunks\",\n /** Data directory */\n DATA: \"_veryfront/data\",\n /** Assets directory */\n ASSETS: \"_veryfront/assets\",\n} as const;\n\n/**\n * Local project directory paths (relative to project root)\n * These are .gitignore'd directories for caching and temporary files\n */\nexport const PROJECT_DIRS = {\n /** Base veryfront internal directory */\n ROOT: \".veryfront\",\n /** Cache directory for build artifacts, transforms, etc. */\n CACHE: \".veryfront/cache\",\n /** KV store directory */\n KV: \".veryfront/kv\",\n /** Log files directory */\n LOGS: \".veryfront/logs\",\n /** Temporary files directory */\n TMP: \".veryfront/tmp\",\n} as const;\n\n/** Default cache directory path */\nexport const DEFAULT_CACHE_DIR = PROJECT_DIRS.CACHE;\n\n/**\n * Helper to check if a pathname is an internal veryfront endpoint\n */\nexport function isInternalEndpoint(pathname: string): boolean {\n return pathname.startsWith(INTERNAL_PREFIX + \"/\");\n}\n\n/**\n * Helper to check if a pathname is a static asset (has extension or is internal)\n */\nexport function isStaticAsset(pathname: string): boolean {\n return pathname.includes(\".\") || isInternalEndpoint(pathname);\n}\n\n/**\n * Normalize a chunk path to include the base prefix\n */\nexport function normalizeChunkPath(\n filename: string,\n basePath: string = INTERNAL_PATH_PREFIXES.CHUNKS,\n): string {\n if (filename.startsWith(\"/\")) {\n return filename;\n }\n return `${basePath.replace(/\\/$/, \"\")}/${filename}`;\n}\n\n// Re-export for backward compatibility\nexport const DEV_SERVER_ENDPOINTS = {\n HMR_RUNTIME: INTERNAL_ENDPOINTS.HMR_RUNTIME,\n ERROR_OVERLAY: INTERNAL_ENDPOINTS.ERROR_OVERLAY,\n} as const;\n", "export * from \"./build.ts\";\nexport * from \"./cache.ts\";\nexport * from \"./cdn.ts\";\nexport * from \"./env.ts\";\nexport * from \"./hash.ts\";\nexport * from \"./hmr.ts\";\nexport * from \"./html.ts\";\nexport * from \"./http.ts\";\nexport * from \"./network.ts\";\nexport * from \"./security.ts\";\nexport * from \"./server.ts\";\n", "/**\n * Project directory paths and file extensions\n *\n * For internal veryfront URL endpoints, see ./constants/server.ts\n */\n\nimport {\n BUILD_DIRS,\n INTERNAL_ENDPOINTS,\n INTERNAL_PATH_PREFIXES,\n INTERNAL_PREFIX,\n} from \"./constants/server.ts\";\n\nexport const PATHS = {\n PAGES_DIR: \"pages\",\n COMPONENTS_DIR: \"components\",\n PUBLIC_DIR: \"public\",\n STYLES_DIR: \"styles\",\n DIST_DIR: \"dist\",\n CONFIG_FILE: \"veryfront.config.js\",\n} as const;\n\n/**\n * @deprecated Use INTERNAL_PREFIX, INTERNAL_ENDPOINTS, INTERNAL_PATH_PREFIXES from ./constants/server.ts\n */\nexport const VERYFRONT_PATHS = {\n INTERNAL_PREFIX: INTERNAL_PREFIX,\n BUILD_DIR: BUILD_DIRS.ROOT,\n CHUNKS_DIR: BUILD_DIRS.CHUNKS,\n DATA_DIR: BUILD_DIRS.DATA,\n ASSETS_DIR: BUILD_DIRS.ASSETS,\n HMR_RUNTIME: INTERNAL_ENDPOINTS.HMR_RUNTIME,\n CLIENT_JS: INTERNAL_ENDPOINTS.CLIENT_JS,\n ROUTER_JS: INTERNAL_ENDPOINTS.ROUTER_JS,\n ERROR_OVERLAY: INTERNAL_ENDPOINTS.ERROR_OVERLAY,\n} as const;\n\nexport const FILE_EXTENSIONS = {\n MDX: [\".mdx\", \".md\"],\n SCRIPT: [\".tsx\", \".ts\", \".jsx\", \".js\"],\n STYLE: [\".css\", \".scss\", \".sass\"],\n ALL: [\".mdx\", \".md\", \".tsx\", \".ts\", \".jsx\", \".js\", \".css\"],\n} as const;\n\n// Re-export for convenience\nexport { BUILD_DIRS, INTERNAL_ENDPOINTS, INTERNAL_PATH_PREFIXES, INTERNAL_PREFIX };\n", "export async function computeHash(content: string): Promise<string> {\n const encoder = new TextEncoder();\n const data = encoder.encode(content);\n const hashBuffer = await crypto.subtle.digest(\"SHA-256\", data);\n const hashArray = Array.from(new Uint8Array(hashBuffer));\n return hashArray.map((b) => b.toString(16).padStart(2, \"0\")).join(\"\");\n}\n\nexport function getContentHash(content: string): Promise<string> {\n return computeHash(content);\n}\n\nexport function computeContentHash(content: string): Promise<string> {\n return computeHash(content);\n}\n\nexport interface BundleCode {\n code: string;\n css?: string;\n sourceMap?: string;\n}\n\nexport function computeCodeHash(code: BundleCode): Promise<string> {\n const combined = code.code + (code.css || \"\") + (code.sourceMap || \"\");\n return computeHash(combined);\n}\n\nexport function simpleHash(str: string): number {\n let hash = 0;\n for (let i = 0; i < str.length; i++) {\n const char = str.charCodeAt(i);\n hash = ((hash << 5) - hash) + char;\n hash = hash & hash;\n }\n return Math.abs(hash);\n}\n\nexport async function shortHash(content: string): Promise<string> {\n const fullHash = await computeHash(content);\n return fullHash.slice(0, 8);\n}\n", "export class MemoCache<V> {\n private cache = new Map<string, V>();\n\n get(key: string): V | undefined {\n return this.cache.get(key);\n }\n\n set(key: string, value: V): void {\n this.cache.set(key, value);\n }\n\n has(key: string): boolean {\n return this.cache.has(key);\n }\n\n clear(): void {\n this.cache.clear();\n }\n\n size(): number {\n return this.cache.size;\n }\n}\n\nexport function memoizeAsync<Args extends unknown[], Result>(\n fn: (...args: Args) => Promise<Result>,\n keyHasher: (...args: Args) => string,\n): (...args: Args) => Promise<Result> {\n const cache = new MemoCache<Result>();\n\n return async (...args: Args): Promise<Result> => {\n const key = keyHasher(...args);\n if (cache.has(key)) {\n return cache.get(key)!;\n }\n\n const result = await fn(...args);\n cache.set(key, result);\n return result;\n };\n}\n\nexport function memoize<Args extends unknown[], Result>(\n fn: (...args: Args) => Result,\n keyHasher: (...args: Args) => string,\n): (...args: Args) => Result {\n const cache = new MemoCache<Result>();\n\n return (...args: Args): Result => {\n const key = keyHasher(...args);\n if (cache.has(key)) {\n return cache.get(key)!;\n }\n\n const result = fn(...args);\n cache.set(key, result);\n return result;\n };\n}\n\n/**\n * FNV-1a hash algorithm for fast cache key generation.\n * 10-15x faster than JSON.stringify() and uses 70-80% less memory.\n *\n * @param values - Values to hash\n * @returns Hash string\n */\nexport function simpleHash(...values: unknown[]): string {\n const FNV_OFFSET_BASIS = 2166136261;\n const FNV_PRIME = 16777619;\n\n let hash = FNV_OFFSET_BASIS;\n\n for (const value of values) {\n const str = typeof value === \"string\" ? value : String(value);\n\n for (let i = 0; i < str.length; i++) {\n hash ^= str.charCodeAt(i);\n hash = Math.imul(hash, FNV_PRIME);\n }\n }\n\n // Convert to unsigned 32-bit and then to base-36 string\n return (hash >>> 0).toString(36);\n}\n", "import { logger } from \"./logger/logger.ts\";\n\nexport function normalizePath(pathname: string): string {\n pathname = pathname.replace(/\\\\+/g, \"/\").replace(/\\/\\.+\\//g, \"/\");\n\n if (pathname !== \"/\" && pathname.endsWith(\"/\")) {\n pathname = pathname.slice(0, -1);\n }\n\n return pathname;\n}\n\nexport function joinPath(a: string, b: string): string {\n return `${a.replace(/\\/$/, \"\")}/${b.replace(/^\\//, \"\")}`;\n}\n\nexport function isWithinDirectory(root: string, target: string): boolean {\n const normalizedRoot = normalizePath(root);\n const normalizedTarget = normalizePath(target);\n return normalizedTarget.startsWith(`${normalizedRoot}/`) || normalizedTarget === normalizedRoot;\n}\n\nexport function getExtension(path: string): string {\n const lastDot = path.lastIndexOf(\".\");\n if (lastDot === -1 || lastDot === path.length - 1) {\n return \"\";\n }\n return path.slice(lastDot);\n}\n\nexport function getDirectory(path: string): string {\n const normalized = normalizePath(path);\n const lastSlash = normalized.lastIndexOf(\"/\");\n return lastSlash <= 0 ? \"/\" : normalized.slice(0, lastSlash);\n}\n\nexport function hasHashedFilename(path: string): boolean {\n return /\\.[a-f0-9]{8,}\\./.test(path);\n}\n\nexport function isAbsolutePath(path: string): boolean {\n return path.startsWith(\"/\") || /^[A-Za-z]:[\\\\/]/.test(path);\n}\n\nexport function toBase64Url(s: string): string {\n const b64 = btoa(s);\n return b64.replaceAll(\"+\", \"-\").replaceAll(\"/\", \"_\").replaceAll(\"=\", \"\");\n}\n\nexport function fromBase64Url(encoded: string): string {\n const b64 = encoded.replaceAll(\"-\", \"+\").replaceAll(\"_\", \"/\");\n const pad = b64.length % 4 === 2 ? \"==\" : b64.length % 4 === 3 ? \"=\" : \"\";\n try {\n return atob(b64 + pad);\n } catch (error) {\n logger.debug(`Failed to decode base64url string \"${encoded}\":`, error);\n return \"\";\n }\n}\n", "import { logger } from \"./logger/logger.ts\";\n\nexport function formatBytes(bytes: number): string {\n if (bytes === 0) return \"0 Bytes\";\n\n const absBytes = Math.abs(bytes);\n\n if (absBytes < 1) {\n return `${absBytes} Bytes`;\n }\n\n const k = 1024;\n const sizes = [\"Bytes\", \"KB\", \"MB\", \"GB\", \"TB\"];\n const i = Math.floor(Math.log(absBytes) / Math.log(k));\n\n const index = Math.max(0, Math.min(i, sizes.length - 1));\n\n return `${parseFloat((absBytes / Math.pow(k, index)).toFixed(2))} ${sizes[index]}`;\n}\n\nexport function estimateSize(value: unknown): number {\n if (value === null || value === undefined) return 8;\n\n switch (typeof value) {\n case \"boolean\":\n return 4;\n case \"number\":\n return 8;\n case \"string\":\n return value.length * 2; // UTF-16\n case \"function\":\n return 0; // Functions not cached\n case \"object\":\n return estimateObjectSize(value);\n default:\n return 32;\n }\n}\n\nexport function estimateSizeWithCircularHandling(value: unknown): number {\n const seen = new WeakSet();\n const encoder = new TextEncoder();\n\n const json = JSON.stringify(value, (_key, val) => {\n if (typeof val === \"object\" && val !== null) {\n if (seen.has(val as object)) return undefined;\n seen.add(val as object);\n\n if (val instanceof Map) {\n return { __type: \"Map\", entries: Array.from(val.entries()) };\n }\n if (val instanceof Set) {\n return { __type: \"Set\", values: Array.from(val.values()) };\n }\n }\n\n if (typeof val === \"function\") return undefined;\n\n if (val instanceof Uint8Array) {\n return { __type: \"Uint8Array\", length: val.length };\n }\n\n return val;\n });\n\n return encoder.encode(json ?? \"\").length;\n}\n\nfunction estimateObjectSize(value: object): number {\n if (value instanceof ArrayBuffer) return value.byteLength;\n\n if (\n value instanceof Uint8Array || value instanceof Uint16Array ||\n value instanceof Uint32Array || value instanceof Int8Array ||\n value instanceof Int16Array || value instanceof Int32Array\n ) {\n return value.byteLength;\n }\n\n try {\n return JSON.stringify(value).length * 2;\n } catch (error) {\n logger.debug(\"Failed to estimate size of non-serializable object:\", error);\n return 1024; // Default estimate for non-serializable\n }\n}\n\nexport function formatDuration(ms: number): string {\n if (ms < 1000) return `${ms}ms`;\n if (ms < 60000) return `${(ms / 1000).toFixed(1)}s`;\n if (ms < 3600000) return `${Math.floor(ms / 60000)}m ${Math.floor((ms % 60000) / 1000)}s`;\n return `${Math.floor(ms / 3600000)}h ${Math.floor((ms % 3600000) / 60000)}m`;\n}\n\nexport function formatNumber(num: number): string {\n return num.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, \",\");\n}\n\nexport function truncateString(str: string, maxLength: number): string {\n if (str.length <= maxLength) return str;\n return str.slice(0, maxLength - 3) + \"...\";\n}\n", "import { serverLogger as logger } from \"./logger/index.ts\";\n\nexport interface BundleMetadata {\n hash: string;\n codeHash: string;\n size: number;\n compiledAt: number;\n source: string;\n mode: \"development\" | \"production\";\n meta?: {\n type?: \"mdx\" | \"component\" | \"layout\" | \"provider\";\n depsHash?: string;\n reactVersion?: string;\n };\n}\n\nexport interface BundleCode {\n code: string;\n sourceMap?: string;\n css?: string;\n}\n\nexport interface BundleManifestStore {\n getBundleMetadata(key: string): Promise<BundleMetadata | undefined>;\n\n setBundleMetadata(key: string, metadata: BundleMetadata, ttlMs?: number): Promise<void>;\n\n getBundleCode(hash: string): Promise<BundleCode | undefined>;\n\n setBundleCode(hash: string, code: BundleCode, ttlMs?: number): Promise<void>;\n\n deleteBundle(key: string): Promise<void>;\n\n invalidateSource(source: string): Promise<number>;\n\n clear(): Promise<void>;\n\n isAvailable(): Promise<boolean>;\n\n getStats(): Promise<{\n totalBundles: number;\n totalSize: number;\n oldestBundle?: number;\n newestBundle?: number;\n }>;\n}\n\nexport class InMemoryBundleManifestStore implements BundleManifestStore {\n private metadata = new Map<string, { value: BundleMetadata; expiry?: number }>();\n private code = new Map<string, { value: BundleCode; expiry?: number }>();\n private sourceIndex = new Map<string, Set<string>>();\n\n getBundleMetadata(key: string): Promise<BundleMetadata | undefined> {\n const entry = this.metadata.get(key);\n if (!entry) return Promise.resolve(undefined);\n if (entry.expiry && Date.now() > entry.expiry) {\n this.metadata.delete(key);\n return Promise.resolve(undefined);\n }\n return Promise.resolve(entry.value);\n }\n\n setBundleMetadata(key: string, metadata: BundleMetadata, ttlMs?: number): Promise<void> {\n const expiry = ttlMs ? Date.now() + ttlMs : undefined;\n this.metadata.set(key, { value: metadata, expiry });\n\n if (!this.sourceIndex.has(metadata.source)) {\n this.sourceIndex.set(metadata.source, new Set());\n }\n this.sourceIndex.get(metadata.source)!.add(key);\n return Promise.resolve();\n }\n\n getBundleCode(hash: string): Promise<BundleCode | undefined> {\n const entry = this.code.get(hash);\n if (!entry) return Promise.resolve(undefined);\n if (entry.expiry && Date.now() > entry.expiry) {\n this.code.delete(hash);\n return Promise.resolve(undefined);\n }\n return Promise.resolve(entry.value);\n }\n\n setBundleCode(hash: string, code: BundleCode, ttlMs?: number): Promise<void> {\n const expiry = ttlMs ? Date.now() + ttlMs : undefined;\n this.code.set(hash, { value: code, expiry });\n return Promise.resolve();\n }\n\n async deleteBundle(key: string): Promise<void> {\n const metadata = await this.getBundleMetadata(key);\n this.metadata.delete(key);\n if (metadata) {\n this.code.delete(metadata.codeHash);\n const sourceKeys = this.sourceIndex.get(metadata.source);\n if (sourceKeys) {\n sourceKeys.delete(key);\n if (sourceKeys.size === 0) {\n this.sourceIndex.delete(metadata.source);\n }\n }\n }\n }\n\n async invalidateSource(source: string): Promise<number> {\n const keys = this.sourceIndex.get(source);\n if (!keys) return 0;\n\n let count = 0;\n for (const key of Array.from(keys)) {\n await this.deleteBundle(key);\n count++;\n }\n this.sourceIndex.delete(source);\n return count;\n }\n\n clear(): Promise<void> {\n this.metadata.clear();\n this.code.clear();\n this.sourceIndex.clear();\n return Promise.resolve();\n }\n\n isAvailable(): Promise<boolean> {\n return Promise.resolve(true);\n }\n\n getStats(): Promise<{\n totalBundles: number;\n totalSize: number;\n oldestBundle?: number;\n newestBundle?: number;\n }> {\n let totalSize = 0;\n let oldest: number | undefined;\n let newest: number | undefined;\n\n for (const { value } of this.metadata.values()) {\n totalSize += value.size;\n if (!oldest || value.compiledAt < oldest) oldest = value.compiledAt;\n if (!newest || value.compiledAt > newest) newest = value.compiledAt;\n }\n\n return Promise.resolve({\n totalBundles: this.metadata.size,\n totalSize,\n oldestBundle: oldest,\n newestBundle: newest,\n });\n }\n}\n\nlet manifestStore: BundleManifestStore = new InMemoryBundleManifestStore();\n\nexport function setBundleManifestStore(store: BundleManifestStore): void {\n manifestStore = store;\n logger.info(\"[bundle-manifest] Bundle manifest store configured\", {\n type: store.constructor.name,\n });\n}\n\nexport function getBundleManifestStore(): BundleManifestStore {\n return manifestStore;\n}\n\nexport { computeCodeHash, computeContentHash } from \"./hash-utils.ts\";\n", "import type { RuntimeAdapter } from \"@veryfront/platform/adapters/base.ts\";\nimport type { VeryfrontConfig } from \"@veryfront/config\";\nimport { serverLogger as logger } from \"./logger/index.ts\";\nimport {\n type BundleManifestStore,\n InMemoryBundleManifestStore,\n setBundleManifestStore,\n} from \"./bundle-manifest.ts\";\nimport { BUNDLE_MANIFEST_DEV_TTL_MS, BUNDLE_MANIFEST_PROD_TTL_MS } from \"./constants/cache.ts\";\n\nexport async function initializeBundleManifest(\n config: VeryfrontConfig,\n mode: \"development\" | \"production\",\n adapter?: RuntimeAdapter,\n): Promise<void> {\n const manifestConfig = config.cache?.bundleManifest;\n const enabled = manifestConfig?.enabled ?? mode === \"production\";\n\n if (!enabled) {\n logger.info(\"[bundle-manifest] Bundle manifest disabled\");\n setBundleManifestStore(new InMemoryBundleManifestStore());\n return;\n }\n\n const envType = adapter?.env.get(\"VERYFRONT_BUNDLE_MANIFEST_TYPE\");\n const storeType = manifestConfig?.type || envType || \"memory\";\n\n logger.info(\"[bundle-manifest] Initializing bundle manifest\", {\n type: storeType,\n mode,\n });\n\n try {\n let store: BundleManifestStore;\n\n switch (storeType) {\n case \"redis\": {\n const { RedisBundleManifestStore } = await import(\"./bundle-manifest-redis.ts\");\n const redisUrl = manifestConfig?.redisUrl ||\n adapter?.env.get(\"VERYFRONT_BUNDLE_MANIFEST_REDIS_URL\");\n store = new RedisBundleManifestStore(\n {\n url: redisUrl,\n keyPrefix: manifestConfig?.keyPrefix,\n },\n adapter,\n );\n\n const available = await store.isAvailable();\n if (!available) {\n logger.warn(\"[bundle-manifest] Redis not available, falling back to in-memory\");\n store = new InMemoryBundleManifestStore();\n } else {\n logger.info(\"[bundle-manifest] Redis store initialized\");\n }\n break;\n }\n\n case \"kv\": {\n const { KVBundleManifestStore } = await import(\"./bundle-manifest-kv.ts\");\n store = new KVBundleManifestStore({\n keyPrefix: manifestConfig?.keyPrefix,\n });\n\n const available = await store.isAvailable();\n if (!available) {\n logger.warn(\"[bundle-manifest] KV not available, falling back to in-memory\");\n store = new InMemoryBundleManifestStore();\n } else {\n logger.info(\"[bundle-manifest] KV store initialized\");\n }\n break;\n }\n\n case \"memory\":\n default: {\n store = new InMemoryBundleManifestStore();\n logger.info(\"[bundle-manifest] In-memory store initialized\");\n break;\n }\n }\n\n setBundleManifestStore(store);\n\n try {\n const stats = await store.getStats();\n logger.info(\"[bundle-manifest] Store statistics\", stats);\n } catch (error) {\n logger.debug(\"[bundle-manifest] Failed to get stats\", { error });\n }\n } catch (error) {\n logger.error(\"[bundle-manifest] Failed to initialize store, using in-memory fallback\", {\n error,\n });\n setBundleManifestStore(new InMemoryBundleManifestStore());\n }\n}\n\nexport function getBundleManifestTTL(\n config: VeryfrontConfig,\n mode: \"development\" | \"production\",\n): number | undefined {\n const manifestConfig = config.cache?.bundleManifest;\n if (manifestConfig?.ttl) {\n return manifestConfig.ttl;\n }\n\n if (mode === \"production\") {\n return BUNDLE_MANIFEST_PROD_TTL_MS;\n } else {\n return BUNDLE_MANIFEST_DEV_TTL_MS;\n }\n}\n\nexport async function warmupBundleManifest(\n store: BundleManifestStore,\n keys: string[],\n): Promise<void> {\n logger.info(\"[bundle-manifest] Warming up cache\", { keys: keys.length });\n\n let loaded = 0;\n let failed = 0;\n\n for (const key of keys) {\n try {\n const metadata = await store.getBundleMetadata(key);\n if (metadata) {\n await store.getBundleCode(metadata.codeHash);\n loaded++;\n }\n } catch (error) {\n logger.debug(\"[bundle-manifest] Failed to warm up key\", { key, error });\n failed++;\n }\n }\n\n logger.info(\"[bundle-manifest] Cache warmup complete\", { loaded, failed });\n}\n", "declare const process: { env: Record<string, string | undefined> } | undefined;\nimport { getEnv } from \"../../platform/compat/process.ts\";\n\n/**\n * Checks if React Server Components (RSC) are enabled.\n *\n * Priority order:\n * 1. Config file (config.experimental.rsc)\n * 2. Environment variables (VERYFRONT_EXPERIMENTAL_RSC=1)\n * 3. Default (false)\n *\n * @param config - Optional config object to check first\n * @returns true if RSC is enabled, false otherwise\n */\nexport function isRSCEnabled(config?: { experimental?: { rsc?: boolean } }): boolean {\n // 1. Check config first (highest priority)\n if (config?.experimental?.rsc !== undefined) {\n return config.experimental.rsc;\n }\n\n // 2. Fallback to environment variables (backward compatibility)\n return getEnv(\"VERYFRONT_EXPERIMENTAL_RSC\") === \"1\";\n}\n", "/**\n * Platform detection utilities\n */\n\nimport { isDeno } from \"../../platform/compat/runtime.ts\";\nimport { execPath } from \"../../platform/compat/process.ts\";\n\n/**\n * Detect if the code is running in a compiled Deno binary\n * @returns true if running in a compiled binary, false otherwise\n */\nexport function isCompiledBinary(): boolean {\n if (!isDeno) return false;\n\n try {\n const path = execPath();\n return path.includes(\"veryfront\");\n } catch {\n return false;\n }\n}\n", "export * from \"./runtime-guards.ts\";\n\nexport * from \"./logger/index.ts\";\n\nexport * from \"./constants/index.ts\";\nexport { VERSION } from \"./version.ts\";\n\nexport * from \"./paths.ts\";\n\nexport {\n type BundleCode as HashBundleCode, // Alias to avoid conflict with bundle-manifest\n computeCodeHash,\n computeContentHash,\n computeHash,\n getContentHash,\n shortHash,\n simpleHash,\n simpleHash as numericHash, // Alias to avoid conflict with memoize\n} from \"./hash-utils.ts\";\n\nexport {\n MemoCache,\n memoize,\n memoizeAsync,\n simpleHash as memoizeHash, // Alias to distinguish from hash-utils version\n} from \"./memoize.ts\";\n\nexport * from \"./path-utils.ts\";\n\nexport * from \"./format-utils.ts\";\n\nexport * from \"./bundle-manifest.ts\";\nexport * from \"./bundle-manifest-init.ts\";\n\nexport * from \"./feature-flags.ts\";\n\nexport { isCompiledBinary } from \"./platform.ts\";\n", "export interface BuildContext {\n file?: string;\n line?: number;\n column?: number;\n moduleId?: string;\n phase?: \"parse\" | \"transform\" | \"bundle\" | \"optimize\";\n}\n\nexport interface APIContext {\n endpoint?: string;\n method?: string;\n statusCode?: number;\n headers?: Record<string, string>;\n}\n\nexport interface RenderContext {\n component?: string;\n route?: string;\n phase?: \"server\" | \"client\" | \"hydration\";\n props?: unknown;\n}\n\nexport interface ConfigContext {\n configFile?: string;\n field?: string;\n value?: unknown;\n expected?: string;\n}\n\nexport interface AgentContext {\n agentId?: string;\n intent?: string;\n timeout?: number;\n}\n\nexport interface FileContext {\n path?: string;\n operation?: \"read\" | \"write\" | \"delete\" | \"mkdir\";\n permissions?: string;\n}\n\nexport interface NetworkContext {\n url?: string;\n timeout?: number;\n retryCount?: number;\n}\n\nexport type VeryfrontError =\n | { type: \"build\"; message: string; context?: BuildContext }\n | { type: \"api\"; message: string; context?: APIContext }\n | { type: \"render\"; message: string; context?: RenderContext }\n | { type: \"config\"; message: string; context?: ConfigContext }\n | { type: \"agent\"; message: string; context?: AgentContext }\n | { type: \"file\"; message: string; context?: FileContext }\n | { type: \"network\"; message: string; context?: NetworkContext }\n | { type: \"permission\"; message: string; context?: FileContext }\n | { type: \"not_supported\"; message: string; feature?: string };\n\nexport function createError(error: VeryfrontError): VeryfrontError {\n return error;\n}\n\nexport function isBuildError(\n error: VeryfrontError,\n): error is Extract<VeryfrontError, { type: \"build\" }> {\n return error.type === \"build\";\n}\n\nexport function isAPIError(\n error: VeryfrontError,\n): error is Extract<VeryfrontError, { type: \"api\" }> {\n return error.type === \"api\";\n}\n\nexport function isRenderError(\n error: VeryfrontError,\n): error is Extract<VeryfrontError, { type: \"render\" }> {\n return error.type === \"render\";\n}\n\nexport function isConfigError(\n error: VeryfrontError,\n): error is Extract<VeryfrontError, { type: \"config\" }> {\n return error.type === \"config\";\n}\n\nexport function isAgentError(\n error: VeryfrontError,\n): error is Extract<VeryfrontError, { type: \"agent\" }> {\n return error.type === \"agent\";\n}\n\nexport function isFileError(\n error: VeryfrontError,\n): error is Extract<VeryfrontError, { type: \"file\" }> {\n return error.type === \"file\";\n}\n\nexport function isNetworkError(\n error: VeryfrontError,\n): error is Extract<VeryfrontError, { type: \"network\" }> {\n return error.type === \"network\";\n}\n\nexport function toError(veryfrontError: VeryfrontError): Error {\n const error = new Error(veryfrontError.message);\n error.name = `VeryfrontError[${veryfrontError.type}]`;\n Object.defineProperty(error, \"context\", {\n value: veryfrontError,\n enumerable: false,\n configurable: true,\n });\n return error;\n}\n\nexport function fromError(error: unknown): VeryfrontError | null {\n if (error && typeof error === \"object\" && \"context\" in error) {\n // Safe access after 'in' check\n const context = (error as Record<string, unknown>).context;\n if (\n context &&\n typeof context === \"object\" &&\n \"type\" in context &&\n \"message\" in context\n ) {\n return context as VeryfrontError;\n }\n }\n return null;\n}\n\nexport function logError(\n error: VeryfrontError,\n logger?: { error: (msg: string, ...args: unknown[]) => void },\n): void {\n const log = logger || console;\n const context = \"context\" in error ? error.context || {} : {};\n log.error(`[${error.type}] ${error.message}`, context);\n}\n", "import { z } from \"zod\";\nimport type { VeryfrontConfig } from \"./types.ts\";\nimport { type ConfigContext, createError, toError } from \"../errors/veryfront-error.ts\";\n\nconst corsSchema = z.union([z.boolean(), z.object({ origin: z.string().optional() }).strict()]);\n\nexport const veryfrontConfigSchema = z\n .object({\n title: z.string().optional(),\n description: z.string().optional(),\n experimental: z.object({\n esmLayouts: z.boolean().optional(),\n precompileMDX: z.boolean().optional(),\n }).partial().optional(),\n router: z.enum([\"app\", \"pages\"]).optional(),\n defaultLayout: z.string().optional(),\n theme: z\n .object({ colors: z.record(z.string()).optional() })\n .partial()\n .optional(),\n build: z\n .object({\n outDir: z.string().optional(),\n trailingSlash: z.boolean().optional(),\n esbuild: z\n .object({\n wasmURL: z.string().url().optional(),\n worker: z.boolean().optional(),\n })\n .partial()\n .optional(),\n })\n .partial()\n .optional(),\n cache: z\n .object({\n dir: z.string().optional(),\n bundleManifest: z\n .object({\n type: z.enum([\"redis\", \"kv\", \"memory\"]).optional(),\n redisUrl: z.string().optional(),\n keyPrefix: z.string().optional(),\n ttl: z.number().int().positive().optional(),\n enabled: z.boolean().optional(),\n })\n .partial()\n .optional(),\n })\n .partial()\n .optional(),\n dev: z\n .object({\n port: z.number().int().positive().optional(),\n host: z.string().optional(),\n open: z.boolean().optional(),\n hmr: z.boolean().optional(),\n components: z.array(z.string()).optional(),\n })\n .partial()\n .optional(),\n resolve: z\n .object({\n importMap: z\n .object({\n imports: z.record(z.string()).optional(),\n scopes: z.record(z.record(z.string())).optional(),\n })\n .partial()\n .optional(),\n })\n .partial()\n .optional(),\n security: z\n .object({\n csp: z.record(z.array(z.string())).optional(),\n remoteHosts: z.array(z.string().url()).optional(),\n cors: corsSchema.optional(),\n coop: z.enum([\"same-origin\", \"same-origin-allow-popups\", \"unsafe-none\"]).optional(),\n corp: z.enum([\"same-origin\", \"same-site\", \"cross-origin\"]).optional(),\n coep: z.enum([\"require-corp\", \"unsafe-none\"]).optional(),\n })\n .partial()\n .optional(),\n middleware: z\n .object({\n custom: z.array(z.function()).optional(),\n })\n .partial()\n .optional(),\n theming: z\n .object({\n brandName: z.string().optional(),\n logoHtml: z.string().optional(),\n })\n .partial()\n .optional(),\n assetPipeline: z\n .object({\n images: z\n .object({\n enabled: z.boolean().optional(),\n formats: z.array(z.enum([\"webp\", \"avif\", \"jpeg\", \"png\"])).optional(),\n sizes: z.array(z.number().int().positive()).optional(),\n quality: z.number().int().min(1).max(100).optional(),\n inputDir: z.string().optional(),\n outputDir: z.string().optional(),\n preserveOriginal: z.boolean().optional(),\n })\n .partial()\n .optional(),\n css: z\n .object({\n enabled: z.boolean().optional(),\n minify: z.boolean().optional(),\n autoprefixer: z.boolean().optional(),\n purge: z.boolean().optional(),\n criticalCSS: z.boolean().optional(),\n inputDir: z.string().optional(),\n outputDir: z.string().optional(),\n browsers: z.array(z.string()).optional(),\n purgeContent: z.array(z.string()).optional(),\n sourceMap: z.boolean().optional(),\n })\n .partial()\n .optional(),\n })\n .partial()\n .optional(),\n observability: z\n .object({\n tracing: z\n .object({\n enabled: z.boolean().optional(),\n exporter: z.enum([\"jaeger\", \"zipkin\", \"otlp\", \"console\"]).optional(),\n endpoint: z.string().optional(),\n serviceName: z.string().optional(),\n sampleRate: z.number().min(0).max(1).optional(),\n })\n .partial()\n .optional(),\n metrics: z\n .object({\n enabled: z.boolean().optional(),\n exporter: z.enum([\"prometheus\", \"otlp\", \"console\"]).optional(),\n endpoint: z.string().optional(),\n prefix: z.string().optional(),\n collectInterval: z.number().int().positive().optional(),\n })\n .partial()\n .optional(),\n })\n .partial()\n .optional(),\n fs: z\n .object({\n type: z.enum([\"local\", \"veryfront-api\", \"memory\"]).optional(),\n local: z\n .object({\n baseDir: z.string().optional(),\n })\n .partial()\n .optional(),\n veryfront: z\n .object({\n apiBaseUrl: z.string().url(),\n apiToken: z.string(),\n projectSlug: z.string(),\n cache: z\n .object({\n enabled: z.boolean().optional(),\n ttl: z.number().int().positive().optional(),\n maxSize: z.number().int().positive().optional(),\n })\n .partial()\n .optional(),\n retry: z\n .object({\n maxRetries: z.number().int().min(0).optional(),\n initialDelay: z.number().int().positive().optional(),\n maxDelay: z.number().int().positive().optional(),\n })\n .partial()\n .optional(),\n })\n .partial()\n .optional(),\n memory: z\n .object({\n files: z.record(z.union([z.string(), z.instanceof(Uint8Array)])).optional(),\n })\n .partial()\n .optional(),\n })\n .partial()\n .optional(),\n client: z\n .object({\n moduleResolution: z.enum([\"cdn\", \"self-hosted\", \"bundled\"]).optional(),\n cdn: z\n .object({\n provider: z.enum([\"esm.sh\", \"unpkg\", \"jsdelivr\"]).optional(),\n versions: z\n .union([\n z.literal(\"auto\"),\n z.object({\n react: z.string().optional(),\n veryfront: z.string().optional(),\n }),\n ])\n .optional(),\n })\n .partial()\n .optional(),\n })\n .partial()\n .optional(),\n })\n .partial();\n\nexport type VeryfrontConfigInput = z.input<typeof veryfrontConfigSchema>;\n\nexport function validateVeryfrontConfig(input: unknown): VeryfrontConfig {\n const parsed = veryfrontConfigSchema.safeParse(input);\n if (!parsed.success) {\n const first = parsed.error.issues[0];\n const path = first?.path?.length ? first.path.join(\".\") : \"<root>\";\n const expected = first?.message || String(first);\n let hint = \"\";\n if (String(path).includes(\"security.cors\")) {\n hint = \" Expected boolean or { origin?: string }.\";\n }\n\n const context: ConfigContext = {\n field: path,\n expected: expected + hint,\n value: input,\n };\n\n throw toError(\n createError({\n type: \"config\",\n message: `Invalid veryfront.config at ${path}: ${expected}.${hint}`,\n context,\n }),\n );\n }\n return parsed.data as VeryfrontConfig;\n}\n\nexport function findUnknownTopLevelKeys(input: Record<string, unknown>): string[] {\n const known = new Set([\n \"title\",\n \"description\",\n \"experimental\",\n \"router\",\n \"defaultLayout\",\n \"theme\",\n \"build\",\n \"cache\",\n \"dev\",\n \"resolve\",\n \"security\",\n \"middleware\",\n \"theming\",\n \"assetPipeline\",\n \"observability\",\n \"fs\",\n \"client\",\n ]);\n return Object.keys(input).filter((k) => !known.has(k));\n}\n", "import type { VeryfrontConfig } from \"./types.ts\";\nimport { findUnknownTopLevelKeys, validateVeryfrontConfig } from \"./schema.ts\";\nimport { join } from \"std/path/mod.ts\";\nimport type { RuntimeAdapter } from \"@veryfront/platform/adapters/base.ts\";\nimport { serverLogger } from \"@veryfront/utils/logger/logger.ts\";\nimport { getReactImportMap, REACT_DEFAULT_VERSION } from \"@veryfront/utils/constants/cdn.ts\";\nimport { DEFAULT_CACHE_DIR } from \"@veryfront/utils/constants/server.ts\";\nimport { DEFAULT_PORT } from \"./defaults.ts\";\n\nexport type { VeryfrontConfig } from \"./types.ts\";\n\nfunction getDefaultImportMapForConfig() {\n return { imports: getReactImportMap(REACT_DEFAULT_VERSION) };\n}\n\nconst DEFAULT_CONFIG: Partial<VeryfrontConfig> = {\n title: \"Veryfront App\",\n description: \"Built with Veryfront\",\n experimental: {\n esmLayouts: true,\n },\n router: undefined,\n defaultLayout: undefined,\n theme: {\n colors: {\n primary: \"#3B82F6\",\n },\n },\n build: {\n outDir: \"dist\",\n trailingSlash: false,\n esbuild: {\n wasmURL: \"https://deno.land/x/esbuild@v0.20.1/esbuild.wasm\",\n worker: false,\n },\n },\n cache: {\n dir: DEFAULT_CACHE_DIR,\n render: {\n type: \"memory\",\n ttl: undefined,\n maxEntries: 500,\n kvPath: undefined,\n redisUrl: undefined,\n redisKeyPrefix: undefined,\n },\n },\n dev: {\n port: DEFAULT_PORT,\n host: \"localhost\",\n open: false,\n },\n resolve: {\n importMap: getDefaultImportMapForConfig(),\n },\n client: {\n moduleResolution: \"cdn\",\n cdn: {\n provider: \"esm.sh\",\n versions: \"auto\",\n },\n },\n};\n\nconst configCacheByProject = new Map<string, { revision: number; config: VeryfrontConfig }>();\nlet cacheRevision = 0;\n\nfunction validateCorsConfig(userConfig: unknown): void {\n if (!userConfig || typeof userConfig !== \"object\") {\n return;\n }\n const config = userConfig as Record<string, unknown>;\n const security = config.security as Record<string, unknown> | undefined;\n const cors = security?.cors;\n if (!cors || typeof cors !== \"object\" || Array.isArray(cors)) {\n return;\n }\n\n const corsObj = cors as Record<string, unknown>;\n const origin = corsObj.origin;\n if (origin !== undefined && typeof origin !== \"string\") {\n throw new ConfigValidationError(\n \"security.cors.origin must be a string. Expected boolean or { origin?: string }\",\n );\n }\n}\n\nfunction validateConfigShape(userConfig: unknown): void {\n validateVeryfrontConfig(userConfig);\n const unknown = typeof userConfig === \"object\" && userConfig\n ? findUnknownTopLevelKeys(userConfig as Record<string, unknown>)\n : [];\n if (unknown.length > 0) {\n serverLogger.warn(`Unknown config keys: ${unknown.join(\", \")}. These will be ignored.`);\n }\n}\n\nfunction mergeConfigs(userConfig: Partial<VeryfrontConfig>): VeryfrontConfig {\n const merged: VeryfrontConfig = {\n ...DEFAULT_CONFIG,\n ...userConfig,\n dev: {\n ...DEFAULT_CONFIG.dev,\n ...userConfig.dev,\n },\n theme: {\n ...DEFAULT_CONFIG.theme,\n ...userConfig.theme,\n },\n build: {\n ...DEFAULT_CONFIG.build,\n ...userConfig.build,\n },\n cache: {\n ...DEFAULT_CONFIG.cache,\n ...userConfig.cache,\n },\n resolve: {\n ...DEFAULT_CONFIG.resolve,\n ...userConfig.resolve,\n },\n client: {\n ...DEFAULT_CONFIG.client,\n ...userConfig.client,\n cdn: {\n ...DEFAULT_CONFIG.client?.cdn,\n ...userConfig.client?.cdn,\n },\n },\n } as VeryfrontConfig;\n\n if (merged.resolve) {\n const defaultMap = DEFAULT_CONFIG.resolve?.importMap;\n const userMap = userConfig.resolve?.importMap;\n\n if (defaultMap || userMap) {\n merged.resolve.importMap = {\n imports: {\n ...(defaultMap?.imports ?? {}),\n ...(userMap?.imports ?? {}),\n },\n scopes: {\n ...(defaultMap?.scopes ?? {}),\n ...(userMap?.scopes ?? {}),\n },\n };\n }\n }\n\n return merged;\n}\n\nclass ConfigValidationError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"ConfigValidationError\";\n }\n}\n\nasync function loadAndMergeConfig(\n configPath: string,\n projectDir: string,\n): Promise<VeryfrontConfig | null> {\n try {\n const configUrl = `file://${configPath}?t=${Date.now()}-${crypto.randomUUID()}`;\n const configModule = await import(configUrl);\n const userConfig = configModule.default || configModule;\n\n if (userConfig === null || typeof userConfig !== \"object\" || Array.isArray(userConfig)) {\n throw new ConfigValidationError(\n `Expected object, received ${userConfig === null ? \"null\" : typeof userConfig}`,\n );\n }\n\n validateCorsConfig(userConfig);\n validateConfigShape(userConfig);\n\n const merged = mergeConfigs(userConfig);\n configCacheByProject.set(projectDir, { revision: cacheRevision, config: merged });\n return merged;\n } catch (error) {\n if (error instanceof ConfigValidationError) {\n throw error;\n }\n\n if (error instanceof Error && error.message.startsWith(\"Invalid veryfront.config\")) {\n throw error;\n }\n\n throw error;\n }\n}\n\nexport async function getConfig(\n projectDir: string,\n adapter: RuntimeAdapter,\n): Promise<VeryfrontConfig> {\n const cached = configCacheByProject.get(projectDir);\n if (cached && cached.revision === cacheRevision) return cached.config;\n\n const configFiles = [\"veryfront.config.js\", \"veryfront.config.ts\", \"veryfront.config.mjs\"];\n\n for (const configFile of configFiles) {\n const configPath = join(projectDir, configFile);\n\n const exists = await adapter.fs.exists(configPath);\n if (!exists) continue;\n\n try {\n const merged = await loadAndMergeConfig(configPath, projectDir);\n if (merged) return merged;\n } catch (error) {\n if (error instanceof ConfigValidationError) {\n throw error;\n }\n\n if (error instanceof Error && error.message.startsWith(\"Invalid veryfront.config\")) {\n throw error;\n }\n\n // Only log at debug level - this is expected when .ts exists but .js is tried first\n const errorMessage = error instanceof Error ? error.message : String(error);\n serverLogger.debug(`[CONFIG] Failed to load ${configFile}, trying next config file:`, {\n error: errorMessage,\n });\n\n continue;\n }\n }\n\n const defaultConfig = DEFAULT_CONFIG as VeryfrontConfig;\n configCacheByProject.set(projectDir, { revision: cacheRevision, config: defaultConfig });\n return defaultConfig;\n}\n\nexport function clearConfigCache() {\n configCacheByProject.clear();\n cacheRevision++;\n}\n", "import type { VeryfrontConfig } from \"./types.ts\";\nimport { createError, toError } from \"../../core/errors/veryfront-error.ts\";\nimport { getEnv } from \"../../platform/compat/process.ts\";\n\nexport function defineConfig(config: VeryfrontConfig): VeryfrontConfig {\n return config;\n}\n\nexport function defineConfigWithEnv(\n factory: (env: string) => VeryfrontConfig,\n): VeryfrontConfig {\n const env = getEnv(\"NODE_ENV\") || \"development\";\n return factory(env);\n}\n\nexport function mergeConfigs(\n ...configs: Partial<VeryfrontConfig>[]\n): VeryfrontConfig {\n const merged: Partial<VeryfrontConfig> = {};\n\n for (const config of configs) {\n Object.assign(merged, config);\n }\n\n return merged as VeryfrontConfig;\n}\n\nexport async function validateConfig(config: unknown): Promise<void> {\n if (!config || typeof config !== \"object\") {\n throw toError(createError({\n type: \"config\",\n message: \"Configuration must be an object\",\n }));\n }\n\n const cfg = config as Record<string, unknown>;\n\n if (cfg.dev && typeof cfg.dev === \"object\") {\n const dev = cfg.dev as Record<string, unknown>;\n if (dev.port !== undefined) {\n const { MIN_PORT, MAX_PORT } = await import(\"../utils/constants/network.ts\");\n if (typeof dev.port !== \"number\" || dev.port < MIN_PORT || dev.port > MAX_PORT) {\n throw toError(createError({\n type: \"config\",\n message: `dev.port must be a number between ${MIN_PORT} and ${MAX_PORT}`,\n context: {\n field: \"dev.port\",\n value: dev.port,\n expected: `number between ${MIN_PORT} and ${MAX_PORT}`,\n },\n }));\n }\n }\n }\n\n if (cfg.build && typeof cfg.build === \"object\") {\n const build = cfg.build as Record<string, unknown>;\n if (build.outDir !== undefined && typeof build.outDir !== \"string\") {\n throw toError(createError({\n type: \"config\",\n message: \"build.outDir must be a string\",\n context: { field: \"build.outDir\", value: build.outDir, expected: \"string\" },\n }));\n }\n }\n}\n", "export const LOCALHOST = {\n IPV4: \"127.0.0.1\",\n IPV6: \"::1\",\n HOSTNAME: \"localhost\",\n} as const;\n\nexport const HTTP_DEFAULTS = {\n PORT: 3000,\n HOST: \"localhost\",\n PROD_HOST: \"0.0.0.0\",\n} as const;\n\nexport const REDIS_DEFAULTS = {\n URL: \"redis://127.0.0.1:6379\",\n PORT: 6379,\n HOST: \"127.0.0.1\",\n} as const;\n\nexport const DEV_LOCALHOST_ORIGINS = [\n \"http://localhost\",\n \"http://127.0.0.1\",\n \"https://localhost\",\n \"https://127.0.0.1\",\n] as const;\n\nexport const DEV_LOCALHOST_CSP = {\n WS: \"ws://localhost:* wss://localhost:*\",\n HTTP: \"http://localhost\",\n} as const;\n\nexport const LOCALHOST_URLS = {\n HTTP: \"http://localhost\",\n HTTPS: \"https://localhost\",\n HTTP_IPV4: \"http://127.0.0.1\",\n HTTPS_IPV4: \"https://127.0.0.1\",\n} as const;\n\nexport function buildLocalhostUrl(\n port: number,\n protocol: \"http\" | \"https\" = \"http\",\n): string {\n return `${protocol}://${LOCALHOST.HOSTNAME}:${port}`;\n}\n\nexport function buildIpv4Url(\n port: number,\n protocol: \"http\" | \"https\" = \"http\",\n): string {\n return `${protocol}://${LOCALHOST.IPV4}:${port}`;\n}\n", "export { clearConfigCache, getConfig } from \"./loader.ts\";\n\nexport { defineConfig } from \"./define-config.ts\";\n\nexport type { VeryfrontConfig } from \"./types.ts\";\n\nexport {\n findUnknownTopLevelKeys,\n validateVeryfrontConfig,\n veryfrontConfigSchema,\n} from \"./schema.ts\";\n\nexport {\n DEFAULT_CACHE_MAX_SIZE,\n DEFAULT_METRICS_COLLECT_INTERVAL_MS,\n DEFAULT_PORT,\n DEFAULT_PREFETCH_DELAY_MS,\n DEFAULT_REDIS_BATCH_DELETE_SIZE,\n DEFAULT_REDIS_SCAN_COUNT,\n DEFAULT_TIMEOUT_MS,\n type DefaultConfig,\n defaultConfig,\n DURATION_HISTOGRAM_BOUNDARIES_MS,\n PAGE_TRANSITION_DELAY_MS,\n SANDBOX_TIMEOUT_MS,\n SIZE_HISTOGRAM_BOUNDARIES_KB,\n SSR_TIMEOUT_MS,\n} from \"./defaults.ts\";\n\nexport {\n buildIpv4Url,\n buildLocalhostUrl,\n DEV_LOCALHOST_CSP,\n DEV_LOCALHOST_ORIGINS,\n HTTP_DEFAULTS,\n LOCALHOST,\n LOCALHOST_URLS,\n REDIS_DEFAULTS,\n} from \"./network-defaults.ts\";\n", "import { createError, toError } from \"../../core/errors/veryfront-error.ts\";\nimport type {\n DirEntry,\n EnvironmentAdapter,\n FileChangeEvent,\n FileChangeKind,\n FileInfo,\n FileSystemAdapter,\n FileWatcher,\n RuntimeAdapter,\n RuntimeFeatures,\n ServeOptions,\n Server,\n ServerAdapter,\n ShellAdapter,\n WatchOptions,\n WebSocketUpgrade,\n} from \"./base.ts\";\nimport { DEFAULT_PORT } from \"@veryfront/config\";\nimport { serverLogger } from \"@veryfront/utils\";\n\nclass DenoFileSystemAdapter implements FileSystemAdapter {\n async readFile(path: string): Promise<string> {\n return await Deno.readTextFile(path);\n }\n\n async readFileBytes(path: string): Promise<Uint8Array> {\n return await Deno.readFile(path);\n }\n\n async writeFile(path: string, content: string): Promise<void> {\n await Deno.writeTextFile(path, content);\n }\n\n async exists(path: string): Promise<boolean> {\n try {\n await Deno.stat(path);\n return true;\n } catch (_error) {\n return false;\n }\n }\n\n async *readDir(path: string): AsyncIterable<DirEntry> {\n for await (const entry of Deno.readDir(path)) {\n yield {\n name: entry.name,\n isFile: entry.isFile,\n isDirectory: entry.isDirectory,\n isSymlink: entry.isSymlink,\n };\n }\n }\n\n async stat(path: string): Promise<FileInfo> {\n const stat = await Deno.stat(path);\n return {\n size: stat.size,\n isFile: stat.isFile,\n isDirectory: stat.isDirectory,\n isSymlink: stat.isSymlink,\n mtime: stat.mtime,\n };\n }\n\n async mkdir(path: string, options?: { recursive?: boolean }): Promise<void> {\n await Deno.mkdir(path, options);\n }\n\n async remove(path: string, options?: { recursive?: boolean }): Promise<void> {\n await Deno.remove(path, options);\n }\n\n async makeTempDir(prefix: string): Promise<string> {\n return await Deno.makeTempDir({ prefix });\n }\n\n watch(paths: string | string[], options?: WatchOptions): FileWatcher {\n const pathArray = Array.isArray(paths) ? paths : [paths];\n const recursive = options?.recursive ?? true;\n const signal = options?.signal;\n\n const watcher = Deno.watchFs(pathArray, { recursive });\n let closed = false;\n\n const denoIterator = watcher[Symbol.asyncIterator]();\n\n const mapEventKind = (kind: string): FileChangeKind => {\n switch (kind) {\n case \"create\":\n return \"create\";\n case \"modify\":\n return \"modify\";\n case \"remove\":\n return \"delete\";\n default:\n return \"any\";\n }\n };\n\n const iterator: AsyncIterator<FileChangeEvent> = {\n async next(): Promise<IteratorResult<FileChangeEvent>> {\n if (closed || signal?.aborted) {\n return { done: true, value: undefined };\n }\n\n try {\n const result = await denoIterator.next();\n if (result.done) {\n return { done: true, value: undefined };\n }\n\n return {\n done: false,\n value: {\n kind: mapEventKind(result.value.kind),\n paths: result.value.paths,\n },\n };\n } catch (error) {\n if (closed || signal?.aborted) {\n return { done: true, value: undefined };\n }\n throw error;\n }\n },\n\n async return(): Promise<IteratorResult<FileChangeEvent>> {\n closed = true;\n if (denoIterator.return) {\n await denoIterator.return();\n }\n return { done: true, value: undefined };\n },\n };\n\n const cleanup = () => {\n if (closed) return;\n closed = true;\n try {\n if (\"close\" in watcher && typeof watcher.close === \"function\") {\n watcher.close();\n }\n } catch (error) {\n serverLogger.debug(\"[Deno] Filesystem watcher cleanup failed\", { error });\n }\n };\n\n if (signal) {\n signal.addEventListener(\"abort\", cleanup);\n }\n\n return {\n [Symbol.asyncIterator]() {\n return iterator;\n },\n close: cleanup,\n };\n }\n}\n\nclass DenoEnvironmentAdapter implements EnvironmentAdapter {\n get(key: string): string | undefined {\n return Deno.env.get(key);\n }\n\n set(key: string, value: string): void {\n Deno.env.set(key, value);\n }\n\n toObject(): Record<string, string> {\n return Deno.env.toObject();\n }\n}\n\nclass DenoServerAdapter implements ServerAdapter {\n upgradeWebSocket(request: Request): WebSocketUpgrade {\n const { socket, response } = Deno.upgradeWebSocket(request);\n return { socket, response };\n }\n}\n\nclass DenoShellAdapter implements ShellAdapter {\n statSync(path: string): { isFile: boolean; isDirectory: boolean } {\n try {\n const stat = Deno.statSync(path);\n return {\n isFile: stat.isFile,\n isDirectory: stat.isDirectory,\n };\n } catch (error) {\n throw toError(createError({\n type: \"file\",\n message: `Failed to stat file: ${error}`,\n }));\n }\n }\n\n readFileSync(path: string): string {\n try {\n return Deno.readTextFileSync(path);\n } catch (error) {\n throw toError(createError({\n type: \"file\",\n message: `Failed to read file: ${error}`,\n }));\n }\n }\n}\n\nclass DenoServer implements Server {\n constructor(\n private server: Deno.HttpServer,\n private hostname: string,\n private port: number,\n private abortController?: AbortController,\n ) {}\n\n async stop(): Promise<void> {\n try {\n if (this.abortController) {\n this.abortController.abort();\n }\n\n await this.server.shutdown();\n } catch (error) {\n serverLogger.debug(\"[Deno] Server shutdown failed\", { error });\n }\n }\n\n get addr() {\n return { hostname: this.hostname, port: this.port };\n }\n}\n\nexport class DenoAdapter implements RuntimeAdapter {\n readonly id = \"deno\" as const;\n readonly name = \"deno\";\n /** @deprecated Use `id` instead */\n readonly platform = \"deno\" as const;\n\n fs = new DenoFileSystemAdapter();\n env = new DenoEnvironmentAdapter();\n server = new DenoServerAdapter();\n shell = new DenoShellAdapter();\n\n readonly capabilities = {\n typescript: true,\n jsx: true,\n http2: true,\n websocket: true,\n workers: true,\n fileWatching: true,\n shell: true,\n kvStore: true, // Deno KV available\n writableFs: true,\n };\n\n /** @deprecated Use `capabilities` instead */\n readonly features: RuntimeFeatures = {\n websocket: true,\n http2: true,\n workers: true,\n jsx: true,\n typescript: true,\n };\n\n serve(\n handler: (request: Request) => Promise<Response> | Response,\n options: ServeOptions = {},\n ): Promise<Server> {\n const { port = DEFAULT_PORT, hostname = \"localhost\", onListen } = options;\n\n const controller = new AbortController();\n const signal = options.signal || controller.signal;\n\n const server = Deno.serve({\n port,\n hostname,\n signal,\n handler: async (request, _info) => {\n try {\n return await handler(request);\n } catch (error) {\n const { serverLogger } = await import(\"@veryfront/utils\");\n serverLogger.error(\"Request handler error:\", error);\n return new Response(\"Internal Server Error\", { status: 500 });\n }\n },\n onListen: (params) => {\n onListen?.({ hostname: params.hostname, port: params.port });\n },\n });\n\n const controllerToPass = options.signal ? undefined : controller;\n return Promise.resolve(new DenoServer(server, hostname, port, controllerToPass));\n }\n}\n\nexport const denoAdapter = new DenoAdapter();\n", "import type { FileChangeEvent, FileChangeKind, FileWatcher } from \"./base.ts\";\nimport { join } from \"node:path\";\n\nexport async function setupNodeFsWatcher(\n path: string,\n options: {\n recursive: boolean;\n closed: () => boolean;\n signal: AbortSignal | undefined;\n eventQueue: FileChangeEvent[];\n getResolver: () => ((value: IteratorResult<FileChangeEvent>) => void) | null;\n setResolver: (resolver: ((value: IteratorResult<FileChangeEvent>) => void) | null) => void;\n watchers: Array<import(\"node:fs\").FSWatcher>;\n onError: (error: Error, path: string) => void;\n },\n): Promise<void> {\n try {\n const fs = await import(\"node:fs\");\n const fsPromises = await import(\"node:fs/promises\");\n\n const exists = await fsPromises.access(path).then(() => true).catch(() => false);\n if (!exists) return;\n\n const watcher = fs.watch(path, { recursive: options.recursive }, (eventType, filename) => {\n if (options.closed() || options.signal?.aborted) return;\n\n const kind: FileChangeKind = eventType === \"change\" ? \"modify\" : \"any\";\n const fullPath = filename ? join(path, filename) : path;\n\n enqueueWatchEvent(\n { kind, paths: [fullPath] },\n options.eventQueue,\n options.getResolver,\n options.setResolver,\n );\n });\n\n watcher.on(\"error\", (error: Error) => {\n if (!options.closed() && !options.signal?.aborted) {\n options.onError(error, path);\n }\n });\n\n options.watchers.push(watcher);\n } catch (error) {\n options.onError(error as Error, path);\n }\n}\n\nexport function createWatcherIterator(\n eventQueue: FileChangeEvent[],\n _getResolver: () => ((value: IteratorResult<FileChangeEvent>) => void) | null,\n setResolver: (r: ((value: IteratorResult<FileChangeEvent>) => void) | null) => void,\n isClosed: () => boolean,\n isAborted: () => boolean,\n): AsyncIterator<FileChangeEvent> {\n return {\n next(): Promise<IteratorResult<FileChangeEvent>> {\n if (isClosed() || isAborted()) {\n return Promise.resolve({ done: true, value: undefined });\n }\n\n if (eventQueue.length > 0) {\n const event = eventQueue.shift()!;\n return Promise.resolve({ done: false, value: event });\n }\n\n return new Promise((resolve) => {\n if (isClosed() || isAborted()) {\n resolve({ done: true, value: undefined });\n return;\n }\n setResolver(resolve);\n });\n },\n\n return(): Promise<IteratorResult<FileChangeEvent>> {\n return Promise.resolve({ done: true, value: undefined });\n },\n };\n}\n\nexport function enqueueWatchEvent(\n event: FileChangeEvent,\n eventQueue: FileChangeEvent[],\n getResolver: () => ((value: IteratorResult<FileChangeEvent>) => void) | null,\n setResolver: (resolver: ((value: IteratorResult<FileChangeEvent>) => void) | null) => void,\n): void {\n const resolver = getResolver();\n if (resolver) {\n resolver({ done: false, value: event });\n setResolver(null);\n } else {\n eventQueue.push(event);\n }\n}\n\nexport function createFileWatcher(\n iterator: AsyncIterator<FileChangeEvent>,\n cleanup: () => void,\n): FileWatcher {\n return {\n [Symbol.asyncIterator]() {\n return iterator;\n },\n close: cleanup,\n };\n}\n", "import type { DirEntry, FileInfo, FileSystemAdapter, FileWatcher, WatchOptions } from \"../base.ts\";\nimport { createFileWatcher, createWatcherIterator, setupNodeFsWatcher } from \"../shared-watcher.ts\";\nimport { serverLogger } from \"@veryfront/utils\";\nimport type { FileChangeEvent } from \"../base.ts\";\n\nexport class NodeFileSystemAdapter implements FileSystemAdapter {\n async readFile(path: string): Promise<string> {\n const fs = await import(\"node:fs/promises\");\n return await fs.readFile(path, \"utf-8\");\n }\n\n async readFileBytes(path: string): Promise<Uint8Array> {\n const fs = await import(\"node:fs/promises\");\n const buffer = await fs.readFile(path);\n return buffer instanceof Uint8Array ? buffer : new Uint8Array(buffer);\n }\n\n async writeFile(path: string, content: string): Promise<void> {\n const fs = await import(\"node:fs/promises\");\n await fs.writeFile(path, content, \"utf-8\");\n }\n\n async exists(path: string): Promise<boolean> {\n const fs = await import(\"node:fs/promises\");\n try {\n await fs.access(path);\n return true;\n } catch (error) {\n serverLogger.debug(`File access check failed for ${path}:`, error);\n return false;\n }\n }\n\n async *readDir(path: string): AsyncIterable<DirEntry> {\n const fs = await import(\"node:fs/promises\");\n const entries = await fs.readdir(path, { withFileTypes: true });\n\n for (const entry of entries) {\n yield {\n name: entry.name,\n isFile: entry.isFile(),\n isDirectory: entry.isDirectory(),\n isSymlink: entry.isSymbolicLink(),\n };\n }\n }\n\n async stat(path: string): Promise<FileInfo> {\n const fs = await import(\"node:fs/promises\");\n const stats = await fs.stat(path);\n\n return {\n size: stats.size,\n isFile: stats.isFile(),\n isDirectory: stats.isDirectory(),\n isSymlink: stats.isSymbolicLink(),\n mtime: stats.mtime,\n };\n }\n\n async mkdir(path: string, options?: { recursive?: boolean }): Promise<void> {\n const fs = await import(\"node:fs/promises\");\n await fs.mkdir(path, options);\n }\n\n async remove(path: string, options?: { recursive?: boolean }): Promise<void> {\n const fs = await import(\"node:fs/promises\");\n await fs.rm(path, { recursive: options?.recursive, force: true });\n }\n\n async makeTempDir(prefix: string): Promise<string> {\n const { mkdtemp } = await import(\"node:fs/promises\");\n const { join } = await import(\"node:path\");\n const { tmpdir } = await import(\"node:os\");\n return await mkdtemp(join(tmpdir(), prefix));\n }\n\n watch(paths: string | string[], options?: WatchOptions): FileWatcher {\n const pathArray = Array.isArray(paths) ? paths : [paths];\n const recursive = options?.recursive ?? true;\n const signal = options?.signal;\n\n let closed = false;\n const watchers: Array<import(\"node:fs\").FSWatcher> = [];\n const eventQueue: FileChangeEvent[] = [];\n let resolver: ((value: IteratorResult<FileChangeEvent>) => void) | null = null;\n\n Promise.all(\n pathArray.map((path) =>\n setupNodeFsWatcher(path, {\n recursive,\n closed: () => closed,\n signal,\n eventQueue,\n getResolver: () => resolver,\n setResolver: (r) => {\n resolver = r;\n },\n watchers,\n onError: (error, path) => serverLogger.error(`File watcher error for ${path}:`, error),\n })\n ),\n ).catch((error) => {\n serverLogger.error(\"Failed to setup file watchers:\", error);\n });\n\n const iterator = createWatcherIterator(\n eventQueue,\n () => resolver,\n (r) => {\n resolver = r;\n },\n () => closed,\n () => signal?.aborted ?? false,\n );\n\n const cleanup = () => {\n closed = true;\n watchers.forEach((watcher) => {\n try {\n watcher.close();\n } catch (error) {\n serverLogger.debug(\"Error closing file watcher during cleanup:\", error);\n }\n });\n if (resolver) {\n resolver({ done: true, value: undefined });\n resolver = null;\n }\n };\n\n if (signal) {\n signal.addEventListener(\"abort\", cleanup);\n }\n\n return createFileWatcher(iterator, cleanup);\n }\n}\n", "import process from \"node:process\";\nimport type { EnvironmentAdapter } from \"../base.ts\";\n\nexport class NodeEnvironmentAdapter implements EnvironmentAdapter {\n get(key: string): string | undefined {\n return process.env[key];\n }\n\n set(key: string, value: string): void {\n process.env[key] = value;\n }\n\n toObject(): Record<string, string> {\n return { ...process.env } as Record<string, string>;\n }\n}\n", "'use strict';\n\nconst BINARY_TYPES = ['nodebuffer', 'arraybuffer', 'fragments'];\nconst hasBlob = typeof Blob !== 'undefined';\n\nif (hasBlob) BINARY_TYPES.push('blob');\n\nmodule.exports = {\n BINARY_TYPES,\n EMPTY_BUFFER: Buffer.alloc(0),\n GUID: '258EAFA5-E914-47DA-95CA-C5AB0DC85B11',\n hasBlob,\n kForOnEventAttribute: Symbol('kIsForOnEventAttribute'),\n kListener: Symbol('kListener'),\n kStatusCode: Symbol('status-code'),\n kWebSocket: Symbol('websocket'),\n NOOP: () => {}\n};\n", "'use strict';\n\nconst { EMPTY_BUFFER } = require('./constants');\n\nconst FastBuffer = Buffer[Symbol.species];\n\n/**\n * Merges an array of buffers into a new buffer.\n *\n * @param {Buffer[]} list The array of buffers to concat\n * @param {Number} totalLength The total length of buffers in the list\n * @return {Buffer} The resulting buffer\n * @public\n */\nfunction concat(list, totalLength) {\n if (list.length === 0) return EMPTY_BUFFER;\n if (list.length === 1) return list[0];\n\n const target = Buffer.allocUnsafe(totalLength);\n let offset = 0;\n\n for (let i = 0; i < list.length; i++) {\n const buf = list[i];\n target.set(buf, offset);\n offset += buf.length;\n }\n\n if (offset < totalLength) {\n return new FastBuffer(target.buffer, target.byteOffset, offset);\n }\n\n return target;\n}\n\n/**\n * Masks a buffer using the given mask.\n *\n * @param {Buffer} source The buffer to mask\n * @param {Buffer} mask The mask to use\n * @param {Buffer} output The buffer where to store the result\n * @param {Number} offset The offset at which to start writing\n * @param {Number} length The number of bytes to mask.\n * @public\n */\nfunction _mask(source, mask, output, offset, length) {\n for (let i = 0; i < length; i++) {\n output[offset + i] = source[i] ^ mask[i & 3];\n }\n}\n\n/**\n * Unmasks a buffer using the given mask.\n *\n * @param {Buffer} buffer The buffer to unmask\n * @param {Buffer} mask The mask to use\n * @public\n */\nfunction _unmask(buffer, mask) {\n for (let i = 0; i < buffer.length; i++) {\n buffer[i] ^= mask[i & 3];\n }\n}\n\n/**\n * Converts a buffer to an `ArrayBuffer`.\n *\n * @param {Buffer} buf The buffer to convert\n * @return {ArrayBuffer} Converted buffer\n * @public\n */\nfunction toArrayBuffer(buf) {\n if (buf.length === buf.buffer.byteLength) {\n return buf.buffer;\n }\n\n return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.length);\n}\n\n/**\n * Converts `data` to a `Buffer`.\n *\n * @param {*} data The data to convert\n * @return {Buffer} The buffer\n * @throws {TypeError}\n * @public\n */\nfunction toBuffer(data) {\n toBuffer.readOnly = true;\n\n if (Buffer.isBuffer(data)) return data;\n\n let buf;\n\n if (data instanceof ArrayBuffer) {\n buf = new FastBuffer(data);\n } else if (ArrayBuffer.isView(data)) {\n buf = new FastBuffer(data.buffer, data.byteOffset, data.byteLength);\n } else {\n buf = Buffer.from(data);\n toBuffer.readOnly = false;\n }\n\n return buf;\n}\n\nmodule.exports = {\n concat,\n mask: _mask,\n toArrayBuffer,\n toBuffer,\n unmask: _unmask\n};\n\n/* istanbul ignore else */\nif (!process.env.WS_NO_BUFFER_UTIL) {\n try {\n const bufferUtil = require('bufferutil');\n\n module.exports.mask = function (source, mask, output, offset, length) {\n if (length < 48) _mask(source, mask, output, offset, length);\n else bufferUtil.mask(source, mask, output, offset, length);\n };\n\n module.exports.unmask = function (buffer, mask) {\n if (buffer.length < 32) _unmask(buffer, mask);\n else bufferUtil.unmask(buffer, mask);\n };\n } catch (e) {\n // Continue regardless of the error.\n }\n}\n", "'use strict';\n\nconst kDone = Symbol('kDone');\nconst kRun = Symbol('kRun');\n\n/**\n * A very simple job queue with adjustable concurrency. Adapted from\n * https://github.com/STRML/async-limiter\n */\nclass Limiter {\n /**\n * Creates a new `Limiter`.\n *\n * @param {Number} [concurrency=Infinity] The maximum number of jobs allowed\n * to run concurrently\n */\n constructor(concurrency) {\n this[kDone] = () => {\n this.pending--;\n this[kRun]();\n };\n this.concurrency = concurrency || Infinity;\n this.jobs = [];\n this.pending = 0;\n }\n\n /**\n * Adds a job to the queue.\n *\n * @param {Function} job The job to run\n * @public\n */\n add(job) {\n this.jobs.push(job);\n this[kRun]();\n }\n\n /**\n * Removes a job from the queue and runs it if possible.\n *\n * @private\n */\n [kRun]() {\n if (this.pending === this.concurrency) return;\n\n if (this.jobs.length) {\n const job = this.jobs.shift();\n\n this.pending++;\n job(this[kDone]);\n }\n }\n}\n\nmodule.exports = Limiter;\n", "'use strict';\n\nconst zlib = require('zlib');\n\nconst bufferUtil = require('./buffer-util');\nconst Limiter = require('./limiter');\nconst { kStatusCode } = require('./constants');\n\nconst FastBuffer = Buffer[Symbol.species];\nconst TRAILER = Buffer.from([0x00, 0x00, 0xff, 0xff]);\nconst kPerMessageDeflate = Symbol('permessage-deflate');\nconst kTotalLength = Symbol('total-length');\nconst kCallback = Symbol('callback');\nconst kBuffers = Symbol('buffers');\nconst kError = Symbol('error');\n\n//\n// We limit zlib concurrency, which prevents severe memory fragmentation\n// as documented in https://github.com/nodejs/node/issues/8871#issuecomment-250915913\n// and https://github.com/websockets/ws/issues/1202\n//\n// Intentionally global; it's the global thread pool that's an issue.\n//\nlet zlibLimiter;\n\n/**\n * permessage-deflate implementation.\n */\nclass PerMessageDeflate {\n /**\n * Creates a PerMessageDeflate instance.\n *\n * @param {Object} [options] Configuration options\n * @param {(Boolean|Number)} [options.clientMaxWindowBits] Advertise support\n * for, or request, a custom client window size\n * @param {Boolean} [options.clientNoContextTakeover=false] Advertise/\n * acknowledge disabling of client context takeover\n * @param {Number} [options.concurrencyLimit=10] The number of concurrent\n * calls to zlib\n * @param {(Boolean|Number)} [options.serverMaxWindowBits] Request/confirm the\n * use of a custom server window size\n * @param {Boolean} [options.serverNoContextTakeover=false] Request/accept\n * disabling of server context takeover\n * @param {Number} [options.threshold=1024] Size (in bytes) below which\n * messages should not be compressed if context takeover is disabled\n * @param {Object} [options.zlibDeflateOptions] Options to pass to zlib on\n * deflate\n * @param {Object} [options.zlibInflateOptions] Options to pass to zlib on\n * inflate\n * @param {Boolean} [isServer=false] Create the instance in either server or\n * client mode\n * @param {Number} [maxPayload=0] The maximum allowed message length\n */\n constructor(options, isServer, maxPayload) {\n this._maxPayload = maxPayload | 0;\n this._options = options || {};\n this._threshold =\n this._options.threshold !== undefined ? this._options.threshold : 1024;\n this._isServer = !!isServer;\n this._deflate = null;\n this._inflate = null;\n\n this.params = null;\n\n if (!zlibLimiter) {\n const concurrency =\n this._options.concurrencyLimit !== undefined\n ? this._options.concurrencyLimit\n : 10;\n zlibLimiter = new Limiter(concurrency);\n }\n }\n\n /**\n * @type {String}\n */\n static get extensionName() {\n return 'permessage-deflate';\n }\n\n /**\n * Create an extension negotiation offer.\n *\n * @return {Object} Extension parameters\n * @public\n */\n offer() {\n const params = {};\n\n if (this._options.serverNoContextTakeover) {\n params.server_no_context_takeover = true;\n }\n if (this._options.clientNoContextTakeover) {\n params.client_no_context_takeover = true;\n }\n if (this._options.serverMaxWindowBits) {\n params.server_max_window_bits = this._options.serverMaxWindowBits;\n }\n if (this._options.clientMaxWindowBits) {\n params.client_max_window_bits = this._options.clientMaxWindowBits;\n } else if (this._options.clientMaxWindowBits == null) {\n params.client_max_window_bits = true;\n }\n\n return params;\n }\n\n /**\n * Accept an extension negotiation offer/response.\n *\n * @param {Array} configurations The extension negotiation offers/reponse\n * @return {Object} Accepted configuration\n * @public\n */\n accept(configurations) {\n configurations = this.normalizeParams(configurations);\n\n this.params = this._isServer\n ? this.acceptAsServer(configurations)\n : this.acceptAsClient(configurations);\n\n return this.params;\n }\n\n /**\n * Releases all resources used by the extension.\n *\n * @public\n */\n cleanup() {\n if (this._inflate) {\n this._inflate.close();\n this._inflate = null;\n }\n\n if (this._deflate) {\n const callback = this._deflate[kCallback];\n\n this._deflate.close();\n this._deflate = null;\n\n if (callback) {\n callback(\n new Error(\n 'The deflate stream was closed while data was being processed'\n )\n );\n }\n }\n }\n\n /**\n * Accept an extension negotiation offer.\n *\n * @param {Array} offers The extension negotiation offers\n * @return {Object} Accepted configuration\n * @private\n */\n acceptAsServer(offers) {\n const opts = this._options;\n const accepted = offers.find((params) => {\n if (\n (opts.serverNoContextTakeover === false &&\n params.server_no_context_takeover) ||\n (params.server_max_window_bits &&\n (opts.serverMaxWindowBits === false ||\n (typeof opts.serverMaxWindowBits === 'number' &&\n opts.serverMaxWindowBits > params.server_max_window_bits))) ||\n (typeof opts.clientMaxWindowBits === 'number' &&\n !params.client_max_window_bits)\n ) {\n return false;\n }\n\n return true;\n });\n\n if (!accepted) {\n throw new Error('None of the extension offers can be accepted');\n }\n\n if (opts.serverNoContextTakeover) {\n accepted.server_no_context_takeover = true;\n }\n if (opts.clientNoContextTakeover) {\n accepted.client_no_context_takeover = true;\n }\n if (typeof opts.serverMaxWindowBits === 'number') {\n accepted.server_max_window_bits = opts.serverMaxWindowBits;\n }\n if (typeof opts.clientMaxWindowBits === 'number') {\n accepted.client_max_window_bits = opts.clientMaxWindowBits;\n } else if (\n accepted.client_max_window_bits === true ||\n opts.clientMaxWindowBits === false\n ) {\n delete accepted.client_max_window_bits;\n }\n\n return accepted;\n }\n\n /**\n * Accept the extension negotiation response.\n *\n * @param {Array} response The extension negotiation response\n * @return {Object} Accepted configuration\n * @private\n */\n acceptAsClient(response) {\n const params = response[0];\n\n if (\n this._options.clientNoContextTakeover === false &&\n params.client_no_context_takeover\n ) {\n throw new Error('Unexpected parameter \"client_no_context_takeover\"');\n }\n\n if (!params.client_max_window_bits) {\n if (typeof this._options.clientMaxWindowBits === 'number') {\n params.client_max_window_bits = this._options.clientMaxWindowBits;\n }\n } else if (\n this._options.clientMaxWindowBits === false ||\n (typeof this._options.clientMaxWindowBits === 'number' &&\n params.client_max_window_bits > this._options.clientMaxWindowBits)\n ) {\n throw new Error(\n 'Unexpected or invalid parameter \"client_max_window_bits\"'\n );\n }\n\n return params;\n }\n\n /**\n * Normalize parameters.\n *\n * @param {Array} configurations The extension negotiation offers/reponse\n * @return {Array} The offers/response with normalized parameters\n * @private\n */\n normalizeParams(configurations) {\n configurations.forEach((params) => {\n Object.keys(params).forEach((key) => {\n let value = params[key];\n\n if (value.length > 1) {\n throw new Error(`Parameter \"${key}\" must have only a single value`);\n }\n\n value = value[0];\n\n if (key === 'client_max_window_bits') {\n if (value !== true) {\n const num = +value;\n if (!Number.isInteger(num) || num < 8 || num > 15) {\n throw new TypeError(\n `Invalid value for parameter \"${key}\": ${value}`\n );\n }\n value = num;\n } else if (!this._isServer) {\n throw new TypeError(\n `Invalid value for parameter \"${key}\": ${value}`\n );\n }\n } else if (key === 'server_max_window_bits') {\n const num = +value;\n if (!Number.isInteger(num) || num < 8 || num > 15) {\n throw new TypeError(\n `Invalid value for parameter \"${key}\": ${value}`\n );\n }\n value = num;\n } else if (\n key === 'client_no_context_takeover' ||\n key === 'server_no_context_takeover'\n ) {\n if (value !== true) {\n throw new TypeError(\n `Invalid value for parameter \"${key}\": ${value}`\n );\n }\n } else {\n throw new Error(`Unknown parameter \"${key}\"`);\n }\n\n params[key] = value;\n });\n });\n\n return configurations;\n }\n\n /**\n * Decompress data. Concurrency limited.\n *\n * @param {Buffer} data Compressed data\n * @param {Boolean} fin Specifies whether or not this is the last fragment\n * @param {Function} callback Callback\n * @public\n */\n decompress(data, fin, callback) {\n zlibLimiter.add((done) => {\n this._decompress(data, fin, (err, result) => {\n done();\n callback(err, result);\n });\n });\n }\n\n /**\n * Compress data. Concurrency limited.\n *\n * @param {(Buffer|String)} data Data to compress\n * @param {Boolean} fin Specifies whether or not this is the last fragment\n * @param {Function} callback Callback\n * @public\n */\n compress(data, fin, callback) {\n zlibLimiter.add((done) => {\n this._compress(data, fin, (err, result) => {\n done();\n callback(err, result);\n });\n });\n }\n\n /**\n * Decompress data.\n *\n * @param {Buffer} data Compressed data\n * @param {Boolean} fin Specifies whether or not this is the last fragment\n * @param {Function} callback Callback\n * @private\n */\n _decompress(data, fin, callback) {\n const endpoint = this._isServer ? 'client' : 'server';\n\n if (!this._inflate) {\n const key = `${endpoint}_max_window_bits`;\n const windowBits =\n typeof this.params[key] !== 'number'\n ? zlib.Z_DEFAULT_WINDOWBITS\n : this.params[key];\n\n this._inflate = zlib.createInflateRaw({\n ...this._options.zlibInflateOptions,\n windowBits\n });\n this._inflate[kPerMessageDeflate] = this;\n this._inflate[kTotalLength] = 0;\n this._inflate[kBuffers] = [];\n this._inflate.on('error', inflateOnError);\n this._inflate.on('data', inflateOnData);\n }\n\n this._inflate[kCallback] = callback;\n\n this._inflate.write(data);\n if (fin) this._inflate.write(TRAILER);\n\n this._inflate.flush(() => {\n const err = this._inflate[kError];\n\n if (err) {\n this._inflate.close();\n this._inflate = null;\n callback(err);\n return;\n }\n\n const data = bufferUtil.concat(\n this._inflate[kBuffers],\n this._inflate[kTotalLength]\n );\n\n if (this._inflate._readableState.endEmitted) {\n this._inflate.close();\n this._inflate = null;\n } else {\n this._inflate[kTotalLength] = 0;\n this._inflate[kBuffers] = [];\n\n if (fin && this.params[`${endpoint}_no_context_takeover`]) {\n this._inflate.reset();\n }\n }\n\n callback(null, data);\n });\n }\n\n /**\n * Compress data.\n *\n * @param {(Buffer|String)} data Data to compress\n * @param {Boolean} fin Specifies whether or not this is the last fragment\n * @param {Function} callback Callback\n * @private\n */\n _compress(data, fin, callback) {\n const endpoint = this._isServer ? 'server' : 'client';\n\n if (!this._deflate) {\n const key = `${endpoint}_max_window_bits`;\n const windowBits =\n typeof this.params[key] !== 'number'\n ? zlib.Z_DEFAULT_WINDOWBITS\n : this.params[key];\n\n this._deflate = zlib.createDeflateRaw({\n ...this._options.zlibDeflateOptions,\n windowBits\n });\n\n this._deflate[kTotalLength] = 0;\n this._deflate[kBuffers] = [];\n\n this._deflate.on('data', deflateOnData);\n }\n\n this._deflate[kCallback] = callback;\n\n this._deflate.write(data);\n this._deflate.flush(zlib.Z_SYNC_FLUSH, () => {\n if (!this._deflate) {\n //\n // The deflate stream was closed while data was being processed.\n //\n return;\n }\n\n let data = bufferUtil.concat(\n this._deflate[kBuffers],\n this._deflate[kTotalLength]\n );\n\n if (fin) {\n data = new FastBuffer(data.buffer, data.byteOffset, data.length - 4);\n }\n\n //\n // Ensure that the callback will not be called again in\n // `PerMessageDeflate#cleanup()`.\n //\n this._deflate[kCallback] = null;\n\n this._deflate[kTotalLength] = 0;\n this._deflate[kBuffers] = [];\n\n if (fin && this.params[`${endpoint}_no_context_takeover`]) {\n this._deflate.reset();\n }\n\n callback(null, data);\n });\n }\n}\n\nmodule.exports = PerMessageDeflate;\n\n/**\n * The listener of the `zlib.DeflateRaw` stream `'data'` event.\n *\n * @param {Buffer} chunk A chunk of data\n * @private\n */\nfunction deflateOnData(chunk) {\n this[kBuffers].push(chunk);\n this[kTotalLength] += chunk.length;\n}\n\n/**\n * The listener of the `zlib.InflateRaw` stream `'data'` event.\n *\n * @param {Buffer} chunk A chunk of data\n * @private\n */\nfunction inflateOnData(chunk) {\n this[kTotalLength] += chunk.length;\n\n if (\n this[kPerMessageDeflate]._maxPayload < 1 ||\n this[kTotalLength] <= this[kPerMessageDeflate]._maxPayload\n ) {\n this[kBuffers].push(chunk);\n return;\n }\n\n this[kError] = new RangeError('Max payload size exceeded');\n this[kError].code = 'WS_ERR_UNSUPPORTED_MESSAGE_LENGTH';\n this[kError][kStatusCode] = 1009;\n this.removeListener('data', inflateOnData);\n\n //\n // The choice to employ `zlib.reset()` over `zlib.close()` is dictated by the\n // fact that in Node.js versions prior to 13.10.0, the callback for\n // `zlib.flush()` is not called if `zlib.close()` is used. Utilizing\n // `zlib.reset()` ensures that either the callback is invoked or an error is\n // emitted.\n //\n this.reset();\n}\n\n/**\n * The listener of the `zlib.InflateRaw` stream `'error'` event.\n *\n * @param {Error} err The emitted error\n * @private\n */\nfunction inflateOnError(err) {\n //\n // There is no need to call `Zlib#close()` as the handle is automatically\n // closed when an error is emitted.\n //\n this[kPerMessageDeflate]._inflate = null;\n\n if (this[kError]) {\n this[kCallback](this[kError]);\n return;\n }\n\n err[kStatusCode] = 1007;\n this[kCallback](err);\n}\n", "'use strict';\n\nconst { isUtf8 } = require('buffer');\n\nconst { hasBlob } = require('./constants');\n\n//\n// Allowed token characters:\n//\n// '!', '#', '$', '%', '&', ''', '*', '+', '-',\n// '.', 0-9, A-Z, '^', '_', '`', a-z, '|', '~'\n//\n// tokenChars[32] === 0 // ' '\n// tokenChars[33] === 1 // '!'\n// tokenChars[34] === 0 // '\"'\n// ...\n//\n// prettier-ignore\nconst tokenChars = [\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0 - 15\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 16 - 31\n 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, // 32 - 47\n 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, // 48 - 63\n 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 64 - 79\n 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, // 80 - 95\n 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 96 - 111\n 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0 // 112 - 127\n];\n\n/**\n * Checks if a status code is allowed in a close frame.\n *\n * @param {Number} code The status code\n * @return {Boolean} `true` if the status code is valid, else `false`\n * @public\n */\nfunction isValidStatusCode(code) {\n return (\n (code >= 1000 &&\n code <= 1014 &&\n code !== 1004 &&\n code !== 1005 &&\n code !== 1006) ||\n (code >= 3000 && code <= 4999)\n );\n}\n\n/**\n * Checks if a given buffer contains only correct UTF-8.\n * Ported from https://www.cl.cam.ac.uk/%7Emgk25/ucs/utf8_check.c by\n * Markus Kuhn.\n *\n * @param {Buffer} buf The buffer to check\n * @return {Boolean} `true` if `buf` contains only correct UTF-8, else `false`\n * @public\n */\nfunction _isValidUTF8(buf) {\n const len = buf.length;\n let i = 0;\n\n while (i < len) {\n if ((buf[i] & 0x80) === 0) {\n // 0xxxxxxx\n i++;\n } else if ((buf[i] & 0xe0) === 0xc0) {\n // 110xxxxx 10xxxxxx\n if (\n i + 1 === len ||\n (buf[i + 1] & 0xc0) !== 0x80 ||\n (buf[i] & 0xfe) === 0xc0 // Overlong\n ) {\n return false;\n }\n\n i += 2;\n } else if ((buf[i] & 0xf0) === 0xe0) {\n // 1110xxxx 10xxxxxx 10xxxxxx\n if (\n i + 2 >= len ||\n (buf[i + 1] & 0xc0) !== 0x80 ||\n (buf[i + 2] & 0xc0) !== 0x80 ||\n (buf[i] === 0xe0 && (buf[i + 1] & 0xe0) === 0x80) || // Overlong\n (buf[i] === 0xed && (buf[i + 1] & 0xe0) === 0xa0) // Surrogate (U+D800 - U+DFFF)\n ) {\n return false;\n }\n\n i += 3;\n } else if ((buf[i] & 0xf8) === 0xf0) {\n // 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx\n if (\n i + 3 >= len ||\n (buf[i + 1] & 0xc0) !== 0x80 ||\n (buf[i + 2] & 0xc0) !== 0x80 ||\n (buf[i + 3] & 0xc0) !== 0x80 ||\n (buf[i] === 0xf0 && (buf[i + 1] & 0xf0) === 0x80) || // Overlong\n (buf[i] === 0xf4 && buf[i + 1] > 0x8f) ||\n buf[i] > 0xf4 // > U+10FFFF\n ) {\n return false;\n }\n\n i += 4;\n } else {\n return false;\n }\n }\n\n return true;\n}\n\n/**\n * Determines whether a value is a `Blob`.\n *\n * @param {*} value The value to be tested\n * @return {Boolean} `true` if `value` is a `Blob`, else `false`\n * @private\n */\nfunction isBlob(value) {\n return (\n hasBlob &&\n typeof value === 'object' &&\n typeof value.arrayBuffer === 'function' &&\n typeof value.type === 'string' &&\n typeof value.stream === 'function' &&\n (value[Symbol.toStringTag] === 'Blob' ||\n value[Symbol.toStringTag] === 'File')\n );\n}\n\nmodule.exports = {\n isBlob,\n isValidStatusCode,\n isValidUTF8: _isValidUTF8,\n tokenChars\n};\n\nif (isUtf8) {\n module.exports.isValidUTF8 = function (buf) {\n return buf.length < 24 ? _isValidUTF8(buf) : isUtf8(buf);\n };\n} /* istanbul ignore else */ else if (!process.env.WS_NO_UTF_8_VALIDATE) {\n try {\n const isValidUTF8 = require('utf-8-validate');\n\n module.exports.isValidUTF8 = function (buf) {\n return buf.length < 32 ? _isValidUTF8(buf) : isValidUTF8(buf);\n };\n } catch (e) {\n // Continue regardless of the error.\n }\n}\n", "'use strict';\n\nconst { Writable } = require('stream');\n\nconst PerMessageDeflate = require('./permessage-deflate');\nconst {\n BINARY_TYPES,\n EMPTY_BUFFER,\n kStatusCode,\n kWebSocket\n} = require('./constants');\nconst { concat, toArrayBuffer, unmask } = require('./buffer-util');\nconst { isValidStatusCode, isValidUTF8 } = require('./validation');\n\nconst FastBuffer = Buffer[Symbol.species];\n\nconst GET_INFO = 0;\nconst GET_PAYLOAD_LENGTH_16 = 1;\nconst GET_PAYLOAD_LENGTH_64 = 2;\nconst GET_MASK = 3;\nconst GET_DATA = 4;\nconst INFLATING = 5;\nconst DEFER_EVENT = 6;\n\n/**\n * HyBi Receiver implementation.\n *\n * @extends Writable\n */\nclass Receiver extends Writable {\n /**\n * Creates a Receiver instance.\n *\n * @param {Object} [options] Options object\n * @param {Boolean} [options.allowSynchronousEvents=true] Specifies whether\n * any of the `'message'`, `'ping'`, and `'pong'` events can be emitted\n * multiple times in the same tick\n * @param {String} [options.binaryType=nodebuffer] The type for binary data\n * @param {Object} [options.extensions] An object containing the negotiated\n * extensions\n * @param {Boolean} [options.isServer=false] Specifies whether to operate in\n * client or server mode\n * @param {Number} [options.maxPayload=0] The maximum allowed message length\n * @param {Boolean} [options.skipUTF8Validation=false] Specifies whether or\n * not to skip UTF-8 validation for text and close messages\n */\n constructor(options = {}) {\n super();\n\n this._allowSynchronousEvents =\n options.allowSynchronousEvents !== undefined\n ? options.allowSynchronousEvents\n : true;\n this._binaryType = options.binaryType || BINARY_TYPES[0];\n this._extensions = options.extensions || {};\n this._isServer = !!options.isServer;\n this._maxPayload = options.maxPayload | 0;\n this._skipUTF8Validation = !!options.skipUTF8Validation;\n this[kWebSocket] = undefined;\n\n this._bufferedBytes = 0;\n this._buffers = [];\n\n this._compressed = false;\n this._payloadLength = 0;\n this._mask = undefined;\n this._fragmented = 0;\n this._masked = false;\n this._fin = false;\n this._opcode = 0;\n\n this._totalPayloadLength = 0;\n this._messageLength = 0;\n this._fragments = [];\n\n this._errored = false;\n this._loop = false;\n this._state = GET_INFO;\n }\n\n /**\n * Implements `Writable.prototype._write()`.\n *\n * @param {Buffer} chunk The chunk of data to write\n * @param {String} encoding The character encoding of `chunk`\n * @param {Function} cb Callback\n * @private\n */\n _write(chunk, encoding, cb) {\n if (this._opcode === 0x08 && this._state == GET_INFO) return cb();\n\n this._bufferedBytes += chunk.length;\n this._buffers.push(chunk);\n this.startLoop(cb);\n }\n\n /**\n * Consumes `n` bytes from the buffered data.\n *\n * @param {Number} n The number of bytes to consume\n * @return {Buffer} The consumed bytes\n * @private\n */\n consume(n) {\n this._bufferedBytes -= n;\n\n if (n === this._buffers[0].length) return this._buffers.shift();\n\n if (n < this._buffers[0].length) {\n const buf = this._buffers[0];\n this._buffers[0] = new FastBuffer(\n buf.buffer,\n buf.byteOffset + n,\n buf.length - n\n );\n\n return new FastBuffer(buf.buffer, buf.byteOffset, n);\n }\n\n const dst = Buffer.allocUnsafe(n);\n\n do {\n const buf = this._buffers[0];\n const offset = dst.length - n;\n\n if (n >= buf.length) {\n dst.set(this._buffers.shift(), offset);\n } else {\n dst.set(new Uint8Array(buf.buffer, buf.byteOffset, n), offset);\n this._buffers[0] = new FastBuffer(\n buf.buffer,\n buf.byteOffset + n,\n buf.length - n\n );\n }\n\n n -= buf.length;\n } while (n > 0);\n\n return dst;\n }\n\n /**\n * Starts the parsing loop.\n *\n * @param {Function} cb Callback\n * @private\n */\n startLoop(cb) {\n this._loop = true;\n\n do {\n switch (this._state) {\n case GET_INFO:\n this.getInfo(cb);\n break;\n case GET_PAYLOAD_LENGTH_16:\n this.getPayloadLength16(cb);\n break;\n case GET_PAYLOAD_LENGTH_64:\n this.getPayloadLength64(cb);\n break;\n case GET_MASK:\n this.getMask();\n break;\n case GET_DATA:\n this.getData(cb);\n break;\n case INFLATING:\n case DEFER_EVENT:\n this._loop = false;\n return;\n }\n } while (this._loop);\n\n if (!this._errored) cb();\n }\n\n /**\n * Reads the first two bytes of a frame.\n *\n * @param {Function} cb Callback\n * @private\n */\n getInfo(cb) {\n if (this._bufferedBytes < 2) {\n this._loop = false;\n return;\n }\n\n const buf = this.consume(2);\n\n if ((buf[0] & 0x30) !== 0x00) {\n const error = this.createError(\n RangeError,\n 'RSV2 and RSV3 must be clear',\n true,\n 1002,\n 'WS_ERR_UNEXPECTED_RSV_2_3'\n );\n\n cb(error);\n return;\n }\n\n const compressed = (buf[0] & 0x40) === 0x40;\n\n if (compressed && !this._extensions[PerMessageDeflate.extensionName]) {\n const error = this.createError(\n RangeError,\n 'RSV1 must be clear',\n true,\n 1002,\n 'WS_ERR_UNEXPECTED_RSV_1'\n );\n\n cb(error);\n return;\n }\n\n this._fin = (buf[0] & 0x80) === 0x80;\n this._opcode = buf[0] & 0x0f;\n this._payloadLength = buf[1] & 0x7f;\n\n if (this._opcode === 0x00) {\n if (compressed) {\n const error = this.createError(\n RangeError,\n 'RSV1 must be clear',\n true,\n 1002,\n 'WS_ERR_UNEXPECTED_RSV_1'\n );\n\n cb(error);\n return;\n }\n\n if (!this._fragmented) {\n const error = this.createError(\n RangeError,\n 'invalid opcode 0',\n true,\n 1002,\n 'WS_ERR_INVALID_OPCODE'\n );\n\n cb(error);\n return;\n }\n\n this._opcode = this._fragmented;\n } else if (this._opcode === 0x01 || this._opcode === 0x02) {\n if (this._fragmented) {\n const error = this.createError(\n RangeError,\n `invalid opcode ${this._opcode}`,\n true,\n 1002,\n 'WS_ERR_INVALID_OPCODE'\n );\n\n cb(error);\n return;\n }\n\n this._compressed = compressed;\n } else if (this._opcode > 0x07 && this._opcode < 0x0b) {\n if (!this._fin) {\n const error = this.createError(\n RangeError,\n 'FIN must be set',\n true,\n 1002,\n 'WS_ERR_EXPECTED_FIN'\n );\n\n cb(error);\n return;\n }\n\n if (compressed) {\n const error = this.createError(\n RangeError,\n 'RSV1 must be clear',\n true,\n 1002,\n 'WS_ERR_UNEXPECTED_RSV_1'\n );\n\n cb(error);\n return;\n }\n\n if (\n this._payloadLength > 0x7d ||\n (this._opcode === 0x08 && this._payloadLength === 1)\n ) {\n const error = this.createError(\n RangeError,\n `invalid payload length ${this._payloadLength}`,\n true,\n 1002,\n 'WS_ERR_INVALID_CONTROL_PAYLOAD_LENGTH'\n );\n\n cb(error);\n return;\n }\n } else {\n const error = this.createError(\n RangeError,\n `invalid opcode ${this._opcode}`,\n true,\n 1002,\n 'WS_ERR_INVALID_OPCODE'\n );\n\n cb(error);\n return;\n }\n\n if (!this._fin && !this._fragmented) this._fragmented = this._opcode;\n this._masked = (buf[1] & 0x80) === 0x80;\n\n if (this._isServer) {\n if (!this._masked) {\n const error = this.createError(\n RangeError,\n 'MASK must be set',\n true,\n 1002,\n 'WS_ERR_EXPECTED_MASK'\n );\n\n cb(error);\n return;\n }\n } else if (this._masked) {\n const error = this.createError(\n RangeError,\n 'MASK must be clear',\n true,\n 1002,\n 'WS_ERR_UNEXPECTED_MASK'\n );\n\n cb(error);\n return;\n }\n\n if (this._payloadLength === 126) this._state = GET_PAYLOAD_LENGTH_16;\n else if (this._payloadLength === 127) this._state = GET_PAYLOAD_LENGTH_64;\n else this.haveLength(cb);\n }\n\n /**\n * Gets extended payload length (7+16).\n *\n * @param {Function} cb Callback\n * @private\n */\n getPayloadLength16(cb) {\n if (this._bufferedBytes < 2) {\n this._loop = false;\n return;\n }\n\n this._payloadLength = this.consume(2).readUInt16BE(0);\n this.haveLength(cb);\n }\n\n /**\n * Gets extended payload length (7+64).\n *\n * @param {Function} cb Callback\n * @private\n */\n getPayloadLength64(cb) {\n if (this._bufferedBytes < 8) {\n this._loop = false;\n return;\n }\n\n const buf = this.consume(8);\n const num = buf.readUInt32BE(0);\n\n //\n // The maximum safe integer in JavaScript is 2^53 - 1. An error is returned\n // if payload length is greater than this number.\n //\n if (num > Math.pow(2, 53 - 32) - 1) {\n const error = this.createError(\n RangeError,\n 'Unsupported WebSocket frame: payload length > 2^53 - 1',\n false,\n 1009,\n 'WS_ERR_UNSUPPORTED_DATA_PAYLOAD_LENGTH'\n );\n\n cb(error);\n return;\n }\n\n this._payloadLength = num * Math.pow(2, 32) + buf.readUInt32BE(4);\n this.haveLength(cb);\n }\n\n /**\n * Payload length has been read.\n *\n * @param {Function} cb Callback\n * @private\n */\n haveLength(cb) {\n if (this._payloadLength && this._opcode < 0x08) {\n this._totalPayloadLength += this._payloadLength;\n if (this._totalPayloadLength > this._maxPayload && this._maxPayload > 0) {\n const error = this.createError(\n RangeError,\n 'Max payload size exceeded',\n false,\n 1009,\n 'WS_ERR_UNSUPPORTED_MESSAGE_LENGTH'\n );\n\n cb(error);\n return;\n }\n }\n\n if (this._masked) this._state = GET_MASK;\n else this._state = GET_DATA;\n }\n\n /**\n * Reads mask bytes.\n *\n * @private\n */\n getMask() {\n if (this._bufferedBytes < 4) {\n this._loop = false;\n return;\n }\n\n this._mask = this.consume(4);\n this._state = GET_DATA;\n }\n\n /**\n * Reads data bytes.\n *\n * @param {Function} cb Callback\n * @private\n */\n getData(cb) {\n let data = EMPTY_BUFFER;\n\n if (this._payloadLength) {\n if (this._bufferedBytes < this._payloadLength) {\n this._loop = false;\n return;\n }\n\n data = this.consume(this._payloadLength);\n\n if (\n this._masked &&\n (this._mask[0] | this._mask[1] | this._mask[2] | this._mask[3]) !== 0\n ) {\n unmask(data, this._mask);\n }\n }\n\n if (this._opcode > 0x07) {\n this.controlMessage(data, cb);\n return;\n }\n\n if (this._compressed) {\n this._state = INFLATING;\n this.decompress(data, cb);\n return;\n }\n\n if (data.length) {\n //\n // This message is not compressed so its length is the sum of the payload\n // length of all fragments.\n //\n this._messageLength = this._totalPayloadLength;\n this._fragments.push(data);\n }\n\n this.dataMessage(cb);\n }\n\n /**\n * Decompresses data.\n *\n * @param {Buffer} data Compressed data\n * @param {Function} cb Callback\n * @private\n */\n decompress(data, cb) {\n const perMessageDeflate = this._extensions[PerMessageDeflate.extensionName];\n\n perMessageDeflate.decompress(data, this._fin, (err, buf) => {\n if (err) return cb(err);\n\n if (buf.length) {\n this._messageLength += buf.length;\n if (this._messageLength > this._maxPayload && this._maxPayload > 0) {\n const error = this.createError(\n RangeError,\n 'Max payload size exceeded',\n false,\n 1009,\n 'WS_ERR_UNSUPPORTED_MESSAGE_LENGTH'\n );\n\n cb(error);\n return;\n }\n\n this._fragments.push(buf);\n }\n\n this.dataMessage(cb);\n if (this._state === GET_INFO) this.startLoop(cb);\n });\n }\n\n /**\n * Handles a data message.\n *\n * @param {Function} cb Callback\n * @private\n */\n dataMessage(cb) {\n if (!this._fin) {\n this._state = GET_INFO;\n return;\n }\n\n const messageLength = this._messageLength;\n const fragments = this._fragments;\n\n this._totalPayloadLength = 0;\n this._messageLength = 0;\n this._fragmented = 0;\n this._fragments = [];\n\n if (this._opcode === 2) {\n let data;\n\n if (this._binaryType === 'nodebuffer') {\n data = concat(fragments, messageLength);\n } else if (this._binaryType === 'arraybuffer') {\n data = toArrayBuffer(concat(fragments, messageLength));\n } else if (this._binaryType === 'blob') {\n data = new Blob(fragments);\n } else {\n data = fragments;\n }\n\n if (this._allowSynchronousEvents) {\n this.emit('message', data, true);\n this._state = GET_INFO;\n } else {\n this._state = DEFER_EVENT;\n setImmediate(() => {\n this.emit('message', data, true);\n this._state = GET_INFO;\n this.startLoop(cb);\n });\n }\n } else {\n const buf = concat(fragments, messageLength);\n\n if (!this._skipUTF8Validation && !isValidUTF8(buf)) {\n const error = this.createError(\n Error,\n 'invalid UTF-8 sequence',\n true,\n 1007,\n 'WS_ERR_INVALID_UTF8'\n );\n\n cb(error);\n return;\n }\n\n if (this._state === INFLATING || this._allowSynchronousEvents) {\n this.emit('message', buf, false);\n this._state = GET_INFO;\n } else {\n this._state = DEFER_EVENT;\n setImmediate(() => {\n this.emit('message', buf, false);\n this._state = GET_INFO;\n this.startLoop(cb);\n });\n }\n }\n }\n\n /**\n * Handles a control message.\n *\n * @param {Buffer} data Data to handle\n * @return {(Error|RangeError|undefined)} A possible error\n * @private\n */\n controlMessage(data, cb) {\n if (this._opcode === 0x08) {\n if (data.length === 0) {\n this._loop = false;\n this.emit('conclude', 1005, EMPTY_BUFFER);\n this.end();\n } else {\n const code = data.readUInt16BE(0);\n\n if (!isValidStatusCode(code)) {\n const error = this.createError(\n RangeError,\n `invalid status code ${code}`,\n true,\n 1002,\n 'WS_ERR_INVALID_CLOSE_CODE'\n );\n\n cb(error);\n return;\n }\n\n const buf = new FastBuffer(\n data.buffer,\n data.byteOffset + 2,\n data.length - 2\n );\n\n if (!this._skipUTF8Validation && !isValidUTF8(buf)) {\n const error = this.createError(\n Error,\n 'invalid UTF-8 sequence',\n true,\n 1007,\n 'WS_ERR_INVALID_UTF8'\n );\n\n cb(error);\n return;\n }\n\n this._loop = false;\n this.emit('conclude', code, buf);\n this.end();\n }\n\n this._state = GET_INFO;\n return;\n }\n\n if (this._allowSynchronousEvents) {\n this.emit(this._opcode === 0x09 ? 'ping' : 'pong', data);\n this._state = GET_INFO;\n } else {\n this._state = DEFER_EVENT;\n setImmediate(() => {\n this.emit(this._opcode === 0x09 ? 'ping' : 'pong', data);\n this._state = GET_INFO;\n this.startLoop(cb);\n });\n }\n }\n\n /**\n * Builds an error object.\n *\n * @param {function(new:Error|RangeError)} ErrorCtor The error constructor\n * @param {String} message The error message\n * @param {Boolean} prefix Specifies whether or not to add a default prefix to\n * `message`\n * @param {Number} statusCode The status code\n * @param {String} errorCode The exposed error code\n * @return {(Error|RangeError)} The error\n * @private\n */\n createError(ErrorCtor, message, prefix, statusCode, errorCode) {\n this._loop = false;\n this._errored = true;\n\n const err = new ErrorCtor(\n prefix ? `Invalid WebSocket frame: ${message}` : message\n );\n\n Error.captureStackTrace(err, this.createError);\n err.code = errorCode;\n err[kStatusCode] = statusCode;\n return err;\n }\n}\n\nmodule.exports = Receiver;\n", "/* eslint no-unused-vars: [\"error\", { \"varsIgnorePattern\": \"^Duplex\" }] */\n\n'use strict';\n\nconst { Duplex } = require('stream');\nconst { randomFillSync } = require('crypto');\n\nconst PerMessageDeflate = require('./permessage-deflate');\nconst { EMPTY_BUFFER, kWebSocket, NOOP } = require('./constants');\nconst { isBlob, isValidStatusCode } = require('./validation');\nconst { mask: applyMask, toBuffer } = require('./buffer-util');\n\nconst kByteLength = Symbol('kByteLength');\nconst maskBuffer = Buffer.alloc(4);\nconst RANDOM_POOL_SIZE = 8 * 1024;\nlet randomPool;\nlet randomPoolPointer = RANDOM_POOL_SIZE;\n\nconst DEFAULT = 0;\nconst DEFLATING = 1;\nconst GET_BLOB_DATA = 2;\n\n/**\n * HyBi Sender implementation.\n */\nclass Sender {\n /**\n * Creates a Sender instance.\n *\n * @param {Duplex} socket The connection socket\n * @param {Object} [extensions] An object containing the negotiated extensions\n * @param {Function} [generateMask] The function used to generate the masking\n * key\n */\n constructor(socket, extensions, generateMask) {\n this._extensions = extensions || {};\n\n if (generateMask) {\n this._generateMask = generateMask;\n this._maskBuffer = Buffer.alloc(4);\n }\n\n this._socket = socket;\n\n this._firstFragment = true;\n this._compress = false;\n\n this._bufferedBytes = 0;\n this._queue = [];\n this._state = DEFAULT;\n this.onerror = NOOP;\n this[kWebSocket] = undefined;\n }\n\n /**\n * Frames a piece of data according to the HyBi WebSocket protocol.\n *\n * @param {(Buffer|String)} data The data to frame\n * @param {Object} options Options object\n * @param {Boolean} [options.fin=false] Specifies whether or not to set the\n * FIN bit\n * @param {Function} [options.generateMask] The function used to generate the\n * masking key\n * @param {Boolean} [options.mask=false] Specifies whether or not to mask\n * `data`\n * @param {Buffer} [options.maskBuffer] The buffer used to store the masking\n * key\n * @param {Number} options.opcode The opcode\n * @param {Boolean} [options.readOnly=false] Specifies whether `data` can be\n * modified\n * @param {Boolean} [options.rsv1=false] Specifies whether or not to set the\n * RSV1 bit\n * @return {(Buffer|String)[]} The framed data\n * @public\n */\n static frame(data, options) {\n let mask;\n let merge = false;\n let offset = 2;\n let skipMasking = false;\n\n if (options.mask) {\n mask = options.maskBuffer || maskBuffer;\n\n if (options.generateMask) {\n options.generateMask(mask);\n } else {\n if (randomPoolPointer === RANDOM_POOL_SIZE) {\n /* istanbul ignore else */\n if (randomPool === undefined) {\n //\n // This is lazily initialized because server-sent frames must not\n // be masked so it may never be used.\n //\n randomPool = Buffer.alloc(RANDOM_POOL_SIZE);\n }\n\n randomFillSync(randomPool, 0, RANDOM_POOL_SIZE);\n randomPoolPointer = 0;\n }\n\n mask[0] = randomPool[randomPoolPointer++];\n mask[1] = randomPool[randomPoolPointer++];\n mask[2] = randomPool[randomPoolPointer++];\n mask[3] = randomPool[randomPoolPointer++];\n }\n\n skipMasking = (mask[0] | mask[1] | mask[2] | mask[3]) === 0;\n offset = 6;\n }\n\n let dataLength;\n\n if (typeof data === 'string') {\n if (\n (!options.mask || skipMasking) &&\n options[kByteLength] !== undefined\n ) {\n dataLength = options[kByteLength];\n } else {\n data = Buffer.from(data);\n dataLength = data.length;\n }\n } else {\n dataLength = data.length;\n merge = options.mask && options.readOnly && !skipMasking;\n }\n\n let payloadLength = dataLength;\n\n if (dataLength >= 65536) {\n offset += 8;\n payloadLength = 127;\n } else if (dataLength > 125) {\n offset += 2;\n payloadLength = 126;\n }\n\n const target = Buffer.allocUnsafe(merge ? dataLength + offset : offset);\n\n target[0] = options.fin ? options.opcode | 0x80 : options.opcode;\n if (options.rsv1) target[0] |= 0x40;\n\n target[1] = payloadLength;\n\n if (payloadLength === 126) {\n target.writeUInt16BE(dataLength, 2);\n } else if (payloadLength === 127) {\n target[2] = target[3] = 0;\n target.writeUIntBE(dataLength, 4, 6);\n }\n\n if (!options.mask) return [target, data];\n\n target[1] |= 0x80;\n target[offset - 4] = mask[0];\n target[offset - 3] = mask[1];\n target[offset - 2] = mask[2];\n target[offset - 1] = mask[3];\n\n if (skipMasking) return [target, data];\n\n if (merge) {\n applyMask(data, mask, target, offset, dataLength);\n return [target];\n }\n\n applyMask(data, mask, data, 0, dataLength);\n return [target, data];\n }\n\n /**\n * Sends a close message to the other peer.\n *\n * @param {Number} [code] The status code component of the body\n * @param {(String|Buffer)} [data] The message component of the body\n * @param {Boolean} [mask=false] Specifies whether or not to mask the message\n * @param {Function} [cb] Callback\n * @public\n */\n close(code, data, mask, cb) {\n let buf;\n\n if (code === undefined) {\n buf = EMPTY_BUFFER;\n } else if (typeof code !== 'number' || !isValidStatusCode(code)) {\n throw new TypeError('First argument must be a valid error code number');\n } else if (data === undefined || !data.length) {\n buf = Buffer.allocUnsafe(2);\n buf.writeUInt16BE(code, 0);\n } else {\n const length = Buffer.byteLength(data);\n\n if (length > 123) {\n throw new RangeError('The message must not be greater than 123 bytes');\n }\n\n buf = Buffer.allocUnsafe(2 + length);\n buf.writeUInt16BE(code, 0);\n\n if (typeof data === 'string') {\n buf.write(data, 2);\n } else {\n buf.set(data, 2);\n }\n }\n\n const options = {\n [kByteLength]: buf.length,\n fin: true,\n generateMask: this._generateMask,\n mask,\n maskBuffer: this._maskBuffer,\n opcode: 0x08,\n readOnly: false,\n rsv1: false\n };\n\n if (this._state !== DEFAULT) {\n this.enqueue([this.dispatch, buf, false, options, cb]);\n } else {\n this.sendFrame(Sender.frame(buf, options), cb);\n }\n }\n\n /**\n * Sends a ping message to the other peer.\n *\n * @param {*} data The message to send\n * @param {Boolean} [mask=false] Specifies whether or not to mask `data`\n * @param {Function} [cb] Callback\n * @public\n */\n ping(data, mask, cb) {\n let byteLength;\n let readOnly;\n\n if (typeof data === 'string') {\n byteLength = Buffer.byteLength(data);\n readOnly = false;\n } else if (isBlob(data)) {\n byteLength = data.size;\n readOnly = false;\n } else {\n data = toBuffer(data);\n byteLength = data.length;\n readOnly = toBuffer.readOnly;\n }\n\n if (byteLength > 125) {\n throw new RangeError('The data size must not be greater than 125 bytes');\n }\n\n const options = {\n [kByteLength]: byteLength,\n fin: true,\n generateMask: this._generateMask,\n mask,\n maskBuffer: this._maskBuffer,\n opcode: 0x09,\n readOnly,\n rsv1: false\n };\n\n if (isBlob(data)) {\n if (this._state !== DEFAULT) {\n this.enqueue([this.getBlobData, data, false, options, cb]);\n } else {\n this.getBlobData(data, false, options, cb);\n }\n } else if (this._state !== DEFAULT) {\n this.enqueue([this.dispatch, data, false, options, cb]);\n } else {\n this.sendFrame(Sender.frame(data, options), cb);\n }\n }\n\n /**\n * Sends a pong message to the other peer.\n *\n * @param {*} data The message to send\n * @param {Boolean} [mask=false] Specifies whether or not to mask `data`\n * @param {Function} [cb] Callback\n * @public\n */\n pong(data, mask, cb) {\n let byteLength;\n let readOnly;\n\n if (typeof data === 'string') {\n byteLength = Buffer.byteLength(data);\n readOnly = false;\n } else if (isBlob(data)) {\n byteLength = data.size;\n readOnly = false;\n } else {\n data = toBuffer(data);\n byteLength = data.length;\n readOnly = toBuffer.readOnly;\n }\n\n if (byteLength > 125) {\n throw new RangeError('The data size must not be greater than 125 bytes');\n }\n\n const options = {\n [kByteLength]: byteLength,\n fin: true,\n generateMask: this._generateMask,\n mask,\n maskBuffer: this._maskBuffer,\n opcode: 0x0a,\n readOnly,\n rsv1: false\n };\n\n if (isBlob(data)) {\n if (this._state !== DEFAULT) {\n this.enqueue([this.getBlobData, data, false, options, cb]);\n } else {\n this.getBlobData(data, false, options, cb);\n }\n } else if (this._state !== DEFAULT) {\n this.enqueue([this.dispatch, data, false, options, cb]);\n } else {\n this.sendFrame(Sender.frame(data, options), cb);\n }\n }\n\n /**\n * Sends a data message to the other peer.\n *\n * @param {*} data The message to send\n * @param {Object} options Options object\n * @param {Boolean} [options.binary=false] Specifies whether `data` is binary\n * or text\n * @param {Boolean} [options.compress=false] Specifies whether or not to\n * compress `data`\n * @param {Boolean} [options.fin=false] Specifies whether the fragment is the\n * last one\n * @param {Boolean} [options.mask=false] Specifies whether or not to mask\n * `data`\n * @param {Function} [cb] Callback\n * @public\n */\n send(data, options, cb) {\n const perMessageDeflate = this._extensions[PerMessageDeflate.extensionName];\n let opcode = options.binary ? 2 : 1;\n let rsv1 = options.compress;\n\n let byteLength;\n let readOnly;\n\n if (typeof data === 'string') {\n byteLength = Buffer.byteLength(data);\n readOnly = false;\n } else if (isBlob(data)) {\n byteLength = data.size;\n readOnly = false;\n } else {\n data = toBuffer(data);\n byteLength = data.length;\n readOnly = toBuffer.readOnly;\n }\n\n if (this._firstFragment) {\n this._firstFragment = false;\n if (\n rsv1 &&\n perMessageDeflate &&\n perMessageDeflate.params[\n perMessageDeflate._isServer\n ? 'server_no_context_takeover'\n : 'client_no_context_takeover'\n ]\n ) {\n rsv1 = byteLength >= perMessageDeflate._threshold;\n }\n this._compress = rsv1;\n } else {\n rsv1 = false;\n opcode = 0;\n }\n\n if (options.fin) this._firstFragment = true;\n\n const opts = {\n [kByteLength]: byteLength,\n fin: options.fin,\n generateMask: this._generateMask,\n mask: options.mask,\n maskBuffer: this._maskBuffer,\n opcode,\n readOnly,\n rsv1\n };\n\n if (isBlob(data)) {\n if (this._state !== DEFAULT) {\n this.enqueue([this.getBlobData, data, this._compress, opts, cb]);\n } else {\n this.getBlobData(data, this._compress, opts, cb);\n }\n } else if (this._state !== DEFAULT) {\n this.enqueue([this.dispatch, data, this._compress, opts, cb]);\n } else {\n this.dispatch(data, this._compress, opts, cb);\n }\n }\n\n /**\n * Gets the contents of a blob as binary data.\n *\n * @param {Blob} blob The blob\n * @param {Boolean} [compress=false] Specifies whether or not to compress\n * the data\n * @param {Object} options Options object\n * @param {Boolean} [options.fin=false] Specifies whether or not to set the\n * FIN bit\n * @param {Function} [options.generateMask] The function used to generate the\n * masking key\n * @param {Boolean} [options.mask=false] Specifies whether or not to mask\n * `data`\n * @param {Buffer} [options.maskBuffer] The buffer used to store the masking\n * key\n * @param {Number} options.opcode The opcode\n * @param {Boolean} [options.readOnly=false] Specifies whether `data` can be\n * modified\n * @param {Boolean} [options.rsv1=false] Specifies whether or not to set the\n * RSV1 bit\n * @param {Function} [cb] Callback\n * @private\n */\n getBlobData(blob, compress, options, cb) {\n this._bufferedBytes += options[kByteLength];\n this._state = GET_BLOB_DATA;\n\n blob\n .arrayBuffer()\n .then((arrayBuffer) => {\n if (this._socket.destroyed) {\n const err = new Error(\n 'The socket was closed while the blob was being read'\n );\n\n //\n // `callCallbacks` is called in the next tick to ensure that errors\n // that might be thrown in the callbacks behave like errors thrown\n // outside the promise chain.\n //\n process.nextTick(callCallbacks, this, err, cb);\n return;\n }\n\n this._bufferedBytes -= options[kByteLength];\n const data = toBuffer(arrayBuffer);\n\n if (!compress) {\n this._state = DEFAULT;\n this.sendFrame(Sender.frame(data, options), cb);\n this.dequeue();\n } else {\n this.dispatch(data, compress, options, cb);\n }\n })\n .catch((err) => {\n //\n // `onError` is called in the next tick for the same reason that\n // `callCallbacks` above is.\n //\n process.nextTick(onError, this, err, cb);\n });\n }\n\n /**\n * Dispatches a message.\n *\n * @param {(Buffer|String)} data The message to send\n * @param {Boolean} [compress=false] Specifies whether or not to compress\n * `data`\n * @param {Object} options Options object\n * @param {Boolean} [options.fin=false] Specifies whether or not to set the\n * FIN bit\n * @param {Function} [options.generateMask] The function used to generate the\n * masking key\n * @param {Boolean} [options.mask=false] Specifies whether or not to mask\n * `data`\n * @param {Buffer} [options.maskBuffer] The buffer used to store the masking\n * key\n * @param {Number} options.opcode The opcode\n * @param {Boolean} [options.readOnly=false] Specifies whether `data` can be\n * modified\n * @param {Boolean} [options.rsv1=false] Specifies whether or not to set the\n * RSV1 bit\n * @param {Function} [cb] Callback\n * @private\n */\n dispatch(data, compress, options, cb) {\n if (!compress) {\n this.sendFrame(Sender.frame(data, options), cb);\n return;\n }\n\n const perMessageDeflate = this._extensions[PerMessageDeflate.extensionName];\n\n this._bufferedBytes += options[kByteLength];\n this._state = DEFLATING;\n perMessageDeflate.compress(data, options.fin, (_, buf) => {\n if (this._socket.destroyed) {\n const err = new Error(\n 'The socket was closed while data was being compressed'\n );\n\n callCallbacks(this, err, cb);\n return;\n }\n\n this._bufferedBytes -= options[kByteLength];\n this._state = DEFAULT;\n options.readOnly = false;\n this.sendFrame(Sender.frame(buf, options), cb);\n this.dequeue();\n });\n }\n\n /**\n * Executes queued send operations.\n *\n * @private\n */\n dequeue() {\n while (this._state === DEFAULT && this._queue.length) {\n const params = this._queue.shift();\n\n this._bufferedBytes -= params[3][kByteLength];\n Reflect.apply(params[0], this, params.slice(1));\n }\n }\n\n /**\n * Enqueues a send operation.\n *\n * @param {Array} params Send operation parameters.\n * @private\n */\n enqueue(params) {\n this._bufferedBytes += params[3][kByteLength];\n this._queue.push(params);\n }\n\n /**\n * Sends a frame.\n *\n * @param {(Buffer | String)[]} list The frame to send\n * @param {Function} [cb] Callback\n * @private\n */\n sendFrame(list, cb) {\n if (list.length === 2) {\n this._socket.cork();\n this._socket.write(list[0]);\n this._socket.write(list[1], cb);\n this._socket.uncork();\n } else {\n this._socket.write(list[0], cb);\n }\n }\n}\n\nmodule.exports = Sender;\n\n/**\n * Calls queued callbacks with an error.\n *\n * @param {Sender} sender The `Sender` instance\n * @param {Error} err The error to call the callbacks with\n * @param {Function} [cb] The first callback\n * @private\n */\nfunction callCallbacks(sender, err, cb) {\n if (typeof cb === 'function') cb(err);\n\n for (let i = 0; i < sender._queue.length; i++) {\n const params = sender._queue[i];\n const callback = params[params.length - 1];\n\n if (typeof callback === 'function') callback(err);\n }\n}\n\n/**\n * Handles a `Sender` error.\n *\n * @param {Sender} sender The `Sender` instance\n * @param {Error} err The error\n * @param {Function} [cb] The first pending callback\n * @private\n */\nfunction onError(sender, err, cb) {\n callCallbacks(sender, err, cb);\n sender.onerror(err);\n}\n", "'use strict';\n\nconst { kForOnEventAttribute, kListener } = require('./constants');\n\nconst kCode = Symbol('kCode');\nconst kData = Symbol('kData');\nconst kError = Symbol('kError');\nconst kMessage = Symbol('kMessage');\nconst kReason = Symbol('kReason');\nconst kTarget = Symbol('kTarget');\nconst kType = Symbol('kType');\nconst kWasClean = Symbol('kWasClean');\n\n/**\n * Class representing an event.\n */\nclass Event {\n /**\n * Create a new `Event`.\n *\n * @param {String} type The name of the event\n * @throws {TypeError} If the `type` argument is not specified\n */\n constructor(type) {\n this[kTarget] = null;\n this[kType] = type;\n }\n\n /**\n * @type {*}\n */\n get target() {\n return this[kTarget];\n }\n\n /**\n * @type {String}\n */\n get type() {\n return this[kType];\n }\n}\n\nObject.defineProperty(Event.prototype, 'target', { enumerable: true });\nObject.defineProperty(Event.prototype, 'type', { enumerable: true });\n\n/**\n * Class representing a close event.\n *\n * @extends Event\n */\nclass CloseEvent extends Event {\n /**\n * Create a new `CloseEvent`.\n *\n * @param {String} type The name of the event\n * @param {Object} [options] A dictionary object that allows for setting\n * attributes via object members of the same name\n * @param {Number} [options.code=0] The status code explaining why the\n * connection was closed\n * @param {String} [options.reason=''] A human-readable string explaining why\n * the connection was closed\n * @param {Boolean} [options.wasClean=false] Indicates whether or not the\n * connection was cleanly closed\n */\n constructor(type, options = {}) {\n super(type);\n\n this[kCode] = options.code === undefined ? 0 : options.code;\n this[kReason] = options.reason === undefined ? '' : options.reason;\n this[kWasClean] = options.wasClean === undefined ? false : options.wasClean;\n }\n\n /**\n * @type {Number}\n */\n get code() {\n return this[kCode];\n }\n\n /**\n * @type {String}\n */\n get reason() {\n return this[kReason];\n }\n\n /**\n * @type {Boolean}\n */\n get wasClean() {\n return this[kWasClean];\n }\n}\n\nObject.defineProperty(CloseEvent.prototype, 'code', { enumerable: true });\nObject.defineProperty(CloseEvent.prototype, 'reason', { enumerable: true });\nObject.defineProperty(CloseEvent.prototype, 'wasClean', { enumerable: true });\n\n/**\n * Class representing an error event.\n *\n * @extends Event\n */\nclass ErrorEvent extends Event {\n /**\n * Create a new `ErrorEvent`.\n *\n * @param {String} type The name of the event\n * @param {Object} [options] A dictionary object that allows for setting\n * attributes via object members of the same name\n * @param {*} [options.error=null] The error that generated this event\n * @param {String} [options.message=''] The error message\n */\n constructor(type, options = {}) {\n super(type);\n\n this[kError] = options.error === undefined ? null : options.error;\n this[kMessage] = options.message === undefined ? '' : options.message;\n }\n\n /**\n * @type {*}\n */\n get error() {\n return this[kError];\n }\n\n /**\n * @type {String}\n */\n get message() {\n return this[kMessage];\n }\n}\n\nObject.defineProperty(ErrorEvent.prototype, 'error', { enumerable: true });\nObject.defineProperty(ErrorEvent.prototype, 'message', { enumerable: true });\n\n/**\n * Class representing a message event.\n *\n * @extends Event\n */\nclass MessageEvent extends Event {\n /**\n * Create a new `MessageEvent`.\n *\n * @param {String} type The name of the event\n * @param {Object} [options] A dictionary object that allows for setting\n * attributes via object members of the same name\n * @param {*} [options.data=null] The message content\n */\n constructor(type, options = {}) {\n super(type);\n\n this[kData] = options.data === undefined ? null : options.data;\n }\n\n /**\n * @type {*}\n */\n get data() {\n return this[kData];\n }\n}\n\nObject.defineProperty(MessageEvent.prototype, 'data', { enumerable: true });\n\n/**\n * This provides methods for emulating the `EventTarget` interface. It's not\n * meant to be used directly.\n *\n * @mixin\n */\nconst EventTarget = {\n /**\n * Register an event listener.\n *\n * @param {String} type A string representing the event type to listen for\n * @param {(Function|Object)} handler The listener to add\n * @param {Object} [options] An options object specifies characteristics about\n * the event listener\n * @param {Boolean} [options.once=false] A `Boolean` indicating that the\n * listener should be invoked at most once after being added. If `true`,\n * the listener would be automatically removed when invoked.\n * @public\n */\n addEventListener(type, handler, options = {}) {\n for (const listener of this.listeners(type)) {\n if (\n !options[kForOnEventAttribute] &&\n listener[kListener] === handler &&\n !listener[kForOnEventAttribute]\n ) {\n return;\n }\n }\n\n let wrapper;\n\n if (type === 'message') {\n wrapper = function onMessage(data, isBinary) {\n const event = new MessageEvent('message', {\n data: isBinary ? data : data.toString()\n });\n\n event[kTarget] = this;\n callListener(handler, this, event);\n };\n } else if (type === 'close') {\n wrapper = function onClose(code, message) {\n const event = new CloseEvent('close', {\n code,\n reason: message.toString(),\n wasClean: this._closeFrameReceived && this._closeFrameSent\n });\n\n event[kTarget] = this;\n callListener(handler, this, event);\n };\n } else if (type === 'error') {\n wrapper = function onError(error) {\n const event = new ErrorEvent('error', {\n error,\n message: error.message\n });\n\n event[kTarget] = this;\n callListener(handler, this, event);\n };\n } else if (type === 'open') {\n wrapper = function onOpen() {\n const event = new Event('open');\n\n event[kTarget] = this;\n callListener(handler, this, event);\n };\n } else {\n return;\n }\n\n wrapper[kForOnEventAttribute] = !!options[kForOnEventAttribute];\n wrapper[kListener] = handler;\n\n if (options.once) {\n this.once(type, wrapper);\n } else {\n this.on(type, wrapper);\n }\n },\n\n /**\n * Remove an event listener.\n *\n * @param {String} type A string representing the event type to remove\n * @param {(Function|Object)} handler The listener to remove\n * @public\n */\n removeEventListener(type, handler) {\n for (const listener of this.listeners(type)) {\n if (listener[kListener] === handler && !listener[kForOnEventAttribute]) {\n this.removeListener(type, listener);\n break;\n }\n }\n }\n};\n\nmodule.exports = {\n CloseEvent,\n ErrorEvent,\n Event,\n EventTarget,\n MessageEvent\n};\n\n/**\n * Call an event listener\n *\n * @param {(Function|Object)} listener The listener to call\n * @param {*} thisArg The value to use as `this`` when calling the listener\n * @param {Event} event The event to pass to the listener\n * @private\n */\nfunction callListener(listener, thisArg, event) {\n if (typeof listener === 'object' && listener.handleEvent) {\n listener.handleEvent.call(listener, event);\n } else {\n listener.call(thisArg, event);\n }\n}\n", "'use strict';\n\nconst { tokenChars } = require('./validation');\n\n/**\n * Adds an offer to the map of extension offers or a parameter to the map of\n * parameters.\n *\n * @param {Object} dest The map of extension offers or parameters\n * @param {String} name The extension or parameter name\n * @param {(Object|Boolean|String)} elem The extension parameters or the\n * parameter value\n * @private\n */\nfunction push(dest, name, elem) {\n if (dest[name] === undefined) dest[name] = [elem];\n else dest[name].push(elem);\n}\n\n/**\n * Parses the `Sec-WebSocket-Extensions` header into an object.\n *\n * @param {String} header The field value of the header\n * @return {Object} The parsed object\n * @public\n */\nfunction parse(header) {\n const offers = Object.create(null);\n let params = Object.create(null);\n let mustUnescape = false;\n let isEscaping = false;\n let inQuotes = false;\n let extensionName;\n let paramName;\n let start = -1;\n let code = -1;\n let end = -1;\n let i = 0;\n\n for (; i < header.length; i++) {\n code = header.charCodeAt(i);\n\n if (extensionName === undefined) {\n if (end === -1 && tokenChars[code] === 1) {\n if (start === -1) start = i;\n } else if (\n i !== 0 &&\n (code === 0x20 /* ' ' */ || code === 0x09) /* '\\t' */\n ) {\n if (end === -1 && start !== -1) end = i;\n } else if (code === 0x3b /* ';' */ || code === 0x2c /* ',' */) {\n if (start === -1) {\n throw new SyntaxError(`Unexpected character at index ${i}`);\n }\n\n if (end === -1) end = i;\n const name = header.slice(start, end);\n if (code === 0x2c) {\n push(offers, name, params);\n params = Object.create(null);\n } else {\n extensionName = name;\n }\n\n start = end = -1;\n } else {\n throw new SyntaxError(`Unexpected character at index ${i}`);\n }\n } else if (paramName === undefined) {\n if (end === -1 && tokenChars[code] === 1) {\n if (start === -1) start = i;\n } else if (code === 0x20 || code === 0x09) {\n if (end === -1 && start !== -1) end = i;\n } else if (code === 0x3b || code === 0x2c) {\n if (start === -1) {\n throw new SyntaxError(`Unexpected character at index ${i}`);\n }\n\n if (end === -1) end = i;\n push(params, header.slice(start, end), true);\n if (code === 0x2c) {\n push(offers, extensionName, params);\n params = Object.create(null);\n extensionName = undefined;\n }\n\n start = end = -1;\n } else if (code === 0x3d /* '=' */ && start !== -1 && end === -1) {\n paramName = header.slice(start, i);\n start = end = -1;\n } else {\n throw new SyntaxError(`Unexpected character at index ${i}`);\n }\n } else {\n //\n // The value of a quoted-string after unescaping must conform to the\n // token ABNF, so only token characters are valid.\n // Ref: https://tools.ietf.org/html/rfc6455#section-9.1\n //\n if (isEscaping) {\n if (tokenChars[code] !== 1) {\n throw new SyntaxError(`Unexpected character at index ${i}`);\n }\n if (start === -1) start = i;\n else if (!mustUnescape) mustUnescape = true;\n isEscaping = false;\n } else if (inQuotes) {\n if (tokenChars[code] === 1) {\n if (start === -1) start = i;\n } else if (code === 0x22 /* '\"' */ && start !== -1) {\n inQuotes = false;\n end = i;\n } else if (code === 0x5c /* '\\' */) {\n isEscaping = true;\n } else {\n throw new SyntaxError(`Unexpected character at index ${i}`);\n }\n } else if (code === 0x22 && header.charCodeAt(i - 1) === 0x3d) {\n inQuotes = true;\n } else if (end === -1 && tokenChars[code] === 1) {\n if (start === -1) start = i;\n } else if (start !== -1 && (code === 0x20 || code === 0x09)) {\n if (end === -1) end = i;\n } else if (code === 0x3b || code === 0x2c) {\n if (start === -1) {\n throw new SyntaxError(`Unexpected character at index ${i}`);\n }\n\n if (end === -1) end = i;\n let value = header.slice(start, end);\n if (mustUnescape) {\n value = value.replace(/\\\\/g, '');\n mustUnescape = false;\n }\n push(params, paramName, value);\n if (code === 0x2c) {\n push(offers, extensionName, params);\n params = Object.create(null);\n extensionName = undefined;\n }\n\n paramName = undefined;\n start = end = -1;\n } else {\n throw new SyntaxError(`Unexpected character at index ${i}`);\n }\n }\n }\n\n if (start === -1 || inQuotes || code === 0x20 || code === 0x09) {\n throw new SyntaxError('Unexpected end of input');\n }\n\n if (end === -1) end = i;\n const token = header.slice(start, end);\n if (extensionName === undefined) {\n push(offers, token, params);\n } else {\n if (paramName === undefined) {\n push(params, token, true);\n } else if (mustUnescape) {\n push(params, paramName, token.replace(/\\\\/g, ''));\n } else {\n push(params, paramName, token);\n }\n push(offers, extensionName, params);\n }\n\n return offers;\n}\n\n/**\n * Builds the `Sec-WebSocket-Extensions` header field value.\n *\n * @param {Object} extensions The map of extensions and parameters to format\n * @return {String} A string representing the given object\n * @public\n */\nfunction format(extensions) {\n return Object.keys(extensions)\n .map((extension) => {\n let configurations = extensions[extension];\n if (!Array.isArray(configurations)) configurations = [configurations];\n return configurations\n .map((params) => {\n return [extension]\n .concat(\n Object.keys(params).map((k) => {\n let values = params[k];\n if (!Array.isArray(values)) values = [values];\n return values\n .map((v) => (v === true ? k : `${k}=${v}`))\n .join('; ');\n })\n )\n .join('; ');\n })\n .join(', ');\n })\n .join(', ');\n}\n\nmodule.exports = { format, parse };\n", "/* eslint no-unused-vars: [\"error\", { \"varsIgnorePattern\": \"^Duplex|Readable$\", \"caughtErrors\": \"none\" }] */\n\n'use strict';\n\nconst EventEmitter = require('events');\nconst https = require('https');\nconst http = require('http');\nconst net = require('net');\nconst tls = require('tls');\nconst { randomBytes, createHash } = require('crypto');\nconst { Duplex, Readable } = require('stream');\nconst { URL } = require('url');\n\nconst PerMessageDeflate = require('./permessage-deflate');\nconst Receiver = require('./receiver');\nconst Sender = require('./sender');\nconst { isBlob } = require('./validation');\n\nconst {\n BINARY_TYPES,\n EMPTY_BUFFER,\n GUID,\n kForOnEventAttribute,\n kListener,\n kStatusCode,\n kWebSocket,\n NOOP\n} = require('./constants');\nconst {\n EventTarget: { addEventListener, removeEventListener }\n} = require('./event-target');\nconst { format, parse } = require('./extension');\nconst { toBuffer } = require('./buffer-util');\n\nconst closeTimeout = 30 * 1000;\nconst kAborted = Symbol('kAborted');\nconst protocolVersions = [8, 13];\nconst readyStates = ['CONNECTING', 'OPEN', 'CLOSING', 'CLOSED'];\nconst subprotocolRegex = /^[!#$%&'*+\\-.0-9A-Z^_`|a-z~]+$/;\n\n/**\n * Class representing a WebSocket.\n *\n * @extends EventEmitter\n */\nclass WebSocket extends EventEmitter {\n /**\n * Create a new `WebSocket`.\n *\n * @param {(String|URL)} address The URL to which to connect\n * @param {(String|String[])} [protocols] The subprotocols\n * @param {Object} [options] Connection options\n */\n constructor(address, protocols, options) {\n super();\n\n this._binaryType = BINARY_TYPES[0];\n this._closeCode = 1006;\n this._closeFrameReceived = false;\n this._closeFrameSent = false;\n this._closeMessage = EMPTY_BUFFER;\n this._closeTimer = null;\n this._errorEmitted = false;\n this._extensions = {};\n this._paused = false;\n this._protocol = '';\n this._readyState = WebSocket.CONNECTING;\n this._receiver = null;\n this._sender = null;\n this._socket = null;\n\n if (address !== null) {\n this._bufferedAmount = 0;\n this._isServer = false;\n this._redirects = 0;\n\n if (protocols === undefined) {\n protocols = [];\n } else if (!Array.isArray(protocols)) {\n if (typeof protocols === 'object' && protocols !== null) {\n options = protocols;\n protocols = [];\n } else {\n protocols = [protocols];\n }\n }\n\n initAsClient(this, address, protocols, options);\n } else {\n this._autoPong = options.autoPong;\n this._isServer = true;\n }\n }\n\n /**\n * For historical reasons, the custom \"nodebuffer\" type is used by the default\n * instead of \"blob\".\n *\n * @type {String}\n */\n get binaryType() {\n return this._binaryType;\n }\n\n set binaryType(type) {\n if (!BINARY_TYPES.includes(type)) return;\n\n this._binaryType = type;\n\n //\n // Allow to change `binaryType` on the fly.\n //\n if (this._receiver) this._receiver._binaryType = type;\n }\n\n /**\n * @type {Number}\n */\n get bufferedAmount() {\n if (!this._socket) return this._bufferedAmount;\n\n return this._socket._writableState.length + this._sender._bufferedBytes;\n }\n\n /**\n * @type {String}\n */\n get extensions() {\n return Object.keys(this._extensions).join();\n }\n\n /**\n * @type {Boolean}\n */\n get isPaused() {\n return this._paused;\n }\n\n /**\n * @type {Function}\n */\n /* istanbul ignore next */\n get onclose() {\n return null;\n }\n\n /**\n * @type {Function}\n */\n /* istanbul ignore next */\n get onerror() {\n return null;\n }\n\n /**\n * @type {Function}\n */\n /* istanbul ignore next */\n get onopen() {\n return null;\n }\n\n /**\n * @type {Function}\n */\n /* istanbul ignore next */\n get onmessage() {\n return null;\n }\n\n /**\n * @type {String}\n */\n get protocol() {\n return this._protocol;\n }\n\n /**\n * @type {Number}\n */\n get readyState() {\n return this._readyState;\n }\n\n /**\n * @type {String}\n */\n get url() {\n return this._url;\n }\n\n /**\n * Set up the socket and the internal resources.\n *\n * @param {Duplex} socket The network socket between the server and client\n * @param {Buffer} head The first packet of the upgraded stream\n * @param {Object} options Options object\n * @param {Boolean} [options.allowSynchronousEvents=false] Specifies whether\n * any of the `'message'`, `'ping'`, and `'pong'` events can be emitted\n * multiple times in the same tick\n * @param {Function} [options.generateMask] The function used to generate the\n * masking key\n * @param {Number} [options.maxPayload=0] The maximum allowed message size\n * @param {Boolean} [options.skipUTF8Validation=false] Specifies whether or\n * not to skip UTF-8 validation for text and close messages\n * @private\n */\n setSocket(socket, head, options) {\n const receiver = new Receiver({\n allowSynchronousEvents: options.allowSynchronousEvents,\n binaryType: this.binaryType,\n extensions: this._extensions,\n isServer: this._isServer,\n maxPayload: options.maxPayload,\n skipUTF8Validation: options.skipUTF8Validation\n });\n\n const sender = new Sender(socket, this._extensions, options.generateMask);\n\n this._receiver = receiver;\n this._sender = sender;\n this._socket = socket;\n\n receiver[kWebSocket] = this;\n sender[kWebSocket] = this;\n socket[kWebSocket] = this;\n\n receiver.on('conclude', receiverOnConclude);\n receiver.on('drain', receiverOnDrain);\n receiver.on('error', receiverOnError);\n receiver.on('message', receiverOnMessage);\n receiver.on('ping', receiverOnPing);\n receiver.on('pong', receiverOnPong);\n\n sender.onerror = senderOnError;\n\n //\n // These methods may not be available if `socket` is just a `Duplex`.\n //\n if (socket.setTimeout) socket.setTimeout(0);\n if (socket.setNoDelay) socket.setNoDelay();\n\n if (head.length > 0) socket.unshift(head);\n\n socket.on('close', socketOnClose);\n socket.on('data', socketOnData);\n socket.on('end', socketOnEnd);\n socket.on('error', socketOnError);\n\n this._readyState = WebSocket.OPEN;\n this.emit('open');\n }\n\n /**\n * Emit the `'close'` event.\n *\n * @private\n */\n emitClose() {\n if (!this._socket) {\n this._readyState = WebSocket.CLOSED;\n this.emit('close', this._closeCode, this._closeMessage);\n return;\n }\n\n if (this._extensions[PerMessageDeflate.extensionName]) {\n this._extensions[PerMessageDeflate.extensionName].cleanup();\n }\n\n this._receiver.removeAllListeners();\n this._readyState = WebSocket.CLOSED;\n this.emit('close', this._closeCode, this._closeMessage);\n }\n\n /**\n * Start a closing handshake.\n *\n * +----------+ +-----------+ +----------+\n * - - -|ws.close()|-->|close frame|-->|ws.close()|- - -\n * | +----------+ +-----------+ +----------+ |\n * +----------+ +-----------+ |\n * CLOSING |ws.close()|<--|close frame|<--+-----+ CLOSING\n * +----------+ +-----------+ |\n * | | | +---+ |\n * +------------------------+-->|fin| - - - -\n * | +---+ | +---+\n * - - - - -|fin|<---------------------+\n * +---+\n *\n * @param {Number} [code] Status code explaining why the connection is closing\n * @param {(String|Buffer)} [data] The reason why the connection is\n * closing\n * @public\n */\n close(code, data) {\n if (this.readyState === WebSocket.CLOSED) return;\n if (this.readyState === WebSocket.CONNECTING) {\n const msg = 'WebSocket was closed before the connection was established';\n abortHandshake(this, this._req, msg);\n return;\n }\n\n if (this.readyState === WebSocket.CLOSING) {\n if (\n this._closeFrameSent &&\n (this._closeFrameReceived || this._receiver._writableState.errorEmitted)\n ) {\n this._socket.end();\n }\n\n return;\n }\n\n this._readyState = WebSocket.CLOSING;\n this._sender.close(code, data, !this._isServer, (err) => {\n //\n // This error is handled by the `'error'` listener on the socket. We only\n // want to know if the close frame has been sent here.\n //\n if (err) return;\n\n this._closeFrameSent = true;\n\n if (\n this._closeFrameReceived ||\n this._receiver._writableState.errorEmitted\n ) {\n this._socket.end();\n }\n });\n\n setCloseTimer(this);\n }\n\n /**\n * Pause the socket.\n *\n * @public\n */\n pause() {\n if (\n this.readyState === WebSocket.CONNECTING ||\n this.readyState === WebSocket.CLOSED\n ) {\n return;\n }\n\n this._paused = true;\n this._socket.pause();\n }\n\n /**\n * Send a ping.\n *\n * @param {*} [data] The data to send\n * @param {Boolean} [mask] Indicates whether or not to mask `data`\n * @param {Function} [cb] Callback which is executed when the ping is sent\n * @public\n */\n ping(data, mask, cb) {\n if (this.readyState === WebSocket.CONNECTING) {\n throw new Error('WebSocket is not open: readyState 0 (CONNECTING)');\n }\n\n if (typeof data === 'function') {\n cb = data;\n data = mask = undefined;\n } else if (typeof mask === 'function') {\n cb = mask;\n mask = undefined;\n }\n\n if (typeof data === 'number') data = data.toString();\n\n if (this.readyState !== WebSocket.OPEN) {\n sendAfterClose(this, data, cb);\n return;\n }\n\n if (mask === undefined) mask = !this._isServer;\n this._sender.ping(data || EMPTY_BUFFER, mask, cb);\n }\n\n /**\n * Send a pong.\n *\n * @param {*} [data] The data to send\n * @param {Boolean} [mask] Indicates whether or not to mask `data`\n * @param {Function} [cb] Callback which is executed when the pong is sent\n * @public\n */\n pong(data, mask, cb) {\n if (this.readyState === WebSocket.CONNECTING) {\n throw new Error('WebSocket is not open: readyState 0 (CONNECTING)');\n }\n\n if (typeof data === 'function') {\n cb = data;\n data = mask = undefined;\n } else if (typeof mask === 'function') {\n cb = mask;\n mask = undefined;\n }\n\n if (typeof data === 'number') data = data.toString();\n\n if (this.readyState !== WebSocket.OPEN) {\n sendAfterClose(this, data, cb);\n return;\n }\n\n if (mask === undefined) mask = !this._isServer;\n this._sender.pong(data || EMPTY_BUFFER, mask, cb);\n }\n\n /**\n * Resume the socket.\n *\n * @public\n */\n resume() {\n if (\n this.readyState === WebSocket.CONNECTING ||\n this.readyState === WebSocket.CLOSED\n ) {\n return;\n }\n\n this._paused = false;\n if (!this._receiver._writableState.needDrain) this._socket.resume();\n }\n\n /**\n * Send a data message.\n *\n * @param {*} data The message to send\n * @param {Object} [options] Options object\n * @param {Boolean} [options.binary] Specifies whether `data` is binary or\n * text\n * @param {Boolean} [options.compress] Specifies whether or not to compress\n * `data`\n * @param {Boolean} [options.fin=true] Specifies whether the fragment is the\n * last one\n * @param {Boolean} [options.mask] Specifies whether or not to mask `data`\n * @param {Function} [cb] Callback which is executed when data is written out\n * @public\n */\n send(data, options, cb) {\n if (this.readyState === WebSocket.CONNECTING) {\n throw new Error('WebSocket is not open: readyState 0 (CONNECTING)');\n }\n\n if (typeof options === 'function') {\n cb = options;\n options = {};\n }\n\n if (typeof data === 'number') data = data.toString();\n\n if (this.readyState !== WebSocket.OPEN) {\n sendAfterClose(this, data, cb);\n return;\n }\n\n const opts = {\n binary: typeof data !== 'string',\n mask: !this._isServer,\n compress: true,\n fin: true,\n ...options\n };\n\n if (!this._extensions[PerMessageDeflate.extensionName]) {\n opts.compress = false;\n }\n\n this._sender.send(data || EMPTY_BUFFER, opts, cb);\n }\n\n /**\n * Forcibly close the connection.\n *\n * @public\n */\n terminate() {\n if (this.readyState === WebSocket.CLOSED) return;\n if (this.readyState === WebSocket.CONNECTING) {\n const msg = 'WebSocket was closed before the connection was established';\n abortHandshake(this, this._req, msg);\n return;\n }\n\n if (this._socket) {\n this._readyState = WebSocket.CLOSING;\n this._socket.destroy();\n }\n }\n}\n\n/**\n * @constant {Number} CONNECTING\n * @memberof WebSocket\n */\nObject.defineProperty(WebSocket, 'CONNECTING', {\n enumerable: true,\n value: readyStates.indexOf('CONNECTING')\n});\n\n/**\n * @constant {Number} CONNECTING\n * @memberof WebSocket.prototype\n */\nObject.defineProperty(WebSocket.prototype, 'CONNECTING', {\n enumerable: true,\n value: readyStates.indexOf('CONNECTING')\n});\n\n/**\n * @constant {Number} OPEN\n * @memberof WebSocket\n */\nObject.defineProperty(WebSocket, 'OPEN', {\n enumerable: true,\n value: readyStates.indexOf('OPEN')\n});\n\n/**\n * @constant {Number} OPEN\n * @memberof WebSocket.prototype\n */\nObject.defineProperty(WebSocket.prototype, 'OPEN', {\n enumerable: true,\n value: readyStates.indexOf('OPEN')\n});\n\n/**\n * @constant {Number} CLOSING\n * @memberof WebSocket\n */\nObject.defineProperty(WebSocket, 'CLOSING', {\n enumerable: true,\n value: readyStates.indexOf('CLOSING')\n});\n\n/**\n * @constant {Number} CLOSING\n * @memberof WebSocket.prototype\n */\nObject.defineProperty(WebSocket.prototype, 'CLOSING', {\n enumerable: true,\n value: readyStates.indexOf('CLOSING')\n});\n\n/**\n * @constant {Number} CLOSED\n * @memberof WebSocket\n */\nObject.defineProperty(WebSocket, 'CLOSED', {\n enumerable: true,\n value: readyStates.indexOf('CLOSED')\n});\n\n/**\n * @constant {Number} CLOSED\n * @memberof WebSocket.prototype\n */\nObject.defineProperty(WebSocket.prototype, 'CLOSED', {\n enumerable: true,\n value: readyStates.indexOf('CLOSED')\n});\n\n[\n 'binaryType',\n 'bufferedAmount',\n 'extensions',\n 'isPaused',\n 'protocol',\n 'readyState',\n 'url'\n].forEach((property) => {\n Object.defineProperty(WebSocket.prototype, property, { enumerable: true });\n});\n\n//\n// Add the `onopen`, `onerror`, `onclose`, and `onmessage` attributes.\n// See https://html.spec.whatwg.org/multipage/comms.html#the-websocket-interface\n//\n['open', 'error', 'close', 'message'].forEach((method) => {\n Object.defineProperty(WebSocket.prototype, `on${method}`, {\n enumerable: true,\n get() {\n for (const listener of this.listeners(method)) {\n if (listener[kForOnEventAttribute]) return listener[kListener];\n }\n\n return null;\n },\n set(handler) {\n for (const listener of this.listeners(method)) {\n if (listener[kForOnEventAttribute]) {\n this.removeListener(method, listener);\n break;\n }\n }\n\n if (typeof handler !== 'function') return;\n\n this.addEventListener(method, handler, {\n [kForOnEventAttribute]: true\n });\n }\n });\n});\n\nWebSocket.prototype.addEventListener = addEventListener;\nWebSocket.prototype.removeEventListener = removeEventListener;\n\nmodule.exports = WebSocket;\n\n/**\n * Initialize a WebSocket client.\n *\n * @param {WebSocket} websocket The client to initialize\n * @param {(String|URL)} address The URL to which to connect\n * @param {Array} protocols The subprotocols\n * @param {Object} [options] Connection options\n * @param {Boolean} [options.allowSynchronousEvents=true] Specifies whether any\n * of the `'message'`, `'ping'`, and `'pong'` events can be emitted multiple\n * times in the same tick\n * @param {Boolean} [options.autoPong=true] Specifies whether or not to\n * automatically send a pong in response to a ping\n * @param {Function} [options.finishRequest] A function which can be used to\n * customize the headers of each http request before it is sent\n * @param {Boolean} [options.followRedirects=false] Whether or not to follow\n * redirects\n * @param {Function} [options.generateMask] The function used to generate the\n * masking key\n * @param {Number} [options.handshakeTimeout] Timeout in milliseconds for the\n * handshake request\n * @param {Number} [options.maxPayload=104857600] The maximum allowed message\n * size\n * @param {Number} [options.maxRedirects=10] The maximum number of redirects\n * allowed\n * @param {String} [options.origin] Value of the `Origin` or\n * `Sec-WebSocket-Origin` header\n * @param {(Boolean|Object)} [options.perMessageDeflate=true] Enable/disable\n * permessage-deflate\n * @param {Number} [options.protocolVersion=13] Value of the\n * `Sec-WebSocket-Version` header\n * @param {Boolean} [options.skipUTF8Validation=false] Specifies whether or\n * not to skip UTF-8 validation for text and close messages\n * @private\n */\nfunction initAsClient(websocket, address, protocols, options) {\n const opts = {\n allowSynchronousEvents: true,\n autoPong: true,\n protocolVersion: protocolVersions[1],\n maxPayload: 100 * 1024 * 1024,\n skipUTF8Validation: false,\n perMessageDeflate: true,\n followRedirects: false,\n maxRedirects: 10,\n ...options,\n socketPath: undefined,\n hostname: undefined,\n protocol: undefined,\n timeout: undefined,\n method: 'GET',\n host: undefined,\n path: undefined,\n port: undefined\n };\n\n websocket._autoPong = opts.autoPong;\n\n if (!protocolVersions.includes(opts.protocolVersion)) {\n throw new RangeError(\n `Unsupported protocol version: ${opts.protocolVersion} ` +\n `(supported versions: ${protocolVersions.join(', ')})`\n );\n }\n\n let parsedUrl;\n\n if (address instanceof URL) {\n parsedUrl = address;\n } else {\n try {\n parsedUrl = new URL(address);\n } catch (e) {\n throw new SyntaxError(`Invalid URL: ${address}`);\n }\n }\n\n if (parsedUrl.protocol === 'http:') {\n parsedUrl.protocol = 'ws:';\n } else if (parsedUrl.protocol === 'https:') {\n parsedUrl.protocol = 'wss:';\n }\n\n websocket._url = parsedUrl.href;\n\n const isSecure = parsedUrl.protocol === 'wss:';\n const isIpcUrl = parsedUrl.protocol === 'ws+unix:';\n let invalidUrlMessage;\n\n if (parsedUrl.protocol !== 'ws:' && !isSecure && !isIpcUrl) {\n invalidUrlMessage =\n 'The URL\\'s protocol must be one of \"ws:\", \"wss:\", ' +\n '\"http:\", \"https:\", or \"ws+unix:\"';\n } else if (isIpcUrl && !parsedUrl.pathname) {\n invalidUrlMessage = \"The URL's pathname is empty\";\n } else if (parsedUrl.hash) {\n invalidUrlMessage = 'The URL contains a fragment identifier';\n }\n\n if (invalidUrlMessage) {\n const err = new SyntaxError(invalidUrlMessage);\n\n if (websocket._redirects === 0) {\n throw err;\n } else {\n emitErrorAndClose(websocket, err);\n return;\n }\n }\n\n const defaultPort = isSecure ? 443 : 80;\n const key = randomBytes(16).toString('base64');\n const request = isSecure ? https.request : http.request;\n const protocolSet = new Set();\n let perMessageDeflate;\n\n opts.createConnection =\n opts.createConnection || (isSecure ? tlsConnect : netConnect);\n opts.defaultPort = opts.defaultPort || defaultPort;\n opts.port = parsedUrl.port || defaultPort;\n opts.host = parsedUrl.hostname.startsWith('[')\n ? parsedUrl.hostname.slice(1, -1)\n : parsedUrl.hostname;\n opts.headers = {\n ...opts.headers,\n 'Sec-WebSocket-Version': opts.protocolVersion,\n 'Sec-WebSocket-Key': key,\n Connection: 'Upgrade',\n Upgrade: 'websocket'\n };\n opts.path = parsedUrl.pathname + parsedUrl.search;\n opts.timeout = opts.handshakeTimeout;\n\n if (opts.perMessageDeflate) {\n perMessageDeflate = new PerMessageDeflate(\n opts.perMessageDeflate !== true ? opts.perMessageDeflate : {},\n false,\n opts.maxPayload\n );\n opts.headers['Sec-WebSocket-Extensions'] = format({\n [PerMessageDeflate.extensionName]: perMessageDeflate.offer()\n });\n }\n if (protocols.length) {\n for (const protocol of protocols) {\n if (\n typeof protocol !== 'string' ||\n !subprotocolRegex.test(protocol) ||\n protocolSet.has(protocol)\n ) {\n throw new SyntaxError(\n 'An invalid or duplicated subprotocol was specified'\n );\n }\n\n protocolSet.add(protocol);\n }\n\n opts.headers['Sec-WebSocket-Protocol'] = protocols.join(',');\n }\n if (opts.origin) {\n if (opts.protocolVersion < 13) {\n opts.headers['Sec-WebSocket-Origin'] = opts.origin;\n } else {\n opts.headers.Origin = opts.origin;\n }\n }\n if (parsedUrl.username || parsedUrl.password) {\n opts.auth = `${parsedUrl.username}:${parsedUrl.password}`;\n }\n\n if (isIpcUrl) {\n const parts = opts.path.split(':');\n\n opts.socketPath = parts[0];\n opts.path = parts[1];\n }\n\n let req;\n\n if (opts.followRedirects) {\n if (websocket._redirects === 0) {\n websocket._originalIpc = isIpcUrl;\n websocket._originalSecure = isSecure;\n websocket._originalHostOrSocketPath = isIpcUrl\n ? opts.socketPath\n : parsedUrl.host;\n\n const headers = options && options.headers;\n\n //\n // Shallow copy the user provided options so that headers can be changed\n // without mutating the original object.\n //\n options = { ...options, headers: {} };\n\n if (headers) {\n for (const [key, value] of Object.entries(headers)) {\n options.headers[key.toLowerCase()] = value;\n }\n }\n } else if (websocket.listenerCount('redirect') === 0) {\n const isSameHost = isIpcUrl\n ? websocket._originalIpc\n ? opts.socketPath === websocket._originalHostOrSocketPath\n : false\n : websocket._originalIpc\n ? false\n : parsedUrl.host === websocket._originalHostOrSocketPath;\n\n if (!isSameHost || (websocket._originalSecure && !isSecure)) {\n //\n // Match curl 7.77.0 behavior and drop the following headers. These\n // headers are also dropped when following a redirect to a subdomain.\n //\n delete opts.headers.authorization;\n delete opts.headers.cookie;\n\n if (!isSameHost) delete opts.headers.host;\n\n opts.auth = undefined;\n }\n }\n\n //\n // Match curl 7.77.0 behavior and make the first `Authorization` header win.\n // If the `Authorization` header is set, then there is nothing to do as it\n // will take precedence.\n //\n if (opts.auth && !options.headers.authorization) {\n options.headers.authorization =\n 'Basic ' + Buffer.from(opts.auth).toString('base64');\n }\n\n req = websocket._req = request(opts);\n\n if (websocket._redirects) {\n //\n // Unlike what is done for the `'upgrade'` event, no early exit is\n // triggered here if the user calls `websocket.close()` or\n // `websocket.terminate()` from a listener of the `'redirect'` event. This\n // is because the user can also call `request.destroy()` with an error\n // before calling `websocket.close()` or `websocket.terminate()` and this\n // would result in an error being emitted on the `request` object with no\n // `'error'` event listeners attached.\n //\n websocket.emit('redirect', websocket.url, req);\n }\n } else {\n req = websocket._req = request(opts);\n }\n\n if (opts.timeout) {\n req.on('timeout', () => {\n abortHandshake(websocket, req, 'Opening handshake has timed out');\n });\n }\n\n req.on('error', (err) => {\n if (req === null || req[kAborted]) return;\n\n req = websocket._req = null;\n emitErrorAndClose(websocket, err);\n });\n\n req.on('response', (res) => {\n const location = res.headers.location;\n const statusCode = res.statusCode;\n\n if (\n location &&\n opts.followRedirects &&\n statusCode >= 300 &&\n statusCode < 400\n ) {\n if (++websocket._redirects > opts.maxRedirects) {\n abortHandshake(websocket, req, 'Maximum redirects exceeded');\n return;\n }\n\n req.abort();\n\n let addr;\n\n try {\n addr = new URL(location, address);\n } catch (e) {\n const err = new SyntaxError(`Invalid URL: ${location}`);\n emitErrorAndClose(websocket, err);\n return;\n }\n\n initAsClient(websocket, addr, protocols, options);\n } else if (!websocket.emit('unexpected-response', req, res)) {\n abortHandshake(\n websocket,\n req,\n `Unexpected server response: ${res.statusCode}`\n );\n }\n });\n\n req.on('upgrade', (res, socket, head) => {\n websocket.emit('upgrade', res);\n\n //\n // The user may have closed the connection from a listener of the\n // `'upgrade'` event.\n //\n if (websocket.readyState !== WebSocket.CONNECTING) return;\n\n req = websocket._req = null;\n\n const upgrade = res.headers.upgrade;\n\n if (upgrade === undefined || upgrade.toLowerCase() !== 'websocket') {\n abortHandshake(websocket, socket, 'Invalid Upgrade header');\n return;\n }\n\n const digest = createHash('sha1')\n .update(key + GUID)\n .digest('base64');\n\n if (res.headers['sec-websocket-accept'] !== digest) {\n abortHandshake(websocket, socket, 'Invalid Sec-WebSocket-Accept header');\n return;\n }\n\n const serverProt = res.headers['sec-websocket-protocol'];\n let protError;\n\n if (serverProt !== undefined) {\n if (!protocolSet.size) {\n protError = 'Server sent a subprotocol but none was requested';\n } else if (!protocolSet.has(serverProt)) {\n protError = 'Server sent an invalid subprotocol';\n }\n } else if (protocolSet.size) {\n protError = 'Server sent no subprotocol';\n }\n\n if (protError) {\n abortHandshake(websocket, socket, protError);\n return;\n }\n\n if (serverProt) websocket._protocol = serverProt;\n\n const secWebSocketExtensions = res.headers['sec-websocket-extensions'];\n\n if (secWebSocketExtensions !== undefined) {\n if (!perMessageDeflate) {\n const message =\n 'Server sent a Sec-WebSocket-Extensions header but no extension ' +\n 'was requested';\n abortHandshake(websocket, socket, message);\n return;\n }\n\n let extensions;\n\n try {\n extensions = parse(secWebSocketExtensions);\n } catch (err) {\n const message = 'Invalid Sec-WebSocket-Extensions header';\n abortHandshake(websocket, socket, message);\n return;\n }\n\n const extensionNames = Object.keys(extensions);\n\n if (\n extensionNames.length !== 1 ||\n extensionNames[0] !== PerMessageDeflate.extensionName\n ) {\n const message = 'Server indicated an extension that was not requested';\n abortHandshake(websocket, socket, message);\n return;\n }\n\n try {\n perMessageDeflate.accept(extensions[PerMessageDeflate.extensionName]);\n } catch (err) {\n const message = 'Invalid Sec-WebSocket-Extensions header';\n abortHandshake(websocket, socket, message);\n return;\n }\n\n websocket._extensions[PerMessageDeflate.extensionName] =\n perMessageDeflate;\n }\n\n websocket.setSocket(socket, head, {\n allowSynchronousEvents: opts.allowSynchronousEvents,\n generateMask: opts.generateMask,\n maxPayload: opts.maxPayload,\n skipUTF8Validation: opts.skipUTF8Validation\n });\n });\n\n if (opts.finishRequest) {\n opts.finishRequest(req, websocket);\n } else {\n req.end();\n }\n}\n\n/**\n * Emit the `'error'` and `'close'` events.\n *\n * @param {WebSocket} websocket The WebSocket instance\n * @param {Error} The error to emit\n * @private\n */\nfunction emitErrorAndClose(websocket, err) {\n websocket._readyState = WebSocket.CLOSING;\n //\n // The following assignment is practically useless and is done only for\n // consistency.\n //\n websocket._errorEmitted = true;\n websocket.emit('error', err);\n websocket.emitClose();\n}\n\n/**\n * Create a `net.Socket` and initiate a connection.\n *\n * @param {Object} options Connection options\n * @return {net.Socket} The newly created socket used to start the connection\n * @private\n */\nfunction netConnect(options) {\n options.path = options.socketPath;\n return net.connect(options);\n}\n\n/**\n * Create a `tls.TLSSocket` and initiate a connection.\n *\n * @param {Object} options Connection options\n * @return {tls.TLSSocket} The newly created socket used to start the connection\n * @private\n */\nfunction tlsConnect(options) {\n options.path = undefined;\n\n if (!options.servername && options.servername !== '') {\n options.servername = net.isIP(options.host) ? '' : options.host;\n }\n\n return tls.connect(options);\n}\n\n/**\n * Abort the handshake and emit an error.\n *\n * @param {WebSocket} websocket The WebSocket instance\n * @param {(http.ClientRequest|net.Socket|tls.Socket)} stream The request to\n * abort or the socket to destroy\n * @param {String} message The error message\n * @private\n */\nfunction abortHandshake(websocket, stream, message) {\n websocket._readyState = WebSocket.CLOSING;\n\n const err = new Error(message);\n Error.captureStackTrace(err, abortHandshake);\n\n if (stream.setHeader) {\n stream[kAborted] = true;\n stream.abort();\n\n if (stream.socket && !stream.socket.destroyed) {\n //\n // On Node.js >= 14.3.0 `request.abort()` does not destroy the socket if\n // called after the request completed. See\n // https://github.com/websockets/ws/issues/1869.\n //\n stream.socket.destroy();\n }\n\n process.nextTick(emitErrorAndClose, websocket, err);\n } else {\n stream.destroy(err);\n stream.once('error', websocket.emit.bind(websocket, 'error'));\n stream.once('close', websocket.emitClose.bind(websocket));\n }\n}\n\n/**\n * Handle cases where the `ping()`, `pong()`, or `send()` methods are called\n * when the `readyState` attribute is `CLOSING` or `CLOSED`.\n *\n * @param {WebSocket} websocket The WebSocket instance\n * @param {*} [data] The data to send\n * @param {Function} [cb] Callback\n * @private\n */\nfunction sendAfterClose(websocket, data, cb) {\n if (data) {\n const length = isBlob(data) ? data.size : toBuffer(data).length;\n\n //\n // The `_bufferedAmount` property is used only when the peer is a client and\n // the opening handshake fails. Under these circumstances, in fact, the\n // `setSocket()` method is not called, so the `_socket` and `_sender`\n // properties are set to `null`.\n //\n if (websocket._socket) websocket._sender._bufferedBytes += length;\n else websocket._bufferedAmount += length;\n }\n\n if (cb) {\n const err = new Error(\n `WebSocket is not open: readyState ${websocket.readyState} ` +\n `(${readyStates[websocket.readyState]})`\n );\n process.nextTick(cb, err);\n }\n}\n\n/**\n * The listener of the `Receiver` `'conclude'` event.\n *\n * @param {Number} code The status code\n * @param {Buffer} reason The reason for closing\n * @private\n */\nfunction receiverOnConclude(code, reason) {\n const websocket = this[kWebSocket];\n\n websocket._closeFrameReceived = true;\n websocket._closeMessage = reason;\n websocket._closeCode = code;\n\n if (websocket._socket[kWebSocket] === undefined) return;\n\n websocket._socket.removeListener('data', socketOnData);\n process.nextTick(resume, websocket._socket);\n\n if (code === 1005) websocket.close();\n else websocket.close(code, reason);\n}\n\n/**\n * The listener of the `Receiver` `'drain'` event.\n *\n * @private\n */\nfunction receiverOnDrain() {\n const websocket = this[kWebSocket];\n\n if (!websocket.isPaused) websocket._socket.resume();\n}\n\n/**\n * The listener of the `Receiver` `'error'` event.\n *\n * @param {(RangeError|Error)} err The emitted error\n * @private\n */\nfunction receiverOnError(err) {\n const websocket = this[kWebSocket];\n\n if (websocket._socket[kWebSocket] !== undefined) {\n websocket._socket.removeListener('data', socketOnData);\n\n //\n // On Node.js < 14.0.0 the `'error'` event is emitted synchronously. See\n // https://github.com/websockets/ws/issues/1940.\n //\n process.nextTick(resume, websocket._socket);\n\n websocket.close(err[kStatusCode]);\n }\n\n if (!websocket._errorEmitted) {\n websocket._errorEmitted = true;\n websocket.emit('error', err);\n }\n}\n\n/**\n * The listener of the `Receiver` `'finish'` event.\n *\n * @private\n */\nfunction receiverOnFinish() {\n this[kWebSocket].emitClose();\n}\n\n/**\n * The listener of the `Receiver` `'message'` event.\n *\n * @param {Buffer|ArrayBuffer|Buffer[])} data The message\n * @param {Boolean} isBinary Specifies whether the message is binary or not\n * @private\n */\nfunction receiverOnMessage(data, isBinary) {\n this[kWebSocket].emit('message', data, isBinary);\n}\n\n/**\n * The listener of the `Receiver` `'ping'` event.\n *\n * @param {Buffer} data The data included in the ping frame\n * @private\n */\nfunction receiverOnPing(data) {\n const websocket = this[kWebSocket];\n\n if (websocket._autoPong) websocket.pong(data, !this._isServer, NOOP);\n websocket.emit('ping', data);\n}\n\n/**\n * The listener of the `Receiver` `'pong'` event.\n *\n * @param {Buffer} data The data included in the pong frame\n * @private\n */\nfunction receiverOnPong(data) {\n this[kWebSocket].emit('pong', data);\n}\n\n/**\n * Resume a readable stream\n *\n * @param {Readable} stream The readable stream\n * @private\n */\nfunction resume(stream) {\n stream.resume();\n}\n\n/**\n * The `Sender` error event handler.\n *\n * @param {Error} The error\n * @private\n */\nfunction senderOnError(err) {\n const websocket = this[kWebSocket];\n\n if (websocket.readyState === WebSocket.CLOSED) return;\n if (websocket.readyState === WebSocket.OPEN) {\n websocket._readyState = WebSocket.CLOSING;\n setCloseTimer(websocket);\n }\n\n //\n // `socket.end()` is used instead of `socket.destroy()` to allow the other\n // peer to finish sending queued data. There is no need to set a timer here\n // because `CLOSING` means that it is already set or not needed.\n //\n this._socket.end();\n\n if (!websocket._errorEmitted) {\n websocket._errorEmitted = true;\n websocket.emit('error', err);\n }\n}\n\n/**\n * Set a timer to destroy the underlying raw socket of a WebSocket.\n *\n * @param {WebSocket} websocket The WebSocket instance\n * @private\n */\nfunction setCloseTimer(websocket) {\n websocket._closeTimer = setTimeout(\n websocket._socket.destroy.bind(websocket._socket),\n closeTimeout\n );\n}\n\n/**\n * The listener of the socket `'close'` event.\n *\n * @private\n */\nfunction socketOnClose() {\n const websocket = this[kWebSocket];\n\n this.removeListener('close', socketOnClose);\n this.removeListener('data', socketOnData);\n this.removeListener('end', socketOnEnd);\n\n websocket._readyState = WebSocket.CLOSING;\n\n let chunk;\n\n //\n // The close frame might not have been received or the `'end'` event emitted,\n // for example, if the socket was destroyed due to an error. Ensure that the\n // `receiver` stream is closed after writing any remaining buffered data to\n // it. If the readable side of the socket is in flowing mode then there is no\n // buffered data as everything has been already written and `readable.read()`\n // will return `null`. If instead, the socket is paused, any possible buffered\n // data will be read as a single chunk.\n //\n if (\n !this._readableState.endEmitted &&\n !websocket._closeFrameReceived &&\n !websocket._receiver._writableState.errorEmitted &&\n (chunk = websocket._socket.read()) !== null\n ) {\n websocket._receiver.write(chunk);\n }\n\n websocket._receiver.end();\n\n this[kWebSocket] = undefined;\n\n clearTimeout(websocket._closeTimer);\n\n if (\n websocket._receiver._writableState.finished ||\n websocket._receiver._writableState.errorEmitted\n ) {\n websocket.emitClose();\n } else {\n websocket._receiver.on('error', receiverOnFinish);\n websocket._receiver.on('finish', receiverOnFinish);\n }\n}\n\n/**\n * The listener of the socket `'data'` event.\n *\n * @param {Buffer} chunk A chunk of data\n * @private\n */\nfunction socketOnData(chunk) {\n if (!this[kWebSocket]._receiver.write(chunk)) {\n this.pause();\n }\n}\n\n/**\n * The listener of the socket `'end'` event.\n *\n * @private\n */\nfunction socketOnEnd() {\n const websocket = this[kWebSocket];\n\n websocket._readyState = WebSocket.CLOSING;\n websocket._receiver.end();\n this.end();\n}\n\n/**\n * The listener of the socket `'error'` event.\n *\n * @private\n */\nfunction socketOnError() {\n const websocket = this[kWebSocket];\n\n this.removeListener('error', socketOnError);\n this.on('error', NOOP);\n\n if (websocket) {\n websocket._readyState = WebSocket.CLOSING;\n this.destroy();\n }\n}\n", "/* eslint no-unused-vars: [\"error\", { \"varsIgnorePattern\": \"^WebSocket$\" }] */\n'use strict';\n\nconst WebSocket = require('./websocket');\nconst { Duplex } = require('stream');\n\n/**\n * Emits the `'close'` event on a stream.\n *\n * @param {Duplex} stream The stream.\n * @private\n */\nfunction emitClose(stream) {\n stream.emit('close');\n}\n\n/**\n * The listener of the `'end'` event.\n *\n * @private\n */\nfunction duplexOnEnd() {\n if (!this.destroyed && this._writableState.finished) {\n this.destroy();\n }\n}\n\n/**\n * The listener of the `'error'` event.\n *\n * @param {Error} err The error\n * @private\n */\nfunction duplexOnError(err) {\n this.removeListener('error', duplexOnError);\n this.destroy();\n if (this.listenerCount('error') === 0) {\n // Do not suppress the throwing behavior.\n this.emit('error', err);\n }\n}\n\n/**\n * Wraps a `WebSocket` in a duplex stream.\n *\n * @param {WebSocket} ws The `WebSocket` to wrap\n * @param {Object} [options] The options for the `Duplex` constructor\n * @return {Duplex} The duplex stream\n * @public\n */\nfunction createWebSocketStream(ws, options) {\n let terminateOnDestroy = true;\n\n const duplex = new Duplex({\n ...options,\n autoDestroy: false,\n emitClose: false,\n objectMode: false,\n writableObjectMode: false\n });\n\n ws.on('message', function message(msg, isBinary) {\n const data =\n !isBinary && duplex._readableState.objectMode ? msg.toString() : msg;\n\n if (!duplex.push(data)) ws.pause();\n });\n\n ws.once('error', function error(err) {\n if (duplex.destroyed) return;\n\n // Prevent `ws.terminate()` from being called by `duplex._destroy()`.\n //\n // - If the `'error'` event is emitted before the `'open'` event, then\n // `ws.terminate()` is a noop as no socket is assigned.\n // - Otherwise, the error is re-emitted by the listener of the `'error'`\n // event of the `Receiver` object. The listener already closes the\n // connection by calling `ws.close()`. This allows a close frame to be\n // sent to the other peer. If `ws.terminate()` is called right after this,\n // then the close frame might not be sent.\n terminateOnDestroy = false;\n duplex.destroy(err);\n });\n\n ws.once('close', function close() {\n if (duplex.destroyed) return;\n\n duplex.push(null);\n });\n\n duplex._destroy = function (err, callback) {\n if (ws.readyState === ws.CLOSED) {\n callback(err);\n process.nextTick(emitClose, duplex);\n return;\n }\n\n let called = false;\n\n ws.once('error', function error(err) {\n called = true;\n callback(err);\n });\n\n ws.once('close', function close() {\n if (!called) callback(err);\n process.nextTick(emitClose, duplex);\n });\n\n if (terminateOnDestroy) ws.terminate();\n };\n\n duplex._final = function (callback) {\n if (ws.readyState === ws.CONNECTING) {\n ws.once('open', function open() {\n duplex._final(callback);\n });\n return;\n }\n\n // If the value of the `_socket` property is `null` it means that `ws` is a\n // client websocket and the handshake failed. In fact, when this happens, a\n // socket is never assigned to the websocket. Wait for the `'error'` event\n // that will be emitted by the websocket.\n if (ws._socket === null) return;\n\n if (ws._socket._writableState.finished) {\n callback();\n if (duplex._readableState.endEmitted) duplex.destroy();\n } else {\n ws._socket.once('finish', function finish() {\n // `duplex` is not destroyed here because the `'end'` event will be\n // emitted on `duplex` after this `'finish'` event. The EOF signaling\n // `null` chunk is, in fact, pushed when the websocket emits `'close'`.\n callback();\n });\n ws.close();\n }\n };\n\n duplex._read = function () {\n if (ws.isPaused) ws.resume();\n };\n\n duplex._write = function (chunk, encoding, callback) {\n if (ws.readyState === ws.CONNECTING) {\n ws.once('open', function open() {\n duplex._write(chunk, encoding, callback);\n });\n return;\n }\n\n ws.send(chunk, callback);\n };\n\n duplex.on('end', duplexOnEnd);\n duplex.on('error', duplexOnError);\n return duplex;\n}\n\nmodule.exports = createWebSocketStream;\n", "'use strict';\n\nconst { tokenChars } = require('./validation');\n\n/**\n * Parses the `Sec-WebSocket-Protocol` header into a set of subprotocol names.\n *\n * @param {String} header The field value of the header\n * @return {Set} The subprotocol names\n * @public\n */\nfunction parse(header) {\n const protocols = new Set();\n let start = -1;\n let end = -1;\n let i = 0;\n\n for (i; i < header.length; i++) {\n const code = header.charCodeAt(i);\n\n if (end === -1 && tokenChars[code] === 1) {\n if (start === -1) start = i;\n } else if (\n i !== 0 &&\n (code === 0x20 /* ' ' */ || code === 0x09) /* '\\t' */\n ) {\n if (end === -1 && start !== -1) end = i;\n } else if (code === 0x2c /* ',' */) {\n if (start === -1) {\n throw new SyntaxError(`Unexpected character at index ${i}`);\n }\n\n if (end === -1) end = i;\n\n const protocol = header.slice(start, end);\n\n if (protocols.has(protocol)) {\n throw new SyntaxError(`The \"${protocol}\" subprotocol is duplicated`);\n }\n\n protocols.add(protocol);\n start = end = -1;\n } else {\n throw new SyntaxError(`Unexpected character at index ${i}`);\n }\n }\n\n if (start === -1 || end !== -1) {\n throw new SyntaxError('Unexpected end of input');\n }\n\n const protocol = header.slice(start, i);\n\n if (protocols.has(protocol)) {\n throw new SyntaxError(`The \"${protocol}\" subprotocol is duplicated`);\n }\n\n protocols.add(protocol);\n return protocols;\n}\n\nmodule.exports = { parse };\n", "/* eslint no-unused-vars: [\"error\", { \"varsIgnorePattern\": \"^Duplex$\", \"caughtErrors\": \"none\" }] */\n\n'use strict';\n\nconst EventEmitter = require('events');\nconst http = require('http');\nconst { Duplex } = require('stream');\nconst { createHash } = require('crypto');\n\nconst extension = require('./extension');\nconst PerMessageDeflate = require('./permessage-deflate');\nconst subprotocol = require('./subprotocol');\nconst WebSocket = require('./websocket');\nconst { GUID, kWebSocket } = require('./constants');\n\nconst keyRegex = /^[+/0-9A-Za-z]{22}==$/;\n\nconst RUNNING = 0;\nconst CLOSING = 1;\nconst CLOSED = 2;\n\n/**\n * Class representing a WebSocket server.\n *\n * @extends EventEmitter\n */\nclass WebSocketServer extends EventEmitter {\n /**\n * Create a `WebSocketServer` instance.\n *\n * @param {Object} options Configuration options\n * @param {Boolean} [options.allowSynchronousEvents=true] Specifies whether\n * any of the `'message'`, `'ping'`, and `'pong'` events can be emitted\n * multiple times in the same tick\n * @param {Boolean} [options.autoPong=true] Specifies whether or not to\n * automatically send a pong in response to a ping\n * @param {Number} [options.backlog=511] The maximum length of the queue of\n * pending connections\n * @param {Boolean} [options.clientTracking=true] Specifies whether or not to\n * track clients\n * @param {Function} [options.handleProtocols] A hook to handle protocols\n * @param {String} [options.host] The hostname where to bind the server\n * @param {Number} [options.maxPayload=104857600] The maximum allowed message\n * size\n * @param {Boolean} [options.noServer=false] Enable no server mode\n * @param {String} [options.path] Accept only connections matching this path\n * @param {(Boolean|Object)} [options.perMessageDeflate=false] Enable/disable\n * permessage-deflate\n * @param {Number} [options.port] The port where to bind the server\n * @param {(http.Server|https.Server)} [options.server] A pre-created HTTP/S\n * server to use\n * @param {Boolean} [options.skipUTF8Validation=false] Specifies whether or\n * not to skip UTF-8 validation for text and close messages\n * @param {Function} [options.verifyClient] A hook to reject connections\n * @param {Function} [options.WebSocket=WebSocket] Specifies the `WebSocket`\n * class to use. It must be the `WebSocket` class or class that extends it\n * @param {Function} [callback] A listener for the `listening` event\n */\n constructor(options, callback) {\n super();\n\n options = {\n allowSynchronousEvents: true,\n autoPong: true,\n maxPayload: 100 * 1024 * 1024,\n skipUTF8Validation: false,\n perMessageDeflate: false,\n handleProtocols: null,\n clientTracking: true,\n verifyClient: null,\n noServer: false,\n backlog: null, // use default (511 as implemented in net.js)\n server: null,\n host: null,\n path: null,\n port: null,\n WebSocket,\n ...options\n };\n\n if (\n (options.port == null && !options.server && !options.noServer) ||\n (options.port != null && (options.server || options.noServer)) ||\n (options.server && options.noServer)\n ) {\n throw new TypeError(\n 'One and only one of the \"port\", \"server\", or \"noServer\" options ' +\n 'must be specified'\n );\n }\n\n if (options.port != null) {\n this._server = http.createServer((req, res) => {\n const body = http.STATUS_CODES[426];\n\n res.writeHead(426, {\n 'Content-Length': body.length,\n 'Content-Type': 'text/plain'\n });\n res.end(body);\n });\n this._server.listen(\n options.port,\n options.host,\n options.backlog,\n callback\n );\n } else if (options.server) {\n this._server = options.server;\n }\n\n if (this._server) {\n const emitConnection = this.emit.bind(this, 'connection');\n\n this._removeListeners = addListeners(this._server, {\n listening: this.emit.bind(this, 'listening'),\n error: this.emit.bind(this, 'error'),\n upgrade: (req, socket, head) => {\n this.handleUpgrade(req, socket, head, emitConnection);\n }\n });\n }\n\n if (options.perMessageDeflate === true) options.perMessageDeflate = {};\n if (options.clientTracking) {\n this.clients = new Set();\n this._shouldEmitClose = false;\n }\n\n this.options = options;\n this._state = RUNNING;\n }\n\n /**\n * Returns the bound address, the address family name, and port of the server\n * as reported by the operating system if listening on an IP socket.\n * If the server is listening on a pipe or UNIX domain socket, the name is\n * returned as a string.\n *\n * @return {(Object|String|null)} The address of the server\n * @public\n */\n address() {\n if (this.options.noServer) {\n throw new Error('The server is operating in \"noServer\" mode');\n }\n\n if (!this._server) return null;\n return this._server.address();\n }\n\n /**\n * Stop the server from accepting new connections and emit the `'close'` event\n * when all existing connections are closed.\n *\n * @param {Function} [cb] A one-time listener for the `'close'` event\n * @public\n */\n close(cb) {\n if (this._state === CLOSED) {\n if (cb) {\n this.once('close', () => {\n cb(new Error('The server is not running'));\n });\n }\n\n process.nextTick(emitClose, this);\n return;\n }\n\n if (cb) this.once('close', cb);\n\n if (this._state === CLOSING) return;\n this._state = CLOSING;\n\n if (this.options.noServer || this.options.server) {\n if (this._server) {\n this._removeListeners();\n this._removeListeners = this._server = null;\n }\n\n if (this.clients) {\n if (!this.clients.size) {\n process.nextTick(emitClose, this);\n } else {\n this._shouldEmitClose = true;\n }\n } else {\n process.nextTick(emitClose, this);\n }\n } else {\n const server = this._server;\n\n this._removeListeners();\n this._removeListeners = this._server = null;\n\n //\n // The HTTP/S server was created internally. Close it, and rely on its\n // `'close'` event.\n //\n server.close(() => {\n emitClose(this);\n });\n }\n }\n\n /**\n * See if a given request should be handled by this server instance.\n *\n * @param {http.IncomingMessage} req Request object to inspect\n * @return {Boolean} `true` if the request is valid, else `false`\n * @public\n */\n shouldHandle(req) {\n if (this.options.path) {\n const index = req.url.indexOf('?');\n const pathname = index !== -1 ? req.url.slice(0, index) : req.url;\n\n if (pathname !== this.options.path) return false;\n }\n\n return true;\n }\n\n /**\n * Handle a HTTP Upgrade request.\n *\n * @param {http.IncomingMessage} req The request object\n * @param {Duplex} socket The network socket between the server and client\n * @param {Buffer} head The first packet of the upgraded stream\n * @param {Function} cb Callback\n * @public\n */\n handleUpgrade(req, socket, head, cb) {\n socket.on('error', socketOnError);\n\n const key = req.headers['sec-websocket-key'];\n const upgrade = req.headers.upgrade;\n const version = +req.headers['sec-websocket-version'];\n\n if (req.method !== 'GET') {\n const message = 'Invalid HTTP method';\n abortHandshakeOrEmitwsClientError(this, req, socket, 405, message);\n return;\n }\n\n if (upgrade === undefined || upgrade.toLowerCase() !== 'websocket') {\n const message = 'Invalid Upgrade header';\n abortHandshakeOrEmitwsClientError(this, req, socket, 400, message);\n return;\n }\n\n if (key === undefined || !keyRegex.test(key)) {\n const message = 'Missing or invalid Sec-WebSocket-Key header';\n abortHandshakeOrEmitwsClientError(this, req, socket, 400, message);\n return;\n }\n\n if (version !== 13 && version !== 8) {\n const message = 'Missing or invalid Sec-WebSocket-Version header';\n abortHandshakeOrEmitwsClientError(this, req, socket, 400, message, {\n 'Sec-WebSocket-Version': '13, 8'\n });\n return;\n }\n\n if (!this.shouldHandle(req)) {\n abortHandshake(socket, 400);\n return;\n }\n\n const secWebSocketProtocol = req.headers['sec-websocket-protocol'];\n let protocols = new Set();\n\n if (secWebSocketProtocol !== undefined) {\n try {\n protocols = subprotocol.parse(secWebSocketProtocol);\n } catch (err) {\n const message = 'Invalid Sec-WebSocket-Protocol header';\n abortHandshakeOrEmitwsClientError(this, req, socket, 400, message);\n return;\n }\n }\n\n const secWebSocketExtensions = req.headers['sec-websocket-extensions'];\n const extensions = {};\n\n if (\n this.options.perMessageDeflate &&\n secWebSocketExtensions !== undefined\n ) {\n const perMessageDeflate = new PerMessageDeflate(\n this.options.perMessageDeflate,\n true,\n this.options.maxPayload\n );\n\n try {\n const offers = extension.parse(secWebSocketExtensions);\n\n if (offers[PerMessageDeflate.extensionName]) {\n perMessageDeflate.accept(offers[PerMessageDeflate.extensionName]);\n extensions[PerMessageDeflate.extensionName] = perMessageDeflate;\n }\n } catch (err) {\n const message =\n 'Invalid or unacceptable Sec-WebSocket-Extensions header';\n abortHandshakeOrEmitwsClientError(this, req, socket, 400, message);\n return;\n }\n }\n\n //\n // Optionally call external client verification handler.\n //\n if (this.options.verifyClient) {\n const info = {\n origin:\n req.headers[`${version === 8 ? 'sec-websocket-origin' : 'origin'}`],\n secure: !!(req.socket.authorized || req.socket.encrypted),\n req\n };\n\n if (this.options.verifyClient.length === 2) {\n this.options.verifyClient(info, (verified, code, message, headers) => {\n if (!verified) {\n return abortHandshake(socket, code || 401, message, headers);\n }\n\n this.completeUpgrade(\n extensions,\n key,\n protocols,\n req,\n socket,\n head,\n cb\n );\n });\n return;\n }\n\n if (!this.options.verifyClient(info)) return abortHandshake(socket, 401);\n }\n\n this.completeUpgrade(extensions, key, protocols, req, socket, head, cb);\n }\n\n /**\n * Upgrade the connection to WebSocket.\n *\n * @param {Object} extensions The accepted extensions\n * @param {String} key The value of the `Sec-WebSocket-Key` header\n * @param {Set} protocols The subprotocols\n * @param {http.IncomingMessage} req The request object\n * @param {Duplex} socket The network socket between the server and client\n * @param {Buffer} head The first packet of the upgraded stream\n * @param {Function} cb Callback\n * @throws {Error} If called more than once with the same socket\n * @private\n */\n completeUpgrade(extensions, key, protocols, req, socket, head, cb) {\n //\n // Destroy the socket if the client has already sent a FIN packet.\n //\n if (!socket.readable || !socket.writable) return socket.destroy();\n\n if (socket[kWebSocket]) {\n throw new Error(\n 'server.handleUpgrade() was called more than once with the same ' +\n 'socket, possibly due to a misconfiguration'\n );\n }\n\n if (this._state > RUNNING) return abortHandshake(socket, 503);\n\n const digest = createHash('sha1')\n .update(key + GUID)\n .digest('base64');\n\n const headers = [\n 'HTTP/1.1 101 Switching Protocols',\n 'Upgrade: websocket',\n 'Connection: Upgrade',\n `Sec-WebSocket-Accept: ${digest}`\n ];\n\n const ws = new this.options.WebSocket(null, undefined, this.options);\n\n if (protocols.size) {\n //\n // Optionally call external protocol selection handler.\n //\n const protocol = this.options.handleProtocols\n ? this.options.handleProtocols(protocols, req)\n : protocols.values().next().value;\n\n if (protocol) {\n headers.push(`Sec-WebSocket-Protocol: ${protocol}`);\n ws._protocol = protocol;\n }\n }\n\n if (extensions[PerMessageDeflate.extensionName]) {\n const params = extensions[PerMessageDeflate.extensionName].params;\n const value = extension.format({\n [PerMessageDeflate.extensionName]: [params]\n });\n headers.push(`Sec-WebSocket-Extensions: ${value}`);\n ws._extensions = extensions;\n }\n\n //\n // Allow external modification/inspection of handshake headers.\n //\n this.emit('headers', headers, req);\n\n socket.write(headers.concat('\\r\\n').join('\\r\\n'));\n socket.removeListener('error', socketOnError);\n\n ws.setSocket(socket, head, {\n allowSynchronousEvents: this.options.allowSynchronousEvents,\n maxPayload: this.options.maxPayload,\n skipUTF8Validation: this.options.skipUTF8Validation\n });\n\n if (this.clients) {\n this.clients.add(ws);\n ws.on('close', () => {\n this.clients.delete(ws);\n\n if (this._shouldEmitClose && !this.clients.size) {\n process.nextTick(emitClose, this);\n }\n });\n }\n\n cb(ws, req);\n }\n}\n\nmodule.exports = WebSocketServer;\n\n/**\n * Add event listeners on an `EventEmitter` using a map of <event, listener>\n * pairs.\n *\n * @param {EventEmitter} server The event emitter\n * @param {Object.<String, Function>} map The listeners to add\n * @return {Function} A function that will remove the added listeners when\n * called\n * @private\n */\nfunction addListeners(server, map) {\n for (const event of Object.keys(map)) server.on(event, map[event]);\n\n return function removeListeners() {\n for (const event of Object.keys(map)) {\n server.removeListener(event, map[event]);\n }\n };\n}\n\n/**\n * Emit a `'close'` event on an `EventEmitter`.\n *\n * @param {EventEmitter} server The event emitter\n * @private\n */\nfunction emitClose(server) {\n server._state = CLOSED;\n server.emit('close');\n}\n\n/**\n * Handle socket errors.\n *\n * @private\n */\nfunction socketOnError() {\n this.destroy();\n}\n\n/**\n * Close the connection when preconditions are not fulfilled.\n *\n * @param {Duplex} socket The socket of the upgrade request\n * @param {Number} code The HTTP response status code\n * @param {String} [message] The HTTP response body\n * @param {Object} [headers] Additional HTTP response headers\n * @private\n */\nfunction abortHandshake(socket, code, message, headers) {\n //\n // The socket is writable unless the user destroyed or ended it before calling\n // `server.handleUpgrade()` or in the `verifyClient` function, which is a user\n // error. Handling this does not make much sense as the worst that can happen\n // is that some of the data written by the user might be discarded due to the\n // call to `socket.end()` below, which triggers an `'error'` event that in\n // turn causes the socket to be destroyed.\n //\n message = message || http.STATUS_CODES[code];\n headers = {\n Connection: 'close',\n 'Content-Type': 'text/html',\n 'Content-Length': Buffer.byteLength(message),\n ...headers\n };\n\n socket.once('finish', socket.destroy);\n\n socket.end(\n `HTTP/1.1 ${code} ${http.STATUS_CODES[code]}\\r\\n` +\n Object.keys(headers)\n .map((h) => `${h}: ${headers[h]}`)\n .join('\\r\\n') +\n '\\r\\n\\r\\n' +\n message\n );\n}\n\n/**\n * Emit a `'wsClientError'` event on a `WebSocketServer` if there is at least\n * one listener for it, otherwise call `abortHandshake()`.\n *\n * @param {WebSocketServer} server The WebSocket server\n * @param {http.IncomingMessage} req The request object\n * @param {Duplex} socket The socket of the upgrade request\n * @param {Number} code The HTTP response status code\n * @param {String} message The HTTP response body\n * @param {Object} [headers] The HTTP response headers\n * @private\n */\nfunction abortHandshakeOrEmitwsClientError(\n server,\n req,\n socket,\n code,\n message,\n headers\n) {\n if (server.listenerCount('wsClientError')) {\n const err = new Error(message);\n Error.captureStackTrace(err, abortHandshakeOrEmitwsClientError);\n\n server.emit('wsClientError', err, socket, req);\n } else {\n abortHandshake(socket, code, message, headers);\n }\n}\n", "import createWebSocketStream from './lib/stream.js';\nimport Receiver from './lib/receiver.js';\nimport Sender from './lib/sender.js';\nimport WebSocket from './lib/websocket.js';\nimport WebSocketServer from './lib/websocket-server.js';\n\nexport { createWebSocketStream, Receiver, Sender, WebSocket, WebSocketServer };\nexport default WebSocket;\n", "import type { ServeOptions, Server } from \"../base.ts\";\nimport type { NodeHttpServer, WSWebSocket, WSWebSocketServer } from \"./types.ts\";\nimport { DEFAULT_PORT } from \"@veryfront/config\";\n\n// Track pending WebSocket upgrades by request ID\nconst pendingWebSocketUpgrades = new Map<string, {\n resolve: (ws: WSWebSocket) => void;\n reject: (error: Error) => void;\n}>();\n\n// Singleton WebSocket server instance (one per HTTP server)\nlet wsServer: WSWebSocketServer | null = null;\n\nexport class NodeServer implements Server {\n constructor(\n private server: NodeHttpServer,\n private hostname: string,\n private port: number,\n ) {}\n\n stop(): Promise<void> {\n return new Promise((resolve) => {\n // Close WebSocket server first\n if (wsServer) {\n wsServer.close();\n wsServer = null;\n }\n this.server.close(() => resolve());\n });\n }\n\n get addr() {\n return { hostname: this.hostname, port: this.port };\n }\n}\n\n/**\n * Create a request ID for matching WebSocket upgrades\n */\nfunction createRequestId(req: { headers: Record<string, string | string[] | undefined> }): string {\n const key = req.headers[\"sec-websocket-key\"];\n return typeof key === \"string\" ? key : (Array.isArray(key) ? key[0] : \"\") || crypto.randomUUID();\n}\n\n/**\n * Register a pending WebSocket upgrade\n * Called by NodeServerAdapter.upgradeWebSocket\n */\nexport function registerWebSocketUpgrade(requestId: string): Promise<WSWebSocket> {\n return new Promise((resolve, reject) => {\n pendingWebSocketUpgrades.set(requestId, { resolve, reject });\n // Cleanup after timeout (30 seconds)\n setTimeout(() => {\n if (pendingWebSocketUpgrades.has(requestId)) {\n pendingWebSocketUpgrades.delete(requestId);\n reject(new Error(\"WebSocket upgrade timed out\"));\n }\n }, 30000);\n });\n}\n\nexport async function createNodeServer(\n handler: (request: Request) => Promise<Response> | Response,\n options: ServeOptions = {},\n): Promise<Server> {\n const { port = DEFAULT_PORT, hostname = \"localhost\", onListen } = options;\n const { createServer } = await import(\"node:http\");\n\n const server = createServer(async (_req, _res) => {\n try {\n const url = new URL(_req.url || \"/\", `http://${_req.headers.host || hostname}`);\n const body = _req.method === \"GET\" || _req.method === \"HEAD\" ? null : _req;\n\n const headersRecord: Record<string, string> = {};\n for (const [key, value] of Object.entries(_req.headers)) {\n if (typeof value === \"string\") {\n headersRecord[key] = value;\n } else if (Array.isArray(value)) {\n headersRecord[key] = value[0] || \"\";\n }\n }\n\n // Node.js 18+ requires duplex: \"half\" when creating a Request with a streaming body\n const requestInit: RequestInit & { duplex?: string } = {\n method: _req.method,\n headers: headersRecord,\n body: body as BodyInit | null,\n };\n // Only add duplex for requests with a body (POST, PUT, PATCH, etc.)\n if (body !== null) {\n requestInit.duplex = \"half\";\n }\n const request = new Request(url.toString(), requestInit);\n\n const response = await handler(request);\n\n // Check if this is a WebSocket upgrade response (status 101)\n // The actual WebSocket handling is done in the 'upgrade' event\n if (response.status === 101) {\n // Don't end the response - the upgrade handler will take over\n return;\n }\n\n _res.statusCode = response.status;\n _res.statusMessage = response.statusText;\n\n response.headers.forEach((value, key) => {\n _res.setHeader(key, value);\n });\n\n if (response.body) {\n const reader = response.body.getReader();\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n _res.write(value);\n }\n }\n\n _res.end();\n } catch (_error) {\n const { serverLogger } = await import(\"@veryfront/utils\");\n serverLogger.error(\"Request handler error:\", _error);\n _res.statusCode = 500;\n _res.end(\"Internal Server Error\");\n }\n });\n\n // Handle WebSocket upgrades\n server.on(\"upgrade\", async (request, socket, head) => {\n try {\n // Lazy load ws package\n const { WebSocketServer } = await import(\"ws\");\n\n // Create WebSocket server if not exists\n if (!wsServer) {\n wsServer = new WebSocketServer({ noServer: true }) as unknown as WSWebSocketServer;\n }\n\n // Get request ID to match with pending upgrade\n const requestId = createRequestId(request);\n\n // Handle the upgrade\n (wsServer as unknown as {\n handleUpgrade: (\n req: unknown,\n socket: unknown,\n head: unknown,\n callback: (ws: WSWebSocket) => void,\n ) => void;\n })\n .handleUpgrade(request, socket, head, (ws: WSWebSocket) => {\n const pending = pendingWebSocketUpgrades.get(requestId);\n if (pending) {\n pendingWebSocketUpgrades.delete(requestId);\n pending.resolve(ws);\n }\n // Emit connection event\n (wsServer as unknown as { emit: (event: string, ws: WSWebSocket, req: unknown) => void })\n .emit(\"connection\", ws, request);\n });\n } catch (error) {\n const { serverLogger } = await import(\"@veryfront/utils\");\n serverLogger.error(\"WebSocket upgrade error:\", error);\n socket.destroy();\n }\n });\n\n if (options.signal) {\n options.signal.addEventListener(\"abort\", () => {\n if (wsServer) {\n wsServer.close();\n wsServer = null;\n }\n server.close();\n });\n }\n\n return new Promise((resolve) => {\n server.listen(port, hostname, () => {\n onListen?.({ hostname, port });\n resolve(new NodeServer(server as unknown as NodeHttpServer, hostname, port));\n });\n });\n}\n", "import type { ServerAdapter, WebSocketUpgrade } from \"../base.ts\";\nimport type { WSMessageData, WSWebSocket } from \"./types.ts\";\nimport { createError, toError } from \"../../../core/errors/veryfront-error.ts\";\nimport { serverLogger } from \"@veryfront/utils\";\nimport { registerWebSocketUpgrade } from \"./http-server.ts\";\nimport * as crypto from \"node:crypto\";\n\nexport class NodeServerAdapter implements ServerAdapter {\n upgradeWebSocket(request: Request): WebSocketUpgrade {\n const key = request.headers.get(\"sec-websocket-key\");\n const protocol = request.headers.get(\"sec-websocket-protocol\");\n\n if (!key) {\n throw toError(createError({\n type: \"network\",\n message: \"Missing Sec-WebSocket-Key header\",\n }));\n }\n\n // Create a proxy WebSocket that will be connected when the upgrade completes\n const socket = new NodeWebSocket();\n\n // Register the upgrade and connect when complete\n registerWebSocketUpgrade(key).then((ws) => {\n socket._attachRealSocket(ws);\n }).catch((error) => {\n serverLogger.error(\"WebSocket upgrade failed:\", error);\n socket._emitError(error);\n });\n\n // Return 101 response - the http-server upgrade handler will complete the handshake\n const response = new Response(null, {\n status: 101,\n statusText: \"Switching Protocols\",\n headers: {\n \"Upgrade\": \"websocket\",\n \"Connection\": \"Upgrade\",\n \"Sec-WebSocket-Accept\": this.generateAcceptKey(key),\n ...(protocol ? { \"Sec-WebSocket-Protocol\": protocol } : {}),\n },\n });\n\n return { socket: socket as unknown as WebSocket, response };\n }\n\n private generateAcceptKey(key: string): string {\n const GUID = \"258EAFA5-E914-47DA-95CA-C5AB0DC85B11\";\n return crypto.createHash(\"sha1\").update(key + GUID).digest(\"base64\");\n }\n}\n\n/**\n * NodeWebSocket - A WebSocket wrapper that works with Node.js\n * Proxies to the real ws WebSocket once the upgrade completes\n */\nexport class NodeWebSocket {\n private ws: WSWebSocket | null = null;\n public readyState = 0; // CONNECTING\n\n public onopen: ((event: Event) => void) | null = null;\n public onclose: ((event: CloseEvent) => void) | null = null;\n public onerror: ((event: Event) => void) | null = null;\n public onmessage: ((event: MessageEvent) => void) | null = null;\n\n static readonly CONNECTING = 0;\n static readonly OPEN = 1;\n static readonly CLOSING = 2;\n static readonly CLOSED = 3;\n\n // Queue messages sent before the socket is ready\n private pendingMessages: Array<string | ArrayBuffer> = [];\n\n /**\n * Attach the real WebSocket after upgrade completes\n * Called by NodeServerAdapter\n */\n _attachRealSocket(ws: WSWebSocket) {\n this.ws = ws;\n this.readyState = 1; // OPEN\n\n // Set up event handlers\n ws.on(\"open\", () => {\n this.readyState = 1;\n this.onopen?.(new Event(\"open\"));\n });\n\n ws.on(\"message\", (data: WSMessageData) => {\n this.onmessage?.(new MessageEvent(\"message\", { data: data.toString() }));\n });\n\n ws.on(\"close\", () => {\n this.readyState = 3;\n this.onclose?.(new CloseEvent(\"close\"));\n });\n\n ws.on(\"error\", (error: Error) => {\n this.onerror?.(new ErrorEvent(\"error\", { error }));\n });\n\n // Send any pending messages\n for (const msg of this.pendingMessages) {\n ws.send(msg);\n }\n this.pendingMessages = [];\n\n // The socket is already open when we get it from handleUpgrade\n this.onopen?.(new Event(\"open\"));\n }\n\n /**\n * Emit an error when upgrade fails\n * Called by NodeServerAdapter\n */\n _emitError(error: Error) {\n this.readyState = 3; // CLOSED\n this.onerror?.(new ErrorEvent(\"error\", { error }));\n }\n\n send(data: string | ArrayBuffer) {\n if (this.ws && this.readyState === 1) {\n this.ws.send(data);\n } else if (this.readyState === 0) {\n // Queue the message until the socket is ready\n this.pendingMessages.push(data);\n } else {\n throw toError(createError({\n type: \"network\",\n message: \"WebSocket is not open\",\n }));\n }\n }\n\n close(code?: number, reason?: string) {\n if (this.ws) {\n this.ws.close(code, reason);\n }\n this.readyState = 2; // CLOSING\n }\n\n // WebSocket standard interface\n addEventListener(type: string, listener: EventListener) {\n switch (type) {\n case \"open\":\n this.onopen = listener as (event: Event) => void;\n break;\n case \"close\":\n this.onclose = listener as (event: CloseEvent) => void;\n break;\n case \"error\":\n this.onerror = listener as (event: Event) => void;\n break;\n case \"message\":\n this.onmessage = listener as (event: MessageEvent) => void;\n break;\n }\n }\n\n removeEventListener(_type: string, _listener: EventListener) {\n // Simplified - just null out the handler\n switch (_type) {\n case \"open\":\n this.onopen = null;\n break;\n case \"close\":\n this.onclose = null;\n break;\n case \"error\":\n this.onerror = null;\n break;\n case \"message\":\n this.onmessage = null;\n break;\n }\n }\n}\n", "import type {\n RuntimeAdapter,\n RuntimeCapabilities,\n RuntimeFeatures,\n ServeOptions,\n Server,\n} from \"../base.ts\";\nimport { NodeFileSystemAdapter } from \"./filesystem-adapter.ts\";\nimport { NodeEnvironmentAdapter } from \"./environment-adapter.ts\";\nimport { NodeServerAdapter } from \"./websocket-adapter.ts\";\nimport { createNodeServer } from \"./http-server.ts\";\n\nexport class NodeAdapter implements RuntimeAdapter {\n readonly id = \"node\" as const;\n readonly name = \"node\";\n /** @deprecated Use `id` instead */\n readonly platform = \"node\" as const;\n\n fs = new NodeFileSystemAdapter();\n env = new NodeEnvironmentAdapter();\n server = new NodeServerAdapter();\n\n readonly capabilities: RuntimeCapabilities = {\n typescript: false, // Requires compilation\n jsx: false, // Requires compilation\n http2: true,\n websocket: true,\n workers: true,\n fileWatching: true,\n shell: true,\n kvStore: false,\n writableFs: true,\n };\n\n /** @deprecated Use `capabilities` instead */\n readonly features: RuntimeFeatures = {\n websocket: true,\n http2: true,\n workers: true,\n jsx: false,\n typescript: false,\n };\n\n serve(\n handler: (request: Request) => Promise<Response> | Response,\n options: ServeOptions = {},\n ): Promise<Server> {\n return createNodeServer(handler, options);\n }\n}\n\nexport const nodeAdapter = new NodeAdapter();\n", "export { NodeAdapter, nodeAdapter } from \"./adapter.ts\";\nexport { NodeFileSystemAdapter } from \"./filesystem-adapter.ts\";\nexport { NodeEnvironmentAdapter } from \"./environment-adapter.ts\";\nexport { NodeServerAdapter, NodeWebSocket } from \"./websocket-adapter.ts\";\nexport { createNodeServer, NodeServer } from \"./http-server.ts\";\nexport type {\n NodeHttpServer,\n NodeIncomingMessage,\n NodeServerResponse,\n WSMessageData,\n WSWebSocket,\n} from \"./types.ts\";\n", "export {\n createNodeServer,\n NodeAdapter,\n nodeAdapter,\n NodeEnvironmentAdapter,\n NodeFileSystemAdapter,\n NodeServer,\n NodeServerAdapter,\n NodeWebSocket,\n} from \"./node/index.ts\";\n\nexport type {\n NodeHttpServer,\n NodeIncomingMessage,\n NodeServerResponse,\n WSMessageData,\n WSWebSocket,\n} from \"./node/index.ts\";\n", "export enum ErrorCode {\n FILE_NOT_FOUND = \"FILE_NOT_FOUND\",\n BUILD_ERROR = \"BUILD_ERROR\",\n CONFIG_ERROR = \"CONFIG_ERROR\",\n COMPILATION_ERROR = \"COMPILATION_ERROR\",\n NETWORK_ERROR = \"NETWORK_ERROR\",\n PERMISSION_ERROR = \"PERMISSION_ERROR\",\n RENDER_ERROR = \"RENDER_ERROR\",\n INITIALIZATION_ERROR = \"INITIALIZATION_ERROR\",\n AGENT_ERROR = \"AGENT_ERROR\",\n AGENT_NOT_FOUND = \"AGENT_NOT_FOUND\",\n AGENT_TIMEOUT = \"AGENT_TIMEOUT\",\n AGENT_INTENT_ERROR = \"AGENT_INTENT_ERROR\",\n ORCHESTRATION_ERROR = \"ORCHESTRATION_ERROR\",\n NOT_SUPPORTED = \"NOT_SUPPORTED\",\n}\n\nexport class VeryfrontError extends Error {\n public code: ErrorCode;\n public context?: unknown;\n\n constructor(message: string, code: ErrorCode, context?: unknown) {\n super(message);\n this.name = \"VeryfrontError\";\n this.code = code;\n this.context = context;\n }\n}\n", "import { ErrorCode, VeryfrontError } from \"./types.ts\";\n\nexport class AgentError extends VeryfrontError {\n constructor(message: string, context?: unknown) {\n super(message, ErrorCode.AGENT_ERROR, context);\n this.name = \"AgentError\";\n }\n}\n\nexport class AgentNotFoundError extends VeryfrontError {\n constructor(agentId: string, context?: unknown) {\n super(`Agent with ID '${agentId}' not found`, ErrorCode.AGENT_NOT_FOUND, {\n agentId,\n ...(context as Record<string, unknown> | undefined),\n });\n this.name = \"AgentNotFoundError\";\n }\n}\n\nexport class AgentTimeoutError extends VeryfrontError {\n constructor(message: string, context?: unknown) {\n super(message, ErrorCode.AGENT_TIMEOUT, context);\n this.name = \"AgentTimeoutError\";\n }\n}\n\nexport class AgentIntentError extends VeryfrontError {\n constructor(message: string, context?: unknown) {\n super(message, ErrorCode.AGENT_INTENT_ERROR, context);\n this.name = \"AgentIntentError\";\n }\n}\n\nexport class OrchestrationError extends VeryfrontError {\n constructor(message: string, context?: unknown) {\n super(message, ErrorCode.ORCHESTRATION_ERROR, context);\n this.name = \"OrchestrationError\";\n }\n}\n", "import { ErrorCode, VeryfrontError } from \"./types.ts\";\n\nexport class BuildError extends VeryfrontError {\n constructor(message: string, context?: unknown) {\n super(message, ErrorCode.BUILD_ERROR, context);\n this.name = \"BuildError\";\n }\n}\n\nexport class CompilationError extends VeryfrontError {\n constructor(message: string, context?: unknown) {\n super(message, ErrorCode.COMPILATION_ERROR, context);\n this.name = \"CompilationError\";\n }\n}\n", "import { ErrorCode, VeryfrontError } from \"./types.ts\";\n\nexport class RuntimeError extends VeryfrontError {\n constructor(message: string, context?: unknown) {\n super(message, ErrorCode.RENDER_ERROR, context);\n this.name = \"RuntimeError\";\n }\n}\n\nexport class RenderError extends VeryfrontError {\n constructor(message: string, context?: unknown) {\n super(message, ErrorCode.RENDER_ERROR, context);\n this.name = \"RenderError\";\n }\n}\n", "import { ErrorCode, VeryfrontError } from \"./types.ts\";\n\nexport class FileSystemError extends VeryfrontError {\n constructor(message: string, context?: unknown) {\n super(message, ErrorCode.FILE_NOT_FOUND, context);\n this.name = \"FileSystemError\";\n }\n}\n\nexport class ConfigError extends VeryfrontError {\n constructor(message: string, context?: unknown) {\n super(message, ErrorCode.CONFIG_ERROR, context);\n this.name = \"ConfigError\";\n }\n}\n\nexport class NetworkError extends VeryfrontError {\n constructor(message: string, context?: unknown) {\n super(message, ErrorCode.NETWORK_ERROR, context);\n this.name = \"NetworkError\";\n }\n}\n\nexport class PermissionError extends VeryfrontError {\n constructor(message: string, context?: unknown) {\n super(message, ErrorCode.PERMISSION_ERROR, context);\n this.name = \"PermissionError\";\n }\n}\n\nexport class NotSupportedError extends VeryfrontError {\n constructor(message: string, context?: unknown) {\n super(message, ErrorCode.NOT_SUPPORTED, context);\n this.name = \"NotSupportedError\";\n }\n}\n", "import { serverLogger } from \"@veryfront/utils/logger/logger.ts\";\nimport { ErrorCode, VeryfrontError } from \"./types.ts\";\n\n/** Default max retries for retry operations */\nconst DEFAULT_MAX_RETRIES = 3;\n\n/** Default initial delay for exponential backoff (100ms) */\nconst DEFAULT_INITIAL_DELAY_MS = 100;\n\n/** Default max delay cap for exponential backoff (5 seconds) */\nconst DEFAULT_MAX_DELAY_MS = 5000;\n\nfunction safeLog(logFn: () => void): void {\n try {\n logFn();\n } catch (error) {\n try {\n serverLogger.warn(\"[errors] Logging failed:\", error);\n } catch {\n // Silently ignore if even warning fails\n }\n }\n}\n\nexport function handleError(error: Error): void {\n safeLog(() => serverLogger.error(`Error: ${error.message}`));\n\n if (error instanceof VeryfrontError && error.context) {\n safeLog(() => serverLogger.error(\"Context:\", error.context));\n }\n\n if (error.stack) {\n safeLog(() => serverLogger.error(error.stack as string));\n }\n}\n\nexport function wrapError(\n error: unknown,\n message: string,\n context?: unknown,\n): VeryfrontError {\n const originalError = error instanceof Error ? error : new Error(String(error));\n const errorMessage = `${message}: ${originalError.message}`;\n\n const wrappedContext = {\n originalError: {\n name: originalError.name,\n message: originalError.message,\n stack: originalError.stack,\n },\n ...(context as Record<string, unknown> | undefined),\n };\n\n const errorCode = error instanceof VeryfrontError ? error.code : ErrorCode.RENDER_ERROR;\n\n return new VeryfrontError(errorMessage, errorCode, wrappedContext);\n}\n\nexport function logAndThrow(\n error: unknown,\n message?: string,\n logger: typeof serverLogger = serverLogger,\n): never {\n const errorObj = error instanceof Error ? error : new Error(String(error));\n const logMessage = message ? `${message}: ${errorObj.message}` : errorObj.message;\n\n safeLog(() => logger.error(logMessage, error));\n\n if (error instanceof Error) {\n throw error;\n }\n throw errorObj;\n}\n\nexport async function handleErrorWithFallback<T>(\n fn: () => T | Promise<T>,\n fallback: T,\n logger: typeof serverLogger = serverLogger,\n): Promise<T> {\n try {\n return await fn();\n } catch (error) {\n safeLog(() => logger.warn(\"Operation failed, using fallback\", error));\n return fallback;\n }\n}\n\nexport function handleErrorWithFallbackSync<T>(\n fn: () => T,\n fallback: T,\n logger: typeof serverLogger = serverLogger,\n): T {\n try {\n return fn();\n } catch (error) {\n safeLog(() => logger.warn(\"Operation failed, using fallback\", error));\n return fallback;\n }\n}\n\nexport async function retryWithBackoff<T>(\n fn: () => Promise<T>,\n options: {\n maxRetries?: number;\n initialDelay?: number;\n maxDelay?: number;\n logger?: typeof serverLogger;\n } = {},\n): Promise<T> {\n const {\n maxRetries = DEFAULT_MAX_RETRIES,\n initialDelay = DEFAULT_INITIAL_DELAY_MS,\n maxDelay = DEFAULT_MAX_DELAY_MS,\n logger: log = serverLogger,\n } = options;\n\n let lastError: unknown;\n let delay = initialDelay;\n\n for (let attempt = 0; attempt < maxRetries; attempt++) {\n try {\n return await fn();\n } catch (error) {\n lastError = error;\n safeLog(() => log.warn(`Attempt ${attempt + 1} failed, retrying...`, error));\n\n if (attempt < maxRetries - 1) {\n await new Promise((resolve) => setTimeout(resolve, delay));\n delay = Math.min(delay * 2, maxDelay);\n }\n }\n }\n\n throw lastError;\n}\n", "export const ErrorCode = {\n CONFIG_NOT_FOUND: \"VF001\",\n CONFIG_INVALID: \"VF002\",\n CONFIG_PARSE_ERROR: \"VF003\",\n CONFIG_VALIDATION_ERROR: \"VF004\",\n CONFIG_TYPE_ERROR: \"VF005\",\n IMPORT_MAP_INVALID: \"VF006\",\n CORS_CONFIG_INVALID: \"VF007\",\n\n BUILD_FAILED: \"VF100\",\n BUNDLE_ERROR: \"VF101\",\n TYPESCRIPT_ERROR: \"VF102\",\n MDX_COMPILE_ERROR: \"VF103\",\n ASSET_OPTIMIZATION_ERROR: \"VF104\",\n SSG_GENERATION_ERROR: \"VF105\",\n SOURCEMAP_ERROR: \"VF106\",\n\n HYDRATION_MISMATCH: \"VF200\",\n RENDER_ERROR: \"VF201\",\n COMPONENT_ERROR: \"VF202\",\n LAYOUT_NOT_FOUND: \"VF203\",\n PAGE_NOT_FOUND: \"VF204\",\n API_ERROR: \"VF205\",\n MIDDLEWARE_ERROR: \"VF206\",\n\n ROUTE_CONFLICT: \"VF300\",\n INVALID_ROUTE_FILE: \"VF301\",\n ROUTE_HANDLER_INVALID: \"VF302\",\n DYNAMIC_ROUTE_ERROR: \"VF303\",\n ROUTE_PARAMS_ERROR: \"VF304\",\n API_ROUTE_ERROR: \"VF305\",\n\n MODULE_NOT_FOUND: \"VF400\",\n IMPORT_RESOLUTION_ERROR: \"VF401\",\n CIRCULAR_DEPENDENCY: \"VF402\",\n INVALID_IMPORT: \"VF403\",\n DEPENDENCY_MISSING: \"VF404\",\n VERSION_MISMATCH: \"VF405\",\n\n PORT_IN_USE: \"VF500\",\n SERVER_START_ERROR: \"VF501\",\n HMR_ERROR: \"VF502\",\n CACHE_ERROR: \"VF503\",\n FILE_WATCH_ERROR: \"VF504\",\n REQUEST_ERROR: \"VF505\",\n\n CLIENT_BOUNDARY_VIOLATION: \"VF600\",\n SERVER_ONLY_IN_CLIENT: \"VF601\",\n CLIENT_ONLY_IN_SERVER: \"VF602\",\n INVALID_USE_CLIENT: \"VF603\",\n INVALID_USE_SERVER: \"VF604\",\n RSC_PAYLOAD_ERROR: \"VF605\",\n\n DEV_SERVER_ERROR: \"VF700\",\n FAST_REFRESH_ERROR: \"VF701\",\n ERROR_OVERLAY_ERROR: \"VF702\",\n SOURCE_MAP_ERROR: \"VF703\",\n\n DEPLOYMENT_ERROR: \"VF800\",\n PLATFORM_ERROR: \"VF801\",\n ENV_VAR_MISSING: \"VF802\",\n PRODUCTION_BUILD_REQUIRED: \"VF803\",\n\n UNKNOWN_ERROR: \"VF900\",\n PERMISSION_DENIED: \"VF901\",\n FILE_NOT_FOUND: \"VF902\",\n INVALID_ARGUMENT: \"VF903\",\n TIMEOUT_ERROR: \"VF904\",\n} as const;\n\nexport type ErrorCodeType = typeof ErrorCode[keyof typeof ErrorCode];\n\nexport function getErrorDocsUrl(code: ErrorCodeType): string {\n return `https://veryfront.com/docs/errors/${code}`;\n}\n\nexport function inferErrorCode(error: Error): ErrorCodeType | null {\n const message = error.message.toLowerCase();\n\n if (message.includes(\"config\") && message.includes(\"not found\")) {\n return ErrorCode.CONFIG_NOT_FOUND;\n }\n if (message.includes(\"config\") && message.includes(\"invalid\")) return ErrorCode.CONFIG_INVALID;\n if (message.includes(\"cors\")) return ErrorCode.CORS_CONFIG_INVALID;\n\n if (message.includes(\"route\") && message.includes(\"conflict\")) return ErrorCode.ROUTE_CONFLICT;\n if (message.includes(\"route\") && message.includes(\"invalid\")) return ErrorCode.INVALID_ROUTE_FILE;\n\n if (message.includes(\"client\") && message.includes(\"boundary\")) {\n return ErrorCode.CLIENT_BOUNDARY_VIOLATION;\n }\n if (message.includes(\"server-only\") && message.includes(\"client\")) {\n return ErrorCode.SERVER_ONLY_IN_CLIENT;\n }\n\n if (message.includes(\"module not found\") || message.includes(\"cannot find module\")) {\n return ErrorCode.MODULE_NOT_FOUND;\n }\n if (message.includes(\"import\") || message.includes(\"resolve\")) {\n return ErrorCode.IMPORT_RESOLUTION_ERROR;\n }\n if (message.includes(\"react\") && message.includes(\"not found\")) {\n return ErrorCode.DEPENDENCY_MISSING;\n }\n\n if (message.includes(\"port\") && (message.includes(\"in use\") || message.includes(\"eaddrinuse\"))) {\n return ErrorCode.PORT_IN_USE;\n }\n if (message.includes(\"hydration\")) return ErrorCode.HYDRATION_MISMATCH;\n\n if (message.includes(\"build\") && message.includes(\"fail\")) return ErrorCode.BUILD_FAILED;\n if (message.includes(\"mdx\")) return ErrorCode.MDX_COMPILE_ERROR;\n if (message.includes(\"typescript\")) return ErrorCode.TYPESCRIPT_ERROR;\n\n return null;\n}\n", "import type { ErrorCodeType } from \"../error-codes.ts\";\nimport { getErrorDocsUrl } from \"../error-codes.ts\";\nimport type { ErrorSolution } from \"./types.ts\";\n\nexport function createErrorSolution(\n code: ErrorCodeType,\n config: Omit<ErrorSolution, \"code\" | \"docs\"> & { docs?: string },\n): ErrorSolution {\n return {\n code,\n ...config,\n docs: config.docs ?? getErrorDocsUrl(code),\n };\n}\n\nexport function createSimpleError(\n code: ErrorCodeType,\n title: string,\n message: string,\n steps: string[],\n): ErrorSolution {\n return createErrorSolution(code, { title, message, steps });\n}\n", "import { ErrorCode } from \"../error-codes.ts\";\nimport type { PartialErrorCatalog } from \"./types.ts\";\nimport { createErrorSolution, createSimpleError } from \"./factory.ts\";\n\nexport const CONFIG_ERROR_CATALOG: PartialErrorCatalog = {\n [ErrorCode.CONFIG_NOT_FOUND]: createErrorSolution(ErrorCode.CONFIG_NOT_FOUND, {\n title: \"Configuration file not found\",\n message: \"Veryfront could not find veryfront.config.js in your project root.\",\n steps: [\n \"Create veryfront.config.js in your project root directory\",\n \"Run 'veryfront init' to generate a default configuration\",\n \"Or copy from an example project\",\n ],\n example: `// veryfront.config.js\nexport default {\n title: \"My App\",\n dev: { port: 3002 }\n}`,\n tips: [\"You can use .ts or .mjs extensions too\", \"Config is optional for simple projects\"],\n }),\n\n [ErrorCode.CONFIG_INVALID]: createErrorSolution(ErrorCode.CONFIG_INVALID, {\n title: \"Invalid configuration\",\n message: \"Your configuration file has invalid values or structure.\",\n steps: [\n \"Check that the config exports a default object\",\n \"Ensure all values are valid JavaScript types\",\n \"Remove any trailing commas\",\n \"Verify property names match the schema\",\n ],\n example: `// \u2713 Valid config\nexport default {\n title: \"My App\",\n dev: {\n port: 3002,\n open: true\n }\n}`,\n }),\n\n [ErrorCode.CONFIG_PARSE_ERROR]: createSimpleError(\n ErrorCode.CONFIG_PARSE_ERROR,\n \"Configuration parse error\",\n \"Failed to parse your configuration file.\",\n [\n \"Check for syntax errors (missing brackets, quotes, etc.)\",\n \"Ensure the file has valid JavaScript/TypeScript syntax\",\n \"Look for the specific parse error in the output above\",\n ],\n ),\n\n [ErrorCode.CONFIG_VALIDATION_ERROR]: createSimpleError(\n ErrorCode.CONFIG_VALIDATION_ERROR,\n \"Configuration validation failed\",\n \"Configuration values do not pass validation.\",\n [\n \"Check that port numbers are between 1-65535\",\n \"Ensure boolean flags are true/false (not strings)\",\n \"Verify URLs are properly formatted\",\n \"Check array/object structures match expected format\",\n ],\n ),\n\n [ErrorCode.CONFIG_TYPE_ERROR]: createSimpleError(\n ErrorCode.CONFIG_TYPE_ERROR,\n \"Configuration type error\",\n \"A configuration value has the wrong type.\",\n [\n \"Check that numbers are not in quotes\",\n 'Ensure booleans are true/false, not \"true\"/\"false\"',\n \"Verify arrays use [] brackets\",\n \"Check objects use {} braces\",\n ],\n ),\n\n [ErrorCode.IMPORT_MAP_INVALID]: createErrorSolution(ErrorCode.IMPORT_MAP_INVALID, {\n title: \"Invalid import map\",\n message: \"The import map in your configuration is invalid.\",\n steps: [\n \"Check import map structure: { imports: {}, scopes: {} }\",\n \"Ensure URLs are valid and accessible\",\n \"Verify package names are correct\",\n ],\n example: `resolve: {\n importMap: {\n imports: {\n \"react\": \"https://esm.sh/react@19\",\n \"@/utils\": \"./src/utils/index.ts\"\n }\n }\n}`,\n }),\n\n [ErrorCode.CORS_CONFIG_INVALID]: createErrorSolution(ErrorCode.CORS_CONFIG_INVALID, {\n title: \"Invalid CORS configuration\",\n message: \"The CORS configuration is invalid.\",\n steps: [\n \"Use true for default CORS settings\",\n \"Or provide an object with origin, methods, headers\",\n \"Ensure origin is a string, not an array\",\n ],\n example: `security: {\n cors: true // or { origin: \"https://example.com\" }\n}`,\n }),\n};\n", "import { ErrorCode } from \"../error-codes.ts\";\nimport type { PartialErrorCatalog } from \"./types.ts\";\nimport { createErrorSolution, createSimpleError } from \"./factory.ts\";\n\nexport const BUILD_ERROR_CATALOG: PartialErrorCatalog = {\n [ErrorCode.BUILD_FAILED]: createErrorSolution(ErrorCode.BUILD_FAILED, {\n title: \"Build failed\",\n message: \"The build process encountered errors.\",\n steps: [\n \"Check the error messages above for specific issues\",\n \"Fix any TypeScript or syntax errors\",\n \"Ensure all imports can be resolved\",\n \"Run 'veryfront doctor' to check your environment\",\n ],\n tips: [\"Try running with --verbose for more details\", \"Check build logs for warnings\"],\n }),\n\n [ErrorCode.BUNDLE_ERROR]: createSimpleError(\n ErrorCode.BUNDLE_ERROR,\n \"Bundle generation failed\",\n \"Failed to generate JavaScript bundles.\",\n [\n \"Check for circular dependencies\",\n \"Ensure all imports are valid\",\n \"Try clearing cache: veryfront clean\",\n ],\n ),\n\n [ErrorCode.TYPESCRIPT_ERROR]: createSimpleError(\n ErrorCode.TYPESCRIPT_ERROR,\n \"TypeScript compilation error\",\n \"TypeScript found errors in your code.\",\n [\n \"Fix the TypeScript errors shown above\",\n \"Check your tsconfig.json configuration\",\n \"Ensure all types are properly imported\",\n ],\n ),\n\n [ErrorCode.MDX_COMPILE_ERROR]: createErrorSolution(ErrorCode.MDX_COMPILE_ERROR, {\n title: \"MDX compilation failed\",\n message: \"Failed to compile MDX file.\",\n steps: [\n \"Check for syntax errors in your MDX file\",\n \"Ensure frontmatter YAML is valid\",\n \"Verify JSX components are properly imported\",\n \"Check for unclosed tags or brackets\",\n ],\n example: `---\ntitle: My Post\n---\n\nimport Button from './components/Button.jsx'\n\n# Hello World\n\n<Button>Click me</Button>`,\n }),\n\n [ErrorCode.ASSET_OPTIMIZATION_ERROR]: createSimpleError(\n ErrorCode.ASSET_OPTIMIZATION_ERROR,\n \"Asset optimization failed\",\n \"Failed to optimize assets (images, CSS, etc.).\",\n [\n \"Check that asset files are valid\",\n \"Ensure file paths are correct\",\n \"Try disabling optimization temporarily\",\n ],\n ),\n\n [ErrorCode.SSG_GENERATION_ERROR]: createSimpleError(\n ErrorCode.SSG_GENERATION_ERROR,\n \"Static site generation failed\",\n \"Failed to generate static pages.\",\n [\n \"Check that all routes are valid\",\n \"Ensure getStaticData functions return correctly\",\n \"Verify no dynamic content requires runtime\",\n ],\n ),\n\n [ErrorCode.SOURCEMAP_ERROR]: createSimpleError(\n ErrorCode.SOURCEMAP_ERROR,\n \"Source map generation failed\",\n \"Failed to generate source maps.\",\n [\n \"Try disabling source maps temporarily\",\n \"Check for very large files that might cause issues\",\n ],\n ),\n};\n", "import { ErrorCode } from \"../error-codes.ts\";\nimport type { PartialErrorCatalog } from \"./types.ts\";\nimport { createErrorSolution, createSimpleError } from \"./factory.ts\";\n\nexport const RUNTIME_ERROR_CATALOG: PartialErrorCatalog = {\n [ErrorCode.HYDRATION_MISMATCH]: createErrorSolution(ErrorCode.HYDRATION_MISMATCH, {\n title: \"Hydration mismatch\",\n message: \"Client-side HTML does not match server-rendered HTML.\",\n steps: [\n \"Check for random values or timestamps in render\",\n \"Ensure Date() calls are consistent\",\n \"Avoid using browser-only APIs during SSR\",\n \"Check for white space or formatting differences\",\n ],\n example: `// \u274C Wrong - random on each render\n<div>{Math.random()}</div>\n\nconst [random, setRandom] = useState(0)\nuseEffect(() => setRandom(Math.random()), [])\n<div>{random}</div>`,\n relatedErrors: [ErrorCode.RENDER_ERROR],\n }),\n\n [ErrorCode.RENDER_ERROR]: createSimpleError(\n ErrorCode.RENDER_ERROR,\n \"Render error\",\n \"Failed to render component.\",\n [\n \"Check the component for errors\",\n \"Ensure all props are valid\",\n \"Look for null/undefined access\",\n \"Check error boundaries\",\n ],\n ),\n\n [ErrorCode.COMPONENT_ERROR]: createSimpleError(\n ErrorCode.COMPONENT_ERROR,\n \"Component error\",\n \"Error in component lifecycle or render.\",\n [\n \"Check component code for errors\",\n \"Ensure hooks follow Rules of Hooks\",\n \"Verify props are passed correctly\",\n ],\n ),\n\n [ErrorCode.LAYOUT_NOT_FOUND]: createErrorSolution(ErrorCode.LAYOUT_NOT_FOUND, {\n title: \"Layout file not found\",\n message: \"Required layout file is missing.\",\n steps: [\n \"Create app/layout.tsx in App Router\",\n \"Or create layouts/default.mdx for Pages Router\",\n \"Check file path and name are correct\",\n ],\n example: `// app/layout.tsx\nexport default function RootLayout({ children }) {\n return (\n <html lang=\"en\">\n <body>{children}</body>\n </html>\n )\n}`,\n }),\n\n [ErrorCode.PAGE_NOT_FOUND]: createSimpleError(\n ErrorCode.PAGE_NOT_FOUND,\n \"Page not found\",\n \"The requested page does not exist.\",\n [\n \"Check that the page file exists\",\n \"Verify file name matches route\",\n \"Ensure file extension is correct (.tsx, .jsx, .mdx)\",\n ],\n ),\n\n [ErrorCode.API_ERROR]: createSimpleError(\n ErrorCode.API_ERROR,\n \"API handler error\",\n \"Error in API route handler.\",\n [\n \"Check API handler code for errors\",\n \"Ensure proper error handling\",\n \"Verify request/response format\",\n ],\n ),\n\n [ErrorCode.MIDDLEWARE_ERROR]: createSimpleError(\n ErrorCode.MIDDLEWARE_ERROR,\n \"Middleware error\",\n \"Error in middleware execution.\",\n [\n \"Check middleware code for errors\",\n \"Ensure middleware returns Response\",\n \"Verify middleware is properly exported\",\n ],\n ),\n};\n", "import { ErrorCode } from \"../error-codes.ts\";\nimport type { PartialErrorCatalog } from \"./types.ts\";\nimport { createErrorSolution, createSimpleError } from \"./factory.ts\";\n\nexport const ROUTE_ERROR_CATALOG: PartialErrorCatalog = {\n [ErrorCode.ROUTE_CONFLICT]: createSimpleError(\n ErrorCode.ROUTE_CONFLICT,\n \"Route conflict\",\n \"Multiple files are trying to handle the same route.\",\n [\n \"Check for duplicate route files\",\n \"Remove conflicting routes\",\n \"Use dynamic routes [id] carefully\",\n ],\n ),\n\n [ErrorCode.INVALID_ROUTE_FILE]: createErrorSolution(ErrorCode.INVALID_ROUTE_FILE, {\n title: \"Invalid route file\",\n message: \"Route file has invalid structure or exports.\",\n steps: [\n \"API routes must export GET, POST, etc. functions\",\n \"Page routes must export default component\",\n \"Check for syntax errors\",\n ],\n example: `// app/api/users/route.ts\nexport async function GET() {\n return Response.json({ users: [] })\n}`,\n }),\n\n [ErrorCode.ROUTE_HANDLER_INVALID]: createSimpleError(\n ErrorCode.ROUTE_HANDLER_INVALID,\n \"Invalid route handler\",\n \"Route handler does not return Response.\",\n [\n \"Ensure handler returns Response object\",\n \"Use Response.json() for JSON responses\",\n \"Check for missing return statement\",\n ],\n ),\n\n [ErrorCode.DYNAMIC_ROUTE_ERROR]: createSimpleError(\n ErrorCode.DYNAMIC_ROUTE_ERROR,\n \"Dynamic route error\",\n \"Error in dynamic route handling.\",\n [\n \"Check [param] syntax is correct\",\n \"Ensure params are accessed properly\",\n \"Verify dynamic segment names\",\n ],\n ),\n\n [ErrorCode.ROUTE_PARAMS_ERROR]: createSimpleError(\n ErrorCode.ROUTE_PARAMS_ERROR,\n \"Route parameters error\",\n \"Error accessing route parameters.\",\n [\n \"Check params object structure\",\n \"Ensure parameter names match route\",\n \"Verify params are strings\",\n ],\n ),\n\n [ErrorCode.API_ROUTE_ERROR]: createSimpleError(\n ErrorCode.API_ROUTE_ERROR,\n \"API route error\",\n \"Error in API route execution.\",\n [\n \"Check API handler code\",\n \"Ensure proper error handling\",\n \"Verify request parsing\",\n ],\n ),\n};\n", "import { ErrorCode } from \"../error-codes.ts\";\nimport type { PartialErrorCatalog } from \"./types.ts\";\nimport { createErrorSolution, createSimpleError } from \"./factory.ts\";\n\nexport const MODULE_ERROR_CATALOG: PartialErrorCatalog = {\n [ErrorCode.MODULE_NOT_FOUND]: createErrorSolution(ErrorCode.MODULE_NOT_FOUND, {\n title: \"Module not found\",\n message: \"Cannot find the imported module.\",\n steps: [\n \"Check that the file path is correct\",\n \"Ensure the module is installed or exists\",\n \"Add missing module to import map\",\n \"Check for typos in import statement\",\n ],\n example: `// Add to veryfront.config.js\nresolve: {\n importMap: {\n imports: {\n \"missing-lib\": \"https://esm.sh/missing-lib@1.0.0\"\n }\n }\n}`,\n }),\n\n [ErrorCode.IMPORT_RESOLUTION_ERROR]: createSimpleError(\n ErrorCode.IMPORT_RESOLUTION_ERROR,\n \"Import resolution failed\",\n \"Failed to resolve import specifier.\",\n [\n \"Check import paths are correct\",\n \"Ensure modules are in import map\",\n \"Verify network connectivity for remote imports\",\n ],\n ),\n\n [ErrorCode.CIRCULAR_DEPENDENCY]: createSimpleError(\n ErrorCode.CIRCULAR_DEPENDENCY,\n \"Circular dependency detected\",\n \"Files are importing each other in a circle.\",\n [\n \"Identify the circular import chain\",\n \"Extract shared code to separate file\",\n \"Use dependency injection or lazy imports\",\n ],\n ),\n\n [ErrorCode.INVALID_IMPORT]: createSimpleError(\n ErrorCode.INVALID_IMPORT,\n \"Invalid import statement\",\n \"Import statement has invalid syntax.\",\n [\n 'Check import syntax: import X from \"y\"',\n \"Ensure quotes are properly closed\",\n \"Verify export exists in target module\",\n ],\n ),\n\n [ErrorCode.DEPENDENCY_MISSING]: createErrorSolution(ErrorCode.DEPENDENCY_MISSING, {\n title: \"Required dependency not found\",\n message: \"A required dependency is missing.\",\n steps: [\n \"Add React to your import map\",\n \"Ensure all peer dependencies are included\",\n \"Run 'veryfront doctor' to verify setup\",\n ],\n example: `// Minimum required imports\nresolve: {\n importMap: {\n imports: {\n \"react\": \"https://esm.sh/react@19\",\n \"react-dom\": \"https://esm.sh/react-dom@19\"\n }\n }\n}`,\n }),\n\n [ErrorCode.VERSION_MISMATCH]: createSimpleError(\n ErrorCode.VERSION_MISMATCH,\n \"Dependency version mismatch\",\n \"Incompatible versions of dependencies detected.\",\n [\n \"Ensure React and React-DOM versions match\",\n \"Check for multiple React instances\",\n \"Update dependencies to compatible versions\",\n ],\n ),\n};\n", "import { ErrorCode } from \"../error-codes.ts\";\nimport type { PartialErrorCatalog } from \"./types.ts\";\nimport { createErrorSolution, createSimpleError } from \"./factory.ts\";\n\nexport const SERVER_ERROR_CATALOG: PartialErrorCatalog = {\n [ErrorCode.PORT_IN_USE]: createErrorSolution(ErrorCode.PORT_IN_USE, {\n title: \"Port already in use\",\n message: \"Another process is using the specified port.\",\n steps: [\n \"Stop the other process: lsof -i :PORT\",\n \"Use a different port: veryfront dev --port 3003\",\n \"Add port to config file\",\n ],\n example: `// veryfront.config.js\ndev: {\n port: 3003\n}`,\n }),\n\n [ErrorCode.SERVER_START_ERROR]: createSimpleError(\n ErrorCode.SERVER_START_ERROR,\n \"Server failed to start\",\n \"Development server could not start.\",\n [\n \"Check for port conflicts\",\n \"Ensure file permissions are correct\",\n \"Verify configuration is valid\",\n ],\n ),\n\n [ErrorCode.HMR_ERROR]: createSimpleError(\n ErrorCode.HMR_ERROR,\n \"Hot Module Replacement error\",\n \"HMR failed to update module.\",\n [\n \"Try refreshing the page\",\n \"Check for syntax errors\",\n \"Restart dev server if persistent\",\n ],\n ),\n\n [ErrorCode.CACHE_ERROR]: createSimpleError(\n ErrorCode.CACHE_ERROR,\n \"Cache operation failed\",\n \"Error reading or writing cache.\",\n [\n \"Clear cache: veryfront clean --cache\",\n \"Check disk space\",\n \"Verify file permissions\",\n ],\n ),\n\n [ErrorCode.FILE_WATCH_ERROR]: createSimpleError(\n ErrorCode.FILE_WATCH_ERROR,\n \"File watching failed\",\n \"Could not watch files for changes.\",\n [\n \"Check system file watch limits\",\n \"Reduce number of watched files\",\n \"Try restarting dev server\",\n ],\n ),\n\n [ErrorCode.REQUEST_ERROR]: createSimpleError(\n ErrorCode.REQUEST_ERROR,\n \"Request handling error\",\n \"Error processing HTTP request.\",\n [\n \"Check request format and headers\",\n \"Verify route handler code\",\n \"Check for middleware errors\",\n ],\n ),\n};\n", "import { ErrorCode } from \"../error-codes.ts\";\nimport type { PartialErrorCatalog } from \"./types.ts\";\nimport { createErrorSolution, createSimpleError } from \"./factory.ts\";\n\nexport const RSC_ERROR_CATALOG: PartialErrorCatalog = {\n [ErrorCode.CLIENT_BOUNDARY_VIOLATION]: createErrorSolution(\n ErrorCode.CLIENT_BOUNDARY_VIOLATION,\n {\n title: \"Client/Server boundary violation\",\n message: \"Server-only code used in Client Component.\",\n steps: [\n \"Move server-only imports to Server Components\",\n \"Use 'use server' for server actions\",\n \"Split component into server and client parts\",\n ],\n example: `// \u2713 Correct pattern\nimport { db } from './database'\nexport default async function ServerComponent() {\n const data = await db.query('...')\n return <ClientComponent data={data} />\n}\n\n'use client'\nexport default function ClientComponent({ data }) {\n return <div>{data}</div>\n}`,\n },\n ),\n\n [ErrorCode.SERVER_ONLY_IN_CLIENT]: createSimpleError(\n ErrorCode.SERVER_ONLY_IN_CLIENT,\n \"Server-only module in Client Component\",\n \"Cannot use server-only module in client code.\",\n [\n \"Move server logic to Server Component\",\n \"Use API routes for client data fetching\",\n \"Pass data as props from server\",\n ],\n ),\n\n [ErrorCode.CLIENT_ONLY_IN_SERVER]: createSimpleError(\n ErrorCode.CLIENT_ONLY_IN_SERVER,\n \"Client-only code in Server Component\",\n \"Cannot use browser APIs in Server Component.\",\n [\n \"Add 'use client' directive\",\n \"Move client-only code to Client Component\",\n \"Use useEffect for client-side logic\",\n ],\n ),\n\n [ErrorCode.INVALID_USE_CLIENT]: createErrorSolution(ErrorCode.INVALID_USE_CLIENT, {\n title: \"Invalid 'use client' directive\",\n message: \"'use client' directive is not properly placed.\",\n steps: [\n \"Place 'use client' at the very top of file\",\n \"Must be before any imports\",\n 'Use exact string: \"use client\"',\n ],\n example: `'use client' // Must be first line\n\nimport React from 'react'`,\n }),\n\n [ErrorCode.INVALID_USE_SERVER]: createSimpleError(\n ErrorCode.INVALID_USE_SERVER,\n \"Invalid 'use server' directive\",\n \"'use server' directive is not properly placed.\",\n [\n \"Place 'use server' at top of function\",\n \"Or at top of file for all functions\",\n 'Use exact string: \"use server\"',\n ],\n ),\n\n [ErrorCode.RSC_PAYLOAD_ERROR]: createSimpleError(\n ErrorCode.RSC_PAYLOAD_ERROR,\n \"RSC payload error\",\n \"Error serializing Server Component payload.\",\n [\n \"Ensure props are JSON-serializable\",\n \"Avoid passing functions as props\",\n \"Check for circular references\",\n ],\n ),\n};\n", "import { ErrorCode } from \"../error-codes.ts\";\nimport type { PartialErrorCatalog } from \"./types.ts\";\nimport { createSimpleError } from \"./factory.ts\";\n\nexport const DEV_ERROR_CATALOG: PartialErrorCatalog = {\n [ErrorCode.DEV_SERVER_ERROR]: createSimpleError(\n ErrorCode.DEV_SERVER_ERROR,\n \"Development server error\",\n \"Error in development server.\",\n [\n \"Check server logs for details\",\n \"Try restarting dev server\",\n \"Clear cache and restart\",\n ],\n ),\n\n [ErrorCode.FAST_REFRESH_ERROR]: createSimpleError(\n ErrorCode.FAST_REFRESH_ERROR,\n \"Fast Refresh error\",\n \"React Fast Refresh failed.\",\n [\n \"Check for syntax errors\",\n \"Ensure components follow Fast Refresh rules\",\n \"Try full page refresh\",\n ],\n ),\n\n [ErrorCode.ERROR_OVERLAY_ERROR]: createSimpleError(\n ErrorCode.ERROR_OVERLAY_ERROR,\n \"Error overlay failed\",\n \"Could not display error overlay.\",\n [\n \"Check browser console for details\",\n \"Try disabling browser extensions\",\n \"Refresh the page\",\n ],\n ),\n\n [ErrorCode.SOURCE_MAP_ERROR]: createSimpleError(\n ErrorCode.SOURCE_MAP_ERROR,\n \"Source map error\",\n \"Error loading or parsing source map.\",\n [\n \"Check that source maps are enabled\",\n \"Try rebuilding the project\",\n \"Check for corrupted build files\",\n ],\n ),\n};\n", "import { ErrorCode } from \"../error-codes.ts\";\nimport type { PartialErrorCatalog } from \"./types.ts\";\nimport { createSimpleError } from \"./factory.ts\";\n\nexport const DEPLOYMENT_ERROR_CATALOG: PartialErrorCatalog = {\n [ErrorCode.DEPLOYMENT_ERROR]: createSimpleError(\n ErrorCode.DEPLOYMENT_ERROR,\n \"Deployment failed\",\n \"Failed to deploy application.\",\n [\n \"Check deployment logs for details\",\n \"Verify platform credentials\",\n \"Ensure build succeeded first\",\n ],\n ),\n\n [ErrorCode.PLATFORM_ERROR]: createSimpleError(\n ErrorCode.PLATFORM_ERROR,\n \"Platform error\",\n \"Deployment platform returned an error.\",\n [\n \"Check platform status page\",\n \"Verify API keys and credentials\",\n \"Try deploying again\",\n ],\n ),\n\n [ErrorCode.ENV_VAR_MISSING]: createSimpleError(\n ErrorCode.ENV_VAR_MISSING,\n \"Environment variable missing\",\n \"Required environment variable is not set.\",\n [\n \"Add variable to .env file\",\n \"Set variable in deployment platform\",\n \"Check variable name is correct\",\n ],\n ),\n\n [ErrorCode.PRODUCTION_BUILD_REQUIRED]: createSimpleError(\n ErrorCode.PRODUCTION_BUILD_REQUIRED,\n \"Production build required\",\n \"Must build project before deploying.\",\n [\n \"Run 'veryfront build' first\",\n \"Check that dist/ directory exists\",\n \"Verify build completed successfully\",\n ],\n ),\n};\n", "import { ErrorCode } from \"../error-codes.ts\";\nimport type { PartialErrorCatalog } from \"./types.ts\";\nimport { createSimpleError } from \"./factory.ts\";\n\nexport const GENERAL_ERROR_CATALOG: PartialErrorCatalog = {\n [ErrorCode.UNKNOWN_ERROR]: createSimpleError(\n ErrorCode.UNKNOWN_ERROR,\n \"Unknown error\",\n \"An unexpected error occurred.\",\n [\n \"Check error details above\",\n \"Run 'veryfront doctor' to diagnose\",\n \"Try restarting the operation\",\n \"Check GitHub issues for similar problems\",\n ],\n ),\n\n [ErrorCode.PERMISSION_DENIED]: createSimpleError(\n ErrorCode.PERMISSION_DENIED,\n \"Permission denied\",\n \"Insufficient permissions to perform operation.\",\n [\n \"Check file/directory permissions\",\n \"Run with appropriate permissions\",\n \"Verify user has write access\",\n ],\n ),\n\n [ErrorCode.FILE_NOT_FOUND]: createSimpleError(\n ErrorCode.FILE_NOT_FOUND,\n \"File not found\",\n \"Required file does not exist.\",\n [\n \"Check that file path is correct\",\n \"Verify file exists in project\",\n \"Check for typos in file name\",\n ],\n ),\n\n [ErrorCode.INVALID_ARGUMENT]: createSimpleError(\n ErrorCode.INVALID_ARGUMENT,\n \"Invalid argument\",\n \"Command received invalid argument.\",\n [\n \"Check command syntax\",\n \"Verify argument values\",\n \"Run 'veryfront help <command>' for usage\",\n ],\n ),\n\n [ErrorCode.TIMEOUT_ERROR]: createSimpleError(\n ErrorCode.TIMEOUT_ERROR,\n \"Operation timed out\",\n \"Operation took too long to complete.\",\n [\n \"Check network connectivity\",\n \"Try increasing timeout if available\",\n \"Check for very large files\",\n ],\n ),\n};\n", "import type { ErrorCodeType } from \"../error-codes.ts\";\nimport type { ErrorCatalog, ErrorSolution } from \"./types.ts\";\n\nimport { CONFIG_ERROR_CATALOG } from \"./config-errors.ts\";\nimport { BUILD_ERROR_CATALOG } from \"./build-errors.ts\";\nimport { RUNTIME_ERROR_CATALOG } from \"./runtime-errors.ts\";\nimport { ROUTE_ERROR_CATALOG } from \"./route-errors.ts\";\nimport { MODULE_ERROR_CATALOG } from \"./module-errors.ts\";\nimport { SERVER_ERROR_CATALOG } from \"./server-errors.ts\";\nimport { RSC_ERROR_CATALOG } from \"./rsc-errors.ts\";\nimport { DEV_ERROR_CATALOG } from \"./dev-errors.ts\";\nimport { DEPLOYMENT_ERROR_CATALOG } from \"./deployment-errors.ts\";\nimport { GENERAL_ERROR_CATALOG } from \"./general-errors.ts\";\n\nexport const ERROR_CATALOG = {\n ...CONFIG_ERROR_CATALOG,\n ...BUILD_ERROR_CATALOG,\n ...RUNTIME_ERROR_CATALOG,\n ...ROUTE_ERROR_CATALOG,\n ...MODULE_ERROR_CATALOG,\n ...SERVER_ERROR_CATALOG,\n ...RSC_ERROR_CATALOG,\n ...DEV_ERROR_CATALOG,\n ...DEPLOYMENT_ERROR_CATALOG,\n ...GENERAL_ERROR_CATALOG,\n} as ErrorCatalog;\n\nexport function getErrorSolution(code: ErrorCodeType): ErrorSolution | null {\n return ERROR_CATALOG[code] || null;\n}\n\nexport function searchErrors(query: string): ErrorSolution[] {\n const lowerQuery = query.toLowerCase();\n return Object.values(ERROR_CATALOG).filter(\n (error) =>\n error.title.toLowerCase().includes(lowerQuery) ||\n error.message.toLowerCase().includes(lowerQuery) ||\n error.steps?.some((step) => step.toLowerCase().includes(lowerQuery)),\n );\n}\n\nexport type { ErrorCatalog, ErrorSolution, PartialErrorCatalog } from \"./types.ts\";\n\nexport { createErrorSolution, createSimpleError } from \"./factory.ts\";\n\nexport {\n BUILD_ERROR_CATALOG,\n CONFIG_ERROR_CATALOG,\n DEPLOYMENT_ERROR_CATALOG,\n DEV_ERROR_CATALOG,\n GENERAL_ERROR_CATALOG,\n MODULE_ERROR_CATALOG,\n ROUTE_ERROR_CATALOG,\n RSC_ERROR_CATALOG,\n RUNTIME_ERROR_CATALOG,\n SERVER_ERROR_CATALOG,\n};\n", "export interface ErrorSolution {\n message: string;\n steps?: string[];\n example?: string;\n docs?: string;\n}\n\nexport const ERROR_SOLUTIONS: Record<string, ErrorSolution> = {\n \"missing-config\": {\n message: \"No veryfront.config.js found in project directory\",\n steps: [\n \"Create a veryfront.config.js file in your project root\",\n \"Run 'veryfront init' to generate a default config\",\n \"Or create one manually with minimal configuration\",\n ],\n example: `export default {\n title: \"My App\",\n dev: { port: 3002 }\n};`,\n },\n\n \"invalid-config\": {\n message: \"Invalid configuration in veryfront.config.js\",\n steps: [\n \"Check that your config exports a default object\",\n \"Ensure all values are valid JavaScript\",\n \"Remove any trailing commas in objects\",\n ],\n example: `export default {\n title: \"My App\", // \u2713 Valid string\n dev: {\n port: 3002, // \u2713 Valid number\n open: true // \u2713 No trailing comma\n }\n};`,\n },\n\n \"invalid-route\": {\n message: \"Invalid route file format\",\n steps: [\n \"Route files must export handler functions (GET, POST, etc.)\",\n \"Each handler must return a Response object\",\n \"Check for syntax errors in your route file\",\n ],\n example: `// app/api/users/route.ts\nexport async function GET() {\n return Response.json({ users: [] });\n}\n\nexport async function POST(request: Request) {\n const body = await request.json();\n return Response.json({ created: true });\n}`,\n },\n\n \"client-boundary\": {\n message: \"Server-only code used in Client Component\",\n steps: [\n \"Move server-only imports to Server Components\",\n \"Use 'use server' directive for server actions\",\n \"Split component into server and client parts\",\n ],\n example: `// \u274C Wrong - database import in client component\n'use client';\nimport { db } from './database'; // Error!\n\nimport { db } from './database';\nexport default async function ServerComponent() {\n const data = await db.query('...');\n return <ClientComponent data={data} />;\n}\n\n'use client';\nexport default function ClientComponent({ data }) {\n}`,\n docs: \"https://github.com/veryfront/veryfront/docs/rsc-boundaries\",\n },\n\n \"import-not-found\": {\n message: \"Failed to resolve import\",\n steps: [\n \"Check that the file path is correct\",\n \"Ensure the module is installed or available\",\n \"For remote imports, check network connectivity\",\n \"Add missing imports to veryfront.config.js importMap\",\n ],\n example: `// veryfront.config.js\nresolve: {\n importMap: {\n imports: {\n \"my-lib\": \"https://esm.sh/my-lib@1.0.0\",\n \"@/utils\": \"./src/utils/index.ts\"\n }\n }\n}`,\n },\n\n \"port-in-use\": {\n message: \"Port is already in use\",\n steps: [\n \"Stop any other servers running on this port\",\n \"Use a different port with --port flag\",\n \"Check for zombie processes: lsof -i :PORT\",\n ],\n example: `veryfront dev --port 3003`,\n },\n\n \"build-failed\": {\n message: \"Build failed with errors\",\n steps: [\n \"Check the error messages above for details\",\n \"Fix any TypeScript or syntax errors\",\n \"Ensure all imports can be resolved\",\n \"Run 'veryfront doctor' to check system\",\n ],\n },\n\n \"missing-deps\": {\n message: \"Required dependencies not found\",\n steps: [\n \"Check that React is in your import map\",\n \"Ensure all peer dependencies are included\",\n \"Run 'veryfront doctor' to verify setup\",\n ],\n example: `// Minimum required imports\n\"react\": \"https://esm.sh/react@19.1.1\",\n\"react-dom\": \"https://esm.sh/react-dom@19.1.1\"`,\n },\n};\n", "/**\n * Pure ANSI escape code colors for npm/Node.js builds\n *\n * This file provides a zero-dependency color implementation using ANSI codes.\n * It's used in npm builds where std/fmt/colors.ts isn't available.\n */\n\nimport type { ColorFunction, ConsoleStyler } from \"./types.ts\";\n\nconst ansi = (open: number, close: number): ColorFunction => (text: string) =>\n `\\x1b[${open}m${text}\\x1b[${close}m`;\n\nexport const red: ColorFunction = ansi(31, 39);\nexport const green: ColorFunction = ansi(32, 39);\nexport const yellow: ColorFunction = ansi(33, 39);\nexport const blue: ColorFunction = ansi(34, 39);\nexport const magenta: ColorFunction = ansi(35, 39);\nexport const cyan: ColorFunction = ansi(36, 39);\nexport const white: ColorFunction = ansi(37, 39);\nexport const gray: ColorFunction = ansi(90, 39);\nexport const bold: ColorFunction = ansi(1, 22);\nexport const dim: ColorFunction = ansi(2, 22);\nexport const italic: ColorFunction = ansi(3, 23);\nexport const underline: ColorFunction = ansi(4, 24);\nexport const strikethrough: ColorFunction = ansi(9, 29);\nexport const reset: ColorFunction = (text: string) => `\\x1b[0m${text}`;\n\nexport const colors: ConsoleStyler = {\n red,\n green,\n yellow,\n blue,\n cyan,\n magenta,\n white,\n gray,\n bold,\n dim,\n italic,\n underline,\n strikethrough,\n reset,\n};\n", "/**\n * Deno console styling implementation using std/fmt/colors.ts\n */\n\nimport {\n blue,\n bold,\n cyan,\n dim,\n gray,\n green,\n italic,\n magenta,\n red,\n reset,\n strikethrough,\n underline,\n white,\n yellow,\n} from \"std/fmt/colors.ts\";\n\nimport type { ConsoleStyler } from \"./types.ts\";\n\nexport const colors: ConsoleStyler = {\n red,\n green,\n yellow,\n blue,\n cyan,\n magenta,\n white,\n gray,\n bold,\n dim,\n italic,\n underline,\n strikethrough,\n reset,\n};\n\nexport {\n blue,\n bold,\n cyan,\n dim,\n gray,\n green,\n italic,\n magenta,\n red,\n reset,\n strikethrough,\n underline,\n white,\n yellow,\n};\n", "/**\n * Node.js console styling implementation using picocolors\n */\n\nimport type { ConsoleStyler } from \"./types.ts\";\n\n// Lazy-loaded picocolors instance\ntype PicoColors = {\n red: (s: string) => string;\n green: (s: string) => string;\n yellow: (s: string) => string;\n blue: (s: string) => string;\n cyan: (s: string) => string;\n magenta: (s: string) => string;\n white: (s: string) => string;\n gray: (s: string) => string;\n bold: (s: string) => string;\n dim: (s: string) => string;\n italic: (s: string) => string;\n underline: (s: string) => string;\n strikethrough: (s: string) => string;\n reset: (s: string) => string;\n};\n\nlet pc: PicoColors | null = null;\n\nasync function ensurePc(): Promise<PicoColors> {\n if (pc) return pc;\n // Construct module name dynamically to prevent Deno static analyzer\n // from trying to resolve this npm package during lint/check\n const picocolorsModule = [\"npm:\", \"picocolors\"].join(\"\");\n const mod = await import(picocolorsModule);\n pc = mod.default as PicoColors;\n return pc;\n}\n\n// Lazy wrapper that falls back to identity if not loaded\nconst lazyColor = (fn: keyof PicoColors) => (s: string) => pc?.[fn]?.(s) ?? s;\n\nexport const colors: ConsoleStyler = {\n red: lazyColor(\"red\"),\n green: lazyColor(\"green\"),\n yellow: lazyColor(\"yellow\"),\n blue: lazyColor(\"blue\"),\n cyan: lazyColor(\"cyan\"),\n magenta: lazyColor(\"magenta\"),\n white: lazyColor(\"white\"),\n gray: lazyColor(\"gray\"),\n bold: lazyColor(\"bold\"),\n dim: lazyColor(\"dim\"),\n italic: lazyColor(\"italic\"),\n underline: lazyColor(\"underline\"),\n strikethrough: lazyColor(\"strikethrough\"),\n reset: lazyColor(\"reset\"),\n};\n\nexport const red = lazyColor(\"red\");\nexport const green = lazyColor(\"green\");\nexport const yellow = lazyColor(\"yellow\");\nexport const blue = lazyColor(\"blue\");\nexport const cyan = lazyColor(\"cyan\");\nexport const magenta = lazyColor(\"magenta\");\nexport const white = lazyColor(\"white\");\nexport const gray = lazyColor(\"gray\");\nexport const bold = lazyColor(\"bold\");\nexport const dim = lazyColor(\"dim\");\nexport const italic = lazyColor(\"italic\");\nexport const underline = lazyColor(\"underline\");\nexport const strikethrough = lazyColor(\"strikethrough\");\nexport const reset = lazyColor(\"reset\");\n\n// Initialize picocolors on first use\nexport async function initColors(): Promise<void> {\n await ensurePc();\n}\n", "/**\n * Cross-runtime console styling\n *\n * Provides terminal colors that work in Deno, Node.js, and Bun.\n * Falls back to no-op functions in environments without terminal support.\n */\n\nimport { isDeno } from \"../runtime.ts\";\nimport type { ColorFunction, ConsoleStyler } from \"./types.ts\";\n\nexport type { ColorFunction, ConsoleStyler } from \"./types.ts\";\n\nconst noOp: ColorFunction = (text: string) => text;\n\nconst fallbackColors: ConsoleStyler = {\n red: noOp,\n green: noOp,\n yellow: noOp,\n blue: noOp,\n cyan: noOp,\n magenta: noOp,\n white: noOp,\n gray: noOp,\n bold: noOp,\n dim: noOp,\n italic: noOp,\n underline: noOp,\n strikethrough: noOp,\n reset: noOp,\n};\n\nlet _colors: ConsoleStyler | null = null;\n\nasync function loadColors(): Promise<ConsoleStyler> {\n if (_colors) return _colors;\n\n try {\n if (isDeno) {\n const mod = await import(\"./deno.ts\");\n _colors = mod.colors;\n } else {\n const mod = await import(\"./node.ts\");\n _colors = mod.colors;\n }\n } catch {\n _colors = fallbackColors;\n }\n\n return _colors;\n}\n\nconst colorsPromise = loadColors();\n\nfunction getColors(): ConsoleStyler {\n return _colors ?? fallbackColors;\n}\n\nexport const red: ColorFunction = (text) => getColors().red(text);\nexport const green: ColorFunction = (text) => getColors().green(text);\nexport const yellow: ColorFunction = (text) => getColors().yellow(text);\nexport const blue: ColorFunction = (text) => getColors().blue(text);\nexport const cyan: ColorFunction = (text) => getColors().cyan(text);\nexport const magenta: ColorFunction = (text) => getColors().magenta(text);\nexport const white: ColorFunction = (text) => getColors().white(text);\nexport const gray: ColorFunction = (text) => getColors().gray(text);\nexport const bold: ColorFunction = (text) => getColors().bold(text);\nexport const dim: ColorFunction = (text) => getColors().dim(text);\nexport const italic: ColorFunction = (text) => getColors().italic(text);\nexport const underline: ColorFunction = (text) => getColors().underline(text);\nexport const strikethrough: ColorFunction = (text) => getColors().strikethrough(text);\nexport const reset: ColorFunction = (text) => getColors().reset(text);\n\nexport const colors = {\n red,\n green,\n yellow,\n blue,\n cyan,\n magenta,\n white,\n gray,\n bold,\n dim,\n italic,\n underline,\n strikethrough,\n reset,\n} satisfies ConsoleStyler;\n\nexport { colorsPromise };\n", "export function identifyError(error: Error): string {\n const message = error.message.toLowerCase();\n\n if (message.includes(\"veryfront.config\") && message.includes(\"not found\")) {\n return \"missing-config\";\n }\n if (message.includes(\"config\") && (message.includes(\"invalid\") || message.includes(\"parse\"))) {\n return \"invalid-config\";\n }\n\n if (message.includes(\"route\") && (message.includes(\"invalid\") || message.includes(\"export\"))) {\n return \"invalid-route\";\n }\n\n if (message.includes(\"client\") && (message.includes(\"boundary\") || message.includes(\"server\"))) {\n return \"client-boundary\";\n }\n\n if (\n message.includes(\"import\") ||\n message.includes(\"module not found\") ||\n message.includes(\"resolve\")\n ) {\n return \"import-not-found\";\n }\n\n if (message.includes(\"port\") && (message.includes(\"in use\") || message.includes(\"eaddrinuse\"))) {\n return \"port-in-use\";\n }\n\n if (message.includes(\"build\") && message.includes(\"fail\")) {\n return \"build-failed\";\n }\n\n if (message.includes(\"react\") && message.includes(\"not found\")) {\n return \"missing-deps\";\n }\n\n return \"unknown\";\n}\n", "import { bold, cyan, dim, red, yellow } from \"@veryfront/compat/console\";\nimport { ERROR_SOLUTIONS } from \"./error-catalog.ts\";\nimport { identifyError } from \"./error-identifier.ts\";\n\nexport function formatUserError(error: Error): string {\n const output: string[] = [];\n\n output.push(\"\");\n output.push(red(bold(\"\u2716 Error: \")) + bold(error.message));\n output.push(\"\");\n\n const errorKey = identifyError(error);\n const solution = ERROR_SOLUTIONS[errorKey];\n\n if (solution) {\n if (solution.message) {\n output.push(yellow(\"Problem: \") + solution.message);\n output.push(\"\");\n }\n\n if (solution.steps && solution.steps.length > 0) {\n output.push(cyan(\"How to fix:\"));\n solution.steps.forEach((step, i) => {\n output.push(` ${dim(`${i + 1}.`)} ${step}`);\n });\n output.push(\"\");\n }\n\n if (solution.example) {\n output.push(cyan(\"Example:\"));\n output.push(\"\");\n solution.example.split(\"\\n\").forEach((line) => {\n output.push(` ${dim(line)}`);\n });\n output.push(\"\");\n }\n\n if (solution.docs) {\n output.push(dim(\"Learn more: \") + cyan(solution.docs));\n output.push(\"\");\n }\n } else {\n if (error.stack) {\n output.push(yellow(\"Stack trace:\"));\n const stackLines = error.stack.split(\"\\n\").slice(1, 4);\n stackLines.forEach((line) => {\n output.push(dim(` ${line.trim()}`));\n });\n output.push(\"\");\n }\n\n output.push(dim(\"For help, run: \") + cyan(\"veryfront doctor\"));\n output.push(\"\");\n }\n\n return output.join(\"\\n\");\n}\n", "import { red } from \"@veryfront/compat/console\";\nimport { exit } from \"@veryfront/platform/compat/process.ts\";\nimport { cliLogger } from \"@veryfront/utils/logger/logger.ts\";\nimport { formatUserError } from \"./error-formatter.ts\";\n\nexport function wrapErrorHandler<TArgs extends unknown[], TReturn>(\n fn: (...args: TArgs) => Promise<TReturn>,\n): (...args: TArgs) => Promise<TReturn> {\n return async (...args: TArgs): Promise<TReturn> => {\n try {\n return await fn(...args);\n } catch (error) {\n if (error instanceof Error) {\n cliLogger.error(formatUserError(error));\n } else {\n cliLogger.error(red(\"\u2716 Unknown error:\"), error);\n }\n if (import.meta.main) {\n exit(1);\n }\n throw error;\n }\n };\n}\n", "export { ERROR_SOLUTIONS, type ErrorSolution } from \"./error-catalog.ts\";\nexport { formatUserError } from \"./error-formatter.ts\";\nexport { identifyError } from \"./error-identifier.ts\";\nexport { wrapErrorHandler } from \"./error-wrapper.ts\";\n", "export { ErrorCode, VeryfrontError } from \"./types.ts\";\n\nexport {\n AgentError,\n AgentIntentError,\n AgentNotFoundError,\n AgentTimeoutError,\n OrchestrationError,\n} from \"./agent-errors.ts\";\n\nexport { BuildError, CompilationError } from \"./build-errors.ts\";\n\nexport { RenderError, RuntimeError } from \"./runtime-errors.ts\";\n\nexport {\n ConfigError,\n FileSystemError,\n NetworkError,\n NotSupportedError,\n PermissionError,\n} from \"./system-errors.ts\";\n\nexport {\n handleError,\n handleErrorWithFallback,\n handleErrorWithFallbackSync,\n logAndThrow,\n retryWithBackoff,\n wrapError,\n} from \"./error-handlers.ts\";\n\nexport {\n BUILD_ERROR_CATALOG,\n CONFIG_ERROR_CATALOG,\n createErrorSolution,\n createSimpleError,\n DEPLOYMENT_ERROR_CATALOG,\n DEV_ERROR_CATALOG,\n ERROR_CATALOG,\n GENERAL_ERROR_CATALOG,\n getErrorSolution,\n MODULE_ERROR_CATALOG,\n ROUTE_ERROR_CATALOG,\n RSC_ERROR_CATALOG,\n RUNTIME_ERROR_CATALOG,\n searchErrors,\n SERVER_ERROR_CATALOG,\n} from \"./catalog/index.ts\";\n\nexport type { ErrorCatalog, ErrorSolution, PartialErrorCatalog } from \"./catalog/index.ts\";\n\nexport {\n ERROR_SOLUTIONS,\n formatUserError,\n identifyError,\n wrapErrorHandler,\n} from \"./user-friendly/index.ts\";\n\nexport type { ErrorSolution as UserFriendlyErrorSolution } from \"./user-friendly/index.ts\";\n\nexport type { ErrorCodeType } from \"./error-codes.ts\";\n", "import { FileSystemError } from \"@veryfront/errors\";\nimport { createError, toError } from \"../../../core/errors/veryfront-error.ts\";\nimport type {\n DirEntry,\n FileChangeEvent,\n FileChangeKind,\n FileInfo,\n FileSystemAdapter,\n FileWatcher,\n WatchOptions,\n} from \"../base.ts\";\n\nimport { createFileWatcher, createWatcherIterator, enqueueWatchEvent } from \"../shared-watcher.ts\";\nimport type { BunFSWatcher, BunWatchEvent } from \"./types.ts\";\nimport { serverLogger } from \"@veryfront/utils\";\n\nexport class BunFileSystemAdapter implements FileSystemAdapter {\n async readFile(path: string): Promise<string> {\n const file = Bun.file(path);\n return await file.text();\n }\n\n async readFileBytes(path: string): Promise<Uint8Array> {\n const file = Bun.file(path);\n // deno-lint-ignore no-explicit-any\n const buffer = await (file as any).arrayBuffer();\n return new Uint8Array(buffer);\n }\n\n async writeFile(path: string, content: string): Promise<void> {\n await Bun.write(path, content);\n }\n\n async exists(path: string): Promise<boolean> {\n const file = Bun.file(path);\n return await file.exists();\n }\n\n async *readDir(path: string): AsyncIterable<DirEntry> {\n const { readdir } = await import(\"node:fs/promises\");\n const entries = await readdir(path, { withFileTypes: true });\n\n for (const entry of entries) {\n yield {\n name: entry.name,\n isFile: entry.isFile(),\n isDirectory: entry.isDirectory(),\n isSymlink: entry.isSymbolicLink(),\n };\n }\n }\n\n async stat(path: string): Promise<FileInfo> {\n const file = Bun.file(path);\n const exists = await file.exists();\n if (!exists) {\n throw new FileSystemError(`File not found: ${path}`, { path });\n }\n\n const { stat } = await import(\"node:fs/promises\");\n const stats = await stat(path);\n\n return {\n size: file.size,\n isFile: stats.isFile(),\n isDirectory: stats.isDirectory(),\n isSymlink: stats.isSymbolicLink(),\n mtime: stats.mtime,\n };\n }\n\n async mkdir(path: string, options?: { recursive?: boolean }): Promise<void> {\n const { mkdir } = await import(\"node:fs/promises\");\n await mkdir(path, options);\n }\n\n async remove(path: string, options?: { recursive?: boolean }): Promise<void> {\n const { rm } = await import(\"node:fs/promises\");\n await rm(path, { recursive: options?.recursive, force: true });\n }\n\n async makeTempDir(prefix: string): Promise<string> {\n const { mkdtemp } = await import(\"node:fs/promises\");\n const { join } = await import(\"node:path\");\n const { tmpdir } = await import(\"node:os\");\n return await mkdtemp(join(tmpdir(), prefix));\n }\n\n watch(paths: string | string[], options?: WatchOptions): FileWatcher {\n const pathArray = Array.isArray(paths) ? paths : [paths];\n const recursive = options?.recursive ?? true;\n const signal = options?.signal;\n\n let closed = false;\n const watchers: Array<BunFSWatcher | import(\"node:fs\").FSWatcher> = [];\n const eventQueue: FileChangeEvent[] = [];\n let resolver: ((value: IteratorResult<FileChangeEvent>) => void) | null = null;\n\n const mapBunEventKind = (type: string): FileChangeKind => {\n switch (type) {\n case \"create\":\n return \"create\";\n case \"change\":\n return \"modify\";\n case \"delete\":\n return \"delete\";\n default:\n return \"any\";\n }\n };\n\n const setupWatcher = (path: string) => {\n try {\n if (typeof Bun !== \"undefined\" && Bun.watch) {\n const watcher = Bun.watch(path, {\n recursive,\n onChange: (event: BunWatchEvent) => {\n if (closed || signal?.aborted) return;\n\n enqueueWatchEvent(\n { kind: mapBunEventKind(event.type), paths: [event.path] },\n eventQueue,\n () => resolver,\n (r) => {\n resolver = r;\n },\n );\n },\n });\n watchers.push(watcher);\n } else {\n throw toError(createError({\n type: \"not_supported\",\n message: \"Bun.watch is not available in this environment\",\n feature: \"Bun.watch\",\n }));\n }\n } catch (error) {\n serverLogger.error(`Failed to watch ${path}:`, error);\n }\n };\n\n Promise.all(pathArray.map(setupWatcher)).catch((error) => {\n serverLogger.error(\"Failed to setup Bun file watchers:\", error);\n });\n\n const iterator = createWatcherIterator(\n eventQueue,\n () => resolver,\n (r) => {\n resolver = r;\n },\n () => closed,\n () => signal?.aborted ?? false,\n );\n\n const cleanup = () => {\n closed = true;\n watchers.forEach((watcher) => {\n try {\n if (\"stop\" in watcher && typeof watcher.stop === \"function\") {\n watcher.stop();\n } else if (\"close\" in watcher && typeof watcher.close === \"function\") {\n watcher.close();\n }\n } catch (error) {\n serverLogger.debug(\"Error closing Bun file watcher during cleanup:\", error);\n }\n });\n if (resolver) {\n resolver({ done: true, value: undefined });\n resolver = null;\n }\n };\n\n if (signal) {\n signal.addEventListener(\"abort\", cleanup);\n }\n\n return createFileWatcher(iterator, cleanup);\n }\n}\n", "import type { EnvironmentAdapter } from \"../base.ts\";\n\nexport class BunEnvironmentAdapter implements EnvironmentAdapter {\n get(key: string): string | undefined {\n return Bun.env[key];\n }\n\n set(key: string, value: string): void {\n Bun.env[key] = value;\n }\n\n toObject(): Record<string, string> {\n return { ...Bun.env };\n }\n}\n", "import type { ServerAdapter, WebSocketUpgrade } from \"../base.ts\";\nimport { createError, toError } from \"../../../core/errors/veryfront-error.ts\";\n\nexport class BunServerAdapter implements ServerAdapter {\n upgradeWebSocket(request: Request): WebSocketUpgrade {\n const success = Bun.upgrade(request);\n\n if (!success) {\n throw toError(createError({\n type: \"network\",\n message: \"Failed to upgrade WebSocket connection\",\n }));\n }\n\n const socket = new BunWebSocket();\n const response = new Response(null, {\n status: 101,\n statusText: \"Switching Protocols\",\n });\n\n return { socket: socket as unknown as WebSocket, response };\n }\n}\n\nexport class BunWebSocket {\n public readyState = 1;\n\n public onopen: ((event: Event) => void) | null = null;\n public onclose: ((event: Event) => void) | null = null;\n public onerror: ((event: Event) => void) | null = null;\n public onmessage: ((event: MessageEvent) => void) | null = null;\n\n static readonly CONNECTING = 0;\n static readonly OPEN = 1;\n static readonly CLOSING = 2;\n static readonly CLOSED = 3;\n\n send(_data: string | ArrayBuffer) {\n throw toError(createError({\n type: \"network\",\n message: \"WebSocket send called on placeholder - use Bun.serve websocket handlers\",\n }));\n }\n\n close(_code?: number, _reason?: string) {\n this.readyState = 3;\n }\n}\n", "import type { ServeOptions, Server } from \"../base.ts\";\nimport type { BunServer as BunServerType } from \"./types.ts\";\nimport { DEFAULT_PORT } from \"@veryfront/config\";\nimport { serverLogger } from \"@veryfront/utils\";\n\nexport class BunServer implements Server {\n constructor(\n private server: BunServerType,\n private hostname: string,\n private port: number,\n ) {}\n\n stop(): Promise<void> {\n this.server.stop();\n return Promise.resolve();\n }\n\n get addr() {\n return { hostname: this.hostname, port: this.port };\n }\n}\n\nexport function createBunServer(\n handler: (request: Request) => Promise<Response> | Response,\n options: ServeOptions = {},\n): Promise<Server> {\n const { port = DEFAULT_PORT, hostname = \"localhost\", onListen } = options;\n\n const server = Bun.serve({\n port,\n hostname,\n async fetch(request: Request) {\n try {\n return await handler(request);\n } catch (error) {\n serverLogger.error(\"Request handler error:\", error);\n return new Response(\"Internal Server Error\", { status: 500 });\n }\n },\n });\n\n onListen?.({ hostname, port });\n\n return Promise.resolve(new BunServer(server, hostname, port));\n}\n", "import type {\n RuntimeAdapter,\n RuntimeCapabilities,\n RuntimeFeatures,\n ServeOptions,\n Server,\n} from \"../base.ts\";\nimport { BunFileSystemAdapter } from \"./filesystem-adapter.ts\";\nimport { BunEnvironmentAdapter } from \"./environment-adapter.ts\";\nimport { BunServerAdapter } from \"./websocket-adapter.ts\";\nimport { createBunServer } from \"./http-server.ts\";\n\nexport class BunAdapter implements RuntimeAdapter {\n readonly id = \"bun\" as const;\n readonly name = \"bun\";\n /** @deprecated Use `id` instead */\n readonly platform = \"bun\" as const;\n\n fs = new BunFileSystemAdapter();\n env = new BunEnvironmentAdapter();\n server = new BunServerAdapter();\n\n readonly capabilities: RuntimeCapabilities = {\n typescript: true,\n jsx: true,\n http2: false, // Bun's HTTP/2 support is experimental\n websocket: true,\n workers: true,\n fileWatching: true,\n shell: true,\n kvStore: false,\n writableFs: true,\n };\n\n /** @deprecated Use `capabilities` instead */\n readonly features: RuntimeFeatures = {\n websocket: true,\n http2: false,\n workers: true,\n jsx: true,\n typescript: true,\n };\n\n serve(\n handler: (request: Request) => Promise<Response> | Response,\n options: ServeOptions = {},\n ): Promise<Server> {\n return createBunServer(handler, options);\n }\n}\n\nexport const bunAdapter = new BunAdapter();\n", "export { BunAdapter, bunAdapter } from \"./adapter.ts\";\nexport { BunFileSystemAdapter } from \"./filesystem-adapter.ts\";\nexport { BunEnvironmentAdapter } from \"./environment-adapter.ts\";\nexport { BunServerAdapter, BunWebSocket } from \"./websocket-adapter.ts\";\nexport { BunServer, createBunServer } from \"./http-server.ts\";\nexport type {\n BunFile,\n BunFSWatcher,\n BunNamespace,\n BunServeOptions,\n BunServer as BunServerType,\n BunWatchEvent,\n BunWatchOptions,\n} from \"./types.ts\";\n", "export {\n BunAdapter,\n bunAdapter,\n BunEnvironmentAdapter,\n BunFileSystemAdapter,\n BunServer,\n BunServerAdapter,\n BunWebSocket,\n createBunServer,\n} from \"./bun/index.ts\";\n\nexport type {\n BunFile,\n BunFSWatcher,\n BunNamespace,\n BunServeOptions,\n BunServerType,\n BunWatchEvent,\n BunWatchOptions,\n} from \"./bun/index.ts\";\n", "import { createError, toError } from \"../../core/errors/veryfront-error.ts\";\nimport type { RuntimeAdapter } from \"./base.ts\";\n\nexport interface MockRuntimeAdapter extends RuntimeAdapter {\n fs: RuntimeAdapter[\"fs\"] & {\n files: Map<string, string>;\n directories: Set<string>;\n };\n}\n\n/**\n * Mock RuntimeAdapter for testing\n *\n * Provides an in-memory filesystem and environment for unit testing.\n * This adapter is useful for testing code that depends on the filesystem\n * without requiring actual file I/O.\n *\n * @example\n * ```typescript\n * const adapter = createMockAdapter();\n * adapter.fs.files.set(\"/project/pages/index.tsx\", \"export default () => <div>Home</div>\");\n * const content = await adapter.fs.readFile(\"/project/pages/index.tsx\");\n * ```\n */\n\n/**\n * Creates a mock RuntimeAdapter for testing\n *\n * The mock adapter uses in-memory Map and Set for file storage:\n * - `files`: Map<string, string> for file contents\n * - `directories`: Set<string> for tracking directories\n * - `envVars`: Map<string, string> for environment variables\n */\nexport function createMockAdapter(): MockRuntimeAdapter {\n const files = new Map<string, string>();\n const directories = new Set<string>();\n const envVars = new Map<string, string>();\n\n return {\n id: \"memory\" as const,\n name: \"mock\",\n /** @deprecated Use `id` instead */\n platform: \"memory\" as const,\n capabilities: {\n typescript: false,\n jsx: false,\n http2: false,\n websocket: false,\n workers: false,\n fileWatching: false,\n shell: false,\n kvStore: false,\n writableFs: true, // In-memory writes work\n },\n serve: (_handler, _options) => {\n return Promise.resolve({\n stop: () => Promise.resolve(),\n addr: { hostname: \"localhost\", port: 8000 },\n });\n },\n fs: {\n files,\n directories,\n readFile: (path: string) => {\n const content = files.get(path);\n if (!content) {\n throw toError(createError({\n type: \"file\",\n message: `File not found: ${path}`,\n }));\n }\n return Promise.resolve(content);\n },\n readFileBytes: (path: string) => {\n const content = files.get(path);\n if (!content) {\n throw toError(createError({\n type: \"file\",\n message: `File not found: ${path}`,\n }));\n }\n return Promise.resolve(new TextEncoder().encode(content));\n },\n writeFile: (path: string, content: string) => {\n files.set(path, content);\n return Promise.resolve();\n },\n exists: (path: string) => {\n if (files.has(path)) return Promise.resolve(true);\n if (directories.has(path)) return Promise.resolve(true);\n for (const filePath of files.keys()) {\n if (filePath.startsWith(path + \"/\")) return Promise.resolve(true);\n }\n return Promise.resolve(false);\n },\n readDir: async function* (path: string) {\n const entries = new Map<string, { isFile: boolean; isDirectory: boolean }>();\n\n for (const filePath of files.keys()) {\n if (filePath.startsWith(path + \"/\")) {\n const relativePath = filePath.slice(path.length + 1);\n const parts = relativePath.split(\"/\");\n const name = parts[0]!;\n\n if (!entries.has(name)) {\n entries.set(name, {\n isFile: parts.length === 1,\n isDirectory: parts.length > 1,\n });\n }\n }\n }\n\n for (const [name, meta] of entries.entries()) {\n yield { name, ...meta, isSymlink: false };\n }\n },\n stat: (path: string) => {\n if (files.has(path)) {\n const content = files.get(path)!;\n return Promise.resolve({\n size: content.length,\n isFile: true,\n isDirectory: false,\n isSymlink: false,\n mtime: new Date(),\n });\n }\n\n if (directories.has(path)) {\n return Promise.resolve({\n size: 0,\n isFile: false,\n isDirectory: true,\n isSymlink: false,\n mtime: new Date(),\n });\n }\n\n for (const filePath of files.keys()) {\n if (filePath.startsWith(path + \"/\")) {\n return Promise.resolve({\n size: 0,\n isFile: false,\n isDirectory: true,\n isSymlink: false,\n mtime: new Date(),\n });\n }\n }\n\n return Promise.reject(new Error(`Path not found: ${path}`));\n },\n mkdir: (_path: string) => Promise.resolve(),\n remove: (_path: string) => Promise.resolve(),\n makeTempDir: (prefix: string) =>\n Promise.resolve(`/tmp/${prefix}-${Math.random().toString(36).slice(2)}`),\n watch: () => ({\n async *[Symbol.asyncIterator]() {\n yield { kind: \"any\", paths: [] };\n },\n close: () => {},\n }),\n },\n env: {\n get: (key: string) => envVars.get(key),\n set: (key: string, value: string) => envVars.set(key, value),\n toObject: () => Object.fromEntries(envVars),\n },\n server: {\n upgradeWebSocket: (_request) => {\n throw new Error(\n \"WebSocket upgrade not available in mock adapter. \" +\n \"The mock adapter is designed for unit testing filesystem and environment operations. \" +\n \"For WebSocket testing, use integration tests with the actual Deno/Node/Bun adapter, \" +\n \"or mock the WebSocket behavior at a higher level in your tests.\",\n );\n },\n },\n features: {\n websocket: false,\n http2: false,\n workers: false,\n jsx: false,\n typescript: false,\n },\n };\n}\n", "/**\n * Adapter Registry - Singleton management for RuntimeAdapter\n *\n * Provides a centralized way to access and configure the runtime adapter.\n * Supports auto-detection, manual configuration, and testing overrides.\n *\n * @example\n * ```ts\n * // Auto-detect and get adapter\n * const adapter = await runtime.get();\n *\n * // Manual configuration (e.g., Cloudflare Workers)\n * await runtime.set(createCloudflareAdapter(env));\n *\n * // Testing override\n * await runtime.set(createMockAdapter());\n * ```\n */\n\nimport type { RuntimeAdapter, RuntimeId } from \"./base.ts\";\n\ntype AdapterLoader = () => Promise<RuntimeAdapter>;\n\n/**\n * Registry for managing RuntimeAdapter singleton\n */\nclass AdapterRegistry {\n private instance: RuntimeAdapter | null = null;\n private initialized = false;\n private loaders: Map<RuntimeId, AdapterLoader> = new Map();\n\n constructor() {\n // Register default loaders (lazy imports to avoid bundling unused adapters)\n this.loaders.set(\"deno\", async () => {\n const { denoAdapter } = await import(\"./deno.ts\");\n return denoAdapter;\n });\n\n this.loaders.set(\"node\", async () => {\n const { nodeAdapter } = await import(\"./node.ts\");\n return nodeAdapter;\n });\n\n this.loaders.set(\"bun\", async () => {\n const { bunAdapter } = await import(\"./bun.ts\");\n return bunAdapter;\n });\n\n // Note: Cloudflare requires manual initialization with env context\n // this.loaders.set(\"cloudflare\", ...) - not auto-detectable\n\n this.loaders.set(\"memory\", async () => {\n const { createMockAdapter } = await import(\"./mock.ts\");\n return createMockAdapter();\n });\n }\n\n /**\n * Get the current adapter, auto-detecting if needed\n */\n async get(): Promise<RuntimeAdapter> {\n if (this.instance) {\n return this.instance;\n }\n\n // Auto-detect runtime\n const runtimeId = this.detectRuntime();\n const loader = this.loaders.get(runtimeId);\n\n if (!loader) {\n throw new Error(\n `Unsupported runtime: ${runtimeId}. ` +\n `Supported runtimes: ${[...this.loaders.keys()].join(\", \")}. ` +\n `For Cloudflare Workers, use runtime.set(createCloudflareAdapter(env)).`,\n );\n }\n\n this.instance = await loader();\n await this.initialize();\n return this.instance;\n }\n\n /**\n * Manually set the adapter (for Cloudflare Workers, testing, etc.)\n */\n async set(adapter: RuntimeAdapter): Promise<void> {\n // Shutdown existing adapter if any\n if (this.instance && this.initialized) {\n await this.instance.shutdown?.();\n }\n\n this.instance = adapter;\n this.initialized = false;\n await this.initialize();\n }\n\n /**\n * Get adapter synchronously (throws if not initialized)\n */\n getSync(): RuntimeAdapter {\n if (!this.instance) {\n throw new Error(\n \"RuntimeAdapter not initialized. Call `await runtime.get()` first, \" +\n \"or use `await runtime.set(adapter)` to configure manually.\",\n );\n }\n return this.instance;\n }\n\n /**\n * Check if adapter is initialized\n */\n isInitialized(): boolean {\n return this.instance !== null && this.initialized;\n }\n\n /**\n * Reset the registry (for testing)\n */\n async reset(): Promise<void> {\n if (this.instance && this.initialized) {\n await this.instance.shutdown?.();\n }\n this.instance = null;\n this.initialized = false;\n }\n\n /**\n * Register a custom adapter loader\n */\n registerLoader(id: RuntimeId, loader: AdapterLoader): void {\n this.loaders.set(id, loader);\n }\n\n /**\n * Detect current runtime\n */\n private detectRuntime(): RuntimeId {\n // Deno\n if (typeof Deno !== \"undefined\" && typeof Deno.version === \"object\") {\n return \"deno\";\n }\n\n // Bun\n if (\"Bun\" in globalThis) {\n return \"bun\";\n }\n\n // Node.js\n if (typeof process !== \"undefined\" && process.versions?.node) {\n return \"node\";\n }\n\n // Cloudflare Workers (detected but requires manual init)\n if (\"caches\" in globalThis && \"WebSocketPair\" in globalThis) {\n throw new Error(\n \"Cloudflare Workers detected but requires manual initialization. \" +\n \"Use: await runtime.set(createCloudflareAdapter(env))\",\n );\n }\n\n throw new Error(\n \"Unsupported runtime detected. Supported runtimes: deno, node, bun. \" +\n \"For Cloudflare Workers, call runtime.set(createCloudflareAdapter(env)).\",\n );\n }\n\n /**\n * Initialize the adapter\n */\n private async initialize(): Promise<void> {\n if (!this.instance || this.initialized) {\n return;\n }\n\n await this.instance.initialize?.();\n this.initialized = true;\n }\n}\n\n/**\n * Global runtime adapter registry\n *\n * @example\n * ```ts\n * import { runtime } from \"@veryfront/platform/adapters/registry.ts\";\n *\n * // Get adapter (auto-detects runtime)\n * const adapter = await runtime.get();\n *\n * // Use filesystem\n * const content = await adapter.fs.readFile(\"./config.json\");\n * ```\n */\nexport const runtime = new AdapterRegistry();\n\n// Re-export for convenience\nexport type { RuntimeAdapter, RuntimeId } from \"./base.ts\";\n", "import { logger } from \"@veryfront/utils\";\nimport type { RuntimeAdapter, RuntimeId } from \"./base.ts\";\nimport { createError, toError } from \"../../core/errors/veryfront-error.ts\";\n\n// Re-export the registry for convenient access\nexport { runtime } from \"./registry.ts\";\n\ninterface DenoGlobal {\n Deno: {\n version: { deno: string };\n [key: string]: unknown;\n };\n}\n\ninterface BunGlobal {\n Bun: {\n version: string;\n [key: string]: unknown;\n };\n}\n\ninterface CloudflareGlobal {\n caches: unknown;\n WebSocketPair: unknown;\n}\n\nfunction isDeno(global: typeof globalThis): global is typeof globalThis & DenoGlobal {\n return \"Deno\" in global && typeof (global as DenoGlobal).Deno === \"object\";\n}\n\nfunction isBun(global: typeof globalThis): global is typeof globalThis & BunGlobal {\n return \"Bun\" in global && typeof (global as BunGlobal).Bun === \"object\";\n}\n\nfunction isCloudflare(global: typeof globalThis): global is typeof globalThis & CloudflareGlobal {\n return \"caches\" in global && \"WebSocketPair\" in global;\n}\n\n/**\n * Detect the current runtime environment\n * @returns Runtime identifier\n */\nexport function detectRuntime(): RuntimeId | \"unknown\" {\n if (isDeno(globalThis)) {\n return \"deno\";\n }\n\n if (isBun(globalThis)) {\n return \"bun\";\n }\n\n const globalProcess = (globalThis as { process?: { versions?: { node?: string } } }).process;\n if (globalProcess?.versions?.node) {\n return \"node\";\n }\n\n if (isCloudflare(globalThis)) {\n return \"cloudflare\";\n }\n\n return \"unknown\";\n}\n\n/**\n * Get the runtime adapter for the current environment\n *\n * @deprecated Use `runtime.get()` from `./registry.ts` instead for singleton management\n *\n * @example\n * ```ts\n * // Old way (deprecated)\n * const adapter = await getAdapter();\n *\n * // New way (recommended)\n * import { runtime } from \"@veryfront/platform/adapters/registry.ts\";\n * const adapter = await runtime.get();\n * ```\n */\nexport async function getAdapter(): Promise<RuntimeAdapter> {\n const runtimeId = detectRuntime();\n\n switch (runtimeId) {\n case \"deno\": {\n const { denoAdapter } = await import(\"./deno.ts\");\n return denoAdapter;\n }\n\n case \"bun\": {\n const { bunAdapter } = await import(\"./bun.ts\");\n return bunAdapter;\n }\n\n case \"node\": {\n const { nodeAdapter } = await import(\"./node.ts\");\n return nodeAdapter;\n }\n\n case \"cloudflare\": {\n const errorMsg = \"Cloudflare adapter requires manual initialization with environment. \" +\n \"Please use createCloudflareAdapter() with your environment context.\";\n logger.error(\"[Adapter Detection]\", errorMsg);\n throw toError(createError({\n type: \"config\",\n message: errorMsg,\n }));\n }\n\n default: {\n const supportedRuntimes = [\"deno\", \"bun\", \"node\", \"cloudflare\"];\n const errorMsg = `Unsupported runtime: ${runtimeId}. Supported runtimes: ${\n supportedRuntimes.join(\", \")\n }`;\n logger.error(\"[Adapter Detection]\", errorMsg);\n throw toError(createError({\n type: \"config\",\n message: errorMsg,\n }));\n }\n }\n}\n\nexport { denoAdapter } from \"./deno.ts\";\nexport { nodeAdapter } from \"./node.ts\";\nexport { bunAdapter } from \"./bun.ts\";\n\nexport type {\n EnvironmentAdapter,\n FileSystemAdapter,\n RuntimeAdapter,\n RuntimeCapabilities,\n RuntimeFeatures,\n RuntimeId,\n} from \"./base.ts\";\n", "/**\n * Veryfront - Main Package\n *\n * This is the core API for building Veryfront applications.\n *\n * ## Subpath Exports (Advanced Use)\n * - `veryfront/server` \u2192 Server APIs (startUniversalServer, createDevServer)\n * - `veryfront/middleware` \u2192 Middleware system\n * - `veryfront/components` \u2192 All React components (including OptimizedImage)\n * - `veryfront/data` \u2192 Data fetching utilities\n * - `veryfront/config` \u2192 Configuration utilities\n */\n\n// ============================================================================\n// React Components (Most Common)\n// ============================================================================\n\nexport { Link } from \"@veryfront/components\";\nexport type { LinkProps } from \"@veryfront/components\";\n\nexport { Head } from \"@veryfront/components\";\n\nexport { MDXProvider, useMDXComponents } from \"@veryfront/components\";\nexport type { MDXProviderProps } from \"@veryfront/components\";\n\n// Optimized Images\nexport {\n OptimizedBackgroundImage,\n OptimizedImage,\n SimpleOptimizedImage,\n} from \"@veryfront/components\";\nexport type { OptimizedImageProps } from \"@veryfront/components\";\n\n// ============================================================================\n// Data Fetching\n// ============================================================================\n\nexport type {\n DataContext,\n InferGetServerDataProps,\n PageWithData,\n StaticPathsResult,\n} from \"@veryfront/data\";\n\n// Data helpers (notFound/redirect for getServerData)\nexport { notFound, redirect } from \"@veryfront/data\";\n\n// ============================================================================\n// API Routes\n// ============================================================================\n\nexport type { APIContext, APIHandler, APIResponse, APIRoute } from \"@veryfront/routing\";\n\n// Response helpers\nexport {\n badRequest,\n forbidden,\n json,\n notFound as apiNotFound,\n redirect as apiRedirect,\n serverError,\n unauthorized,\n} from \"@veryfront/routing\";\n\n// Input validation (for API routes)\nexport {\n CommonSchemas,\n createValidatedHandler,\n parseFormData,\n parseJsonBody,\n parseQueryParams,\n sanitizeData,\n type ValidatedHandlerConfig,\n type ValidatedHandlerFunction,\n ValidationError,\n} from \"@veryfront/security\";\n\n// ============================================================================\n// Configuration\n// ============================================================================\n\nexport { defineConfig } from \"@veryfront/config\";\nexport type { VeryfrontConfig } from \"@veryfront/config\";\n\n// ============================================================================\n// Common Types\n// ============================================================================\n\nexport type { ComponentProps, MDXFrontmatter, PageContext } from \"@veryfront/types\";\n", "export { AppWrapper } from \"./AppWrapper.tsx\";\nexport type { AppWrapperProps } from \"./AppWrapper.tsx\";\n\nexport { Head } from \"./Head.tsx\";\n\nexport { LayoutComponent } from \"./LayoutComponent.tsx\";\nexport type { LayoutComponentProps } from \"./LayoutComponent.tsx\";\n\nexport { Link } from \"./Link.tsx\";\nexport type { LinkProps } from \"./Link.tsx\";\n\nexport { MDXProvider, useMDXComponents } from \"./MDXProvider.tsx\";\nexport type { MDXProviderProps } from \"./MDXProvider.tsx\";\n\nexport { ProviderComponent } from \"./ProviderComponent.tsx\";\nexport type { ProviderComponentProps } from \"./ProviderComponent.tsx\";\n\nexport * from \"./optimized-image/index.ts\";\n", "import type * as React from \"react\";\nimport type { MDXComponents, PageContext as TypedPageContext } from \"@veryfront/types\";\nimport type { MdxBundle } from \"./LayoutComponent.tsx\";\nimport { LayoutComponent } from \"./LayoutComponent.tsx\";\nimport { ProviderComponent } from \"./ProviderComponent.tsx\";\n\nexport interface AppWrapperProps {\n children: React.ReactNode;\n providers?: MdxBundle[];\n layout?: MdxBundle;\n components?: MDXComponents;\n mode?: string;\n studioEnabled?: boolean;\n pageContext?: TypedPageContext;\n}\n\nexport function AppWrapper({\n children,\n providers = [],\n layout,\n components = {},\n mode: _mode,\n studioEnabled: _studioEnabled,\n pageContext,\n}: AppWrapperProps) {\n let content = children;\n\n if (layout) {\n content = (\n <LayoutComponent mdxBundle={layout} components={components} pageContext={pageContext}>\n {content}\n </LayoutComponent>\n );\n }\n\n for (const provider of [...providers].reverse()) {\n content = (\n <ProviderComponent mdxBundle={provider} components={components}>\n {content}\n </ProviderComponent>\n );\n }\n\n return content;\n}\n", "import type React from \"react\";\nimport { useMemo, useRef } from \"react\";\nimport { mdxRenderer } from \"@veryfront/transforms/mdx/index.ts\";\nimport type { MdxBundle, MDXComponents, PageContext as TypedPageContext } from \"@veryfront/types\";\nimport { rendererLogger as logger } from \"@veryfront/utils\";\n\nexport type { MdxBundle } from \"@veryfront/types\";\n\nexport interface LayoutComponentProps {\n mdxBundle: MdxBundle;\n children: React.ReactNode;\n components?: MDXComponents;\n pageContext?: TypedPageContext;\n}\n\nfunction useStableObject<T>(obj: T): T {\n const ref = useRef(obj);\n const serialized = JSON.stringify(obj);\n const prevSerialized = useRef(serialized);\n\n if (prevSerialized.current !== serialized) {\n ref.current = obj;\n prevSerialized.current = serialized;\n }\n\n return ref.current;\n}\n\nexport function LayoutComponent({\n mdxBundle,\n children,\n components = {},\n pageContext,\n}: LayoutComponentProps) {\n const stableFrontmatter = useStableObject(mdxBundle.frontmatter);\n const stablePageContext = useStableObject(pageContext);\n\n const element = useMemo(() => {\n try {\n return mdxRenderer.render(mdxBundle.compiledCode, {\n components,\n frontmatter: { ...(stableFrontmatter || {}), pageContext: stablePageContext },\n globals: mdxBundle.globals,\n extractLayout: true,\n children,\n });\n } catch (error) {\n logger.error(\"[LayoutComponent] Render failed:\", error);\n return <>{children}</>;\n }\n }, [\n mdxBundle.compiledCode,\n stableFrontmatter,\n components,\n children,\n stablePageContext,\n mdxBundle.globals,\n ]);\n\n if (!element) return <>{children}</>;\n return element as React.ReactElement;\n}\n", "import { rendererLogger as logger } from \"@veryfront/utils\";\nimport { LRUCache } from \"@veryfront/utils/lru-wrapper.ts\";\nimport React from \"react\";\nimport { MDX_RENDERER_MAX_ENTRIES, MDX_RENDERER_TTL_MS } from \"@veryfront/utils/constants/cache.ts\";\nimport { type ESMLoaderContext, loadModuleESM } from \"./esm-module-loader.ts\";\nimport {\n executeModule as _executeModule,\n selectComponent as _selectComponent,\n} from \"./module-executor.ts\";\nimport { type ParsedMDX, parseMDXCode } from \"./parser.ts\";\nimport type { MDXComponents, MDXFrontmatter, MDXGlobals, MDXModule } from \"./types.ts\";\n\nexport interface MDXRenderOptions {\n components?: MDXComponents;\n frontmatter?: MDXFrontmatter;\n globals?: MDXGlobals;\n extractLayout?: boolean;\n children?: React.ReactNode;\n}\n\nexport class MDXRenderer {\n private esmCacheDir?: string;\n private moduleCache: LRUCache<string, MDXModule> = new LRUCache({\n maxEntries: MDX_RENDERER_MAX_ENTRIES,\n ttlMs: MDX_RENDERER_TTL_MS,\n });\n\n constructor() {\n }\n\n async clearCache() {\n this.moduleCache.destroy();\n\n if (this.esmCacheDir) {\n try {\n const { getAdapter } = await import(\"@veryfront/platform/adapters/detect.ts\");\n const adapter = await getAdapter();\n await adapter.fs.remove(this.esmCacheDir, { recursive: true });\n } catch (_error) {\n void _error;\n }\n this.esmCacheDir = undefined;\n }\n }\n\n async loadModuleESM(compiledProgramCode: string): Promise<MDXModule> {\n const context: ESMLoaderContext = {\n esmCacheDir: this.esmCacheDir,\n moduleCache: this.moduleCache,\n };\n const result = await loadModuleESM(compiledProgramCode, context);\n this.esmCacheDir = context.esmCacheDir;\n return result;\n }\n\n render(\n _compiledCode: string,\n _options: MDXRenderOptions = {},\n ): React.ReactElement {\n logger.error(\n \"[MDX] Synchronous render() called but string-based factories are disabled for security. \" +\n \"Please use: await mdxRenderer.loadModuleESM(compiledCode) instead.\",\n );\n\n return React.createElement(\n \"div\",\n {\n style: {\n padding: \"1rem\",\n backgroundColor: \"#fff3cd\",\n border: \"1px solid #ffc107\",\n borderRadius: \"0.375rem\",\n color: \"#856404\",\n },\n },\n React.createElement(\"strong\", {}, \"Migration Required: \"),\n \"Synchronous render() is no longer supported for security reasons. \",\n React.createElement(\"br\"),\n \"Please update to: \",\n React.createElement(\"code\", {}, \"await mdxRenderer.loadModuleESM(compiledCode)\"),\n );\n }\n\n private parseMDXCode(compiledCode: string): ParsedMDX {\n return parseMDXCode(compiledCode);\n }\n}\n\nlet _mdxRendererInstance: MDXRenderer | undefined;\n\nfunction getMDXRendererInstance(): MDXRenderer {\n if (!_mdxRendererInstance) {\n _mdxRendererInstance = new MDXRenderer();\n }\n return _mdxRendererInstance;\n}\n\nexport const mdxRenderer = new Proxy({} as MDXRenderer, {\n get(_target, prop) {\n const instance = getMDXRendererInstance();\n const value = instance[prop as keyof MDXRenderer];\n if (typeof value === \"function\") {\n return value.bind(instance);\n }\n return value;\n },\n set(_target, prop, value) {\n const instance = getMDXRendererInstance();\n (instance as any)[prop] = value;\n return true;\n },\n has(_target, prop) {\n const instance = getMDXRendererInstance();\n return prop in instance;\n },\n ownKeys(_target) {\n const instance = getMDXRendererInstance();\n return Reflect.ownKeys(instance);\n },\n getOwnPropertyDescriptor(_target, prop) {\n const instance = getMDXRendererInstance();\n return Reflect.getOwnPropertyDescriptor(instance, prop);\n },\n});\n\nexport async function clearMDXRendererCache() {\n await getMDXRendererInstance().clearCache();\n}\n\nexport {\n MDXCacheAdapter,\n type MDXCacheAdapterOptions,\n type MDXCompilationResult,\n} from \"./mdx-cache-adapter.ts\";\n", "import { LRUCacheAdapter } from \"./cache/stores/memory/lru-cache-adapter.ts\";\nimport type { LRUCacheOptions } from \"./cache/stores/memory/types.ts\";\nimport { DEFAULT_LRU_MAX_ENTRIES } from \"@veryfront/utils\";\nimport { getEnv } from \"../../platform/compat/process.ts\";\n\nexport interface LRUOptions {\n maxEntries?: number;\n ttlMs?: number;\n cleanupIntervalMs?: number;\n}\n\nexport class LRUCache<K, V> {\n private adapter: LRUCacheAdapter;\n private cleanupTimer?: ReturnType<typeof setInterval>;\n private cleanupIntervalMs: number;\n private ttlMs?: number;\n\n constructor(options: LRUOptions = {}) {\n const adapterOptions: LRUCacheOptions = {\n maxEntries: options.maxEntries ?? DEFAULT_LRU_MAX_ENTRIES,\n ttlMs: options.ttlMs,\n };\n\n this.adapter = new LRUCacheAdapter(adapterOptions);\n this.ttlMs = options.ttlMs;\n this.cleanupIntervalMs = options.cleanupIntervalMs ?? 60000;\n\n if (this.ttlMs && this.ttlMs > 0) {\n this.startPeriodicCleanup();\n }\n }\n\n private startPeriodicCleanup(): void {\n if (shouldDisableInterval()) {\n return;\n }\n if (this.cleanupTimer) {\n clearInterval(this.cleanupTimer);\n }\n\n const timer = setInterval(() => {\n this.adapter.cleanupExpired();\n }, this.cleanupIntervalMs);\n this.cleanupTimer = timer;\n }\n\n private toStringKey(key: K): string {\n if (typeof key === \"string\") {\n return key;\n }\n return String(key);\n }\n\n get size(): number {\n return this.adapter.getStats().entries;\n }\n\n has(key: K): boolean {\n return this.adapter.get(this.toStringKey(key)) !== undefined;\n }\n\n get(key: K): V | undefined {\n return this.adapter.get<V>(this.toStringKey(key));\n }\n\n set(key: K, value: V): void {\n this.adapter.set(this.toStringKey(key), value);\n }\n\n delete(key: K): boolean {\n const stringKey = this.toStringKey(key);\n const had = this.adapter.get(stringKey) !== undefined;\n this.adapter.delete(stringKey);\n return had;\n }\n\n clear(): void {\n this.adapter.clear();\n }\n\n cleanup(): void {\n this.adapter.cleanupExpired();\n }\n\n destroy(): void {\n if (this.cleanupTimer) {\n clearInterval(this.cleanupTimer);\n this.cleanupTimer = undefined;\n }\n\n this.adapter.clear();\n }\n\n keys(): IterableIterator<K> {\n return this.adapter.keys() as IterableIterator<K>;\n }\n}\n\nfunction shouldDisableInterval(): boolean {\n if ((globalThis as Record<string, unknown>).__vfDisableLruInterval === true) {\n return true;\n }\n try {\n return getEnv(\"VF_DISABLE_LRU_INTERVAL\") === \"1\";\n } catch {\n return false;\n }\n}\n", "import type { CacheAdapter, LRUCacheOptions, LRUCacheStats, LRUEntry } from \"./types.ts\";\nimport { LRUNode } from \"./lru-node.ts\";\nimport { LRUListManager } from \"./lru-list-manager.ts\";\nimport { EvictionManager } from \"../../eviction/eviction-manager.ts\";\nimport { EntryManager } from \"./entry-manager.ts\";\n\nfunction defaultSizeEstimator(value: unknown): number {\n if (value === null || value === undefined) return 0;\n if (typeof value === \"string\") return value.length * 2;\n if (typeof value === \"number\" || typeof value === \"bigint\") return 8;\n if (typeof value === \"boolean\") return 4;\n if (value instanceof Uint8Array || ArrayBuffer.isView(value)) return value.byteLength;\n if (value instanceof ArrayBuffer) return value.byteLength;\n if (typeof Blob !== \"undefined\" && value instanceof Blob) return value.size;\n\n try {\n return JSON.stringify(value).length * 2;\n } catch {\n return 0;\n }\n}\n\nexport class LRUCacheAdapter implements CacheAdapter {\n private readonly store = new Map<string, LRUNode<unknown>>();\n private readonly tagIndex = new Map<string, Set<string>>();\n private readonly listManager = new LRUListManager<unknown>();\n private readonly evictionManager: EvictionManager<LRUEntry<unknown>>;\n private readonly entryManager: EntryManager;\n private currentSize = 0;\n private readonly maxEntries: number;\n private readonly maxSizeBytes: number;\n private readonly defaultTtlMs?: number;\n private readonly onEvict?: (key: string, value: unknown) => void;\n\n constructor(options: LRUCacheOptions = {}) {\n this.maxEntries = options.maxEntries || 1000;\n this.maxSizeBytes = options.maxSizeBytes || 50 * 1024 * 1024; // 50MB default\n this.defaultTtlMs = options.ttlMs;\n this.onEvict = options.onEvict;\n\n const estimateSizeOf = options.estimateSizeOf || defaultSizeEstimator;\n\n this.evictionManager = new EvictionManager({\n onEvict: this.onEvict,\n loggerContext: \"MemoryCache\",\n });\n this.entryManager = new EntryManager(estimateSizeOf);\n }\n\n get<T>(key: string): T | undefined {\n const node = this.store.get(key);\n if (!node) return undefined;\n\n if (this.evictionManager.isExpired(node.entry)) {\n this.delete(key);\n return undefined;\n }\n\n this.listManager.moveToFront(node);\n return node.entry.value as T;\n }\n\n set<T>(key: string, value: T, ttlMs?: number, tags?: string[]): void {\n const existingNode = this.store.get(key);\n\n if (existingNode) {\n const sizeDelta = this.entryManager.updateExistingEntry(\n existingNode,\n value,\n ttlMs,\n tags,\n this.defaultTtlMs,\n this.listManager,\n this.tagIndex,\n key,\n );\n this.currentSize += sizeDelta;\n } else {\n const [_node, size] = this.entryManager.createNewEntry(\n key,\n value,\n ttlMs,\n tags,\n this.defaultTtlMs,\n this.listManager,\n this.store,\n );\n this.currentSize += size;\n }\n\n if (tags && tags.length > 0) {\n this.entryManager.updateTagIndex(tags, key, this.tagIndex);\n }\n\n this.currentSize = this.evictionManager.enforceMemoryLimits(\n this.listManager,\n this.store,\n this.tagIndex,\n this.currentSize,\n this.maxEntries,\n this.maxSizeBytes,\n );\n }\n\n delete(key: string): void {\n const node = this.store.get(key);\n if (!node) return;\n\n this.listManager.removeNode(node);\n this.store.delete(key);\n this.currentSize -= node.entry.size;\n\n if (node.entry.tags) {\n this.entryManager.cleanupTags(node.entry.tags, key, this.tagIndex);\n }\n\n if (this.onEvict) {\n this.onEvict(key, node.entry.value);\n }\n }\n\n invalidateTag(tag: string): number {\n const set = this.tagIndex.get(tag);\n if (!set) return 0;\n\n let count = 0;\n for (const key of set) {\n this.delete(key);\n count++;\n }\n this.tagIndex.delete(tag);\n return count;\n }\n\n clear(): void {\n if (this.onEvict) {\n for (const [key, node] of this.store) {\n this.onEvict(key, node.entry.value);\n }\n }\n\n this.store.clear();\n this.tagIndex.clear();\n this.listManager.clear();\n this.currentSize = 0;\n }\n\n getStats(): LRUCacheStats {\n return {\n entries: this.store.size,\n sizeBytes: this.currentSize,\n maxEntries: this.maxEntries,\n maxSizeBytes: this.maxSizeBytes,\n tags: this.tagIndex.size,\n };\n }\n\n cleanupExpired(): number {\n const now = Date.now();\n let cleaned = 0;\n\n for (const [key, node] of this.store) {\n if (typeof node.entry.expiry === \"number\" && now > node.entry.expiry) {\n this.delete(key);\n cleaned++;\n }\n }\n\n return cleaned;\n }\n\n keys(): IterableIterator<string> {\n return this.store.keys();\n }\n\n has(key: string): boolean {\n return this.get(key) !== undefined;\n }\n}\n", "import type { LRUNode } from \"./lru-node.ts\";\n\nexport class LRUListManager<T> {\n private head: LRUNode<T> | null = null;\n private tail: LRUNode<T> | null = null;\n\n getHead(): LRUNode<T> | null {\n return this.head;\n }\n\n getTail(): LRUNode<T> | null {\n return this.tail;\n }\n\n moveToFront(node: LRUNode<T>): void {\n if (node === this.head) {\n node.entry.lastAccessed = Date.now();\n return;\n }\n\n this.removeNode(node);\n\n this.addToFront(node);\n }\n\n addToFront(node: LRUNode<T>): void {\n node.next = this.head;\n node.prev = null;\n if (this.head) {\n this.head.prev = node;\n }\n this.head = node;\n if (!this.tail) {\n this.tail = node;\n }\n node.entry.lastAccessed = Date.now();\n }\n\n removeNode(node: LRUNode<T>): void {\n if (node.prev) {\n node.prev.next = node.next;\n }\n if (node.next) {\n node.next.prev = node.prev;\n }\n if (node === this.head) {\n this.head = node.next;\n }\n if (node === this.tail) {\n this.tail = node.prev;\n }\n }\n\n clear(): void {\n this.head = null;\n this.tail = null;\n }\n}\n", "export interface EvictableEntry {\n size: number;\n timestamp?: number;\n expiry?: number;\n value?: unknown;\n tags?: string[];\n}\n\nexport interface LRUTrackerInterface {\n getLRU(): string | undefined;\n remove(key: string): void;\n}\n\nexport interface LRUNodeInterface<T> {\n key: string;\n entry: T;\n prev: LRUNodeInterface<T> | null;\n next: LRUNodeInterface<T> | null;\n}\n\nexport interface LRUListManagerInterface<T> {\n getTail(): LRUNodeInterface<T> | null;\n removeNode(node: LRUNodeInterface<T>): void;\n}\n\nexport interface EvictionManagerOptions {\n onEvict?: (key: string, value: unknown) => void;\n loggerContext?: string;\n}\n\nexport class EvictionManager<TEntry extends EvictableEntry> {\n private readonly onEvict?: (key: string, value: unknown) => void;\n\n constructor(options: EvictionManagerOptions = {}) {\n this.onEvict = options.onEvict;\n }\n\n evictIfNeeded(\n cache: Map<string, TEntry>,\n lruTracker: LRUTrackerInterface,\n newEntrySize: number,\n maxSize: number,\n maxMemory: number,\n ): void {\n while (cache.size >= maxSize) {\n this.evictLRU(cache, lruTracker);\n }\n\n let memoryUsed = Array.from(cache.values()).reduce((sum, entry) => sum + entry.size, 0);\n\n while (memoryUsed + newEntrySize > maxMemory && cache.size > 0) {\n const evictedSize = this.evictLRU(cache, lruTracker);\n memoryUsed -= evictedSize;\n }\n }\n\n evictLRU(cache: Map<string, TEntry>, lruTracker: LRUTrackerInterface): number {\n const keyToEvict = lruTracker.getLRU();\n\n if (!keyToEvict) {\n return 0;\n }\n\n const entry = cache.get(keyToEvict);\n const size = entry?.size || 0;\n const value = entry?.value;\n\n cache.delete(keyToEvict);\n lruTracker.remove(keyToEvict);\n\n if (this.onEvict && entry) {\n this.onEvict(keyToEvict, value);\n }\n\n return size;\n }\n\n evictLRUFromList<T extends TEntry>(\n listManager: LRUListManagerInterface<T>,\n store: Map<string, LRUNodeInterface<T>>,\n tagIndex: Map<string, Set<string>>,\n currentSize: number,\n ): number {\n const tail = listManager.getTail();\n if (!tail) return currentSize;\n\n const node = tail;\n listManager.removeNode(node);\n store.delete(node.key);\n const newSize = currentSize - node.entry.size;\n\n if (node.entry.tags) {\n this.cleanupTags(node.entry.tags, node.key, tagIndex);\n }\n\n if (this.onEvict) {\n this.onEvict(node.key, node.entry.value);\n }\n\n return newSize;\n }\n\n enforceMemoryLimits<T extends TEntry>(\n listManager: LRUListManagerInterface<T>,\n store: Map<string, LRUNodeInterface<T>>,\n tagIndex: Map<string, Set<string>>,\n currentSize: number,\n maxEntries: number,\n maxSizeBytes: number,\n ): number {\n let size = currentSize;\n while ((store.size > maxEntries || size > maxSizeBytes) && listManager.getTail()) {\n size = this.evictLRUFromList(listManager, store, tagIndex, size);\n }\n return size;\n }\n\n private cleanupTags(tags: string[], key: string, tagIndex: Map<string, Set<string>>): void {\n for (const tag of tags) {\n const set = tagIndex.get(tag);\n if (set) {\n set.delete(key);\n if (set.size === 0) {\n tagIndex.delete(tag);\n }\n }\n }\n }\n\n evictExpired(cache: Map<string, TEntry>, lruTracker: LRUTrackerInterface, ttl: number): number {\n const now = Date.now();\n let evicted = 0;\n\n for (const [key, entry] of cache.entries()) {\n if (this.isExpired(entry, ttl, now)) {\n cache.delete(key);\n lruTracker.remove(key);\n evicted++;\n }\n }\n\n return evicted;\n }\n\n isExpired(entry: TEntry, ttl?: number, now: number = Date.now()): boolean {\n if (typeof entry.expiry === \"number\") {\n return now > entry.expiry;\n }\n\n if (typeof entry.timestamp === \"number\" && typeof ttl === \"number\") {\n const age = now - entry.timestamp;\n return age > ttl;\n }\n\n return false;\n }\n}\n", "import type { LRUEntry } from \"./types.ts\";\nimport { LRUNode } from \"./lru-node.ts\";\nimport type { LRUListManager } from \"./lru-list-manager.ts\";\n\nexport class EntryManager {\n constructor(\n private readonly estimateSizeOf: (value: unknown) => number,\n ) {}\n\n updateExistingEntry<T>(\n node: LRUNode<unknown>,\n value: T,\n ttlMs: number | undefined,\n tags: string[] | undefined,\n defaultTtlMs: number | undefined,\n listManager: LRUListManager<unknown>,\n tagIndex: Map<string, Set<string>>,\n key: string,\n ): number {\n const oldSize = node.entry.size;\n const newSize = this.estimateSizeOf(value);\n const expiry = this.calculateExpiry(ttlMs, defaultTtlMs);\n\n if (node.entry.tags) {\n this.cleanupTags(node.entry.tags, key, tagIndex);\n }\n\n node.entry = {\n value,\n size: newSize,\n expiry,\n tags,\n lastAccessed: Date.now(),\n };\n\n listManager.moveToFront(node);\n\n return newSize - oldSize;\n }\n\n createNewEntry<T>(\n key: string,\n value: T,\n ttlMs: number | undefined,\n tags: string[] | undefined,\n defaultTtlMs: number | undefined,\n listManager: LRUListManager<unknown>,\n store: Map<string, LRUNode<unknown>>,\n ): [LRUNode<unknown>, number] {\n const size = this.estimateSizeOf(value);\n const expiry = this.calculateExpiry(ttlMs, defaultTtlMs);\n\n const entry: LRUEntry<unknown> = {\n value,\n size,\n expiry,\n tags,\n lastAccessed: Date.now(),\n };\n\n const node = new LRUNode(key, entry);\n store.set(key, node);\n listManager.addToFront(node);\n\n return [node, size];\n }\n\n updateTagIndex(\n tags: string[],\n key: string,\n tagIndex: Map<string, Set<string>>,\n ): void {\n for (const tag of tags) {\n if (!tagIndex.has(tag)) {\n tagIndex.set(tag, new Set());\n }\n tagIndex.get(tag)?.add(key);\n }\n }\n\n cleanupTags(\n tags: string[],\n key: string,\n tagIndex: Map<string, Set<string>>,\n ): void {\n for (const tag of tags) {\n const set = tagIndex.get(tag);\n if (set) {\n set.delete(key);\n if (set.size === 0) {\n tagIndex.delete(tag);\n }\n }\n }\n }\n\n private calculateExpiry(\n ttlMs: number | undefined,\n defaultTtlMs: number | undefined,\n ): number | undefined {\n if (typeof ttlMs === \"number\") {\n return Date.now() + ttlMs;\n }\n if (defaultTtlMs) {\n return Date.now() + defaultTtlMs;\n }\n return undefined;\n }\n}\n", "import type { LRUEntry } from \"./types.ts\";\n\nexport class LRUNode<T> {\n constructor(\n public key: string,\n public entry: LRUEntry<T>,\n public prev: LRUNode<T> | null = null,\n public next: LRUNode<T> | null = null,\n ) {}\n}\n", "import { rendererLogger as logger } from \"@veryfront/utils\";\nimport { LRUCache } from \"@veryfront/utils/lru-wrapper.ts\";\nimport React from \"react\";\nimport { getCacheNamespace } from \"@veryfront/utils/cache/keys/namespace.ts\";\nimport {\n getDefaultImportMap,\n transformImportsWithMap,\n} from \"@veryfront/modules/import-map/index.ts\";\nimport type { MDXFrontmatter, MDXModule } from \"./types.ts\";\nimport { join } from \"https://deno.land/std@0.220.0/path/mod.ts\";\nimport { isDeno, isNode } from \"../../../platform/compat/runtime.ts\";\nimport { cwd } from \"../../../platform/compat/process.ts\";\n\n// True Node.js runtime (not Deno with Node.js compat)\nconst IS_TRUE_NODE = isNode && !isDeno;\n\n// Constants\nconst LOG_PREFIX_MDX_LOADER = \"[mdx-loader]\";\nconst LOG_PREFIX_MDX_RENDERER = \"[mdx-renderer]\";\nconst JSX_IMPORT_PATTERN = /import\\s+([^'\"]+)\\s+from\\s+['\"]file:\\/\\/([^'\"]+\\.(jsx|tsx))['\"];?/g;\nconst REACT_IMPORT_PATTERN = /import\\s+.*React.*\\s+from\\s+['\"]react['\"]/;\nconst HTTP_IMPORT_PATTERN = /['\"]https?:\\/\\/[^'\"]+['\"]/;\nconst ESBUILD_JSX_FACTORY = \"React.createElement\";\nconst ESBUILD_JSX_FRAGMENT = \"React.Fragment\";\nconst HTTP_MODULE_FETCH_TIMEOUT_MS = 30000;\n\n// Cache for resolved react package paths (Node.js only)\nconst _resolvedPaths: Record<string, string | null> = {};\n\n/**\n * Resolve a Node.js package path using require.resolve\n * Returns null if resolution fails\n */\nasync function resolveNodePackage(packageSpec: string): Promise<string | null> {\n if (!IS_TRUE_NODE) return null;\n if (packageSpec in _resolvedPaths) return _resolvedPaths[packageSpec]!;\n\n try {\n // Use Node.js createRequire to resolve the package from THIS file's location\n // This ensures react is found from veryfront's node_modules, not the project's\n const { createRequire } = await import(\"node:module\");\n const require = createRequire(import.meta.url);\n const resolved = require.resolve(packageSpec);\n _resolvedPaths[packageSpec] = resolved;\n return resolved;\n } catch {\n _resolvedPaths[packageSpec] = null;\n return null;\n }\n}\n\n/**\n * Transform react imports to absolute file:// paths for Node.js.\n * This is needed because MDX modules are cached in arbitrary directories\n * (like temp dirs) where Node.js cannot resolve bare 'react' imports.\n */\nasync function transformReactImportsToAbsolute(code: string): Promise<string> {\n if (!IS_TRUE_NODE) return code;\n\n // Resolve the actual react package paths\n const reactPath = await resolveNodePackage(\"react\");\n const reactJsxPath = await resolveNodePackage(\"react/jsx-runtime\");\n const reactJsxDevPath = await resolveNodePackage(\"react/jsx-dev-runtime\");\n const reactDomPath = await resolveNodePackage(\"react-dom\");\n\n let result = code;\n\n // Replace bare react imports with absolute file:// paths\n if (reactJsxPath) {\n result = result.replace(\n /from\\s+['\"]react\\/jsx-runtime['\"]/g,\n `from \"file://${reactJsxPath}\"`,\n );\n }\n if (reactJsxDevPath) {\n result = result.replace(\n /from\\s+['\"]react\\/jsx-dev-runtime['\"]/g,\n `from \"file://${reactJsxDevPath}\"`,\n );\n }\n if (reactDomPath) {\n result = result.replace(\n /from\\s+['\"]react-dom['\"]/g,\n `from \"file://${reactDomPath}\"`,\n );\n }\n if (reactPath) {\n result = result.replace(\n /from\\s+['\"]react['\"]/g,\n `from \"file://${reactPath}\"`,\n );\n }\n\n return result;\n}\n\nexport interface ESMLoaderContext {\n esmCacheDir?: string;\n moduleCache: LRUCache<string, MDXModule>;\n}\n\nexport function hashString(input: string): string {\n const HASH_SEED_FNV1A = 2166136261;\n let hash = HASH_SEED_FNV1A >>> 0; // FNV-1a\n for (let i = 0; i < input.length; i++) {\n hash ^= input.charCodeAt(i);\n hash = Math.imul(hash, 16777619);\n }\n return (hash >>> 0).toString(16);\n}\n\n/**\n * Creates an esbuild plugin to fetch and bundle HTTP/HTTPS imports.\n * This allows Node.js to use remote imports via esbuild bundling.\n */\nfunction createHTTPPluginForMDX(): import(\"esbuild\").Plugin {\n return {\n name: \"vf-mdx-http-fetch\",\n setup(build) {\n // Intercept HTTP/HTTPS imports\n build.onResolve({ filter: /^(http|https):\\/\\// }, (args) => ({\n path: args.path,\n namespace: \"http-url\",\n }));\n\n // Resolve relative imports within HTTP modules\n build.onResolve({ filter: /.*/, namespace: \"http-url\" }, (args) => {\n if (args.path.startsWith(\"http://\") || args.path.startsWith(\"https://\")) {\n return { path: args.path, namespace: \"http-url\" };\n }\n try {\n const resolved = new URL(args.path, args.importer).toString();\n return { path: resolved, namespace: \"http-url\" };\n } catch {\n return undefined;\n }\n });\n\n // Fetch and return HTTP module contents\n build.onLoad({ filter: /.*/, namespace: \"http-url\" }, async (args) => {\n let requestUrl = args.path;\n try {\n const u = new URL(args.path);\n // Optimize esm.sh URLs\n if (u.hostname === \"esm.sh\") {\n if (u.pathname.includes(\"/denonext/\")) {\n u.pathname = u.pathname.replace(\"/denonext/\", \"/\");\n }\n u.searchParams.set(\"target\", \"es2020\");\n u.searchParams.set(\"bundle\", \"true\");\n requestUrl = u.toString();\n }\n } catch {\n // Use original URL if parsing fails\n }\n\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), HTTP_MODULE_FETCH_TIMEOUT_MS);\n try {\n const res = await fetch(requestUrl, {\n headers: { \"user-agent\": \"Mozilla/5.0 Veryfront/1.0\" },\n signal: controller.signal,\n });\n clearTimeout(timeout);\n\n if (!res.ok) {\n return {\n errors: [{ text: `Failed to fetch ${args.path}: ${res.status}` }],\n };\n }\n\n const text = await res.text();\n return { contents: text, loader: \"js\" };\n } catch (e) {\n clearTimeout(timeout);\n return {\n errors: [{\n text: `Failed to fetch ${args.path}: ${e instanceof Error ? e.message : String(e)}`,\n }],\n };\n }\n });\n },\n };\n}\n\nexport async function loadModuleESM(\n compiledProgramCode: string,\n context: ESMLoaderContext,\n): Promise<MDXModule> {\n try {\n const { getAdapter } = await import(\"@veryfront/platform/adapters/detect.ts\");\n const adapter = await getAdapter();\n\n if (!context.esmCacheDir) {\n if (IS_TRUE_NODE) {\n // On Node.js, use a cache dir inside the project so module resolution works\n // Node.js resolves bare imports relative to the file location\n const projectCacheDir = join(\n cwd(),\n \"node_modules\",\n \".cache\",\n \"veryfront-mdx\",\n );\n await adapter.fs.mkdir(projectCacheDir, { recursive: true });\n context.esmCacheDir = projectCacheDir;\n } else {\n // On Deno, system temp dir is fine\n context.esmCacheDir = await adapter.fs.makeTempDir(\"veryfront-mdx-esm-\");\n }\n }\n\n // Transform imports with import map\n let rewritten: string;\n if (IS_TRUE_NODE) {\n // On Node.js, transform react imports to absolute file:// paths\n // This is needed because MDX modules are cached in temp directories\n // where Node.js cannot resolve bare imports\n rewritten = await transformReactImportsToAbsolute(compiledProgramCode);\n } else {\n // On Deno/browser, transform to esm.sh URLs\n rewritten = transformImportsWithMap(\n compiledProgramCode,\n getDefaultImportMap(),\n undefined,\n { resolveBare: true },\n );\n }\n\n // Transform JSX/TSX imports using esbuild\n // This handles user components that use JSX syntax\n let jsxMatch;\n const jsxTransforms: Array<{ original: string; transformed: string }> = [];\n\n // Import esbuild once outside the loop for better performance\n const { transform } = await import(\"esbuild/mod.js\");\n\n while ((jsxMatch = JSX_IMPORT_PATTERN.exec(rewritten)) !== null) {\n const [fullMatch, importClause, filePath, ext] = jsxMatch;\n\n if (!filePath) {\n logger.warn(`${LOG_PREFIX_MDX_LOADER} Skipping JSX import with undefined file path`, {\n fullMatch,\n });\n continue;\n }\n\n try {\n // Read the JSX file (filePath already includes full path)\n const jsxCode = await adapter.fs.readFile(filePath);\n\n // Use esbuild to transform JSX to JavaScript\n const result = await transform(jsxCode as string, {\n loader: ext === \"tsx\" ? \"tsx\" : \"jsx\",\n jsx: \"transform\",\n jsxFactory: ESBUILD_JSX_FACTORY,\n jsxFragment: ESBUILD_JSX_FRAGMENT,\n format: \"esm\",\n });\n\n let transformed = result.code;\n\n // Add React import if not present\n if (!REACT_IMPORT_PATTERN.test(transformed)) {\n transformed = `import React from 'react';\\n${transformed}`;\n }\n\n // Write transformed code to temp file\n const transformedFileName = `jsx-${hashString(filePath)}.mjs`;\n const transformedPath = join(context.esmCacheDir!, transformedFileName);\n await adapter.fs.writeFile(transformedPath, transformed);\n\n jsxTransforms.push({\n original: fullMatch,\n transformed: `import ${importClause} from \"file://${transformedPath}\";`,\n });\n\n logger.info(\n `${LOG_PREFIX_MDX_LOADER} Transformed JSX import using esbuild: ${filePath} -> ${transformedPath}`,\n );\n } catch (error) {\n logger.warn(`${LOG_PREFIX_MDX_LOADER} Failed to transform JSX import: ${filePath}`, error);\n // Keep original import if transformation fails\n }\n }\n\n // Apply all JSX transformations\n for (const { original, transformed } of jsxTransforms) {\n rewritten = rewritten.replace(original, transformed);\n }\n\n if (/\\bconst\\s+MDXLayout\\b/.test(rewritten) && !/export\\s+\\{[^}]*MDXLayout/.test(rewritten)) {\n rewritten += \"\\nexport { MDXLayout as __vfLayout };\\n\";\n }\n\n // On Node.js, bundle HTTP imports via esbuild instead of trying to import them directly\n if (IS_TRUE_NODE && HTTP_IMPORT_PATTERN.test(rewritten)) {\n logger.info(`${LOG_PREFIX_MDX_LOADER} Bundling HTTP imports via esbuild for Node.js`);\n const { build } = await import(\"esbuild/mod.js\");\n\n // Write temp source file for esbuild to process\n const tempSourcePath = join(context.esmCacheDir!, `temp-${hashString(rewritten)}.mjs`);\n await adapter.fs.writeFile(tempSourcePath, rewritten);\n\n try {\n const result = await build({\n entryPoints: [tempSourcePath],\n bundle: true,\n format: \"esm\",\n platform: \"neutral\",\n target: \"es2020\",\n write: false,\n plugins: [createHTTPPluginForMDX()],\n // Mark npm packages as external so they're not bundled\n external: [\"react\", \"react-dom\", \"react/jsx-runtime\", \"react/jsx-dev-runtime\"],\n });\n\n const bundledCode = result.outputFiles?.[0]?.text;\n if (bundledCode) {\n rewritten = bundledCode;\n logger.info(`${LOG_PREFIX_MDX_LOADER} Successfully bundled HTTP imports`);\n }\n } catch (bundleError) {\n logger.warn(\n `${LOG_PREFIX_MDX_LOADER} Failed to bundle HTTP imports, falling back to original code`,\n bundleError,\n );\n // Keep original code if bundling fails\n } finally {\n // Clean up temp file (use unlink since rm may not exist on all adapters)\n try {\n // deno-lint-ignore no-explicit-any\n const fsAny = adapter.fs as any;\n if (typeof fsAny.rm === \"function\") {\n await fsAny.rm(tempSourcePath);\n } else if (typeof fsAny.unlink === \"function\") {\n await fsAny.unlink(tempSourcePath);\n }\n // If neither exists, just leave the temp file (it's in a cache dir anyway)\n } catch {\n // Ignore cleanup errors\n }\n }\n }\n\n const codeHash = hashString(rewritten);\n const namespace = getCacheNamespace() || \"default\";\n const compositeKey = `${namespace}:${codeHash}`;\n\n const cached = context.moduleCache.get(compositeKey);\n if (cached) return cached as MDXModule;\n\n const nsDir = join(context.esmCacheDir, namespace);\n try {\n await adapter.fs.mkdir(nsDir, { recursive: true });\n } catch (e) {\n logger.debug(\n `${LOG_PREFIX_MDX_RENDERER} mkdir nsDir failed`,\n e instanceof Error ? e : String(e),\n );\n }\n\n const filePath = join(nsDir, `${codeHash}.mjs`);\n try {\n const stat = await adapter.fs.stat(filePath);\n if (!stat?.isFile) {\n await adapter.fs.writeFile(filePath, rewritten);\n }\n } catch (error) {\n logger.debug(`${LOG_PREFIX_MDX_RENDERER} Writing temporary MDX module file:`, error);\n await adapter.fs.writeFile(filePath, rewritten);\n }\n\n logger.info(`${LOG_PREFIX_MDX_RENDERER} Loading MDX module`, {\n filePath,\n codePreview: rewritten.substring(0, 300),\n });\n const mod = await import(`file://${filePath}?v=${codeHash}`) as Record<string, unknown> & {\n __vfLayout?: React.ComponentType;\n };\n\n const result: MDXModule = {\n ...mod,\n default: mod?.default as React.ComponentType<unknown> | undefined,\n MDXContent: mod?.MDXContent as React.ComponentType<unknown> | undefined,\n frontmatter: mod?.frontmatter as MDXFrontmatter | undefined,\n headings: mod?.headings as Array<{ text: string; level: number }> | undefined,\n title: mod?.title as string | undefined,\n description: mod?.description as string | undefined,\n layout: mod?.layout as string | boolean | React.ComponentType | undefined,\n MDXLayout: (mod?.MDXLayout || mod?.__vfLayout) as React.ComponentType<unknown> | undefined,\n MainLayout: mod?.MainLayout as React.ComponentType<unknown> | undefined,\n };\n context.moduleCache.set(compositeKey, result);\n return result;\n } catch (error) {\n logger.error(`${LOG_PREFIX_MDX_RENDERER} MDX ESM load failed:`, error);\n throw error;\n }\n}\n", "import { serverLogger as logger } from \"../../logger/logger.ts\";\nimport { getEnvironmentVariable } from \"../../logger/env.ts\";\nimport type { GlobalWithVeryFrontCache } from \"@veryfront/types/global-guards.ts\";\n\nlet cacheNamespace: string | undefined =\n (globalThis as GlobalWithVeryFrontCache).__VF_CACHE_NAMESPACE__ ||\n getEnvironmentVariable(\"VF_CACHE_NAMESPACE\");\n\nexport function setCacheNamespace(namespace?: string): void {\n cacheNamespace = namespace || undefined;\n try {\n (globalThis as GlobalWithVeryFrontCache).__VF_CACHE_NAMESPACE__ = cacheNamespace;\n } catch (e) {\n logger.debug(\"[cache] setCacheNamespace failed\", e);\n }\n}\n\nexport function getCacheNamespace(): string | undefined {\n return cacheNamespace;\n}\n", "export { loadImportMap } from \"./loader.ts\";\nexport { getDefaultImportMap } from \"./default-import-map.ts\";\nexport { resolveImport } from \"./resolver.ts\";\nexport { transformImportsWithMap } from \"./transformer.ts\";\nexport { mergeImportMaps } from \"./merger.ts\";\n\nexport type { ImportMapConfig, TransformOptions } from \"./types.ts\";\n", "import { rendererLogger as logger } from \"@veryfront/utils\";\nimport { dirname, join } from \"std/path/mod.ts\";\nimport type { RuntimeAdapter } from \"@veryfront/platform/adapters/base.ts\";\nimport { getConfig } from \"@veryfront/config\";\nimport type { ImportMapConfig } from \"./types.ts\";\nimport { getDefaultImportMap } from \"./default-import-map.ts\";\n\nexport async function loadImportMap(\n startPath: string,\n adapter?: RuntimeAdapter,\n): Promise<ImportMapConfig> {\n let runtimeAdapter = adapter;\n if (!runtimeAdapter) {\n const { getAdapter } = await import(\"@veryfront/platform/adapters/detect.ts\");\n runtimeAdapter = await getAdapter();\n }\n\n try {\n const cfg = await getConfig(startPath, runtimeAdapter!);\n if (cfg?.resolve?.importMap && typeof cfg.resolve.importMap === \"object\") {\n return {\n imports: cfg.resolve.importMap.imports ?? {},\n scopes: cfg.resolve.importMap.scopes ?? {},\n };\n }\n } catch {\n // Config not found or invalid, fall through to file-based discovery\n }\n\n let currentPath = startPath;\n\n while (currentPath !== \"/\" && currentPath !== \"\") {\n const denoJsonPath = join(currentPath, \"deno.json\");\n\n try {\n const content = await runtimeAdapter!.fs.readFile(denoJsonPath);\n const config = JSON.parse(content);\n\n if (config.imports || config.scopes) {\n logger.debug(`Loaded import map from ${denoJsonPath}`);\n return {\n imports: config.imports ?? {},\n scopes: config.scopes ?? {},\n };\n }\n } catch {\n // deno.json not found in this directory, continue searching\n }\n\n const parent = dirname(currentPath);\n if (parent === currentPath) break; // Reached root\n currentPath = parent;\n }\n\n return getDefaultImportMap();\n}\n", "import { getReactImportMap, REACT_DEFAULT_VERSION } from \"@veryfront/utils\";\nimport type { ImportMapConfig } from \"./types.ts\";\n\nexport function getDefaultImportMap(): ImportMapConfig {\n const reactVersion = REACT_DEFAULT_VERSION;\n\n const importMap = getReactImportMap(reactVersion);\n importMap[\"react/\"] = `https://esm.sh/react@${reactVersion}/`;\n\n return { imports: importMap };\n}\n", "import type { ImportMapConfig } from \"./types.ts\";\n\nexport function resolveImport(\n specifier: string,\n importMap: ImportMapConfig,\n scope?: string,\n): string {\n if (scope && importMap.scopes?.[scope]?.[specifier]) {\n return importMap.scopes[scope][specifier];\n }\n\n if (importMap.imports?.[specifier]) {\n return importMap.imports[specifier];\n }\n\n if (\n specifier.endsWith(\".js\") || specifier.endsWith(\".mjs\") ||\n specifier.endsWith(\".cjs\")\n ) {\n const base = specifier.replace(/\\.(m|c)?js$/, \"\");\n if (importMap.imports?.[base]) {\n return importMap.imports[base];\n }\n }\n\n if (importMap.imports) {\n for (const [key, value] of Object.entries(importMap.imports)) {\n if (key.endsWith(\"/\") && specifier.startsWith(key)) {\n return value + specifier.slice(key.length);\n }\n }\n }\n\n return specifier;\n}\n", "import type { ImportMapConfig, TransformOptions } from \"./types.ts\";\nimport { resolveImport } from \"./resolver.ts\";\n\nexport function transformImportsWithMap(\n code: string,\n importMap: ImportMapConfig,\n scope?: string,\n options?: TransformOptions,\n): string {\n let transformedCode = code;\n\n transformedCode = transformedCode.replace(\n /((?:import|export)\\s+(?:[\\w,{}\\s*]+\\s+from\\s+)?|export\\s+(?:\\*|\\{[^}]+\\})\\s+from\\s+)[\"']([^\"']+)[\"']/g,\n (_match, prefix, specifier) => {\n const isBare = !specifier.startsWith(\"http\") &&\n !specifier.startsWith(\"/\") &&\n !specifier.startsWith(\".\");\n if (isBare && !options?.resolveBare) {\n return `${prefix}\"${specifier}\"`;\n }\n const resolved = resolveImport(specifier, importMap, scope);\n return `${prefix}\"${resolved}\"`;\n },\n );\n\n transformedCode = transformedCode.replace(\n /from\\s+[\"']([^\"']+)[\"']/g,\n (match, specifier) => {\n const isBare = !specifier.startsWith(\"http\") &&\n !specifier.startsWith(\"/\") &&\n !specifier.startsWith(\".\");\n if (isBare && !options?.resolveBare) {\n return match;\n }\n const resolved = resolveImport(specifier, importMap, scope);\n return `from \"${resolved}\"`;\n },\n );\n\n transformedCode = transformedCode.replace(\n /import\\s*\\(\\s*[\"']([^\"']+)[\"']\\s*\\)/g,\n (_match, specifier) => {\n const resolved = resolveImport(specifier, importMap, scope);\n return `import(\"${resolved}\")`;\n },\n );\n\n return transformedCode;\n}\n", "import type { ImportMapConfig } from \"./types.ts\";\n\nexport function mergeImportMaps(...maps: ImportMapConfig[]): ImportMapConfig {\n const merged: ImportMapConfig = {\n imports: {},\n scopes: {},\n };\n\n for (const map of maps) {\n if (map.imports) {\n Object.assign(merged.imports!, map.imports);\n }\n\n if (map.scopes) {\n for (const [scope, imports] of Object.entries(map.scopes)) {\n if (!merged.scopes![scope]) {\n merged.scopes![scope] = {};\n }\n Object.assign(merged.scopes![scope], imports);\n }\n }\n }\n\n return merged;\n}\n", "import { rendererLogger as logger } from \"@veryfront/utils\";\nimport type { MDXExports, MDXImportInfo, ParsedMDX } from \"./types.ts\";\nimport { extractFrontmatter, extractMetadata } from \"./module-loader/metadata-extractor.ts\";\n\nexport type { ParsedMDX };\n\nexport function parseMDXCode(compiledCode: string): ParsedMDX {\n logger.debug(\"Parsing MDX code, first 200 chars:\", compiledCode.substring(0, 200));\n const importRegex = /^\\s*import\\s+(?:{([^}]+)}|(\\w+))\\s+from\\s+['\"]([^'\"]+)['\"]\\s*;?\\s*$/gm;\n const imports = new Map<string, MDXImportInfo>();\n let match: RegExpExecArray | null;\n\n while ((match = importRegex.exec(compiledCode)) !== null) {\n if (match[1]) {\n const names = match[1].split(\",\").map((n: string) => n.trim());\n names.forEach((name: string) => {\n if (match?.[3]) {\n imports.set(name, { name, path: match[3], isDefault: false });\n }\n });\n } else if (match[2]) {\n if (match[2] && match[3]) {\n imports.set(match[2], {\n name: match[2],\n path: match[3],\n isDefault: true,\n });\n }\n }\n }\n\n const cleanedCode = compiledCode\n .replace(importRegex, \"\") // Remove top-level imports\n .replace(/^\\s*export\\s+\\{[\\s\\S]*?\\};?\\s*$/gm, \"\") // Remove named exports (including multi-line)\n .replace(/^\\s*export\\s+default\\s+function/gm, \"function\") // Convert default export function\n .replace(/^\\s*export\\s+default\\s+/gm, \"\") // Remove other default exports\n .replace(/^\\s*export\\s+const\\s+/gm, \"const \") // Convert export const to const\n .replace(/^\\s*export\\s+function\\s+/gm, \"function \") // Convert export function to function\n .replace(/^\\s*const\\s+React\\s*=.*?;?\\s*$/gm, \"\") // Remove React declarations\n .replace(/^\\s*import\\s+React\\s+from.*?;?\\s*$/gm, \"\") // Remove React imports\n .replace(/^\\s*const\\s+(Fragment|Fragment2)\\s*=.*?;?\\s*$/gm, \"\") // Remove Fragment declarations\n .replace(/^\\s*const\\s+(jsx|jsx2)\\s*=.*?;?\\s*$/gm, \"\") // Remove jsx declarations\n .replace(/^\\s*const\\s+(jsxs|jsxs2)\\s*=.*?;?\\s*$/gm, \"\"); // Remove jsxs declarations\n\n if (cleanedCode.includes(\"import React\")) {\n logger.warn(\"Import React still in cleaned code\");\n }\n if (cleanedCode.includes(\"const React\") || cleanedCode.includes(\"var React\")) {\n logger.warn(\"React declaration found in cleaned code\");\n logger.debug(\"Code snippet:\", cleanedCode.substring(0, 200));\n }\n\n const exports: MDXExports = {};\n\n const frontmatter = extractFrontmatter(cleanedCode);\n if (frontmatter) {\n exports.frontmatter = frontmatter;\n }\n\n const metadata = extractMetadata(cleanedCode);\n for (const [key, value] of Object.entries(metadata)) {\n if (value !== undefined) {\n (exports as Record<string, unknown>)[key] = value;\n }\n }\n\n return { code: cleanedCode, imports, exports };\n}\n", "import { rendererLogger as logger } from \"@veryfront/utils\";\nimport type { FrontmatterMetadata, LogContext, MDXModule } from \"./types.ts\";\nimport { extractBalancedBlock, parseJsonish } from \"./string-parser.ts\";\n\nexport function extractFrontmatter(moduleCode: string): FrontmatterMetadata | undefined {\n try {\n const fmIndex = moduleCode.search(/(?:export\\s+)?const\\s+frontmatter\\s*=\\s*/);\n if (fmIndex < 0) return undefined;\n\n const braceStart = moduleCode.indexOf(\"{\", fmIndex);\n if (braceStart < 0) return undefined;\n\n const raw = extractBalancedBlock(moduleCode, braceStart, \"{\", \"}\");\n if (!raw) return undefined;\n\n const jsonish = raw\n .replace(/([^\\s\"{[:,]+)\\s*:/g, '\"$1\":')\n .replace(/'([^']*)'/g, '\"$1\"');\n\n try {\n return JSON.parse(jsonish) as FrontmatterMetadata;\n } catch (e) {\n logger.debug(\"[mdx] frontmatter JSON parse failed\", e as LogContext);\n return undefined;\n }\n } catch (e) {\n logger.debug(\"[mdx] frontmatter extraction failed\", e as LogContext);\n return undefined;\n }\n}\n\ninterface MetadataPattern {\n regex: RegExp;\n key: string;\n}\n\nconst METADATA_PATTERNS: MetadataPattern[] = [\n { regex: /(?:export\\s+)?const\\s+title\\s*=\\s*[\"']([^\"']+)[\"']/, key: \"title\" },\n { regex: /(?:export\\s+)?const\\s+description\\s*=\\s*[\"']([^\"']+)[\"']/, key: \"description\" },\n { regex: /(?:export\\s+)?const\\s+layout\\s*=\\s*(true|false|[\"'][^\"']+[\"'])/, key: \"layout\" },\n { regex: /(?:export\\s+)?const\\s+headings\\s*=\\s*(\\[[\\s\\S]*?\\])/, key: \"headings\" },\n { regex: /(?:export\\s+)?const\\s+nested\\s*=\\s*({[\\s\\S]*?})/, key: \"nested\" },\n { regex: /(?:export\\s+)?const\\s+tags\\s*=\\s*(\\[[\\s\\S]*?\\])/, key: \"tags\" },\n { regex: /(?:export\\s+)?const\\s+date\\s*=\\s*[\"']([^\"']+)[\"']/, key: \"date\" },\n { regex: /(?:export\\s+)?const\\s+draft\\s*=\\s*(true|false)/, key: \"draft\" },\n];\n\nexport function extractMetadata(moduleCode: string): Partial<MDXModule> {\n const exports: Partial<MDXModule> = {};\n\n METADATA_PATTERNS.forEach(({ regex, key }) => {\n const match = moduleCode.match(regex);\n if (!match) return;\n\n const value = match[1] as string;\n\n switch (key) {\n case \"title\":\n case \"description\":\n case \"date\":\n exports[key] = value;\n break;\n\n case \"layout\":\n exports[key] = value === \"true\"\n ? true\n : value === \"false\"\n ? false\n : String(value).replace(/^\"|\"$/g, \"\");\n break;\n\n case \"headings\":\n case \"tags\":\n case \"nested\":\n try {\n exports[key] = parseJsonish(value) as never;\n } catch (e) {\n logger.warn(`Failed to parse ${key}`, e);\n }\n break;\n\n case \"draft\":\n exports[key] = value === \"true\";\n break;\n }\n });\n\n return exports;\n}\n\nexport function mergeFrontmatter(result: MDXModule): void {\n result.frontmatter = result.frontmatter || {};\n\n const keys = [\"title\", \"description\", \"layout\", \"headings\", \"tags\", \"date\", \"draft\", \"nested\"];\n for (const key of keys) {\n if (result[key] !== undefined && result.frontmatter[key] === undefined) {\n result.frontmatter[key] = result[key];\n }\n }\n}\n", "export function extractBalancedBlock(\n source: string,\n startIndex: number,\n open: \"{\" | \"[\" | \"(\",\n close?: \"}\" | \"]\" | \")\",\n): string {\n const closeCh = close || (open === \"{\" ? \"}\" : open === \"[\" ? \"]\" : \")\");\n let depth = 0;\n let i = startIndex;\n\n while (i < source.length) {\n const ch = source[i] as string;\n\n if (ch === '\"' || ch === \"'\") {\n const quote = ch;\n i++;\n while (i < source.length) {\n const q = source[i] as string;\n if (q === \"\\\\\") {\n i += 2;\n continue;\n }\n if (q === quote) {\n i++;\n break;\n }\n i++;\n }\n continue;\n }\n\n if (ch === open) depth++;\n if (ch === closeCh) {\n depth--;\n if (depth === 0) {\n return source.slice(startIndex, i + 1);\n }\n }\n i++;\n }\n\n return \"\";\n}\n\nexport function cleanModuleCode(moduleCode: string): string {\n return moduleCode\n .replace(/import\\s+.*?from\\s+['\"][^'\"]+['\"];?\\s*/gm, \"\")\n .replace(/export\\s+\\{[\\s\\S]*?\\};?$/gm, \"\")\n .replace(/export\\s+default\\s+/gm, \"\")\n .replace(/export\\s+const\\s+/gm, \"const \")\n .replace(/export\\s+function\\s+/gm, \"function \");\n}\n\nexport function parseJsonish(value: string): unknown {\n const jsonish = value\n .replace(/'([^']*)'/g, '\"$1\"')\n .replace(/([{,]\\s*)([A-Za-z_$][\\w$]*)\\s*:/g, '$1\"$2\":');\n return JSON.parse(jsonish);\n}\n", "import { rendererLogger as logger } from \"@veryfront/utils\";\nimport { wrapError as _wrapError } from \"@veryfront/errors\";\nimport {\n type BundleCode,\n type BundleMetadata,\n computeCodeHash,\n computeContentHash,\n getBundleManifestStore,\n getBundleManifestTTL,\n} from \"@veryfront/utils\";\nimport type { VeryfrontConfig } from \"@veryfront/config\";\nimport type { MdxBundle } from \"@veryfront/types\";\n\nexport interface MDXCompilationResult extends MdxBundle {\n headings?: Array<{ id: string; text: string; level: number }>;\n nodeMap?: Map<number, unknown>;\n}\n\nexport interface MDXCacheAdapterOptions {\n config: VeryfrontConfig;\n mode: \"development\" | \"production\";\n}\n\nexport class MDXCacheAdapter {\n private config: VeryfrontConfig;\n private mode: \"development\" | \"production\";\n private manifestStore = getBundleManifestStore();\n\n constructor(options: MDXCacheAdapterOptions) {\n this.config = options.config;\n this.mode = options.mode;\n }\n\n private getCacheKey(contentHash: string): string {\n return `mdx:${this.mode}:${contentHash}`;\n }\n\n private getTTL(): number | undefined {\n return getBundleManifestTTL(this.config, this.mode);\n }\n\n async computeHash(content: string): Promise<string> {\n return await computeContentHash(content);\n }\n\n async getCachedBundle(\n content: string,\n frontmatter?: Record<string, unknown>,\n filePath?: string,\n ): Promise<MDXCompilationResult | undefined> {\n try {\n const contentHash = await this.computeHash(content);\n const cacheKey = this.getCacheKey(contentHash);\n\n const metadata = await this.manifestStore.getBundleMetadata(cacheKey);\n if (!metadata) {\n return undefined;\n }\n\n const bundleCode = await this.manifestStore.getBundleCode(metadata.codeHash);\n if (!bundleCode) {\n logger.debug(\"[mdx-cache] Metadata found but code missing\", {\n filePath,\n codeHash: metadata.codeHash,\n });\n return undefined;\n }\n\n logger.debug(\"[mdx-cache] Cache hit for MDX compilation\", {\n filePath,\n codeHash: metadata.codeHash,\n size: metadata.size,\n });\n\n return {\n compiledCode: bundleCode.code,\n frontmatter: (frontmatter || {}) as Record<string, string | number | boolean | string[]>,\n headings: [],\n nodeMap: new Map(),\n };\n } catch (error) {\n logger.debug(\"[mdx-cache] Failed to retrieve cached bundle\", {\n error,\n filePath,\n });\n return undefined;\n }\n }\n\n async setCachedBundle(\n content: string,\n bundle: MDXCompilationResult,\n filePath?: string,\n ): Promise<void> {\n if (!bundle.compiledCode) {\n logger.debug(\"[mdx-cache] No compiled code to cache\", { filePath });\n return;\n }\n\n try {\n const contentHash = await this.computeHash(content);\n const cacheKey = this.getCacheKey(contentHash);\n\n const bundleCode: BundleCode = {\n code: bundle.compiledCode,\n };\n\n const codeHash = await computeCodeHash(bundleCode);\n\n const encoder = new TextEncoder();\n const size = encoder.encode(bundle.compiledCode).length;\n\n const metadata: BundleMetadata = {\n hash: contentHash,\n codeHash,\n size,\n compiledAt: Date.now(),\n source: filePath || \"unknown\",\n mode: this.mode,\n meta: {\n type: \"mdx\",\n reactVersion: (await import(\"react\")).version,\n },\n };\n\n const ttl = this.getTTL();\n\n await this.manifestStore.setBundleCode(codeHash, bundleCode, ttl);\n await this.manifestStore.setBundleMetadata(cacheKey, metadata, ttl);\n\n logger.debug(\"[mdx-cache] Cached compiled MDX\", {\n filePath,\n cacheKey,\n codeHash,\n size,\n ttl,\n });\n } catch (error) {\n logger.debug(\"[mdx-cache] Failed to cache bundle\", {\n error,\n filePath,\n });\n }\n }\n\n async invalidateBundle(content: string): Promise<void> {\n try {\n const contentHash = await this.computeHash(content);\n const cacheKey = this.getCacheKey(contentHash);\n await this.manifestStore.deleteBundle(cacheKey);\n logger.debug(\"[mdx-cache] Invalidated cached bundle\", { cacheKey });\n } catch (error) {\n logger.debug(\"[mdx-cache] Failed to invalidate bundle\", { error });\n }\n }\n\n async invalidateSource(source: string): Promise<number> {\n try {\n const count = await this.manifestStore.invalidateSource(source);\n logger.debug(\"[mdx-cache] Invalidated bundles for source\", {\n source,\n count,\n });\n return count;\n } catch (error) {\n logger.debug(\"[mdx-cache] Failed to invalidate source\", {\n error,\n source,\n });\n return 0;\n }\n }\n\n async clearAll(): Promise<void> {\n try {\n await this.manifestStore.clear();\n logger.debug(\"[mdx-cache] Cleared all cached bundles\");\n } catch (error) {\n logger.debug(\"[mdx-cache] Failed to clear cache\", { error });\n }\n }\n\n async getStats(): Promise<{\n totalBundles: number;\n totalSize: number;\n oldestBundle?: number;\n newestBundle?: number;\n }> {\n try {\n return await this.manifestStore.getStats();\n } catch (error) {\n logger.debug(\"[mdx-cache] Failed to get stats\", { error });\n return {\n totalBundles: 0,\n totalSize: 0,\n };\n }\n }\n}\n", "import type * as React from \"react\";\nimport { useMemo, useRef } from \"react\";\nimport { mdxRenderer } from \"@veryfront/transforms/mdx/index.ts\";\nimport type { MDXComponents } from \"@veryfront/types\";\nimport type { MdxBundle } from \"./LayoutComponent.tsx\";\nimport { rendererLogger as logger } from \"@veryfront/utils\";\n\nexport interface ProviderComponentProps {\n mdxBundle: MdxBundle;\n children: React.ReactNode;\n components?: MDXComponents;\n}\n\nfunction useStableFrontmatter(frontmatter: MdxBundle[\"frontmatter\"]): MdxBundle[\"frontmatter\"] {\n const ref = useRef(frontmatter);\n const serialized = JSON.stringify(frontmatter);\n const prevSerialized = useRef(serialized);\n\n if (prevSerialized.current !== serialized) {\n ref.current = frontmatter;\n prevSerialized.current = serialized;\n }\n\n return ref.current;\n}\n\nexport function ProviderComponent({\n mdxBundle,\n children,\n components = {},\n}: ProviderComponentProps) {\n const stableFrontmatter = useStableFrontmatter(mdxBundle.frontmatter);\n\n const element = useMemo(() => {\n try {\n return mdxRenderer.render(mdxBundle.compiledCode, {\n components,\n frontmatter: stableFrontmatter,\n globals: mdxBundle.globals,\n extractLayout: true,\n children,\n });\n } catch (error) {\n logger.error(\"[ProviderComponent] Render failed:\", error);\n return <>{children}</>;\n }\n }, [mdxBundle.compiledCode, stableFrontmatter, components, children, mdxBundle.globals]);\n\n if (!element) return <>{children}</>;\n return element as React.ReactElement;\n}\n", "import React from \"react\";\n\nexport function Head({ children }: { children: React.ReactNode }) {\n return React.createElement(\n \"div\",\n {\n \"data-veryfront-head\": \"1\",\n style: { display: \"none\" },\n },\n children,\n );\n}\n", "import React from \"react\";\n\nexport type LinkProps = React.AnchorHTMLAttributes<HTMLAnchorElement> & {\n prefetch?: boolean;\n};\n\nexport function Link({ prefetch = true, children, ...rest }: LinkProps) {\n const props: React.AnchorHTMLAttributes<HTMLAnchorElement> = {\n ...rest,\n ...(prefetch ? { \"data-prefetch\": \"true\" } : {}),\n };\n return <a {...props}>{children}</a>;\n}\n", "import type React from \"react\";\nimport { createContext, useContext } from \"react\";\nimport type { MDXComponents } from \"@veryfront/types\";\n\nconst MDXContext = createContext<MDXComponents>({});\n\nexport interface MDXProviderProps {\n components?: MDXComponents;\n children: React.ReactNode;\n}\n\nexport function MDXProvider({\n components = {},\n children,\n}: MDXProviderProps) {\n return <MDXContext.Provider value={components}>{children}</MDXContext.Provider>;\n}\n\nexport function useMDXComponents(components?: MDXComponents): MDXComponents {\n const contextComponents = useContext(MDXContext);\n return { ...contextComponents, ...components };\n}\n", "export { OptimizedImage } from \"./OptimizedImage.tsx\";\nexport type { OptimizedImageProps } from \"./OptimizedImage.tsx\";\nexport { SimpleOptimizedImage } from \"./SimpleOptimizedImage.tsx\";\nexport { OptimizedBackgroundImage } from \"./OptimizedBackgroundImage.tsx\";\nexport { useOptimizedImage } from \"./useOptimizedImage.ts\";\nexport { generateBlurDataURL, getAspectRatioPadding, ResponsiveImageContainer } from \"./utils.tsx\";\n", "import React from \"react\";\nimport { RESPONSIVE_IMAGE_WIDTH_LG, RESPONSIVE_IMAGE_WIDTHS } from \"@veryfront/utils\";\nimport { generateSrcSet, getExtension, getOptimizedPath } from \"./helpers.ts\";\n\nexport interface OptimizedImageProps {\n src: string;\n alt: string;\n width?: number;\n height?: number;\n sizes?: string;\n formats?: (\"avif\" | \"webp\" | \"jpeg\" | \"png\")[];\n quality?: number;\n loading?: \"lazy\" | \"eager\";\n priority?: boolean;\n className?: string;\n style?: React.CSSProperties;\n placeholder?: \"blur\" | \"empty\";\n blurDataURL?: string;\n onClick?: (event: React.MouseEvent<HTMLImageElement>) => void;\n onLoad?: (event: React.SyntheticEvent<HTMLImageElement>) => void;\n onError?: (event: React.SyntheticEvent<HTMLImageElement>) => void;\n}\n\nconst DEFAULT_SIZES = [...RESPONSIVE_IMAGE_WIDTHS];\nconst DEFAULT_FORMATS: (\"avif\" | \"webp\" | \"jpeg\")[] = [\"avif\", \"webp\", \"jpeg\"];\n\nexport function OptimizedImage({\n src,\n alt,\n width,\n height,\n sizes = \"100vw\",\n formats = DEFAULT_FORMATS,\n quality = 80,\n loading,\n priority = false,\n className,\n style,\n placeholder = \"empty\",\n blurDataURL,\n onClick,\n onLoad,\n onError,\n}: OptimizedImageProps) {\n const loadingStrategy = priority ? \"eager\" : loading || \"lazy\";\n\n const originalFormat = getExtension(src);\n\n const imgStyle: React.CSSProperties = {\n ...style,\n ...(placeholder === \"blur\" && blurDataURL\n ? { backgroundImage: `url(${blurDataURL})`, backgroundSize: \"cover\" }\n : {}),\n };\n\n return (\n <picture>\n {formats.map((format) => (\n <source\n key={format}\n type={`image/${format}`}\n srcSet={generateSrcSet(src, format, DEFAULT_SIZES, quality)}\n sizes={sizes}\n />\n ))}\n\n <img\n src={getOptimizedPath(src, originalFormat, width || RESPONSIVE_IMAGE_WIDTH_LG, quality)}\n alt={alt}\n width={width}\n height={height}\n loading={loadingStrategy}\n decoding=\"async\"\n className={className}\n style={imgStyle}\n onClick={onClick}\n onLoad={onLoad}\n onError={onError}\n />\n </picture>\n );\n}\n", "export function getOptimizedPath(\n src: string,\n format: string,\n size: number,\n _quality: number = 80,\n): string {\n const basePath = src.replace(/\\.[^.]+$/, \"\");\n const optimizedDir = \".veryfront/optimized-images\";\n\n return `/${optimizedDir}${basePath}-${size}w.${format}`;\n}\n\nexport function generateSrcSet(\n src: string,\n format: string,\n sizes: number[],\n quality: number,\n): string {\n return sizes\n .map((size) => {\n const path = getOptimizedPath(src, format, size, quality);\n return `${path} ${size}w`;\n })\n .join(\", \");\n}\n\nexport function getExtension(src: string): string {\n const match = src.match(/\\.([^.]+)$/);\n const extension = match?.[1];\n return extension ? extension.toLowerCase() : \"jpeg\";\n}\n", "import React from \"react\";\nimport type { OptimizedImageProps } from \"./OptimizedImage.tsx\";\nimport { RESPONSIVE_IMAGE_WIDTH_LG, RESPONSIVE_IMAGE_WIDTHS } from \"@veryfront/utils\";\nimport { generateSrcSet, getOptimizedPath } from \"./helpers.ts\";\n\nconst DEFAULT_SIZES = [...RESPONSIVE_IMAGE_WIDTHS];\n\nexport function SimpleOptimizedImage({\n src,\n alt,\n width,\n height,\n format = \"webp\",\n quality = 80,\n loading = \"lazy\",\n className,\n style,\n onClick,\n onLoad,\n onError,\n}: Omit<OptimizedImageProps, \"formats\" | \"sizes\" | \"priority\" | \"placeholder\" | \"blurDataURL\"> & {\n format?: \"webp\" | \"avif\" | \"jpeg\" | \"png\";\n}) {\n const srcSet = generateSrcSet(src, format, DEFAULT_SIZES, quality);\n\n return (\n <img\n src={getOptimizedPath(src, format, width || RESPONSIVE_IMAGE_WIDTH_LG, quality)}\n srcSet={srcSet}\n alt={alt}\n width={width}\n height={height}\n loading={loading}\n decoding=\"async\"\n className={className}\n style={style as React.CSSProperties}\n onClick={onClick}\n onLoad={onLoad}\n onError={onError}\n />\n );\n}\n", "import React from \"react\";\nimport { RESPONSIVE_IMAGE_WIDTH_LG } from \"@veryfront/utils/constants/network.ts\";\nimport { getOptimizedPath } from \"./helpers.ts\";\n\nexport function OptimizedBackgroundImage({\n src,\n children,\n format = \"webp\",\n quality = 80,\n size = RESPONSIVE_IMAGE_WIDTH_LG,\n className,\n style,\n}: {\n src: string;\n children?: React.ReactNode;\n format?: \"webp\" | \"avif\" | \"jpeg\" | \"png\";\n quality?: number;\n size?: number;\n className?: string;\n style?: React.CSSProperties;\n}) {\n const optimizedSrc = getOptimizedPath(src, format, size, quality);\n\n const bgStyle: React.CSSProperties = {\n backgroundImage: `url(${optimizedSrc})`,\n backgroundSize: \"cover\",\n backgroundPosition: \"center\",\n backgroundRepeat: \"no-repeat\",\n ...style,\n };\n\n return (\n <div className={className} style={bgStyle}>\n {children}\n </div>\n );\n}\n", "import { RESPONSIVE_IMAGE_WIDTH_LG, RESPONSIVE_IMAGE_WIDTHS } from \"@veryfront/utils\";\nimport { generateSrcSet, getExtension, getOptimizedPath } from \"./helpers.ts\";\n\nconst DEFAULT_SIZES = [...RESPONSIVE_IMAGE_WIDTHS];\nconst DEFAULT_FORMATS: (\"avif\" | \"webp\" | \"jpeg\")[] = [\"avif\", \"webp\", \"jpeg\"];\n\nexport function useOptimizedImage(\n src: string,\n options: {\n formats?: (\"avif\" | \"webp\" | \"jpeg\" | \"png\")[];\n quality?: number;\n } = {},\n) {\n const formats = options.formats || DEFAULT_FORMATS;\n const quality = options.quality || 80;\n\n const sources = formats.map((format) => ({\n format,\n srcSet: generateSrcSet(src, format, DEFAULT_SIZES, quality),\n type: `image/${format}`,\n }));\n\n const fallback = getOptimizedPath(\n src,\n getExtension(src),\n RESPONSIVE_IMAGE_WIDTH_LG,\n quality,\n );\n\n return {\n sources,\n fallback,\n };\n}\n", "import React from \"react\";\n\nexport function generateBlurDataURL(\n width: number = 10,\n height: number = 10,\n color: string = \"#cccccc\",\n): string {\n const svg = `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 ${width} ${height}\">\n <rect width=\"${width}\" height=\"${height}\" fill=\"${color}\"/>\n </svg>\n `;\n\n return `data:image/svg+xml;base64,${btoa(svg)}`;\n}\n\nexport function getAspectRatioPadding(width: number, height: number): string {\n return `${(height / width) * 100}%`;\n}\n\nexport function ResponsiveImageContainer({\n width,\n height,\n children,\n className,\n style,\n}: {\n width: number;\n height: number;\n children: React.ReactNode;\n className?: string;\n style?: React.CSSProperties;\n}) {\n const containerStyle = {\n position: \"relative\" as const,\n width: \"100%\",\n paddingBottom: getAspectRatioPadding(width, height),\n ...style,\n };\n\n const contentStyle = {\n position: \"absolute\",\n top: 0,\n left: 0,\n width: \"100%\",\n height: \"100%\",\n } as const;\n\n return (\n <div className={className} style={containerStyle}>\n <div style={contentStyle}>{children}</div>\n </div>\n );\n}\n", "export type {\n CacheEntry,\n DataContext,\n DataResult,\n InferGetServerDataProps,\n PageWithData,\n StaticPathsResult,\n} from \"./types.ts\";\n\nexport { DataFetcher } from \"./data-fetcher.ts\";\nexport { notFound, redirect } from \"./helpers.ts\";\n", "import type { RuntimeAdapter } from \"@veryfront/platform/adapters/index.ts\";\nimport { CacheManager } from \"./data-fetching-cache.ts\";\nimport { ServerDataFetcher } from \"./server-data-fetcher.ts\";\nimport { StaticDataFetcher } from \"./static-data-fetcher.ts\";\nimport { StaticPathsFetcher } from \"./static-paths-fetcher.ts\";\nimport type { DataContext, DataResult, PageWithData, StaticPathsResult } from \"./types.ts\";\n\nexport class DataFetcher {\n private cacheManager: CacheManager;\n private serverFetcher: ServerDataFetcher;\n private staticFetcher: StaticDataFetcher;\n private pathsFetcher: StaticPathsFetcher;\n\n constructor(adapter?: RuntimeAdapter) {\n this.cacheManager = new CacheManager();\n this.serverFetcher = new ServerDataFetcher(adapter);\n this.staticFetcher = new StaticDataFetcher(this.cacheManager, adapter);\n this.pathsFetcher = new StaticPathsFetcher();\n }\n\n async fetchData(\n pageModule: PageWithData,\n context: DataContext,\n mode: \"development\" | \"production\" = \"development\",\n ): Promise<DataResult> {\n if (!pageModule.getServerData && !pageModule.getStaticData) {\n return { props: {} };\n }\n\n if (mode === \"development\" && pageModule.getServerData) {\n return await this.serverFetcher.fetch(pageModule, context);\n }\n\n if (pageModule.getStaticData) {\n return await this.staticFetcher.fetch(pageModule, context);\n }\n\n if (pageModule.getServerData) {\n return await this.serverFetcher.fetch(pageModule, context);\n }\n\n return { props: {} };\n }\n\n async getStaticPaths(pageModule: PageWithData): Promise<StaticPathsResult | null> {\n return await this.pathsFetcher.fetch(pageModule);\n }\n\n clearCache(pattern?: string): void {\n if (pattern) {\n this.cacheManager.clearPattern(pattern);\n } else {\n this.cacheManager.clear();\n }\n }\n}\n", "import { LRUCache } from \"@veryfront/utils/lru-wrapper.ts\";\nimport {\n DATA_FETCHING_MAX_ENTRIES,\n DATA_FETCHING_TTL_MS,\n} from \"@veryfront/utils/constants/cache.ts\";\nimport type { CacheEntry, DataContext } from \"./types.ts\";\nimport { getEnv } from \"../platform/compat/process.ts\";\n\nfunction isLruIntervalDisabled(): boolean {\n if ((globalThis as Record<string, unknown>).__vfDisableLruInterval === true) {\n return true;\n }\n try {\n return getEnv(\"VF_DISABLE_LRU_INTERVAL\") === \"1\";\n } catch {\n return false;\n }\n}\n\nexport class CacheManager {\n private cache = new LRUCache<string, CacheEntry>({\n maxEntries: DATA_FETCHING_MAX_ENTRIES,\n ttlMs: isLruIntervalDisabled() ? undefined : DATA_FETCHING_TTL_MS,\n });\n private cacheKeys = new Set<string>();\n\n get(key: string): CacheEntry | null {\n const entry = this.cache.get(key);\n return entry ?? null;\n }\n\n set(key: string, entry: CacheEntry): void {\n this.cache.set(key, entry);\n this.cacheKeys.add(key);\n }\n\n delete(key: string): void {\n this.cache.delete(key);\n this.cacheKeys.delete(key);\n }\n\n clear(): void {\n this.cache.clear();\n this.cacheKeys.clear();\n }\n\n clearPattern(pattern: string): void {\n for (const key of this.cacheKeys) {\n if (key.includes(pattern)) {\n this.delete(key);\n }\n }\n }\n\n shouldRevalidate(entry: CacheEntry): boolean {\n if (entry.revalidate === false) {\n return false;\n }\n\n if (typeof entry.revalidate === \"number\") {\n const age = Date.now() - entry.timestamp;\n return age > entry.revalidate * 1000;\n }\n\n return false;\n }\n\n createCacheKey(context: DataContext): string {\n const params = JSON.stringify(context.params);\n const pathname = context.url.pathname;\n return `${pathname}::${params}`;\n }\n}\n", "import type { RuntimeAdapter } from \"@veryfront/platform/adapters/index.ts\";\nimport type { DataContext, DataResult, PageWithData } from \"./types.ts\";\nimport { serverLogger } from \"@veryfront/utils\";\n\nexport class ServerDataFetcher {\n constructor(private adapter?: RuntimeAdapter) {}\n\n async fetch(pageModule: PageWithData, context: DataContext): Promise<DataResult> {\n if (!pageModule.getServerData) {\n return { props: {} };\n }\n\n try {\n const result = await pageModule.getServerData(context);\n\n if (result.redirect) {\n return { redirect: result.redirect };\n }\n\n if (result.notFound) {\n return { notFound: true };\n }\n\n return {\n props: result.props ?? {},\n revalidate: result.revalidate,\n };\n } catch (error) {\n this.logError(\"Error in getServerData:\", error);\n throw error;\n }\n }\n\n private logError(message: string, error: unknown): void {\n const debugEnabled = this.adapter?.env.get(\"VERYFRONT_DEBUG\");\n if (debugEnabled) {\n serverLogger.error(message, error);\n }\n }\n}\n", "import type { RuntimeAdapter } from \"@veryfront/platform/adapters/index.ts\";\nimport type { CacheManager } from \"./data-fetching-cache.ts\";\nimport type { DataContext, DataResult, PageWithData } from \"./types.ts\";\nimport { serverLogger } from \"@veryfront/utils\";\n\nexport class StaticDataFetcher {\n private pendingRevalidations = new Map<string, Promise<void>>();\n\n constructor(\n private cacheManager: CacheManager,\n private adapter?: RuntimeAdapter,\n ) {}\n\n async fetch(pageModule: PageWithData, context: DataContext): Promise<DataResult> {\n if (!pageModule.getStaticData) {\n return { props: {} };\n }\n\n const cacheKey = this.cacheManager.createCacheKey(context);\n const cached = this.cacheManager.get(cacheKey);\n\n if (cached && !this.cacheManager.shouldRevalidate(cached)) {\n return cached.data;\n }\n\n if (cached && this.cacheManager.shouldRevalidate(cached)) {\n if (!this.pendingRevalidations.has(cacheKey)) {\n this.pendingRevalidations.set(\n cacheKey,\n this.revalidateInBackground(pageModule, context, cacheKey),\n );\n }\n return cached.data;\n }\n\n return await this.fetchFresh(pageModule, context, cacheKey);\n }\n\n private async fetchFresh(\n pageModule: PageWithData,\n context: DataContext,\n cacheKey: string,\n ): Promise<DataResult> {\n if (!pageModule.getStaticData) {\n return { props: {} };\n }\n\n try {\n const result = await pageModule.getStaticData({\n params: context.params,\n url: context.url,\n });\n\n this.cacheManager.set(cacheKey, {\n data: result,\n timestamp: Date.now(),\n revalidate: result.revalidate,\n });\n\n return result;\n } catch (error) {\n this.logError(\"Error in getStaticData:\", error);\n throw error;\n }\n }\n\n private async revalidateInBackground(\n pageModule: PageWithData,\n context: DataContext,\n cacheKey: string,\n ): Promise<void> {\n try {\n if (!pageModule.getStaticData) {\n return;\n }\n\n const result = await pageModule.getStaticData({\n params: context.params,\n url: context.url,\n });\n\n this.cacheManager.set(cacheKey, {\n data: result,\n timestamp: Date.now(),\n revalidate: result.revalidate,\n });\n } catch (error) {\n this.logError(\"Error revalidating data:\", error);\n } finally {\n this.pendingRevalidations.delete(cacheKey);\n }\n }\n\n private logError(message: string, error: unknown): void {\n const debugEnabled = this.adapter?.env.get(\"VERYFRONT_DEBUG\");\n if (debugEnabled) {\n serverLogger.error(message, error);\n }\n }\n}\n", "import type { PageWithData, StaticPathsResult } from \"./types.ts\";\nimport { serverLogger } from \"@veryfront/utils\";\n\nexport class StaticPathsFetcher {\n async fetch(pageModule: PageWithData): Promise<StaticPathsResult | null> {\n if (!pageModule.getStaticPaths) {\n return null;\n }\n\n try {\n return await pageModule.getStaticPaths();\n } catch (error) {\n this.logError(\"Error in getStaticPaths:\", error);\n throw error;\n }\n }\n\n private logError(message: string, error: unknown): void {\n serverLogger.error(message, error);\n }\n}\n", "import type { DataResult } from \"./types.ts\";\n\nexport const redirect = (destination: string, permanent = false): DataResult => ({\n redirect: { destination, permanent },\n});\n\nexport const notFound = (): DataResult => ({\n notFound: true,\n});\n", "export type { Route, RouteMatch } from \"./matchers/index.ts\";\nexport {\n DynamicRouter,\n getSpecificityScore,\n matchRoute,\n normalizePath,\n parseRoute,\n} from \"./matchers/index.ts\";\n\nexport type { PathCandidates, RouteParams } from \"./slug-mapper/index.ts\";\nexport {\n extractParams,\n getPathCandidates,\n getSlugFromPath,\n getSupportedExtensions,\n isDynamicRoute,\n matchesPattern,\n normalizeSlug,\n pathToSlug,\n slugToPath,\n} from \"./slug-mapper/index.ts\";\n\nexport type { RouteData } from \"./client/index.ts\";\nexport {\n extractPageDataFromScript,\n NavigationHandlers,\n PageLoader,\n PageTransition,\n ViewportPrefetch,\n} from \"./client/index.ts\";\n\nexport type { APIContext, APIHandler, APIResponse, APIRoute } from \"./api/index.ts\";\nexport {\n APIRouteHandler,\n applyCORSHeaders,\n badRequest,\n createContext,\n forbidden,\n handleCORSPreflight,\n json,\n normalizeParams,\n notFound,\n parseCookies,\n redirect,\n serverError,\n unauthorized,\n} from \"./api/index.ts\";\n", "export type { Route, RouteMatch } from \"./types.ts\";\n\nexport { DynamicRouter } from \"./pattern-route-matcher.ts\";\n\nexport { getSpecificityScore, parseRoute } from \"./route-parser.ts\";\nexport { matchRoute } from \"./route-matcher.ts\";\nexport { normalizePath } from \"@veryfront/utils\";\n", "import type { Route, RouteMatch } from \"./types.ts\";\nimport { getSpecificityScore, parseRoute } from \"./route-parser.ts\";\nimport { matchRoute } from \"./route-matcher.ts\";\nimport { normalizePath } from \"@veryfront/utils/path-utils.ts\";\n\nexport class DynamicRouter {\n private routes: Route[] = [];\n private cache = new Map<string, RouteMatch | null>();\n\n addRoute(pattern: string, page: string): void {\n const route = parseRoute(pattern, page);\n this.routes.push(route);\n this.routes.sort((a, b) => {\n const aScore = getSpecificityScore(a);\n const bScore = getSpecificityScore(b);\n return bScore - aScore;\n });\n }\n\n match(pathname: string): RouteMatch | null {\n if (this.cache.has(pathname)) {\n return this.cache.get(pathname)!;\n }\n\n pathname = normalizePath(pathname);\n\n for (const route of this.routes) {\n const match = matchRoute(pathname, route);\n if (match) {\n this.cache.set(pathname, match);\n return match;\n }\n }\n\n this.cache.set(pathname, null);\n return null;\n }\n\n clearCache(): void {\n this.cache.clear();\n }\n\n getRoutes(): Route[] {\n return [...this.routes];\n }\n}\n", "import type { Route } from \"./types.ts\";\n\nexport function parseRoute(pattern: string, page: string): Route {\n const orderedParamNames: string[] = [];\n let isCatchAll = false;\n let isOptionalCatchAll = false;\n\n for (const match of pattern.matchAll(/\\[\\[\\.\\.\\.(\\w+)\\]\\]|\\[\\.\\.\\.(\\w+)\\]|\\[(\\w+)\\]/g)) {\n if (match[1]) {\n const name = match[1];\n orderedParamNames.push(name);\n isOptionalCatchAll = true;\n isCatchAll = true;\n } else if (match[2]) {\n const name = match[2];\n orderedParamNames.push(name);\n isCatchAll = true;\n } else if (match[3]) {\n orderedParamNames.push(match[3]);\n }\n }\n\n let regexPattern = pattern;\n\n regexPattern = regexPattern.replace(/\\[\\[\\.\\.\\.(\\w+)\\]\\]/g, () => {\n return \"___OPTIONAL_CATCHALL___\";\n });\n\n regexPattern = regexPattern.replace(/\\[\\.\\.\\.(\\w+)\\]/g, () => {\n return \"___CATCHALL___\";\n });\n\n regexPattern = regexPattern.replace(/\\[(\\w+)\\]/g, () => {\n return \"___PARAM___\";\n });\n\n regexPattern = regexPattern.replace(/[-/\\\\^$*+?.()|[\\]{}]/g, \"\\\\$&\");\n\n regexPattern = regexPattern\n .replace(/___OPTIONAL_CATCHALL___/g, \"(.*)\")\n .replace(/___CATCHALL___/g, \"(.+)\")\n .replace(/___PARAM___/g, \"([^/]+)\");\n\n if (isOptionalCatchAll) {\n regexPattern = regexPattern.replace(/\\\\\\/\\(\\.\\*\\)$/, \"(?:\\\\/(.*))?\");\n }\n\n return {\n pattern,\n page,\n regex: new RegExp(`^${regexPattern}$`),\n paramNames: orderedParamNames,\n isCatchAll,\n isOptionalCatchAll,\n };\n}\n\nexport function getSpecificityScore(route: Route): number {\n let score = 0;\n const segments = route.pattern.split(\"/\").filter(Boolean);\n\n for (const segment of segments) {\n if (segment.includes(\"[[...\")) {\n score += 1; // Optional catch-all - lowest priority\n } else if (segment.includes(\"[...\")) {\n score += 2; // Catch-all\n } else if (segment.includes(\"[\")) {\n score += 3; // Dynamic segment\n } else {\n score += 4; // Static segment - highest priority\n }\n }\n\n score += segments.length * 0.1;\n\n return score;\n}\n", "import type { Route, RouteMatch } from \"./types.ts\";\n\nexport function matchRoute(pathname: string, route: Route): RouteMatch | null {\n const match = pathname.match(route.regex!);\n if (!match) return null;\n\n const params: Record<string, string | string[]> = {};\n\n const catchAllParamNames = new Set<string>();\n if (route.pattern) {\n route.pattern.replace(/\\[\\[\\.\\.\\.(\\w+)\\]\\]/g, (_, paramName: string) => {\n catchAllParamNames.add(paramName);\n return \"\";\n });\n route.pattern.replace(/\\[\\.\\.\\.(\\w+)\\]/g, (_, paramName: string) => {\n catchAllParamNames.add(paramName);\n return \"\";\n });\n }\n\n route.paramNames?.forEach((name, index) => {\n const value = match[index + 1];\n\n if (catchAllParamNames.has(name)) {\n const segments = value ? value.split(\"/\").filter((segment) => segment.length > 0) : [];\n params[name] = segments.map((segment) => decodeURIComponent(segment));\n } else {\n params[name] = decodeURIComponent(value || \"\");\n }\n });\n\n return { params, route };\n}\n", "export type { PathCandidates, RouteParams } from \"./types.ts\";\n\nexport { getPathCandidates, getSupportedExtensions } from \"./path-candidate-generator.ts\";\nexport { extractParams, isDynamicRoute, matchesPattern } from \"./dynamic-route-matcher.ts\";\nexport { getSlugFromPath, normalizeSlug, pathToSlug, slugToPath } from \"./slug-normalizer.ts\";\n", "import { join } from \"../../platform/compat/path-helper.ts\";\nimport type { PathCandidates } from \"./types.ts\";\n\nconst SUPPORTED_EXTENSIONS = [\".mdx\", \".tsx\", \".jsx\", \".ts\", \".js\"];\n\nexport function generateAppRouterCandidates(\n projectDir: string,\n normalizedSlug: string,\n): string[] {\n const candidates: string[] = [];\n\n if (normalizedSlug) {\n const base = join(projectDir, \"app\", normalizedSlug);\n\n for (const ext of SUPPORTED_EXTENSIONS) {\n candidates.push(`${base}/page${ext}`);\n }\n\n for (const ext of SUPPORTED_EXTENSIONS) {\n candidates.push(`${base}${ext}`);\n }\n } else {\n const appBase = join(projectDir, \"app\");\n for (const ext of SUPPORTED_EXTENSIONS) {\n candidates.push(`${appBase}/page${ext}`);\n }\n }\n\n return candidates;\n}\n\nexport function generatePagesRouterCandidates(\n projectDir: string,\n normalizedSlug: string,\n): string[] {\n const candidates: string[] = [];\n\n if (normalizedSlug === \"\" || normalizedSlug === \"index\") {\n for (const ext of SUPPORTED_EXTENSIONS) {\n candidates.push(join(projectDir, \"pages\", `index${ext}`));\n candidates.push(join(projectDir, `index${ext}`));\n }\n } else {\n for (const ext of SUPPORTED_EXTENSIONS) {\n candidates.push(join(projectDir, \"pages\", `${normalizedSlug}${ext}`));\n\n candidates.push(\n join(projectDir, \"pages\", normalizedSlug, `index${ext}`),\n );\n\n candidates.push(join(projectDir, `${normalizedSlug}${ext}`));\n }\n }\n\n return candidates;\n}\n\nexport function getPathCandidates(\n projectDir: string,\n slug: string,\n): PathCandidates {\n const normalizedSlug = slug || \"\";\n\n return {\n appRouter: generateAppRouterCandidates(projectDir, normalizedSlug),\n pagesRouter: generatePagesRouterCandidates(projectDir, normalizedSlug),\n };\n}\n\nexport function getSupportedExtensions(): string[] {\n return [...SUPPORTED_EXTENSIONS];\n}\n", "// Conditional imports for path module\nimport nodePath from \"node:path\";\nimport type { PlatformPath } from \"node:path\";\n\n// Use node:path for Node.js or import Deno's std/path for Deno\nlet pathMod: PlatformPath | null = null;\n\n// Initialize path module synchronously for Node.js\n// @ts-ignore - Deno global\nif (typeof Deno === \"undefined\") {\n pathMod = nodePath;\n} else {\n // Deno environment - start loading asynchronously but don't await\n // @ts-ignore - Deno global\n import(\"std/path/mod.ts\").then((mod) => {\n pathMod = mod as unknown as PlatformPath;\n });\n}\n\n// Helper to get path module, ensuring it's loaded\nfunction getPathMod(): PlatformPath {\n if (pathMod) return pathMod;\n // In Deno, if pathMod is not yet loaded, use Node.js path as temporary fallback\n // This should rarely happen as the import is fast\n return nodePath;\n}\n\n// Re-export common path functions with proper types\nexport const basename = (path: string, suffix?: string): string =>\n getPathMod().basename(path, suffix);\nexport const dirname = (path: string): string => getPathMod().dirname(path);\nexport const fromFileUrl = (url: string | URL): string => {\n const mod = getPathMod();\n // @ts-ignore - Deno path module has fromFileUrl\n if (mod && typeof (mod as any).fromFileUrl === \"function\") {\n // @ts-ignore - Deno path module has fromFileUrl\n return (mod as any).fromFileUrl(url);\n }\n // Fallback for Node.js where fromFileUrl might not be directly available\n // This uses URL parsing which is generally cross-platform\n const urlObj = typeof url === \"string\" ? new URL(url) : url;\n return urlObj.pathname;\n};\nexport const join = (...paths: string[]): string => getPathMod().join(...paths);\nexport const relative = (from: string, to: string): string => getPathMod().relative(from, to);\nexport const resolve = (...paths: string[]): string => getPathMod().resolve(...paths);\nexport const extname = (path: string): string => getPathMod().extname(path);\nexport const isAbsolute = (path: string): boolean => getPathMod().isAbsolute(path);\n// Export sep - uses getter function to ensure pathMod is resolved\nexport const sep: string = nodePath.sep;\n", "import type { RouteParams } from \"./types.ts\";\n\nexport function isDynamicRoute(pattern: string): boolean {\n return /\\[[\\w.]+\\]/.test(pattern);\n}\n\nexport function extractParams(\n pattern: string,\n slug: string,\n): RouteParams | null {\n const patternParts = pattern.split(\"/\").filter(Boolean);\n const slugParts = slug.split(\"/\").filter(Boolean);\n\n const params: RouteParams = {};\n\n let hasSpreadParam = false;\n for (const part of patternParts) {\n if (part.startsWith(\"[...\") && part.endsWith(\"]\")) {\n hasSpreadParam = true;\n break;\n }\n }\n\n if (!hasSpreadParam && patternParts.length !== slugParts.length) {\n return null;\n }\n\n let slugIndex = 0;\n\n for (let i = 0; i < patternParts.length; i++) {\n const patternPart = patternParts[i];\n if (!patternPart) continue;\n\n if (patternPart.startsWith(\"[...\") && patternPart.endsWith(\"]\")) {\n const paramName = patternPart.slice(4, -1);\n const remainingParts = slugParts.slice(slugIndex);\n params[paramName] = remainingParts;\n return params;\n }\n\n if (patternPart.startsWith(\"[\") && patternPart.endsWith(\"]\")) {\n const paramName = patternPart.slice(1, -1);\n if (slugIndex >= slugParts.length) {\n return null;\n }\n const slugPart = slugParts[slugIndex];\n if (slugPart !== undefined) {\n params[paramName] = slugPart;\n }\n slugIndex++;\n continue;\n }\n\n if (slugIndex >= slugParts.length || slugParts[slugIndex] !== patternPart) {\n return null;\n }\n slugIndex++;\n }\n\n if (slugIndex < slugParts.length) {\n return null;\n }\n\n return params;\n}\n\nexport function matchesPattern(pattern: string, slug: string): boolean {\n return extractParams(pattern, slug) !== null;\n}\n", "export function normalizeSlug(slug: string): string {\n return slug\n .split(\"/\")\n .filter((part) => part.length > 0)\n .join(\"/\");\n}\n\nexport function slugToPath(slug: string): string {\n const normalized = normalizeSlug(slug);\n return normalized ? `/${normalized}` : \"/\";\n}\n\nexport function pathToSlug(path: string): string {\n return normalizeSlug(path.replace(/^\\//, \"\"));\n}\n\nexport function getSlugFromPath(filePath: string): string {\n const parts = filePath.split(\"/\");\n const fileName = parts[parts.length - 1] || \"\";\n\n const slug = fileName.replace(/\\.(mdx?|tsx?|jsx?|ts|js)$/, \"\");\n\n if (slug === \"index\" || slug === \"page\") {\n const parentDir = parts[parts.length - 2];\n return parentDir === \"pages\" || parentDir === \"app\" ? \"\" : parentDir || \"\";\n }\n\n return slug;\n}\n", "export {\n applyHeadDirectives,\n executeScripts,\n extractPageDataFromScript,\n findAnchorElement,\n isInternalLink,\n manageFocus,\n parsePageDataFromHTML,\n updateMetaTags,\n} from \"./dom-utils.ts\";\n\nexport { NavigationHandlers } from \"./navigation-handlers.ts\";\nexport type { NavigationCallbacks } from \"./navigation-handlers.ts\";\n\nexport { PageLoader } from \"./page-loader.ts\";\nexport type { ComponentMap, FrontmatterData, PageData, RouteData } from \"./page-loader.ts\";\n\nexport { PageTransition } from \"./page-transition.ts\";\n\nexport { ViewportPrefetch } from \"./viewport-prefetch.ts\";\n", "import { rendererLogger as logger } from \"@veryfront/utils\";\nimport type { FrontmatterData, PageData } from \"./types.ts\";\n\nexport function isInternalLink(target: HTMLAnchorElement): boolean {\n const href = target.getAttribute(\"href\");\n\n if (!href) return false;\n if (href.startsWith(\"http\") || href.startsWith(\"mailto:\")) return false;\n if (href.startsWith(\"#\")) return false;\n if (target.getAttribute(\"target\") === \"_blank\" || target.getAttribute(\"download\")) {\n return false;\n }\n\n return true;\n}\n\nexport function findAnchorElement(element: HTMLElement | null): HTMLAnchorElement | null {\n let current = element;\n while (current && current.tagName !== \"A\") {\n current = current.parentElement;\n }\n\n if (!current || !(current instanceof HTMLAnchorElement)) {\n return null;\n }\n\n return current;\n}\n\nexport function updateMetaTags(frontmatter: FrontmatterData): void {\n if (frontmatter.description) {\n updateMetaTag('meta[name=\"description\"]', \"name\", \"description\", frontmatter.description);\n }\n\n if (frontmatter.ogTitle) {\n updateMetaTag('meta[property=\"og:title\"]', \"property\", \"og:title\", frontmatter.ogTitle);\n }\n}\n\nfunction updateMetaTag(\n selector: string,\n attributeName: string,\n attributeValue: string,\n content: string,\n): void {\n let metaTag = document.querySelector(selector);\n if (!metaTag) {\n metaTag = document.createElement(\"meta\");\n metaTag.setAttribute(attributeName, attributeValue);\n document.head.appendChild(metaTag);\n }\n metaTag.setAttribute(\"content\", content);\n}\n\nexport function executeScripts(container: HTMLElement): void {\n const scripts = container.querySelectorAll(\"script\");\n scripts.forEach((oldScript) => {\n const newScript = document.createElement(\"script\");\n Array.from(oldScript.attributes).forEach((attribute) => {\n newScript.setAttribute(attribute.name, attribute.value);\n });\n newScript.textContent = oldScript.textContent;\n oldScript.parentNode?.replaceChild(newScript, oldScript);\n });\n}\n\nexport function applyHeadDirectives(container: HTMLElement): void {\n const nodes = container.querySelectorAll('[data-veryfront-head=\"1\"], vf-head');\n if (nodes.length > 0) {\n cleanManagedHeadTags();\n }\n\n nodes.forEach((wrapper) => {\n processHeadWrapper(wrapper);\n wrapper.parentElement?.removeChild(wrapper);\n });\n}\n\nfunction cleanManagedHeadTags(): void {\n document.head\n .querySelectorAll('[data-veryfront-managed=\"1\"]')\n .forEach((element) => element.parentElement?.removeChild(element));\n}\n\nfunction processHeadWrapper(wrapper: Element): void {\n wrapper.childNodes.forEach((node) => {\n if (!(node instanceof Element)) return;\n\n const tagName = node.tagName.toLowerCase();\n if (tagName === \"title\") {\n document.title = node.textContent || document.title;\n return;\n }\n\n const clone = document.createElement(tagName);\n for (const attribute of Array.from(node.attributes)) {\n clone.setAttribute(attribute.name, attribute.value);\n }\n if (node.textContent && !clone.hasAttribute(\"src\")) {\n clone.textContent = node.textContent;\n }\n clone.setAttribute(\"data-veryfront-managed\", \"1\");\n document.head.appendChild(clone);\n });\n}\n\nexport function manageFocus(container: HTMLElement): void {\n try {\n const focusElement = (container.querySelector(\"[data-router-focus]\") ||\n container.querySelector(\"main\") ||\n container.querySelector(\"h1\")) as HTMLElement | null;\n\n if (focusElement && focusElement instanceof HTMLElement && \"focus\" in focusElement) {\n focusElement.focus({ preventScroll: true });\n }\n } catch (error) {\n logger.warn(\"[router] focus management failed\", error);\n }\n}\n\nexport function extractPageDataFromScript(): PageData | null {\n const pageDataScript = document.querySelector(\"script[data-veryfront-page]\");\n if (!pageDataScript) return null;\n\n try {\n const content = pageDataScript.textContent;\n if (!content) {\n logger.warn(\"[dom-utils] Page data script has no content\");\n return {};\n }\n return JSON.parse(content) as PageData;\n } catch (error) {\n logger.error(\"[dom-utils] Failed to parse page data:\", error);\n return null;\n }\n}\n\nexport function parsePageDataFromHTML(html: string): {\n content: string;\n pageData: PageData;\n} {\n const parser = new DOMParser();\n const doc = parser.parseFromString(html, \"text/html\");\n\n const root = doc.getElementById(\"root\");\n let content = \"\";\n\n if (root) {\n content = root.innerHTML || \"\";\n } else {\n logger.warn(\"[dom-utils] No root element found in HTML\");\n }\n\n const pageDataScript = doc.querySelector(\"script[data-veryfront-page]\");\n let pageData: PageData = {};\n\n if (pageDataScript) {\n try {\n const content = pageDataScript.textContent;\n if (!content) {\n logger.warn(\"[dom-utils] Page data script in HTML has no content\");\n } else {\n pageData = JSON.parse(content) as PageData;\n }\n } catch (error) {\n logger.error(\"[dom-utils] Failed to parse page data from HTML:\", error);\n }\n }\n\n return { content, pageData };\n}\n", "import { rendererLogger as logger } from \"@veryfront/utils\";\nimport { DEFAULT_PREFETCH_DELAY_MS } from \"@veryfront/config\";\nimport { findAnchorElement, isInternalLink } from \"./dom-utils.ts\";\n\nexport interface NavigationCallbacks {\n onNavigate: (url: string) => Promise<void>;\n onPrefetch: (url: string) => void;\n}\n\nexport class NavigationHandlers {\n private prefetchQueue = new Set<string>();\n private scrollPositions = new Map<string, number>();\n private isPopStateNav = false;\n private prefetchDelay: number;\n private prefetchOptions: {\n hover?: boolean;\n viewport?: boolean;\n };\n\n constructor(\n prefetchDelay = DEFAULT_PREFETCH_DELAY_MS,\n prefetchOptions: { hover?: boolean; viewport?: boolean } = {},\n ) {\n this.prefetchDelay = prefetchDelay;\n this.prefetchOptions = prefetchOptions;\n }\n\n createClickHandler(callbacks: NavigationCallbacks) {\n return (event: MouseEvent) => {\n const anchor = findAnchorElement(event.target as HTMLElement);\n if (!anchor || !isInternalLink(anchor)) return;\n\n const href = anchor.getAttribute(\"href\")!;\n event.preventDefault();\n callbacks.onNavigate(href);\n };\n }\n\n createPopStateHandler(callbacks: NavigationCallbacks) {\n return (_event: PopStateEvent) => {\n const path = globalThis.location.pathname;\n this.isPopStateNav = true;\n callbacks.onNavigate(path);\n };\n }\n\n createMouseOverHandler(callbacks: NavigationCallbacks) {\n return (event: MouseEvent) => {\n const target = event.target as HTMLElement;\n if (target.tagName !== \"A\") return;\n\n const href = target.getAttribute(\"href\");\n if (!href || href.startsWith(\"http\") || href.startsWith(\"#\")) return;\n\n if (!this.shouldPrefetchOnHover(target)) return;\n\n if (!this.prefetchQueue.has(href)) {\n this.prefetchQueue.add(href);\n setTimeout(() => {\n callbacks.onPrefetch(href);\n this.prefetchQueue.delete(href);\n }, this.prefetchDelay);\n }\n };\n }\n\n private shouldPrefetchOnHover(target: HTMLElement): boolean {\n const prefetchAttribute = target.getAttribute(\"data-prefetch\");\n const isHoverEnabled = Boolean(this.prefetchOptions.hover);\n\n if (prefetchAttribute === \"false\") return false;\n\n return prefetchAttribute === \"true\" || isHoverEnabled;\n }\n\n saveScrollPosition(path: string): void {\n try {\n const scrollY = globalThis.scrollY;\n if (typeof scrollY === \"number\") {\n this.scrollPositions.set(path, scrollY);\n } else {\n logger.debug(\"[router] No valid scrollY value available\");\n this.scrollPositions.set(path, 0);\n }\n } catch (error) {\n logger.warn(\"[router] failed to record scroll position\", error);\n }\n }\n\n getScrollPosition(path: string): number {\n const position = this.scrollPositions.get(path);\n if (position === undefined) {\n logger.debug(`[router] No scroll position stored for ${path}`);\n return 0;\n }\n return position;\n }\n\n isPopState(): boolean {\n return this.isPopStateNav;\n }\n\n clearPopStateFlag(): void {\n this.isPopStateNav = false;\n }\n\n clear(): void {\n this.prefetchQueue.clear();\n this.scrollPositions.clear();\n this.isPopStateNav = false;\n }\n}\n", "import { rendererLogger as logger } from \"@veryfront/utils\";\nimport { NetworkError } from \"@veryfront/errors/index.ts\";\nimport { parsePageDataFromHTML } from \"./dom-utils.ts\";\n\nexport type { ComponentMap, FrontmatterData, PageData, RouteData } from \"./types.ts\";\nimport type { RouteData } from \"./types.ts\";\n\nexport class PageLoader {\n private cache = new Map<string, RouteData>();\n\n getCached(path: string): RouteData | undefined {\n return this.cache.get(path);\n }\n\n isCached(path: string): boolean {\n return this.cache.has(path);\n }\n\n setCache(path: string, data: RouteData): void {\n this.cache.set(path, data);\n }\n\n clearCache(): void {\n this.cache.clear();\n }\n\n async fetchPageData(path: string): Promise<RouteData> {\n const jsonData = await this.tryFetchJSON(path);\n if (jsonData) return jsonData;\n\n return this.fetchAndParseHTML(path);\n }\n\n private async tryFetchJSON(path: string): Promise<RouteData | null> {\n try {\n const response = await fetch(`/_veryfront/data${path}.json`, {\n headers: { \"X-Veryfront-Navigation\": \"client\" },\n });\n\n if (response.ok) {\n return await response.json();\n }\n } catch (error) {\n logger.debug(`[PageLoader] RSC fetch failed for ${path}, falling back to HTML:`, error);\n }\n\n return null;\n }\n\n private async fetchAndParseHTML(path: string): Promise<RouteData> {\n const response = await fetch(path, {\n headers: { \"X-Veryfront-Navigation\": \"client\" },\n });\n\n if (!response.ok) {\n throw new NetworkError(`Failed to fetch ${path}`, {\n status: response.status,\n path,\n });\n }\n\n const html = await response.text();\n const { content, pageData } = parsePageDataFromHTML(html);\n\n return {\n html: content,\n ...pageData,\n };\n }\n\n async loadPage(path: string): Promise<RouteData> {\n const cachedData = this.getCached(path);\n if (cachedData) {\n logger.debug(`Loading ${path} from cache`);\n return cachedData;\n }\n\n const data = await this.fetchPageData(path);\n this.setCache(path, data);\n\n return data;\n }\n\n async prefetch(path: string): Promise<void> {\n if (this.isCached(path)) return;\n\n logger.debug(`Prefetching ${path}`);\n\n try {\n const data = await this.fetchPageData(path);\n this.setCache(path, data);\n } catch (error) {\n logger.warn(`Failed to prefetch ${path}`, error as Error);\n }\n }\n}\n", "import { rendererLogger as logger } from \"@veryfront/utils\";\nimport { PAGE_TRANSITION_DELAY_MS } from \"@veryfront/config\";\nimport { applyHeadDirectives, executeScripts, manageFocus, updateMetaTags } from \"./dom-utils.ts\";\nimport { validateTrustedHtml } from \"@veryfront/security/client/html-sanitizer.ts\";\nimport type { RouteData } from \"./page-loader.ts\";\n\nexport class PageTransition {\n private setupViewportPrefetch: (root: Document | HTMLElement) => void;\n private pendingTransitionTimeout?: number;\n\n constructor(setupViewportPrefetch: (root: Document | HTMLElement) => void) {\n this.setupViewportPrefetch = setupViewportPrefetch;\n }\n\n destroy(): void {\n if (this.pendingTransitionTimeout !== undefined) {\n clearTimeout(this.pendingTransitionTimeout);\n this.pendingTransitionTimeout = undefined;\n }\n }\n\n updatePage(data: RouteData, isPopState: boolean, scrollY: number): void {\n if (data.frontmatter?.title) {\n document.title = data.frontmatter.title;\n }\n\n updateMetaTags(data.frontmatter ?? {});\n\n const rootElement = document.getElementById(\"root\");\n if (rootElement && (data.html ?? \"\") !== \"\") {\n this.performTransition(rootElement, data, isPopState, scrollY);\n }\n }\n\n private performTransition(\n rootElement: HTMLElement,\n data: RouteData,\n isPopState: boolean,\n scrollY: number,\n ): void {\n if (this.pendingTransitionTimeout !== undefined) {\n clearTimeout(this.pendingTransitionTimeout);\n }\n\n rootElement.style.opacity = \"0\";\n\n this.pendingTransitionTimeout = setTimeout(() => {\n this.pendingTransitionTimeout = undefined;\n // Server-rendered RSC HTML is trusted; validateTrustedHtml provides defense-in-depth\n rootElement.innerHTML = validateTrustedHtml(String(data.html ?? \"\"));\n rootElement.style.opacity = \"1\";\n\n executeScripts(rootElement);\n applyHeadDirectives(rootElement);\n this.setupViewportPrefetch(rootElement);\n manageFocus(rootElement);\n this.handleScroll(isPopState, scrollY);\n }, PAGE_TRANSITION_DELAY_MS);\n }\n\n private handleScroll(isPopState: boolean, scrollY: number): void {\n try {\n globalThis.scrollTo(0, isPopState ? scrollY : 0);\n } catch (error) {\n logger.warn(\"[router] scroll handling failed\", error);\n }\n }\n\n showError(error: Error): void {\n const rootElement = document.getElementById(\"root\");\n if (!rootElement) return;\n\n const errorDiv = document.createElement(\"div\");\n errorDiv.className = \"veryfront-error-page\";\n\n const heading = document.createElement(\"h1\");\n heading.textContent = \"Oops! Something went wrong\";\n\n const message = document.createElement(\"p\");\n message.textContent = error.message;\n\n const button = document.createElement(\"button\");\n button.type = \"button\";\n button.textContent = \"Reload Page\";\n button.onclick = () => globalThis.location.reload();\n\n errorDiv.appendChild(heading);\n errorDiv.appendChild(message);\n errorDiv.appendChild(button);\n\n rootElement.innerHTML = \"\";\n rootElement.appendChild(errorDiv);\n }\n\n setLoadingState(loading: boolean): void {\n const indicator = document.getElementById(\"veryfront-loading\");\n if (indicator) {\n indicator.style.display = loading ? \"block\" : \"none\";\n }\n\n document.body.classList.toggle(\"veryfront-loading\", loading);\n }\n}\n", "/**\n * Lightweight HTML sanitizer for client-side use.\n *\n * Security model:\n * - RSC HTML from React's renderToString() is trusted (auto-escapes user content)\n * - Error messages and debug info are untrusted and must be escaped\n * - validateTrustedHtml() provides defense-in-depth for server HTML\n */\n\n/**\n * Escape HTML entities to prevent XSS.\n * Use for untrusted strings that will be inserted into HTML.\n */\nexport function escapeHtml(str: string): string {\n return str\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/\"/g, \""\")\n .replace(/'/g, \"'\");\n}\n\n/**\n * Create text node safely (alternative to innerHTML for simple text).\n */\nexport function createSafeTextNode(text: string): Text {\n return document.createTextNode(text);\n}\n\n/**\n * Set text content safely (never interprets HTML).\n */\nexport function setSafeTextContent(element: HTMLElement, text: string): void {\n element.textContent = text;\n}\n\n/**\n * Patterns that RSC should never generate.\n * These indicate potential server compromise or misconfiguration.\n */\nconst SUSPICIOUS_PATTERNS = [\n { pattern: /<script[^>]*>[\\s\\S]*?<\\/script>/gi, name: \"inline script\" },\n { pattern: /javascript:/gi, name: \"javascript: URL\" },\n { pattern: /\\bon\\w+\\s*=/gi, name: \"event handler attribute\" },\n { pattern: /data:\\s*text\\/html/gi, name: \"data: HTML URL\" },\n];\n\n// Check if we're in development mode\nfunction isDevMode(): boolean {\n if (typeof globalThis !== \"undefined\") {\n // deno-lint-ignore no-explicit-any\n const g = globalThis as any;\n return g.__VERYFRONT_DEV__ === true || g.Deno?.env?.get?.(\"VERYFRONT_ENV\") === \"development\";\n }\n return false;\n}\n\nexport interface ValidateTrustedHtmlOptions {\n /** Throw on suspicious patterns even in dev mode */\n strict?: boolean;\n /** Log warnings for suspicious patterns */\n warn?: boolean;\n}\n\n/**\n * Validate trusted HTML from server (defense-in-depth).\n *\n * This is NOT a full sanitizer - server-rendered RSC content is trusted.\n * This catches scenarios where the server might be compromised or misconfigured.\n *\n * @param html - HTML string from server\n * @param options - Validation options\n * @returns The original HTML if valid\n * @throws Error if suspicious patterns detected in strict mode or production\n */\nexport function validateTrustedHtml(\n html: string,\n options: ValidateTrustedHtmlOptions = {},\n): string {\n const { strict = false, warn = true } = options;\n\n for (const { pattern, name } of SUSPICIOUS_PATTERNS) {\n // Reset regex state for global patterns\n pattern.lastIndex = 0;\n\n if (pattern.test(html)) {\n const message = `[Security] Suspicious ${name} detected in server HTML`;\n\n if (warn) {\n console.warn(message);\n }\n\n // In strict mode or production, throw\n if (strict || !isDevMode()) {\n throw new Error(`Potentially unsafe HTML: ${name} detected`);\n }\n }\n }\n\n return html;\n}\n\n/**\n * Create an error display element safely using DOM APIs.\n * Use this instead of innerHTML for displaying error messages.\n */\nexport function createErrorDisplay(options: {\n title: string;\n message: string;\n details?: string;\n style?: Partial<CSSStyleDeclaration>;\n}): HTMLDivElement {\n const { title, message, details, style } = options;\n\n const container = document.createElement(\"div\");\n\n // Apply default error styling\n Object.assign(container.style, {\n color: \"red\",\n border: \"2px solid red\",\n padding: \"10px\",\n margin: \"5px\",\n fontFamily: \"monospace\",\n fontSize: \"14px\",\n backgroundColor: \"#fff0f0\",\n ...style,\n });\n\n // Title\n const titleEl = document.createElement(\"strong\");\n titleEl.textContent = title;\n container.appendChild(titleEl);\n container.appendChild(document.createElement(\"br\"));\n\n // Message\n const messageEl = document.createElement(\"span\");\n messageEl.textContent = message;\n container.appendChild(messageEl);\n\n // Details (optional)\n if (details) {\n container.appendChild(document.createElement(\"br\"));\n const detailsEl = document.createElement(\"pre\");\n detailsEl.style.cssText = \"margin: 5px 0; white-space: pre-wrap; word-break: break-word;\";\n detailsEl.textContent = details;\n container.appendChild(detailsEl);\n }\n\n return container;\n}\n", "import { rendererLogger as logger } from \"@veryfront/utils\";\n\nexport class ViewportPrefetch {\n private observer: IntersectionObserver | null = null;\n private prefetchCallback: (path: string) => void;\n private prefetchOptions: {\n hover?: boolean;\n viewport?: boolean;\n };\n\n constructor(\n prefetchCallback: (path: string) => void,\n prefetchOptions: { hover?: boolean; viewport?: boolean } = {},\n ) {\n this.prefetchCallback = prefetchCallback;\n this.prefetchOptions = prefetchOptions;\n }\n\n setup(root: Document | HTMLElement): void {\n try {\n if (!(\"IntersectionObserver\" in globalThis)) return;\n\n if (this.observer) this.observer.disconnect();\n\n this.createObserver();\n this.observeLinks(root);\n } catch (error) {\n logger.debug(\"[router] setupViewportPrefetch failed\", error);\n }\n }\n\n private createObserver(): void {\n this.observer = new IntersectionObserver(\n (entries) => {\n for (const entry of entries) {\n if (entry.isIntersecting) {\n const isAnchor = typeof HTMLAnchorElement !== \"undefined\"\n ? entry.target instanceof HTMLAnchorElement\n : (entry.target as any).tagName === \"A\";\n\n if (isAnchor) {\n const href = (entry.target as HTMLAnchorElement).getAttribute(\"href\");\n if (href) {\n this.prefetchCallback(href);\n }\n this.observer?.unobserve(entry.target);\n }\n }\n }\n },\n { rootMargin: \"200px\" },\n );\n }\n\n private observeLinks(root: Document | HTMLElement): void {\n const anchors: NodeListOf<HTMLAnchorElement> =\n root.querySelectorAll?.('a[href]:not([target=\"_blank\"])') ??\n document.createDocumentFragment().querySelectorAll(\"a\");\n const isViewportEnabled = Boolean(this.prefetchOptions.viewport);\n\n anchors.forEach((anchor) => {\n if (this.shouldObserveAnchor(anchor, isViewportEnabled)) {\n this.observer?.observe(anchor);\n }\n });\n }\n\n private shouldObserveAnchor(anchor: HTMLAnchorElement, isViewportEnabled: boolean): boolean {\n const href = anchor.getAttribute(\"href\") || \"\";\n if (\n !href || href.startsWith(\"http\") || href.startsWith(\"#\") || anchor.getAttribute(\"download\")\n ) {\n return false;\n }\n\n const prefetchAttribute = anchor.getAttribute(\"data-prefetch\");\n if (prefetchAttribute === \"false\") return false;\n\n return prefetchAttribute === \"viewport\" || isViewportEnabled;\n }\n\n disconnect(): void {\n if (this.observer) {\n try {\n this.observer.disconnect();\n } catch (error) {\n logger.warn(\"[router] prefetchObserver.disconnect failed\", error);\n }\n this.observer = null;\n }\n }\n}\n", "export { APIRouteHandler } from \"./handler.ts\";\nexport type { APIContext, APIHandler, APIResponse, APIRoute } from \"./handler.ts\";\n\nexport { DynamicRouter } from \"./api-route-matcher.ts\";\nexport type { Route, RouteMatch } from \"./api-route-matcher.ts\";\n\nexport {\n badRequest,\n forbidden,\n json,\n notFound,\n redirect,\n serverError,\n unauthorized,\n} from \"./responses.ts\";\n\nexport { applyCORSHeaders, handleCORSPreflight } from \"@veryfront/security\";\n\nexport type { APIContext as APIContextType } from \"./context-builder.ts\";\nexport { createContext, normalizeParams, parseCookies } from \"./context-builder.ts\";\n", "import { serverLogger as logger } from \"@veryfront/utils\";\nimport { join } from \"std/path/mod.ts\";\nimport type { RuntimeAdapter } from \"@veryfront/platform/adapters/base.ts\";\nimport { getConfig } from \"@veryfront/config\";\nimport { LRUCache } from \"@veryfront/utils/lru-wrapper.ts\";\nimport { createError, toError } from \"../../core/errors/veryfront-error.ts\";\nimport { badGateway, internalServerError, notFound } from \"../../http/responses.ts\";\nimport type { CORSConfig } from \"@veryfront/security\";\nimport { applyCORSHeaders, handleCORSPreflight } from \"@veryfront/security\";\nimport { type APIContext } from \"./context-builder.ts\";\nimport { DynamicRouter, type RouteMatch } from \"./api-route-matcher.ts\";\nimport type { APIRoute } from \"./module-loader/types.ts\";\nimport { loadHandlerModule } from \"./module-loader/loader.ts\";\nimport { discoverAppRoutes, discoverPagesRoutes } from \"./route-discovery.ts\";\nimport { executeAppRoute, executePagesRoute } from \"./route-executor.ts\";\n\nexport type { APIContext, APIRoute };\n\nexport interface APIResponse {\n body?: unknown;\n status?: number;\n headers?: HeadersInit;\n}\n\nexport type APIHandler = (ctx: APIContext) => Promise<Response> | Response;\n\nexport class APIRouteHandler {\n private router: DynamicRouter;\n private routeCache = new LRUCache<string, APIRoute>({\n maxEntries: 256,\n });\n private lastErrorMessage: string | null = null;\n private adapter: RuntimeAdapter | null;\n private adapterPromise: Promise<RuntimeAdapter> | null = null;\n private corsConfig: boolean | CORSConfig | null = null;\n private corsConfigLoaded = false;\n private corsConfigPromise: Promise<void> | null = null;\n private config: Awaited<ReturnType<typeof getConfig>> | null = null;\n private configPromise: Promise<void> | null = null;\n\n constructor(\n private projectDir: string,\n adapter?: RuntimeAdapter,\n ) {\n this.router = new DynamicRouter();\n this.adapter = adapter ?? null;\n if (adapter) {\n this.adapterPromise = Promise.resolve(adapter);\n }\n }\n\n async initialize(): Promise<void> {\n const adapter = await this.ensureAdapter();\n await this.ensureConfig(adapter);\n\n const pagesDir = this.config?.directories?.pages || \"pages\";\n const apiDir = join(this.projectDir, pagesDir, \"api\");\n const apiDirExists = await adapter.fs.exists(apiDir);\n\n if (apiDirExists) {\n await discoverPagesRoutes(this.router, apiDir, \"/api\", adapter);\n }\n\n const appDirName = this.config?.directories?.app || \"app\";\n const appDir = join(this.projectDir, appDirName);\n const appDirExists = await adapter.fs.exists(appDir);\n\n if (appDirExists) {\n await discoverAppRoutes(this.router, appDir, \"\", adapter);\n }\n\n await this.ensureCorsConfig(adapter);\n }\n\n async handle(request: Request): Promise<Response | null> {\n const adapter = await this.ensureAdapter();\n const url = new URL(request.url);\n const pathname = url.pathname;\n\n if (request.method.toUpperCase() === \"OPTIONS\") {\n await this.ensureCorsConfig(adapter);\n return await handleCORSPreflight({\n request,\n config: this.corsConfig ?? undefined,\n });\n }\n\n await this.ensureCorsConfig(adapter);\n\n const match = this.router.match(pathname);\n\n if (!match) {\n if (pathname === \"/api\" || pathname.startsWith(\"/api/\")) {\n return notFound();\n }\n return null;\n }\n\n const handler = await this.loadHandler(match);\n\n if (!handler) {\n try {\n logger.error(`[API] handler module failed to load: ${match.route.page}`);\n } catch (e) {\n logger.warn(\"API error log failed\", e);\n }\n const msg = this.lastErrorMessage ?? \"Handler not found\";\n if (msg.includes(\"Remote import blocked by allow-list\")) {\n return badGateway(msg);\n }\n return internalServerError(\"Handler not found\");\n }\n\n const isAppRoute = /\\/(app)\\//.test(match.route.page);\n const response = isAppRoute\n ? await executeAppRoute(handler, request, match, pathname, adapter)\n : await executePagesRoute(handler, request, match, pathname, adapter);\n\n const corsResponse = await applyCORSHeaders({\n request,\n response,\n config: this.corsConfig ?? undefined,\n });\n return corsResponse ?? response;\n }\n\n private async loadHandler(match: RouteMatch): Promise<APIRoute | null> {\n const adapter = await this.ensureAdapter();\n await this.ensureConfig(adapter);\n const modulePath = match.route.page;\n\n const cached = this.routeCache.get(modulePath);\n if (cached) {\n return cached;\n }\n\n try {\n const handler = await loadHandlerModule({\n projectDir: this.projectDir,\n modulePath,\n adapter,\n config: this.config ?? undefined,\n });\n\n if (handler) {\n this.routeCache.set(modulePath, handler);\n }\n\n return handler;\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n this.lastErrorMessage = msg;\n return null;\n }\n }\n\n clearCache(): void {\n this.routeCache.clear();\n this.router.clearCache();\n }\n\n destroy(): void {\n this.routeCache.destroy();\n this.router.destroy();\n }\n\n private async ensureAdapter(): Promise<RuntimeAdapter> {\n if (this.adapter) return this.adapter;\n if (!this.adapterPromise) {\n const { getAdapter } = await import(\"@veryfront/platform/adapters/detect.ts\");\n\n this.adapterPromise = getAdapter();\n }\n this.adapter = await this.adapterPromise;\n if (!this.adapter) {\n throw toError(createError({\n type: \"api\",\n message: \"Failed to initialize runtime adapter\",\n }));\n }\n return this.adapter;\n }\n\n private async ensureCorsConfig(adapter: RuntimeAdapter): Promise<void> {\n if (this.corsConfigLoaded) return;\n if (!this.corsConfigPromise) {\n this.corsConfigPromise = this.loadCorsConfig(adapter);\n }\n await this.corsConfigPromise;\n }\n\n private async loadCorsConfig(adapter: RuntimeAdapter): Promise<void> {\n try {\n const config = await getConfig(this.projectDir, adapter);\n this.corsConfig = config.security?.cors ?? null;\n } catch (error) {\n this.corsConfig = null;\n try {\n logger.warn(\"Failed to load CORS configuration\", error);\n } catch (logError) {\n logger.error(\"Failed to log CORS config error:\", logError);\n }\n } finally {\n this.corsConfigLoaded = true;\n this.corsConfigPromise = null;\n }\n }\n\n private async ensureConfig(adapter: RuntimeAdapter): Promise<void> {\n if (this.config) return;\n if (!this.configPromise) {\n this.configPromise = this.loadFullConfig(adapter);\n }\n await this.configPromise;\n }\n\n private async loadFullConfig(adapter: RuntimeAdapter): Promise<void> {\n try {\n this.config = await getConfig(this.projectDir, adapter);\n } catch (error) {\n this.config = null;\n try {\n logger.warn(\"Failed to load config\", error);\n } catch (logError) {\n logger.error(\"Failed to log config error:\", logError);\n }\n } finally {\n this.configPromise = null;\n }\n }\n}\n\nexport {\n badRequest,\n forbidden,\n internalServerError as serverError,\n jsonResponse as json,\n notFound,\n redirectResponse as redirect,\n unauthorized,\n} from \"../../http/responses.ts\";\n", "/**\n * Centralized HTTP response factory for clean, consistent error handling.\n * Follows clean code principles: DRY, single responsibility, and clear naming.\n */\n\n/** HTTP Status codes as named constants for clarity */\nexport const HttpStatus = {\n OK: 200,\n CREATED: 201,\n NO_CONTENT: 204,\n MOVED_PERMANENTLY: 301,\n FOUND: 302,\n NOT_MODIFIED: 304,\n BAD_REQUEST: 400,\n UNAUTHORIZED: 401,\n FORBIDDEN: 403,\n NOT_FOUND: 404,\n METHOD_NOT_ALLOWED: 405,\n CONFLICT: 409,\n UNPROCESSABLE_ENTITY: 422,\n TOO_MANY_REQUESTS: 429,\n INTERNAL_SERVER_ERROR: 500,\n NOT_IMPLEMENTED: 501,\n BAD_GATEWAY: 502,\n SERVICE_UNAVAILABLE: 503,\n GATEWAY_TIMEOUT: 504,\n} as const;\n\nexport type HttpStatusCode = typeof HttpStatus[keyof typeof HttpStatus];\n\n/** Response options for additional headers and metadata */\ninterface ResponseOptions extends ResponseInit {\n headers?: HeadersInit;\n correlationId?: string;\n}\n\n/**\n * Creates a standardized error response.\n * Simple, clear, and consistent across the application.\n */\nexport function errorResponse(\n status: HttpStatusCode,\n message?: string,\n options?: ResponseOptions,\n): Response {\n const statusText = getStatusText(status);\n const body = message || statusText;\n\n const headers = new Headers(options?.headers);\n headers.set(\"Content-Type\", \"text/plain; charset=utf-8\");\n\n if (options?.correlationId) {\n headers.set(\"X-Correlation-Id\", options.correlationId);\n }\n\n return new Response(body, {\n ...options,\n status,\n statusText,\n headers,\n });\n}\n\n/**\n * Creates a JSON response with proper content type.\n * Handles serialization errors gracefully.\n */\nexport function jsonResponse<T>(\n data: T,\n status: HttpStatusCode = HttpStatus.OK,\n options?: ResponseOptions,\n): Response {\n const headers = new Headers(options?.headers);\n headers.set(\"Content-Type\", \"application/json; charset=utf-8\");\n\n try {\n const body = JSON.stringify(data);\n return new Response(body, {\n ...options,\n status,\n headers,\n });\n } catch {\n return errorResponse(\n HttpStatus.INTERNAL_SERVER_ERROR,\n \"Failed to serialize response data\",\n );\n }\n}\n\n/**\n * Creates a redirect response.\n * Validates URL to prevent open redirect vulnerabilities.\n */\nexport function redirectResponse(\n url: string,\n permanent = false,\n options?: ResponseOptions,\n): Response {\n // Simple URL validation to prevent open redirects\n if (!isValidRedirectUrl(url)) {\n return errorResponse(\n HttpStatus.BAD_REQUEST,\n \"Invalid redirect URL\",\n );\n }\n\n const status = permanent ? HttpStatus.MOVED_PERMANENTLY : HttpStatus.FOUND;\n const headers = new Headers(options?.headers);\n headers.set(\"Location\", url);\n\n return new Response(null, {\n ...options,\n status,\n headers,\n });\n}\n\n// Convenience methods for common responses\nexport const notFound = (message?: string, options?: ResponseOptions) =>\n errorResponse(HttpStatus.NOT_FOUND, message, options);\n\nexport const badRequest = (message?: string, options?: ResponseOptions) =>\n errorResponse(HttpStatus.BAD_REQUEST, message, options);\n\nexport const unauthorized = (message?: string, options?: ResponseOptions) =>\n errorResponse(HttpStatus.UNAUTHORIZED, message, options);\n\nexport const forbidden = (message?: string, options?: ResponseOptions) =>\n errorResponse(HttpStatus.FORBIDDEN, message, options);\n\nexport const internalServerError = (message?: string, options?: ResponseOptions) =>\n errorResponse(HttpStatus.INTERNAL_SERVER_ERROR, message, options);\n\nexport const badGateway = (message?: string, options?: ResponseOptions) =>\n errorResponse(HttpStatus.BAD_GATEWAY, message, options);\n\nexport const serviceUnavailable = (message?: string, options?: ResponseOptions) =>\n errorResponse(HttpStatus.SERVICE_UNAVAILABLE, message, options);\n\nexport const methodNotAllowed = (allowed: string[], options?: ResponseOptions) => {\n const headers = new Headers(options?.headers);\n headers.set(\"Allow\", allowed.join(\", \"));\n return errorResponse(\n HttpStatus.METHOD_NOT_ALLOWED,\n `Method not allowed. Allowed methods: ${allowed.join(\", \")}`,\n { ...options, headers },\n );\n};\n\nexport const ok = <T>(data?: T, options?: ResponseOptions) =>\n data === undefined\n ? new Response(null, { status: HttpStatus.OK, ...options })\n : jsonResponse(data, HttpStatus.OK, options);\n\nexport const created = <T>(data?: T, location?: string, options?: ResponseOptions) => {\n const headers = new Headers(options?.headers);\n if (location) {\n headers.set(\"Location\", location);\n }\n return data === undefined\n ? new Response(null, { status: HttpStatus.CREATED, headers, ...options })\n : jsonResponse(data, HttpStatus.CREATED, { ...options, headers });\n};\n\nexport const noContent = (options?: ResponseOptions) =>\n new Response(null, { status: HttpStatus.NO_CONTENT, ...options });\n\n/**\n * Helper function to get human-readable status text.\n * Keeps the mapping simple and maintainable.\n */\nfunction getStatusText(status: HttpStatusCode): string {\n const statusTexts: Record<HttpStatusCode, string> = {\n [HttpStatus.OK]: \"OK\",\n [HttpStatus.CREATED]: \"Created\",\n [HttpStatus.NO_CONTENT]: \"No Content\",\n [HttpStatus.MOVED_PERMANENTLY]: \"Moved Permanently\",\n [HttpStatus.FOUND]: \"Found\",\n [HttpStatus.NOT_MODIFIED]: \"Not Modified\",\n [HttpStatus.BAD_REQUEST]: \"Bad Request\",\n [HttpStatus.UNAUTHORIZED]: \"Unauthorized\",\n [HttpStatus.FORBIDDEN]: \"Forbidden\",\n [HttpStatus.NOT_FOUND]: \"Not Found\",\n [HttpStatus.METHOD_NOT_ALLOWED]: \"Method Not Allowed\",\n [HttpStatus.CONFLICT]: \"Conflict\",\n [HttpStatus.UNPROCESSABLE_ENTITY]: \"Unprocessable Entity\",\n [HttpStatus.TOO_MANY_REQUESTS]: \"Too Many Requests\",\n [HttpStatus.INTERNAL_SERVER_ERROR]: \"Internal Server Error\",\n [HttpStatus.NOT_IMPLEMENTED]: \"Not Implemented\",\n [HttpStatus.BAD_GATEWAY]: \"Bad Gateway\",\n [HttpStatus.SERVICE_UNAVAILABLE]: \"Service Unavailable\",\n [HttpStatus.GATEWAY_TIMEOUT]: \"Gateway Timeout\",\n };\n\n return statusTexts[status] || \"Unknown Status\";\n}\n\n/**\n * Simple URL validation for redirect safety.\n * Prevents open redirect vulnerabilities.\n */\nfunction isValidRedirectUrl(url: string): boolean {\n try {\n const parsed = new URL(url, \"http://localhost\"); // Base URL for relative URLs\n\n // Allow relative URLs and same-origin absolute URLs\n if (url.startsWith(\"/\") || url.startsWith(\"./\") || url.startsWith(\"../\")) {\n return true;\n }\n\n // For absolute URLs, could add domain whitelist here if needed\n return parsed.protocol === \"http:\" || parsed.protocol === \"https:\";\n } catch {\n return false;\n }\n}\n", "/**\n * Security Module - Comprehensive HTTP Security & Response System\n *\n * Provides security features including:\n * - Input validation and sanitization\n * - HTTP security headers (CSP, CORS, etc.)\n * - Authentication handlers\n * - Security middleware\n * - Response building with security best practices\n *\n * @module security\n */\n\n// Base Handler\nexport { BaseHandler } from \"./http/base-handler.ts\";\n\n// Input Validation (from input-validation/)\nexport type {\n ParseFormOptions,\n ParseJsonOptions,\n RequestLimits,\n ValidatedData,\n ValidatedHandlerConfig,\n ValidatedHandlerFunction,\n} from \"./input-validation/index.ts\";\n\nexport {\n CommonSchemas,\n createValidatedHandler,\n DEFAULT_LIMITS,\n parseFormData,\n parseJsonBody,\n parseQueryParams,\n readBodyWithLimit,\n sanitizeData,\n validateRequestLimits,\n ValidationError,\n} from \"./input-validation/index.ts\";\n\n// HTTP Security (from http/)\nexport type { CORSConfig, CSPDirectives, SecurityConfig } from \"./http/handlers-index.ts\";\n\nexport {\n AuthHandler,\n loadSecurityConfig,\n SecurityConfigLoader,\n setCors,\n} from \"./http/handlers-index.ts\";\n\n// Additional HTTP Security Utilities (from http/middleware/)\nexport { computeEtag, CONTENT_TYPES, isValidSecurityConfig } from \"./http/middleware/index.ts\";\n\n// CORS (from http/cors/ - merged from cors package)\nexport type {\n CORSConfig as CORSOptions,\n CORSHeaderOptions,\n CORSPreflightOptions,\n CORSValidationResult,\n OriginValidator,\n} from \"./http/cors/index.ts\";\nexport {\n applyCORSHeaders,\n applyCORSHeadersSync,\n cors,\n corsSimple,\n DEFAULT_HEADERS as DEFAULT_CORS_HEADERS,\n DEFAULT_MAX_AGE as CORS_MAX_AGE,\n DEFAULT_METHODS as DEFAULT_CORS_METHODS,\n handleCORSPreflight,\n isPreflightRequest,\n shouldApplyCORS,\n validateCORSConfig,\n validateOrigin,\n validateOriginSync,\n} from \"./http/cors/index.ts\";\n\n// Response Builder (from http/response/ - merged from response-builder package)\nexport type { CacheStrategy, ResponseBuilderConfig } from \"./http/response/index.ts\";\nexport {\n applySecurityHeaders,\n buildCacheControl,\n CACHE_DURATIONS,\n createResponseBuilder,\n generateNonce,\n getSecurityHeader,\n ResponseBuilder,\n} from \"./http/response/index.ts\";\n\n// Path validation and traversal protection\nexport {\n createValidator,\n PathValidationError,\n sanitizePathForDisplay,\n validatePath,\n validatePathSync,\n ValidationPresets,\n} from \"./path-validation.ts\";\nexport type { ValidationLevel, ValidationOptions, ValidationResult } from \"./path-validation.ts\";\n\n// Secure filesystem wrapper\nexport { createSecureFs, SecureFs, SecurityError, wrapAdapterWithSecurity } from \"./secure-fs.ts\";\nexport type { SecureFsConfig, SecurityContext, SecurityEvent } from \"./secure-fs.ts\";\n", "/**\n * Base handler abstract class\n * Provides common functionality for all handlers\n */\n\nimport type {\n Handler,\n HandlerContext,\n HandlerMetadata,\n HandlerResult,\n RoutePattern,\n} from \"@veryfront/types\";\nimport { ResponseBuilder } from \"./response/index.ts\";\nimport { serverLogger } from \"@veryfront/utils\";\n\nexport abstract class BaseHandler implements Handler {\n abstract metadata: HandlerMetadata;\n\n /**\n * Main handler method to be implemented by subclasses\n */\n abstract handle(req: Request, ctx: HandlerContext): Promise<HandlerResult>;\n\n /**\n * Check if this handler should process the request\n */\n protected shouldHandle(req: Request, ctx: HandlerContext): boolean {\n // Check if handler is enabled\n if (this.metadata.enabled && !this.metadata.enabled(ctx)) {\n return false;\n }\n\n // If no patterns specified, handler decides internally\n if (!this.metadata.patterns || this.metadata.patterns.length === 0) {\n return true;\n }\n\n const url = new URL(req.url);\n const pathname = url.pathname;\n const method = req.method.toUpperCase();\n\n // Check each pattern\n for (const pattern of this.metadata.patterns) {\n if (this.matchesPattern(pathname, method, pattern)) {\n return true;\n }\n }\n\n return false;\n }\n\n /**\n * Check if request matches a pattern\n */\n private matchesPattern(pathname: string, method: string, pattern: RoutePattern): boolean {\n // Check method if specified\n if (pattern.method) {\n const methods = Array.isArray(pattern.method) ? pattern.method : [pattern.method];\n if (!methods.map((m) => m.toUpperCase()).includes(method)) {\n return false;\n }\n }\n\n // Check path pattern\n if (typeof pattern.pattern === \"string\") {\n if (pattern.exact) {\n return pathname === pattern.pattern;\n } else if (pattern.prefix) {\n return pathname.startsWith(pattern.pattern);\n } else {\n // Default to exact match for strings\n return pathname === pattern.pattern;\n }\n } else if (pattern.pattern instanceof RegExp) {\n return pattern.pattern.test(pathname);\n }\n\n return false;\n }\n\n /**\n * Create a response builder with context\n * @param ctx - Handler context\n * @param nonce - Optional pre-generated nonce for CSP consistency\n */\n protected createResponseBuilder(ctx: HandlerContext, nonce?: string): ResponseBuilder {\n return new ResponseBuilder({\n securityConfig: ctx.securityConfig ?? undefined,\n isDev: ctx.mode === \"development\",\n cspUserHeader: ctx.cspUserHeader,\n adapter: ctx.adapter,\n nonce, // Pass through the nonce if provided\n });\n }\n\n /**\n * Log debug message if debug mode is enabled\n */\n protected logDebug(message: string, extra?: Record<string, unknown>, ctx?: HandlerContext): void {\n if (ctx?.debug || ctx?.adapter.env.get(\"VERYFRONT_DEBUG\")) {\n serverLogger.debug(`[${this.metadata.name}] ${message}`, extra || undefined);\n }\n }\n\n /**\n * Helper to extract error message safely\n */\n protected getErrorMessage(error: unknown): string {\n if (error instanceof Error) return error.message;\n return String(error);\n }\n\n /**\n * Continue to next handler\n */\n protected continue(): HandlerResult {\n return { continue: true };\n }\n\n /**\n * Return a response and stop the chain\n */\n protected respond(response: Response, metadata?: Record<string, unknown>): HandlerResult {\n return { response, continue: false, metadata };\n }\n}\n", "/**\n * Response Builder - Public API\n * Fluent API for constructing HTTP responses with common patterns\n */\n\n// Re-export types\nexport type { CacheStrategy, CORSConfig, ResponseBuilderConfig, SecurityConfig } from \"./types.ts\";\n\n// Re-export constants\nexport { CACHE_DURATIONS, CONTENT_TYPES } from \"./constants.ts\";\n\n// Re-export main builder\nexport { createResponseBuilder, ResponseBuilder } from \"./builder.ts\";\n\n// Re-export handler utilities (for advanced usage)\nexport { applyCORSHeaders, shouldApplyCORS } from \"../cors/index.ts\";\nexport {\n applySecurityHeaders,\n buildCSP,\n generateNonce,\n getSecurityHeader,\n} from \"./security-handler.ts\";\nexport { buildCacheControl } from \"./cache-handler.ts\";\n", "/**\n * Response Builder Constants\n * Content types and cache duration constants\n */\n\n/**\n * Content type constants\n */\nexport const CONTENT_TYPES = {\n JSON: \"application/json; charset=utf-8\",\n HTML: \"text/html; charset=utf-8\",\n TEXT: \"text/plain; charset=utf-8\",\n JAVASCRIPT: \"application/javascript; charset=utf-8\",\n CSS: \"text/css; charset=utf-8\",\n XML: \"application/xml; charset=utf-8\",\n} as const;\n\n/**\n * Cache duration constants (in seconds)\n */\nexport const CACHE_DURATIONS = {\n SHORT: 60,\n MEDIUM: 3600,\n LONG: 31536000,\n} as const;\n", "/**\n * ResponseBuilder - Main builder class\n * Fluent API for constructing HTTP responses with common patterns\n */\n\nimport type { ResponseBuilderConfig, SecurityConfig } from \"./types.ts\";\nimport * as fluentMethods from \"./fluent-methods.ts\";\nimport type { FluentMethodsContext } from \"./fluent-methods.ts\";\nimport * as responseMethods from \"./response-methods.ts\";\nimport type { ResponseMethodsContext } from \"./response-methods.ts\";\nimport * as staticHelpers from \"./static-helpers.ts\";\nimport { generateNonce } from \"./security-handler.ts\";\n\n/**\n * ResponseBuilder class for fluent response construction\n * Combines fluent methods and response methods into a cohesive builder API\n */\nexport class ResponseBuilder implements FluentMethodsContext, ResponseMethodsContext {\n public headers: Headers;\n public status: number;\n public securityConfig: SecurityConfig | null;\n public isDev: boolean;\n public nonce: string;\n public cspUserHeader: string | null;\n public adapter: import(\"@veryfront/platform/adapters/base.ts\").RuntimeAdapter | undefined;\n\n constructor(config?: ResponseBuilderConfig) {\n this.headers = new Headers();\n this.status = 200;\n this.securityConfig = config?.securityConfig ?? null;\n this.isDev = config?.isDev ?? false;\n this.nonce = config?.nonce ?? generateNonce();\n this.cspUserHeader = config?.cspUserHeader ?? null;\n this.adapter = config?.adapter;\n }\n\n withCORS = fluentMethods.withCORS;\n withCORSAsync = fluentMethods.withCORSAsync;\n withSecurity = fluentMethods.withSecurity;\n withCache = fluentMethods.withCache;\n withETag = fluentMethods.withETag;\n withHeaders = fluentMethods.withHeaders;\n withStatus = fluentMethods.withStatus;\n withAllow = fluentMethods.withAllow;\n\n json = responseMethods.json;\n text = responseMethods.text;\n html = responseMethods.html;\n javascript = responseMethods.javascript;\n withContentType = responseMethods.withContentType;\n build = responseMethods.build;\n notModified = responseMethods.notModified;\n\n static error = staticHelpers.error;\n static json = staticHelpers.json;\n static html = staticHelpers.html;\n static preflight = staticHelpers.preflight;\n static stream = staticHelpers.stream;\n}\n\n// Initialize the ResponseBuilder class reference in static-helpers\nstaticHelpers.setResponseBuilderClass(\n ResponseBuilder as unknown as Parameters<typeof staticHelpers.setResponseBuilderClass>[0],\n);\n\n/**\n * Factory function for creating preconfigured builders\n */\nexport function createResponseBuilder(\n config?: ResponseBuilderConfig,\n): ResponseBuilder {\n return new ResponseBuilder(config);\n}\n", "/**\n * ResponseBuilder - Fluent Builder Methods\n * Fluent methods for configuring response builder state\n */\n\nimport { applyCORSHeaders, applyCORSHeadersSync } from \"../cors/index.ts\";\nimport { applySecurityHeaders } from \"./security-handler.ts\";\nimport { buildCacheControl } from \"./cache-handler.ts\";\nimport type { CacheStrategy, CORSConfig, SecurityConfig } from \"./types.ts\";\n\n/**\n * Internal state interface for fluent methods\n */\nexport interface FluentMethodsContext {\n headers: Headers;\n status: number;\n securityConfig: SecurityConfig | null;\n isDev: boolean;\n nonce: string;\n cspUserHeader: string | null;\n adapter: import(\"@veryfront/platform/adapters/base.ts\").RuntimeAdapter | undefined;\n}\n\n/**\n * Apply CORS headers based on configuration\n */\nexport function withCORS<T extends FluentMethodsContext>(\n this: T,\n req: Request,\n corsConfig?: boolean | CORSConfig,\n): T {\n const config = corsConfig ?? this.securityConfig?.cors;\n applyCORSHeadersSync({\n request: req,\n headers: this.headers,\n config,\n });\n return this;\n}\n\n/**\n * Apply CORS headers asynchronously (for loading config)\n */\nexport function withCORSAsync<T extends FluentMethodsContext>(\n this: T,\n req: Request,\n): Promise<T> {\n return applyCORSHeaders({\n request: req,\n headers: this.headers,\n config: this.securityConfig?.cors,\n }).then(() => this);\n}\n\n/**\n * Apply security headers (CSP, COOP, CORP, COEP)\n */\nexport function withSecurity<T extends FluentMethodsContext>(\n this: T,\n config?: SecurityConfig,\n): T {\n const cfg = config ?? this.securityConfig;\n applySecurityHeaders(\n this.headers,\n this.isDev,\n this.nonce,\n this.cspUserHeader,\n cfg,\n this.adapter,\n );\n return this;\n}\n\n/**\n * Apply cache control headers based on strategy\n */\nexport function withCache<T extends FluentMethodsContext>(\n this: T,\n strategy: CacheStrategy,\n): T {\n const cacheControl = buildCacheControl(strategy);\n this.headers.set(\"cache-control\", cacheControl);\n return this;\n}\n\n/**\n * Set ETag header\n */\nexport function withETag<T extends FluentMethodsContext>(\n this: T,\n etag: string,\n): T {\n this.headers.set(\"ETag\", etag);\n return this;\n}\n\n/**\n * Set custom headers\n */\nexport function withHeaders<T extends FluentMethodsContext>(\n this: T,\n headers: HeadersInit | Record<string, string>,\n): T {\n if (headers instanceof Headers) {\n headers.forEach((value, key) => {\n this.headers.set(key, value);\n });\n } else if (Array.isArray(headers)) {\n headers.forEach(([key, value]) => {\n this.headers.set(key, value);\n });\n } else {\n Object.entries(headers).forEach(([key, value]) => {\n this.headers.set(key, value);\n });\n }\n return this;\n}\n\n/**\n * Set response status\n */\nexport function withStatus<T extends FluentMethodsContext>(\n this: T,\n status: number,\n): T {\n this.status = status;\n return this;\n}\n\n/**\n * Set Allow header for OPTIONS requests\n */\nexport function withAllow<T extends FluentMethodsContext>(\n this: T,\n methods: string | string[],\n): T {\n const methodStr = Array.isArray(methods) ? methods.join(\", \") : methods;\n this.headers.set(\"Allow\", methodStr);\n this.headers.set(\"Access-Control-Allow-Methods\", methodStr);\n return this;\n}\n", "/**\n * CORS Module\n * Consolidated CORS handling for the Veryfront framework\n *\n * This module provides a unified, secure, and feature-complete CORS implementation\n * that replaces multiple scattered CORS handlers throughout the codebase.\n *\n * Features:\n * - Secure by default (no CORS without explicit configuration)\n * - Complete preflight handling with proper error responses\n * - Origin validation (string, array, function)\n * - Credentials support with security validations\n * - Configurable methods, headers, and cache duration\n * - Comprehensive logging for debugging\n *\n * @module core/cors\n */\n\nimport { applyCORSHeaders, applyCORSHeadersSync, shouldApplyCORS } from \"./headers.ts\";\nimport { validateCORSConfig, validateOrigin, validateOriginSync } from \"./validators.ts\";\n\n// Main exports for CORS functionality\nexport { handleCORSPreflight, isPreflightRequest } from \"./preflight.ts\";\nexport {\n applyCORSHeaders,\n applyCORSHeadersSync,\n shouldApplyCORS,\n validateCORSConfig,\n validateOrigin,\n validateOriginSync,\n};\nexport { cors, corsSimple } from \"./middleware.ts\";\n\n// Type exports\nexport type {\n CORSConfig,\n CORSHeaderOptions,\n CORSPreflightOptions,\n CORSValidationResult,\n OriginValidator,\n} from \"./types.ts\";\n\n// Constant exports (excluding DEV_LOCALHOST_ORIGINS to avoid conflict with config/network-defaults)\nexport {\n DEFAULT_HEADERS,\n DEFAULT_MAX_AGE,\n DEFAULT_METHODS,\n HTTP_FORBIDDEN,\n HTTP_NO_CONTENT,\n isProductionMode,\n} from \"./constants.ts\";\n", "/**\n * CORS Headers\n * Functions for applying CORS headers to responses\n *\n * @module core/cors/headers\n */\n\nimport type { CORSConfig, CORSHeaderOptions } from \"./types.ts\";\nimport { validateOrigin, validateOriginSync } from \"./validators.ts\";\n\n/**\n * Apply CORS headers to a response or headers object\n * Adds appropriate CORS headers based on configuration\n *\n * @param options - Header application options\n * @returns New Response with CORS headers or modified Headers object\n */\nexport async function applyCORSHeaders(options: CORSHeaderOptions): Promise<Response | void> {\n const { request, response, headers: headersObj, config } = options;\n\n // Validate origin\n const validation = await validateOrigin(request.headers.get(\"origin\"), config);\n\n // No CORS headers if origin not allowed\n if (!validation.allowedOrigin) {\n return response;\n }\n\n // Determine which headers object to modify\n const headers = headersObj || (response ? new Headers(response.headers) : new Headers());\n\n // Set allowed origin\n headers.set(\"Access-Control-Allow-Origin\", validation.allowedOrigin);\n\n // Add Vary header for non-wildcard origins\n if (validation.allowedOrigin !== \"*\") {\n const existingVary = headers.get(\"Vary\");\n const varyValues = existingVary ? existingVary.split(\",\").map((v) => v.trim()) : [];\n if (!varyValues.includes(\"Origin\")) {\n varyValues.push(\"Origin\");\n headers.set(\"Vary\", varyValues.join(\", \"));\n }\n }\n\n // Add credentials if allowed\n if (validation.allowCredentials && validation.allowedOrigin !== \"*\") {\n headers.set(\"Access-Control-Allow-Credentials\", \"true\");\n }\n\n // Add exposed headers if configured\n const corsConfig = typeof config === \"object\" ? config : null;\n if (corsConfig?.exposedHeaders && corsConfig.exposedHeaders.length > 0) {\n headers.set(\"Access-Control-Expose-Headers\", corsConfig.exposedHeaders.join(\", \"));\n }\n\n // If modifying an existing response, return new response with updated headers\n if (response) {\n return new Response(response.body, {\n status: response.status,\n statusText: response.statusText,\n headers,\n });\n }\n\n // If only modifying headers object, changes are made in place\n return;\n}\n\n/**\n * Synchronous variant of applyCORSHeaders for contexts that require\n * immediate execution (e.g., fluent builder chains). Async origin validators\n * are not supported and will be ignored.\n */\nexport function applyCORSHeadersSync(options: CORSHeaderOptions): Response | void {\n const { request, response, headers: headersObj, config } = options;\n const validation = validateOriginSync(request.headers.get(\"origin\"), config);\n\n if (!validation.allowedOrigin) {\n return response;\n }\n\n const headers = headersObj || (response ? new Headers(response.headers) : new Headers());\n\n headers.set(\"Access-Control-Allow-Origin\", validation.allowedOrigin);\n\n if (validation.allowedOrigin !== \"*\") {\n const existingVary = headers.get(\"Vary\");\n const varyValues = existingVary ? existingVary.split(\",\").map((v) => v.trim()) : [];\n if (!varyValues.includes(\"Origin\")) {\n varyValues.push(\"Origin\");\n headers.set(\"Vary\", varyValues.join(\", \"));\n }\n }\n\n if (validation.allowCredentials && validation.allowedOrigin !== \"*\") {\n headers.set(\"Access-Control-Allow-Credentials\", \"true\");\n }\n\n const corsConfig = typeof config === \"object\" ? config : null;\n if (corsConfig?.exposedHeaders && corsConfig.exposedHeaders.length > 0) {\n headers.set(\"Access-Control-Expose-Headers\", corsConfig.exposedHeaders.join(\", \"));\n }\n\n if (response) {\n return new Response(response.body, {\n status: response.status,\n statusText: response.statusText,\n headers,\n });\n }\n\n return;\n}\n\n/**\n * Determine if CORS headers should be applied\n * Quick check without full validation\n *\n * @param request - The incoming request\n * @param config - CORS configuration\n * @returns True if CORS headers should be added\n */\nexport function shouldApplyCORS(request: Request, config?: boolean | CORSConfig): boolean {\n // No config = no CORS\n if (!config) {\n return false;\n }\n\n // Boolean true = always apply\n if (config === true) {\n return true;\n }\n\n // Check if origin header is present\n const origin = request.headers.get(\"origin\");\n if (!origin) {\n // No origin header - only apply for wildcard\n return config.origin === \"*\";\n }\n\n // Has origin and config - will validate in applyCORSHeaders\n return true;\n}\n", "/**\n * CORS Validators\n * Origin validation logic for CORS handling\n *\n * @module core/cors/validators\n */\n\nimport type { CORSConfig, CORSValidationResult } from \"./types.ts\";\nimport { serverLogger } from \"@veryfront/utils/logger/logger.ts\";\nimport { recordCorsRejection } from \"@veryfront/observability\";\n\n/**\n * Validate origin against CORS configuration\n * Returns the allowed origin or null if not allowed\n *\n * This is the main validation entry point that coordinates\n * all origin validation strategies.\n *\n * @param requestOrigin - The origin from the request header\n * @param config - CORS configuration\n * @returns Validation result with allowed origin and credentials\n */\nexport async function validateOrigin(\n requestOrigin: string | null,\n config?: boolean | CORSConfig,\n): Promise<CORSValidationResult> {\n // Secure by default: no CORS without explicit configuration\n if (!config) {\n return { allowedOrigin: null, allowCredentials: false };\n }\n\n // Simple boolean true = allow all origins\n if (config === true) {\n const origin = requestOrigin || \"*\";\n return { allowedOrigin: origin, allowCredentials: false };\n }\n\n // Object configuration\n const corsConfig = config as CORSConfig;\n\n // No origin configuration = no CORS\n if (!corsConfig.origin) {\n return { allowedOrigin: null, allowCredentials: false };\n }\n\n // No origin header (same-origin request or non-browser client)\n if (!requestOrigin) {\n // For wildcard, return wildcard even without origin header\n if (corsConfig.origin === \"*\") {\n return { allowedOrigin: \"*\", allowCredentials: false };\n }\n // For other configurations, no CORS headers for missing origin\n return { allowedOrigin: null, allowCredentials: false };\n }\n\n // Wildcard origin\n if (corsConfig.origin === \"*\") {\n // Security: Cannot use credentials with wildcard\n if (corsConfig.credentials) {\n serverLogger.warn(\"[CORS] Cannot use credentials with wildcard origin - denying\");\n return {\n allowedOrigin: null,\n allowCredentials: false,\n error: \"Cannot use credentials with wildcard origin\",\n };\n }\n return { allowedOrigin: \"*\", allowCredentials: false };\n }\n\n // Function-based validation\n if (typeof corsConfig.origin === \"function\") {\n try {\n const result = await corsConfig.origin(requestOrigin);\n\n // Function returned specific origin string\n if (typeof result === \"string\") {\n return {\n allowedOrigin: result,\n allowCredentials: corsConfig.credentials ?? false,\n };\n }\n\n // Function returned boolean\n const allowed = result === true;\n return {\n allowedOrigin: allowed ? requestOrigin : null,\n allowCredentials: allowed && (corsConfig.credentials ?? false),\n error: allowed ? undefined : \"Origin rejected by validation function\",\n };\n } catch (error) {\n serverLogger.error(\"[CORS] Origin validation function error\", error);\n return {\n allowedOrigin: null,\n allowCredentials: false,\n error: \"Origin validation error\",\n };\n }\n }\n\n // Array of allowed origins\n if (Array.isArray(corsConfig.origin)) {\n const allowed = corsConfig.origin.includes(requestOrigin);\n if (!allowed) {\n recordCorsRejection();\n serverLogger.warn(\"[CORS] Origin not in allowlist\", {\n requestOrigin,\n allowedOrigins: corsConfig.origin,\n });\n }\n return {\n allowedOrigin: allowed ? requestOrigin : null,\n allowCredentials: allowed && (corsConfig.credentials ?? false),\n error: allowed ? undefined : \"Origin not in allowlist\",\n };\n }\n\n // Single origin string\n if (typeof corsConfig.origin === \"string\") {\n const allowed = corsConfig.origin === requestOrigin;\n if (!allowed) {\n recordCorsRejection();\n serverLogger.warn(\"[CORS] Origin does not match\", {\n requestOrigin,\n expectedOrigin: corsConfig.origin,\n });\n }\n return {\n allowedOrigin: allowed ? requestOrigin : null,\n allowCredentials: allowed && (corsConfig.credentials ?? false),\n error: allowed ? undefined : \"Origin does not match\",\n };\n }\n\n // Should never reach here\n return {\n allowedOrigin: null,\n allowCredentials: false,\n error: \"Invalid origin configuration\",\n };\n}\n\n/**\n * Synchronous origin validation helper for environments that require\n * immediate header evaluation (e.g., fluent response builders).\n * Async origin validators are NOT supported here.\n */\nexport function validateOriginSync(\n requestOrigin: string | null,\n config?: boolean | CORSConfig,\n): CORSValidationResult {\n if (!config) {\n return { allowedOrigin: null, allowCredentials: false };\n }\n\n if (config === true) {\n const origin = requestOrigin || \"*\";\n return { allowedOrigin: origin, allowCredentials: false };\n }\n\n const corsConfig = config as CORSConfig;\n\n if (!corsConfig.origin) {\n return { allowedOrigin: null, allowCredentials: false };\n }\n\n if (!requestOrigin) {\n if (corsConfig.origin === \"*\") {\n return { allowedOrigin: \"*\", allowCredentials: false };\n }\n return { allowedOrigin: null, allowCredentials: false };\n }\n\n if (corsConfig.origin === \"*\") {\n if (corsConfig.credentials) {\n serverLogger.warn(\"[CORS] Cannot use credentials with wildcard origin - denying\");\n return {\n allowedOrigin: null,\n allowCredentials: false,\n error: \"Cannot use credentials with wildcard origin\",\n };\n }\n return { allowedOrigin: \"*\", allowCredentials: false };\n }\n\n if (typeof corsConfig.origin === \"function\") {\n try {\n const result = corsConfig.origin(requestOrigin);\n if (result instanceof Promise) {\n serverLogger.warn(\n \"[CORS] Async origin validators are not supported in synchronous contexts\",\n );\n return {\n allowedOrigin: null,\n allowCredentials: false,\n error: \"Async origin validators not supported\",\n };\n }\n if (typeof result === \"string\") {\n return {\n allowedOrigin: result,\n allowCredentials: corsConfig.credentials ?? false,\n };\n }\n const allowed = result === true;\n return {\n allowedOrigin: allowed ? requestOrigin : null,\n allowCredentials: allowed && (corsConfig.credentials ?? false),\n error: allowed ? undefined : \"Origin rejected by validation function\",\n };\n } catch (error) {\n serverLogger.error(\"[CORS] Origin validation function error\", error);\n return {\n allowedOrigin: null,\n allowCredentials: false,\n error: \"Origin validation error\",\n };\n }\n }\n\n if (Array.isArray(corsConfig.origin)) {\n const allowed = corsConfig.origin.includes(requestOrigin);\n if (!allowed) {\n recordCorsRejection();\n serverLogger.warn(\"[CORS] Origin not in allowlist (sync)\", {\n requestOrigin,\n allowedOrigins: corsConfig.origin,\n });\n }\n return {\n allowedOrigin: allowed ? requestOrigin : null,\n allowCredentials: allowed && (corsConfig.credentials ?? false),\n error: allowed ? undefined : \"Origin not in allowlist\",\n };\n }\n\n if (typeof corsConfig.origin === \"string\") {\n const allowed = corsConfig.origin === requestOrigin;\n if (!allowed) {\n recordCorsRejection();\n serverLogger.warn(\"[CORS] Origin does not match (sync)\", {\n requestOrigin,\n expectedOrigin: corsConfig.origin,\n });\n }\n return {\n allowedOrigin: allowed ? requestOrigin : null,\n allowCredentials: allowed && (corsConfig.credentials ?? false),\n error: allowed ? undefined : \"Origin does not match\",\n };\n }\n\n return {\n allowedOrigin: null,\n allowCredentials: false,\n error: \"Invalid origin configuration\",\n };\n}\n\n/**\n * Validate CORS configuration for security issues\n * Prevents dangerous combinations\n *\n * @param config - CORS configuration to validate\n * @returns Validation result with error if invalid\n */\nexport function validateCORSConfig(config?: boolean | CORSConfig): {\n valid: boolean;\n error?: string;\n} {\n if (!config || config === true) {\n return { valid: true };\n }\n\n const corsConfig = config as CORSConfig;\n\n // Cannot use credentials with wildcard origin\n if (corsConfig.origin === \"*\" && corsConfig.credentials) {\n return {\n valid: false,\n error: \"Cannot use credentials with wildcard origin (*)\",\n };\n }\n\n // Validate methods array if provided\n if (corsConfig.methods && corsConfig.methods.length === 0) {\n return {\n valid: false,\n error: \"methods array cannot be empty\",\n };\n }\n\n // Validate headers arrays\n if (corsConfig.allowedHeaders && corsConfig.allowedHeaders.length === 0) {\n return {\n valid: false,\n error: \"allowedHeaders array cannot be empty\",\n };\n }\n\n if (corsConfig.exposedHeaders && corsConfig.exposedHeaders.length === 0) {\n return {\n valid: false,\n error: \"exposedHeaders array cannot be empty\",\n };\n }\n\n // Validate maxAge is positive\n if (corsConfig.maxAge !== undefined && corsConfig.maxAge < 0) {\n return {\n valid: false,\n error: \"maxAge must be a positive number\",\n };\n }\n\n return { valid: true };\n}\n", "/**\n * Veryfront Observability\n *\n * Comprehensive OpenTelemetry integration for distributed tracing and metrics\n */\n\n// Export tracing utilities\nexport {\n addSpanEvent,\n createChildSpan,\n endSpan,\n extractContext,\n getActiveContext,\n initTracing,\n injectContext,\n isTracingEnabled,\n setSpanAttributes,\n shutdownTracing,\n SpanNames,\n type SpanOptions,\n startSpan,\n type TracingConfig,\n withActiveSpan,\n withSpan,\n withSpanSync,\n} from \"./tracing/index.ts\";\n\n// Export metrics utilities\nexport {\n getMetricsState,\n initMetrics,\n isMetricsEnabled,\n type MetricsConfig,\n recordBuild,\n recordBundle,\n recordCacheGet,\n recordCacheInvalidate,\n recordCacheSet,\n recordCorsRejection,\n recordDataFetch,\n recordDataFetchError,\n recordHttpRequest,\n recordHttpRequestComplete,\n recordRender,\n recordRenderError,\n recordRSCError,\n recordRSCRender,\n recordRSCRequest,\n recordRSCStream,\n recordSecurityHeaders,\n setCacheSize,\n shutdownMetrics,\n} from \"./metrics/index.ts\";\n\nexport {\n type AutoInstrumentConfig,\n initAutoInstrumentation,\n instrument,\n instrumentBatch,\n instrumentErrorHandler,\n instrumentFetch,\n instrumentHttpHandler,\n instrumentReactRender,\n instrumentSync,\n isAutoInstrumentEnabled,\n} from \"./auto-instrument/index.ts\";\n", "import type { RuntimeAdapter } from \"@veryfront/platform/adapters/base.ts\";\nimport { tracingManager } from \"./manager.ts\";\nimport type { Context, Span, SpanOptions, TracingConfig } from \"./types.ts\";\n\nexport type { Context, Span, SpanOptions, TracingConfig } from \"./types.ts\";\nexport { loadConfig } from \"./config.ts\";\nexport { SpanOperations } from \"./span-operations.ts\";\nexport { ContextPropagation } from \"./context-propagation.ts\";\nexport { SpanNames } from \"./span-names.ts\";\n\nexport async function initTracing(\n config: Partial<TracingConfig> = {},\n adapter?: RuntimeAdapter,\n): Promise<void> {\n await tracingManager.initialize(config, adapter);\n}\n\nexport function isTracingEnabled(): boolean {\n return tracingManager.isEnabled();\n}\n\nexport function shutdownTracing(): void {\n tracingManager.shutdown();\n}\n\nexport function getTracingState() {\n return tracingManager.getState();\n}\n\nconst getSpanOps = () => tracingManager.getSpanOperations();\nconst getContextProp = () => tracingManager.getContextPropagation();\n\nexport function startSpan(name: string, options: SpanOptions = {}): Span | null {\n return getSpanOps()?.startSpan(name, options) ?? null;\n}\n\nexport function endSpan(span: Span | null, error?: Error): void {\n getSpanOps()?.endSpan(span, error);\n}\n\nexport function setSpanAttributes(\n span: Span | null,\n attributes: Record<string, string | number | boolean>,\n): void {\n getSpanOps()?.setAttributes(span, attributes);\n}\n\nexport function addSpanEvent(\n span: Span | null,\n name: string,\n attributes?: Record<string, string | number | boolean>,\n): void {\n getSpanOps()?.addEvent(span, name, attributes);\n}\n\nexport function createChildSpan(\n parentSpan: Span | null,\n name: string,\n options: SpanOptions = {},\n): Span | null {\n return getSpanOps()?.createChildSpan(parentSpan, name, options) ?? null;\n}\n\nexport function extractContext(headers: Headers): Context | undefined {\n return getContextProp()?.extractContext(headers);\n}\n\nexport function injectContext(context: Context, headers: Headers): void {\n getContextProp()?.injectContext(context, headers);\n}\n\nexport function getActiveContext(): Context | undefined {\n return getContextProp()?.getActiveContext();\n}\n\nexport async function withActiveSpan<T>(span: Span | null, fn: () => Promise<T>): Promise<T> {\n const contextProp = getContextProp();\n if (!contextProp) return await fn();\n return await contextProp.withActiveSpan(span, fn);\n}\n\nexport async function withSpan<T>(\n name: string,\n fn: (span: Span | null) => Promise<T>,\n options: SpanOptions = {},\n): Promise<T> {\n const contextProp = getContextProp();\n const spanOps = getSpanOps();\n\n if (!contextProp || !spanOps) return await fn(null);\n\n return await contextProp.withSpanAsync(\n name,\n fn,\n (n) => spanOps.startSpan(n, options),\n (s, e) => spanOps.endSpan(s, e),\n );\n}\n\nexport function withSpanSync<T>(\n name: string,\n fn: (span: Span | null) => T,\n options: SpanOptions = {},\n): T {\n const contextProp = getContextProp();\n const spanOps = getSpanOps();\n\n if (!contextProp || !spanOps) return fn(null);\n\n return contextProp.withSpan(\n name,\n fn,\n (n) => spanOps.startSpan(n, options),\n (s, e) => spanOps.endSpan(s, e),\n );\n}\n\nexport { tracingManager } from \"./manager.ts\";\n", "import { serverLogger as logger } from \"@veryfront/utils\";\nimport type { RuntimeAdapter } from \"@veryfront/platform/adapters/base.ts\";\nimport type { OpenTelemetryAPI, TracingConfig, TracingState } from \"./types.ts\";\nimport { loadConfig } from \"./config.ts\";\nimport { SpanOperations } from \"./span-operations.ts\";\nimport { ContextPropagation } from \"./context-propagation.ts\";\n\nclass TracingManager {\n private state: TracingState = {\n initialized: false,\n tracer: null,\n api: null,\n propagator: null,\n };\n\n private spanOps: SpanOperations | null = null;\n private contextProp: ContextPropagation | null = null;\n\n async initialize(config: Partial<TracingConfig> = {}, adapter?: RuntimeAdapter): Promise<void> {\n if (this.state.initialized) {\n logger.debug(\"[tracing] Already initialized\");\n return;\n }\n\n const finalConfig = loadConfig(config, adapter);\n\n if (!finalConfig.enabled) {\n logger.debug(\"[tracing] Tracing disabled\");\n this.state.initialized = true;\n return;\n }\n\n try {\n await this.initializeTracer(finalConfig);\n this.state.initialized = true;\n\n logger.info(\"[tracing] OpenTelemetry tracing initialized\", {\n exporter: finalConfig.exporter,\n serviceName: finalConfig.serviceName,\n endpoint: finalConfig.endpoint,\n });\n } catch (error) {\n logger.warn(\"[tracing] Failed to initialize OpenTelemetry tracing\", error);\n this.state.initialized = true;\n }\n }\n\n private async initializeTracer(config: TracingConfig): Promise<void> {\n const api = await import(\"@opentelemetry/api\") as OpenTelemetryAPI;\n this.state.api = api;\n\n this.state.tracer = api.trace.getTracer(config.serviceName || \"veryfront\", \"0.1.0\");\n\n const { W3CTraceContextPropagator } = await import(\"@opentelemetry/core\");\n const propagator = new W3CTraceContextPropagator();\n this.state.propagator = propagator;\n api.propagation.setGlobalPropagator(propagator);\n\n if (this.state.api && this.state.tracer) {\n this.spanOps = new SpanOperations(this.state.api, this.state.tracer);\n }\n\n if (this.state.api && this.state.propagator) {\n this.contextProp = new ContextPropagation(this.state.api, this.state.propagator);\n }\n }\n\n isEnabled(): boolean {\n return this.state.initialized && this.state.tracer !== null;\n }\n\n getSpanOperations(): SpanOperations | null {\n return this.spanOps;\n }\n\n getContextPropagation(): ContextPropagation | null {\n return this.contextProp;\n }\n\n getState(): TracingState {\n return this.state;\n }\n\n shutdown(): void {\n if (!this.state.initialized) return;\n\n try {\n logger.info(\"[tracing] Tracing shutdown initiated\");\n } catch (error) {\n logger.warn(\"[tracing] Error during tracing shutdown\", error);\n }\n }\n}\n\nexport const tracingManager = new TracingManager();\n", "import type { RuntimeAdapter } from \"@veryfront/platform/adapters/base.ts\";\nimport type { TracingConfig } from \"./types.ts\";\nimport { getEnv } from \"../../platform/compat/process.ts\";\n\nconst DEFAULT_CONFIG: TracingConfig = {\n enabled: false,\n exporter: \"console\",\n serviceName: \"veryfront\",\n sampleRate: 1.0,\n debug: false,\n};\n\nexport function loadConfig(\n config: Partial<TracingConfig> = {},\n adapter?: RuntimeAdapter,\n): TracingConfig {\n const finalConfig = { ...DEFAULT_CONFIG, ...config };\n\n if (adapter?.env) {\n applyEnvFromAdapter(finalConfig, adapter.env);\n } else {\n applyEnvFromDeno(finalConfig);\n }\n\n return finalConfig;\n}\n\nfunction applyEnvFromAdapter(\n config: TracingConfig,\n envAdapter: RuntimeAdapter[\"env\"],\n): void {\n if (!envAdapter) return;\n\n const otelEnabled = envAdapter.get(\"OTEL_TRACES_ENABLED\");\n const veryfrontOtel = envAdapter.get(\"VERYFRONT_OTEL\");\n const serviceName = envAdapter.get(\"OTEL_SERVICE_NAME\");\n\n config.enabled = otelEnabled === \"true\" ||\n veryfrontOtel === \"1\" ||\n config.enabled;\n\n if (serviceName) config.serviceName = serviceName;\n\n const otlpEndpoint = envAdapter.get(\"OTEL_EXPORTER_OTLP_ENDPOINT\");\n const tracesEndpoint = envAdapter.get(\"OTEL_EXPORTER_OTLP_TRACES_ENDPOINT\");\n config.endpoint = otlpEndpoint || tracesEndpoint || config.endpoint;\n\n const exporterType = envAdapter.get(\"OTEL_TRACES_EXPORTER\");\n if (isValidExporter(exporterType)) {\n config.exporter = exporterType;\n }\n}\n\nfunction applyEnvFromDeno(config: TracingConfig): void {\n try {\n // Use platform abstraction for cross-platform env access\n config.enabled = getEnv(\"OTEL_TRACES_ENABLED\") === \"true\" ||\n getEnv(\"VERYFRONT_OTEL\") === \"1\" ||\n config.enabled;\n\n config.serviceName = getEnv(\"OTEL_SERVICE_NAME\") || config.serviceName;\n config.endpoint = getEnv(\"OTEL_EXPORTER_OTLP_ENDPOINT\") ||\n getEnv(\"OTEL_EXPORTER_OTLP_TRACES_ENDPOINT\") ||\n config.endpoint;\n\n const exporterType = getEnv(\"OTEL_TRACES_EXPORTER\");\n if (isValidExporter(exporterType)) {\n config.exporter = exporterType;\n }\n } catch {\n // Environment access may fail in some runtimes\n }\n}\n\nfunction isValidExporter(value: string | undefined): value is TracingConfig[\"exporter\"] {\n return value === \"jaeger\" || value === \"zipkin\" || value === \"otlp\" || value === \"console\";\n}\n", "import { serverLogger as logger } from \"@veryfront/utils\";\nimport type { Span, SpanKind } from \"./types.ts\";\nimport type { OpenTelemetryAPI, SpanOptions } from \"./types.ts\";\n\nexport class SpanOperations {\n constructor(\n private api: OpenTelemetryAPI,\n private tracer: import(\"./types.ts\").Tracer,\n ) {}\n\n startSpan(name: string, options: SpanOptions = {}): Span | null {\n try {\n const spanKind = this.mapSpanKind(options.kind);\n\n const span = this.tracer.startSpan(name, {\n kind: spanKind,\n attributes: options.attributes || {},\n }, options.parent as import(\"./types.ts\").Context | undefined);\n\n return span;\n } catch (error) {\n logger.debug(\"[tracing] Failed to start span\", { name, error });\n return null;\n }\n }\n\n endSpan(span: Span | null, error?: Error): void {\n if (!span) return;\n\n try {\n if (error) {\n span.recordException(error);\n span.setStatus({\n code: this.api.SpanStatusCode.ERROR,\n message: error.message,\n });\n } else {\n span.setStatus({ code: this.api.SpanStatusCode.OK });\n }\n span.end();\n } catch (err) {\n logger.debug(\"[tracing] Failed to end span\", err);\n }\n }\n\n setAttributes(span: Span | null, attributes: Record<string, string | number | boolean>): void {\n if (!span) return;\n\n try {\n span.setAttributes(attributes);\n } catch (error) {\n logger.debug(\"[tracing] Failed to set span attributes\", error);\n }\n }\n\n addEvent(\n span: Span | null,\n name: string,\n attributes?: Record<string, string | number | boolean>,\n ): void {\n if (!span) return;\n\n try {\n span.addEvent(name, attributes);\n } catch (error) {\n logger.debug(\"[tracing] Failed to add span event\", error);\n }\n }\n\n createChildSpan(parentSpan: Span | null, name: string, options: SpanOptions = {}): Span | null {\n if (!parentSpan) return this.startSpan(name, options);\n\n try {\n const parentContext = this.api.trace.setSpan(this.api.context.active(), parentSpan);\n return this.startSpan(name, { ...options, parent: parentContext });\n } catch (error) {\n logger.debug(\"[tracing] Failed to create child span\", error);\n return null;\n }\n }\n\n private mapSpanKind(kind?: SpanOptions[\"kind\"]): SpanKind {\n if (!kind) return this.api.SpanKind.INTERNAL;\n\n const kindMap: Record<string, SpanKind> = {\n \"internal\": this.api.SpanKind.INTERNAL,\n \"server\": this.api.SpanKind.SERVER,\n \"client\": this.api.SpanKind.CLIENT,\n \"producer\": this.api.SpanKind.PRODUCER,\n \"consumer\": this.api.SpanKind.CONSUMER,\n };\n\n return kindMap[kind.toLowerCase()] || this.api.SpanKind.INTERNAL;\n }\n}\n", "import { serverLogger as logger } from \"@veryfront/utils\";\nimport type { Context, OpenTelemetryAPI, Span, TextMapPropagator } from \"./types.ts\";\n\nexport class ContextPropagation {\n constructor(\n private api: OpenTelemetryAPI,\n private propagator: TextMapPropagator,\n ) {}\n\n extractContext(headers: Headers): Context | undefined {\n try {\n const carrier: Record<string, string> = {};\n headers.forEach((value, key) => {\n carrier[key] = value;\n });\n\n return this.api.propagation.extract(this.api.context.active(), carrier);\n } catch (error) {\n logger.debug(\"[tracing] Failed to extract context from headers\", error);\n return undefined;\n }\n }\n\n injectContext(context: Context, headers: Headers): void {\n try {\n const carrier: Record<string, string> = {};\n this.api.propagation.inject(context, carrier);\n\n for (const [key, value] of Object.entries(carrier)) {\n headers.set(key, value);\n }\n } catch (error) {\n logger.debug(\"[tracing] Failed to inject context into headers\", error);\n }\n }\n\n getActiveContext(): Context | undefined {\n try {\n return this.api.context.active();\n } catch (error) {\n logger.debug(\"[tracing] Failed to get active context\", error);\n return undefined;\n }\n }\n\n async withActiveSpan<T>(span: Span | null, fn: () => Promise<T>): Promise<T> {\n if (!span) return await fn();\n\n return await this.api.context.with(\n this.api.trace.setSpan(this.api.context.active(), span),\n fn,\n );\n }\n\n withSpan<T>(\n name: string,\n fn: (span: Span | null) => T,\n startSpan: (name: string) => Span | null,\n endSpan: (span: Span | null, error?: Error) => void,\n ): T {\n const span = startSpan(name);\n\n try {\n const result = fn(span);\n endSpan(span);\n return result;\n } catch (error) {\n endSpan(span, error as Error);\n throw error;\n }\n }\n\n async withSpanAsync<T>(\n name: string,\n fn: (span: Span | null) => Promise<T>,\n startSpan: (name: string) => Span | null,\n endSpan: (span: Span | null, error?: Error) => void,\n ): Promise<T> {\n const span = startSpan(name);\n\n try {\n const result = await fn(span);\n endSpan(span);\n return result;\n } catch (error) {\n endSpan(span, error as Error);\n throw error;\n }\n }\n}\n", "export const SpanNames = {\n HTTP_REQUEST: \"http.request\",\n HTTP_HANDLER: \"http.handler\",\n\n RENDER_PAGE: \"render.page\",\n RENDER_COMPONENT: \"render.component\",\n RENDER_LAYOUT: \"render.layout\",\n RENDER_SSR: \"render.ssr\",\n RENDER_RSC: \"render.rsc\",\n\n DATA_FETCH: \"data.fetch\",\n DATA_CACHE_GET: \"data.cache.get\",\n DATA_CACHE_SET: \"data.cache.set\",\n\n BUILD_BUNDLE: \"build.bundle\",\n BUILD_SPLIT: \"build.split\",\n BUILD_OPTIMIZE: \"build.optimize\",\n BUILD_COMPILE: \"build.compile\",\n\n RSC_RENDER: \"rsc.render\",\n RSC_SERIALIZE: \"rsc.serialize\",\n RSC_STREAM: \"rsc.stream\",\n\n ROUTER_MATCH: \"router.match\",\n ROUTER_RESOLVE: \"router.resolve\",\n} as const;\n", "/**\n * OpenTelemetry Metrics - Public API\n *\n * Comprehensive OpenTelemetry integration for Veryfront:\n * - Custom metrics: request count, latency, cache hits\n * - Histogram buckets for latency distribution\n * - Gauges for active connections, memory usage\n * - Export to Prometheus, CloudWatch, OTLP, etc.\n */\n\nimport type { RuntimeAdapter } from \"@veryfront/platform/adapters/base.ts\";\nimport { metricsManager } from \"./manager.ts\";\n\n// Re-export types\nexport type { MemoryUsage, MetricsConfig } from \"./types.ts\";\n\n// Re-export utilities (for advanced usage)\nexport { getMemoryUsage, loadConfig } from \"./config.ts\";\n// Removed: deleted module - export { initializeInstruments } from \"./instruments.ts\";\nexport { MetricsRecorder } from \"./recorder.ts\";\n\n/**\n * Initialize OpenTelemetry metrics\n */\nexport async function initMetrics(\n config: Parameters<typeof metricsManager.initialize>[0] = {},\n adapter?: RuntimeAdapter,\n): Promise<void> {\n await metricsManager.initialize(config, adapter);\n}\n\n/**\n * Check if metrics collection is enabled\n */\nexport function isMetricsEnabled(): boolean {\n return metricsManager.isEnabled();\n}\n\n/**\n * Shutdown metrics (for graceful shutdown)\n */\nexport async function shutdownMetrics(): Promise<void> {\n await metricsManager.shutdown();\n}\n\n/**\n * Export runtime state for testing/debugging\n */\nexport function getMetricsState() {\n return metricsManager.getState();\n}\n\n// Convenience API - delegates to recorder\nconst getRecorder = () => metricsManager.getRecorder();\n\n// HTTP Metrics API\nexport function recordHttpRequest(attributes?: Record<string, string>): void {\n getRecorder()?.recordHttpRequest(attributes);\n}\n\nexport function recordHttpRequestComplete(\n durationMs: number,\n attributes?: Record<string, string>,\n): void {\n getRecorder()?.recordHttpRequestComplete(durationMs, attributes);\n}\n\n// Cache Metrics API\nexport function recordCacheGet(\n hit: boolean,\n attributes?: Record<string, string>,\n): void {\n getRecorder()?.recordCacheGet(hit, attributes);\n}\n\nexport function recordCacheSet(attributes?: Record<string, string>): void {\n getRecorder()?.recordCacheSet(attributes);\n}\n\nexport function recordCacheInvalidate(\n count: number,\n attributes?: Record<string, string>,\n): void {\n getRecorder()?.recordCacheInvalidate(count, attributes);\n}\n\nexport function setCacheSize(size: number): void {\n getRecorder()?.setCacheSize(size);\n}\n\n// Render Metrics API\nexport function recordRender(\n durationMs: number,\n attributes?: Record<string, string>,\n): void {\n getRecorder()?.recordRender(durationMs, attributes);\n}\n\nexport function recordRenderError(attributes?: Record<string, string>): void {\n getRecorder()?.recordRenderError(attributes);\n}\n\n// RSC Metrics API\nexport function recordRSCRender(\n durationMs: number,\n attributes?: Record<string, string>,\n): void {\n getRecorder()?.recordRSCRender(durationMs, attributes);\n}\n\nexport function recordRSCStream(\n durationMs: number,\n attributes?: Record<string, string>,\n): void {\n getRecorder()?.recordRSCStream(durationMs, attributes);\n}\n\nexport function recordRSCRequest(\n type: \"manifest\" | \"page\" | \"stream\" | \"action\",\n attributes?: Record<string, string>,\n): void {\n getRecorder()?.recordRSCRequest(type, attributes);\n}\n\nexport function recordRSCError(attributes?: Record<string, string>): void {\n getRecorder()?.recordRSCError(attributes);\n}\n\n// Build Metrics API\nexport function recordBuild(\n durationMs: number,\n attributes?: Record<string, string>,\n): void {\n getRecorder()?.recordBuild(durationMs, attributes);\n}\n\nexport function recordBundle(\n sizeKb: number,\n attributes?: Record<string, string>,\n): void {\n getRecorder()?.recordBundle(sizeKb, attributes);\n}\n\n// Data Fetching Metrics API\nexport function recordDataFetch(\n durationMs: number,\n attributes?: Record<string, string>,\n): void {\n getRecorder()?.recordDataFetch(durationMs, attributes);\n}\n\nexport function recordDataFetchError(\n attributes?: Record<string, string>,\n): void {\n getRecorder()?.recordDataFetchError(attributes);\n}\n\n// Security Metrics API\nexport function recordCorsRejection(attributes?: Record<string, string>): void {\n getRecorder()?.recordCorsRejection?.(attributes);\n}\n\nexport function recordSecurityHeaders(attributes?: Record<string, string>): void {\n getRecorder()?.recordSecurityHeaders?.(attributes);\n}\n\n// Export singleton for advanced usage\nexport { metricsManager } from \"./manager.ts\";\n", "/**\n * Metrics Manager\n * Main OpenTelemetry metrics initialization and management\n */\n\nimport type { Meter } from \"@opentelemetry/api\";\nimport { serverLogger as logger } from \"@veryfront/utils\";\nimport type { RuntimeAdapter } from \"@veryfront/platform/adapters/base.ts\";\nimport { loadConfig } from \"./config.ts\";\nimport { initializeInstruments } from \"../instruments/index.ts\";\nimport { MetricsRecorder } from \"./recorder.ts\";\nimport type { MetricsConfig, MetricsInstruments, OpenTelemetryAPI, RuntimeState } from \"./types.ts\";\n\n/**\n * Metrics manager singleton state\n */\nclass MetricsManager {\n private initialized = false;\n private meter: Meter | null = null;\n private api: OpenTelemetryAPI | null = null;\n private instruments: MetricsInstruments;\n private runtimeState: RuntimeState;\n private recorder: MetricsRecorder | null = null;\n\n constructor() {\n this.instruments = this.createEmptyInstruments();\n this.runtimeState = {\n cacheSize: 0,\n activeRequests: 0,\n };\n // Create recorder immediately so state tracking works even before initialization\n // The recorder gracefully handles null instruments (optional chaining)\n this.recorder = new MetricsRecorder(this.instruments, this.runtimeState);\n }\n\n private createEmptyInstruments(): MetricsInstruments {\n return {\n httpRequestCounter: null,\n httpRequestDuration: null,\n httpActiveRequests: null,\n cacheGetCounter: null,\n cacheHitCounter: null,\n cacheMissCounter: null,\n cacheSetCounter: null,\n cacheInvalidateCounter: null,\n cacheSizeGauge: null,\n renderDuration: null,\n renderCounter: null,\n renderErrorCounter: null,\n rscRenderDuration: null,\n rscStreamDuration: null,\n rscManifestCounter: null,\n rscPageCounter: null,\n rscStreamCounter: null,\n rscActionCounter: null,\n rscErrorCounter: null,\n buildDuration: null,\n bundleSizeHistogram: null,\n bundleCounter: null,\n dataFetchDuration: null,\n dataFetchCounter: null,\n dataFetchErrorCounter: null,\n corsRejectionCounter: null,\n securityHeadersCounter: null,\n memoryUsageGauge: null,\n heapUsageGauge: null,\n };\n }\n\n async initialize(\n config: Partial<MetricsConfig> = {},\n adapter?: RuntimeAdapter,\n ): Promise<void> {\n if (this.initialized) {\n logger.debug(\"[metrics] Already initialized\");\n return;\n }\n\n const finalConfig = loadConfig(config, adapter);\n\n if (!finalConfig.enabled) {\n logger.debug(\"[metrics] Metrics collection disabled\");\n this.initialized = true;\n return;\n }\n\n try {\n // Load OpenTelemetry API\n this.api = await import(\"@opentelemetry/api\");\n\n // Get or create meter\n this.meter = this.api.metrics.getMeter(finalConfig.prefix, \"0.1.0\");\n\n // Initialize all metric instruments\n this.instruments = await initializeInstruments(\n this.meter,\n finalConfig,\n this.runtimeState,\n );\n\n // Update recorder with initialized instruments\n // Recorder was already created in constructor, just update its instruments reference\n if (this.recorder) {\n (this.recorder as any).instruments = this.instruments;\n }\n\n this.initialized = true;\n logger.info(\"[metrics] OpenTelemetry metrics initialized\", {\n exporter: finalConfig.exporter,\n endpoint: finalConfig.endpoint,\n prefix: finalConfig.prefix,\n });\n } catch (error) {\n logger.warn(\"[metrics] Failed to initialize OpenTelemetry metrics\", error);\n this.initialized = true; // Mark as initialized to prevent retry loops\n }\n }\n\n isEnabled(): boolean {\n return this.initialized && this.meter !== null;\n }\n\n getRecorder(): MetricsRecorder | null {\n return this.recorder;\n }\n\n getState() {\n return {\n initialized: this.initialized,\n cacheSize: this.runtimeState.cacheSize,\n activeRequests: this.runtimeState.activeRequests,\n };\n }\n\n shutdown(): void {\n if (!this.initialized) return;\n\n try {\n logger.info(\"[metrics] Metrics shutdown initiated\");\n } catch (error) {\n logger.warn(\"[metrics] Error during metrics shutdown\", error);\n }\n }\n}\n\n// Export singleton instance\nexport const metricsManager = new MetricsManager();\n", "/**\n * Metrics Configuration\n * Configuration loading and defaults for metrics system\n */\n\nimport type { RuntimeAdapter } from \"@veryfront/platform/adapters/base.ts\";\nimport type { MetricsConfig } from \"./types.ts\";\nimport { getEnv } from \"../../platform/compat/process.ts\";\nimport { memoryUsage as platformMemoryUsage } from \"../../platform/compat/process.ts\";\n\n/**\n * Default metrics collect interval in milliseconds (60 seconds)\n * Inlined to avoid circular dependency with @veryfront/config\n */\nconst DEFAULT_METRICS_COLLECT_INTERVAL_MS = 60000;\n\n/**\n * Default metrics configuration\n */\nexport const DEFAULT_CONFIG: MetricsConfig = {\n enabled: false,\n exporter: \"console\",\n prefix: \"veryfront\",\n collectInterval: DEFAULT_METRICS_COLLECT_INTERVAL_MS,\n debug: false,\n};\n\n/**\n * Load metrics configuration from environment and options\n */\nexport function loadConfig(\n config: Partial<MetricsConfig>,\n adapter?: RuntimeAdapter,\n): MetricsConfig {\n const finalConfig = { ...DEFAULT_CONFIG, ...config };\n\n // Check environment variables for configuration\n if (adapter?.env) {\n const envAdapter = adapter.env;\n const otelEnabled = envAdapter.get(\"OTEL_METRICS_ENABLED\");\n const veryfrontOtel = envAdapter.get(\"VERYFRONT_OTEL\");\n\n finalConfig.enabled = otelEnabled === \"true\" ||\n veryfrontOtel === \"1\" ||\n finalConfig.enabled;\n\n const otlpEndpoint = envAdapter.get(\"OTEL_EXPORTER_OTLP_ENDPOINT\");\n const metricsEndpoint = envAdapter.get(\n \"OTEL_EXPORTER_OTLP_METRICS_ENDPOINT\",\n );\n finalConfig.endpoint = otlpEndpoint || metricsEndpoint ||\n finalConfig.endpoint;\n\n const exporterType = envAdapter.get(\"OTEL_METRICS_EXPORTER\");\n if (\n exporterType === \"prometheus\" || exporterType === \"otlp\" ||\n exporterType === \"console\"\n ) {\n finalConfig.exporter = exporterType;\n }\n } else {\n // Fallback to platform getEnv for cross-platform compatibility\n try {\n finalConfig.enabled = getEnv(\"OTEL_METRICS_ENABLED\") === \"true\" ||\n getEnv(\"VERYFRONT_OTEL\") === \"1\" ||\n finalConfig.enabled;\n finalConfig.endpoint = getEnv(\"OTEL_EXPORTER_OTLP_ENDPOINT\") ||\n getEnv(\"OTEL_EXPORTER_OTLP_METRICS_ENDPOINT\") ||\n finalConfig.endpoint;\n const exporterType = getEnv(\"OTEL_METRICS_EXPORTER\");\n if (\n exporterType === \"prometheus\" || exporterType === \"otlp\" ||\n exporterType === \"console\"\n ) {\n finalConfig.exporter = exporterType;\n }\n } catch {\n // getEnv access may fail, silently continue\n }\n }\n\n return finalConfig;\n}\n\n/**\n * Get memory usage from runtime (Deno or Node.js)\n */\nexport function getMemoryUsage(): {\n rss: number;\n heapUsed: number;\n heapTotal: number;\n} | null {\n try {\n // Use platform abstraction for cross-platform compatibility\n return platformMemoryUsage();\n } catch {\n return null;\n }\n}\n", "/**\n * Metrics Instruments Module\n * Barrel exports for all metric instruments\n *\n * @module\n */\n\nexport { initializeInstruments } from \"./instruments-factory.ts\";\nexport type { HttpInstruments } from \"./http-instruments.ts\";\nexport type { CacheInstruments } from \"./cache-instruments.ts\";\nexport type { RenderInstruments } from \"./render-instruments.ts\";\nexport type { RscInstruments } from \"./rsc-instruments.ts\";\nexport type { BuildInstruments } from \"./build-instruments.ts\";\nexport type { DataInstruments } from \"./data-instruments.ts\";\nexport type { MemoryInstruments } from \"./memory-instruments.ts\";\n", "/**\n * Metrics Instruments Factory\n * Main orchestrator for initializing all metric instruments\n *\n * @module\n */\n\nimport type { Meter } from \"@opentelemetry/api\";\nimport { serverLogger as logger } from \"@veryfront/utils\";\nimport type { MetricsConfig, MetricsInstruments, RuntimeState } from \"../metrics/types.ts\";\nimport { createBuildInstruments } from \"./build-instruments.ts\";\nimport { createCacheInstruments } from \"./cache-instruments.ts\";\nimport { createDataInstruments } from \"./data-instruments.ts\";\nimport { createHttpInstruments } from \"./http-instruments.ts\";\nimport { createMemoryInstruments } from \"./memory-instruments.ts\";\nimport { createRenderInstruments } from \"./render-instruments.ts\";\nimport { createRscInstruments } from \"./rsc-instruments.ts\";\n\n/**\n * Initialize all metric instruments\n *\n * This function creates all OpenTelemetry metric instruments organized by category:\n * - HTTP metrics (requests, duration, active requests)\n * - Cache metrics (hits, misses, size)\n * - Render metrics (duration, count, errors)\n * - RSC metrics (render, stream, actions)\n * - Build metrics (duration, bundle size)\n * - Data fetching metrics (duration, count, errors)\n * - Memory metrics (usage, heap)\n *\n * Note: This function is async to maintain backward compatibility with the original API,\n * even though current implementation is synchronous.\n *\n * @param meter - OpenTelemetry meter instance\n * @param config - Metrics configuration\n * @param runtimeState - Runtime state for observable metrics\n * @returns Promise resolving to all metric instruments\n *\n * @example\n * ```ts\n * const instruments = await initializeInstruments(meter, config, runtimeState);\n * instruments.httpRequestCounter?.add(1, { method: \"GET\", status: 200 });\n * ```\n */\nexport function initializeInstruments(\n meter: Meter,\n config: MetricsConfig,\n runtimeState: RuntimeState,\n): Promise<MetricsInstruments> {\n const instruments: MetricsInstruments = {\n httpRequestCounter: null,\n httpRequestDuration: null,\n httpActiveRequests: null,\n cacheGetCounter: null,\n cacheHitCounter: null,\n cacheMissCounter: null,\n cacheSetCounter: null,\n cacheInvalidateCounter: null,\n cacheSizeGauge: null,\n renderDuration: null,\n renderCounter: null,\n renderErrorCounter: null,\n rscRenderDuration: null,\n rscStreamDuration: null,\n rscManifestCounter: null,\n rscPageCounter: null,\n rscStreamCounter: null,\n rscActionCounter: null,\n rscErrorCounter: null,\n buildDuration: null,\n bundleSizeHistogram: null,\n bundleCounter: null,\n dataFetchDuration: null,\n dataFetchCounter: null,\n dataFetchErrorCounter: null,\n corsRejectionCounter: null,\n securityHeadersCounter: null,\n memoryUsageGauge: null,\n heapUsageGauge: null,\n };\n\n try {\n // Create HTTP metrics\n const httpInstruments = createHttpInstruments(meter, config);\n Object.assign(instruments, httpInstruments);\n\n // Create cache metrics\n const cacheInstruments = createCacheInstruments(meter, config, runtimeState);\n Object.assign(instruments, cacheInstruments);\n\n // Create render metrics\n const renderInstruments = createRenderInstruments(meter, config);\n Object.assign(instruments, renderInstruments);\n\n // Create RSC metrics\n const rscInstruments = createRscInstruments(meter, config);\n Object.assign(instruments, rscInstruments);\n\n // Create build metrics\n const buildInstruments = createBuildInstruments(meter, config);\n Object.assign(instruments, buildInstruments);\n\n // Create data fetching metrics\n const dataInstruments = createDataInstruments(meter, config);\n Object.assign(instruments, dataInstruments);\n\n // Create memory metrics\n const memoryInstruments = createMemoryInstruments(meter, config);\n Object.assign(instruments, memoryInstruments);\n } catch (error) {\n logger.warn(\"[metrics] Failed to initialize metric instruments\", error);\n }\n\n return Promise.resolve(instruments);\n}\n", "/**\n * Build Metrics Instruments\n * Creation of build-related metric instruments\n *\n * @module\n */\n\nimport type { Counter, Histogram, Meter } from \"@opentelemetry/api\";\nimport { DURATION_HISTOGRAM_BOUNDARIES_MS, SIZE_HISTOGRAM_BOUNDARIES_KB } from \"@veryfront/config\";\nimport type { MetricsConfig } from \"../metrics/types.ts\";\n\n/**\n * Build metric instruments\n */\nexport interface BuildInstruments {\n buildDuration: Histogram | null;\n bundleSizeHistogram: Histogram | null;\n bundleCounter: Counter | null;\n}\n\n/**\n * Create build metric instruments\n *\n * @param meter - OpenTelemetry meter instance\n * @param config - Metrics configuration\n * @returns Build metric instruments\n *\n * @example\n * ```ts\n * const buildInstruments = createBuildInstruments(meter, config);\n * buildInstruments.bundleCounter?.add(1);\n * ```\n */\nexport function createBuildInstruments(\n meter: Meter,\n config: MetricsConfig,\n): BuildInstruments {\n const buildDuration = meter.createHistogram(\n `${config.prefix}.build.duration`,\n {\n description: \"Build operation duration\",\n unit: \"ms\",\n advice: { explicitBucketBoundaries: DURATION_HISTOGRAM_BOUNDARIES_MS },\n },\n );\n\n const bundleSizeHistogram = meter.createHistogram(\n `${config.prefix}.build.bundle.size`,\n {\n description: \"Bundle size distribution\",\n unit: \"kb\",\n advice: { explicitBucketBoundaries: SIZE_HISTOGRAM_BOUNDARIES_KB },\n },\n );\n\n const bundleCounter = meter.createCounter(\n `${config.prefix}.build.bundles`,\n {\n description: \"Total number of bundles created\",\n unit: \"bundles\",\n },\n );\n\n return {\n buildDuration,\n bundleSizeHistogram,\n bundleCounter,\n };\n}\n", "/**\n * Cache Metrics Instruments\n * Creation of cache-related metric instruments\n *\n * @module\n */\n\nimport type { Counter, Meter, ObservableGauge, ObservableResult } from \"@opentelemetry/api\";\nimport type { MetricsConfig, RuntimeState } from \"../metrics/types.ts\";\n\n/**\n * Cache metric instruments\n */\nexport interface CacheInstruments {\n cacheGetCounter: Counter | null;\n cacheHitCounter: Counter | null;\n cacheMissCounter: Counter | null;\n cacheSetCounter: Counter | null;\n cacheInvalidateCounter: Counter | null;\n cacheSizeGauge: ObservableGauge | null;\n}\n\n/**\n * Create cache metric instruments\n *\n * @param meter - OpenTelemetry meter instance\n * @param config - Metrics configuration\n * @param runtimeState - Runtime state for observable metrics\n * @returns Cache metric instruments\n *\n * @example\n * ```ts\n * const cacheInstruments = createCacheInstruments(meter, config, runtimeState);\n * cacheInstruments.cacheHitCounter?.add(1);\n * ```\n */\nexport function createCacheInstruments(\n meter: Meter,\n config: MetricsConfig,\n runtimeState: RuntimeState,\n): CacheInstruments {\n const cacheGetCounter = meter.createCounter(\n `${config.prefix}.cache.gets`,\n {\n description: \"Total number of cache get operations\",\n unit: \"operations\",\n },\n );\n\n const cacheHitCounter = meter.createCounter(\n `${config.prefix}.cache.hits`,\n {\n description: \"Total number of cache hits\",\n unit: \"hits\",\n },\n );\n\n const cacheMissCounter = meter.createCounter(\n `${config.prefix}.cache.misses`,\n {\n description: \"Total number of cache misses\",\n unit: \"misses\",\n },\n );\n\n const cacheSetCounter = meter.createCounter(\n `${config.prefix}.cache.sets`,\n {\n description: \"Total number of cache set operations\",\n unit: \"operations\",\n },\n );\n\n const cacheInvalidateCounter = meter.createCounter(\n `${config.prefix}.cache.invalidations`,\n {\n description: \"Total number of cache invalidations\",\n unit: \"operations\",\n },\n );\n\n const cacheSizeGauge = meter.createObservableGauge(\n `${config.prefix}.cache.size`,\n {\n description: \"Current cache size\",\n unit: \"entries\",\n },\n );\n cacheSizeGauge.addCallback((result: ObservableResult) => {\n result.observe(runtimeState.cacheSize);\n });\n\n return {\n cacheGetCounter,\n cacheHitCounter,\n cacheMissCounter,\n cacheSetCounter,\n cacheInvalidateCounter,\n cacheSizeGauge,\n };\n}\n", "/**\n * Data Fetching Metrics Instruments\n * Creation of data fetching metric instruments\n *\n * @module\n */\n\nimport type { Counter, Histogram, Meter } from \"@opentelemetry/api\";\nimport { DURATION_HISTOGRAM_BOUNDARIES_MS } from \"@veryfront/config\";\nimport type { MetricsConfig } from \"../metrics/types.ts\";\n\n/**\n * Data fetching metric instruments\n */\nexport interface DataInstruments {\n dataFetchDuration: Histogram | null;\n dataFetchCounter: Counter | null;\n dataFetchErrorCounter: Counter | null;\n}\n\n/**\n * Create data fetching metric instruments\n *\n * @param meter - OpenTelemetry meter instance\n * @param config - Metrics configuration\n * @returns Data fetching metric instruments\n *\n * @example\n * ```ts\n * const dataInstruments = createDataInstruments(meter, config);\n * dataInstruments.dataFetchCounter?.add(1);\n * ```\n */\nexport function createDataInstruments(\n meter: Meter,\n config: MetricsConfig,\n): DataInstruments {\n const dataFetchDuration = meter.createHistogram(\n `${config.prefix}.data.fetch.duration`,\n {\n description: \"Data fetch duration\",\n unit: \"ms\",\n advice: { explicitBucketBoundaries: DURATION_HISTOGRAM_BOUNDARIES_MS },\n },\n );\n\n const dataFetchCounter = meter.createCounter(\n `${config.prefix}.data.fetch.count`,\n {\n description: \"Total number of data fetches\",\n unit: \"fetches\",\n },\n );\n\n const dataFetchErrorCounter = meter.createCounter(\n `${config.prefix}.data.fetch.errors`,\n {\n description: \"Data fetch errors\",\n unit: \"errors\",\n },\n );\n\n return {\n dataFetchDuration,\n dataFetchCounter,\n dataFetchErrorCounter,\n };\n}\n", "/**\n * HTTP Metrics Instruments\n * Creation of HTTP-related metric instruments\n *\n * @module\n */\n\nimport type { Counter, Histogram, Meter, UpDownCounter } from \"@opentelemetry/api\";\nimport { DURATION_HISTOGRAM_BOUNDARIES_MS } from \"@veryfront/config\";\nimport type { MetricsConfig } from \"../metrics/types.ts\";\n\n/**\n * HTTP metric instruments\n */\nexport interface HttpInstruments {\n httpRequestCounter: Counter | null;\n httpRequestDuration: Histogram | null;\n httpActiveRequests: UpDownCounter | null;\n}\n\n/**\n * Create HTTP metric instruments\n *\n * @param meter - OpenTelemetry meter instance\n * @param config - Metrics configuration\n * @returns HTTP metric instruments\n *\n * @example\n * ```ts\n * const httpInstruments = createHttpInstruments(meter, config);\n * httpInstruments.httpRequestCounter?.add(1);\n * ```\n */\nexport function createHttpInstruments(\n meter: Meter,\n config: MetricsConfig,\n): HttpInstruments {\n const httpRequestCounter = meter.createCounter(\n `${config.prefix}.http.requests`,\n {\n description: \"Total number of HTTP requests\",\n unit: \"requests\",\n },\n );\n\n const httpRequestDuration = meter.createHistogram(\n `${config.prefix}.http.request.duration`,\n {\n description: \"HTTP request duration\",\n unit: \"ms\",\n advice: { explicitBucketBoundaries: DURATION_HISTOGRAM_BOUNDARIES_MS },\n },\n );\n\n const httpActiveRequests = meter.createUpDownCounter(\n `${config.prefix}.http.requests.active`,\n {\n description: \"Number of active HTTP requests\",\n unit: \"requests\",\n },\n );\n\n return {\n httpRequestCounter,\n httpRequestDuration,\n httpActiveRequests,\n };\n}\n", "/**\n * Memory Metrics Instruments\n * Creation of memory-related metric instruments\n *\n * @module\n */\n\nimport type { Meter, ObservableGauge, ObservableResult } from \"@opentelemetry/api\";\nimport { getMemoryUsage } from \"../metrics/config.ts\";\nimport type { MetricsConfig } from \"../metrics/types.ts\";\n\n/**\n * Memory metric instruments\n */\nexport interface MemoryInstruments {\n memoryUsageGauge: ObservableGauge | null;\n heapUsageGauge: ObservableGauge | null;\n}\n\n/**\n * Create memory metric instruments\n *\n * @param meter - OpenTelemetry meter instance\n * @param config - Metrics configuration\n * @returns Memory metric instruments\n *\n * @example\n * ```ts\n * const memoryInstruments = createMemoryInstruments(meter, config);\n * // Observables automatically track memory usage\n * ```\n */\nexport function createMemoryInstruments(\n meter: Meter,\n config: MetricsConfig,\n): MemoryInstruments {\n const memoryUsageGauge = meter.createObservableGauge(\n `${config.prefix}.memory.usage`,\n {\n description: \"Memory usage\",\n unit: \"bytes\",\n },\n );\n memoryUsageGauge.addCallback((result: ObservableResult) => {\n const memoryUsage = getMemoryUsage();\n if (memoryUsage) {\n result.observe(memoryUsage.rss);\n }\n });\n\n const heapUsageGauge = meter.createObservableGauge(\n `${config.prefix}.memory.heap`,\n {\n description: \"Heap memory usage\",\n unit: \"bytes\",\n },\n );\n heapUsageGauge.addCallback((result: ObservableResult) => {\n const memoryUsage = getMemoryUsage();\n if (memoryUsage) {\n result.observe(memoryUsage.heapUsed);\n }\n });\n\n return {\n memoryUsageGauge,\n heapUsageGauge,\n };\n}\n", "/**\n * Render Metrics Instruments\n * Creation of render-related metric instruments\n *\n * @module\n */\n\nimport type { Counter, Histogram, Meter } from \"@opentelemetry/api\";\nimport { DURATION_HISTOGRAM_BOUNDARIES_MS } from \"@veryfront/config\";\nimport type { MetricsConfig } from \"../metrics/types.ts\";\n\n/**\n * Render metric instruments\n */\nexport interface RenderInstruments {\n renderDuration: Histogram | null;\n renderCounter: Counter | null;\n renderErrorCounter: Counter | null;\n}\n\n/**\n * Create render metric instruments\n *\n * @param meter - OpenTelemetry meter instance\n * @param config - Metrics configuration\n * @returns Render metric instruments\n *\n * @example\n * ```ts\n * const renderInstruments = createRenderInstruments(meter, config);\n * renderInstruments.renderCounter?.add(1);\n * ```\n */\nexport function createRenderInstruments(\n meter: Meter,\n config: MetricsConfig,\n): RenderInstruments {\n const renderDuration = meter.createHistogram(\n `${config.prefix}.render.duration`,\n {\n description: \"Page render duration\",\n unit: \"ms\",\n advice: { explicitBucketBoundaries: DURATION_HISTOGRAM_BOUNDARIES_MS },\n },\n );\n\n const renderCounter = meter.createCounter(\n `${config.prefix}.render.count`,\n {\n description: \"Total number of page renders\",\n unit: \"renders\",\n },\n );\n\n const renderErrorCounter = meter.createCounter(\n `${config.prefix}.render.errors`,\n {\n description: \"Total number of render errors\",\n unit: \"errors\",\n },\n );\n\n return {\n renderDuration,\n renderCounter,\n renderErrorCounter,\n };\n}\n", "/**\n * RSC Metrics Instruments\n * Creation of React Server Components metric instruments\n *\n * @module\n */\n\nimport type { Counter, Histogram, Meter } from \"@opentelemetry/api\";\nimport { DURATION_HISTOGRAM_BOUNDARIES_MS } from \"@veryfront/config\";\nimport type { MetricsConfig } from \"../metrics/types.ts\";\n\n/**\n * RSC metric instruments\n */\nexport interface RscInstruments {\n rscRenderDuration: Histogram | null;\n rscStreamDuration: Histogram | null;\n rscManifestCounter: Counter | null;\n rscPageCounter: Counter | null;\n rscStreamCounter: Counter | null;\n rscActionCounter: Counter | null;\n rscErrorCounter: Counter | null;\n}\n\n/**\n * Create RSC metric instruments\n *\n * @param meter - OpenTelemetry meter instance\n * @param config - Metrics configuration\n * @returns RSC metric instruments\n *\n * @example\n * ```ts\n * const rscInstruments = createRscInstruments(meter, config);\n * rscInstruments.rscPageCounter?.add(1);\n * ```\n */\nexport function createRscInstruments(\n meter: Meter,\n config: MetricsConfig,\n): RscInstruments {\n const rscRenderDuration = meter.createHistogram(\n `${config.prefix}.rsc.render.duration`,\n {\n description: \"RSC render duration\",\n unit: \"ms\",\n advice: { explicitBucketBoundaries: DURATION_HISTOGRAM_BOUNDARIES_MS },\n },\n );\n\n const rscStreamDuration = meter.createHistogram(\n `${config.prefix}.rsc.stream.duration`,\n {\n description: \"RSC stream duration\",\n unit: \"ms\",\n advice: { explicitBucketBoundaries: DURATION_HISTOGRAM_BOUNDARIES_MS },\n },\n );\n\n const rscManifestCounter = meter.createCounter(\n `${config.prefix}.rsc.manifest`,\n {\n description: \"RSC manifest requests\",\n unit: \"requests\",\n },\n );\n\n const rscPageCounter = meter.createCounter(\n `${config.prefix}.rsc.page`,\n {\n description: \"RSC page requests\",\n unit: \"requests\",\n },\n );\n\n const rscStreamCounter = meter.createCounter(\n `${config.prefix}.rsc.stream`,\n {\n description: \"RSC stream requests\",\n unit: \"requests\",\n },\n );\n\n const rscActionCounter = meter.createCounter(\n `${config.prefix}.rsc.action`,\n {\n description: \"RSC action requests\",\n unit: \"requests\",\n },\n );\n\n const rscErrorCounter = meter.createCounter(\n `${config.prefix}.rsc.errors`,\n {\n description: \"RSC errors\",\n unit: \"errors\",\n },\n );\n\n return {\n rscRenderDuration,\n rscStreamDuration,\n rscManifestCounter,\n rscPageCounter,\n rscStreamCounter,\n rscActionCounter,\n rscErrorCounter,\n };\n}\n", "/**\n * Metrics Recorder\n * Functions for recording metrics across all categories\n */\n\nimport type { MetricsInstruments, RuntimeState } from \"./types.ts\";\n\nexport class MetricsRecorder {\n constructor(\n private instruments: MetricsInstruments,\n private runtimeState: RuntimeState,\n ) {}\n\n recordHttpRequest(attributes?: Record<string, string>): void {\n this.instruments.httpRequestCounter?.add(1, attributes);\n this.instruments.httpActiveRequests?.add(1, attributes);\n this.runtimeState.activeRequests++;\n }\n\n recordHttpRequestComplete(\n durationMs: number,\n attributes?: Record<string, string>,\n ): void {\n this.instruments.httpRequestDuration?.record(durationMs, attributes);\n this.instruments.httpActiveRequests?.add(-1, attributes);\n this.runtimeState.activeRequests--;\n }\n\n recordCacheGet(hit: boolean, attributes?: Record<string, string>): void {\n this.instruments.cacheGetCounter?.add(1, attributes);\n if (hit) {\n this.instruments.cacheHitCounter?.add(1, attributes);\n } else {\n this.instruments.cacheMissCounter?.add(1, attributes);\n }\n }\n\n recordCacheSet(attributes?: Record<string, string>): void {\n this.instruments.cacheSetCounter?.add(1, attributes);\n this.runtimeState.cacheSize++;\n }\n\n recordCacheInvalidate(\n count: number,\n attributes?: Record<string, string>,\n ): void {\n this.instruments.cacheInvalidateCounter?.add(count, attributes);\n this.runtimeState.cacheSize = Math.max(\n 0,\n this.runtimeState.cacheSize - count,\n );\n }\n\n setCacheSize(size: number): void {\n this.runtimeState.cacheSize = size;\n }\n\n // Render Metrics\n recordRender(durationMs: number, attributes?: Record<string, string>): void {\n this.instruments.renderDuration?.record(durationMs, attributes);\n this.instruments.renderCounter?.add(1, attributes);\n }\n\n recordRenderError(attributes?: Record<string, string>): void {\n this.instruments.renderErrorCounter?.add(1, attributes);\n }\n\n // RSC Metrics\n recordRSCRender(\n durationMs: number,\n attributes?: Record<string, string>,\n ): void {\n this.instruments.rscRenderDuration?.record(durationMs, attributes);\n }\n\n recordRSCStream(\n durationMs: number,\n attributes?: Record<string, string>,\n ): void {\n this.instruments.rscStreamDuration?.record(durationMs, attributes);\n }\n\n recordRSCRequest(\n type: \"manifest\" | \"page\" | \"stream\" | \"action\",\n attributes?: Record<string, string>,\n ): void {\n switch (type) {\n case \"manifest\":\n this.instruments.rscManifestCounter?.add(1, attributes);\n break;\n case \"page\":\n this.instruments.rscPageCounter?.add(1, attributes);\n break;\n case \"stream\":\n this.instruments.rscStreamCounter?.add(1, attributes);\n break;\n case \"action\":\n this.instruments.rscActionCounter?.add(1, attributes);\n break;\n }\n }\n\n recordRSCError(attributes?: Record<string, string>): void {\n this.instruments.rscErrorCounter?.add(1, attributes);\n }\n\n // Build Metrics\n recordBuild(durationMs: number, attributes?: Record<string, string>): void {\n this.instruments.buildDuration?.record(durationMs, attributes);\n }\n\n recordBundle(sizeKb: number, attributes?: Record<string, string>): void {\n this.instruments.bundleSizeHistogram?.record(sizeKb, attributes);\n this.instruments.bundleCounter?.add(1, attributes);\n }\n\n // Data Fetching Metrics\n recordDataFetch(\n durationMs: number,\n attributes?: Record<string, string>,\n ): void {\n this.instruments.dataFetchDuration?.record(durationMs, attributes);\n this.instruments.dataFetchCounter?.add(1, attributes);\n }\n\n recordDataFetchError(attributes?: Record<string, string>): void {\n this.instruments.dataFetchErrorCounter?.add(1, attributes);\n }\n\n // Security Metrics\n recordCorsRejection(attributes?: Record<string, string>): void {\n this.instruments.corsRejectionCounter?.add(1, attributes);\n }\n\n recordSecurityHeaders(attributes?: Record<string, string>): void {\n this.instruments.securityHeadersCounter?.add(1, attributes);\n }\n}\n", "export type { AutoInstrumentConfig } from \"./types.ts\";\n\nexport {\n __resetAutoInstrumentForTests,\n initAutoInstrumentation,\n isAutoInstrumentEnabled,\n} from \"./orchestrator.ts\";\n\nexport { createInstrumentedFetch, instrumentHttpHandler } from \"./http-instrumentation.ts\";\n\n// Backward compatibility alias (DEPRECATED)\nexport { createInstrumentedFetch as instrumentFetch } from \"./http-instrumentation.ts\";\n\nexport { instrumentErrorHandler, instrumentReactRender } from \"./react-instrumentation.ts\";\n\nexport { instrument, instrumentBatch, instrumentSync } from \"./wrappers.ts\";\n", "import { serverLogger as logger } from \"@veryfront/utils\";\nimport type { RuntimeAdapter } from \"@veryfront/platform/adapters/base.ts\";\nimport { initTracing } from \"../tracing/index.ts\";\nimport { initMetrics } from \"../metrics/index.ts\";\nimport type { AutoInstrumentConfig } from \"./types.ts\";\nimport { mergeConfig } from \"./configurator.ts\";\n\nlet initialized = false;\n\nexport async function initAutoInstrumentation(\n config: AutoInstrumentConfig = {},\n adapter?: RuntimeAdapter,\n): Promise<void> {\n if (initialized) {\n logger.debug(\"[auto-instrument] Already initialized\");\n return;\n }\n\n const finalConfig = mergeConfig(config);\n\n try {\n await initializeTracing(finalConfig, adapter);\n await initializeMetrics(finalConfig, adapter);\n\n initialized = true;\n logInitialization(finalConfig);\n } catch (error) {\n logger.warn(\"[auto-instrument] Failed to initialize auto-instrumentation\", error);\n initialized = true;\n }\n}\n\nexport function isAutoInstrumentEnabled(): boolean {\n return initialized;\n}\n\n/**\n * Reset initialization state (for testing only)\n * @internal\n */\nexport function __resetAutoInstrumentForTests(): void {\n initialized = false;\n}\n\nasync function initializeTracing(\n config: AutoInstrumentConfig,\n adapter?: RuntimeAdapter,\n): Promise<void> {\n if (config.tracing?.enabled) {\n await initTracing(config.tracing, adapter);\n }\n}\n\nasync function initializeMetrics(\n config: AutoInstrumentConfig,\n adapter?: RuntimeAdapter,\n): Promise<void> {\n if (config.metrics?.enabled) {\n await initMetrics(config.metrics, adapter);\n }\n}\n\nfunction logInitialization(config: AutoInstrumentConfig): void {\n logger.info(\"[auto-instrument] Auto-instrumentation initialized\", {\n tracing: config.tracing?.enabled || false,\n metrics: config.metrics?.enabled || false,\n http: config.instrumentHttp,\n fetch: config.instrumentFetch,\n react: config.instrumentReact,\n });\n}\n", "import type { AutoInstrumentConfig } from \"./types.ts\";\n\nexport const DEFAULT_CONFIG: AutoInstrumentConfig = {\n instrumentHttp: true,\n instrumentFetch: true,\n instrumentReact: true,\n captureErrors: true,\n};\n\nexport function mergeConfig(config: AutoInstrumentConfig = {}): AutoInstrumentConfig {\n return { ...DEFAULT_CONFIG, ...config };\n}\n", "import { serverLogger as logger } from \"@veryfront/utils\";\nimport {\n context as otContext,\n propagation,\n type Span,\n SpanKind,\n SpanStatusCode,\n trace,\n} from \"@opentelemetry/api\";\nimport type { ErrorAttributes, HttpAttributes } from \"./types.ts\";\n\nconst tracer = trace.getTracer(\"veryfront-http\");\n\nconst headersGetter = {\n keys(carrier: Headers): string[] {\n return [...carrier.keys()];\n },\n get(carrier: Headers, key: string): string | undefined {\n return carrier.get(key) ?? undefined;\n },\n};\n\nfunction extractParentContext(headers: Headers) {\n try {\n return propagation.extract(otContext.active(), headers, headersGetter);\n } catch (error) {\n logger.debug(\"[auto-instrument] Failed to extract parent context\", error);\n return otContext.active();\n }\n}\n\nexport function instrumentHttpHandler(\n handler: (request: Request) => Promise<Response> | Response,\n): (request: Request) => Promise<Response> {\n return async (request: Request): Promise<Response> => {\n const startTime = performance.now();\n const url = new URL(request.url);\n const httpAttrs = buildHttpAttributes(request, url);\n const parentContext = extractParentContext(request.headers);\n\n try {\n const response = await tracer.startActiveSpan(\n \"http.server.request\",\n {\n kind: SpanKind.SERVER,\n attributes: httpAttrs,\n },\n parentContext,\n async (span) => {\n try {\n const response = await handler(request);\n const duration = performance.now() - startTime;\n recordResponseSuccess(span, response, duration, httpAttrs);\n return response;\n } catch (error) {\n const duration = performance.now() - startTime;\n recordResponseError(span, error, duration, httpAttrs);\n throw error;\n } finally {\n span.end();\n }\n },\n );\n return response as Response;\n } catch (error) {\n logger.debug(\n \"[auto-instrument] HTTP handler span failed, falling back to raw handler\",\n error,\n );\n return await handler(request);\n }\n };\n}\n\n/**\n * Create an instrumented fetch function without mutating globals\n * Returns a wrapped fetch that adds OpenTelemetry spans\n *\n * @param baseFetch - The fetch function to instrument (defaults to globalThis.fetch)\n * @returns Instrumented fetch function\n *\n * @example\n * ```ts\n * const instrumentedFetch = createInstrumentedFetch()\n * const response = await instrumentedFetch('https://api.example.com')\n * ```\n */\nexport function createInstrumentedFetch(\n baseFetch: typeof fetch = globalThis.fetch,\n): typeof fetch {\n return async function instrumentedFetch(\n input: RequestInfo | URL,\n init?: RequestInit,\n ): Promise<Response> {\n const startTime = performance.now();\n const urlString = extractFetchUrl(input);\n const method = init?.method || \"GET\";\n const fetchAttrs: HttpAttributes = {\n \"http.method\": method,\n \"http.url\": urlString,\n \"http.target\": urlString,\n \"http.host\": \"\",\n \"http.scheme\": \"\",\n };\n\n try {\n const parsed = new URL(urlString);\n fetchAttrs[\"http.target\"] = parsed.pathname;\n fetchAttrs[\"http.host\"] = parsed.host;\n fetchAttrs[\"http.scheme\"] = parsed.protocol.replace(\":\", \"\");\n } catch {\n // Relative URLs are fine; leave defaults\n }\n\n try {\n const response = await tracer.startActiveSpan(\n \"http.client.fetch\",\n {\n kind: SpanKind.CLIENT,\n attributes: fetchAttrs,\n },\n async (span) => {\n try {\n // Inject trace context into headers\n const headers = new Headers(init?.headers);\n propagation.inject(otContext.active(), headers, {\n set: (h, k, v) => h.set(k, v),\n });\n\n const updatedInit = { ...init, headers };\n const response = await baseFetch(input, updatedInit);\n const duration = performance.now() - startTime;\n recordResponseSuccess(span, response, duration, fetchAttrs);\n return response;\n } catch (error) {\n const duration = performance.now() - startTime;\n recordResponseError(span, error, duration, fetchAttrs);\n throw error;\n } finally {\n span.end();\n }\n },\n );\n return response as Response;\n } catch (error) {\n logger.debug(\"[auto-instrument] Fetch span failed, falling back to base fetch\", error);\n return await baseFetch(input, init);\n }\n };\n}\n\nfunction buildHttpAttributes(request: Request, url: URL): HttpAttributes {\n return {\n \"http.method\": request.method,\n \"http.url\": request.url,\n \"http.target\": url.pathname,\n \"http.host\": url.host,\n \"http.scheme\": url.protocol.replace(\":\", \"\"),\n };\n}\n\nfunction recordResponseSuccess(\n span: Span | null,\n response: Response,\n duration: number,\n httpAttrs: HttpAttributes,\n): void {\n if (!span) return;\n\n const attributes: Record<string, number | string> = {\n \"http.status_code\": response.status,\n \"http.response.size\": Number(response.headers.get(\"content-length\") || 0),\n \"http.duration_ms\": Math.round(duration),\n };\n\n span.setAttributes(attributes);\n\n if (response.status >= 500) {\n span.setStatus({ code: SpanStatusCode.ERROR });\n } else if (response.status >= 400) {\n span.setStatus({ code: SpanStatusCode.UNSET, message: `HTTP ${response.status}` });\n } else {\n span.setStatus({ code: SpanStatusCode.OK });\n }\n\n // Preserve original request method/path for downstream analysis\n span.setAttributes({\n \"http.method\": httpAttrs[\"http.method\"],\n \"http.target\": httpAttrs[\"http.target\"],\n });\n}\n\nfunction recordResponseError(\n span: Span | null,\n error: unknown,\n duration: number,\n httpAttrs: HttpAttributes,\n): void {\n if (!span) return;\n\n span.recordException(error as Error);\n span.setAttributes({\n ...buildErrorAttributes(error),\n \"http.duration_ms\": Math.round(duration),\n \"http.method\": httpAttrs[\"http.method\"],\n \"http.target\": httpAttrs[\"http.target\"],\n });\n span.setStatus({\n code: SpanStatusCode.ERROR,\n message: error instanceof Error ? error.message : String(error),\n });\n}\n\nfunction extractFetchUrl(input: RequestInfo | URL): string {\n if (typeof input === \"string\") return input;\n if (input instanceof URL) return input.href;\n return input.url;\n}\n\nfunction buildErrorAttributes(error: unknown): ErrorAttributes {\n return {\n \"error\": \"true\",\n \"error.type\": error instanceof Error ? error.constructor.name : \"Unknown\",\n \"error.message\": error instanceof Error ? error.message : String(error),\n };\n}\n", "import type { Span } from \"@opentelemetry/api\";\nimport { endSpan, setSpanAttributes, SpanNames, startSpan, withSpan } from \"../tracing/index.ts\";\nimport { recordRenderError } from \"../metrics/index.ts\";\n\nexport function instrumentReactRender<T>(\n renderFn: () => Promise<T> | T,\n componentName: string,\n): Promise<T> {\n return withSpan(\n SpanNames.RENDER_COMPONENT,\n async (span) => {\n const startTime = performance.now();\n try {\n const result = renderFn();\n\n if (result instanceof Promise) {\n return await handleAsyncRender(result, span, startTime);\n }\n\n return handleSyncRender(result, span, startTime);\n } catch (error) {\n handleRenderError(span, error, componentName);\n throw error;\n }\n },\n {\n kind: \"internal\",\n attributes: { \"component.name\": componentName },\n },\n );\n}\n\nexport function instrumentErrorHandler(\n handler: (error: Error, request?: Request) => Promise<Response> | Response,\n captureToSpan = true,\n): (error: Error, request?: Request) => Promise<Response> | Response {\n return (error: Error, request?: Request): Promise<Response> | Response => {\n if (captureToSpan) {\n captureErrorToSpan(error, request);\n }\n\n return handler(error, request);\n };\n}\n\nasync function handleAsyncRender<T>(\n result: Promise<T>,\n span: Span | null,\n startTime: number,\n): Promise<T> {\n const resolved = await result;\n recordRenderDuration(span, startTime);\n return resolved;\n}\n\nfunction handleSyncRender<T>(result: T, span: Span | null, startTime: number): T {\n recordRenderDuration(span, startTime);\n return result;\n}\n\nfunction handleRenderError(span: Span | null, error: unknown, componentName: string): void {\n recordRenderError({ component: componentName });\n // endSpan is handled by withActiveSpan automatically,\n // but we need to record the exception and status\n if (span) {\n span.recordException(error as Error);\n span.setStatus({ code: 2, message: String(error) }); // 2 = ERROR\n }\n}\n\nfunction recordRenderDuration(span: Span | null, startTime: number): void {\n const duration = performance.now() - startTime;\n setSpanAttributes(span, { \"render.duration_ms\": Math.floor(duration) });\n}\n\nfunction captureErrorToSpan(error: Error, request?: Request): void {\n const span = startSpan(\"error.handler\", {\n kind: \"internal\",\n attributes: {\n \"error.type\": error.constructor.name,\n \"error.message\": error.message,\n \"error.stack\": error.stack || \"\",\n },\n });\n\n if (request) {\n const url = new URL(request.url);\n setSpanAttributes(span, {\n \"http.method\": request.method,\n \"http.url\": request.url,\n \"http.path\": url.pathname,\n });\n }\n\n endSpan(span, error);\n}\n", "import type { Span } from \"@opentelemetry/api\";\nimport { endSpan, setSpanAttributes, type SpanOptions, startSpan } from \"../tracing/index.ts\";\nimport type { BatchOptions, InstrumentOptions } from \"./types.ts\";\n\nexport function instrument<T extends (...args: any[]) => Promise<any>>(\n fn: T,\n spanName: string,\n options?: InstrumentOptions,\n): T {\n return (async (...args: Parameters<T>): Promise<ReturnType<T>> => {\n const span = createSpan(spanName, args, options);\n const startTime = performance.now();\n\n try {\n const result = await fn(...args);\n recordDuration(span, startTime);\n endSpan(span);\n return result as ReturnType<T>;\n } catch (error) {\n endSpan(span, error as Error);\n throw error;\n }\n }) as T;\n}\n\nexport function instrumentSync<T extends (...args: any[]) => any>(\n fn: T,\n spanName: string,\n options?: InstrumentOptions,\n): T {\n return ((...args: Parameters<T>): ReturnType<T> => {\n const span = createSpan(spanName, args, options);\n const startTime = performance.now();\n\n try {\n const result = fn(...args);\n recordDuration(span, startTime);\n endSpan(span);\n return result as ReturnType<T>;\n } catch (error) {\n endSpan(span, error as Error);\n throw error;\n }\n }) as T;\n}\n\nexport async function instrumentBatch<T>(\n operationName: string,\n items: T[],\n processor: (item: T, index: number) => Promise<void>,\n options?: BatchOptions,\n): Promise<void> {\n const batchSize = options?.batchSize || 10;\n const totalBatches = Math.ceil(items.length / batchSize);\n\n const batchSpan = startSpan(operationName, {\n kind: \"internal\",\n attributes: {\n \"batch.total_items\": items.length,\n \"batch.size\": batchSize,\n \"batch.total_batches\": totalBatches,\n ...(options?.attributes || {}),\n },\n });\n\n try {\n await processBatches(items, batchSize, totalBatches, processor, operationName);\n endSpan(batchSpan);\n } catch (error) {\n endSpan(batchSpan, error as Error);\n throw error;\n }\n}\n\nfunction createSpan(spanName: string, args: unknown[], options?: InstrumentOptions): Span | null {\n const spanOptions: SpanOptions = {\n kind: options?.kind || \"internal\",\n attributes: options?.attributes?.(args) || {},\n };\n\n return startSpan(spanName, spanOptions);\n}\n\nfunction recordDuration(span: Span | null, startTime: number): void {\n const duration = performance.now() - startTime;\n setSpanAttributes(span, { \"duration_ms\": Math.floor(duration) });\n}\n\nasync function processBatches<T>(\n items: T[],\n batchSize: number,\n totalBatches: number,\n processor: (item: T, index: number) => Promise<void>,\n operationName: string,\n): Promise<void> {\n for (let batchIndex = 0; batchIndex < totalBatches; batchIndex++) {\n await processSingleBatch(items, batchSize, batchIndex, processor, operationName);\n }\n}\n\nasync function processSingleBatch<T>(\n items: T[],\n batchSize: number,\n batchIndex: number,\n processor: (item: T, index: number) => Promise<void>,\n operationName: string,\n): Promise<void> {\n const start = batchIndex * batchSize;\n const end = Math.min(start + batchSize, items.length);\n const batch = items.slice(start, end);\n\n const batchItemSpan = startSpan(`${operationName}.batch`, {\n kind: \"internal\",\n attributes: {\n \"batch.index\": batchIndex,\n \"batch.items\": batch.length,\n },\n });\n\n try {\n await Promise.all(batch.map((item, index) => processor(item, start + index)));\n endSpan(batchItemSpan);\n } catch (error) {\n endSpan(batchItemSpan, error as Error);\n throw error;\n }\n}\n", "/**\n * CORS Preflight Handler\n * Handles OPTIONS preflight requests for CORS\n *\n * @module core/cors/preflight\n */\n\nimport type { CORSPreflightOptions } from \"./types.ts\";\nimport { validateOrigin } from \"./validators.ts\";\nimport {\n DEFAULT_HEADERS,\n DEFAULT_MAX_AGE,\n DEFAULT_METHODS,\n HTTP_FORBIDDEN,\n HTTP_NO_CONTENT,\n} from \"./constants.ts\";\nimport { serverLogger } from \"@veryfront/utils/logger/logger.ts\";\n\n/**\n * Handle CORS preflight request\n * Returns appropriate response for OPTIONS requests\n *\n * @param options - Preflight handling options\n * @returns Response with CORS headers or error\n */\nexport async function handleCORSPreflight(options: CORSPreflightOptions): Promise<Response> {\n const { request, config, allowMethods, allowHeaders } = options;\n\n // Validate origin\n const validation = await validateOrigin(request.headers.get(\"origin\"), config);\n\n // If origin not allowed but no config provided, return success without CORS headers (secure-by-default)\n // This allows OPTIONS requests to succeed but doesn't expose CORS capabilities\n if (!validation.allowedOrigin) {\n // No config = allow OPTIONS but no CORS headers (secure-by-default)\n if (!config) {\n return new Response(null, {\n status: HTTP_NO_CONTENT,\n });\n }\n\n // Config exists but origin not allowed = reject\n serverLogger.warn(\"[CORS] Preflight rejected\", {\n origin: request.headers.get(\"origin\"),\n error: validation.error,\n });\n\n return new Response(validation.error || \"CORS policy: Origin not allowed\", {\n status: HTTP_FORBIDDEN,\n headers: {\n \"X-CORS-Error\": validation.error || \"Origin not allowed\",\n },\n });\n }\n\n // Build preflight response headers\n const headers = new Headers();\n\n // Set allowed origin\n headers.set(\"Access-Control-Allow-Origin\", validation.allowedOrigin);\n\n // Add Vary header for non-wildcard origins\n if (validation.allowedOrigin !== \"*\") {\n headers.set(\"Vary\", \"Origin\");\n }\n\n // Determine allowed methods\n const corsConfig = typeof config === \"object\" ? config : null;\n const methods = allowMethods ||\n (corsConfig?.methods?.length ? corsConfig.methods.join(\", \") : DEFAULT_METHODS.join(\", \"));\n headers.set(\"Access-Control-Allow-Methods\", methods);\n\n // Determine allowed headers\n let allowedHeaders = allowHeaders;\n if (!allowedHeaders) {\n // Check if specific headers were requested\n const requestedHeaders = request.headers.get(\"access-control-request-headers\");\n if (requestedHeaders) {\n allowedHeaders = requestedHeaders;\n } else if (corsConfig?.allowedHeaders?.length) {\n allowedHeaders = corsConfig.allowedHeaders.join(\", \");\n } else {\n allowedHeaders = DEFAULT_HEADERS.join(\", \");\n }\n }\n headers.set(\"Access-Control-Allow-Headers\", allowedHeaders);\n\n // Set max age for preflight caching\n const maxAge = corsConfig?.maxAge ?? DEFAULT_MAX_AGE;\n headers.set(\"Access-Control-Max-Age\", String(maxAge));\n\n // Add credentials if configured and allowed\n if (validation.allowCredentials && validation.allowedOrigin !== \"*\") {\n headers.set(\"Access-Control-Allow-Credentials\", \"true\");\n }\n\n return new Response(null, {\n status: HTTP_NO_CONTENT,\n headers,\n });\n}\n\n/**\n * Check if request is a CORS preflight request\n *\n * @param request - The incoming request\n * @returns True if this is a preflight request\n */\nexport function isPreflightRequest(request: Request): boolean {\n return request.method === \"OPTIONS\" &&\n (request.headers.has(\"access-control-request-method\") ||\n request.headers.has(\"access-control-request-headers\"));\n}\n", "/**\n * CORS Constants\n * Default values and constants for CORS handling\n *\n * @module core/cors/constants\n */\n\nimport { DEV_LOCALHOST_ORIGINS } from \"@veryfront/config\";\nimport { getEnv } from \"../../../platform/compat/process.ts\";\n\n/**\n * Default allowed HTTP methods for CORS\n */\nexport const DEFAULT_METHODS = [\"GET\", \"POST\", \"PUT\", \"PATCH\", \"DELETE\", \"OPTIONS\"];\n\n/**\n * Default allowed headers for CORS\n */\nexport const DEFAULT_HEADERS = [\"Content-Type\", \"Authorization\"];\n\n/**\n * Default max age for preflight cache (24 hours in seconds)\n */\nexport const DEFAULT_MAX_AGE = 86400;\n\n/**\n * Development-only localhost origins\n * Re-exported from config/network-defaults for convenience\n *\n * Security Note: These are ONLY used in development mode.\n * Production mode requires explicit origin configuration.\n */\nexport { DEV_LOCALHOST_ORIGINS };\n\n/**\n * HTTP status codes\n */\nexport const HTTP_NO_CONTENT = 204;\nexport const HTTP_FORBIDDEN = 403;\n\n/**\n * Check if running in production mode\n * Checks multiple environment variables for robustness\n *\n * @returns true if in production, false if in development\n *\n * Security Note: Defaults to production (true) for fail-secure behavior.\n */\nexport function isProductionMode(): boolean {\n try {\n const veryfrontEnv = getEnv(\"VERYFRONT_ENV\");\n const nodeEnv = getEnv(\"NODE_ENV\");\n const denoEnv = getEnv(\"DENO_ENV\");\n\n // Check for explicit development mode\n if (\n veryfrontEnv === \"development\" ||\n nodeEnv === \"development\" ||\n denoEnv === \"development\"\n ) {\n return false;\n }\n\n return true;\n } catch {\n // Default to production for safety (fail-secure)\n return true;\n }\n}\n", "/**\n * CORS Middleware\n * Middleware implementation for CORS handling\n *\n * @module core/cors/middleware\n */\n\nimport type { Context, MiddlewareHandler } from \"@veryfront/middleware/core/index.ts\";\nimport type { CORSConfig } from \"./types.ts\";\nimport { handleCORSPreflight, isPreflightRequest } from \"./preflight.ts\";\nimport { applyCORSHeaders } from \"./headers.ts\";\nimport { validateCORSConfig } from \"./validators.ts\";\nimport { createError, toError } from \"../../../core/errors/veryfront-error.ts\";\n\n/**\n * Create CORS middleware\n * Full-featured CORS middleware with security validations\n *\n * @param config - CORS configuration\n * @returns Middleware handler function\n *\n * @example\n * ```typescript\n * // Allow specific origins\n * app.use('*', cors({\n * origin: ['https://example.com', 'https://app.example.com'],\n * credentials: true\n * }))\n *\n * // Dynamic origin validation\n * app.use('*', cors({\n * origin: (origin) => origin.endsWith('.example.com'),\n * methods: ['GET', 'POST'],\n * maxAge: 3600\n * }))\n *\n * // Simple wildcard (not recommended for production)\n * app.use('*', cors({ origin: '*' }))\n * ```\n */\nexport function cors(config?: boolean | CORSConfig): MiddlewareHandler {\n // Validate configuration at middleware creation time\n const validation = validateCORSConfig(config);\n if (!validation.valid) {\n throw toError(createError({\n type: \"config\",\n message: `[CORS] Invalid configuration: ${validation.error}`,\n }));\n }\n\n return async (c: Context, next: () => Promise<Response | undefined> | Response) => {\n const request = c.req;\n\n // Handle preflight OPTIONS request\n if (isPreflightRequest(request)) {\n const response = await handleCORSPreflight({\n request,\n config,\n });\n\n // Set response on context\n return response;\n }\n\n // For actual requests, continue to next middleware\n const response = await next();\n\n // Add CORS headers to response\n if (response) {\n const corsResponse = await applyCORSHeaders({\n request,\n response,\n config,\n });\n\n return corsResponse || response;\n }\n\n return response;\n };\n}\n\n/**\n * Simple CORS middleware for basic use cases\n * Provides minimal CORS support without advanced features\n *\n * @param origin - Origin string or wildcard\n * @returns Middleware handler function\n *\n * @example\n * ```typescript\n * // Allow all origins (development only)\n * app.use('*', corsSimple('*'))\n *\n * // Allow specific origin\n * app.use('*', corsSimple('https://example.com'))\n * ```\n */\nexport function corsSimple(origin: string = \"*\"): MiddlewareHandler {\n return cors({\n origin,\n credentials: false,\n methods: [\"GET\", \"POST\", \"PUT\", \"PATCH\", \"DELETE\", \"OPTIONS\"],\n });\n}\n", "/**\n * Security Handler\n * Handles security headers (CSP, COOP, CORP, COEP) with nonce-based CSP\n */\n\nimport type { SecurityConfig } from \"./types.ts\";\nimport type { RuntimeAdapter } from \"@veryfront/platform/adapters/base.ts\";\nimport { recordSecurityHeaders } from \"@veryfront/observability\";\n\n/**\n * Generate cryptographic nonce for CSP\n */\nexport function generateNonce(): string {\n const array = new Uint8Array(16);\n crypto.getRandomValues(array);\n return btoa(String.fromCharCode(...array));\n}\n\n/**\n * Build Content Security Policy header with nonce\n *\n * @param isDev - Development mode flag\n * @param nonce - Cryptographic nonce for inline scripts/styles\n * @param cspUserHeader - User-provided CSP header\n * @param config - Security configuration\n * @param adapter - Runtime adapter for environment variables\n * @returns CSP header string\n */\nexport function buildCSP(\n isDev: boolean,\n nonce: string,\n cspUserHeader: string | null,\n config?: SecurityConfig | null,\n adapter?: RuntimeAdapter,\n): string {\n const envCsp = adapter?.env?.get?.(\"VERYFRONT_CSP\");\n if (envCsp?.trim()) return envCsp.replace(/{NONCE}/g, nonce);\n\n // Development CSP - relaxed for HMR and dev tools\n // Note: unsafe-eval allowed in dev only for source maps and dev tools\n // Note: 'self' covers /_vf_modules/ (same-origin module server)\n // Note: Nonces REQUIRED for inline module scripts - 'unsafe-inline' doesn't work for modules\n const defaultCsp = isDev\n ? [\n \"default-src 'self'\",\n `style-src 'self' 'unsafe-inline' https://esm.sh https://cdnjs.cloudflare.com https://cdn.veryfront.com https://cdn.jsdelivr.net https://cdn.tailwindcss.com`,\n \"img-src 'self' data: https://cdn.veryfront.com https://cdnjs.cloudflare.com\",\n `script-src 'self' 'nonce-${nonce}' 'unsafe-eval' https://esm.sh https://cdn.tailwindcss.com`,\n \"connect-src 'self' https://esm.sh ws://localhost:* wss://localhost:*\",\n \"font-src 'self' data: https://cdnjs.cloudflare.com\",\n ].join(\"; \")\n : [\n \"default-src 'self'\",\n `style-src 'self' 'nonce-${nonce}'`,\n \"img-src 'self' data:\",\n `script-src 'self' 'nonce-${nonce}'`,\n \"connect-src 'self'\",\n ].join(\"; \");\n\n if (cspUserHeader?.trim()) {\n return `${cspUserHeader.replace(/{NONCE}/g, nonce)}; ${defaultCsp}`;\n }\n\n // If config has CSP directives, merge them\n const cfgCsp = config?.csp;\n if (cfgCsp && typeof cfgCsp === \"object\") {\n const pieces: string[] = [];\n for (const [k, v] of Object.entries(cfgCsp)) {\n if (v === undefined) continue;\n const key = String(k).replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`);\n const val = Array.isArray(v) ? v.join(\" \") : String(v);\n pieces.push(`${key} ${val}`.replace(/{NONCE}/g, nonce));\n }\n if (pieces.length > 0) {\n return `${pieces.join(\"; \")}; ${defaultCsp}`;\n }\n }\n\n return defaultCsp;\n}\n\n/**\n * Get security header value from config or environment\n *\n * @param headerName - Header name (COOP, CORP, COEP)\n * @param defaultValue - Default value if not configured\n * @param config - Security configuration\n * @param adapter - Runtime adapter for environment variables\n * @returns Header value\n */\nexport function getSecurityHeader(\n headerName: string,\n defaultValue: string,\n config?: SecurityConfig | null,\n adapter?: RuntimeAdapter,\n): string {\n const configKey = headerName.toLowerCase();\n const configValue = config?.[configKey as keyof SecurityConfig];\n const envValue = adapter?.env?.get?.(`VERYFRONT_${headerName}`);\n return (typeof configValue === \"string\" ? configValue : undefined) || envValue || defaultValue;\n}\n\n/**\n * Apply security headers to Headers object with nonce\n *\n * @param headers - Headers object to modify\n * @param isDev - Development mode flag\n * @param nonce - Cryptographic nonce for CSP\n * @param cspUserHeader - User-provided CSP header\n * @param config - Security configuration\n * @param adapter - Runtime adapter for environment variables\n */\nexport function applySecurityHeaders(\n headers: Headers,\n isDev: boolean,\n nonce: string,\n cspUserHeader: string | null,\n config?: SecurityConfig | null,\n adapter?: RuntimeAdapter,\n): void {\n const getHeaderOverride = (name: string): string | undefined => {\n const overrides = config?.headers;\n if (!overrides) return undefined;\n const lower = name.toLowerCase();\n for (const [key, value] of Object.entries(overrides)) {\n if (key.toLowerCase() === lower) {\n return value;\n }\n }\n return undefined;\n };\n\n // Always set basic security headers\n const contentTypeOptions = getHeaderOverride(\"x-content-type-options\") ?? \"nosniff\";\n headers.set(\"X-Content-Type-Options\", contentTypeOptions);\n\n const frameOptions = getHeaderOverride(\"x-frame-options\") ?? \"DENY\";\n headers.set(\"X-Frame-Options\", frameOptions);\n\n const xssProtection = getHeaderOverride(\"x-xss-protection\") ?? \"1; mode=block\";\n headers.set(\"X-XSS-Protection\", xssProtection);\n\n // Build and set CSP with nonce\n const csp = buildCSP(isDev, nonce, cspUserHeader, config, adapter);\n if (csp) {\n headers.set(\"Content-Security-Policy\", csp);\n }\n\n // Set HSTS (Strict-Transport-Security) for HTTPS connections\n // Only set in production to enforce HTTPS\n if (!isDev) {\n const hstsMaxAge = config?.hsts?.maxAge ?? 31536000; // 1 year default\n const hstsIncludeSubDomains = config?.hsts?.includeSubDomains ?? true;\n const hstsPreload = config?.hsts?.preload ?? false;\n\n let hstsValue = `max-age=${hstsMaxAge}`;\n if (hstsIncludeSubDomains) {\n hstsValue += \"; includeSubDomains\";\n }\n if (hstsPreload) {\n hstsValue += \"; preload\";\n }\n\n const hstsOverride = getHeaderOverride(\"strict-transport-security\");\n headers.set(\"Strict-Transport-Security\", hstsOverride ?? hstsValue);\n }\n\n // Set COOP, CORP, COEP\n const coop = getSecurityHeader(\"COOP\", \"same-origin\", config, adapter);\n const corp = getSecurityHeader(\"CORP\", \"same-origin\", config, adapter);\n const coep = getSecurityHeader(\"COEP\", \"\", config, adapter);\n\n headers.set(\"Cross-Origin-Opener-Policy\", coop);\n headers.set(\"Cross-Origin-Resource-Policy\", corp);\n if (coep) {\n headers.set(\"Cross-Origin-Embedder-Policy\", coep);\n }\n\n if (config?.headers) {\n for (const [key, value] of Object.entries(config.headers)) {\n if (value === undefined) continue;\n headers.set(key, value);\n }\n }\n\n // Record metrics for security headers application\n recordSecurityHeaders();\n}\n", "/**\n * Cache Handler\n * Handles cache control header generation\n */\n\nimport { CACHE_DURATIONS } from \"./constants.ts\";\nimport type { CacheStrategy } from \"./types.ts\";\n\n/**\n * Build cache control header value from strategy\n *\n * @param strategy - Cache strategy configuration\n * @returns Cache-Control header value\n */\nexport function buildCacheControl(strategy: CacheStrategy): string {\n let cacheControl: string;\n\n if (typeof strategy === \"string\") {\n switch (strategy) {\n case \"no-cache\":\n cacheControl = \"no-cache, no-store, must-revalidate\";\n break;\n case \"no-store\":\n cacheControl = \"no-store\";\n break;\n case \"short\":\n cacheControl = `public, max-age=${CACHE_DURATIONS.SHORT}`;\n break;\n case \"medium\":\n cacheControl = `public, max-age=${CACHE_DURATIONS.MEDIUM}`;\n break;\n case \"long\":\n cacheControl = `public, max-age=${CACHE_DURATIONS.LONG}`;\n break;\n case \"immutable\":\n cacheControl = `public, max-age=${CACHE_DURATIONS.LONG}, immutable`;\n break;\n case \"none\":\n // Prevent all caching - used in development to avoid nonce mismatches\n cacheControl = \"no-cache, no-store, must-revalidate\";\n break;\n default:\n cacheControl = \"public, max-age=0\";\n }\n } else {\n const parts = [];\n parts.push(strategy.public !== false ? \"public\" : \"private\");\n parts.push(`max-age=${strategy.maxAge}`);\n if (strategy.immutable) parts.push(\"immutable\");\n if (strategy.mustRevalidate) parts.push(\"must-revalidate\");\n cacheControl = parts.join(\", \");\n }\n\n return cacheControl;\n}\n", "/**\n * ResponseBuilder - Response Creation Methods\n * Methods for creating different types of HTTP responses\n */\n\nimport { CONTENT_TYPES } from \"./constants.ts\";\n\n/**\n * Internal state interface for response methods\n */\nexport interface ResponseMethodsContext {\n headers: Headers;\n status: number;\n}\n\n/**\n * Build JSON response\n */\nexport function json(\n this: ResponseMethodsContext,\n data: unknown,\n status?: number,\n): Response {\n this.headers.set(\"content-type\", CONTENT_TYPES.JSON);\n return new Response(JSON.stringify(data), {\n status: status ?? this.status,\n headers: this.headers,\n });\n}\n\n/**\n * Build text response\n */\nexport function text(\n this: ResponseMethodsContext,\n body: string,\n status?: number,\n): Response {\n this.headers.set(\"content-type\", CONTENT_TYPES.TEXT);\n return new Response(body, {\n status: status ?? this.status,\n headers: this.headers,\n });\n}\n\n/**\n * Build HTML response\n */\nexport function html(\n this: ResponseMethodsContext,\n body: string,\n status?: number,\n): Response {\n this.headers.set(\"content-type\", CONTENT_TYPES.HTML);\n return new Response(body, {\n status: status ?? this.status,\n headers: this.headers,\n });\n}\n\n/**\n * Build JavaScript response\n */\nexport function javascript(\n this: ResponseMethodsContext,\n code: string,\n status?: number,\n): Response {\n this.headers.set(\"content-type\", CONTENT_TYPES.JAVASCRIPT);\n return new Response(code, {\n status: status ?? this.status,\n headers: this.headers,\n });\n}\n\n/**\n * Build response with custom content type\n */\nexport function withContentType(\n this: ResponseMethodsContext,\n contentType: string,\n body: BodyInit | null,\n status?: number,\n): Response {\n this.headers.set(\"content-type\", contentType);\n return new Response(body, {\n status: status ?? this.status,\n headers: this.headers,\n });\n}\n\n/**\n * Build response with body and current headers\n */\nexport function build(\n this: ResponseMethodsContext,\n body: BodyInit | null = null,\n status?: number,\n): Response {\n return new Response(body, {\n status: status ?? this.status,\n headers: this.headers,\n });\n}\n\n/**\n * Build 304 Not Modified response\n */\nexport function notModified(\n this: ResponseMethodsContext,\n etag?: string,\n): Response {\n if (etag) {\n this.headers.set(\"ETag\", etag);\n }\n return new Response(null, {\n status: 304,\n headers: this.headers,\n });\n}\n", "/**\n * ResponseBuilder - Static Helper Methods\n * Static utility methods for common response patterns\n */\n\nimport { CONTENT_TYPES } from \"./constants.ts\";\nimport type { CacheStrategy, CORSConfig, SecurityConfig } from \"./types.ts\";\nimport { createError, toError } from \"../../../core/errors/veryfront-error.ts\";\n\n/**\n * Type definition for ResponseBuilder constructor\n * Using a minimal interface to avoid circular dependency\n */\ninterface ResponseBuilderConstructor {\n new (config?: {\n securityConfig?: SecurityConfig | null;\n isDev?: boolean;\n cspUserHeader?: string | null;\n adapter?: import(\"@veryfront/platform/adapters/base.ts\").RuntimeAdapter;\n }): ResponseBuilderInstance;\n}\n\n/**\n * Type definition for ResponseBuilder instance\n */\ninterface ResponseBuilderInstance {\n headers: Headers;\n status: number;\n withCORS(req: Request, corsConfig?: boolean | CORSConfig): ResponseBuilderInstance;\n withSecurity(config?: SecurityConfig): ResponseBuilderInstance;\n withCache(strategy: CacheStrategy): ResponseBuilderInstance;\n withETag(etag: string): ResponseBuilderInstance;\n withAllow(methods: string | string[]): ResponseBuilderInstance;\n json(data: unknown, status?: number): Response;\n html(body: string, status?: number): Response;\n text(message: string, status?: number): Response;\n withContentType(contentType: string, body?: BodyInit | null): Response;\n build(body?: BodyInit | null, status?: number): Response;\n}\n\n// Forward declaration - will be set by builder.ts to avoid circular dependency\nlet ResponseBuilderClass: ResponseBuilderConstructor | null = null;\n\n/**\n * Set the ResponseBuilder class reference\n * This is called by builder.ts to avoid circular dependencies\n */\nexport function setResponseBuilderClass(builderClass: ResponseBuilderConstructor): void {\n ResponseBuilderClass = builderClass;\n}\n\n/**\n * Static helper for error responses\n */\nexport function error(\n status: number,\n message: string,\n req: Request,\n config?: {\n securityConfig?: SecurityConfig | null;\n corsConfig?: boolean | CORSConfig;\n contentType?: string;\n },\n): Response {\n if (!ResponseBuilderClass) {\n throw toError(createError({\n type: \"config\",\n message: \"ResponseBuilder class not initialized\",\n }));\n }\n const builder = new ResponseBuilderClass(config);\n builder.withCORS(req, config?.corsConfig);\n if (config?.securityConfig !== undefined) {\n builder.withSecurity(config.securityConfig ?? undefined);\n }\n\n const contentType = config?.contentType ?? CONTENT_TYPES.TEXT;\n if (contentType === CONTENT_TYPES.JSON) {\n return builder.json({ error: message }, status);\n } else if (contentType === CONTENT_TYPES.HTML) {\n return builder.html(message, status);\n }\n return builder.text(message, status);\n}\n\n/**\n * Static helper for JSON responses\n */\nexport function json(\n data: unknown,\n req: Request,\n config?: {\n status?: number;\n securityConfig?: SecurityConfig | null;\n corsConfig?: boolean | CORSConfig;\n cache?: CacheStrategy;\n etag?: string;\n },\n): Response {\n if (!ResponseBuilderClass) {\n throw toError(createError({\n type: \"config\",\n message: \"ResponseBuilder class not initialized\",\n }));\n }\n const builder = new ResponseBuilderClass(config);\n builder.withCORS(req, config?.corsConfig);\n if (config?.securityConfig !== undefined) {\n builder.withSecurity(config.securityConfig ?? undefined);\n }\n if (config?.cache) {\n builder.withCache(config.cache);\n }\n if (config?.etag) {\n builder.withETag(config.etag);\n }\n return builder.json(data, config?.status);\n}\n\n/**\n * Static helper for HTML responses\n */\nexport function html(\n body: string,\n req: Request,\n config?: {\n status?: number;\n securityConfig?: SecurityConfig | null;\n corsConfig?: boolean | CORSConfig;\n cache?: CacheStrategy;\n etag?: string;\n },\n): Response {\n if (!ResponseBuilderClass) {\n throw toError(createError({\n type: \"config\",\n message: \"ResponseBuilder class not initialized\",\n }));\n }\n const builder = new ResponseBuilderClass(config);\n builder.withCORS(req, config?.corsConfig);\n if (config?.securityConfig !== undefined) {\n builder.withSecurity(config.securityConfig ?? undefined);\n }\n if (config?.cache) {\n builder.withCache(config.cache);\n }\n if (config?.etag) {\n builder.withETag(config.etag);\n }\n return builder.html(body, config?.status);\n}\n\n/**\n * Static helper for OPTIONS preflight responses\n */\nexport function preflight(\n req: Request,\n config?: {\n allowMethods?: string | string[];\n allowHeaders?: string | string[];\n securityConfig?: SecurityConfig | null;\n corsConfig?: boolean | CORSConfig;\n },\n): Response {\n if (!ResponseBuilderClass) {\n throw toError(createError({\n type: \"config\",\n message: \"ResponseBuilder class not initialized\",\n }));\n }\n const builder = new ResponseBuilderClass(config);\n builder.withCORS(req, config?.corsConfig);\n if (config?.securityConfig !== undefined) {\n builder.withSecurity(config.securityConfig ?? undefined);\n }\n\n const methods = config?.allowMethods ?? \"GET,POST,PUT,PATCH,DELETE,OPTIONS\";\n builder.withAllow(methods);\n\n const headers = config?.allowHeaders ??\n req.headers.get(\"access-control-request-headers\") ??\n \"Content-Type,Authorization\";\n builder.headers.set(\n \"Access-Control-Allow-Headers\",\n Array.isArray(headers) ? headers.join(\", \") : headers,\n );\n\n return builder.build(null, 204);\n}\n\n/**\n * Static helper for streaming responses\n */\nexport function stream(\n streamData: ReadableStream,\n req: Request,\n config?: {\n contentType?: string;\n securityConfig?: SecurityConfig | null;\n corsConfig?: boolean | CORSConfig;\n cache?: CacheStrategy;\n },\n): Response {\n if (!ResponseBuilderClass) {\n throw toError(createError({\n type: \"config\",\n message: \"ResponseBuilder class not initialized\",\n }));\n }\n const builder = new ResponseBuilderClass(config);\n builder.withCORS(req, config?.corsConfig);\n if (config?.securityConfig !== undefined) {\n builder.withSecurity(config.securityConfig ?? undefined);\n }\n if (config?.cache) {\n builder.withCache(config.cache);\n }\n const contentType = config?.contentType ?? \"application/octet-stream\";\n return builder.withContentType(contentType, streamData);\n}\n", "/**\n * Input Validation Module\n * Comprehensive input validation system for API handlers\n *\n * @module @veryfront/security/input-validation\n */\n\n// Types\nexport type { ParseFormOptions, ParseJsonOptions, RequestLimits, ValidatedData } from \"./types.ts\";\nexport { DEFAULT_LIMITS } from \"./types.ts\";\n\n// Errors\nexport { ValidationError } from \"./errors.ts\";\n\n// Limit validators\nexport { readBodyWithLimit, validateRequestLimits } from \"./limits.ts\";\n\n// Parsers\nexport { parseFormData, parseJsonBody, parseQueryParams } from \"./parsers.ts\";\n\n// Sanitizers\nexport { sanitizeData } from \"./sanitizers.ts\";\n\n// Common schemas\nexport { CommonSchemas } from \"./schemas.ts\";\n\n// Handler factory\nexport {\n createValidatedHandler,\n type ValidatedHandlerConfig,\n type ValidatedHandlerFunction,\n} from \"./handler.ts\";\n", "/**\n * Input Validation Types\n * Type definitions for input validation system\n */\n\nimport {\n DEFAULT_MAX_BODY_SIZE_BYTES,\n DEFAULT_MAX_FILE_SIZE_BYTES,\n DEFAULT_MAX_HEADER_SIZE_BYTES,\n DEFAULT_MAX_URL_LENGTH_BYTES,\n} from \"@veryfront/core/constants/index.ts\";\n\n/**\n * Request size limits configuration\n */\nexport interface RequestLimits {\n maxBodySize?: number;\n maxUrlLength?: number;\n maxHeaderSize?: number;\n maxFileSize?: number;\n}\n\n/**\n * Default size limits (conservative for security)\n */\nexport const DEFAULT_LIMITS: Required<RequestLimits> = {\n maxBodySize: DEFAULT_MAX_BODY_SIZE_BYTES, // 1MB\n maxUrlLength: DEFAULT_MAX_URL_LENGTH_BYTES, // 2KB\n maxHeaderSize: DEFAULT_MAX_HEADER_SIZE_BYTES, // 8KB\n maxFileSize: DEFAULT_MAX_FILE_SIZE_BYTES, // 5MB\n};\n\n/**\n * Validation options for JSON body parsing\n */\nexport interface ParseJsonOptions {\n limits?: RequestLimits;\n sanitize?: boolean;\n}\n\n/**\n * Validation options for form data parsing\n */\nexport interface ParseFormOptions {\n limits?: RequestLimits;\n}\n\n/**\n * Validated data container\n */\nexport interface ValidatedData<TBody = unknown, TQuery = unknown> {\n body?: TBody;\n query?: TQuery;\n}\n", "/**\n * Core constants module - centralized magic numbers and strings\n *\n * This module consolidates all magic values used throughout the codebase\n * into well-organized, self-documenting constants. This improves:\n * - Maintainability: Change values in one place\n * - Consistency: Same values used everywhere\n * - Clarity: Named constants explain their purpose\n *\n * @module core/constants\n */\n\n// Re-export all existing constants from utils/constants\nexport * from \"../utils/constants/index.ts\";\n\n// Handler priorities - defines execution order in middleware pipeline\nexport * from \"./priorities.ts\";\n\n// Retry and error handling constants\nexport * from \"./retry.ts\";\n\n// Buffer and memory size constants\nexport * from \"./buffers.ts\";\n\n// String truncation and display limits\nexport * from \"./limits.ts\";\n\n// Metrics boundaries and histogram buckets\nexport * from \"./metrics.ts\";\n\n// Hash algorithm identifiers\nexport * from \"./crypto.ts\";\n", "/**\n * Handler priority constants\n *\n * These constants define the execution order of handlers in the middleware pipeline.\n * Lower numbers run first, higher numbers run last.\n *\n * Priority Levels:\n * - CRITICAL (0): Security, authentication - must run first\n * - VERY_HIGH (50): CORS, security headers - run very early\n * - HIGH (100-300): Health checks, monitoring, dev tools\n * - MEDIUM (400-700): File serving, API routes, RSC endpoints\n * - LOW (1000): SSR - catch-all for pages\n * - FALLBACK (10000): 404 handler - absolute last resort\n */\n\n/** CRITICAL priority - Security and authentication handlers (runs first) */\nexport const PRIORITY_CRITICAL = 0;\n\n/** VERY_HIGH priority - CORS and security headers */\nexport const PRIORITY_VERY_HIGH = 50;\n\n/** HIGH priority - Health checks and monitoring endpoints */\nexport const PRIORITY_HIGH = 100;\n\n/** HIGH priority - Client-side logging (dev mode) */\nexport const PRIORITY_HIGH_CLIENT_LOG = 200;\n\n/** HIGH priority - Dev endpoints (dev mode) */\nexport const PRIORITY_HIGH_DEV = 300;\n\n/** MEDIUM priority - Dev file handler */\nexport const PRIORITY_MEDIUM_DEV_FILES = 400;\n\n/** MEDIUM priority - Static file serving */\nexport const PRIORITY_MEDIUM_STATIC = 500;\n\n/** MEDIUM priority - Self-hosted lib modules (veryfront/ai/*) */\nexport const PRIORITY_MEDIUM_LIB_MODULES = 550;\n\n/** MEDIUM priority - RSC, module, and static handlers */\nexport const PRIORITY_MEDIUM = 600;\n\n/** MEDIUM priority - API route handlers */\nexport const PRIORITY_MEDIUM_API = 700;\n\n/** LOW priority - SSR handler (catch-all for pages) */\nexport const PRIORITY_LOW = 1000;\n\n/** FALLBACK priority - 404 handler (runs last) */\nexport const PRIORITY_FALLBACK = 10000;\n\n/**\n * Priority level definitions for better readability in code\n */\nexport const HANDLER_PRIORITIES = {\n CRITICAL: PRIORITY_CRITICAL,\n VERY_HIGH: PRIORITY_VERY_HIGH,\n HIGH: PRIORITY_HIGH,\n HIGH_CLIENT_LOG: PRIORITY_HIGH_CLIENT_LOG,\n HIGH_DEV: PRIORITY_HIGH_DEV,\n MEDIUM_DEV_FILES: PRIORITY_MEDIUM_DEV_FILES,\n MEDIUM_STATIC: PRIORITY_MEDIUM_STATIC,\n MEDIUM_LIB_MODULES: PRIORITY_MEDIUM_LIB_MODULES,\n MEDIUM: PRIORITY_MEDIUM,\n MEDIUM_API: PRIORITY_MEDIUM_API,\n LOW: PRIORITY_LOW,\n FALLBACK: PRIORITY_FALLBACK,\n} as const;\n", "/**\n * Retry and error handling constants\n *\n * These constants define default retry behavior for various operations\n * that may fail temporarily (network requests, file I/O, etc.)\n */\n\n/** Default number of retry attempts before giving up */\nexport const DEFAULT_RETRY_MAX_ATTEMPTS = 3;\n\n/** Initial delay between retry attempts (in milliseconds) */\nexport const DEFAULT_RETRY_INITIAL_DELAY_MS = 100;\n\n/** Maximum delay between retry attempts (in milliseconds) */\nexport const DEFAULT_RETRY_MAX_DELAY_MS = 5000;\n\n/** Exponential backoff multiplier (delay *= this value each retry) */\nexport const DEFAULT_RETRY_BACKOFF_MULTIPLIER = 2;\n\n/**\n * API client retry configuration defaults\n */\nexport const API_RETRY_MAX_ATTEMPTS = 3;\nexport const API_RETRY_INITIAL_DELAY_MS = 1000;\nexport const API_RETRY_MAX_DELAY_MS = 10000;\n\n/**\n * File system operation retry defaults\n */\nexport const FS_RETRY_MAX_ATTEMPTS = 3;\nexport const FS_RETRY_INITIAL_DELAY_MS = 1000;\nexport const FS_RETRY_MAX_DELAY_MS = 10000;\n\n/**\n * WebSocket reconnection defaults\n */\nexport const WS_RECONNECT_MAX_ATTEMPTS = 5;\nexport const WS_RECONNECT_INITIAL_DELAY_MS = 1000;\nexport const WS_RECONNECT_MAX_DELAY_MS = 30000;\n", "/**\n * Buffer size and memory-related constants\n *\n * These constants define buffer sizes for various I/O operations,\n * memory limits, and chunk sizes for streaming data.\n */\n\n/** Standard buffer sizes (powers of 2 for optimal memory alignment) */\nexport const BUFFER_SIZE_256_BYTES = 256;\nexport const BUFFER_SIZE_512_BYTES = 512;\nexport const BUFFER_SIZE_1_KB = 1024;\nexport const BUFFER_SIZE_2_KB = 2048;\nexport const BUFFER_SIZE_4_KB = 4096;\nexport const BUFFER_SIZE_8_KB = 8192;\nexport const BUFFER_SIZE_16_KB = 16384;\nexport const BUFFER_SIZE_32_KB = 32768;\nexport const BUFFER_SIZE_64_KB = 65536;\n\n/**\n * RSC file reading buffer (2KB)\n * Used to read file headers to detect 'use client' and 'use server' directives\n */\nexport const RSC_FILE_READ_BUFFER_SIZE_BYTES = BUFFER_SIZE_2_KB;\n\n/**\n * Default maximum body size for input validation (1MB)\n */\nexport const DEFAULT_MAX_BODY_SIZE_BYTES = 1024 * 1024;\n\n/**\n * Default maximum URL length for input validation (2KB)\n */\nexport const DEFAULT_MAX_URL_LENGTH_BYTES = BUFFER_SIZE_2_KB;\n\n/**\n * Default maximum HTTP header size (8KB)\n * Standard limit used by many web servers (nginx, Apache)\n */\nexport const DEFAULT_MAX_HEADER_SIZE_BYTES = BUFFER_SIZE_8_KB;\n\n/**\n * Default maximum file upload size (5MB)\n */\nexport const DEFAULT_MAX_FILE_SIZE_BYTES = 5 * 1024 * 1024;\n\n/**\n * Prefetch queue maximum size (1MB)\n * Total size of all prefetched resources in memory\n */\nexport const PREFETCH_QUEUE_MAX_SIZE_BYTES = 1024 * 1024;\n\n/**\n * Maximum chunk size for bundling (4MB)\n */\nexport const MAX_BUNDLE_CHUNK_SIZE_BYTES = 4096 * 1024;\n", "/**\n * Display limits and truncation constants\n *\n * These constants define how much data to show in logs, error messages,\n * debug output, and other user-facing displays to prevent overwhelming\n * output or memory issues.\n */\n\n/** Maximum string length for general display purposes */\nexport const MAX_STRING_DISPLAY_LENGTH = 1000;\n\n/** Maximum characters to show in log preview (e.g., request body) */\nexport const LOG_PREVIEW_MAX_LENGTH_CHARS = 500;\n\n/** Maximum characters for short log preview (e.g., WebSocket data) */\nexport const LOG_PREVIEW_SHORT_LENGTH_CHARS = 100;\n\n/** Maximum characters for code preview in error messages */\nexport const CODE_PREVIEW_MAX_LENGTH_CHARS = 200;\n\n/** Maximum number of stack trace lines to show */\nexport const MAX_STACK_TRACE_LINES = 100;\n\n/** Maximum characters in span/trace names before truncation */\nexport const MAX_SPAN_NAME_LENGTH = 1000;\n\n/** Maximum size of attribute values in traces (10KB) */\nexport const MAX_TRACE_ATTRIBUTE_VALUE_SIZE = 10000;\n\n/** Maximum number of events per span before truncation */\nexport const MAX_EVENTS_PER_SPAN = 100;\n\n/** Maximum number of links per span before truncation */\nexport const MAX_LINKS_PER_SPAN = 100;\n\n/** Maximum action arguments for RSC server actions */\nexport const MAX_SERVER_ACTION_ARGS = 50;\n\n/** Maximum test iterations for performance tests */\nexport const MAX_TEST_ITERATIONS = 100;\n\n/** Maximum cache entries for various caches */\nexport const CACHE_MAX_ENTRIES_SMALL = 50;\nexport const CACHE_MAX_ENTRIES_MEDIUM = 200;\nexport const CACHE_MAX_ENTRIES_LARGE = 500;\nexport const CACHE_MAX_ENTRIES_XLARGE = 1000;\n\n/** API route matcher cache size */\nexport const API_ROUTE_CACHE_MAX_ENTRIES = 500;\n\n/** Handler cache size */\nexport const HANDLER_CACHE_MAX_ENTRIES = 256;\n\n/** Maximum path length for security validation */\nexport const MAX_PATH_LENGTH_CHARS = 4096;\n\n/** Maximum port number (valid TCP port range) */\nexport const MAX_PORT_NUMBER = 65535;\n\n/** Minimum port number (valid TCP port range) */\nexport const MIN_PORT_NUMBER = 1;\n\n/** Maximum URL length for schema validation */\nexport const MAX_URL_LENGTH_FOR_VALIDATION = 2048;\n", "/**\n * Metrics and observability constants\n *\n * These constants define histogram boundaries, time buckets,\n * and other metrics-related configuration values.\n */\n\n/**\n * SSR render time histogram boundaries (in milliseconds)\n * Used to bucket SSR rendering times for performance analysis\n *\n * Buckets: 5ms, 10ms, 25ms, 50ms, 75ms, 100ms, 250ms, 500ms, 750ms,\n * 1s, 2.5s, 5s, 7.5s, 10s\n */\nexport const SSR_RENDER_TIME_BOUNDARIES_MS = [\n 5,\n 10,\n 25,\n 50,\n 75,\n 100,\n 250,\n 500,\n 750,\n 1000,\n 2500,\n 5000,\n 7500,\n 10000,\n];\n\n/**\n * HTTP request duration histogram boundaries (in milliseconds)\n * Similar buckets for general HTTP request timing\n */\nexport const HTTP_REQUEST_DURATION_BOUNDARIES_MS = SSR_RENDER_TIME_BOUNDARIES_MS;\n\n/**\n * RSC stream duration boundaries (in milliseconds)\n */\nexport const RSC_STREAM_DURATION_BOUNDARIES_MS = [\n 10,\n 25,\n 50,\n 100,\n 200,\n 500,\n 1000,\n 2000,\n 5000,\n];\n\n/**\n * Default metrics collection interval (60 seconds)\n * How often to collect and export metrics\n */\nexport const DEFAULT_METRICS_COLLECTION_INTERVAL_MS = 60000;\n\n/**\n * Default rate limiter settings\n */\nexport const DEFAULT_RATE_LIMIT_REQUESTS = 100;\nexport const DEFAULT_RATE_LIMIT_WINDOW_MS = 60000;\n\n/**\n * Cache statistics sample size for metrics\n */\nexport const CACHE_METRICS_SAMPLE_SIZE = 100;\n", "/**\n * Cryptographic algorithm and hash constants\n *\n * These constants define algorithm identifiers and related\n * cryptographic configuration values.\n */\n\n/** SHA-256 algorithm identifier */\nexport const HASH_ALGORITHM_SHA256 = \"SHA-256\";\n\n/** SHA-1 algorithm identifier (legacy, avoid for security) */\nexport const HASH_ALGORITHM_SHA1 = \"SHA-1\";\n\n/** MD5 algorithm identifier (legacy, avoid for security) */\nexport const HASH_ALGORITHM_MD5 = \"MD5\";\n\n/** Expected length of SHA-256 hex string (64 characters) */\nexport const SHA256_HEX_LENGTH = 64;\n\n/** Expected length of SHA-1 hex string (40 characters) */\nexport const SHA1_HEX_LENGTH = 40;\n\n/** Expected length of MD5 hex string (32 characters) */\nexport const MD5_HEX_LENGTH = 32;\n\n/**\n * FNV-1a hash prime multiplier (32-bit)\n */\nexport const FNV1A_PRIME_32 = 16777619;\n\n/**\n * Nonce length for CSP (Content Security Policy)\n * Typical length is 16-32 bytes (128-256 bits)\n */\nexport const CSP_NONCE_LENGTH_BYTES = 16;\n", "/**\n * Input Validation Errors\n * Custom error classes for validation failures\n */\n\n/**\n * Custom validation error with details\n */\nexport class ValidationError extends Error {\n constructor(\n message: string,\n public readonly details?: unknown,\n ) {\n super(message);\n this.name = \"ValidationError\";\n }\n}\n", "/**\n * Request Limit Validators\n * Functions for validating request size limits\n */\n\nimport { ValidationError } from \"./errors.ts\";\nimport { DEFAULT_LIMITS, type RequestLimits } from \"./types.ts\";\n\n/**\n * Validate request size limits (URL, headers, body)\n *\n * @param request - Request object to validate\n * @param limits - Optional custom size limits\n * @throws ValidationError if any limit is exceeded\n *\n * @example\n * ```ts\n * validateRequestLimits(request, {\n * maxUrlLength: 1024,\n * maxBodySize: 512 * 1024\n * })\n * ```\n */\nexport function validateRequestLimits(\n request: Request,\n limits: RequestLimits = {},\n): void {\n const config = { ...DEFAULT_LIMITS, ...limits };\n\n validateUrlLength(request.url, config.maxUrlLength);\n validateContentLength(request, config.maxBodySize);\n validateHeaderSize(request, config.maxHeaderSize);\n}\n\n/**\n * Validate URL length\n *\n * @param url - URL to validate\n * @param maxLength - Maximum allowed URL length\n * @throws ValidationError if URL is too long\n */\nfunction validateUrlLength(url: string, maxLength: number): void {\n if (url.length > maxLength) {\n throw new ValidationError(\"URL too long\", {\n maxLength,\n actualLength: url.length,\n });\n }\n}\n\n/**\n * Validate Content-Length header\n *\n * @param request - Request object with headers\n * @param maxSize - Maximum allowed body size\n * @throws ValidationError if Content-Length is invalid or too large\n */\nfunction validateContentLength(request: Request, maxSize: number): void {\n const contentLength = request.headers.get(\"content-length\");\n if (!contentLength) return;\n\n const size = parseInt(contentLength, 10);\n if (isNaN(size)) {\n throw new ValidationError(\"Invalid Content-Length header\");\n }\n\n if (size > maxSize) {\n throw new ValidationError(\"Request body too large\", {\n maxSize,\n actualSize: size,\n });\n }\n}\n\n/**\n * Validate total header size (approximate)\n *\n * @param request - Request object with headers\n * @param maxSize - Maximum allowed header size\n * @throws ValidationError if headers are too large\n */\nfunction validateHeaderSize(request: Request, maxSize: number): void {\n let headerSize = 0;\n\n request.headers.forEach((value, key) => {\n headerSize += key.length + value.length + 4; // \": \" and \"\\r\\n\"\n });\n\n if (headerSize > maxSize) {\n throw new ValidationError(\"Headers too large\", {\n maxSize,\n actualSize: headerSize,\n });\n }\n}\n\n/**\n * Read request body with size limit enforcement\n *\n * @param request - Request object with body stream\n * @param maxSize - Maximum allowed body size\n * @returns Body content as string\n * @throws ValidationError if body exceeds size limit\n *\n * @example\n * ```ts\n * const body = await readBodyWithLimit(request, 1024 * 1024) // 1MB limit\n * ```\n */\nexport async function readBodyWithLimit(\n request: Request,\n maxSize: number = DEFAULT_LIMITS.maxBodySize,\n): Promise<string> {\n const reader = request.body?.getReader();\n if (!reader) {\n throw new ValidationError(\"No request body\");\n }\n\n const chunks: Uint8Array[] = [];\n let totalSize = 0;\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n totalSize += value.length;\n if (totalSize > maxSize) {\n throw new ValidationError(\"Request body exceeds size limit\", {\n maxSize,\n bytesRead: totalSize,\n });\n }\n\n chunks.push(value);\n }\n } finally {\n reader.releaseLock();\n }\n\n // Combine chunks and decode\n const combined = new Uint8Array(totalSize);\n let offset = 0;\n for (const chunk of chunks) {\n combined.set(chunk, offset);\n offset += chunk.length;\n }\n\n return new TextDecoder().decode(combined);\n}\n", "/**\n * Request Parsers\n * Functions for parsing and validating different request body types\n */\n\nimport { z } from \"zod\";\nimport { ValidationError } from \"./errors.ts\";\nimport { readBodyWithLimit, validateRequestLimits } from \"./limits.ts\";\nimport { sanitizeData } from \"./sanitizers.ts\";\nimport { DEFAULT_LIMITS, type ParseFormOptions, type ParseJsonOptions } from \"./types.ts\";\n\n/**\n * Parse and validate JSON body with schema\n *\n * @param request - Request object with JSON body\n * @param schema - Zod schema to validate against\n * @param options - Optional parsing configuration\n * @returns Validated and optionally sanitized data\n * @throws ValidationError if parsing or validation fails\n *\n * @example\n * ```ts\n * const userSchema = z.object({\n * name: z.string(),\n * email: z.string().email()\n * })\n *\n * const user = await parseJsonBody(request, userSchema, { sanitize: true })\n * ```\n */\nexport async function parseJsonBody<T>(\n request: Request,\n schema: z.ZodSchema<T>,\n options?: ParseJsonOptions,\n): Promise<T> {\n // Validate request limits first\n validateRequestLimits(request, options?.limits);\n\n let data: unknown;\n try {\n // Parse JSON with size limit enforcement\n const text = await readBodyWithLimit(request, options?.limits?.maxBodySize);\n data = JSON.parse(text);\n } catch (error) {\n if (error instanceof ValidationError) throw error;\n throw new ValidationError(\"Invalid JSON in request body\", {\n error: error instanceof Error ? error.message : \"Parse error\",\n });\n }\n\n // Validate against schema\n try {\n const validated = await schema.parseAsync(data);\n\n // Optional sanitization\n if (options?.sanitize) {\n return sanitizeData(validated) as T;\n }\n\n return validated;\n } catch (error) {\n if (error instanceof z.ZodError) {\n throw new ValidationError(\"Validation failed\", {\n errors: error.errors.map((e) => ({\n path: e.path.join(\".\"),\n message: e.message,\n code: e.code,\n })),\n });\n }\n throw error;\n }\n}\n\n/**\n * Parse and validate form data\n *\n * @param request - Request object with form data body\n * @param schema - Zod schema to validate against\n * @param options - Optional parsing configuration\n * @returns Validated form data\n * @throws ValidationError if parsing or validation fails\n *\n * @example\n * ```ts\n * const uploadSchema = z.object({\n * file: z.instanceof(File),\n * description: z.string()\n * })\n *\n * const data = await parseFormData(request, uploadSchema)\n * ```\n */\nexport async function parseFormData<T>(\n request: Request,\n schema: z.ZodSchema<T>,\n options?: ParseFormOptions,\n): Promise<T> {\n validateRequestLimits(request, options?.limits);\n\n try {\n const formData = await request.formData();\n const data: Record<string, unknown> = {};\n\n // Convert FormData to object\n for (const [key, value] of formData.entries()) {\n if (value instanceof File) {\n // Validate file size\n const maxFileSize = options?.limits?.maxFileSize || DEFAULT_LIMITS.maxFileSize;\n if (value.size > maxFileSize) {\n throw new ValidationError(`File ${key} too large`, {\n maxSize: maxFileSize,\n actualSize: value.size,\n });\n }\n data[key] = value;\n } else {\n data[key] = value;\n }\n }\n\n return await schema.parseAsync(data);\n } catch (error) {\n if (error instanceof z.ZodError) {\n throw new ValidationError(\"Form validation failed\", {\n errors: error.errors,\n });\n }\n throw error;\n }\n}\n\n/**\n * Parse URL search params with validation\n *\n * @param request - Request object with URL search params\n * @param schema - Zod schema to validate against\n * @returns Validated query parameters\n * @throws ValidationError if validation fails\n *\n * @example\n * ```ts\n * const querySchema = z.object({\n * page: z.coerce.number(),\n * search: z.string().optional()\n * })\n *\n * const params = parseQueryParams(request, querySchema)\n * ```\n */\nexport function parseQueryParams<T>(\n request: Request,\n schema: z.ZodSchema<T>,\n): T {\n const url = new URL(request.url);\n const params: Record<string, unknown> = {};\n\n // Convert URLSearchParams to object\n url.searchParams.forEach((value, key) => {\n // Handle array parameters (e.g., ?tags=a&tags=b)\n if (params[key]) {\n if (Array.isArray(params[key])) {\n (params[key] as unknown[]).push(value);\n } else {\n params[key] = [params[key], value];\n }\n } else {\n params[key] = value;\n }\n });\n\n try {\n return schema.parse(params);\n } catch (error) {\n if (error instanceof z.ZodError) {\n throw new ValidationError(\"Query parameter validation failed\", {\n errors: error.errors,\n });\n }\n throw error;\n }\n}\n", "/**\n * Input Sanitizers\n * Functions for sanitizing and cleaning untrusted input\n */\n\n/**\n * Sanitize data to prevent XSS and injection attacks\n *\n * @param data - Data to sanitize (can be string, array, object, or primitive)\n * @returns Sanitized data with HTML entities encoded and dangerous keys removed\n *\n * @example\n * ```ts\n * sanitizeData('<script>alert(\"xss\")</script>')\n * // Returns: '<script>alert("xss")</script>'\n *\n * sanitizeData({ __proto__: 'malicious', safe: 'value' })\n * // Returns: { safe: 'value' } (prototype pollution prevented)\n * ```\n */\nexport function sanitizeData(data: unknown): unknown {\n if (typeof data === \"string\") {\n return sanitizeString(data);\n }\n\n if (Array.isArray(data)) {\n return data.map(sanitizeData);\n }\n\n if (data && typeof data === \"object\") {\n return sanitizeObject(data as Record<string, unknown>);\n }\n\n return data;\n}\n\n/**\n * Sanitize a string by encoding HTML entities\n *\n * @param str - String to sanitize\n * @returns String with HTML entities encoded\n */\nfunction sanitizeString(str: string): string {\n return str\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/\"/g, \""\")\n .replace(/'/g, \"'\")\n .replace(/\\//g, \"/\");\n}\n\n/**\n * Sanitize an object by cleaning keys and recursively sanitizing values\n *\n * @param obj - Object to sanitize\n * @returns Sanitized object with dangerous keys removed\n */\nfunction sanitizeObject(obj: Record<string, unknown>): Record<string, unknown> {\n const sanitized: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(obj)) {\n // Sanitize keys too (prevent prototype pollution)\n const safeKey = sanitizeKey(key);\n if (isAllowedKey(safeKey)) {\n sanitized[safeKey] = sanitizeData(value);\n }\n }\n\n return sanitized;\n}\n\n/**\n * Sanitize an object key by removing non-word characters\n *\n * @param key - Object key to sanitize\n * @returns Sanitized key\n */\nfunction sanitizeKey(key: string): string {\n return key.replace(/[^\\w.-]/g, \"\");\n}\n\n/**\n * Check if a key is allowed (not a dangerous prototype property)\n *\n * @param key - Object key to check\n * @returns True if key is safe to use\n */\nfunction isAllowedKey(key: string): boolean {\n return key !== \"__proto__\" && key !== \"constructor\" && key !== \"prototype\";\n}\n", "/**\n * Common Validation Schemas\n * Reusable Zod schemas for common validation patterns\n */\n\nimport { z } from \"zod\";\nimport { MAX_URL_LENGTH_FOR_VALIDATION } from \"@veryfront/core/constants/index.ts\";\n\n/**\n * Collection of commonly used validation schemas\n */\nexport const CommonSchemas = {\n /**\n * Valid email address (RFC-compliant, max 255 chars)\n */\n email: z.string().email().max(255),\n\n /**\n * Valid UUID v4 identifier\n */\n uuid: z.string().uuid(),\n\n /**\n * URL-safe slug (lowercase alphanumeric with hyphens)\n */\n slug: z.string().regex(/^[a-z0-9-]+$/).min(1).max(100),\n\n /**\n * Valid HTTP/HTTPS URL (max 2048 chars)\n */\n url: z.string().url().max(MAX_URL_LENGTH_FOR_VALIDATION),\n\n /**\n * International phone number (E.164 format)\n */\n phoneNumber: z.string().regex(/^\\+?[1-9]\\d{1,14}$/),\n\n /**\n * Pagination parameters with defaults\n */\n pagination: z.object({\n page: z.coerce.number().int().positive().default(1),\n limit: z.coerce.number().int().positive().max(100).default(10),\n sort: z.string().optional(),\n order: z.enum([\"asc\", \"desc\"]).optional(),\n }),\n\n /**\n * Date range with validation\n */\n dateRange: z.object({\n from: z.string().datetime(),\n to: z.string().datetime(),\n }).refine((data) => new Date(data.from) <= new Date(data.to), {\n message: \"From date must be before or equal to To date\",\n }),\n\n /**\n * Strong password requirements\n * - Minimum 8 characters\n * - At least one uppercase letter\n * - At least one lowercase letter\n * - At least one number\n * - At least one special character\n */\n strongPassword: z.string()\n .min(8, \"Password must be at least 8 characters\")\n .regex(/[A-Z]/, \"Password must contain at least one uppercase letter\")\n .regex(/[a-z]/, \"Password must contain at least one lowercase letter\")\n .regex(/[0-9]/, \"Password must contain at least one number\")\n .regex(/[^A-Za-z0-9]/, \"Password must contain at least one special character\"),\n};\n", "/**\n * Validated Handler Factory\n * Higher-order function for creating validated API handlers\n */\n\nimport { z } from \"zod\";\nimport { ValidationError } from \"./errors.ts\";\nimport { parseJsonBody, parseQueryParams } from \"./parsers.ts\";\nimport { type RequestLimits, type ValidatedData } from \"./types.ts\";\n\n/**\n * Configuration for validated handler\n */\nexport interface ValidatedHandlerConfig<TBody = unknown, TQuery = unknown> {\n body?: z.ZodSchema<TBody>;\n query?: z.ZodSchema<TQuery>;\n limits?: RequestLimits;\n}\n\n/**\n * Handler function type that receives validated data\n */\nexport type ValidatedHandlerFunction<TBody = unknown, TQuery = unknown> = (\n request: Request,\n validated: ValidatedData<TBody, TQuery>,\n) => Promise<Response> | Response;\n\n/**\n * Create a validated API handler wrapper\n *\n * This higher-order function wraps an API handler to automatically validate\n * request body and query parameters according to provided Zod schemas.\n * Validation errors are automatically converted to 400 responses.\n *\n * @param config - Configuration specifying validation schemas and limits\n * @param handler - Handler function that receives validated data\n * @returns Wrapped handler that performs automatic validation\n *\n * @example\n * ```ts\n * const createUserHandler = createValidatedHandler(\n * {\n * body: z.object({\n * name: z.string(),\n * email: z.string().email()\n * }),\n * query: z.object({\n * sendEmail: z.coerce.boolean().optional()\n * })\n * },\n * async (request, { body, query }) => {\n * // body and query are fully typed and validated\n * const user = await createUser(body)\n * if (query?.sendEmail) {\n * await sendWelcomeEmail(user.email)\n * }\n * return new Response(JSON.stringify(user), { status: 201 })\n * }\n * )\n * ```\n */\nexport function createValidatedHandler<TBody = unknown, TQuery = unknown>(\n config: ValidatedHandlerConfig<TBody, TQuery>,\n handler: ValidatedHandlerFunction<TBody, TQuery>,\n) {\n return async (request: Request): Promise<Response> => {\n try {\n const validated: ValidatedData<TBody, TQuery> = {};\n\n if (config.body) {\n validated.body = await parseJsonBody(request, config.body, { limits: config.limits });\n }\n\n if (config.query) {\n validated.query = parseQueryParams(request, config.query);\n }\n\n return await handler(request, validated);\n } catch (error) {\n if (error instanceof ValidationError) {\n return new Response(\n JSON.stringify({\n error: error.message,\n details: error.details,\n }),\n {\n status: 400,\n headers: { \"Content-Type\": \"application/json\" },\n },\n );\n }\n throw error;\n }\n };\n}\n", "/**\n * Security Handlers\n * Export all security-related handlers and utilities\n */\n\nexport { AuthHandler } from \"./auth.ts\";\nexport { SecurityConfigLoader } from \"./config.ts\";\n\n// Export security middleware functions\nexport { loadSecurityConfig, setCors } from \"./middleware/index.ts\";\n\n// Export security types\nexport type { CORSConfig, CSPDirectives, SecurityConfig } from \"./middleware/index.ts\";\n", "/**\n * Authentication Handler\n * Handles Basic and Bearer authentication\n */\n\nimport { BaseHandler } from \"./base-handler.ts\";\nimport { createError, toError } from \"../../core/errors/veryfront-error.ts\";\nimport type {\n HandlerContext,\n HandlerMetadata,\n HandlerPriority,\n HandlerResult,\n} from \"@veryfront/types\";\n\nfunction encodeBase64(value: string): string {\n if (typeof globalThis.btoa === \"function\") {\n try {\n return globalThis.btoa(value);\n } catch {\n // Fallback for non-Latin1 strings\n const bytes = new TextEncoder().encode(value);\n let binary = \"\";\n for (const byte of bytes) binary += String.fromCharCode(byte);\n return globalThis.btoa(binary);\n }\n }\n\n const bufferCtor = (globalThis as {\n Buffer?: { from(input: string, encoding: string): { toString(encoding: string): string } };\n }).Buffer;\n if (bufferCtor) {\n return bufferCtor.from(value, \"utf8\").toString(\"base64\");\n }\n\n throw toError(createError({\n type: \"not_supported\",\n message: \"Base64 encoding is not supported in this runtime\",\n feature: \"Base64 encoding\",\n }));\n}\n\nexport class AuthHandler extends BaseHandler {\n metadata: HandlerMetadata = {\n name: \"AuthHandler\",\n priority: 0 as HandlerPriority, // CRITICAL priority - runs first\n patterns: [], // Checks all requests\n };\n\n private basicUser: string | null = null;\n private basicPass: string | null = null;\n private bearerToken: string | null = null;\n\n handle(req: Request, ctx: HandlerContext): Promise<HandlerResult> {\n // Load auth config from environment\n this.loadAuthConfig(ctx);\n\n // Skip auth for OPTIONS requests\n if (req.method.toUpperCase() === \"OPTIONS\") {\n return Promise.resolve(this.continue());\n }\n\n // Check Basic Auth\n if (this.shouldUseBasic()) {\n const result = this.checkBasicAuth(req);\n if (result) return Promise.resolve(result);\n }\n\n // Check Bearer Auth\n if (this.shouldUseBearer()) {\n const result = this.checkBearerAuth(req);\n if (result) return Promise.resolve(result);\n }\n\n return Promise.resolve(this.continue());\n }\n\n private loadAuthConfig(ctx: HandlerContext): void {\n this.basicUser = ctx.adapter.env.get(\"VERYFRONT_BASIC_USER\") || \"\";\n this.basicPass = ctx.adapter.env.get(\"VERYFRONT_BASIC_PASS\") || \"\";\n this.bearerToken = ctx.adapter.env.get(\"VERYFRONT_BEARER_TOKEN\") || \"\";\n }\n\n private shouldUseBasic(): boolean {\n return !!(this.basicUser && this.basicPass);\n }\n\n private shouldUseBearer(): boolean {\n return !!this.bearerToken;\n }\n\n private checkBasicAuth(req: Request): HandlerResult | null {\n const expected = `Basic ${encodeBase64(`${this.basicUser}:${this.basicPass}`)}`;\n const auth = req.headers.get(\"authorization\") || \"\";\n\n if (auth !== expected) {\n const response = new Response(\"Unauthorized\", {\n status: 401,\n headers: { \"WWW-Authenticate\": 'Basic realm=\"Secure Area\"' },\n });\n return this.respond(response);\n }\n\n return null;\n }\n\n private checkBearerAuth(req: Request): HandlerResult | null {\n const auth = req.headers.get(\"authorization\") || \"\";\n\n if (!auth.startsWith(\"Bearer \") || auth.slice(7) !== this.bearerToken) {\n const response = new Response(\"Unauthorized\", { status: 401 });\n return this.respond(response);\n }\n\n return null;\n }\n}\n", "/**\n * Security Configuration Loader\n * Loads and caches security configuration from veryfront.config.ts\n */\n\nimport type { RuntimeAdapter } from \"@veryfront/platform/adapters/index.ts\";\nimport type { SecurityConfig } from \"@veryfront/types\";\nimport type { VeryfrontConfig } from \"@veryfront/config\";\nimport { getConfig } from \"@veryfront/config\";\nimport { serverLogger } from \"@veryfront/utils\";\nimport { buildCSP, generateNonce } from \"./response/security-handler.ts\";\n\nexport class SecurityConfigLoader {\n private securityConfig: SecurityConfig | null = null;\n private cspUserHeader: string | null = null;\n private isLoaded = false;\n private loadPromise: Promise<void> | null = null;\n\n constructor(\n private projectDir: string,\n private adapter: RuntimeAdapter,\n ) {}\n\n /**\n * Ensure security config is loaded (singleton pattern)\n */\n async ensureLoaded(): Promise<void> {\n if (this.isLoaded) {\n return;\n }\n\n // If already loading, wait for it\n if (this.loadPromise) {\n return this.loadPromise;\n }\n\n // Start loading\n this.loadPromise = this.load();\n await this.loadPromise;\n }\n\n /**\n * Load security configuration\n */\n private async load(): Promise<void> {\n try {\n const cfg = await getConfig(this.projectDir, this.adapter) as VeryfrontConfig;\n\n const baseSecurity = cfg?.security\n ? { ...cfg.security } as SecurityConfig\n : {} as SecurityConfig;\n\n if (baseSecurity.headers) {\n baseSecurity.headers = { ...baseSecurity.headers };\n }\n\n if (baseSecurity.cors === undefined) {\n baseSecurity.cors = true;\n }\n\n this.securityConfig = baseSecurity;\n\n // Parse CSP from config\n const cfgCsp = this.securityConfig?.csp;\n if (cfgCsp && typeof cfgCsp === \"object\") {\n const pieces: string[] = [];\n for (const [k, v] of Object.entries(cfgCsp)) {\n if (v === undefined) continue;\n const key = String(k).replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`);\n const val = Array.isArray(v) ? v.join(\" \") : String(v);\n pieces.push(`${key} ${val}`);\n }\n if (pieces.length > 0) {\n this.cspUserHeader = pieces.join(\"; \");\n }\n }\n\n this.isLoaded = true;\n } catch (error) {\n // Config is optional, so we don't throw\n serverLogger.debug(\"[SecurityConfigLoader] Failed to load config:\", error);\n this.isLoaded = true; // Mark as loaded even on error to prevent retry\n }\n }\n\n /**\n * Get security configuration\n */\n getSecurityConfig(): SecurityConfig | null {\n return this.securityConfig;\n }\n\n /**\n * Get CSP header from config\n */\n getCspUserHeader(): string | null {\n return this.cspUserHeader;\n }\n\n /**\n * Get CORS configuration\n */\n getCorsConfig(): SecurityConfig[\"cors\"] {\n return this.securityConfig?.cors;\n }\n\n /**\n * Build complete CSP header\n */\n buildCsp(isDev: boolean, nonce: string = generateNonce()): string {\n return buildCSP(\n isDev,\n nonce,\n this.cspUserHeader,\n this.securityConfig,\n this.adapter,\n );\n }\n\n /**\n * Get security header value\n */\n getSecurityHeader(headerName: string, defaultValue: string): string {\n const configKey = headerName.toLowerCase();\n const configValue = this.securityConfig?.[configKey as keyof SecurityConfig];\n const envValue = this.adapter.env.get(`VERYFRONT_${headerName}`);\n return (typeof configValue === \"string\" ? configValue : undefined) || envValue || defaultValue;\n }\n\n /**\n * Reset the loader (mainly for testing)\n */\n reset(): void {\n this.securityConfig = null;\n this.cspUserHeader = null;\n this.isLoaded = false;\n this.loadPromise = null;\n }\n}\n", "/**\n * Security middleware - barrel exports\n *\n * @module security/middleware\n */\n\n// Types\nexport type { CORSConfig, CSPDirectives, SecurityConfig } from \"./types.ts\";\n\n// Config loader\nexport { isValidSecurityConfig, loadSecurityConfig } from \"./config-loader.ts\";\n\n// CORS handler\nexport { setCors } from \"./cors-handler.ts\";\n\n// ETag utilities\nexport { computeEtag } from \"./etag.ts\";\n\n// Content types\nexport { CONTENT_TYPES } from \"./content-types.ts\";\n", "/**\n * Security configuration loader\n *\n * @module security/middleware/config-loader\n */\n\nimport type { RuntimeAdapter } from \"@veryfront/platform/adapters/index.ts\";\nimport type { SecurityConfig } from \"./types.ts\";\nimport { serverLogger } from \"@veryfront/utils\";\n\n/**\n * Validates security configuration structure\n *\n * @param config - Unknown configuration to validate\n * @returns True if configuration is valid SecurityConfig\n *\n * @example\n * ```ts\n * const valid = isValidSecurityConfig({ csp: {}, cors: true })\n * console.log(valid) // true\n * ```\n */\nexport function isValidSecurityConfig(config: unknown): config is SecurityConfig {\n if (!config || typeof config !== \"object\") return false;\n const cfg = config as Record<string, unknown>;\n\n // Validate CSP if present\n if (cfg.csp !== undefined && typeof cfg.csp !== \"object\") return false;\n\n // Validate CORS if present\n if (cfg.cors !== undefined) {\n if (typeof cfg.cors !== \"boolean\" && typeof cfg.cors !== \"object\") return false;\n }\n\n // Validate string fields\n if (cfg.coop !== undefined && typeof cfg.coop !== \"string\") return false;\n if (cfg.corp !== undefined && typeof cfg.corp !== \"string\") return false;\n if (cfg.coep !== undefined && typeof cfg.coep !== \"string\") return false;\n\n return true;\n}\n\n/**\n * Load security configuration from project config\n *\n * @param projectDir - Project directory path\n * @param adapter - Runtime adapter for environment access\n * @returns Security configuration or null if not found/invalid\n *\n * @example\n * ```ts\n * const config = await loadSecurityConfig('/path/to/project', adapter)\n * if (config) {\n * console.log('CSP:', config.csp)\n * }\n * ```\n */\nexport async function loadSecurityConfig(\n projectDir: string,\n adapter: RuntimeAdapter,\n): Promise<SecurityConfig | null> {\n try {\n const { getConfig } = await import(\"@veryfront/config\");\n const cfg = await getConfig(projectDir, adapter);\n const securityConfig = (cfg as Record<string, unknown>)?.security;\n\n if (!securityConfig) return null;\n if (!isValidSecurityConfig(securityConfig)) {\n serverLogger.warn(\"Invalid security configuration structure, ignoring\");\n return null;\n }\n\n return securityConfig;\n } catch {\n return null;\n }\n}\n", "/**\n * CORS header handler\n *\n * @module security/middleware/cors-handler\n */\n\nimport type { SecurityConfig } from \"./types.ts\";\nimport { validateOriginSync } from \"../cors/validators.ts\";\n\n/**\n * Set CORS headers on response\n *\n * Uses consolidated origin validation to determine allowed origin.\n * Reflects request origin if configured, or uses configured value.\n * Always sets Vary: Origin header for proper caching.\n *\n * @param headers - Response headers object to modify\n * @param req - Incoming request\n * @param securityConfig - Security configuration from project\n *\n * @example\n * ```ts\n * const headers = new Headers()\n * setCors(headers, request, securityConfig)\n * // headers now include Access-Control-Allow-Origin and Vary\n * ```\n */\nexport function setCors(headers: Headers, req: Request, securityConfig: SecurityConfig | null) {\n const conf = securityConfig?.cors;\n\n // Use consolidated validator for origin determination\n const validation = validateOriginSync(req.headers.get(\"origin\"), conf);\n\n // Set the allowed origin if validation succeeded\n if (validation.allowedOrigin) {\n headers.set(\"Access-Control-Allow-Origin\", validation.allowedOrigin);\n }\n\n // Always add Vary header for proper caching when origin is not wildcard\n if (validation.allowedOrigin && validation.allowedOrigin !== \"*\") {\n headers.set(\"Vary\", \"Origin\");\n }\n}\n", "/**\n * ETag computation utilities\n *\n * @module security/middleware/etag\n */\n\nimport { HASH_SEED_DJB2 } from \"@veryfront/utils/constants/hash.ts\";\n\n/**\n * Compute ETag for content using DJB2 hash algorithm\n *\n * Generates a weak ETag (W/\"...\") using a fast DJB2 hash.\n * This is suitable for caching validation but not cryptographic purposes.\n *\n * @param text - Content to hash\n * @returns Weak ETag header value\n *\n * @example\n * ```ts\n * const etag = computeEtag('<html>...</html>')\n * headers.set('ETag', etag)\n * // ETag: W/\"a3f2d1c4\"\n * ```\n */\nexport function computeEtag(text: string): string {\n let h = HASH_SEED_DJB2;\n for (let i = 0; i < text.length; i++) {\n h = ((h << 5) + h) ^ text.charCodeAt(i);\n }\n return `W/\"${(h >>> 0).toString(16)}\"`;\n}\n", "/**\n * Content type mappings\n *\n * @module security/middleware/content-types\n */\n\nimport {\n HTTP_CONTENT_TYPE_IMAGE_GIF,\n HTTP_CONTENT_TYPE_IMAGE_ICO,\n HTTP_CONTENT_TYPE_IMAGE_JPEG,\n HTTP_CONTENT_TYPE_IMAGE_PNG,\n HTTP_CONTENT_TYPE_IMAGE_SVG,\n HTTP_CONTENT_TYPE_IMAGE_WEBP,\n} from \"@veryfront/utils/constants/http.ts\";\n\n/**\n * MIME type mappings for common file extensions\n *\n * Maps file extensions (with leading dot) to their MIME types.\n * Includes charset for text-based formats.\n *\n * @example\n * ```ts\n * const contentType = CONTENT_TYPES['.html']\n * console.log(contentType) // 'text/html; charset=utf-8'\n * ```\n */\nexport const CONTENT_TYPES: Record<string, string> = {\n // Text formats\n \".html\": \"text/html; charset=utf-8\",\n \".css\": \"text/css; charset=utf-8\",\n \".txt\": \"text/plain; charset=utf-8\",\n\n // JavaScript\n \".js\": \"application/javascript; charset=utf-8\",\n \".mjs\": \"application/javascript; charset=utf-8\",\n\n // Data formats\n \".json\": \"application/json; charset=utf-8\",\n\n // Images\n \".png\": HTTP_CONTENT_TYPE_IMAGE_PNG,\n \".jpg\": HTTP_CONTENT_TYPE_IMAGE_JPEG,\n \".jpeg\": HTTP_CONTENT_TYPE_IMAGE_JPEG,\n \".gif\": HTTP_CONTENT_TYPE_IMAGE_GIF,\n \".svg\": HTTP_CONTENT_TYPE_IMAGE_SVG,\n \".ico\": HTTP_CONTENT_TYPE_IMAGE_ICO,\n \".webp\": HTTP_CONTENT_TYPE_IMAGE_WEBP,\n\n // Fonts\n \".woff\": \"font/woff\",\n \".woff2\": \"font/woff2\",\n \".ttf\": \"font/ttf\",\n \".otf\": \"font/otf\",\n};\n", "/**\n * Path Traversal Protection\n *\n * Centralized path validation to prevent directory traversal attacks.\n * Implements OWASP security guidelines and defense-in-depth principles.\n *\n * Features:\n * - Canonical path resolution (resolves .., symlinks)\n * - Whitelist-based validation\n * - Null byte and special character detection\n * - Cross-platform support (Windows, Unix)\n * - Multiple security levels\n *\n * @module security/path-validation\n */\n\nimport {\n FORBIDDEN_PATH_PATTERNS,\n MAX_PATH_LENGTH,\n MAX_PATH_TRAVERSAL_DEPTH,\n} from \"@veryfront/utils\";\nimport type { RuntimeAdapter } from \"@veryfront/platform/adapters/base.ts\";\n\n/**\n * Security validation level\n *\n * - strict: Maximum security, strict whitelist enforcement\n * - normal: Standard security for most operations\n * - permissive: More lenient, for build-time operations\n */\nexport type ValidationLevel = \"strict\" | \"normal\" | \"permissive\";\n\n/**\n * Path validation result\n */\nexport interface ValidationResult {\n valid: boolean;\n canonicalPath?: string;\n error?: string;\n code?: string;\n}\n\n/**\n * Path validation options\n */\nexport interface ValidationOptions {\n /** Security level */\n level?: ValidationLevel;\n\n /** Base directory to restrict access to */\n baseDir: string;\n\n /** Additional allowed directories (relative to baseDir) */\n allowedDirs?: string[];\n\n /** Whether to follow symlinks */\n followSymlinks?: boolean;\n\n /** Whether to check file existence */\n checkExists?: boolean;\n\n /** Runtime adapter for filesystem operations */\n adapter?: RuntimeAdapter;\n\n /** Whether to allow absolute paths outside baseDir */\n allowAbsolute?: boolean;\n}\n\n/**\n * Path validation error codes\n */\nexport const PathValidationError = {\n NULL_BYTE: \"NULL_BYTE\",\n PATH_TOO_LONG: \"PATH_TOO_LONG\",\n EXCESSIVE_TRAVERSAL: \"EXCESSIVE_TRAVERSAL\",\n FORBIDDEN_PATTERN: \"FORBIDDEN_PATTERN\",\n OUTSIDE_BASE: \"OUTSIDE_BASE\",\n NOT_IN_ALLOWLIST: \"NOT_IN_ALLOWLIST\",\n FILE_NOT_FOUND: \"FILE_NOT_FOUND\",\n SYMLINK_DETECTED: \"SYMLINK_DETECTED\",\n INVALID_PATH: \"INVALID_PATH\",\n ABSOLUTE_PATH_DENIED: \"ABSOLUTE_PATH_DENIED\",\n} as const;\n\n/**\n * Normalize path separators to forward slashes\n * Handles Windows backslashes and mixed separators\n */\nfunction normalizeSeparators(path: string): string {\n return path.replace(/\\\\+/g, \"/\");\n}\n\n/**\n * Check if path is absolute\n * Supports Unix (/path) and Windows (C:\\path, \\\\UNC\\path)\n */\nfunction isAbsolutePath(path: string): boolean {\n // Unix absolute path\n if (path.startsWith(\"/\")) return true;\n\n // Windows drive letter (C:\\ or C:/)\n if (/^[A-Za-z]:[\\/\\\\]/.test(path)) return true;\n\n // Windows UNC path (\\\\server\\share)\n if (/^\\\\\\\\[^\\\\]+\\\\[^\\\\]+/.test(path)) return true;\n\n return false;\n}\n\n/**\n * Resolve .. and . in path without filesystem access\n * This is a pure string operation for initial validation\n */\nfunction resolvePathSegments(path: string): string {\n const normalized = normalizeSeparators(path);\n const parts = normalized.split(\"/\").filter((p) => p.length > 0);\n const resolved: string[] = [];\n\n for (const part of parts) {\n if (part === \".\") {\n continue;\n } else if (part === \"..\") {\n if (resolved.length > 0) {\n resolved.pop();\n }\n } else {\n resolved.push(part);\n }\n }\n\n // Preserve leading slash for absolute paths\n const isAbs = normalized.startsWith(\"/\");\n return isAbs ? `/${resolved.join(\"/\")}` : resolved.join(\"/\");\n}\n\n/**\n * Join two paths safely\n */\nfunction joinPaths(base: string, relative: string): string {\n const normalizedBase = normalizeSeparators(base).replace(/\\/$/, \"\");\n const normalizedRelative = normalizeSeparators(relative).replace(/^\\//, \"\");\n return `${normalizedBase}/${normalizedRelative}`;\n}\n\n/**\n * Check if target path is within base directory\n * Compares normalized paths (string comparison)\n */\nfunction isWithinDirectory(baseDir: string, targetPath: string): boolean {\n const normalizedBase = normalizeSeparators(baseDir).replace(/\\/$/, \"\");\n const normalizedTarget = normalizeSeparators(targetPath).replace(/\\/$/, \"\");\n\n return normalizedTarget === normalizedBase ||\n normalizedTarget.startsWith(`${normalizedBase}/`);\n}\n\n/**\n * Validate path for security issues (basic checks)\n */\nfunction validatePathBasics(path: string): ValidationResult {\n // Check for null bytes\n // deno-lint-ignore no-control-regex\n if (path.includes(\"\\0\") || /\\x00/.test(path)) {\n return {\n valid: false,\n error: \"Path contains null bytes\",\n code: PathValidationError.NULL_BYTE,\n };\n }\n\n // Check path length\n if (path.length > MAX_PATH_LENGTH) {\n return {\n valid: false,\n error: `Path exceeds maximum length of ${MAX_PATH_LENGTH}`,\n code: PathValidationError.PATH_TOO_LONG,\n };\n }\n\n // Check forbidden patterns\n for (const pattern of FORBIDDEN_PATH_PATTERNS) {\n if (pattern.test(path)) {\n return {\n valid: false,\n error: `Path contains forbidden pattern: ${pattern}`,\n code: PathValidationError.FORBIDDEN_PATTERN,\n };\n }\n }\n\n // Check for excessive directory traversal\n const parts = normalizeSeparators(path).split(\"/\");\n let depth = 0;\n let maxDepth = 0;\n\n for (const part of parts) {\n if (part === \"..\") {\n depth++;\n maxDepth = Math.max(maxDepth, depth);\n } else if (part !== \".\" && part !== \"\") {\n depth = 0;\n }\n }\n\n if (maxDepth > MAX_PATH_TRAVERSAL_DEPTH) {\n return {\n valid: false,\n error: `Path has excessive traversal depth (${maxDepth} > ${MAX_PATH_TRAVERSAL_DEPTH})`,\n code: PathValidationError.EXCESSIVE_TRAVERSAL,\n };\n }\n\n return { valid: true };\n}\n\n/**\n * Get canonical path by resolving symlinks\n * Falls back to path resolution if adapter not available\n */\nasync function getCanonicalPath(\n path: string,\n adapter?: RuntimeAdapter,\n followSymlinks = false,\n): Promise<{ path: string; isSymlink: boolean }> {\n // If no adapter or not following symlinks, just resolve path segments\n if (!adapter || !followSymlinks) {\n return {\n path: resolvePathSegments(path),\n isSymlink: false,\n };\n }\n\n try {\n const stat = await adapter.fs.stat(path);\n\n if (stat.isSymlink) {\n return {\n path: resolvePathSegments(path),\n isSymlink: true,\n };\n }\n\n return {\n path: resolvePathSegments(path),\n isSymlink: false,\n };\n } catch {\n return {\n path: resolvePathSegments(path),\n isSymlink: false,\n };\n }\n}\n\n/**\n * Validate path against allowed directories\n */\nfunction validateAllowedDirs(\n canonicalPath: string,\n baseDir: string,\n allowedDirs: string[],\n): ValidationResult {\n const normalizedBase = normalizeSeparators(baseDir).replace(/\\/$/, \"\");\n const normalizedPath = normalizeSeparators(canonicalPath).replace(/\\/$/, \"\");\n\n // Path must be within base directory\n if (!isWithinDirectory(normalizedBase, normalizedPath)) {\n return {\n valid: false,\n error: `Path is outside base directory: ${baseDir}`,\n code: PathValidationError.OUTSIDE_BASE,\n };\n }\n\n // If no allowed dirs specified, any path in base is OK\n if (!allowedDirs || allowedDirs.length === 0) {\n return { valid: true, canonicalPath };\n }\n\n // Check if path is in one of the allowed directories\n const relativePath = normalizedPath === normalizedBase\n ? \"\"\n : normalizedPath.slice(normalizedBase.length + 1);\n\n if (!relativePath) {\n // Base directory itself is always allowed\n return { valid: true, canonicalPath };\n }\n\n const topLevelDir = relativePath.split(\"/\")[0] ?? \"\";\n\n if (!topLevelDir || !allowedDirs.includes(topLevelDir)) {\n return {\n valid: false,\n error: `Access to directory '${topLevelDir}' not allowed. Allowed: ${allowedDirs.join(\", \")}`,\n code: PathValidationError.NOT_IN_ALLOWLIST,\n };\n }\n\n return { valid: true, canonicalPath };\n}\n\n/**\n * Validate a file path for security\n *\n * This is the main validation function that should be used for all file operations.\n * It implements defense-in-depth with multiple layers of validation.\n *\n * @param path - Path to validate (can be relative or absolute)\n * @param options - Validation options\n * @returns Validation result with canonical path if valid\n *\n * @example\n * ```typescript\n * const result = await validatePath(\"../../../etc/passwd\", {\n * baseDir: \"/project\",\n * allowedDirs: [\"app\", \"pages\", \"public\"],\n * });\n *\n * if (!result.valid) {\n * console.error(`Invalid path: ${result.error}`);\n * }\n * ```\n */\nexport async function validatePath(\n path: string,\n options: ValidationOptions,\n): Promise<ValidationResult> {\n const {\n level = \"normal\",\n baseDir,\n allowedDirs = [],\n followSymlinks = false,\n checkExists = false,\n adapter,\n allowAbsolute = false,\n } = options;\n\n // Basic validation\n const basicResult = validatePathBasics(path);\n if (!basicResult.valid) {\n return basicResult;\n }\n\n // Normalize path\n const normalized = normalizeSeparators(path);\n\n // Handle absolute paths\n let targetPath: string;\n if (isAbsolutePath(normalized)) {\n if (!allowAbsolute && level === \"strict\") {\n return {\n valid: false,\n error: \"Absolute paths not allowed in strict mode\",\n code: PathValidationError.ABSOLUTE_PATH_DENIED,\n };\n }\n targetPath = normalized;\n } else {\n // Relative path - join with base directory\n targetPath = joinPaths(baseDir, normalized);\n }\n\n // Get canonical path (resolve .., symlinks if enabled)\n const { path: canonicalPath, isSymlink } = await getCanonicalPath(\n targetPath,\n adapter,\n followSymlinks,\n );\n\n // In strict mode, reject symlinks\n if (isSymlink && level === \"strict\") {\n return {\n valid: false,\n error: \"Symlinks not allowed in strict mode\",\n code: PathValidationError.SYMLINK_DETECTED,\n };\n }\n\n // Validate against allowed directories\n const allowResult = validateAllowedDirs(canonicalPath, baseDir, allowedDirs);\n if (!allowResult.valid) {\n return allowResult;\n }\n\n // Check file existence if requested\n if (checkExists && adapter) {\n try {\n await adapter.fs.stat(canonicalPath);\n } catch {\n return {\n valid: false,\n error: `File not found: ${canonicalPath}`,\n code: PathValidationError.FILE_NOT_FOUND,\n };\n }\n }\n\n return {\n valid: true,\n canonicalPath,\n };\n}\n\n/**\n * Validate a path synchronously (without filesystem access)\n *\n * This is faster but less secure than validatePath() as it cannot\n * resolve symlinks or check file existence. Use for pre-validation\n * before filesystem operations.\n *\n * @param path - Path to validate\n * @param options - Validation options (adapter is ignored)\n * @returns Validation result\n */\nexport function validatePathSync(\n path: string,\n options: ValidationOptions,\n): ValidationResult {\n const {\n level = \"normal\",\n baseDir,\n allowedDirs = [],\n allowAbsolute = false,\n } = options;\n\n // Basic validation\n const basicResult = validatePathBasics(path);\n if (!basicResult.valid) {\n return basicResult;\n }\n\n // Normalize and resolve path\n const normalized = normalizeSeparators(path);\n\n let targetPath: string;\n if (isAbsolutePath(normalized)) {\n if (!allowAbsolute && level === \"strict\") {\n return {\n valid: false,\n error: \"Absolute paths not allowed in strict mode\",\n code: PathValidationError.ABSOLUTE_PATH_DENIED,\n };\n }\n targetPath = normalized;\n } else {\n targetPath = joinPaths(baseDir, normalized);\n }\n\n const canonicalPath = resolvePathSegments(targetPath);\n\n // Validate against allowed directories\n return validateAllowedDirs(canonicalPath, baseDir, allowedDirs);\n}\n\n/**\n * Create a validation function with preset options\n *\n * Useful for creating validators for specific contexts.\n *\n * @param defaultOptions - Default validation options\n * @returns Validation function\n *\n * @example\n * ```typescript\n * const validateAppPath = createValidator({\n * baseDir: \"/project\",\n * allowedDirs: [\"app\", \"components\", \"lib\"],\n * level: \"strict\",\n * });\n *\n * const result = await validateAppPath(\"app/page.tsx\");\n * ```\n */\nexport function createValidator(defaultOptions: ValidationOptions) {\n return (path: string, overrides?: Partial<ValidationOptions>): Promise<ValidationResult> => {\n return validatePath(path, { ...defaultOptions, ...overrides });\n };\n}\n\n/**\n * Common validation presets for different contexts\n */\nexport const ValidationPresets = {\n /**\n * Strict validation for user-provided paths\n */\n userInput: (baseDir: string): ValidationOptions => ({\n baseDir,\n level: \"strict\",\n allowedDirs: [\"app\", \"pages\", \"public\", \"components\", \"lib\"],\n followSymlinks: false,\n checkExists: true,\n allowAbsolute: false,\n }),\n\n /**\n * Normal validation for internal operations\n */\n internal: (baseDir: string): ValidationOptions => ({\n baseDir,\n level: \"normal\",\n followSymlinks: false,\n checkExists: false,\n allowAbsolute: false,\n }),\n\n /**\n * Permissive validation for build operations\n */\n build: (baseDir: string): ValidationOptions => ({\n baseDir,\n level: \"permissive\",\n followSymlinks: true,\n checkExists: false,\n allowAbsolute: true,\n }),\n\n /**\n * Static file serving validation\n */\n static: (baseDir: string): ValidationOptions => ({\n baseDir,\n level: \"normal\",\n allowedDirs: [\"dist\", \"public\"],\n followSymlinks: false,\n checkExists: true,\n allowAbsolute: false,\n }),\n};\n\n/**\n * Sanitize a path for safe use in error messages\n * Removes potentially sensitive information\n */\nexport function sanitizePathForDisplay(path: string, baseDir: string): string {\n const normalized = normalizeSeparators(path);\n const normalizedBase = normalizeSeparators(baseDir);\n\n if (normalized.startsWith(normalizedBase)) {\n return normalized.slice(normalizedBase.length).replace(/^\\//, \"\");\n }\n\n // For paths outside base, show only filename\n const parts = normalized.split(\"/\");\n return parts[parts.length - 1] || normalized;\n}\n", "/**\n * Secure Filesystem Wrapper\n *\n * Provides automatic path validation for all filesystem operations.\n * Wraps RuntimeAdapter filesystem methods with security checks.\n *\n * Features:\n * - Automatic path validation before all operations\n * - Configurable validation levels per context\n * - Protection against path traversal attacks\n * - Audit logging for security events\n * - Drop-in replacement for adapter.fs\n *\n * @module security/secure-fs\n */\n\nimport type {\n DirEntry,\n FileInfo,\n FileWatcher,\n RuntimeAdapter,\n} from \"@veryfront/platform/adapters/base.ts\";\nimport { logger } from \"@veryfront/utils\";\nimport {\n sanitizePathForDisplay,\n validatePath,\n validatePathSync,\n type ValidationOptions,\n ValidationPresets,\n type ValidationResult,\n} from \"./path-validation.ts\";\n\n/**\n * Security context for filesystem operations\n */\nexport type SecurityContext =\n | \"user-input\" // User-provided paths (strict)\n | \"static-serving\" // Static file serving\n | \"build\" // Build-time operations (permissive)\n | \"internal\" // Internal framework operations\n | \"route-discovery\" // Route discovery operations\n | \"module-loading\"; // Module loading operations\n\n/**\n * Secure filesystem wrapper configuration\n */\nexport interface SecureFsConfig {\n /** Base directory to restrict operations to */\n baseDir: string;\n\n /** Runtime adapter to wrap */\n adapter: RuntimeAdapter;\n\n /** Security context (determines validation strictness) */\n context?: SecurityContext;\n\n /** Custom validation options (overrides context preset) */\n validationOptions?: Partial<ValidationOptions>;\n\n /** Whether to throw on validation errors (default: true) */\n throwOnError?: boolean;\n\n /** Callback for security events */\n onSecurityEvent?: (event: SecurityEvent) => void;\n}\n\n/**\n * Security event for auditing\n */\nexport interface SecurityEvent {\n type: \"validation-failed\" | \"validation-passed\" | \"operation-blocked\";\n operation: string;\n path: string;\n error?: string;\n code?: string;\n timestamp: Date;\n}\n\n/**\n * Get validation options for a security context\n */\nfunction getContextValidationOptions(\n context: SecurityContext,\n baseDir: string,\n): ValidationOptions {\n switch (context) {\n case \"user-input\":\n return ValidationPresets.userInput(baseDir);\n case \"static-serving\":\n return ValidationPresets.static(baseDir);\n case \"build\":\n return ValidationPresets.build(baseDir);\n case \"route-discovery\":\n return {\n baseDir,\n level: \"normal\",\n allowedDirs: [\"app\", \"pages\", \"routes\", \"api\"],\n followSymlinks: false,\n allowAbsolute: false,\n };\n case \"module-loading\":\n return {\n baseDir,\n level: \"normal\",\n allowedDirs: [\n \"app\",\n \"pages\",\n \"components\",\n \"lib\",\n \"modules\",\n \"server\",\n \"client\",\n \"shared\",\n \"islands\",\n ],\n followSymlinks: false,\n allowAbsolute: true, // Allow node_modules, etc.\n };\n case \"internal\":\n default:\n return ValidationPresets.internal(baseDir);\n }\n}\n\n/**\n * Secure filesystem wrapper\n *\n * Drop-in replacement for adapter.fs with automatic path validation.\n */\nexport class SecureFs {\n private config: Required<SecureFsConfig>;\n private validationOptions: ValidationOptions;\n\n constructor(config: SecureFsConfig) {\n this.config = {\n context: \"internal\",\n throwOnError: true,\n onSecurityEvent: () => {},\n validationOptions: {},\n ...config,\n };\n\n const contextOptions = getContextValidationOptions(\n this.config.context,\n this.config.baseDir,\n );\n\n this.validationOptions = {\n ...contextOptions,\n ...this.config.validationOptions,\n baseDir: this.config.baseDir,\n adapter: this.config.adapter,\n };\n }\n\n /**\n * Validate a path before operation\n */\n private async validatePathForOperation(\n path: string,\n operation: string,\n ): Promise<ValidationResult> {\n const result = await validatePath(path, this.validationOptions);\n\n // Emit security event\n this.config.onSecurityEvent({\n type: result.valid ? \"validation-passed\" : \"validation-failed\",\n operation,\n path: sanitizePathForDisplay(path, this.config.baseDir),\n error: result.error,\n code: result.code,\n timestamp: new Date(),\n });\n\n // Throw if validation failed and throwOnError is true\n if (!result.valid && this.config.throwOnError) {\n throw new SecurityError(\n `Path validation failed for ${operation}: ${result.error}`,\n result.code,\n path,\n );\n }\n\n return result;\n }\n\n /**\n * Validate a path synchronously\n */\n private validatePathSync(path: string, operation: string): ValidationResult {\n const result = validatePathSync(path, this.validationOptions);\n\n // Emit security event\n this.config.onSecurityEvent({\n type: result.valid ? \"validation-passed\" : \"validation-failed\",\n operation,\n path: sanitizePathForDisplay(path, this.config.baseDir),\n error: result.error,\n code: result.code,\n timestamp: new Date(),\n });\n\n // Throw if validation failed and throwOnError is true\n if (!result.valid && this.config.throwOnError) {\n throw new SecurityError(\n `Path validation failed for ${operation}: ${result.error}`,\n result.code,\n path,\n );\n }\n\n return result;\n }\n\n async readFile(path: string): Promise<string> {\n const validation = await this.validatePathForOperation(path, \"readFile\");\n if (!validation.valid || !validation.canonicalPath) {\n throw new SecurityError(\"Invalid path\", validation.code, path);\n }\n return await this.config.adapter.fs.readFile(validation.canonicalPath);\n }\n\n async readFileBytes(path: string): Promise<Uint8Array> {\n const validation = await this.validatePathForOperation(path, \"readFileBytes\");\n if (!validation.valid || !validation.canonicalPath) {\n throw new SecurityError(\"Invalid path\", validation.code, path);\n }\n\n const reader = this.config.adapter.fs.readFileBytes;\n if (reader) {\n return await reader.call(this.config.adapter.fs, validation.canonicalPath);\n }\n\n const content = await this.config.adapter.fs.readFile(validation.canonicalPath);\n return new TextEncoder().encode(content);\n }\n\n async writeFile(path: string, content: string): Promise<void> {\n const validation = await this.validatePathForOperation(path, \"writeFile\");\n if (!validation.valid || !validation.canonicalPath) {\n throw new SecurityError(\"Invalid path\", validation.code, path);\n }\n await this.config.adapter.fs.writeFile(validation.canonicalPath, content);\n }\n\n async stat(path: string): Promise<FileInfo> {\n const validation = await this.validatePathForOperation(path, \"stat\");\n if (!validation.valid || !validation.canonicalPath) {\n throw new SecurityError(\"Invalid path\", validation.code, path);\n }\n return await this.config.adapter.fs.stat(validation.canonicalPath);\n }\n\n async mkdir(path: string, options?: { recursive?: boolean }): Promise<void> {\n const validation = await this.validatePathForOperation(path, \"mkdir\");\n if (!validation.valid || !validation.canonicalPath) {\n throw new SecurityError(\"Invalid path\", validation.code, path);\n }\n await this.config.adapter.fs.mkdir(validation.canonicalPath, options);\n }\n\n async remove(path: string, options?: { recursive?: boolean }): Promise<void> {\n const validation = await this.validatePathForOperation(path, \"remove\");\n if (!validation.valid || !validation.canonicalPath) {\n throw new SecurityError(\"Invalid path\", validation.code, path);\n }\n await this.config.adapter.fs.remove(validation.canonicalPath, options);\n }\n\n async exists(path: string): Promise<boolean> {\n const validation = await this.validatePathForOperation(path, \"exists\");\n if (!validation.valid || !validation.canonicalPath) {\n return false;\n }\n return await this.config.adapter.fs.exists(validation.canonicalPath);\n }\n\n readDir(path: string): AsyncIterable<DirEntry> {\n const validation = this.validatePathSync(path, \"readDir\");\n if (!validation.valid || !validation.canonicalPath) {\n throw new SecurityError(\"Invalid path\", validation.code, path);\n }\n return this.config.adapter.fs.readDir(validation.canonicalPath);\n }\n\n async makeTempDir(prefix: string): Promise<string> {\n return await this.config.adapter.fs.makeTempDir(prefix);\n }\n\n watch(\n paths: string | string[],\n options?: { recursive?: boolean; signal?: AbortSignal },\n ): FileWatcher {\n const pathArray = Array.isArray(paths) ? paths : [paths];\n const validatedPaths: string[] = [];\n\n for (const path of pathArray) {\n const validation = this.validatePathSync(path, \"watch\");\n if (validation.valid && validation.canonicalPath) {\n validatedPaths.push(validation.canonicalPath);\n } else if (this.config.throwOnError) {\n throw new SecurityError(\"Invalid path\", validation.code, path);\n }\n }\n\n if (validatedPaths.length === 0) {\n throw new SecurityError(\n \"No valid paths to watch\",\n \"NO_VALID_PATHS\",\n paths.toString(),\n );\n }\n\n return this.config.adapter.fs.watch(\n validatedPaths.length === 1 ? validatedPaths[0]! : validatedPaths,\n options,\n );\n }\n\n /**\n * Get underlying adapter (use with caution)\n * This bypasses security checks\n */\n getUnsafeAdapter(): RuntimeAdapter {\n logger.warn(\n \"[SecureFs] Using unsafe adapter - security checks bypassed!\",\n );\n return this.config.adapter;\n }\n\n /**\n * Update validation options at runtime\n */\n updateValidationOptions(options: Partial<ValidationOptions>): void {\n this.validationOptions = {\n ...this.validationOptions,\n ...options,\n };\n }\n\n /**\n * Change security context\n */\n setContext(context: SecurityContext): void {\n const contextOptions = getContextValidationOptions(\n context,\n this.config.baseDir,\n );\n this.validationOptions = {\n ...contextOptions,\n ...this.config.validationOptions,\n adapter: this.config.adapter,\n };\n this.config.context = context;\n }\n}\n\n/**\n * Security error thrown by SecureFs\n */\nexport class SecurityError extends Error {\n constructor(\n message: string,\n public code?: string,\n public path?: string,\n ) {\n super(message);\n this.name = \"SecurityError\";\n }\n}\n\n/**\n * Create a secure filesystem wrapper\n *\n * @example\n * ```typescript\n * const secureFs = createSecureFs({\n * baseDir: ctx.projectDir,\n * adapter: ctx.adapter,\n * context: \"user-input\",\n * onSecurityEvent: (event) => {\n * if (event.type === \"validation-failed\") {\n * console.error(`Security: Blocked ${event.operation} on ${event.path}`);\n * }\n * }\n * });\n *\n * // Use like adapter.fs but with automatic validation\n * const content = await secureFs.readFile(\"app/page.tsx\");\n * ```\n */\nexport function createSecureFs(config: SecureFsConfig): SecureFs {\n return new SecureFs(config);\n}\n\n/**\n * Wrap an existing adapter with security\n *\n * @example\n * ```typescript\n * const originalAdapter = ctx.adapter;\n * const secureAdapter = wrapAdapterWithSecurity(originalAdapter, {\n * baseDir: ctx.projectDir,\n * context: \"build\",\n * });\n *\n * // secureAdapter.fs is now a SecureFs instance\n * ```\n */\nexport function wrapAdapterWithSecurity(\n adapter: RuntimeAdapter,\n options: Omit<SecureFsConfig, \"adapter\">,\n): RuntimeAdapter & { secureFs: SecureFs } {\n const secureFs = createSecureFs({\n ...options,\n adapter,\n });\n\n // Create a new adapter with secure fs\n return {\n ...adapter,\n fs: secureFs,\n secureFs, // Keep reference to SecureFs for advanced usage\n };\n}\n", "import type { Route, RouteMatch } from \"@veryfront/routing/matchers/types.ts\";\nimport { getEnv } from \"../../platform/compat/process.ts\";\nimport { LRUCache } from \"@veryfront/utils/lru-wrapper.ts\";\n\nexport type { Route, RouteMatch };\n\nexport class DynamicRouter {\n private routes: Map<\n string,\n {\n regex: RegExp;\n route: Route;\n paramNames: string[];\n isOptionalCatchAll: boolean;\n isCatchAll: boolean;\n }\n > = new Map();\n private routeCache: LRUCache<string, RouteMatch | null>;\n\n constructor() {\n const disableIntervals = shouldDisableLruInterval();\n this.routeCache = new LRUCache<string, RouteMatch | null>({\n maxEntries: 500,\n ttlMs: disableIntervals ? undefined : 5 * 60 * 1000,\n });\n }\n\n addRoute(pattern: string, page: string): void {\n const originalPattern = pattern;\n let regex = pattern;\n let isOptionalCatchAll = false;\n let isCatchAll = false;\n\n const orderedParamNames: string[] = [];\n for (\n const match of originalPattern.matchAll(/\\[\\[\\.\\.\\.(\\w+)\\]\\]|\\[\\.\\.\\.(\\w+)\\]|\\[(\\w+)\\]/g)\n ) {\n if (match[1]) {\n const name = match[1];\n orderedParamNames.push(name);\n isOptionalCatchAll = true;\n isCatchAll = true;\n } else if (match[2]) {\n const name = match[2];\n orderedParamNames.push(name);\n isCatchAll = true;\n } else if (match[3]) {\n orderedParamNames.push(match[3]);\n }\n }\n const paramNames = orderedParamNames;\n\n regex = regex.replace(/\\/?\\[\\[\\.\\.\\.([^\\]]+)\\]\\]/g, () => {\n return \"(?:/(.+))?\";\n });\n\n regex = regex.replace(/\\[\\.\\.\\.([^\\]]+)\\]/g, () => {\n return \"(.+)\";\n });\n\n regex = regex.replace(/\\[([^\\]]+)\\]/g, () => {\n return \"([^/]+)\";\n });\n\n if (pattern !== \"/\" && pattern.endsWith(\"/\")) {\n pattern = pattern.slice(0, -1);\n if (regex.endsWith(\"/\")) {\n regex = regex.slice(0, -1);\n }\n }\n\n const route: Route = { pattern, page };\n this.routes.set(pattern, {\n regex: new RegExp(`^${regex}$`),\n route,\n paramNames,\n isOptionalCatchAll,\n isCatchAll,\n });\n }\n\n private normalizePathname(path: string): string {\n return path !== \"/\" && path.endsWith(\"/\") ? path.slice(0, -1) : path;\n }\n\n private sortRoutesByPriority(): Array<\n [\n string,\n {\n regex: RegExp;\n route: Route;\n paramNames: string[];\n isOptionalCatchAll: boolean;\n isCatchAll: boolean;\n },\n ]\n > {\n return Array.from(this.routes.entries()).sort(([patternA], [patternB]) => {\n const hasParamsA = patternA.includes(\"[\");\n const hasParamsB = patternB.includes(\"[\");\n const isCatchAllA = patternA.includes(\"[...\");\n const isCatchAllB = patternB.includes(\"[...\");\n\n if (!hasParamsA && hasParamsB) return -1;\n if (hasParamsA && !hasParamsB) return 1;\n if (!isCatchAllA && isCatchAllB) return -1;\n if (isCatchAllA && !isCatchAllB) return 1;\n\n return patternB.split(\"/\").length - patternA.split(\"/\").length;\n });\n }\n\n match(path: string): RouteMatch | null {\n const normalizedPath = this.normalizePathname(path);\n\n const cached = this.routeCache.get(normalizedPath);\n if (cached !== undefined) {\n return cached;\n }\n\n const sortedRoutes = this.sortRoutesByPriority();\n\n for (const [, routeData] of sortedRoutes) {\n const match = normalizedPath.match(routeData.regex);\n if (match) {\n const params = this.extractParams(\n match,\n routeData.paramNames,\n routeData.route,\n );\n const result = { params, route: routeData.route };\n this.routeCache.set(normalizedPath, result);\n return result;\n }\n }\n\n this.routeCache.set(normalizedPath, null);\n return null;\n }\n\n private extractParams(\n match: RegExpMatchArray,\n paramNames: string[],\n route: Route,\n ): Record<string, string | string[]> {\n const params: Record<string, string | string[]> = {};\n\n const catchAllParamNames = new Set<string>();\n route.pattern.replace(/\\[\\[\\.\\.\\.(\\w+)\\]\\]/g, (_, paramName: string) => {\n catchAllParamNames.add(paramName);\n return \"\";\n });\n route.pattern.replace(/\\[\\.\\.\\.(\\w+)\\]/g, (_, paramName: string) => {\n catchAllParamNames.add(paramName);\n return \"\";\n });\n\n for (let i = 0; i < paramNames.length; i++) {\n const paramName = paramNames[i] as string;\n const value = match[i + 1];\n\n if (catchAllParamNames.has(paramName)) {\n const segments = value ? value.split(\"/\").filter((segment) => segment.length > 0) : [];\n params[paramName] = segments.map((segment) => decodeURIComponent(segment));\n } else {\n params[paramName] = decodeURIComponent(value ?? \"\");\n }\n }\n\n return params;\n }\n\n listRoutes(): Route[] {\n return Array.from(this.routes.values()).map(({ route }) => route);\n }\n\n clear(): void {\n this.routes.clear();\n this.routeCache.destroy();\n }\n\n clearCache(): void {\n this.routeCache.clear();\n }\n\n destroy(): void {\n this.clear();\n }\n}\n\nfunction shouldDisableLruInterval(): boolean {\n if ((globalThis as Record<string, unknown>).__vfDisableLruInterval === true) {\n return true;\n }\n try {\n return getEnv(\"VF_DISABLE_LRU_INTERVAL\") === \"1\";\n } catch (_error) {\n return false;\n }\n}\n", "import { serverLogger as logger } from \"@veryfront/utils\";\nimport type { BuildResult, Plugin } from \"esbuild\";\nimport type { RuntimeAdapter } from \"@veryfront/platform/adapters/index.ts\";\nimport type { VeryfrontConfig } from \"@veryfront/config\";\nimport { createHTTPPlugin } from \"./esbuild-plugin.ts\";\nimport { validateHTTPImports } from \"./http-validator.ts\";\nimport { loadSecurityConfig } from \"./security-config.ts\";\nimport type { APIRoute, LoadModuleOptions } from \"./types.ts\";\nimport { createError, toError } from \"../../../core/errors/veryfront-error.ts\";\nimport { createFileSystem, FileSystem } from \"../../../platform/compat/fs.ts\";\nimport * as pathHelper from \"../../../platform/compat/path-helper.ts\";\nimport { isDeno, isNode } from \"../../../platform/compat/runtime.ts\";\n\nexport async function loadHandlerModule(options: LoadModuleOptions): Promise<APIRoute | null> {\n const { projectDir, modulePath, adapter, config } = options;\n const fs = createFileSystem();\n\n try {\n let module: APIRoute;\n\n if (modulePath.endsWith(\".js\")) {\n // JS files can be loaded directly\n module = await loadJSModule(modulePath);\n } else if (isDeno) {\n // In Deno, directly import TypeScript files without bundling\n // This allows modules to share the same runtime context (including singletons like agentRegistry)\n module = await loadTSModuleDirect(modulePath);\n } else {\n // In Node.js, use esbuild to transpile TypeScript\n // Singletons are shared via globalThis pattern (see src/ai/agent/composition.ts etc.)\n module = await loadAndTranspileModule(modulePath, projectDir, adapter, fs, config);\n }\n\n return extractAPIRouteHandlers(module);\n } catch (error: unknown) {\n const errorMsg = error instanceof Error ? error.message : String(error);\n logger.error(`Failed to load API handler ${modulePath}:`, error);\n throw toError(createError({\n type: \"api\",\n message: `Failed to load API handler: ${errorMsg}`,\n }));\n }\n}\n\n/**\n * Directly import a TypeScript module in Deno without bundling.\n * This allows the module to share the same runtime context as the dev server,\n * enabling auto-discovery features like agentRegistry to work.\n */\nasync function loadTSModuleDirect(modulePath: string): Promise<APIRoute> {\n // Add cache buster for HMR\n const cacheBuster = `?v=${Date.now()}`;\n const url = modulePath.startsWith(\"file://\")\n ? `${modulePath}${cacheBuster}`\n : `file://${modulePath}${cacheBuster}`;\n\n logger.debug(`[API] Direct import (Deno): ${url}`);\n return await import(url);\n}\n\nasync function loadJSModule(modulePath: string): Promise<APIRoute> {\n return await import(`file://${modulePath}`);\n}\n\nfunction createImportMapPlugin(\n projectDir: string,\n adapter: RuntimeAdapter,\n config?: VeryfrontConfig,\n): Plugin {\n const importMap = config?.resolve?.importMap?.imports || {};\n const hasImportMap = Object.keys(importMap).length > 0;\n\n if (!hasImportMap) {\n return {\n name: \"import-map\",\n setup() {},\n };\n }\n\n logger.info(`[API] Using import map with ${Object.keys(importMap).length} entries`);\n\n return {\n name: \"import-map\",\n setup(build) {\n build.onResolve({ filter: /.*/ }, (args) => {\n if (args.path.startsWith(\"http://\") || args.path.startsWith(\"https://\")) {\n return undefined;\n }\n\n if (args.path.startsWith(\"node:\")) {\n return { path: args.path, external: true };\n }\n\n if (args.path === \"ai/react\" || args.path.startsWith(\"ai/react/\")) {\n return { path: args.path, external: true };\n }\n\n if (\n args.path.includes(\"bundle-manifest-kv\") ||\n args.path.includes(\"bundle-manifest-redis\")\n ) {\n return { path: args.path, external: true };\n }\n\n if (args.namespace === \"import-map\" && args.path.startsWith(\".\")) {\n const importerDir = pathHelper.dirname(args.importer);\n const absolutePath = pathHelper.resolve(importerDir, args.path);\n\n logger.debug(\n `[API] Import map relative resolve: ${args.path} (from ${args.importer}) -> ${absolutePath}`,\n );\n\n return {\n path: absolutePath,\n namespace: \"import-map\",\n };\n }\n\n if (pathHelper.isAbsolute(args.path) && args.namespace !== \"import-map\") {\n return undefined;\n }\n\n let resolvedPath: string | undefined;\n\n if (importMap[args.path]) {\n resolvedPath = importMap[args.path];\n } else {\n for (const [key, value] of Object.entries(importMap)) {\n if (key.endsWith(\"/\") && args.path.startsWith(key)) {\n const suffix = args.path.slice(key.length);\n resolvedPath = value + suffix;\n break;\n }\n }\n }\n\n if (resolvedPath) {\n if (resolvedPath.startsWith(\"http://\") || resolvedPath.startsWith(\"https://\")) {\n logger.debug(`[API] Import map resolved to HTTP URL: ${args.path} -> ${resolvedPath}`);\n return undefined;\n }\n\n const absolutePath = pathHelper.isAbsolute(resolvedPath)\n ? resolvedPath\n : pathHelper.resolve(projectDir, resolvedPath);\n\n logger.debug(`[API] Import map resolved: ${args.path} -> ${absolutePath}`);\n\n return {\n path: absolutePath,\n namespace: \"import-map\",\n };\n }\n\n return undefined;\n });\n\n build.onLoad({ filter: /.*/, namespace: \"import-map\" }, async (args) => {\n try {\n let filePath = args.path;\n let contents = \"\";\n\n try {\n contents = await adapter.fs.readFile(filePath);\n } catch {\n const extensions = [\".ts\", \".tsx\", \".js\", \".jsx\", \".mjs\"];\n let found = false;\n\n for (const ext of extensions) {\n try {\n const pathWithExt = filePath + ext;\n contents = await adapter.fs.readFile(pathWithExt);\n filePath = pathWithExt;\n found = true;\n break;\n } catch {\n // Ignore error, try next extension\n }\n }\n\n if (!found) {\n throw toError(createError({\n type: \"file\",\n message: `File not found: ${filePath}`,\n }));\n }\n }\n\n const ext = filePath.split(\".\").pop() || \"\";\n const loader = ext === \"tsx\"\n ? \"tsx\"\n : ext === \"jsx\"\n ? \"jsx\"\n : ext === \"ts\"\n ? \"ts\"\n : ext === \"js\"\n ? \"js\"\n : ext === \"json\"\n ? \"json\"\n : \"js\";\n\n return {\n contents,\n loader,\n resolveDir: pathHelper.dirname(filePath),\n };\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n logger.error(`[API] Failed to load file via import map: ${args.path}`, error);\n return {\n errors: [{ text: `Failed to load: ${msg}` }],\n };\n }\n });\n },\n };\n}\n\nasync function loadAndTranspileModule(\n modulePath: string,\n projectDir: string,\n adapter: RuntimeAdapter,\n fs: FileSystem, // Pass fs compat instance\n config?: VeryfrontConfig,\n): Promise<APIRoute> {\n // Try to resolve the module path with various extensions if not found\n let resolvedPath = modulePath;\n let source: string | undefined;\n\n try {\n source = await adapter.fs.readFile(modulePath);\n } catch {\n // If file not found, try with common extensions\n const extensions = [\".ts\", \".tsx\", \".js\", \".jsx\", \".mjs\"];\n\n for (const ext of extensions) {\n try {\n const pathWithExt = modulePath + ext;\n source = await adapter.fs.readFile(pathWithExt);\n resolvedPath = pathWithExt;\n break;\n } catch {\n // Continue trying other extensions\n }\n }\n\n if (source === undefined) {\n throw toError(createError({\n type: \"file\",\n message: `File not found: ${modulePath} (tried extensions: ${extensions.join(\", \")})`,\n }));\n }\n }\n\n const isTsx = resolvedPath.endsWith(\".tsx\");\n const isJsx = resolvedPath.endsWith(\".jsx\");\n const loader = isTsx ? \"tsx\" : isJsx ? \"jsx\" : resolvedPath.endsWith(\".ts\") ? \"ts\" : \"js\";\n\n const allowedHosts = await loadSecurityConfig(projectDir, adapter);\n validateHTTPImports(source, allowedHosts);\n\n const { build } = await import(\"esbuild\");\n\n const plugins = [\n createImportMapPlugin(projectDir, adapter, config),\n createHTTPPlugin(allowedHosts),\n ];\n\n const externalPackages = [\n \"ai\",\n \"ai/*\",\n \"ai/react\",\n \"@ai-sdk/*\",\n \"zod\",\n \"node:*\",\n // Veryfront packages - should use runtime resolution, not bundled\n \"veryfront\",\n \"veryfront/*\",\n // OpenTelemetry packages used by veryfront/ai\n \"@opentelemetry/*\",\n // Path module - Node.js built-in\n \"path\",\n ];\n\n // Use the directory containing the source file as resolveDir\n // This allows relative imports like ../../../ai/agents to resolve correctly\n const resolveDir = pathHelper.dirname(resolvedPath);\n\n const result: BuildResult = await build({\n bundle: true,\n write: false,\n format: \"esm\",\n platform: \"neutral\",\n target: \"es2022\",\n jsx: \"automatic\",\n jsxImportSource: \"react\",\n resolveExtensions: [\".ts\", \".tsx\", \".js\", \".jsx\", \".mjs\"],\n external: externalPackages,\n stdin: {\n contents: source,\n loader,\n resolveDir,\n sourcefile: resolvedPath,\n },\n plugins,\n });\n\n if (result.errors && result.errors.length > 0) {\n const first = result.errors[0]?.text || \"unknown error\";\n throw toError(createError({\n type: \"api\",\n message: `[API] handler build failed: ${first}`,\n }));\n }\n\n logger.info(`[API] built handler ${resolvedPath}`);\n const js = result.outputFiles?.[0]?.text ?? \"export {}\";\n logger.debug(`[API] transpiled size ${js.length} bytes`);\n\n return await loadModuleFromCode(js, adapter, projectDir, fs);\n}\n\nasync function loadModuleFromCode(\n code: string,\n _adapter: RuntimeAdapter,\n projectDir: string,\n fs: FileSystem,\n): Promise<APIRoute> {\n const tempDir = await fs.makeTempDir({ prefix: \"vf-api-\" });\n const tempFile = pathHelper.join(tempDir, \"handler.mjs\");\n\n const transformedCode = await rewriteExternalImports(code, projectDir, fs);\n\n await fs.writeTextFile(tempFile, transformedCode);\n\n try {\n return await import(`file://${tempFile}?v=${Date.now()}`);\n } catch (e: unknown) {\n const errorMessage = e instanceof Error && e.stack ? e.stack : String(e);\n logger.error(`[API] dynamic import failed ${tempFile}: ${errorMessage}`);\n throw e;\n } finally {\n await fs.remove(tempDir, { recursive: true });\n }\n}\n\nasync function rewriteExternalImports(\n code: string,\n projectDir: string,\n fs: FileSystem,\n): Promise<string> {\n let transformed = code;\n\n // In Node.js, resolve external imports to absolute paths\n // since the temp file is outside the project's node_modules\n if (isNode) {\n try {\n const { pathToFileURL } = await import(\"node:url\");\n\n logger.debug(`[API] Rewriting external imports for Node.js, projectDir: ${projectDir}`);\n\n // Helper to resolve a package to absolute file:// URL\n const resolvePackageToFileUrl = async (packageName: string): Promise<string | null> => {\n const packagePath = pathHelper.join(projectDir, \"node_modules\", packageName);\n const packageJsonPath = pathHelper.join(packagePath, \"package.json\");\n\n try {\n const pkgJson = JSON.parse(await fs.readTextFile(packageJsonPath));\n // Try exports[\".\"].import, exports[\".\"].default, main, module in that order\n let entryPoint: string | undefined;\n\n if (pkgJson.exports) {\n const dotExport = pkgJson.exports[\".\"];\n if (typeof dotExport === \"string\") {\n entryPoint = dotExport;\n } else if (dotExport?.import) {\n entryPoint = dotExport.import;\n } else if (dotExport?.default) {\n entryPoint = dotExport.default;\n }\n }\n\n if (!entryPoint) {\n entryPoint = pkgJson.module || pkgJson.main || \"index.js\";\n }\n\n if (!entryPoint) {\n return null;\n }\n\n const resolvedPath = pathHelper.join(packagePath, entryPoint);\n return pathToFileURL(resolvedPath).href;\n } catch {\n return null;\n }\n };\n\n // List of external packages that need to be resolved to absolute paths\n const externalPackagesToResolve = [\n \"zod\",\n \"ai\",\n \"@ai-sdk/anthropic\",\n \"@ai-sdk/openai\",\n \"@ai-sdk/google\",\n \"@ai-sdk/mistral\",\n \"@ai-sdk/provider\",\n \"@ai-sdk/provider-utils\",\n ];\n\n // Resolve external packages to absolute paths\n for (const pkg of externalPackagesToResolve) {\n const escapedPkg = pkg.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n\n // Match static imports: from \"package\"\n const staticImportRegex = new RegExp(`from\\\\s+[\"']${escapedPkg}[\"']`, \"g\");\n if (staticImportRegex.test(transformed)) {\n const resolvedUrl = await resolvePackageToFileUrl(pkg);\n if (resolvedUrl) {\n transformed = transformed.replace(staticImportRegex, `from \"${resolvedUrl}\"`);\n logger.debug(`[API] Resolved ${pkg} -> ${resolvedUrl}`);\n }\n }\n\n // Match dynamic imports: import(\"package\")\n const dynamicImportRegex = new RegExp(`import\\\\s*\\\\(\\\\s*[\"']${escapedPkg}[\"']\\\\s*\\\\)`, \"g\");\n if (dynamicImportRegex.test(transformed)) {\n const resolvedUrl = await resolvePackageToFileUrl(pkg);\n if (resolvedUrl) {\n transformed = transformed.replace(dynamicImportRegex, `import(\"${resolvedUrl}\")`);\n logger.debug(`[API] Resolved dynamic import ${pkg} -> ${resolvedUrl}`);\n }\n }\n }\n\n // Manual resolution for veryfront using package.json exports\n // This is more reliable than createRequire for subpath exports\n const vfPackagePath = pathHelper.join(projectDir, \"node_modules\", \"veryfront\");\n const vfPackageJsonPath = pathHelper.join(vfPackagePath, \"package.json\");\n\n let exportsMap: Record<string, { import?: string }> = {};\n try {\n const pkgJson = JSON.parse(await fs.readTextFile(vfPackageJsonPath));\n exportsMap = pkgJson.exports || {};\n } catch (err) {\n logger.debug(`[API] Could not read veryfront package.json: ${err}`);\n }\n\n // Resolve veryfront subpath imports (e.g., veryfront/ai)\n transformed = transformed.replace(\n /from\\s+[\"'](veryfront\\/[^\"']+)[\"']/g,\n (_match, fullSpecifier: string) => {\n const subpath = \"./\" + fullSpecifier.replace(\"veryfront/\", \"\");\n const exportEntry = exportsMap[subpath];\n if (exportEntry?.import) {\n const resolvedPath = pathHelper.join(vfPackagePath, exportEntry.import);\n logger.debug(`[API] Resolved ${fullSpecifier} -> ${resolvedPath}`);\n return `from \"${pathToFileURL(resolvedPath).href}\"`;\n }\n logger.warn(`[API] No export found for ${subpath}`);\n return _match;\n },\n );\n\n // Resolve bare veryfront import\n transformed = transformed.replace(\n /from\\s+[\"']veryfront[\"']/g,\n () => {\n const exportEntry = exportsMap[\".\"];\n if (exportEntry?.import) {\n const resolvedPath = pathHelper.join(vfPackagePath, exportEntry.import);\n logger.debug(`[API] Resolved veryfront -> ${resolvedPath}`);\n return `from \"${pathToFileURL(resolvedPath).href}\"`;\n }\n return 'from \"veryfront\"';\n },\n );\n } catch (e) {\n // If node:module import fails, we're not in Node.js or something went wrong\n logger.warn(`[API] Failed to import node:module: ${e}`);\n // Fall through to Deno handling\n }\n }\n\n // For Deno, use npm: specifiers for selected packages\n // For Node.js, these are typically resolved via node_modules\n // This list should only include packages that are externalized by esbuild but need explicit npm: specifiers in Deno\n const externalPackages = [\n { pattern: /from\\s+[\"']ai[\"']/g, replacement: 'from \"npm:ai@latest\"' },\n {\n pattern: /from\\s+[\"']@ai-sdk\\/anthropic[\"']/g,\n replacement: 'from \"npm:@ai-sdk/anthropic@latest\"',\n },\n { pattern: /from\\s+[\"']@ai-sdk\\/openai[\"']/g, replacement: 'from \"npm:@ai-sdk/openai@latest\"' },\n { pattern: /from\\s+[\"']@ai-sdk\\/google[\"']/g, replacement: 'from \"npm:@ai-sdk/google@latest\"' },\n {\n pattern: /from\\s+[\"']@ai-sdk\\/mistral[\"']/g,\n replacement: 'from \"npm:@ai-sdk/mistral@latest\"',\n },\n {\n pattern: /from\\s+[\"']@ai-sdk\\/provider[\"']/g,\n replacement: 'from \"npm:@ai-sdk/provider@latest\"',\n },\n {\n pattern: /from\\s+[\"']@ai-sdk\\/provider-utils[\"']/g,\n replacement: 'from \"npm:@ai-sdk/provider-utils@latest\"',\n },\n { pattern: /from\\s+[\"']zod[\"']/g, replacement: 'from \"npm:zod@latest\"' },\n { pattern: /import\\s*\\(\\s*[\"']ai[\"']\\s*\\)/g, replacement: 'import(\"npm:ai@latest\")' },\n {\n pattern: /import\\s*\\(\\s*[\"']@ai-sdk\\/anthropic[\"']\\s*\\)/g,\n replacement: 'import(\"npm:@ai-sdk/anthropic@latest\")',\n },\n {\n pattern: /import\\s*\\(\\s*[\"']@ai-sdk\\/openai[\"']\\s*\\)/g,\n replacement: 'import(\"npm:@ai-sdk/openai@latest\")',\n },\n {\n pattern: /import\\s*\\(\\s*[\"']@ai-sdk\\/google[\"']\\s*\\)/g,\n replacement: 'import(\"npm:@ai-sdk/google@latest\")',\n },\n {\n pattern: /import\\s*\\(\\s*[\"']@ai-sdk\\/mistral[\"']\\s*\\)/g,\n replacement: 'import(\"npm:@ai-sdk/mistral@latest\")',\n },\n {\n pattern: /import\\s*\\(\\s*[\"']@ai-sdk\\/provider[\"']\\s*\\)/g,\n replacement: 'import(\"npm:@ai-sdk/provider@latest\")',\n },\n {\n pattern: /import\\s*\\(\\s*[\"']@ai-sdk\\/provider-utils[\"']\\s*\\)/g,\n replacement: 'import(\"npm:@ai-sdk/provider-utils@latest\")',\n },\n { pattern: /import\\s*\\(\\s*[\"']zod[\"']\\s*\\)/g, replacement: 'import(\"npm:zod@latest\")' },\n ];\n\n // Apply npm: specifier rewrites only if not in Node.js (i.e., in Deno)\n if (isDeno) {\n for (const { pattern, replacement } of externalPackages) {\n transformed = transformed.replace(pattern, replacement);\n }\n }\n\n return transformed;\n}\n\nfunction extractAPIRouteHandlers(module: unknown): APIRoute {\n const handler: APIRoute = {};\n\n if (!module || typeof module !== \"object\") {\n return handler;\n }\n\n const mod = module as Record<string, unknown>;\n\n if (typeof mod.GET === \"function\") handler.GET = mod.GET as APIRoute[\"GET\"];\n if (typeof mod.POST === \"function\") handler.POST = mod.POST as APIRoute[\"POST\"];\n if (typeof mod.PUT === \"function\") handler.PUT = mod.PUT as APIRoute[\"PUT\"];\n if (typeof mod.PATCH === \"function\") handler.PATCH = mod.PATCH as APIRoute[\"PATCH\"];\n if (typeof mod.DELETE === \"function\") handler.DELETE = mod.DELETE as APIRoute[\"DELETE\"];\n if (typeof mod.HEAD === \"function\") handler.HEAD = mod.HEAD as APIRoute[\"HEAD\"];\n if (typeof mod.OPTIONS === \"function\") handler.OPTIONS = mod.OPTIONS as APIRoute[\"OPTIONS\"];\n\n if (typeof mod.default === \"function\") {\n handler.default = mod.default as APIRoute[\"default\"];\n }\n\n return handler;\n}\n", "import { serverLogger as logger } from \"@veryfront/utils\";\nimport type { Message, Plugin } from \"esbuild\";\nimport { getDenoStdNodeBase } from \"@veryfront/utils\";\nimport { HTTP_MODULE_FETCH_TIMEOUT_MS, HTTP_NETWORK_CONNECT_TIMEOUT } from \"@veryfront/utils\";\n\nexport function createHTTPPlugin(allowedHosts: string[]): Plugin {\n return {\n name: \"vf-api-http-fetch\",\n setup(build: Parameters<Plugin[\"setup\"]>[0]) {\n const stdNodeBase = getDenoStdNodeBase();\n const resolvedUrls: string[] = [];\n const nodeMapped: Array<{ from: string; to: string }> = [];\n\n const mapNodeCore = (spec: string): string | null => {\n if (spec.startsWith(\"node:\")) {\n const sub = spec.slice(5);\n return `${stdNodeBase}/${sub}.ts`;\n }\n if (spec === \"buffer\") return `${stdNodeBase}/buffer.ts`;\n if (spec === \"path\") return `${stdNodeBase}/path.ts`;\n if (spec === \"fs\") return `${stdNodeBase}/fs.ts`;\n return null;\n };\n\n build.onResolve({ filter: /^(http|https):\\/\\// }, (args) => ({\n path: args.path,\n namespace: \"http-url\",\n }));\n\n build.onResolve({ filter: /^react\\/(jsx-runtime|jsx-dev-runtime)$/ }, (args) => {\n const reactUrl = `https://esm.sh/react@18/${args.path.split(\"/\")[1]}`;\n logger.debug(`[API][http] map '${args.path}' -> '${reactUrl}'`);\n return { path: reactUrl, namespace: \"http-url\" };\n });\n\n build.onResolve({ filter: /^(node:|buffer$|path$|fs$)/ }, (args) => {\n const mapped = mapNodeCore(args.path);\n if (mapped) {\n nodeMapped.push({ from: args.path, to: mapped });\n logger.debug(`[API][http] map '${args.path}' -> '${mapped}'`);\n return { path: mapped, namespace: \"http-url\" };\n }\n return undefined;\n });\n\n build.onResolve({ filter: /.*/ }, (args) => {\n if (args.namespace === \"http-url\") {\n try {\n const resolved = new URL(args.path, args.importer).toString();\n resolvedUrls.push(resolved);\n return { path: resolved, namespace: \"http-url\" };\n } catch {\n return undefined;\n }\n }\n return undefined;\n });\n\n build.onLoad({ filter: /.*/, namespace: \"http-url\" }, async (args) => {\n let requestUrl = args.path;\n try {\n const u = new URL(args.path);\n if (allowedHosts && allowedHosts.length > 0) {\n const hostUrl = `${u.protocol}//${u.host}`;\n const isAllowed = allowedHosts.some((h) => hostUrl.startsWith(h));\n if (!isAllowed) {\n const remediation =\n `Add \"${hostUrl}\" to security.remoteHosts in veryfront.config.(ts|js) or replace with an approved CDN (e.g., https://esm.sh).`;\n return {\n errors: [\n {\n text: `Remote import blocked by allow-list: ${hostUrl}. ${remediation}`,\n } as Message,\n ],\n };\n }\n }\n if (u.hostname === \"esm.sh\") {\n if (u.pathname.includes(\"/denonext/\")) {\n u.pathname = u.pathname.replace(\"/denonext/\", \"/\");\n }\n u.searchParams.set(\"target\", \"es2020\");\n u.searchParams.set(\"bundle\", \"true\");\n logger.debug(`[API][http] esm.sh rewrite: ${args.path} -> ${u.toString()}`);\n requestUrl = u.toString();\n }\n } catch (e) {\n logger.warn(\"API URL parse failed\", e);\n }\n\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), HTTP_MODULE_FETCH_TIMEOUT_MS);\n const res = await fetch(requestUrl, {\n headers: { \"user-agent\": \"Mozilla/5.0 Veryfront/1.0\" },\n signal: controller.signal,\n })\n .catch((e) => {\n return new Response(String(e?.message || e), { status: HTTP_NETWORK_CONNECT_TIMEOUT });\n })\n .finally(() => clearTimeout(timeout));\n\n if (!res.ok) {\n logger.error(`[API][http] fetch failed ${requestUrl} ${res.status}`);\n return {\n errors: [\n {\n text: `Failed to fetch ${args.path}: ${res.status}`,\n } as Message,\n ],\n };\n }\n\n const text = await res.text();\n return { contents: text, loader: \"js\" } as const;\n });\n\n logger.debug(\n `[API][http] resolvedUrls: ${resolvedUrls.length}, nodeMapped: ${nodeMapped.length}`,\n );\n },\n };\n}\n", "import { createError, toError } from \"../../../core/errors/veryfront-error.ts\";\n\nexport function validateHTTPImports(source: string, allowedHosts: string[]): void {\n const importRegex = /import\\s+(?:[\\w\\s{},*]+\\s+from\\s+)?['\"]https?:\\/\\/[^'\"]+['\"]/g;\n const dynamicImportRegex = /import\\s*\\(['\"]https?:\\/\\/[^'\"]+['\"]\\)/g;\n\n const matches = [\n ...source.matchAll(importRegex),\n ...source.matchAll(dynamicImportRegex),\n ];\n\n for (const match of matches) {\n const urlMatch = match[0].match(/https?:\\/\\/[^'\"]+/);\n if (!urlMatch) continue;\n\n const fullUrl = urlMatch[0];\n try {\n const u = new URL(fullUrl);\n const hostUrl = `${u.protocol}//${u.host}`;\n\n if (allowedHosts && allowedHosts.length > 0) {\n const isAllowed = allowedHosts.some((h) => hostUrl.startsWith(h));\n if (!isAllowed) {\n const remediation =\n `Add \"${hostUrl}\" to security.remoteHosts in veryfront.config.(ts|js) or replace with an approved CDN (e.g., https://esm.sh).`;\n throw toError(createError({\n type: \"api\",\n message:\n `[API] handler build failed: Remote import blocked by allow-list: ${hostUrl}. ${remediation}`,\n }));\n }\n }\n } catch (e) {\n if (e instanceof Error && e.message.includes(\"Remote import blocked\")) {\n throw e;\n }\n }\n }\n}\n", "import { serverLogger as logger } from \"@veryfront/utils\";\nimport type { RuntimeAdapter } from \"@veryfront/platform/adapters/index.ts\";\nimport type { VeryfrontConfig } from \"@veryfront/config\";\nimport { DEFAULT_ALLOWED_CDN_HOSTS } from \"@veryfront/utils\";\n\nexport async function loadSecurityConfig(\n projectDir: string,\n adapter: RuntimeAdapter,\n): Promise<string[]> {\n try {\n const { getConfig } = await import(\"@veryfront/config\");\n const cfg: VeryfrontConfig = await getConfig(projectDir, adapter);\n const remote = cfg?.security?.remoteHosts;\n if (Array.isArray(remote)) return remote;\n } catch (e) {\n logger.warn(\"Failed to load security.remoteHosts\", e);\n }\n return DEFAULT_ALLOWED_CDN_HOSTS;\n}\n", "/**\n * Cross-platform filesystem abstraction for CLI commands and standalone utilities.\n *\n * This module provides a synchronous-style API for filesystem operations that works\n * across Deno, Node.js, and Bun runtimes. It's designed for CLI commands and scripts\n * where you don't have access to a RuntimeAdapter context.\n *\n * For server/rendering contexts where you have an adapter, prefer using adapter.fs directly:\n * ```ts\n * const adapter = await getAdapter();\n * const content = await adapter.fs.readFile(path);\n * ```\n *\n * For CLI commands and standalone utilities, use createFileSystem():\n * ```ts\n * import { createFileSystem } from \"@veryfront/platform/compat/fs.ts\";\n * const fs = createFileSystem();\n * const content = await fs.readTextFile(path);\n * ```\n *\n * @module\n */\n\nimport type { FileInfo } from \"@veryfront/platform/adapters/base.ts\";\nimport { createError, toError } from \"../../core/errors/veryfront-error.ts\";\nimport { isDeno, isNode } from \"./runtime.ts\";\n\n/**\n * Cross-platform filesystem interface for CLI commands and standalone utilities.\n * Compatible with RuntimeAdapter.fs (FileSystemAdapter) for easy interoperability.\n */\nexport interface FileSystem {\n readTextFile(path: string): Promise<string>;\n readFile(path: string): Promise<Uint8Array>; // Changed to Uint8Array for binary\n writeTextFile(path: string, data: string): Promise<void>;\n writeFile(path: string, data: Uint8Array): Promise<void>; // Changed to Uint8Array for binary\n exists(path: string): Promise<boolean>;\n stat(path: string): Promise<FileInfo>;\n mkdir(path: string, options?: { recursive?: boolean }): Promise<void>;\n readDir(path: string): AsyncIterable<{ name: string; isFile: boolean; isDirectory: boolean }>;\n remove(path: string, options?: { recursive?: boolean }): Promise<void>;\n makeTempDir(options?: { prefix?: string }): Promise<string>; // New for temp dirs\n}\n\n// ============================================================================\n// Node.js Implementation\n// ============================================================================\n\ninterface NodeFsPromises {\n readFile(\n path: string,\n options?: { encoding?: string; flag?: string } | string,\n ): Promise<string | Uint8Array>;\n writeFile(\n path: string,\n data: string | Uint8Array,\n options?: { encoding?: string; flag?: string } | string,\n ): Promise<void>;\n access(path: string, mode?: number): Promise<void>;\n stat(path: string): Promise<{\n isFile(): boolean;\n isDirectory(): boolean;\n isSymbolicLink(): boolean;\n size: number;\n mtime: Date;\n }>;\n mkdir(path: string, options?: { recursive?: boolean }): Promise<void>;\n readdir(path: string, options: { withFileTypes: true }): Promise<\n Array<{\n name: string;\n isFile(): boolean;\n isDirectory(): boolean;\n isSymbolicLink(): boolean;\n }>\n >;\n rm(path: string, options?: { recursive?: boolean; force?: boolean }): Promise<void>;\n}\n\nclass NodeFileSystem implements FileSystem {\n private fs: NodeFsPromises | null = null;\n private os: typeof import(\"node:os\") | null = null;\n private path: typeof import(\"node:path\") | null = null;\n private initialized = false;\n\n private async ensureInitialized(): Promise<void> {\n if (this.initialized) return;\n\n if (!isNode) {\n throw toError(createError({\n type: \"not_supported\",\n message: \"Node.js fs modules not available\",\n feature: \"Node.js\",\n }));\n }\n\n // Use dynamic ESM imports for Node.js modules\n const [fsModule, osModule, pathModule] = await Promise.all([\n import(\"node:fs/promises\"),\n import(\"node:os\"),\n import(\"node:path\"),\n ]);\n\n this.fs = fsModule as unknown as NodeFsPromises;\n this.os = osModule;\n this.path = pathModule;\n this.initialized = true;\n }\n\n async readTextFile(path: string): Promise<string> {\n await this.ensureInitialized();\n return await (this.fs!.readFile(path, { encoding: \"utf8\" }) as Promise<string>);\n }\n\n async readFile(path: string): Promise<Uint8Array> {\n await this.ensureInitialized();\n return await (this.fs!.readFile(path) as Promise<Uint8Array>);\n }\n\n async writeTextFile(path: string, data: string): Promise<void> {\n await this.ensureInitialized();\n await this.fs!.writeFile(path, data, { encoding: \"utf8\" });\n }\n\n async writeFile(path: string, data: Uint8Array): Promise<void> {\n await this.ensureInitialized();\n await this.fs!.writeFile(path, data);\n }\n\n async exists(path: string): Promise<boolean> {\n await this.ensureInitialized();\n try {\n await this.fs!.access(path);\n return true;\n } catch (error: any) {\n if (error.code === \"ENOENT\") {\n return false;\n }\n throw error;\n }\n }\n\n async stat(path: string): Promise<FileInfo> {\n await this.ensureInitialized();\n const stat = await this.fs!.stat(path);\n return {\n isFile: stat.isFile(),\n isDirectory: stat.isDirectory(),\n isSymlink: stat.isSymbolicLink(),\n size: stat.size,\n mtime: stat.mtime,\n };\n }\n\n async mkdir(path: string, options?: { recursive?: boolean }): Promise<void> {\n await this.ensureInitialized();\n await this.fs!.mkdir(path, { recursive: options?.recursive ?? false });\n }\n\n async *readDir(\n path: string,\n ): AsyncIterable<{ name: string; isFile: boolean; isDirectory: boolean }> {\n await this.ensureInitialized();\n const entries = await this.fs!.readdir(path, { withFileTypes: true });\n for (const entry of entries) {\n yield {\n name: entry.name,\n isFile: entry.isFile(),\n isDirectory: entry.isDirectory(),\n };\n }\n }\n\n async remove(path: string, options?: { recursive?: boolean }): Promise<void> {\n await this.ensureInitialized();\n // Node.js fs.rm requires force for recursive deletion of non-empty directories\n await this.fs!.rm(path, {\n recursive: options?.recursive ?? false,\n force: options?.recursive ?? false,\n });\n }\n\n async makeTempDir(options?: { prefix?: string }): Promise<string> {\n await this.ensureInitialized();\n const tempDir = this.path!.join(\n this.os!.tmpdir(),\n `${options?.prefix ?? \"tmp-\"}${Math.random().toString(36).substring(2, 8)}`,\n );\n await this.fs!.mkdir(tempDir, { recursive: true });\n return tempDir;\n }\n}\n\n// ============================================================================\n// Deno Implementation\n// ============================================================================\n\nclass DenoFileSystem implements FileSystem {\n async readTextFile(path: string): Promise<string> {\n // @ts-ignore - Deno global\n return await Deno.readTextFile(path);\n }\n\n async readFile(path: string): Promise<Uint8Array> {\n // @ts-ignore - Deno global\n return await Deno.readFile(path);\n }\n\n async writeTextFile(path: string, data: string): Promise<void> {\n // @ts-ignore - Deno global\n await Deno.writeTextFile(path, data);\n }\n\n async writeFile(path: string, data: Uint8Array): Promise<void> {\n // @ts-ignore - Deno global\n await Deno.writeFile(path, data);\n }\n\n async exists(path: string): Promise<boolean> {\n try {\n // @ts-ignore - Deno global\n await Deno.stat(path);\n return true;\n } catch (error: any) {\n // @ts-ignore - Deno global\n if (error instanceof Deno.errors.NotFound) {\n return false;\n }\n throw error;\n }\n }\n\n async stat(path: string): Promise<FileInfo> {\n // @ts-ignore - Deno global\n const stat = await Deno.stat(path);\n return {\n isFile: stat.isFile,\n isDirectory: stat.isDirectory,\n isSymlink: stat.isSymlink,\n size: stat.size,\n mtime: stat.mtime,\n };\n }\n\n async mkdir(path: string, options?: { recursive?: boolean }): Promise<void> {\n // @ts-ignore - Deno global\n await Deno.mkdir(path, { recursive: options?.recursive ?? false });\n }\n\n async *readDir(\n path: string,\n ): AsyncIterable<{ name: string; isFile: boolean; isDirectory: boolean }> {\n // @ts-ignore - Deno global\n for await (const entry of Deno.readDir(path)) {\n yield {\n name: entry.name,\n isFile: entry.isFile,\n isDirectory: entry.isDirectory,\n };\n }\n }\n\n async remove(path: string, options?: { recursive?: boolean }): Promise<void> {\n // @ts-ignore - Deno global\n await Deno.remove(path, { recursive: options?.recursive ?? false });\n }\n\n async makeTempDir(options?: { prefix?: string }): Promise<string> {\n // @ts-ignore - Deno global\n return await Deno.makeTempDir({ prefix: options?.prefix });\n }\n}\n\n/**\n * Create a cross-platform filesystem instance for CLI commands and standalone utilities.\n *\n * Use this for CLI commands that don't have access to a RuntimeAdapter context:\n * ```ts\n * const fs = createFileSystem();\n * const content = await fs.readTextFile(path);\n * await fs.writeTextFile(outputPath, result);\n * ```\n *\n * For server/rendering contexts, prefer using adapter.fs directly.\n *\n * Note: For npm package, always uses Node.js fs APIs for cross-platform compatibility.\n */\nexport function createFileSystem(): FileSystem {\n if (isDeno) {\n return new DenoFileSystem();\n } else {\n // Node.js or Bun\n return new NodeFileSystem();\n }\n}\n", "import { relative } from \"std/path/mod.ts\";\nimport type { RuntimeAdapter } from \"@veryfront/platform/adapters/base.ts\";\nimport type { DynamicRouter } from \"./api-route-matcher.ts\";\nimport { discoverFiles } from \"@veryfront/core/utils/file-discovery.ts\";\n\nexport async function discoverPagesRoutes(\n router: DynamicRouter,\n dir: string,\n prefix: string,\n adapter: RuntimeAdapter,\n): Promise<void> {\n for await (\n const file of discoverFiles({\n baseDir: dir,\n extensions: [\".ts\", \".js\", \".tsx\", \".jsx\"],\n adapter,\n })\n ) {\n const relativePath = relative(dir, file.path);\n const routePath = `${prefix}/${relativePath.replace(/\\.(ts|js|tsx|jsx)$/, \"\")}`;\n\n let pattern = routePath.replace(/\\/index$/, \"\");\n\n if (pattern === prefix && file.name.replace(/\\.(ts|js|tsx|jsx)$/, \"\") === \"index\") {\n pattern = prefix;\n }\n\n router.addRoute(pattern, file.path);\n }\n}\n\nexport async function discoverAppRoutes(\n router: DynamicRouter,\n dir: string,\n prefix: string,\n adapter: RuntimeAdapter,\n): Promise<void> {\n for await (\n const file of discoverFiles({\n baseDir: dir,\n extensions: [\".ts\", \".js\", \".tsx\", \".jsx\"],\n patterns: [\"route\"],\n recursive: false,\n adapter,\n })\n ) {\n if (file.isFile && /^route\\.(ts|js|tsx|jsx)$/.test(file.name)) {\n const pattern = prefix === \"\" ? \"/\" : prefix;\n router.addRoute(pattern, file.path);\n }\n }\n\n for await (\n const dir_entry of discoverFiles({\n baseDir: dir,\n includeDirs: true,\n recursive: false,\n adapter,\n })\n ) {\n if (dir_entry.isDirectory) {\n const dirPrefix = `${prefix}/${dir_entry.name}`;\n await discoverAppRoutes(router, dir_entry.path, dirPrefix, adapter);\n }\n }\n}\n", "/**\n * Consolidated file discovery utility\n *\n * Provides unified file walking, filtering, and pattern matching\n * for route discovery, build asset scanning, and module discovery.\n */\n\nimport { join } from \"std/path/mod.ts\";\nimport type { RuntimeAdapter } from \"@veryfront/platform/adapters/base.ts\";\nimport { denoAdapter } from \"@veryfront/platform/adapters/deno.ts\";\n\nexport interface FileDiscoveryOptions {\n /**\n * Base directory to start searching from\n */\n baseDir: string;\n\n /**\n * File extensions to include (e.g., [\".ts\", \".tsx\", \".mdx\"])\n * If not specified, all files are included\n */\n extensions?: string[];\n\n /**\n * File name patterns to match (e.g., [\"page\", \"layout\", \"route\"])\n * Files must match at least one pattern if specified\n */\n patterns?: string[];\n\n /**\n * Whether to recursively traverse subdirectories\n * @default true\n */\n recursive?: boolean;\n\n /**\n * Maximum depth for recursive traversal\n * @default Infinity\n */\n maxDepth?: number;\n\n /**\n * Directory or file name patterns to ignore (e.g., [\"node_modules\", \".git\"])\n */\n ignorePatterns?: string[];\n\n /**\n * Include directories in the results\n * @default false\n */\n includeDirs?: boolean;\n\n /**\n * Follow symbolic links\n * @default false\n */\n followSymlinks?: boolean;\n\n /**\n * Runtime adapter for filesystem operations\n * If not provided, uses the default Deno adapter (for backward compatibility)\n */\n adapter?: RuntimeAdapter;\n}\n\nexport interface FileDiscoveryResult {\n /**\n * Absolute path to the file or directory\n */\n path: string;\n\n /**\n * File or directory name\n */\n name: string;\n\n /**\n * Whether this is a file\n */\n isFile: boolean;\n\n /**\n * Whether this is a directory\n */\n isDirectory: boolean;\n\n /**\n * Current depth from base directory\n */\n depth: number;\n}\n\n/**\n * Check if a file matches the given extensions\n */\nfunction matchesExtensions(fileName: string, extensions: string[] | undefined): boolean {\n if (!extensions || extensions.length === 0) {\n return true;\n }\n return extensions.some((ext) => fileName.endsWith(ext));\n}\n\n/**\n * Check if a file matches the given patterns\n */\nfunction matchesPatterns(fileName: string, patterns: string[] | undefined): boolean {\n if (!patterns || patterns.length === 0) {\n return true;\n }\n return patterns.some((pattern) => fileName.includes(pattern));\n}\n\n/**\n * Check if a path should be ignored\n */\nfunction shouldIgnore(name: string, ignorePatterns: string[] | undefined): boolean {\n if (!ignorePatterns || ignorePatterns.length === 0) {\n return false;\n }\n return ignorePatterns.some((pattern) => name.includes(pattern));\n}\n\n/**\n * Discover files matching the given criteria\n *\n * @example\n * ```ts\n * // Find all TypeScript route files\n * for await (const file of discoverFiles({\n * baseDir: \"./app\",\n * extensions: [\".ts\", \".tsx\"],\n * patterns: [\"route\"],\n * })) {\n * console.log(file.path);\n * }\n * ```\n */\nexport async function* discoverFiles(\n options: FileDiscoveryOptions,\n): AsyncGenerator<FileDiscoveryResult> {\n const {\n baseDir,\n extensions,\n patterns,\n recursive = true,\n maxDepth = Infinity,\n ignorePatterns,\n includeDirs = false,\n followSymlinks = false,\n adapter = denoAdapter,\n } = options;\n\n yield* walkDirectory(\n baseDir,\n 0,\n maxDepth,\n extensions,\n patterns,\n ignorePatterns,\n includeDirs,\n recursive,\n followSymlinks,\n adapter,\n );\n}\n\n/**\n * Internal recursive directory walker\n */\nasync function* walkDirectory(\n dir: string,\n currentDepth: number,\n maxDepth: number,\n extensions: string[] | undefined,\n patterns: string[] | undefined,\n ignorePatterns: string[] | undefined,\n includeDirs: boolean,\n recursive: boolean,\n followSymlinks: boolean,\n adapter: RuntimeAdapter,\n): AsyncGenerator<FileDiscoveryResult> {\n // Check depth limit\n if (currentDepth > maxDepth) {\n return;\n }\n\n try {\n // Use adapter for cross-platform filesystem access\n const entries = adapter.fs.readDir(dir);\n\n for await (const entry of entries) {\n const fullPath = join(dir, entry.name);\n\n // Check if should be ignored\n if (shouldIgnore(entry.name, ignorePatterns)) {\n continue;\n }\n\n // Handle directories\n if (entry.isDirectory) {\n // Yield directory if requested\n if (includeDirs) {\n yield {\n path: fullPath,\n name: entry.name,\n isFile: false,\n isDirectory: true,\n depth: currentDepth,\n };\n }\n\n // Recurse into directory if enabled\n if (recursive) {\n yield* walkDirectory(\n fullPath,\n currentDepth + 1,\n maxDepth,\n extensions,\n patterns,\n ignorePatterns,\n includeDirs,\n recursive,\n followSymlinks,\n adapter,\n );\n }\n } // Handle files\n else if (entry.isFile) {\n // Check extension and pattern matches\n if (\n matchesExtensions(entry.name, extensions) &&\n matchesPatterns(entry.name, patterns)\n ) {\n yield {\n path: fullPath,\n name: entry.name,\n isFile: true,\n isDirectory: false,\n depth: currentDepth,\n };\n }\n } // Handle symlinks (if following is enabled)\n else if (entry.isSymlink && followSymlinks) {\n // For symlinks, we need to check what they point to\n try {\n const stat = await adapter.fs.stat(fullPath);\n\n if (stat.isDirectory && recursive) {\n yield* walkDirectory(\n fullPath,\n currentDepth + 1,\n maxDepth,\n extensions,\n patterns,\n ignorePatterns,\n includeDirs,\n recursive,\n followSymlinks,\n adapter,\n );\n } else if (stat.isFile) {\n if (\n matchesExtensions(entry.name, extensions) &&\n matchesPatterns(entry.name, patterns)\n ) {\n yield {\n path: fullPath,\n name: entry.name,\n isFile: true,\n isDirectory: false,\n depth: currentDepth,\n };\n }\n }\n } catch {\n // Ignore broken symlinks\n }\n }\n }\n } catch {\n // Directory doesn't exist or not accessible\n // Silently skip - this is expected behavior for optional directories\n }\n}\n\n/**\n * Collect all files matching criteria into an array\n *\n * @example\n * ```ts\n * const mdxFiles = await collectFiles({\n * baseDir: \"./pages\",\n * extensions: [\".mdx\"],\n * });\n * ```\n */\nexport async function collectFiles(\n options: FileDiscoveryOptions,\n): Promise<FileDiscoveryResult[]> {\n const results: FileDiscoveryResult[] = [];\n for await (const file of discoverFiles(options)) {\n results.push(file);\n }\n return results;\n}\n\n/**\n * Check if a directory has files matching criteria\n *\n * @example\n * ```ts\n * const hasRoutes = await hasMatchingFiles({\n * baseDir: \"./app\",\n * patterns: [\"page\", \"layout\"],\n * });\n * ```\n */\nexport async function hasMatchingFiles(\n options: FileDiscoveryOptions,\n): Promise<boolean> {\n for await (const _file of discoverFiles(options)) {\n return true; // Found at least one matching file\n }\n return false;\n}\n\n/**\n * Count files matching criteria\n */\nexport async function countFiles(options: FileDiscoveryOptions): Promise<number> {\n let count = 0;\n for await (const _file of discoverFiles(options)) {\n count++;\n }\n return count;\n}\n", "import type { RuntimeAdapter } from \"@veryfront/platform/adapters/base.ts\";\nimport { createContext, normalizeParams } from \"./context-builder.ts\";\nimport type { RouteMatch } from \"./api-route-matcher.ts\";\nimport { createError, toError } from \"../../core/errors/veryfront-error.ts\";\nimport type {\n APIRoute,\n AppRouteContext,\n AppRouteHandler,\n PagesRouteHandler,\n} from \"./module-loader/types.ts\";\nimport {\n createAppRouteMethodNotAllowed,\n createPagesRouteMethodNotAllowed,\n} from \"./method-validator.ts\";\nimport { handleAPIError } from \"./error-handler.ts\";\n\ntype HTTPMethod = \"GET\" | \"POST\" | \"PUT\" | \"DELETE\" | \"PATCH\" | \"HEAD\" | \"OPTIONS\";\n\nexport async function executeAppRoute(\n handler: APIRoute,\n request: Request,\n match: RouteMatch,\n pathname: string,\n adapter: RuntimeAdapter,\n): Promise<Response> {\n const method = request.method.toUpperCase() as HTTPMethod;\n const handlerModule = handler as Record<string, unknown>;\n const handlerFn = handlerModule[method] as PagesRouteHandler | AppRouteHandler | undefined;\n const defaultFn = handlerModule.default as PagesRouteHandler | AppRouteHandler | undefined;\n let resolvedFn = handlerFn || defaultFn;\n const appContext: AppRouteContext = { params: normalizeParams(match.params) };\n\n if (!resolvedFn && method === \"HEAD\") {\n const getFn = handlerModule.GET as PagesRouteHandler | AppRouteHandler | undefined;\n if (typeof getFn === \"function\") {\n resolvedFn = getFn;\n }\n }\n\n if (!resolvedFn) {\n return createAppRouteMethodNotAllowed(handlerModule);\n }\n\n try {\n const response: Response = await (resolvedFn as AppRouteHandler)(\n request,\n appContext,\n );\n\n if (!(response instanceof Response)) {\n throw toError(createError({\n type: \"api\",\n message: \"API handler must return a Response\",\n }));\n }\n\n if (method === \"HEAD\") {\n return new Response(null, {\n status: response.status,\n headers: response.headers,\n });\n }\n\n return response;\n } catch (error) {\n return handleAPIError(error, pathname, adapter);\n }\n}\n\nexport async function executePagesRoute(\n handler: APIRoute,\n request: Request,\n match: RouteMatch,\n pathname: string,\n adapter: RuntimeAdapter,\n): Promise<Response> {\n const ctx = createContext(request, match);\n const method = request.method as keyof APIRoute;\n const methodHandler = handler[method] || handler.default;\n\n if (!methodHandler) {\n return createPagesRouteMethodNotAllowed(handler as Record<string, unknown>);\n }\n\n try {\n const response = await (methodHandler as PagesRouteHandler)(ctx);\n\n if (!(response instanceof Response)) {\n throw toError(createError({\n type: \"api\",\n message: \"API handler must return a Response\",\n }));\n }\n\n return response;\n } catch (error) {\n return handleAPIError(error, pathname, adapter);\n }\n}\n", "import type { RouteMatch } from \"./api-route-matcher.ts\";\n\nexport interface APIContext {\n request: Request;\n params: Record<string, string | string[]>;\n query: URLSearchParams;\n cookies: Record<string, string>;\n headers: Headers;\n url: URL;\n}\n\nexport function parseCookies(cookieHeader: string): Record<string, string> {\n const cookies: Record<string, string> = {};\n\n if (!cookieHeader) return cookies;\n\n cookieHeader.split(\";\").forEach((cookie) => {\n const trimmed = cookie.trim();\n if (!trimmed) return;\n const separatorIndex = trimmed.indexOf(\"=\");\n if (separatorIndex <= 0) return;\n const name = trimmed.slice(0, separatorIndex).trim();\n const value = trimmed.slice(separatorIndex + 1);\n if (!name) return;\n cookies[name] = decodeURIComponent(value);\n });\n\n return cookies;\n}\n\nexport function createContext(request: Request, match: RouteMatch): APIContext {\n const url = new URL(request.url);\n\n return {\n request,\n params: match.params,\n query: url.searchParams,\n cookies: parseCookies(request.headers.get(\"cookie\") ?? \"\"),\n headers: request.headers,\n url,\n };\n}\n\nexport function normalizeParams(params: Record<string, string | string[]>): Record<string, string> {\n const out: Record<string, string> = {};\n for (const [k, v] of Object.entries(params)) {\n out[k] = Array.isArray(v) ? v.join(\"/\") : v;\n }\n return out;\n}\n", "import { HTTP_METHOD_NOT_ALLOWED } from \"@veryfront/utils\";\n\ntype HTTPMethod = \"GET\" | \"POST\" | \"PUT\" | \"DELETE\" | \"PATCH\" | \"HEAD\" | \"OPTIONS\";\n\nexport function createAppRouteMethodNotAllowed(\n handlerModule: Record<string, unknown>,\n): Response {\n const candidates: HTTPMethod[] = [\"GET\", \"POST\", \"PUT\", \"PATCH\", \"DELETE\", \"HEAD\", \"OPTIONS\"];\n const implemented = candidates.filter((m) => typeof handlerModule[m] === \"function\");\n const allow = implemented.join(\", \");\n return new Response(\"Method not allowed\", {\n status: HTTP_METHOD_NOT_ALLOWED,\n headers: { Allow: allow },\n });\n}\n\nexport function createPagesRouteMethodNotAllowed(\n handler: Record<string, unknown>,\n): Response {\n const allowedMethods = Object.keys(handler)\n .filter((m) => m !== \"default\" && typeof handler[m] === \"function\")\n .join(\", \");\n return new Response(\"Method not allowed\", {\n status: HTTP_METHOD_NOT_ALLOWED,\n headers: { Allow: allowedMethods },\n });\n}\n", "import { serverLogger as logger } from \"@veryfront/utils\";\nimport type { RuntimeAdapter } from \"@veryfront/platform/adapters/base.ts\";\nimport { HTTP_INTERNAL_SERVER_ERROR } from \"@veryfront/utils\";\nimport { getEnvironmentVariable } from \"@veryfront/utils\";\n\nexport function handleAPIError(\n error: unknown,\n pathname: string,\n adapter: RuntimeAdapter,\n): Response {\n logger.error(`API route error in ${pathname}:`, error);\n\n const envFromAdapter = adapter.env.get(\"MODE\") ??\n adapter.env.get(\"NODE_ENV\") ??\n adapter.env.get(\"DENO_ENV\");\n const envFromRuntime = getEnvironmentVariable(\"MODE\") ??\n getEnvironmentVariable(\"NODE_ENV\") ??\n getEnvironmentVariable(\"DENO_ENV\");\n const environment = (envFromAdapter ?? envFromRuntime ?? \"development\").toLowerCase();\n const isDevelopment = environment === \"development\" || environment === \"dev\";\n\n if (isDevelopment) {\n return Response.json(\n {\n error: error instanceof Error ? error.message : \"Internal server error\",\n stack: error instanceof Error ? error.stack : undefined,\n },\n { status: HTTP_INTERNAL_SERVER_ERROR },\n );\n }\n\n return new Response(\"Internal server error\", {\n status: HTTP_INTERNAL_SERVER_ERROR,\n });\n}\n", "/**\n * Re-export from centralized HTTP response factory.\n * This file exists for backward compatibility.\n *\n * @deprecated Use imports from \"../../http/responses.ts\" directly\n * Will be removed in v1.0.0\n */\nexport {\n badRequest,\n forbidden,\n internalServerError as serverError,\n jsonResponse as json,\n notFound,\n redirectResponse as redirect,\n unauthorized,\n} from \"../../http/responses.ts\";\n"],
|
|
5
5
|
"mappings": "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",
|
|
6
6
|
"names": ["logger", "LogLevel", "error", "init_logger", "hasNodeProcess", "usage", "init_env", "init_env", "simpleHash", "error", "json", "error", "init_logger", "error", "init_logger", "simpleHash", "init_logger", "error", "init_deno", "error", "serverLogger", "join", "error", "resolve", "error", "join", "path", "process", "data", "Receiver", "error", "Sender", "Event", "CloseEvent", "ErrorEvent", "MessageEvent", "error", "createHash", "URL", "Receiver", "Sender", "WebSocket", "key", "stream", "WebSocket", "stream", "createWebSocketStream", "error", "err", "protocol", "createHash", "WebSocket", "WebSocketServer", "Receiver", "Sender", "WebSocket", "WebSocketServer", "createWebSocketStream", "resolve", "serverLogger", "WebSocketServer", "error", "crypto", "error", "init_node", "ErrorCode", "ErrorCode", "init_build_errors", "ErrorCode", "init_runtime_errors", "ErrorCode", "ErrorCode", "ErrorCode", "ErrorCode", "ErrorCode", "ErrorCode", "ErrorCode", "ErrorCode", "init_build_errors", "init_runtime_errors", "text", "deno_exports", "init_deno", "node_exports", "blue", "bold", "colors", "cyan", "dim", "gray", "green", "italic", "magenta", "red", "reset", "strikethrough", "underline", "white", "yellow", "init_node", "text", "init_filesystem_adapter", "join", "error", "init_environment_adapter", "init_websocket_adapter", "error", "init_http_server", "init_adapter", "init_filesystem_adapter", "init_environment_adapter", "init_websocket_adapter", "init_http_server", "init_adapter", "init_filesystem_adapter", "init_environment_adapter", "init_websocket_adapter", "init_http_server", "init_bun", "denoAdapter", "nodeAdapter", "bunAdapter", "createMockAdapter", "isDeno", "isBun", "isCloudflare", "denoAdapter", "bunAdapter", "nodeAdapter", "init_deno", "init_node", "init_bun", "join", "join", "HTTP_MODULE_FETCH_TIMEOUT_MS", "require", "HASH_SEED_FNV1A", "build", "text", "getAdapter", "filePath", "result", "error", "getAdapter", "useMemo", "useRef", "Fragment", "jsx", "jsx", "React", "jsx", "jsx", "getExtension", "jsx", "getExtension", "jsx", "DEFAULT_SIZES", "jsx", "DEFAULT_SIZES", "jsx", "join", "notFound", "DEFAULT_CONFIG", "tracer", "error", "error", "startSpan", "endSpan", "error", "DEFAULT_METRICS_COLLECT_INTERVAL_MS", "DEFAULT_CONFIG", "loadConfig", "memoryUsage", "error", "loadConfig", "error", "error", "json", "html", "json", "html", "z", "text", "error", "z", "z", "z", "error", "init_deno", "join"]
|
|
7
7
|
}
|