@spfn/core 0.2.0-beta.10 → 0.2.0-beta.12
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/codegen/index.js +29 -9
- package/dist/codegen/index.js.map +1 -1
- package/dist/nextjs/index.d.ts +2 -2
- package/dist/nextjs/server.d.ts +5 -1
- package/dist/nextjs/server.js +4 -2
- package/dist/nextjs/server.js.map +1 -1
- package/dist/server/index.js +5 -30
- package/dist/server/index.js.map +1 -1
- package/dist/{types-BOPTApC2.d.ts → types-DP8nzQcY.d.ts} +5 -0
- package/docs/event.md +289 -70
- package/package.json +1 -1
package/dist/codegen/index.js
CHANGED
|
@@ -356,17 +356,27 @@ function parseRouterFile(routerPath) {
|
|
|
356
356
|
let match;
|
|
357
357
|
while ((match = importPattern.exec(content)) !== null) {
|
|
358
358
|
const importPath = match[1];
|
|
359
|
-
if (importPath.
|
|
359
|
+
if (importPath.startsWith(".")) {
|
|
360
360
|
importPaths.push(importPath);
|
|
361
361
|
}
|
|
362
362
|
}
|
|
363
|
-
const
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
363
|
+
const defineRouterStart = content.indexOf("defineRouter(");
|
|
364
|
+
if (defineRouterStart !== -1) {
|
|
365
|
+
const braceStart = content.indexOf("{", defineRouterStart);
|
|
366
|
+
if (braceStart !== -1) {
|
|
367
|
+
let depth = 1;
|
|
368
|
+
let braceEnd = braceStart + 1;
|
|
369
|
+
while (depth > 0 && braceEnd < content.length) {
|
|
370
|
+
if (content[braceEnd] === "{") depth++;
|
|
371
|
+
else if (content[braceEnd] === "}") depth--;
|
|
372
|
+
braceEnd++;
|
|
373
|
+
}
|
|
374
|
+
const routerContent = content.slice(braceStart + 1, braceEnd - 1);
|
|
375
|
+
const withoutComments = routerContent.replace(/\/\/[^\n]*/g, "");
|
|
376
|
+
const namePattern = /^\s*(\w+)\s*[,\n]/gm;
|
|
377
|
+
while ((match = namePattern.exec(withoutComments)) !== null) {
|
|
378
|
+
routeNames.push(match[1]);
|
|
379
|
+
}
|
|
370
380
|
}
|
|
371
381
|
}
|
|
372
382
|
} catch (error) {
|
|
@@ -449,7 +459,17 @@ Usage:
|
|
|
449
459
|
for (const importPath of importPaths) {
|
|
450
460
|
let resolvedPath = resolve(routerDir, importPath);
|
|
451
461
|
if (!resolvedPath.endsWith(".ts")) {
|
|
452
|
-
resolvedPath
|
|
462
|
+
const withTs = resolvedPath + ".ts";
|
|
463
|
+
if (existsSync(withTs)) {
|
|
464
|
+
resolvedPath = withTs;
|
|
465
|
+
} else {
|
|
466
|
+
const indexPath = join(resolvedPath, "index.ts");
|
|
467
|
+
if (existsSync(indexPath)) {
|
|
468
|
+
resolvedPath = indexPath;
|
|
469
|
+
} else {
|
|
470
|
+
resolvedPath = withTs;
|
|
471
|
+
}
|
|
472
|
+
}
|
|
453
473
|
}
|
|
454
474
|
if (existsSync(resolvedPath)) {
|
|
455
475
|
const routes = parseRouteFile(resolvedPath);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/codegen/core/orchestrator.ts","../../src/codegen/core/config-loader.ts","../../src/codegen/generators/route-map.ts","../../src/codegen/generators/index.ts"],"names":["chokidarWatch","resolve","logger","join","generators","readFileSync","existsSync","relative"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Codegen Orchestrator\n *\n * Manages multiple code generators and coordinates their execution\n */\n\nimport { watch as chokidarWatch } from 'chokidar';\nimport { join, relative } from 'path';\nimport mm from 'micromatch';\nimport type { Generator, GeneratorOptions, GeneratorTrigger } from './generator';\nimport { logger } from '@spfn/core/logger';\n\nconst orchestratorLogger = logger.child('@spfn/core:orchestrator');\n\nexport interface OrchestratorOptions\n{\n /** List of generators to orchestrate */\n generators: Generator[];\n\n /** Project root directory */\n cwd?: string;\n\n /** Enable debug logging */\n debug?: boolean;\n}\n\nexport class CodegenOrchestrator\n{\n private readonly generators: Generator[];\n private readonly cwd: string;\n private readonly debug: boolean;\n private isGenerating = false;\n private pendingRegenerations = new Set<string>();\n private watcher?: ReturnType<typeof chokidarWatch>;\n private watcherClosePromise?: { resolve: () => void; reject: (error: Error) => void };\n\n constructor(options: OrchestratorOptions)\n {\n this.generators = options.generators;\n this.cwd = options.cwd ?? process.cwd();\n this.debug = options.debug ?? false;\n }\n\n /**\n * Close watcher and cleanup resources\n */\n async close(): Promise<void>\n {\n if (this.watcher)\n {\n if (this.debug)\n {\n orchestratorLogger.info('Closing watcher');\n }\n await this.watcher.close();\n this.watcher = undefined;\n }\n\n // Resolve the watch promise if it exists\n if (this.watcherClosePromise)\n {\n this.watcherClosePromise.resolve();\n this.watcherClosePromise = undefined;\n }\n }\n\n /**\n * Check if generator should run for given trigger\n */\n private shouldRun(generator: Generator, trigger: GeneratorTrigger): boolean\n {\n const runOn = generator.runOn ?? ['watch', 'manual', 'build'];\n return runOn.includes(trigger);\n }\n\n /**\n * Run all generators once\n *\n * @param trigger - How the generators are being triggered\n */\n async generateAll(trigger: GeneratorTrigger = 'manual'): Promise<void>\n {\n // Always log generation start\n const activeGenerators = this.generators.filter(g => this.shouldRun(g, trigger));\n\n if (activeGenerators.length === 0)\n {\n orchestratorLogger.info('No generators to run for this trigger', { trigger });\n return;\n }\n\n orchestratorLogger.info(`Running ${activeGenerators.length} generator(s)`, {\n generators: activeGenerators.map(g => g.name).join(', '),\n trigger\n });\n\n for (const generator of this.generators)\n {\n // Check if generator should run for this trigger\n if (!this.shouldRun(generator, trigger))\n {\n if (this.debug)\n {\n orchestratorLogger.info(`[${generator.name}] Skipped (runOn: ${generator.runOn?.join(', ') ?? 'default'})`);\n }\n\n continue;\n }\n\n try\n {\n const startTime = Date.now();\n\n const genOptions: GeneratorOptions = {\n cwd: this.cwd,\n debug: this.debug,\n trigger: {\n type: trigger\n }\n };\n\n await generator.generate(genOptions);\n\n const duration = Date.now() - startTime;\n orchestratorLogger.info(`[${generator.name}] ✓ Generated successfully (${duration}ms)`);\n }\n catch (error)\n {\n const err = error instanceof Error ? error : new Error(String(error));\n orchestratorLogger.error(`[${generator.name}] ✗ Generation failed`, err);\n }\n }\n }\n\n /**\n * Start watch mode\n */\n async watch(): Promise<void>\n {\n // Initial generation with 'watch' trigger\n await this.generateAll('watch');\n\n // Collect all watch patterns from generators\n const allPatterns = this.generators.flatMap(g => g.watchPatterns);\n\n if (allPatterns.length === 0)\n {\n orchestratorLogger.warn('No watch patterns defined, exiting watch mode');\n return;\n }\n\n // Extract directories to watch from patterns\n // For pattern like \"watched/**/*.ts\", watch \"watched\" directory\n const dirsToWatch = new Set<string>();\n for (const pattern of allPatterns)\n {\n // Extract base directory from glob pattern (e.g., \"src/**/*.ts\" -> \"src\")\n const baseDir = pattern.split('**')[0].replace(/\\/$/, '') || '.';\n dirsToWatch.add(join(this.cwd, baseDir));\n }\n\n const watchDirs = Array.from(dirsToWatch);\n\n // Always log watch mode start\n orchestratorLogger.info('Watch mode started', {\n watching: watchDirs.length === 1 ? watchDirs[0] : `${watchDirs.length} directories`,\n generators: this.generators.filter(g => this.shouldRun(g, 'watch')).map(g => g.name).join(', ')\n });\n\n if (this.debug)\n {\n orchestratorLogger.info('Watch mode details', {\n patterns: allPatterns,\n watchDirs,\n cwd: this.cwd\n });\n }\n\n this.watcher = chokidarWatch(watchDirs, {\n ignored: /(^|[\\/\\\\])\\../, // ignore dotfiles\n persistent: true,\n ignoreInitial: true,\n awaitWriteFinish: {\n stabilityThreshold: 100,\n pollInterval: 50\n }\n });\n\n const handleChange = async (absolutePath: string, event: 'add' | 'change' | 'unlink') =>\n {\n // Convert absolute path to relative path for pattern matching\n const filePath = relative(this.cwd, absolutePath);\n\n if (this.isGenerating)\n {\n this.pendingRegenerations.add(absolutePath);\n return;\n }\n\n this.isGenerating = true;\n this.pendingRegenerations.clear();\n\n // Always log file changes\n const eventIcon = event === 'add' ? '+' : event === 'unlink' ? '-' : '~';\n orchestratorLogger.info(`File ${eventIcon} ${filePath}`);\n\n // Find matching generators\n let regeneratedCount = 0;\n for (const generator of this.generators)\n {\n // Check if generator should run for 'watch' trigger\n if (!this.shouldRun(generator, 'watch'))\n {\n continue;\n }\n\n const matches = generator.watchPatterns.some(pattern =>\n mm.isMatch(filePath, pattern)\n );\n\n if (matches)\n {\n try\n {\n const startTime = Date.now();\n\n // Call generate() with trigger information\n const genOptions: GeneratorOptions = {\n cwd: this.cwd,\n debug: this.debug,\n trigger: {\n type: 'watch',\n changedFile: {\n path: filePath,\n event\n }\n }\n };\n\n await generator.generate(genOptions);\n\n const duration = Date.now() - startTime;\n orchestratorLogger.info(`[${generator.name}] ✓ Regenerated (${duration}ms)`);\n regeneratedCount++;\n }\n catch (error)\n {\n const err = error instanceof Error ? error : new Error(String(error));\n orchestratorLogger.error(`[${generator.name}] ✗ Regeneration failed`, err);\n }\n }\n }\n\n if (regeneratedCount === 0 && this.debug)\n {\n orchestratorLogger.info('No generators matched this file');\n }\n\n this.isGenerating = false;\n\n // Process pending regenerations\n if (this.pendingRegenerations.size > 0)\n {\n const next = Array.from(this.pendingRegenerations)[0];\n await handleChange(next, 'change');\n }\n };\n\n this.watcher\n .on('add', (path) => handleChange(path, 'add'))\n .on('change', (path) => handleChange(path, 'change'))\n .on('unlink', (path) => handleChange(path, 'unlink'));\n\n // Return a promise that resolves when the watcher is closed\n // This allows the caller to await the watch() method and keep the process alive\n return new Promise<void>((resolve, reject) =>\n {\n this.watcherClosePromise = { resolve, reject };\n });\n }\n}\n","/**\n * Codegen Configuration Loader\n *\n * Loads codegen configuration from .spfnrc.ts, .spfnrc.json or package.json\n */\n\nimport { existsSync, readFileSync } from 'fs';\nimport { join } from 'path';\nimport { createJiti } from 'jiti';\nimport type { Generator } from './generator';\nimport { logger } from '@spfn/core/logger';\n\nconst configLogger = logger.child('@spfn/core:codegen-config');\n\n/**\n * Custom generator via file path\n */\ntype CustomGeneratorByPath = { path: string };\n\n/**\n * Package-based generator configuration\n */\ntype PackageGeneratorDef = { name: string; enabled?: boolean } & Record<string, any>;\n\n/**\n * Any generator configuration\n */\nexport type GeneratorConfig = CustomGeneratorByPath | PackageGeneratorDef;\n\n/**\n * Codegen configuration\n */\nexport interface CodegenConfig\n{\n generators?: GeneratorConfig[];\n}\n\n/**\n * Define a generator with type safety\n *\n * @example\n * Custom generator with type parameter:\n * ```ts\n * import { defineGenerator } from '@spfn/core/codegen';\n * import type { MyGeneratorConfig } from 'my-package';\n *\n * const customGen = defineGenerator<MyGeneratorConfig>({\n * name: 'my-package:generator',\n * myOption: 'value',\n * });\n * ```\n */\nexport function defineGenerator<T extends Record<string, any>>(config: T): T;\nexport function defineGenerator(config: PackageGeneratorDef): PackageGeneratorDef;\nexport function defineGenerator(config: CustomGeneratorByPath): CustomGeneratorByPath;\nexport function defineGenerator<T extends Record<string, any>>(config: T): T\n{\n return config;\n}\n\n/**\n * Helper function to define codegen configuration with type safety\n *\n * @example\n * With custom generator:\n * ```ts\n * import { defineConfig, defineGenerator } from '@spfn/core/codegen';\n * import type { MyGeneratorConfig } from 'my-package';\n *\n * const customGen = defineGenerator<MyGeneratorConfig>({\n * name: 'my-package:custom',\n * myOption: 'value', // Type-safe!\n * });\n *\n * export default defineConfig({\n * generators: [customGen]\n * });\n * ```\n */\nexport function defineConfig(config: CodegenConfig): CodegenConfig\n{\n return config;\n}\n\n/**\n * Load codegen configuration from .spfnrc.ts, .spfnrc.json or package.json\n */\nexport function loadCodegenConfig(cwd: string): CodegenConfig\n{\n // 1. Check .spfnrc.ts (highest priority)\n const rcTsPath = join(cwd, '.spfnrc.ts');\n if (existsSync(rcTsPath))\n {\n try\n {\n const jiti = createJiti(cwd, {\n interopDefault: true,\n moduleCache: false\n });\n\n const module = jiti(rcTsPath);\n const config = module.default || module;\n\n if (config && typeof config === 'object')\n {\n configLogger.info('Loaded config from .spfnrc.ts');\n return config as CodegenConfig;\n }\n }\n catch (error)\n {\n const err = error instanceof Error ? error : new Error(String(error));\n configLogger.warn('Failed to load .spfnrc.ts', err);\n }\n }\n\n // 2. Check .spfnrc.json\n const rcPath = join(cwd, '.spfnrc.json');\n if (existsSync(rcPath))\n {\n try\n {\n const content = readFileSync(rcPath, 'utf-8');\n const config = JSON.parse(content);\n\n if (config.codegen)\n {\n configLogger.info('Loaded config from .spfnrc.json');\n return config.codegen as CodegenConfig;\n }\n }\n catch (error)\n {\n configLogger.warn('Failed to parse .spfnrc.json', error as Error);\n }\n }\n\n // 3. Check package.json\n const pkgPath = join(cwd, 'package.json');\n if (existsSync(pkgPath))\n {\n try\n {\n const content = readFileSync(pkgPath, 'utf-8');\n const pkg = JSON.parse(content);\n\n if (pkg.spfn?.codegen)\n {\n configLogger.info('Loaded config from package.json');\n return pkg.spfn.codegen as CodegenConfig;\n }\n }\n catch (error)\n {\n configLogger.warn('Failed to parse package.json', error as Error);\n }\n }\n\n // 4. Default configuration (empty - no generators by default)\n configLogger.info('Using default config (no generators)');\n return {\n generators: []\n };\n}\n\n/**\n * Load generator from package\n *\n * Supports format: \"package:generator-name\" or \"@scope/package:generator-name\"\n */\nasync function loadGeneratorFromPackage(\n packageName: string,\n generatorName: string,\n config: Record<string, any>\n): Promise<Generator | null>\n{\n try\n {\n // Try to load package/generators export using jiti for better module resolution\n const jiti = createJiti(import.meta.url, {\n interopDefault: true,\n moduleCache: false\n });\n\n const generatorsModule = jiti(`${packageName}/codegen`);\n\n // Look for generator by name in registry\n if (generatorsModule.generators?.[generatorName])\n {\n const createFn = generatorsModule.generators[generatorName];\n const generator = createFn(config);\n configLogger.info(`Loaded ${packageName}:${generatorName}`);\n return generator;\n }\n\n // Fallback: try conventional name (createXxxGenerator)\n const conventionalName = `create${capitalize(generatorName)}Generator`;\n if (generatorsModule[conventionalName])\n {\n const createFn = generatorsModule[conventionalName];\n const generator = createFn(config);\n configLogger.info(`Loaded ${packageName}:${generatorName} (via ${conventionalName})`);\n return generator;\n }\n\n configLogger.warn(\n `Generator \"${generatorName}\" not found in ${packageName}/codegen. ` +\n `Expected: generators.${generatorName} or ${conventionalName}`\n );\n\n return null;\n }\n catch (error)\n {\n const err = error instanceof Error ? error : new Error(String(error));\n configLogger.warn(\n `Failed to load ${packageName}:${generatorName}. ` +\n `Make sure ${packageName} is installed. Error: ${err.message}`\n );\n return null;\n }\n}\n\n/**\n * Capitalize first letter\n */\nfunction capitalize(str: string): string\n{\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\n\n/**\n * Create generator instances from configuration\n */\nexport async function createGeneratorsFromConfig(config: CodegenConfig, cwd: string): Promise<Generator[]>\n{\n const generators: Generator[] = [];\n\n if (!config.generators || config.generators.length === 0)\n {\n return generators;\n }\n\n for (const generatorConfig of config.generators)\n {\n try\n {\n // Already instantiated Generator (has generate function)\n // This prevents double-loading when users accidentally call factory directly\n if ('generate' in generatorConfig && typeof (generatorConfig as any).generate === 'function')\n {\n generators.push(generatorConfig as Generator);\n configLogger.info(`Generator instance added: ${(generatorConfig as Generator).name}`);\n continue;\n }\n\n // Custom generator (via file path)\n if ('path' in generatorConfig)\n {\n const generatorPath = generatorConfig.path.startsWith('.')\n ? join(cwd, generatorConfig.path)\n : generatorConfig.path;\n\n configLogger.info(`Loading custom generator: ${generatorPath}`);\n\n let module: any;\n\n // Use jiti for .ts files, regular import for .js\n if (generatorPath.endsWith('.ts'))\n {\n const jiti = createJiti(cwd, {\n interopDefault: true\n });\n module = jiti(generatorPath);\n }\n else\n {\n module = await import(generatorPath);\n }\n\n const createGenerator = module.default || module.createGenerator || module;\n\n if (typeof createGenerator === 'function')\n {\n const generator = createGenerator();\n generators.push(generator);\n configLogger.info(`Custom generator loaded: ${generator.name}`);\n }\n else\n {\n configLogger.warn(`Invalid generator at ${generatorPath}: expected function`);\n }\n }\n // Package-based generator: \"package:name\" or \"@scope/package:name\"\n else if ('name' in generatorConfig && generatorConfig.name.includes(':'))\n {\n if (generatorConfig.enabled !== false)\n {\n const [packageName, generatorName] = generatorConfig.name.split(':');\n const { enabled, name, ...generatorOptions } = generatorConfig;\n\n const generator = await loadGeneratorFromPackage(\n packageName,\n generatorName,\n generatorOptions\n );\n\n if (generator)\n {\n generators.push(generator);\n }\n }\n }\n // Unknown generator name format\n else if ('name' in generatorConfig)\n {\n configLogger.warn(\n `Invalid generator name \"${generatorConfig.name}\". ` +\n `Use package:name format (e.g., \"@spfn/core:contract\")`\n );\n }\n }\n catch (error)\n {\n const err = error instanceof Error ? error : new Error(String(error));\n configLogger.error('Failed to load generator', err);\n }\n }\n\n return generators;\n}","/**\n * Route Map Generator\n *\n * Generates a route map file containing routeName → {method, path} mappings.\n * This allows RPC proxy to resolve routes without importing the full router.\n *\n * @example\n * ```typescript\n * // .spfnrc.ts\n * import { defineConfig, defineGenerator } from '@spfn/core/codegen';\n *\n * export default defineConfig({\n * generators: [\n * defineGenerator({\n * name: '@spfn/core:route-map',\n * routerPath: './src/server/router.ts',\n * outputPath: './src/generated/route-map.ts',\n * })\n * ]\n * });\n * ```\n */\n\nimport { readFileSync, writeFileSync, mkdirSync, existsSync } from 'fs';\nimport { join, dirname, relative, resolve } from 'path';\nimport type { Generator, GeneratorOptions } from '../core/generator';\nimport { logger } from '@spfn/core/logger';\n\nconst genLogger = logger.child('@spfn/core:route-map-generator');\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface RouteMapGeneratorConfig\n{\n /**\n * Generator name (required for package-based loading)\n */\n name: '@spfn/core:route-map';\n\n /**\n * Path to the router file (relative to project root)\n * @example './src/server/router.ts'\n */\n routerPath: string;\n\n /**\n * Output path for generated route map (relative to project root)\n * @default './src/generated/route-map.ts'\n */\n outputPath?: string;\n\n /**\n * Additional route directories to scan (for package routers)\n */\n additionalRouteDirs?: string[];\n}\n\ninterface ParsedRoute\n{\n name: string;\n method: string;\n path: string;\n file: string;\n}\n\n// ============================================================================\n// Parser\n// ============================================================================\n\n/**\n * Parse route definitions from a route file\n *\n * Supports patterns:\n * - export const routeName = route.get('/path')...\n * - export const routeName = route.post('/path')...\n */\nfunction parseRouteFile(filePath: string): ParsedRoute[]\n{\n const routes: ParsedRoute[] = [];\n\n try\n {\n const content = readFileSync(filePath, 'utf-8');\n\n // Pattern: export const {name} = route.{method}('{path}')\n // Handles both single and double quotes\n const routePattern = /export\\s+const\\s+(\\w+)\\s*=\\s*route\\.(get|post|put|patch|delete)\\s*\\(\\s*['\"`]([^'\"`]+)['\"`]\\s*\\)/gi;\n\n let match;\n while ((match = routePattern.exec(content)) !== null)\n {\n const [, name, method, path] = match;\n routes.push({\n name,\n method: method.toUpperCase(),\n path,\n file: filePath\n });\n }\n }\n catch (error)\n {\n genLogger.warn(`Failed to parse route file: ${filePath}`, error as Error);\n }\n\n return routes;\n}\n\n/**\n * Parse router file to find route imports and names\n *\n * Extracts:\n * - Import paths for route files\n * - Route names from defineRouter({...})\n */\nfunction parseRouterFile(routerPath: string): { importPaths: string[]; routeNames: string[] }\n{\n const importPaths: string[] = [];\n const routeNames: string[] = [];\n\n try\n {\n const content = readFileSync(routerPath, 'utf-8');\n\n // Extract import paths\n // Pattern: import { ... } from './routes/xxx'\n const importPattern = /import\\s+\\{[^}]+\\}\\s+from\\s+['\"`](\\.[^'\"`]+)['\"`]/g;\n let match;\n while ((match = importPattern.exec(content)) !== null)\n {\n const importPath = match[1];\n if (importPath.includes('route'))\n {\n importPaths.push(importPath);\n }\n }\n\n // Extract route names from defineRouter({...})\n const routerPattern = /defineRouter\\s*\\(\\s*\\{([^}]+)\\}/s;\n const routerMatch = routerPattern.exec(content);\n if (routerMatch)\n {\n const routerContent = routerMatch[1];\n // Extract identifiers (route names)\n const namePattern = /(\\w+)\\s*[,}]/g;\n while ((match = namePattern.exec(routerContent)) !== null)\n {\n routeNames.push(match[1]);\n }\n }\n }\n catch (error)\n {\n genLogger.warn(`Failed to parse router file: ${routerPath}`, error as Error);\n }\n\n return { importPaths, routeNames };\n}\n\n// ============================================================================\n// Generator\n// ============================================================================\n\n/**\n * Generate route map file content\n */\nfunction generateRouteMapContent(routes: ParsedRoute[]): string\n{\n const lines: string[] = [\n '/**',\n ' * Route Map (Auto-generated)',\n ' *',\n ' * DO NOT EDIT - This file is generated by @spfn/core:route-map generator',\n ' */',\n '',\n 'import type { HttpMethod } from \\'@spfn/core/route\\';',\n '',\n 'export interface RouteInfo',\n '{',\n ' method: HttpMethod;',\n ' path: string;',\n '}',\n '',\n 'export const routeMap: Record<string, RouteInfo> = {'\n ];\n\n for (const route of routes)\n {\n lines.push(` ${route.name}: { method: '${route.method}', path: '${route.path}' },`);\n }\n\n lines.push('};');\n lines.push('');\n lines.push('export type RouteMap = typeof routeMap;');\n lines.push('');\n lines.push('export type RouteName = keyof RouteMap;');\n lines.push('');\n\n return lines.join('\\n');\n}\n\n/**\n * Create Route Map Generator\n */\nexport function createRouteMapGenerator(config: RouteMapGeneratorConfig): Generator\n{\n const {\n routerPath,\n outputPath = './src/generated/route-map.ts',\n additionalRouteDirs = []\n } = config;\n\n if (!routerPath)\n {\n throw new Error(\n '[@spfn/core:route-map] Missing required \"routerPath\" option.\\n\\n' +\n 'Usage:\\n' +\n ' defineGenerator<RouteMapGeneratorConfig>({\\n' +\n ' name: \\'@spfn/core:route-map\\',\\n' +\n ' routerPath: \\'./src/server/router.ts\\',\\n' +\n ' })'\n );\n }\n\n return {\n name: '@spfn/core:route-map',\n\n watchPatterns: [\n routerPath,\n // Watch route directories derived from router imports\n 'src/server/routes/**/*.ts',\n ...additionalRouteDirs.map(dir => `${dir}/**/*.ts`)\n ],\n\n runOn: ['watch', 'build', 'start', 'manual'],\n\n async generate(options: GeneratorOptions): Promise<void>\n {\n const { cwd, debug } = options;\n\n const absoluteRouterPath = join(cwd, routerPath);\n const absoluteOutputPath = join(cwd, outputPath);\n\n if (!existsSync(absoluteRouterPath))\n {\n genLogger.warn(`Router file not found: ${absoluteRouterPath}`);\n return;\n }\n\n if (debug)\n {\n genLogger.info('Parsing router file', { path: absoluteRouterPath });\n }\n\n // Parse router file\n const { importPaths, routeNames } = parseRouterFile(absoluteRouterPath);\n\n if (debug)\n {\n genLogger.info('Found route imports', { count: importPaths.length, names: routeNames });\n }\n\n // Resolve import paths and parse route files\n const routerDir = dirname(absoluteRouterPath);\n const allRoutes: ParsedRoute[] = [];\n\n for (const importPath of importPaths)\n {\n // Resolve .ts extension\n let resolvedPath = resolve(routerDir, importPath);\n if (!resolvedPath.endsWith('.ts'))\n {\n resolvedPath += '.ts';\n }\n\n if (existsSync(resolvedPath))\n {\n const routes = parseRouteFile(resolvedPath);\n allRoutes.push(...routes);\n\n if (debug)\n {\n genLogger.info(`Parsed ${routes.length} routes from ${relative(cwd, resolvedPath)}`);\n }\n }\n }\n\n // Filter routes that are actually exported in router\n const exportedRoutes = allRoutes.filter(r => routeNames.includes(r.name));\n\n if (debug)\n {\n genLogger.info(`Found ${exportedRoutes.length} exported routes`);\n }\n\n // Generate output\n const content = generateRouteMapContent(exportedRoutes);\n\n // Ensure output directory exists\n const outputDir = dirname(absoluteOutputPath);\n if (!existsSync(outputDir))\n {\n mkdirSync(outputDir, { recursive: true });\n }\n\n // Write file\n writeFileSync(absoluteOutputPath, content, 'utf-8');\n\n genLogger.info(`Generated route map: ${relative(cwd, absoluteOutputPath)} (${exportedRoutes.length} routes)`);\n }\n };\n}\n\n// ============================================================================\n// Export for package-based loading\n// ============================================================================\n\nexport default createRouteMapGenerator;\n","/**\n * Built-in Generators Export\n *\n * @example\n * ```typescript\n * // .spfnrc.ts\n * import { defineConfig, defineGenerator } from '@spfn/core/codegen';\n * import type { RouteMapGeneratorConfig } from '@spfn/core/codegen';\n *\n * export default defineConfig({\n * generators: [\n * defineGenerator<RouteMapGeneratorConfig>({\n * name: '@spfn/core:route-map',\n * routerPath: './src/server/router.ts',\n * outputPath: './src/generated/route-map.ts',\n * })\n * ]\n * });\n * ```\n */\n\nimport { createRouteMapGenerator } from './route-map';\nexport type { RouteMapGeneratorConfig } from './route-map';\n\n/**\n * @internal\n * Registry of available generators for package-based loading.\n * DO NOT use directly - use defineGenerator({ name: '@spfn/core:route-map', ... }) instead.\n */\nexport const generators: Record<string, unknown> = {\n 'route-map': createRouteMapGenerator,\n};\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/codegen/core/orchestrator.ts","../../src/codegen/core/config-loader.ts","../../src/codegen/generators/route-map.ts","../../src/codegen/generators/index.ts"],"names":["chokidarWatch","resolve","logger","join","generators","readFileSync","existsSync","relative"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Codegen Orchestrator\n *\n * Manages multiple code generators and coordinates their execution\n */\n\nimport { watch as chokidarWatch } from 'chokidar';\nimport { join, relative } from 'path';\nimport mm from 'micromatch';\nimport type { Generator, GeneratorOptions, GeneratorTrigger } from './generator';\nimport { logger } from '@spfn/core/logger';\n\nconst orchestratorLogger = logger.child('@spfn/core:orchestrator');\n\nexport interface OrchestratorOptions\n{\n /** List of generators to orchestrate */\n generators: Generator[];\n\n /** Project root directory */\n cwd?: string;\n\n /** Enable debug logging */\n debug?: boolean;\n}\n\nexport class CodegenOrchestrator\n{\n private readonly generators: Generator[];\n private readonly cwd: string;\n private readonly debug: boolean;\n private isGenerating = false;\n private pendingRegenerations = new Set<string>();\n private watcher?: ReturnType<typeof chokidarWatch>;\n private watcherClosePromise?: { resolve: () => void; reject: (error: Error) => void };\n\n constructor(options: OrchestratorOptions)\n {\n this.generators = options.generators;\n this.cwd = options.cwd ?? process.cwd();\n this.debug = options.debug ?? false;\n }\n\n /**\n * Close watcher and cleanup resources\n */\n async close(): Promise<void>\n {\n if (this.watcher)\n {\n if (this.debug)\n {\n orchestratorLogger.info('Closing watcher');\n }\n await this.watcher.close();\n this.watcher = undefined;\n }\n\n // Resolve the watch promise if it exists\n if (this.watcherClosePromise)\n {\n this.watcherClosePromise.resolve();\n this.watcherClosePromise = undefined;\n }\n }\n\n /**\n * Check if generator should run for given trigger\n */\n private shouldRun(generator: Generator, trigger: GeneratorTrigger): boolean\n {\n const runOn = generator.runOn ?? ['watch', 'manual', 'build'];\n return runOn.includes(trigger);\n }\n\n /**\n * Run all generators once\n *\n * @param trigger - How the generators are being triggered\n */\n async generateAll(trigger: GeneratorTrigger = 'manual'): Promise<void>\n {\n // Always log generation start\n const activeGenerators = this.generators.filter(g => this.shouldRun(g, trigger));\n\n if (activeGenerators.length === 0)\n {\n orchestratorLogger.info('No generators to run for this trigger', { trigger });\n return;\n }\n\n orchestratorLogger.info(`Running ${activeGenerators.length} generator(s)`, {\n generators: activeGenerators.map(g => g.name).join(', '),\n trigger\n });\n\n for (const generator of this.generators)\n {\n // Check if generator should run for this trigger\n if (!this.shouldRun(generator, trigger))\n {\n if (this.debug)\n {\n orchestratorLogger.info(`[${generator.name}] Skipped (runOn: ${generator.runOn?.join(', ') ?? 'default'})`);\n }\n\n continue;\n }\n\n try\n {\n const startTime = Date.now();\n\n const genOptions: GeneratorOptions = {\n cwd: this.cwd,\n debug: this.debug,\n trigger: {\n type: trigger\n }\n };\n\n await generator.generate(genOptions);\n\n const duration = Date.now() - startTime;\n orchestratorLogger.info(`[${generator.name}] ✓ Generated successfully (${duration}ms)`);\n }\n catch (error)\n {\n const err = error instanceof Error ? error : new Error(String(error));\n orchestratorLogger.error(`[${generator.name}] ✗ Generation failed`, err);\n }\n }\n }\n\n /**\n * Start watch mode\n */\n async watch(): Promise<void>\n {\n // Initial generation with 'watch' trigger\n await this.generateAll('watch');\n\n // Collect all watch patterns from generators\n const allPatterns = this.generators.flatMap(g => g.watchPatterns);\n\n if (allPatterns.length === 0)\n {\n orchestratorLogger.warn('No watch patterns defined, exiting watch mode');\n return;\n }\n\n // Extract directories to watch from patterns\n // For pattern like \"watched/**/*.ts\", watch \"watched\" directory\n const dirsToWatch = new Set<string>();\n for (const pattern of allPatterns)\n {\n // Extract base directory from glob pattern (e.g., \"src/**/*.ts\" -> \"src\")\n const baseDir = pattern.split('**')[0].replace(/\\/$/, '') || '.';\n dirsToWatch.add(join(this.cwd, baseDir));\n }\n\n const watchDirs = Array.from(dirsToWatch);\n\n // Always log watch mode start\n orchestratorLogger.info('Watch mode started', {\n watching: watchDirs.length === 1 ? watchDirs[0] : `${watchDirs.length} directories`,\n generators: this.generators.filter(g => this.shouldRun(g, 'watch')).map(g => g.name).join(', ')\n });\n\n if (this.debug)\n {\n orchestratorLogger.info('Watch mode details', {\n patterns: allPatterns,\n watchDirs,\n cwd: this.cwd\n });\n }\n\n this.watcher = chokidarWatch(watchDirs, {\n ignored: /(^|[\\/\\\\])\\../, // ignore dotfiles\n persistent: true,\n ignoreInitial: true,\n awaitWriteFinish: {\n stabilityThreshold: 100,\n pollInterval: 50\n }\n });\n\n const handleChange = async (absolutePath: string, event: 'add' | 'change' | 'unlink') =>\n {\n // Convert absolute path to relative path for pattern matching\n const filePath = relative(this.cwd, absolutePath);\n\n if (this.isGenerating)\n {\n this.pendingRegenerations.add(absolutePath);\n return;\n }\n\n this.isGenerating = true;\n this.pendingRegenerations.clear();\n\n // Always log file changes\n const eventIcon = event === 'add' ? '+' : event === 'unlink' ? '-' : '~';\n orchestratorLogger.info(`File ${eventIcon} ${filePath}`);\n\n // Find matching generators\n let regeneratedCount = 0;\n for (const generator of this.generators)\n {\n // Check if generator should run for 'watch' trigger\n if (!this.shouldRun(generator, 'watch'))\n {\n continue;\n }\n\n const matches = generator.watchPatterns.some(pattern =>\n mm.isMatch(filePath, pattern)\n );\n\n if (matches)\n {\n try\n {\n const startTime = Date.now();\n\n // Call generate() with trigger information\n const genOptions: GeneratorOptions = {\n cwd: this.cwd,\n debug: this.debug,\n trigger: {\n type: 'watch',\n changedFile: {\n path: filePath,\n event\n }\n }\n };\n\n await generator.generate(genOptions);\n\n const duration = Date.now() - startTime;\n orchestratorLogger.info(`[${generator.name}] ✓ Regenerated (${duration}ms)`);\n regeneratedCount++;\n }\n catch (error)\n {\n const err = error instanceof Error ? error : new Error(String(error));\n orchestratorLogger.error(`[${generator.name}] ✗ Regeneration failed`, err);\n }\n }\n }\n\n if (regeneratedCount === 0 && this.debug)\n {\n orchestratorLogger.info('No generators matched this file');\n }\n\n this.isGenerating = false;\n\n // Process pending regenerations\n if (this.pendingRegenerations.size > 0)\n {\n const next = Array.from(this.pendingRegenerations)[0];\n await handleChange(next, 'change');\n }\n };\n\n this.watcher\n .on('add', (path) => handleChange(path, 'add'))\n .on('change', (path) => handleChange(path, 'change'))\n .on('unlink', (path) => handleChange(path, 'unlink'));\n\n // Return a promise that resolves when the watcher is closed\n // This allows the caller to await the watch() method and keep the process alive\n return new Promise<void>((resolve, reject) =>\n {\n this.watcherClosePromise = { resolve, reject };\n });\n }\n}\n","/**\n * Codegen Configuration Loader\n *\n * Loads codegen configuration from .spfnrc.ts, .spfnrc.json or package.json\n */\n\nimport { existsSync, readFileSync } from 'fs';\nimport { join } from 'path';\nimport { createJiti } from 'jiti';\nimport type { Generator } from './generator';\nimport { logger } from '@spfn/core/logger';\n\nconst configLogger = logger.child('@spfn/core:codegen-config');\n\n/**\n * Custom generator via file path\n */\ntype CustomGeneratorByPath = { path: string };\n\n/**\n * Package-based generator configuration\n */\ntype PackageGeneratorDef = { name: string; enabled?: boolean } & Record<string, any>;\n\n/**\n * Any generator configuration\n */\nexport type GeneratorConfig = CustomGeneratorByPath | PackageGeneratorDef;\n\n/**\n * Codegen configuration\n */\nexport interface CodegenConfig\n{\n generators?: GeneratorConfig[];\n}\n\n/**\n * Define a generator with type safety\n *\n * @example\n * Custom generator with type parameter:\n * ```ts\n * import { defineGenerator } from '@spfn/core/codegen';\n * import type { MyGeneratorConfig } from 'my-package';\n *\n * const customGen = defineGenerator<MyGeneratorConfig>({\n * name: 'my-package:generator',\n * myOption: 'value',\n * });\n * ```\n */\nexport function defineGenerator<T extends Record<string, any>>(config: T): T;\nexport function defineGenerator(config: PackageGeneratorDef): PackageGeneratorDef;\nexport function defineGenerator(config: CustomGeneratorByPath): CustomGeneratorByPath;\nexport function defineGenerator<T extends Record<string, any>>(config: T): T\n{\n return config;\n}\n\n/**\n * Helper function to define codegen configuration with type safety\n *\n * @example\n * With custom generator:\n * ```ts\n * import { defineConfig, defineGenerator } from '@spfn/core/codegen';\n * import type { MyGeneratorConfig } from 'my-package';\n *\n * const customGen = defineGenerator<MyGeneratorConfig>({\n * name: 'my-package:custom',\n * myOption: 'value', // Type-safe!\n * });\n *\n * export default defineConfig({\n * generators: [customGen]\n * });\n * ```\n */\nexport function defineConfig(config: CodegenConfig): CodegenConfig\n{\n return config;\n}\n\n/**\n * Load codegen configuration from .spfnrc.ts, .spfnrc.json or package.json\n */\nexport function loadCodegenConfig(cwd: string): CodegenConfig\n{\n // 1. Check .spfnrc.ts (highest priority)\n const rcTsPath = join(cwd, '.spfnrc.ts');\n if (existsSync(rcTsPath))\n {\n try\n {\n const jiti = createJiti(cwd, {\n interopDefault: true,\n moduleCache: false\n });\n\n const module = jiti(rcTsPath);\n const config = module.default || module;\n\n if (config && typeof config === 'object')\n {\n configLogger.info('Loaded config from .spfnrc.ts');\n return config as CodegenConfig;\n }\n }\n catch (error)\n {\n const err = error instanceof Error ? error : new Error(String(error));\n configLogger.warn('Failed to load .spfnrc.ts', err);\n }\n }\n\n // 2. Check .spfnrc.json\n const rcPath = join(cwd, '.spfnrc.json');\n if (existsSync(rcPath))\n {\n try\n {\n const content = readFileSync(rcPath, 'utf-8');\n const config = JSON.parse(content);\n\n if (config.codegen)\n {\n configLogger.info('Loaded config from .spfnrc.json');\n return config.codegen as CodegenConfig;\n }\n }\n catch (error)\n {\n configLogger.warn('Failed to parse .spfnrc.json', error as Error);\n }\n }\n\n // 3. Check package.json\n const pkgPath = join(cwd, 'package.json');\n if (existsSync(pkgPath))\n {\n try\n {\n const content = readFileSync(pkgPath, 'utf-8');\n const pkg = JSON.parse(content);\n\n if (pkg.spfn?.codegen)\n {\n configLogger.info('Loaded config from package.json');\n return pkg.spfn.codegen as CodegenConfig;\n }\n }\n catch (error)\n {\n configLogger.warn('Failed to parse package.json', error as Error);\n }\n }\n\n // 4. Default configuration (empty - no generators by default)\n configLogger.info('Using default config (no generators)');\n return {\n generators: []\n };\n}\n\n/**\n * Load generator from package\n *\n * Supports format: \"package:generator-name\" or \"@scope/package:generator-name\"\n */\nasync function loadGeneratorFromPackage(\n packageName: string,\n generatorName: string,\n config: Record<string, any>\n): Promise<Generator | null>\n{\n try\n {\n // Try to load package/generators export using jiti for better module resolution\n const jiti = createJiti(import.meta.url, {\n interopDefault: true,\n moduleCache: false\n });\n\n const generatorsModule = jiti(`${packageName}/codegen`);\n\n // Look for generator by name in registry\n if (generatorsModule.generators?.[generatorName])\n {\n const createFn = generatorsModule.generators[generatorName];\n const generator = createFn(config);\n configLogger.info(`Loaded ${packageName}:${generatorName}`);\n return generator;\n }\n\n // Fallback: try conventional name (createXxxGenerator)\n const conventionalName = `create${capitalize(generatorName)}Generator`;\n if (generatorsModule[conventionalName])\n {\n const createFn = generatorsModule[conventionalName];\n const generator = createFn(config);\n configLogger.info(`Loaded ${packageName}:${generatorName} (via ${conventionalName})`);\n return generator;\n }\n\n configLogger.warn(\n `Generator \"${generatorName}\" not found in ${packageName}/codegen. ` +\n `Expected: generators.${generatorName} or ${conventionalName}`\n );\n\n return null;\n }\n catch (error)\n {\n const err = error instanceof Error ? error : new Error(String(error));\n configLogger.warn(\n `Failed to load ${packageName}:${generatorName}. ` +\n `Make sure ${packageName} is installed. Error: ${err.message}`\n );\n return null;\n }\n}\n\n/**\n * Capitalize first letter\n */\nfunction capitalize(str: string): string\n{\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\n\n/**\n * Create generator instances from configuration\n */\nexport async function createGeneratorsFromConfig(config: CodegenConfig, cwd: string): Promise<Generator[]>\n{\n const generators: Generator[] = [];\n\n if (!config.generators || config.generators.length === 0)\n {\n return generators;\n }\n\n for (const generatorConfig of config.generators)\n {\n try\n {\n // Already instantiated Generator (has generate function)\n // This prevents double-loading when users accidentally call factory directly\n if ('generate' in generatorConfig && typeof (generatorConfig as any).generate === 'function')\n {\n generators.push(generatorConfig as Generator);\n configLogger.info(`Generator instance added: ${(generatorConfig as Generator).name}`);\n continue;\n }\n\n // Custom generator (via file path)\n if ('path' in generatorConfig)\n {\n const generatorPath = generatorConfig.path.startsWith('.')\n ? join(cwd, generatorConfig.path)\n : generatorConfig.path;\n\n configLogger.info(`Loading custom generator: ${generatorPath}`);\n\n let module: any;\n\n // Use jiti for .ts files, regular import for .js\n if (generatorPath.endsWith('.ts'))\n {\n const jiti = createJiti(cwd, {\n interopDefault: true\n });\n module = jiti(generatorPath);\n }\n else\n {\n module = await import(generatorPath);\n }\n\n const createGenerator = module.default || module.createGenerator || module;\n\n if (typeof createGenerator === 'function')\n {\n const generator = createGenerator();\n generators.push(generator);\n configLogger.info(`Custom generator loaded: ${generator.name}`);\n }\n else\n {\n configLogger.warn(`Invalid generator at ${generatorPath}: expected function`);\n }\n }\n // Package-based generator: \"package:name\" or \"@scope/package:name\"\n else if ('name' in generatorConfig && generatorConfig.name.includes(':'))\n {\n if (generatorConfig.enabled !== false)\n {\n const [packageName, generatorName] = generatorConfig.name.split(':');\n const { enabled, name, ...generatorOptions } = generatorConfig;\n\n const generator = await loadGeneratorFromPackage(\n packageName,\n generatorName,\n generatorOptions\n );\n\n if (generator)\n {\n generators.push(generator);\n }\n }\n }\n // Unknown generator name format\n else if ('name' in generatorConfig)\n {\n configLogger.warn(\n `Invalid generator name \"${generatorConfig.name}\". ` +\n `Use package:name format (e.g., \"@spfn/core:contract\")`\n );\n }\n }\n catch (error)\n {\n const err = error instanceof Error ? error : new Error(String(error));\n configLogger.error('Failed to load generator', err);\n }\n }\n\n return generators;\n}","/**\n * Route Map Generator\n *\n * Generates a route map file containing routeName → {method, path} mappings.\n * This allows RPC proxy to resolve routes without importing the full router.\n *\n * @example\n * ```typescript\n * // .spfnrc.ts\n * import { defineConfig, defineGenerator } from '@spfn/core/codegen';\n *\n * export default defineConfig({\n * generators: [\n * defineGenerator({\n * name: '@spfn/core:route-map',\n * routerPath: './src/server/router.ts',\n * outputPath: './src/generated/route-map.ts',\n * })\n * ]\n * });\n * ```\n */\n\nimport { readFileSync, writeFileSync, mkdirSync, existsSync } from 'fs';\nimport { join, dirname, relative, resolve } from 'path';\nimport type { Generator, GeneratorOptions } from '../core/generator';\nimport { logger } from '@spfn/core/logger';\n\nconst genLogger = logger.child('@spfn/core:route-map-generator');\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface RouteMapGeneratorConfig\n{\n /**\n * Generator name (required for package-based loading)\n */\n name: '@spfn/core:route-map';\n\n /**\n * Path to the router file (relative to project root)\n * @example './src/server/router.ts'\n */\n routerPath: string;\n\n /**\n * Output path for generated route map (relative to project root)\n * @default './src/generated/route-map.ts'\n */\n outputPath?: string;\n\n /**\n * Additional route directories to scan (for package routers)\n */\n additionalRouteDirs?: string[];\n}\n\ninterface ParsedRoute\n{\n name: string;\n method: string;\n path: string;\n file: string;\n}\n\n// ============================================================================\n// Parser\n// ============================================================================\n\n/**\n * Parse route definitions from a route file\n *\n * Supports patterns:\n * - export const routeName = route.get('/path')...\n * - export const routeName = route.post('/path')...\n */\nfunction parseRouteFile(filePath: string): ParsedRoute[]\n{\n const routes: ParsedRoute[] = [];\n\n try\n {\n const content = readFileSync(filePath, 'utf-8');\n\n // Pattern: export const {name} = route.{method}('{path}')\n // Handles both single and double quotes\n const routePattern = /export\\s+const\\s+(\\w+)\\s*=\\s*route\\.(get|post|put|patch|delete)\\s*\\(\\s*['\"`]([^'\"`]+)['\"`]\\s*\\)/gi;\n\n let match;\n while ((match = routePattern.exec(content)) !== null)\n {\n const [, name, method, path] = match;\n routes.push({\n name,\n method: method.toUpperCase(),\n path,\n file: filePath\n });\n }\n }\n catch (error)\n {\n genLogger.warn(`Failed to parse route file: ${filePath}`, error as Error);\n }\n\n return routes;\n}\n\n/**\n * Parse router file to find route imports and names\n *\n * Extracts:\n * - Import paths for route files\n * - Route names from defineRouter({...})\n */\nfunction parseRouterFile(routerPath: string): { importPaths: string[]; routeNames: string[] }\n{\n const importPaths: string[] = [];\n const routeNames: string[] = [];\n\n try\n {\n const content = readFileSync(routerPath, 'utf-8');\n\n // Extract import paths\n // Pattern: import { ... } from './xxx'\n // Include all relative imports (not @spfn/core or other packages)\n const importPattern = /import\\s+\\{[^}]+\\}\\s+from\\s+['\"`](\\.[^'\"`]+)['\"`]/g;\n let match;\n while ((match = importPattern.exec(content)) !== null)\n {\n const importPath = match[1];\n // Include relative imports, exclude external packages\n if (importPath.startsWith('.'))\n {\n importPaths.push(importPath);\n }\n }\n\n // Extract route names from defineRouter({...})\n // Use balanced brace matching for nested structures\n const defineRouterStart = content.indexOf('defineRouter(');\n if (defineRouterStart !== -1)\n {\n // Find the opening brace after defineRouter(\n const braceStart = content.indexOf('{', defineRouterStart);\n if (braceStart !== -1)\n {\n // Find matching closing brace\n let depth = 1;\n let braceEnd = braceStart + 1;\n while (depth > 0 && braceEnd < content.length)\n {\n if (content[braceEnd] === '{') depth++;\n else if (content[braceEnd] === '}') depth--;\n braceEnd++;\n }\n\n const routerContent = content.slice(braceStart + 1, braceEnd - 1);\n\n // Extract identifiers (route names), ignoring comments\n // Remove single-line comments\n const withoutComments = routerContent.replace(/\\/\\/[^\\n]*/g, '');\n // Extract identifiers that are standalone (not part of property access like xxx.routes)\n const namePattern = /^\\s*(\\w+)\\s*[,\\n]/gm;\n while ((match = namePattern.exec(withoutComments)) !== null)\n {\n routeNames.push(match[1]);\n }\n }\n }\n }\n catch (error)\n {\n genLogger.warn(`Failed to parse router file: ${routerPath}`, error as Error);\n }\n\n return { importPaths, routeNames };\n}\n\n// ============================================================================\n// Generator\n// ============================================================================\n\n/**\n * Generate route map file content\n */\nfunction generateRouteMapContent(routes: ParsedRoute[]): string\n{\n const lines: string[] = [\n '/**',\n ' * Route Map (Auto-generated)',\n ' *',\n ' * DO NOT EDIT - This file is generated by @spfn/core:route-map generator',\n ' */',\n '',\n 'import type { HttpMethod } from \\'@spfn/core/route\\';',\n '',\n 'export interface RouteInfo',\n '{',\n ' method: HttpMethod;',\n ' path: string;',\n '}',\n '',\n 'export const routeMap: Record<string, RouteInfo> = {'\n ];\n\n for (const route of routes)\n {\n lines.push(` ${route.name}: { method: '${route.method}', path: '${route.path}' },`);\n }\n\n lines.push('};');\n lines.push('');\n lines.push('export type RouteMap = typeof routeMap;');\n lines.push('');\n lines.push('export type RouteName = keyof RouteMap;');\n lines.push('');\n\n return lines.join('\\n');\n}\n\n/**\n * Create Route Map Generator\n */\nexport function createRouteMapGenerator(config: RouteMapGeneratorConfig): Generator\n{\n const {\n routerPath,\n outputPath = './src/generated/route-map.ts',\n additionalRouteDirs = []\n } = config;\n\n if (!routerPath)\n {\n throw new Error(\n '[@spfn/core:route-map] Missing required \"routerPath\" option.\\n\\n' +\n 'Usage:\\n' +\n ' defineGenerator<RouteMapGeneratorConfig>({\\n' +\n ' name: \\'@spfn/core:route-map\\',\\n' +\n ' routerPath: \\'./src/server/router.ts\\',\\n' +\n ' })'\n );\n }\n\n return {\n name: '@spfn/core:route-map',\n\n watchPatterns: [\n routerPath,\n // Watch route directories derived from router imports\n 'src/server/routes/**/*.ts',\n ...additionalRouteDirs.map(dir => `${dir}/**/*.ts`)\n ],\n\n runOn: ['watch', 'build', 'start', 'manual'],\n\n async generate(options: GeneratorOptions): Promise<void>\n {\n const { cwd, debug } = options;\n\n const absoluteRouterPath = join(cwd, routerPath);\n const absoluteOutputPath = join(cwd, outputPath);\n\n if (!existsSync(absoluteRouterPath))\n {\n genLogger.warn(`Router file not found: ${absoluteRouterPath}`);\n return;\n }\n\n if (debug)\n {\n genLogger.info('Parsing router file', { path: absoluteRouterPath });\n }\n\n // Parse router file\n const { importPaths, routeNames } = parseRouterFile(absoluteRouterPath);\n\n if (debug)\n {\n genLogger.info('Found route imports', { count: importPaths.length, names: routeNames });\n }\n\n // Resolve import paths and parse route files\n const routerDir = dirname(absoluteRouterPath);\n const allRoutes: ParsedRoute[] = [];\n\n for (const importPath of importPaths)\n {\n // Resolve path - try multiple patterns\n let resolvedPath = resolve(routerDir, importPath);\n\n // Try: exact path with .ts extension\n if (!resolvedPath.endsWith('.ts'))\n {\n const withTs = resolvedPath + '.ts';\n if (existsSync(withTs))\n {\n resolvedPath = withTs;\n }\n // Try: directory with index.ts\n else\n {\n const indexPath = join(resolvedPath, 'index.ts');\n if (existsSync(indexPath))\n {\n resolvedPath = indexPath;\n }\n else\n {\n resolvedPath = withTs; // fallback to original\n }\n }\n }\n\n if (existsSync(resolvedPath))\n {\n const routes = parseRouteFile(resolvedPath);\n allRoutes.push(...routes);\n\n if (debug)\n {\n genLogger.info(`Parsed ${routes.length} routes from ${relative(cwd, resolvedPath)}`);\n }\n }\n }\n\n // Filter routes that are actually exported in router\n const exportedRoutes = allRoutes.filter(r => routeNames.includes(r.name));\n\n if (debug)\n {\n genLogger.info(`Found ${exportedRoutes.length} exported routes`);\n }\n\n // Generate output\n const content = generateRouteMapContent(exportedRoutes);\n\n // Ensure output directory exists\n const outputDir = dirname(absoluteOutputPath);\n if (!existsSync(outputDir))\n {\n mkdirSync(outputDir, { recursive: true });\n }\n\n // Write file\n writeFileSync(absoluteOutputPath, content, 'utf-8');\n\n genLogger.info(`Generated route map: ${relative(cwd, absoluteOutputPath)} (${exportedRoutes.length} routes)`);\n }\n };\n}\n\n// ============================================================================\n// Export for package-based loading\n// ============================================================================\n\nexport default createRouteMapGenerator;\n","/**\n * Built-in Generators Export\n *\n * @example\n * ```typescript\n * // .spfnrc.ts\n * import { defineConfig, defineGenerator } from '@spfn/core/codegen';\n * import type { RouteMapGeneratorConfig } from '@spfn/core/codegen';\n *\n * export default defineConfig({\n * generators: [\n * defineGenerator<RouteMapGeneratorConfig>({\n * name: '@spfn/core:route-map',\n * routerPath: './src/server/router.ts',\n * outputPath: './src/generated/route-map.ts',\n * })\n * ]\n * });\n * ```\n */\n\nimport { createRouteMapGenerator } from './route-map';\nexport type { RouteMapGeneratorConfig } from './route-map';\n\n/**\n * @internal\n * Registry of available generators for package-based loading.\n * DO NOT use directly - use defineGenerator({ name: '@spfn/core:route-map', ... }) instead.\n */\nexport const generators: Record<string, unknown> = {\n 'route-map': createRouteMapGenerator,\n};\n"]}
|
package/dist/nextjs/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Router, RouteDef } from '@spfn/core/route';
|
|
2
|
-
import { R as RequestInterceptor, a as ResponseInterceptor, I as InferRouteInput, b as InferRouteOutput, A as ApiConfig } from '../types-
|
|
3
|
-
export { C as CallOptions, e as CookieOptions, c as RouterInput, d as RouterOutput, f as SetCookie, S as StructuredInput } from '../types-
|
|
2
|
+
import { R as RequestInterceptor, a as ResponseInterceptor, I as InferRouteInput, b as InferRouteOutput, A as ApiConfig } from '../types-DP8nzQcY.js';
|
|
3
|
+
export { C as CallOptions, e as CookieOptions, c as RouterInput, d as RouterOutput, f as SetCookie, S as StructuredInput } from '../types-DP8nzQcY.js';
|
|
4
4
|
import '@sinclair/typebox';
|
|
5
5
|
import '@spfn/core/errors';
|
|
6
6
|
|
package/dist/nextjs/server.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { NextRequest, NextResponse } from 'next/server';
|
|
2
2
|
import { Router, HttpMethod } from '@spfn/core/route';
|
|
3
3
|
import { InterceptorRule as InterceptorRule$1 } from '@spfn/core/nextjs/server';
|
|
4
|
-
import { f as SetCookie } from '../types-
|
|
4
|
+
import { f as SetCookie } from '../types-DP8nzQcY.js';
|
|
5
5
|
import '@sinclair/typebox';
|
|
6
6
|
import '@spfn/core/errors';
|
|
7
7
|
|
|
@@ -332,6 +332,10 @@ interface ResponseInterceptorContext {
|
|
|
332
332
|
headers: Headers;
|
|
333
333
|
body: any;
|
|
334
334
|
};
|
|
335
|
+
/**
|
|
336
|
+
* Cookies from original request (read-only)
|
|
337
|
+
*/
|
|
338
|
+
cookies: Map<string, string>;
|
|
335
339
|
/**
|
|
336
340
|
* Cookies to set in response
|
|
337
341
|
*
|
package/dist/nextjs/server.js
CHANGED
|
@@ -305,7 +305,7 @@ function buildRequestContext(path, method, headers, body, searchParams, cookiesM
|
|
|
305
305
|
metadata: {}
|
|
306
306
|
};
|
|
307
307
|
}
|
|
308
|
-
function buildResponseContext(path, method, requestHeaders, requestBody, response, responseBody, requestMetadata) {
|
|
308
|
+
function buildResponseContext(path, method, requestHeaders, requestBody, response, responseBody, requestMetadata, cookies) {
|
|
309
309
|
return {
|
|
310
310
|
path: `/${path}`,
|
|
311
311
|
method,
|
|
@@ -320,6 +320,7 @@ function buildResponseContext(path, method, requestHeaders, requestBody, respons
|
|
|
320
320
|
headers: response.headers,
|
|
321
321
|
body: responseBody
|
|
322
322
|
},
|
|
323
|
+
cookies,
|
|
323
324
|
setCookies: [],
|
|
324
325
|
metadata: requestMetadata
|
|
325
326
|
};
|
|
@@ -555,7 +556,8 @@ function createRpcProxy(config) {
|
|
|
555
556
|
inputBody,
|
|
556
557
|
response,
|
|
557
558
|
body,
|
|
558
|
-
requestCtx.metadata
|
|
559
|
+
requestCtx.metadata,
|
|
560
|
+
requestCtx.cookies
|
|
559
561
|
);
|
|
560
562
|
const responseInterceptorsToRun = matchingInterceptors.map((r) => r.response).filter((i) => !!i);
|
|
561
563
|
if (responseInterceptorsToRun.length > 0) {
|