cushin-monorepo 3.0.1

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.
Files changed (103) hide show
  1. package/.changeset/README.md +8 -0
  2. package/.changeset/config.json +14 -0
  3. package/.claude/settings.local.json +44 -0
  4. package/CHANGELOG.md +93 -0
  5. package/LICENSE +0 -0
  6. package/README.md +482 -0
  7. package/biome.json +34 -0
  8. package/dist/cli.d.ts +1 -0
  9. package/dist/cli.js +1552 -0
  10. package/dist/cli.js.map +1 -0
  11. package/dist/config/index.d.ts +84 -0
  12. package/dist/config/index.js +69 -0
  13. package/dist/config/index.js.map +1 -0
  14. package/dist/config/schema.d.ts +43 -0
  15. package/dist/config/schema.js +14 -0
  16. package/dist/config/schema.js.map +1 -0
  17. package/dist/index.d.ts +27 -0
  18. package/dist/index.js +1666 -0
  19. package/dist/index.js.map +1 -0
  20. package/dist/runtime/client.d.ts +40 -0
  21. package/dist/runtime/client.js +260 -0
  22. package/dist/runtime/client.js.map +1 -0
  23. package/package.json +41 -0
  24. package/packages/api-codegen/CHANGELOG.md +86 -0
  25. package/packages/api-codegen/biome.json +34 -0
  26. package/packages/api-codegen/dist/cli.js +1038 -0
  27. package/packages/api-codegen/dist/cli.js.map +1 -0
  28. package/packages/api-codegen/dist/index.d.ts +103 -0
  29. package/packages/api-codegen/dist/index.js +1026 -0
  30. package/packages/api-codegen/dist/index.js.map +1 -0
  31. package/packages/api-codegen/node_modules/.bin/acorn +21 -0
  32. package/packages/api-codegen/node_modules/.bin/conventional-changelog +21 -0
  33. package/packages/api-codegen/node_modules/.bin/conventional-commits-parser +21 -0
  34. package/packages/api-codegen/node_modules/.bin/esbuild +21 -0
  35. package/packages/api-codegen/node_modules/.bin/eslint +21 -0
  36. package/packages/api-codegen/node_modules/.bin/jiti +21 -0
  37. package/packages/api-codegen/node_modules/.bin/next +21 -0
  38. package/packages/api-codegen/node_modules/.bin/tsc +21 -0
  39. package/packages/api-codegen/node_modules/.bin/tsserver +21 -0
  40. package/packages/api-codegen/node_modules/.bin/tsup +21 -0
  41. package/packages/api-codegen/node_modules/.bin/tsup-node +21 -0
  42. package/packages/api-codegen/node_modules/.bin/vitest +21 -0
  43. package/packages/api-codegen/package.json +88 -0
  44. package/packages/api-runtime/CHANGELOG.md +46 -0
  45. package/packages/api-runtime/README.md +95 -0
  46. package/packages/api-runtime/dist/chunk-3FFXWCVP.js +17 -0
  47. package/packages/api-runtime/dist/chunk-3FFXWCVP.js.map +1 -0
  48. package/packages/api-runtime/dist/chunk-EZ5P7OPH.js +267 -0
  49. package/packages/api-runtime/dist/chunk-EZ5P7OPH.js.map +1 -0
  50. package/packages/api-runtime/dist/client.d.ts +40 -0
  51. package/packages/api-runtime/dist/client.js +13 -0
  52. package/packages/api-runtime/dist/client.js.map +1 -0
  53. package/packages/api-runtime/dist/index.d.ts +3 -0
  54. package/packages/api-runtime/dist/index.js +21 -0
  55. package/packages/api-runtime/dist/index.js.map +1 -0
  56. package/packages/api-runtime/dist/schema.d.ts +45 -0
  57. package/packages/api-runtime/dist/schema.js +11 -0
  58. package/packages/api-runtime/dist/schema.js.map +1 -0
  59. package/packages/api-runtime/node_modules/.bin/esbuild +21 -0
  60. package/packages/api-runtime/node_modules/.bin/jiti +21 -0
  61. package/packages/api-runtime/node_modules/.bin/tsc +21 -0
  62. package/packages/api-runtime/node_modules/.bin/tsserver +21 -0
  63. package/packages/api-runtime/node_modules/.bin/tsup +21 -0
  64. package/packages/api-runtime/node_modules/.bin/tsup-node +21 -0
  65. package/packages/api-runtime/package.json +54 -0
  66. package/packages/cli/CHANGELOG.md +34 -0
  67. package/packages/cli/biome.json +34 -0
  68. package/packages/cli/dist/index.d.ts +27 -0
  69. package/packages/cli/dist/index.js +183 -0
  70. package/packages/cli/dist/index.js.map +1 -0
  71. package/packages/cli/node_modules/.bin/esbuild +21 -0
  72. package/packages/cli/node_modules/.bin/jiti +21 -0
  73. package/packages/cli/node_modules/.bin/tsc +21 -0
  74. package/packages/cli/node_modules/.bin/tsserver +21 -0
  75. package/packages/cli/node_modules/.bin/tsup +21 -0
  76. package/packages/cli/node_modules/.bin/tsup-node +21 -0
  77. package/packages/cli/package.json +47 -0
  78. package/pnpm-workspace.yaml +2 -0
  79. package/test-config.js +9 -0
  80. package/test-content-type-handling.mjs +100 -0
  81. package/test-endpoints-config.mjs +144 -0
  82. package/test-formdata-content-type-protection.mjs +127 -0
  83. package/test-formdata-runtime.mjs +127 -0
  84. package/test-full-integration.mjs +90 -0
  85. package/test-headers-formdata.mjs +97 -0
  86. package/test-headers-runtime.mjs +106 -0
  87. package/test-headers.mjs +79 -0
  88. package/test-internal-calls.mjs +57 -0
  89. package/test-ky-formdata.mjs +81 -0
  90. package/test-output/actions.ts +134 -0
  91. package/test-output/client.ts +81 -0
  92. package/test-output/hooks.ts +182 -0
  93. package/test-output/index.ts +9 -0
  94. package/test-output/prefetchs.ts +25 -0
  95. package/test-output/queries.ts +78 -0
  96. package/test-output/query-keys.ts +16 -0
  97. package/test-output/query-options.ts +38 -0
  98. package/test-output/server-client.ts +32 -0
  99. package/test-output/types.ts +61 -0
  100. package/test-real-endpoints.mjs +132 -0
  101. package/test-runtime-params.mjs +160 -0
  102. package/test-simple-config.mjs +71 -0
  103. package/tsconfig.base.json +29 -0
