@yigityalim/next-router-client 1.0.0
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/LICENSE +21 -0
- package/README.md +101 -0
- package/dist/index.d.mts +52 -0
- package/dist/index.d.ts +52 -0
- package/dist/index.js +647 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +606 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +52 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/generate-client.ts","../src/generators/fetchers.ts","../src/generators/hooks.ts","../src/generators/keys.ts","../src/generators/types.ts"],"sourcesContent":["export { generateClient } from \"./generate-client\";\r\nexport { generateFetchers } from \"./generators/fetchers\";\r\nexport { generateHooks } from \"./generators/hooks\";\r\nexport { generateKeys } from \"./generators/keys\";\r\nexport { generateTypes } from \"./generators/types\";\r\nexport type { ClientLibrary, GenerateOptions } from \"./types\";\r\n","import fs from \"node:fs\";\r\nimport path from \"node:path\";\r\nimport { generateFetchers } from \"./generators/fetchers\";\r\nimport { generateHooks } from \"./generators/hooks\";\r\nimport { generateKeys } from \"./generators/keys\";\r\nimport { generateTypes } from \"./generators/types\";\r\nimport type { GenerateOptions } from \"./types\";\r\n\r\nexport async function generateClient(options: GenerateOptions): Promise<void> {\r\n const {\r\n openApiPath,\r\n outputDir = \".next-router/generated\",\r\n library = \"vanilla\",\r\n baseUrl = \"/api/v1\",\r\n } = options;\r\n\r\n // Clean and ensure output directory exists\r\n const resolvedOutputDir = path.resolve(process.cwd(), outputDir);\r\n if (fs.existsSync(resolvedOutputDir)) {\r\n fs.rmSync(resolvedOutputDir, { recursive: true, force: true });\r\n }\r\n fs.mkdirSync(resolvedOutputDir, { recursive: true });\r\n\r\n console.log(`\\nđ Output directory: ${outputDir}`);\r\n console.log(`đ Client library: ${library}`);\r\n console.log(`đ Base URL: ${baseUrl}\\n`);\r\n\r\n // Generate types\r\n console.log(\"âď¸ Generating types...\");\r\n await generateTypes({ openApiPath, outputDir: resolvedOutputDir });\r\n\r\n // Generate fetchers\r\n console.log(\"âď¸ Generating fetchers...\");\r\n await generateFetchers({\r\n openApiPath,\r\n outputDir: resolvedOutputDir,\r\n baseUrl,\r\n });\r\n\r\n // Generate query keys\r\n console.log(\"âď¸ Generating query keys...\");\r\n await generateKeys({ openApiPath, outputDir: resolvedOutputDir });\r\n\r\n // Generate hooks if not vanilla\r\n if (library !== \"vanilla\") {\r\n console.log(`âď¸ Generating ${library} hooks...`);\r\n await generateHooks({ openApiPath, outputDir: resolvedOutputDir, library });\r\n }\r\n\r\n // Generate index file\r\n const indexContent = generateIndexFile(library);\r\n fs.writeFileSync(path.join(resolvedOutputDir, \"index.ts\"), indexContent);\r\n\r\n // Update tsconfig.json with path alias\r\n updateTsConfig(resolvedOutputDir);\r\n\r\n console.log(\"\\nâ
Client generation complete!\");\r\n console.log(`\\nImport from: import { ... } from \"next-router/generated\"\\n`);\r\n}\r\n\r\nfunction generateIndexFile(library: string): string {\r\n let exports = `export * from \"./types\";\r\nexport * from \"./fetchers\";\r\nexport * from \"./keys\";\r\n`;\r\n\r\n if (library !== \"vanilla\") {\r\n exports += `export * from \"./hooks\";\\n`;\r\n }\r\n\r\n return exports;\r\n}\r\n\r\nfunction updateTsConfig(resolvedOutputDir: string): void {\r\n // Find tsconfig.json by searching from output dir up to root\r\n let searchDir = resolvedOutputDir;\r\n let tsconfigPath: string | null = null;\r\n \r\n // Search up to 5 levels (e.g., .next-router/generated -> apps/api)\r\n for (let i = 0; i < 5; i++) {\r\n searchDir = path.dirname(searchDir);\r\n const candidatePath = path.join(searchDir, \"tsconfig.json\");\r\n if (fs.existsSync(candidatePath)) {\r\n tsconfigPath = candidatePath;\r\n break;\r\n }\r\n }\r\n\r\n if (!tsconfigPath) {\r\n console.log(\"\\nâ ď¸ tsconfig.json not found - skipping path alias setup\");\r\n console.log(` Add this to your tsconfig.json manually:`);\r\n console.log(` \"paths\": { \"next-router/generated/*\": [\".next-router/generated/*\"] }\\n`);\r\n return;\r\n }\r\n\r\n // Convert absolute path to relative path from tsconfig directory\r\n const tsconfigDir = path.dirname(tsconfigPath);\r\n const relativeOutputDir = path\r\n .relative(tsconfigDir, resolvedOutputDir)\r\n .replace(/\\\\/g, \"/\");\r\n\r\n try {\r\n const tsconfigContent = fs.readFileSync(tsconfigPath, \"utf-8\");\r\n const tsconfig = JSON.parse(tsconfigContent);\r\n\r\n // Ensure compilerOptions exists\r\n if (!tsconfig.compilerOptions) {\r\n tsconfig.compilerOptions = {};\r\n }\r\n\r\n // Ensure paths exists\r\n if (!tsconfig.compilerOptions.paths) {\r\n tsconfig.compilerOptions.paths = {};\r\n }\r\n\r\n // Add or update path alias\r\n const pathKey = `next-router/generated/*`;\r\n const pathValue = [`${relativeOutputDir}/*`];\r\n\r\n const existingPath = tsconfig.compilerOptions.paths[pathKey];\r\n if (JSON.stringify(existingPath) !== JSON.stringify(pathValue)) {\r\n tsconfig.compilerOptions.paths[pathKey] = pathValue;\r\n\r\n // Write back with pretty formatting\r\n fs.writeFileSync(tsconfigPath, JSON.stringify(tsconfig, null, 2) + \"\\n\");\r\n\r\n console.log(`\\nâ
Updated ${path.basename(path.dirname(tsconfigPath))}/${path.basename(tsconfigPath)} with path alias:`);\r\n console.log(` \"${pathKey}\": [\"${pathValue[0]}\"]`);\r\n } else {\r\n console.log(`\\nâ Path alias already configured in ${path.basename(path.dirname(tsconfigPath))}/${path.basename(tsconfigPath)}`);\r\n }\r\n } catch (error) {\r\n console.log(`\\nâ ď¸ Could not update tsconfig.json automatically`);\r\n console.log(` Add this to your tsconfig.json manually:`);\r\n console.log(\r\n ` \"paths\": { \"next-router/generated/*\": [\"${relativeOutputDir}/*\"] }\\n`,\r\n );\r\n }\r\n}\r\n","import fs from \"node:fs\";\r\nimport path from \"node:path\";\r\nimport type { RouteDefinition } from \"../types\";\r\n\r\ninterface GenerateFetchersOptions {\r\n openApiPath: string;\r\n outputDir: string;\r\n baseUrl: string;\r\n}\r\n\r\nexport async function generateFetchers(\r\n options: GenerateFetchersOptions,\r\n): Promise<void> {\r\n const { openApiPath, outputDir, baseUrl } = options;\r\n\r\n // Parse OpenAPI spec\r\n const spec = JSON.parse(fs.readFileSync(openApiPath, \"utf-8\"));\r\n const routes = parseRoutes(spec);\r\n\r\n // Generate fetcher code\r\n const code = generateFetcherCode(routes, baseUrl);\r\n\r\n // Write to fetchers.ts\r\n const fetchersPath = path.join(outputDir, \"fetchers.ts\");\r\n fs.writeFileSync(fetchersPath, code);\r\n}\r\n\r\nfunction parseRoutes(spec: any): RouteDefinition[] {\r\n const routes: RouteDefinition[] = [];\r\n\r\n for (const [path, pathItem] of Object.entries<any>(spec.paths || {})) {\r\n for (const [method, operation] of Object.entries<any>(pathItem)) {\r\n if (![\"get\", \"post\", \"put\", \"delete\", \"patch\"].includes(method)) continue;\r\n\r\n routes.push({\r\n path,\r\n method: method.toUpperCase() as any,\r\n operationId:\r\n operation.operationId || `${method}${path.replace(/\\//g, \"_\")}`,\r\n parameters: operation.parameters || [],\r\n requestBody: operation.requestBody,\r\n responses: operation.responses || {},\r\n });\r\n }\r\n }\r\n\r\n return routes;\r\n}\r\n\r\nfunction generateFetcherCode(\r\n routes: RouteDefinition[],\r\n baseUrl: string,\r\n): string {\r\n let code = `/**\r\n * This file was auto-generated by route-handler client generator.\r\n * Do not make direct changes to this file.\r\n */\r\n\r\nexport interface FetcherOptions {\r\n baseUrl?: string;\r\n headers?: Record<string, string>;\r\n}\r\n\r\nconst defaultOptions: FetcherOptions = {\r\n baseUrl: \"${baseUrl}\",\r\n};\r\n\r\nfunction buildQueryString(params: Record<string, unknown>): string {\r\n const searchParams = new URLSearchParams();\r\n for (const [key, value] of Object.entries(params)) {\r\n if (value !== undefined && value !== null) {\r\n searchParams.append(key, String(value));\r\n }\r\n }\r\n return searchParams.toString();\r\n}\r\n\r\nasync function fetcher<TData = unknown>(\r\n path: string,\r\n init?: RequestInit,\r\n options?: FetcherOptions,\r\n): Promise<TData> {\r\n const { baseUrl, headers } = { ...defaultOptions, ...options };\r\n const url = \\`\\${baseUrl}\\${path}\\`;\r\n\r\n const response = await fetch(url, {\r\n ...init,\r\n headers: {\r\n \"Content-Type\": \"application/json\",\r\n ...headers,\r\n ...init?.headers,\r\n },\r\n });\r\n\r\n if (!response.ok) {\r\n throw new Error(\\`HTTP error! status: \\${response.status}\\`);\r\n }\r\n\r\n return response.json();\r\n}\r\n\r\n`;\r\n\r\n // Group routes by resource\r\n const resourceMap = new Map<string, RouteDefinition[]>();\r\n for (const route of routes) {\r\n const resource = extractResource(route.path);\r\n if (!resourceMap.has(resource)) {\r\n resourceMap.set(resource, []);\r\n }\r\n resourceMap.get(resource)!.push(route);\r\n }\r\n\r\n // Generate fetchers for each resource\r\n for (const [resource, resourceRoutes] of resourceMap) {\r\n code += `export const ${resource}Fetchers = {\\n`;\r\n\r\n for (const route of resourceRoutes) {\r\n code += generateFetcherFunction(route);\r\n }\r\n\r\n code += `};\\n\\n`;\r\n }\r\n\r\n return code;\r\n}\r\n\r\nfunction extractResource(path: string): string {\r\n // Extract resource name from path: /v1/resumes -> resumes\r\n const parts = path.split(\"/\").filter(Boolean);\r\n const resourcePart = parts.find((p) => !p.startsWith(\"{\") && p !== \"v1\");\r\n return resourcePart || \"api\";\r\n}\r\n\r\nfunction generateFetcherFunction(route: RouteDefinition): string {\r\n const { method, path, operationId } = route;\r\n const hasPathParams = path.includes(\"{\");\r\n const hasQueryParams = route.parameters?.some((p) => p.in === \"query\");\r\n const hasBody = method !== \"GET\" && method !== \"DELETE\";\r\n\r\n const funcName = operationId.replace(/[A-Z]/g, (m, offset) =>\r\n offset > 0 ? m : m.toLowerCase(),\r\n );\r\n\r\n let params = \"\";\r\n let pathReplacement = path;\r\n let fetchOptions = \"\";\r\n\r\n if (hasPathParams) {\r\n const pathParams = route.parameters?.filter((p) => p.in === \"path\") || [];\r\n params += pathParams.map((p) => `${p.name}: string`).join(\", \");\r\n for (const param of pathParams) {\r\n pathReplacement = pathReplacement.replace(\r\n `{${param.name}}`,\r\n `\\${${param.name}}`,\r\n );\r\n }\r\n }\r\n\r\n if (hasQueryParams) {\r\n if (params) params += \", \";\r\n params += \"params?: Record<string, unknown>\";\r\n }\r\n\r\n if (hasBody) {\r\n if (params) params += \", \";\r\n params += \"body?: unknown\";\r\n fetchOptions = `, { method: \"${method}\", body: JSON.stringify(body) }`;\r\n } else if (method !== \"GET\") {\r\n fetchOptions = `, { method: \"${method}\" }`;\r\n }\r\n\r\n let url = `\\`${pathReplacement}\\``;\r\n if (hasQueryParams) {\r\n url += ` + (params ? \\`?\\${buildQueryString(params)}\\` : \"\")`;\r\n }\r\n\r\n return ` ${funcName}: async (${params}) => fetcher(${url}${fetchOptions}),\r\n`;\r\n}\r\n","import fs from \"node:fs\";\r\nimport path from \"node:path\";\r\nimport type { ClientLibrary, RouteDefinition } from \"../types\";\r\n\r\ninterface GenerateHooksOptions {\r\n openApiPath: string;\r\n outputDir: string;\r\n library: ClientLibrary;\r\n}\r\n\r\nexport async function generateHooks(\r\n options: GenerateHooksOptions,\r\n): Promise<void> {\r\n const { openApiPath, outputDir, library } = options;\r\n\r\n // Parse OpenAPI spec\r\n const spec = JSON.parse(fs.readFileSync(openApiPath, \"utf-8\"));\r\n const routes = parseRoutes(spec);\r\n\r\n // Generate hooks code based on library\r\n const code =\r\n library === \"react-query\"\r\n ? generateReactQueryHooks(routes)\r\n : generateSWRHooks(routes);\r\n\r\n // Write to hooks.ts\r\n const hooksPath = path.join(outputDir, \"hooks.ts\");\r\n fs.writeFileSync(hooksPath, code);\r\n}\r\n\r\nfunction parseRoutes(spec: any): RouteDefinition[] {\r\n const routes: RouteDefinition[] = [];\r\n\r\n for (const [path, pathItem] of Object.entries<any>(spec.paths || {})) {\r\n for (const [method, operation] of Object.entries<any>(pathItem)) {\r\n if (![\"get\", \"post\", \"put\", \"delete\", \"patch\"].includes(method)) continue;\r\n\r\n routes.push({\r\n path,\r\n method: method.toUpperCase() as any,\r\n operationId:\r\n operation.operationId || `${method}${path.replace(/\\//g, \"_\")}`,\r\n parameters: operation.parameters || [],\r\n requestBody: operation.requestBody,\r\n responses: operation.responses || {},\r\n });\r\n }\r\n }\r\n\r\n return routes;\r\n}\r\n\r\nfunction generateReactQueryHooks(routes: RouteDefinition[]): string {\r\n let code = `/**\r\n * This file was auto-generated by route-handler client generator.\r\n * Do not make direct changes to this file.\r\n */\r\n\r\nimport { useQuery, useMutation, useQueryClient } from \"@tanstack/react-query\";\r\nimport type { UseQueryOptions, UseMutationOptions } from \"@tanstack/react-query\";\r\nimport * as fetchers from \"./fetchers\";\r\nimport * as keys from \"./keys\";\r\n\r\n`;\r\n\r\n // Group routes by resource\r\n const resourceMap = new Map<string, RouteDefinition[]>();\r\n for (const route of routes) {\r\n const resource = extractResource(route.path);\r\n if (!resourceMap.has(resource)) {\r\n resourceMap.set(resource, []);\r\n }\r\n resourceMap.get(resource)!.push(route);\r\n }\r\n\r\n // Generate hooks for each resource\r\n for (const [resource, resourceRoutes] of resourceMap) {\r\n // Generate query hooks (GET)\r\n for (const route of resourceRoutes.filter((r) => r.method === \"GET\")) {\r\n code += generateReactQueryHook(resource, route);\r\n }\r\n\r\n // Generate mutation hooks (POST, PUT, DELETE, PATCH)\r\n for (const route of resourceRoutes.filter((r) => r.method !== \"GET\")) {\r\n code += generateReactMutationHook(resource, route);\r\n }\r\n }\r\n\r\n return code;\r\n}\r\n\r\nfunction generateReactQueryHook(\r\n resource: string,\r\n route: RouteDefinition,\r\n): string {\r\n const isList = !route.path.includes(\"{\");\r\n const hookName = isList\r\n ? `use${capitalize(resource)}`\r\n : `use${capitalize(resource.endsWith(\"s\") ? resource.slice(0, -1) : resource)}`;\r\n const keyFactory = isList\r\n ? `keys.${resource}Keys.list`\r\n : `keys.${resource}Keys.detail`;\r\n const fetcherName = route.operationId;\r\n\r\n // Check if fetcher actually accepts params\r\n const hasQueryParams = route.parameters?.some((p) => p.in === \"query\");\r\n\r\n let params = \"\";\r\n let fetcherArgs = \"\";\r\n let keyArgs = \"\";\r\n\r\n if (isList && hasQueryParams) {\r\n params = \"params?: Record<string, unknown>, \";\r\n fetcherArgs = \"params\";\r\n keyArgs = \"params\";\r\n } else if (isList) {\r\n // List without params\r\n keyArgs = \"undefined\";\r\n } else if (!isList) {\r\n params = \"id: string, \";\r\n fetcherArgs = \"id\";\r\n keyArgs = \"id\";\r\n }\r\n\r\n return `export function ${hookName}(${params}options?: Omit<UseQueryOptions, \"queryKey\" | \"queryFn\">) {\r\n return useQuery({\r\n queryKey: ${keyFactory}(${keyArgs}),\r\n queryFn: () => fetchers.${resource}Fetchers.${fetcherName}(${fetcherArgs}),\r\n ...options,\r\n });\r\n}\r\n\r\n`;\r\n}\r\n\r\nfunction generateReactMutationHook(\r\n resource: string,\r\n route: RouteDefinition,\r\n): string {\r\n // Generate better hook names\r\n const hookName = generateHookName(resource, route);\r\n const fetcherName = route.operationId;\r\n\r\n const pathParams = route.parameters?.filter((p) => p.in === \"path\") || [];\r\n const hasBody = route.method !== \"DELETE\" && route.method !== \"GET\";\r\n\r\n // Build params interface\r\n let paramsInterface = \"{ \";\r\n for (const param of pathParams) {\r\n paramsInterface += `${param.name}: string; `;\r\n }\r\n if (hasBody) {\r\n paramsInterface += \"body?: unknown; \";\r\n }\r\n paramsInterface += \"}\";\r\n\r\n // Build fetcher call with destructuring\r\n let destructure = \"{ \";\r\n let fetcherArgs = \"\";\r\n for (const param of pathParams) {\r\n destructure += `${param.name}, `;\r\n fetcherArgs += `${param.name}, `;\r\n }\r\n if (hasBody) {\r\n destructure += \"body \";\r\n fetcherArgs += \"body\";\r\n } else {\r\n destructure = destructure.slice(0, -2); // Remove trailing \", \"\r\n fetcherArgs = fetcherArgs.slice(0, -2);\r\n }\r\n destructure += \"}\";\r\n\r\n return `export function ${hookName}(options?: UseMutationOptions<unknown, Error, ${paramsInterface}>) {\r\n const queryClient = useQueryClient();\r\n \r\n return useMutation({\r\n mutationFn: (${destructure}) => fetchers.${resource}Fetchers.${fetcherName}(${fetcherArgs}),\r\n onSuccess: () => {\r\n queryClient.invalidateQueries({ queryKey: keys.${resource}Keys.all });\r\n },\r\n ...options,\r\n });\r\n}\r\n\r\n`;\r\n}\r\n\r\nfunction generateHookName(resource: string, route: RouteDefinition): string {\r\n const singular = resource.endsWith(\"s\") ? resource.slice(0, -1) : resource;\r\n\r\n switch (route.method) {\r\n case \"POST\":\r\n return `useCreate${capitalize(singular)}`;\r\n case \"PUT\":\r\n case \"PATCH\":\r\n // Check if it's a special operation (e.g., /resumes/[id]/public)\r\n if (route.path.includes(\"/public\")) {\r\n return `useToggle${capitalize(singular)}Visibility`;\r\n }\r\n return `useUpdate${capitalize(singular)}`;\r\n case \"DELETE\":\r\n return `useDelete${capitalize(singular)}`;\r\n default:\r\n return `use${capitalize(route.operationId)}`;\r\n }\r\n}\r\n\r\nfunction generateSWRHooks(routes: RouteDefinition[]): string {\r\n let code = `/**\r\n * This file was auto-generated by route-handler client generator.\r\n * Do not make direct changes to this file.\r\n */\r\n\r\nimport useSWR from \"swr\";\r\nimport useSWRMutation from \"swr/mutation\";\r\nimport type { SWRConfiguration } from \"swr\";\r\nimport * as fetchers from \"./fetchers\";\r\nimport * as keys from \"./keys\";\r\n\r\n`;\r\n\r\n // Group routes by resource\r\n const resourceMap = new Map<string, RouteDefinition[]>();\r\n for (const route of routes) {\r\n const resource = extractResource(route.path);\r\n if (!resourceMap.has(resource)) {\r\n resourceMap.set(resource, []);\r\n }\r\n resourceMap.get(resource)!.push(route);\r\n }\r\n\r\n // Generate hooks for each resource\r\n for (const [resource, resourceRoutes] of resourceMap) {\r\n // Generate query hooks (GET)\r\n for (const route of resourceRoutes.filter((r) => r.method === \"GET\")) {\r\n code += generateSWRHook(resource, route);\r\n }\r\n\r\n // Generate mutation hooks (POST, PUT, DELETE, PATCH)\r\n for (const route of resourceRoutes.filter((r) => r.method !== \"GET\")) {\r\n code += generateSWRMutationHook(resource, route);\r\n }\r\n }\r\n\r\n return code;\r\n}\r\n\r\nfunction generateSWRHook(resource: string, route: RouteDefinition): string {\r\n const isList = !route.path.includes(\"{\");\r\n const hookName = isList\r\n ? `use${capitalize(resource)}`\r\n : `use${capitalize(resource.endsWith(\"s\") ? resource.slice(0, -1) : resource)}`;\r\n const keyFactory = isList\r\n ? `keys.${resource}Keys.list`\r\n : `keys.${resource}Keys.detail`;\r\n const fetcherName = route.operationId;\r\n\r\n // Check if fetcher actually accepts params\r\n const hasQueryParams = route.parameters?.some((p) => p.in === \"query\");\r\n\r\n let params = \"\";\r\n let fetcherArgs = \"\";\r\n let keyArgs = \"\";\r\n\r\n if (isList && hasQueryParams) {\r\n params = \"params?: Record<string, unknown>, \";\r\n fetcherArgs = \"params\";\r\n keyArgs = \"params\";\r\n } else if (isList) {\r\n // List without params\r\n keyArgs = \"undefined\";\r\n } else if (!isList) {\r\n params = \"id: string, \";\r\n fetcherArgs = \"id\";\r\n keyArgs = \"id\";\r\n }\r\n\r\n return `export function ${hookName}(${params}config?: SWRConfiguration) {\r\n return useSWR(\r\n ${keyFactory}(${keyArgs}),\r\n () => fetchers.${resource}Fetchers.${fetcherName}(${fetcherArgs}),\r\n config\r\n );\r\n}\r\n\r\n`;\r\n}\r\n\r\nfunction generateSWRMutationHook(\r\n resource: string,\r\n route: RouteDefinition,\r\n): string {\r\n const hookName = generateHookName(resource, route);\r\n const fetcherName = route.operationId;\r\n\r\n const pathParams = route.parameters?.filter((p) => p.in === \"path\") || [];\r\n const hasBody = route.method !== \"DELETE\" && route.method !== \"GET\";\r\n\r\n let argType = \"{ \";\r\n for (const param of pathParams) {\r\n argType += `${param.name}: string; `;\r\n }\r\n if (hasBody) {\r\n argType += \"body?: unknown; \";\r\n }\r\n argType += \"}\";\r\n\r\n let fetcherArgs = \"\";\r\n for (const param of pathParams) {\r\n fetcherArgs += `arg.${param.name}, `;\r\n }\r\n if (hasBody) {\r\n fetcherArgs += \"arg.body\";\r\n } else {\r\n fetcherArgs = fetcherArgs.slice(0, -2);\r\n }\r\n\r\n return `export function ${hookName}() {\r\n return useSWRMutation(\r\n keys.${resource}Keys.all,\r\n async (_key, { arg }: { arg: ${argType} }) => \r\n fetchers.${resource}Fetchers.${fetcherName}(${fetcherArgs})\r\n );\r\n}\r\n\r\n`;\r\n}\r\n\r\nfunction extractResource(path: string): string {\r\n const parts = path.split(\"/\").filter(Boolean);\r\n const resourcePart = parts.find((p) => !p.startsWith(\"{\") && p !== \"v1\");\r\n return resourcePart || \"api\";\r\n}\r\n\r\nfunction capitalize(str: string): string {\r\n return str.charAt(0).toUpperCase() + str.slice(1);\r\n}\r\n","import fs from \"node:fs\";\r\nimport path from \"node:path\";\r\nimport type { RouteDefinition } from \"../types\";\r\n\r\ninterface GenerateKeysOptions {\r\n openApiPath: string;\r\n outputDir: string;\r\n}\r\n\r\nexport async function generateKeys(\r\n options: GenerateKeysOptions,\r\n): Promise<void> {\r\n const { openApiPath, outputDir } = options;\r\n\r\n // Parse OpenAPI spec\r\n const spec = JSON.parse(fs.readFileSync(openApiPath, \"utf-8\"));\r\n const routes = parseRoutes(spec);\r\n\r\n // Generate query keys code\r\n const code = generateKeysCode(routes);\r\n\r\n // Write to keys.ts\r\n const keysPath = path.join(outputDir, \"keys.ts\");\r\n fs.writeFileSync(keysPath, code);\r\n}\r\n\r\nfunction parseRoutes(spec: any): RouteDefinition[] {\r\n const routes: RouteDefinition[] = [];\r\n\r\n for (const [path, pathItem] of Object.entries<any>(spec.paths || {})) {\r\n for (const [method, operation] of Object.entries<any>(pathItem)) {\r\n if (![\"get\", \"post\", \"put\", \"delete\", \"patch\"].includes(method)) continue;\r\n\r\n routes.push({\r\n path,\r\n method: method.toUpperCase() as any,\r\n operationId:\r\n operation.operationId || `${method}${path.replace(/\\//g, \"_\")}`,\r\n parameters: operation.parameters || [],\r\n requestBody: operation.requestBody,\r\n responses: operation.responses || {},\r\n });\r\n }\r\n }\r\n\r\n return routes;\r\n}\r\n\r\nfunction generateKeysCode(routes: RouteDefinition[]): string {\r\n let code = `/**\r\n * This file was auto-generated by route-handler client generator.\r\n * Do not make direct changes to this file.\r\n * \r\n * Query key factories following TanStack Query best practices.\r\n * @see https://tkdodo.eu/blog/effective-react-query-keys\r\n */\r\n\r\n`;\r\n\r\n // Group routes by resource\r\n const resourceMap = new Map<string, RouteDefinition[]>();\r\n for (const route of routes) {\r\n const resource = extractResource(route.path);\r\n if (!resourceMap.has(resource)) {\r\n resourceMap.set(resource, []);\r\n }\r\n resourceMap.get(resource)!.push(route);\r\n }\r\n\r\n // Generate query keys for each resource\r\n for (const [resource, resourceRoutes] of resourceMap) {\r\n code += `export const ${resource}Keys = {\\n`;\r\n code += ` all: [\"${resource}\"] as const,\\n`;\r\n\r\n // Generate list keys\r\n const listRoutes = resourceRoutes.filter(\r\n (r) => !r.path.includes(\"{\") && r.method === \"GET\",\r\n );\r\n if (listRoutes.length > 0) {\r\n code += ` lists: () => [...${resource}Keys.all, \"list\"] as const,\\n`;\r\n code += ` list: (filters?: Record<string, unknown>) => [...${resource}Keys.lists(), filters] as const,\\n`;\r\n }\r\n\r\n // Generate detail keys\r\n const detailRoutes = resourceRoutes.filter(\r\n (r) => r.path.includes(\"{\") && r.method === \"GET\",\r\n );\r\n if (detailRoutes.length > 0) {\r\n code += ` details: () => [...${resource}Keys.all, \"detail\"] as const,\\n`;\r\n code += ` detail: (id: string) => [...${resource}Keys.details(), id] as const,\\n`;\r\n }\r\n\r\n code += `};\\n\\n`;\r\n }\r\n\r\n return code;\r\n}\r\n\r\nfunction extractResource(path: string): string {\r\n // Extract resource name from path: /v1/resumes -> resumes\r\n const parts = path.split(\"/\").filter(Boolean);\r\n const resourcePart = parts.find((p) => !p.startsWith(\"{\") && p !== \"v1\");\r\n return resourcePart || \"api\";\r\n}\r\n","import fs from \"node:fs\";\r\nimport path from \"node:path\";\r\nimport openapiTS, { astToString } from \"openapi-typescript\";\r\n\r\ninterface GenerateTypesOptions {\r\n openApiPath: string;\r\n outputDir: string;\r\n}\r\n\r\nexport async function generateTypes(\r\n options: GenerateTypesOptions,\r\n): Promise<void> {\r\n const { openApiPath, outputDir } = options;\r\n\r\n // Generate types using openapi-typescript\r\n const ast = await openapiTS(new URL(`file://${path.resolve(openApiPath)}`));\r\n\r\n const output = astToString(ast);\r\n\r\n const header = `/**\r\n * This file was auto-generated by route-handler client generator.\r\n * Do not make direct changes to this file.\r\n */\r\n\r\n`;\r\n\r\n // Write to types.ts\r\n const typesPath = path.join(outputDir, \"types.ts\");\r\n fs.writeFileSync(typesPath, header + output);\r\n}\r\n"],"mappings":"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","names":["import_node_fs","import_node_path","fs","path","import_node_fs","import_node_path","fs","parseRoutes","path","extractResource","import_node_fs","import_node_path","fs","parseRoutes","path","extractResource","import_node_fs","import_node_path","openapiTS","path","fs","path","fs","exports"]}
|