diff --git a/apps/ui/scripts/codegen/new-feature.ts b/apps/ui/scripts/codegen/new-feature.ts index 6ae078ef..c0f56038 100644 --- a/apps/ui/scripts/codegen/new-feature.ts +++ b/apps/ui/scripts/codegen/new-feature.ts @@ -43,7 +43,8 @@ const dotFiles: Record = { [`${Name}.schemas.ts`]: `import { z } from "zod";\n\nexport const ${lower}ItemSchema = z.object({\n id: z.uuid(),\n createdAt: z.string()\n});\n`, [`${Name}.types.ts`]: `import type { z } from "zod";\nimport type { ${lower}ItemSchema } from "./${Name}.schemas";\n\nexport type I${Name}Item = z.infer;\n`, [`${Name}.utils.ts`]: `import type { I${Name}Item } from "./${Name}.types";\n\nexport function sort${Name}ByCreated(items: readonly I${Name}Item[]): I${Name}Item[] {\n return [...items].sort((a, b) => a.createdAt.localeCompare(b.createdAt));\n}\n`, - [`${Name}.queries.ts`]: `import { useQuery, type UseQueryResult } from "@tanstack/react-query";\nimport { ${Name.toUpperCase()}_QUERY_KEYS } from "./${Name}.constants";\nimport type { I${Name}Item } from "./${Name}.types";\n\n/**\n * Replace the queryFn stub with a typed call:\n *\n * import { apiClient } from "@/lib/api/client";\n * queryFn: async (): Promise => {\n * const { data } = await apiClient.GET("/api/${lower}");\n * return data ?? [];\n * }\n *\n * Run \`bun run generate:api\` after the endpoint is added to the OpenAPI spec.\n */\nexport function use${Name}(): UseQueryResult {\n return useQuery({\n queryKey: ${Name.toUpperCase()}_QUERY_KEYS.list,\n queryFn: async (): Promise => Promise.resolve([])\n });\n}\n`, + [`${Name}.queries.ts`]: `import { useQuery, type UseQueryResult } from "@tanstack/react-query";\nimport { ${Name.toUpperCase()}_QUERY_KEYS } from "./${Name}.constants";\nimport type { I${Name}Item } from "./${Name}.types";\n\n/**\n * Replace the queryFn stub with a typed call. Errors THROW via the client\n * middleware — do NOT check \`response.error\` (dead \`no-unnecessary-condition\`).\n * Read \`data\`:\n *\n * import { apiClient } from "@/lib/api/client";\n * queryFn: async (): Promise => {\n * const { data } = await apiClient.GET("/api/${lower}");\n * return data ?? [];\n * }\n *\n * Run \`bun run generate:api\` after the endpoint is added to the OpenAPI spec.\n */\nexport function use${Name}(): UseQueryResult {\n return useQuery({\n queryKey: ${Name.toUpperCase()}_QUERY_KEYS.list,\n queryFn: async (): Promise => Promise.resolve([])\n });\n}\n`, + [`${Name}.mutations.ts`]: `import {\n useMutation,\n useQueryClient,\n type UseMutationResult\n} from "@tanstack/react-query";\nimport { ${Name.toUpperCase()}_QUERY_KEYS } from "./${Name}.constants";\nimport type { I${Name}Item } from "./${Name}.types";\n\n/**\n * Replace the mutationFn stub with a typed call. Errors THROW via the client\n * middleware — do NOT check \`response.error\` (it is typed \`undefined\`, so any\n * such guard is a dead \`no-unnecessary-condition\` lint error). Read \`data\`:\n *\n * import { apiClient } from "@/lib/api/client";\n * mutationFn: async (input: I${Name}Item): Promise => {\n * const { data } = await apiClient.POST("/api/${lower}", { body: input });\n * return data;\n * }\n *\n * Run \`bun run generate:api\` after the endpoint is added to the OpenAPI spec.\n */\nexport function useCreate${Name}(): UseMutationResult<\n I${Name}Item,\n unknown,\n I${Name}Item\n> {\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: async (input: I${Name}Item): Promise =>\n Promise.resolve(input),\n onSuccess: () => {\n void queryClient.invalidateQueries({\n queryKey: ${Name.toUpperCase()}_QUERY_KEYS.list\n });\n }\n });\n}\n`, [`${Name}.store.ts`]: `import { create } from "zustand";\n\ninterface I${Name}State {\n readonly selectedId: string | null;\n setSelected(id: string | null): void;\n}\n\nexport const use${Name}Store = create((set) => ({\n selectedId: null,\n setSelected: (id) => {\n set({ selectedId: id });\n }\n}));\n` };