@@ -0,0 +1,8 @@
1
+ # Changesets
2
+
3
+ Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works
4
+ with multi-package repos, or single-package repos to help you version and publish your code. You can
5
+ find the full documentation for it [in our repository](https://github.com/changesets/changesets)
6
+
7
+ We have a quick list of common questions to get you started engaging with this project in
8
+ [our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md)
@@ -0,0 +1,14 @@
1
+ {
2
+ "$schema": "https://unpkg.com/@changesets/config@3.0.0/schema.json",
3
+ "changelog": "@changesets/cli/changelog",
4
+ "commit": false,
5
+ "fixed": [],
6
+ "linked": [],
7
+ "access": "public",
8
+ "baseBranch": "main",
9
+ "updateInternalDependencies": "patch",
10
+ "ignore": [],
11
+ "___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH": {
12
+ "onlyUpdatePeerDependentsWhenOutOfRange": true
13
+ }
14
+ }
@@ -0,0 +1,44 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "Bash(pnpm install:*)",
5
+ "Bash(pnpm build:*)",
6
+ "Bash(node /home/hash/work/node/api-codegen/packages/api-codegen/dist/cli.js:*)",
7
+ "Bash(tree:*)",
8
+ "Bash(mkdir:*)",
9
+ "Bash(node /home/hash/work/node/codegen/test-import.mjs:*)",
10
+ "Bash(node /home/hash/work/node/codegen/packages/test-package/test.mjs:*)",
11
+ "Bash(cat:*)",
12
+ "Bash(pnpm changeset:*)",
13
+ "Bash(pnpm version-packages:*)",
14
+ "Bash(git add:*)",
15
+ "Bash(git commit:*)",
16
+ "Bash(npx tsc:*)",
17
+ "Bash(pnpm typecheck:*)",
18
+ "Bash(node test.mjs:*)",
19
+ "Bash(git --git-dir=/home/hash/work/node/codegen/.git --work-tree=/home/hash/work/node/codegen status:*)",
20
+ "Bash(bash -c \"cd /home/hash/work/node/codegen && git status\")",
21
+ "Bash(bash -c 'cd /home/hash/work/node/codegen && pnpm changeset')",
22
+ "Bash(bash -c 'export HOME=/home/hash && cd /home/hash/work/node/codegen && /home/hash/work/node/codegen/node_modules/.bin/changeset version':*)",
23
+ "Bash(export HOME=/home/hash:*)",
24
+ "Bash(/usr/bin/bash:*)",
25
+ "Bash(node /home/hash/work/node/codegen/test-runtime-params.mjs:*)",
26
+ "Bash(node /home/hash/work/node/codegen/test-full-integration.mjs:*)",
27
+ "Bash(node /home/hash/work/node/codegen/test-internal-calls.mjs:*)",
28
+ "Bash(pnpm publish:*)",
29
+ "Bash(node test-full-integration.mjs:*)",
30
+ "Bash(node /home/hash/work/node/codegen/packages/api-codegen/dist/cli.js generate:*)",
31
+ "Bash(node test-headers-formdata.mjs:*)",
32
+ "Bash(node test-headers.mjs:*)",
33
+ "Bash(node test-headers-runtime.mjs:*)",
34
+ "Bash(node test-formdata-runtime.mjs:*)",
35
+ "Bash(pnpm -F @cushin/api-runtime build:*)",
36
+ "Bash(node test-ky-formdata.mjs:*)",
37
+ "Bash(pnpm add:*)",
38
+ "Bash(node test-content-type-handling.mjs:*)",
39
+ "Bash(node test-formdata-content-type-protection.mjs:*)"
40
+ ],
41
+ "deny": [],
42
+ "ask": []
43
+ }
44
+ }
package/CHANGELOG.md ADDED
@@ -0,0 +1,93 @@
1
+ ## <small>4.0.5 (2025-12-19)</small>
2
+
3
+ * feat: add custom headers support for endpoints - allows per-endpoint header configuration for API keys, tracking, and metadata
4
+ * feat: add automatic FormData detection and handling - runtime client now detects FormData bodies and handles Content-Type correctly
5
+ * docs: add comprehensive CUSTOM_HEADERS.md documentation with examples for file uploads, React hooks, and Next.js server actions
6
+ * docs: update README with custom headers and FormData usage examples
7
+
8
+ ## <small>2.0.6 (2025-12-18)</small>
9
+
10
+ * fix: handle undefined params in server-client and client type definitions - endpoints without params, query, or body no longer require passing undefined
11
+
12
+ ## <small>1.0.5 (2025-11-24)</small>
13
+
14
+ * fix: add jiti loader to support TypeScript endpoint files ([eac2867](https://github.com/cushin-org/api-codegen/commit/eac2867))
15
+ * fix: remove unused imports ([7c46e10](https://github.com/cushin-org/api-codegen/commit/7c46e10))
16
+ * fix: resolve build and npm deployment errors ([cef18d7](https://github.com/cushin-org/api-codegen/commit/cef18d7))
17
+ * chore: bump version to 1.0.1 - fix build and npm deployment errors ([6bda5b4](https://github.com/cushin-org/api-codegen/commit/6bda5b4))
18
+ * chore: bump version to 1.0.2 ([5d3a6cd](https://github.com/cushin-org/api-codegen/commit/5d3a6cd))
19
+ * chore: bump version to 1.0.3 ([d7f2489](https://github.com/cushin-org/api-codegen/commit/d7f2489))
20
+ * chore: bump version to 1.0.4 ([7aa777e](https://github.com/cushin-org/api-codegen/commit/7aa777e))
21
+ * chore: bump version to 1.0.4 ([a94bed3](https://github.com/cushin-org/api-codegen/commit/a94bed3))
22
+ * chore: remove unused packed file ([694d3a8](https://github.com/cushin-org/api-codegen/commit/694d3a8))
23
+ * docs: update CHANGELOG ([01b2c9c](https://github.com/cushin-org/api-codegen/commit/01b2c9c))
24
+ * docs: update document for cli ([e27c4fa](https://github.com/cushin-org/api-codegen/commit/e27c4fa))
25
+ * docs: update github username ([98b86f0](https://github.com/cushin-org/api-codegen/commit/98b86f0))
26
+ * Add GitHub Actions workflow for npm publish ([0298a75](https://github.com/cushin-org/api-codegen/commit/0298a75))
27
+ * init project ([d0847c2](https://github.com/cushin-org/api-codegen/commit/d0847c2))
28
+ * update README ([65b6962](https://github.com/cushin-org/api-codegen/commit/65b6962))
29
+ * update README ([e1866ed](https://github.com/cushin-org/api-codegen/commit/e1866ed))
30
+
31
+
32
+
33
+ ## <small>1.0.4 (2025-11-24)</small>
34
+
35
+ * fix: add jiti loader to support TypeScript endpoint files ([eac2867](https://github.com/cushin-org/api-codegen/commit/eac2867))
36
+ * fix: remove unused imports ([7c46e10](https://github.com/cushin-org/api-codegen/commit/7c46e10))
37
+ * fix: resolve build and npm deployment errors ([cef18d7](https://github.com/cushin-org/api-codegen/commit/cef18d7))
38
+ * chore: bump version to 1.0.1 - fix build and npm deployment errors ([6bda5b4](https://github.com/cushin-org/api-codegen/commit/6bda5b4))
39
+ * chore: bump version to 1.0.2 ([5d3a6cd](https://github.com/cushin-org/api-codegen/commit/5d3a6cd))
40
+ * chore: bump version to 1.0.3 ([d7f2489](https://github.com/cushin-org/api-codegen/commit/d7f2489))
41
+ * chore: bump version to 1.0.4 ([7aa777e](https://github.com/cushin-org/api-codegen/commit/7aa777e))
42
+ * chore: bump version to 1.0.4 ([a94bed3](https://github.com/cushin-org/api-codegen/commit/a94bed3))
43
+ * chore: remove unused packed file ([694d3a8](https://github.com/cushin-org/api-codegen/commit/694d3a8))
44
+ * docs: update CHANGELOG ([01b2c9c](https://github.com/cushin-org/api-codegen/commit/01b2c9c))
45
+ * docs: update document for cli ([e27c4fa](https://github.com/cushin-org/api-codegen/commit/e27c4fa))
46
+ * docs: update github username ([98b86f0](https://github.com/cushin-org/api-codegen/commit/98b86f0))
47
+ * Add GitHub Actions workflow for npm publish ([0298a75](https://github.com/cushin-org/api-codegen/commit/0298a75))
48
+ * init project ([d0847c2](https://github.com/cushin-org/api-codegen/commit/d0847c2))
49
+ * update README ([65b6962](https://github.com/cushin-org/api-codegen/commit/65b6962))
50
+ * update README ([e1866ed](https://github.com/cushin-org/api-codegen/commit/e1866ed))
51
+
52
+
53
+
54
+ ## <small>1.0.4 (2025-11-24)</small>
55
+
56
+ * chore: bump version to 1.0.1 - fix build and npm deployment errors ([6bda5b4](https://github.com/cushin-org/api-codegen/commit/6bda5b4))
57
+ * chore: bump version to 1.0.2 ([5d3a6cd](https://github.com/cushin-org/api-codegen/commit/5d3a6cd))
58
+ * chore: bump version to 1.0.3 ([d7f2489](https://github.com/cushin-org/api-codegen/commit/d7f2489))
59
+ * chore: bump version to 1.0.4 ([a94bed3](https://github.com/cushin-org/api-codegen/commit/a94bed3))
60
+ * chore: remove unused packed file ([694d3a8](https://github.com/cushin-org/api-codegen/commit/694d3a8))
61
+ * fix: add jiti loader to support TypeScript endpoint files ([eac2867](https://github.com/cushin-org/api-codegen/commit/eac2867))
62
+ * fix: resolve build and npm deployment errors ([cef18d7](https://github.com/cushin-org/api-codegen/commit/cef18d7))
63
+ * docs: update CHANGELOG ([01b2c9c](https://github.com/cushin-org/api-codegen/commit/01b2c9c))
64
+ * docs: update document for cli ([e27c4fa](https://github.com/cushin-org/api-codegen/commit/e27c4fa))
65
+ * docs: update github username ([98b86f0](https://github.com/cushin-org/api-codegen/commit/98b86f0))
66
+ * Add GitHub Actions workflow for npm publish ([0298a75](https://github.com/cushin-org/api-codegen/commit/0298a75))
67
+ * init project ([d0847c2](https://github.com/cushin-org/api-codegen/commit/d0847c2))
68
+ * update README ([65b6962](https://github.com/cushin-org/api-codegen/commit/65b6962))
69
+ * update README ([e1866ed](https://github.com/cushin-org/api-codegen/commit/e1866ed))
70
+
71
+
72
+
73
+ ## <small>1.0.2 (2025-11-22)</small>
74
+
75
+ * docs: update document for cli ([e27c4fa](https://github.com/cushin-org/api-codegen/commit/e27c4fa))
76
+ * docs: update github username ([98b86f0](https://github.com/cushin-org/api-codegen/commit/98b86f0))
77
+ * Add GitHub Actions workflow for npm publish ([0298a75](https://github.com/cushin-org/api-codegen/commit/0298a75))
78
+ * init project ([d0847c2](https://github.com/cushin-org/api-codegen/commit/d0847c2))
79
+ * update README ([65b6962](https://github.com/cushin-org/api-codegen/commit/65b6962))
80
+ * update README ([e1866ed](https://github.com/cushin-org/api-codegen/commit/e1866ed))
81
+ * fix: resolve build and npm deployment errors ([cef18d7](https://github.com/cushin-org/api-codegen/commit/cef18d7))
82
+
83
+
84
+
85
+ # 1.0.0 (2025-11-22)
86
+
87
+
88
+ ### Bug Fixes
89
+
90
+ * resolve build and npm deployment errors ([cef18d7](https://github.com/hashdotlee/api-codegen/commit/cef18d795e2ac83818b3a06b7bb38bdecc46295b))
91
+
92
+
93
+
package/LICENSE ADDED
File without changes
package/README.md ADDED
@@ -0,0 +1,482 @@
1
+ # @cushin/api-codegen
2
+
3
+ Type-safe API client generator for React/Next.js applications with automatic hooks and server actions generation.
4
+
5
+ ## Features
6
+
7
+ - 🎯 **Type-Safe**: Full TypeScript support with Zod schema validation
8
+ - 🔄 **Auto-Generated**: Generate React Query hooks, Server Actions, and Server Queries
9
+ - 🚀 **Framework Agnostic**: Works with Vite, Next.js, and more
10
+ - 🔐 **Auth Built-in**: Token refresh, automatic retry with customizable callbacks
11
+ - 📦 **Zero Config**: Simple configuration with sensible defaults
12
+ - 🎨 **Customizable**: Custom templates and generation options
13
+ - 📤 **File Uploads**: Automatic FormData detection and handling
14
+ - 🔧 **Custom Headers**: Per-endpoint header configuration for API keys and metadata
15
+
16
+ ## Installation
17
+
18
+ ```bash
19
+ npm install @cushin/api-codegen ky zod
20
+ # or
21
+ pnpm add @cushin/api-codegen ky zod
22
+ # or
23
+ yarn add @cushin/api-codegen ky zod
24
+ ```
25
+
26
+ For React Query support (client-side):
27
+ ```bash
28
+ npm install @tanstack/react-query
29
+ ```
30
+
31
+ ## Quick Start
32
+
33
+ ### 1. Initialize Configuration
34
+
35
+ ```bash
36
+ npx @cushin/api-codegen init --provider vite
37
+ # or for Next.js
38
+ npx @cushin/api-codegen init --provider nextjs
39
+ ```
40
+
41
+ This creates `api-codegen.config.js`:
42
+
43
+ ```js
44
+ /** @type {import('@cushin/api-codegen').UserConfig} */
45
+ export default {
46
+ provider: 'vite',
47
+ endpoints: './lib/api/config/endpoints.ts',
48
+ output: './lib/api/generated',
49
+ baseUrl: process.env.VITE_API_URL,
50
+ generateHooks: true,
51
+ generateClient: true,
52
+ };
53
+ ```
54
+
55
+ ### 2. Define Your API Endpoints
56
+
57
+ Create your endpoints configuration file:
58
+
59
+ ```typescript
60
+ // lib/api/config/endpoints.ts
61
+ import { z } from 'zod';
62
+ import { defineConfig, defineEndpoint } from '@cushin/api-codegen';
63
+
64
+ // Define your schemas
65
+ const UserSchema = z.object({
66
+ id: z.string(),
67
+ name: z.string(),
68
+ email: z.string().email(),
69
+ });
70
+
71
+ const CreateUserSchema = z.object({
72
+ name: z.string(),
73
+ email: z.string().email(),
74
+ });
75
+
76
+ // Define your endpoints
77
+ export const apiConfig = defineConfig({
78
+ baseUrl: 'https://api.example.com',
79
+ endpoints: {
80
+ // GET request
81
+ getUser: defineEndpoint({
82
+ path: '/users/:id',
83
+ method: 'GET',
84
+ params: z.object({ id: z.string() }),
85
+ response: UserSchema,
86
+ tags: ['users', 'query'],
87
+ description: 'Get user by ID',
88
+ }),
89
+
90
+ // GET with query params
91
+ listUsers: defineEndpoint({
92
+ path: '/users',
93
+ method: 'GET',
94
+ query: z.object({
95
+ page: z.number().optional(),
96
+ limit: z.number().optional(),
97
+ }),
98
+ response: z.array(UserSchema),
99
+ tags: ['users', 'query'],
100
+ }),
101
+
102
+ // POST request
103
+ createUser: defineEndpoint({
104
+ path: '/users',
105
+ method: 'POST',
106
+ body: CreateUserSchema,
107
+ response: UserSchema,
108
+ tags: ['users', 'mutation'],
109
+ }),
110
+
111
+ // PUT request with params
112
+ updateUser: defineEndpoint({
113
+ path: '/users/:id',
114
+ method: 'PUT',
115
+ params: z.object({ id: z.string() }),
116
+ body: CreateUserSchema,
117
+ response: UserSchema,
118
+ tags: ['users', 'mutation'],
119
+ }),
120
+
121
+ // DELETE request
122
+ deleteUser: defineEndpoint({
123
+ path: '/users/:id',
124
+ method: 'DELETE',
125
+ params: z.object({ id: z.string() }),
126
+ response: z.object({ success: z.boolean() }),
127
+ tags: ['users', 'mutation'],
128
+ }),
129
+ },
130
+ });
131
+ ```
132
+
133
+ ### 3. Generate Code
134
+
135
+ ```bash
136
+ npx @cushin/api-codegen generate
137
+ ```
138
+
139
+ This generates:
140
+ - `generated/types.ts` - Type definitions
141
+ - `generated/client.ts` - API client
142
+ - `generated/hooks.ts` - React Query hooks
143
+ - `generated/actions.ts` - Server Actions (Next.js only)
144
+ - `generated/queries.ts` - Server Queries (Next.js only)
145
+
146
+ ### 4. Initialize Client (Vite)
147
+
148
+ ```typescript
149
+ // lib/auth/provider.tsx
150
+ import { initializeAPIClient } from '@/lib/api/generated/client';
151
+
152
+ export function AuthProvider({ children }) {
153
+ useEffect(() => {
154
+ initializeAPIClient({
155
+ getTokens: () => {
156
+ const token = localStorage.getItem('access_token');
157
+ return token ? { accessToken: token } : null;
158
+ },
159
+ setTokens: (tokens) => {
160
+ localStorage.setItem('access_token', tokens.accessToken);
161
+ },
162
+ clearTokens: () => {
163
+ localStorage.removeItem('access_token');
164
+ },
165
+ onAuthError: () => {
166
+ router.push('/login');
167
+ },
168
+ onRefreshToken: async () => {
169
+ const response = await fetch('/api/auth/refresh', {
170
+ method: 'POST',
171
+ credentials: 'include',
172
+ });
173
+ const data = await response.json();
174
+ return data.accessToken;
175
+ },
176
+ });
177
+ }, []);
178
+
179
+ return <>{children}</>;
180
+ }
181
+ ```
182
+
183
+ ### 5. Use Generated Hooks
184
+
185
+ ```typescript
186
+ // components/UserList.tsx
187
+ import { useListUsers, useCreateUser, useDeleteUser } from '@/lib/api/generated/hooks';
188
+
189
+ export function UserList() {
190
+ // Query hook
191
+ const { data: users, isLoading } = useListUsers({
192
+ page: 1,
193
+ limit: 10,
194
+ });
195
+
196
+ // Mutation hooks
197
+ const createUser = useCreateUser({
198
+ onSuccess: () => {
199
+ console.log('User created!');
200
+ },
201
+ });
202
+
203
+ const deleteUser = useDeleteUser();
204
+
205
+ const handleCreate = () => {
206
+ createUser.mutate({
207
+ name: 'John Doe',
208
+ email: 'john@example.com',
209
+ });
210
+ };
211
+
212
+ const handleDelete = (id: string) => {
213
+ deleteUser.mutate({ id });
214
+ };
215
+
216
+ if (isLoading) return <div>Loading...</div>;
217
+
218
+ return (
219
+ <div>
220
+ <button onClick={handleCreate}>Create User</button>
221
+ {users?.map((user) => (
222
+ <div key={user.id}>
223
+ {user.name}
224
+ <button onClick={() => handleDelete(user.id)}>Delete</button>
225
+ </div>
226
+ ))}
227
+ </div>
228
+ );
229
+ }
230
+ ```
231
+
232
+ ## Next.js Usage
233
+
234
+ ### Server Components
235
+
236
+ ```typescript
237
+ // app/users/page.tsx
238
+ import { listUsersQuery } from '@/lib/api/generated/queries';
239
+
240
+ export default async function UsersPage() {
241
+ const users = await listUsersQuery({ page: 1, limit: 10 });
242
+
243
+ return (
244
+ <div>
245
+ {users.map((user) => (
246
+ <div key={user.id}>{user.name}</div>
247
+ ))}
248
+ </div>
249
+ );
250
+ }
251
+ ```
252
+
253
+ ### Server Actions
254
+
255
+ ```typescript
256
+ // app/users/actions.ts
257
+ 'use client';
258
+
259
+ import { createUserAction, deleteUserAction } from '@/lib/api/generated/actions';
260
+ import { useTransition } from 'react';
261
+
262
+ export function UserForm() {
263
+ const [isPending, startTransition] = useTransition();
264
+
265
+ const handleSubmit = async (formData: FormData) => {
266
+ startTransition(async () => {
267
+ const result = await createUserAction({
268
+ name: formData.get('name') as string,
269
+ email: formData.get('email') as string,
270
+ });
271
+
272
+ if (result.success) {
273
+ console.log('User created:', result.data);
274
+ } else {
275
+ console.error('Error:', result.error);
276
+ }
277
+ });
278
+ };
279
+
280
+ return <form action={handleSubmit}>...</form>;
281
+ }
282
+ ```
283
+
284
+ ## Configuration
285
+
286
+ ### Full Configuration Options
287
+
288
+ ```typescript
289
+ /** @type {import('@cushin/api-codegen').UserConfig} */
290
+ export default {
291
+ // Required: Provider type
292
+ provider: 'vite' | 'nextjs',
293
+
294
+ // Required: Path to endpoints configuration
295
+ endpoints: './lib/api/config/endpoints.ts',
296
+
297
+ // Required: Output directory
298
+ output: './lib/api/generated',
299
+
300
+ // Optional: Base URL (can also be set at runtime)
301
+ baseUrl: process.env.VITE_API_URL,
302
+
303
+ // Optional: Generation flags
304
+ generateHooks: true, // Generate React Query hooks
305
+ generateClient: true, // Generate API client
306
+ generateServerActions: true, // Next.js only
307
+ generateServerQueries: true, // Next.js only
308
+
309
+ // Optional: Advanced options
310
+ options: {
311
+ useClientDirective: true, // Add 'use client' to generated files
312
+ hookPrefix: 'use', // Prefix for hook names (e.g., useGetUser)
313
+ actionSuffix: 'Action', // Suffix for action names (e.g., createUserAction)
314
+ customImports: {
315
+ // Add custom imports to generated files
316
+ hooks: ['import { customHook } from "./custom"'],
317
+ },
318
+ },
319
+ };
320
+ ```
321
+
322
+ ## CLI Commands
323
+
324
+ ```bash
325
+ # Generate code from config
326
+ npx @cushin/api-codegen generate
327
+
328
+ # Generate with specific config file
329
+ npx @cushin/api-codegen generate --config ./custom.config.js
330
+
331
+ # Initialize new config
332
+ npx @cushin/api-codegen init --provider nextjs
333
+
334
+ # Validate configuration
335
+ npx @cushin/api-codegen validate
336
+ ```
337
+
338
+ ## Advanced Usage
339
+
340
+ ### Custom Headers
341
+
342
+ Add custom headers to specific endpoints for API keys, tracking, or other metadata:
343
+
344
+ ```typescript
345
+ defineEndpoint({
346
+ path: '/api/data',
347
+ method: 'POST',
348
+ body: z.object({ name: z.string() }),
349
+ response: z.object({ id: z.string() }),
350
+ headers: {
351
+ 'X-API-Key': process.env.THIRD_PARTY_API_KEY,
352
+ 'X-Custom-Header': 'custom-value',
353
+ },
354
+ });
355
+ ```
356
+
357
+ ### FormData Support
358
+
359
+ The client automatically detects and handles FormData for file uploads:
360
+
361
+ ```typescript
362
+ // Define endpoint (no body schema needed for FormData)
363
+ const uploadAvatar = defineEndpoint({
364
+ path: '/users/:userId/avatar',
365
+ method: 'POST',
366
+ params: z.object({ userId: z.string() }),
367
+ response: z.object({ avatarUrl: z.string() }),
368
+ headers: {
369
+ 'X-Upload-Source': 'web-app', // Optional custom headers
370
+ },
371
+ });
372
+
373
+ // Usage
374
+ const formData = new FormData();
375
+ formData.append('avatar', fileBlob, 'avatar.jpg');
376
+
377
+ const result = await apiClient.uploadAvatar(
378
+ { userId: '123' },
379
+ formData
380
+ );
381
+ ```
382
+
383
+ See [CUSTOM_HEADERS.md](./CUSTOM_HEADERS.md) for detailed documentation and examples.
384
+
385
+ ### Custom Base URL per Endpoint
386
+
387
+ ```typescript
388
+ defineEndpoint({
389
+ path: '/auth/login',
390
+ method: 'POST',
391
+ baseUrl: 'https://auth.example.com', // Override base URL
392
+ body: LoginSchema,
393
+ response: TokenSchema,
394
+ });
395
+ ```
396
+
397
+ ### Multiple Endpoints Files
398
+
399
+ ```typescript
400
+ // lib/api/config/modules/users.ts
401
+ export const userEndpoints = {
402
+ getUser: defineEndpoint({ ... }),
403
+ createUser: defineEndpoint({ ... }),
404
+ };
405
+
406
+ // lib/api/config/endpoints.ts
407
+ import { userEndpoints } from './modules/users';
408
+ import { productEndpoints } from './modules/products';
409
+
410
+ export const apiConfig = defineConfig({
411
+ baseUrl: 'https://api.example.com',
412
+ endpoints: {
413
+ ...userEndpoints,
414
+ ...productEndpoints,
415
+ },
416
+ });
417
+ ```
418
+
419
+ ### Custom Auth Logic
420
+
421
+ ```typescript
422
+ initializeAPIClient({
423
+ getTokens: () => {
424
+ // Custom token retrieval
425
+ return yourAuthStore.getTokens();
426
+ },
427
+ setTokens: (tokens) => {
428
+ // Custom token storage
429
+ yourAuthStore.setTokens(tokens);
430
+ },
431
+ clearTokens: () => {
432
+ // Custom cleanup
433
+ yourAuthStore.clearTokens();
434
+ },
435
+ onRefreshToken: async () => {
436
+ // Custom refresh logic
437
+ const newToken = await yourRefreshFunction();
438
+ return newToken;
439
+ },
440
+ onAuthError: () => {
441
+ // Custom error handling
442
+ yourRouter.push('/login');
443
+ },
444
+ });
445
+ ```
446
+
447
+ ## Type Safety
448
+
449
+ All generated code is fully typed:
450
+
451
+ ```typescript
452
+ // IntelliSense knows the exact shape
453
+ const { data } = useGetUser({ id: '123' });
454
+ // ^? { id: string; name: string; email: string; }
455
+
456
+ // TypeScript will error on invalid params
457
+ const { data } = useGetUser({ id: 123 }); // ❌ Type error
458
+ const { data } = useGetUser({ wrongParam: '123' }); // ❌ Type error
459
+
460
+ // Mutation inputs are also typed
461
+ createUser.mutate({
462
+ name: 'John',
463
+ email: 'invalid', // ❌ Type error: invalid email format
464
+ });
465
+ ```
466
+
467
+ ## Best Practices
468
+
469
+ 1. **Organize endpoints by feature/module**
470
+ 2. **Use descriptive endpoint names**
471
+ 3. **Add descriptions to endpoints for better documentation**
472
+ 4. **Use tags for query invalidation**
473
+ 5. **Define reusable schemas**
474
+ 6. **Keep baseUrl in environment variables**
475
+
476
+ ## Contributing
477
+
478
+ Contributions are welcome! Please read our contributing guide.
479
+
480
+ ## License
481
+
482
+ MIT © Le Viet Hoang
package/biome.json ADDED
@@ -0,0 +1,34 @@
1
+ {
2
+ "$schema": "https://biomejs.dev/schemas/2.2.5/schema.json",
3
+ "vcs": {
4
+ "enabled": false,
5
+ "clientKind": "git",
6
+ "useIgnoreFile": false
7
+ },
8
+ "files": {
9
+ "ignoreUnknown": false
10
+ },
11
+ "formatter": {
12
+ "enabled": true,
13
+ "indentStyle": "space"
14
+ },
15
+ "linter": {
16
+ "enabled": true,
17
+ "rules": {
18
+ "recommended": true
19
+ }
20
+ },
21
+ "javascript": {
22
+ "formatter": {
23
+ "quoteStyle": "double"
24
+ }
25
+ },
26
+ "assist": {
27
+ "enabled": true,
28
+ "actions": {
29
+ "source": {
30
+ "organizeImports": "on"
31
+ }
32
+ }
33
+ }
34
+ }
package/dist/cli.d.ts ADDED
@@ -0,0 +1 @@
1
+ #!/usr/bin/env node