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,182 @@
1
+ 'use client';
2
+
3
+ import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
4
+ import { apiClient } from "./client";
5
+ import { queryKeys } from "./query-keys";
6
+ import { apiQueryOptions } from "./query-options";
7
+ import { z } from "zod";
8
+ import { apiConfig } from "../test-real-endpoints.mjs";
9
+
10
+ /**
11
+ * List all users
12
+ * @tags none
13
+ */
14
+ export function useListUsers(options?: {
15
+ enabled?: boolean;
16
+ select?: <TData = z.infer<NonNullable<typeof apiConfig.endpoints.listUsers.response>>>(data: z.infer<NonNullable<typeof apiConfig.endpoints.listUsers.response>>) => TData;
17
+ }) {
18
+ return useQuery({
19
+ ...apiQueryOptions.users.listUsers(),
20
+ ...options,
21
+ });
22
+ }
23
+
24
+ /**
25
+ * Get user by ID
26
+ * @tags none
27
+ */
28
+ export function useGetUser(params: z.infer<NonNullable<typeof apiConfig.endpoints.getUser.params>>,
29
+ options?: {
30
+ enabled?: boolean;
31
+ select?: <TData = z.infer<NonNullable<typeof apiConfig.endpoints.getUser.response>>>(data: z.infer<NonNullable<typeof apiConfig.endpoints.getUser.response>>) => TData;
32
+ }) {
33
+ return useQuery({
34
+ ...apiQueryOptions.users.user(params),
35
+ ...options,
36
+ });
37
+ }
38
+
39
+ /**
40
+ * Search users
41
+ * @tags none
42
+ */
43
+ export function useSearchUsers(filters?: z.infer<NonNullable<typeof apiConfig.endpoints.searchUsers.query>>,
44
+ options?: {
45
+ enabled?: boolean;
46
+ select?: <TData = z.infer<NonNullable<typeof apiConfig.endpoints.searchUsers.response>>>(data: z.infer<NonNullable<typeof apiConfig.endpoints.searchUsers.response>>) => TData;
47
+ }) {
48
+ return useQuery({
49
+ ...apiQueryOptions.users.searchUsers(filters),
50
+ ...options,
51
+ });
52
+ }
53
+
54
+ /**
55
+ * Get user posts
56
+ * @tags none
57
+ */
58
+ export function useGetUserPosts(params: z.infer<NonNullable<typeof apiConfig.endpoints.getUserPosts.params>>,
59
+ filters?: z.infer<NonNullable<typeof apiConfig.endpoints.getUserPosts.query>>,
60
+ options?: {
61
+ enabled?: boolean;
62
+ select?: <TData = z.infer<NonNullable<typeof apiConfig.endpoints.getUserPosts.response>>>(data: z.infer<NonNullable<typeof apiConfig.endpoints.getUserPosts.response>>) => TData;
63
+ }) {
64
+ return useQuery({
65
+ ...apiQueryOptions.users.userPosts(params, filters),
66
+ ...options,
67
+ });
68
+ }
69
+ /**
70
+ * Create new session
71
+ * @tags auth
72
+ */
73
+ export function useCreateSession(options?: {
74
+ onSuccess?: (data: z.infer<NonNullable<typeof apiConfig.endpoints.createSession.response>>, variables: void, context: unknown) => void;
75
+ onError?: (error: Error, variables: void, context: unknown) => void;
76
+ onSettled?: (data: z.infer<NonNullable<typeof apiConfig.endpoints.createSession.response>> | undefined, error: Error | null, variables: void, context: unknown) => void;
77
+ onMutate?: (variables: void) => Promise<unknown> | unknown;
78
+ }) {
79
+
80
+ return useMutation({
81
+ mutationFn: () => apiClient.createSession(),
82
+ onSuccess: (data, variables, context) => {
83
+
84
+ options?.onSuccess?.(data, variables, context);
85
+ },
86
+ onError: options?.onError,
87
+ onSettled: options?.onSettled,
88
+ onMutate: options?.onMutate,
89
+ });
90
+ }
91
+
92
+ /**
93
+ * Create new user
94
+ * @tags users
95
+ */
96
+ export function useCreateUser(options?: {
97
+ onSuccess?: (data: z.infer<NonNullable<typeof apiConfig.endpoints.createUser.response>>, variables: z.infer<NonNullable<typeof apiConfig.endpoints.createUser.body>>, context: unknown) => void;
98
+ onError?: (error: Error, variables: z.infer<NonNullable<typeof apiConfig.endpoints.createUser.body>>, context: unknown) => void;
99
+ onSettled?: (data: z.infer<NonNullable<typeof apiConfig.endpoints.createUser.response>> | undefined, error: Error | null, variables: z.infer<NonNullable<typeof apiConfig.endpoints.createUser.body>>, context: unknown) => void;
100
+ onMutate?: (variables: z.infer<NonNullable<typeof apiConfig.endpoints.createUser.body>>) => Promise<unknown> | unknown;
101
+ }) {
102
+ const queryClient = useQueryClient();
103
+ return useMutation({
104
+ mutationFn: (body: z.infer<NonNullable<typeof apiConfig.endpoints.createUser.body>>) => apiClient.createUser(body),
105
+ onSuccess: (data, variables, context) => {
106
+ queryClient.invalidateQueries({ queryKey: queryKeys.users.all });
107
+ options?.onSuccess?.(data, variables, context);
108
+ },
109
+ onError: options?.onError,
110
+ onSettled: options?.onSettled,
111
+ onMutate: options?.onMutate,
112
+ });
113
+ }
114
+
115
+ /**
116
+ * Update user
117
+ * @tags users
118
+ */
119
+ export function useUpdateUser(options?: {
120
+ onSuccess?: (data: z.infer<NonNullable<typeof apiConfig.endpoints.updateUser.response>>, variables: { params: z.infer<NonNullable<typeof apiConfig.endpoints.updateUser.params>>; body: z.infer<NonNullable<typeof apiConfig.endpoints.updateUser.body>>; }, context: unknown) => void;
121
+ onError?: (error: Error, variables: { params: z.infer<NonNullable<typeof apiConfig.endpoints.updateUser.params>>; body: z.infer<NonNullable<typeof apiConfig.endpoints.updateUser.body>>; }, context: unknown) => void;
122
+ onSettled?: (data: z.infer<NonNullable<typeof apiConfig.endpoints.updateUser.response>> | undefined, error: Error | null, variables: { params: z.infer<NonNullable<typeof apiConfig.endpoints.updateUser.params>>; body: z.infer<NonNullable<typeof apiConfig.endpoints.updateUser.body>>; }, context: unknown) => void;
123
+ onMutate?: (variables: { params: z.infer<NonNullable<typeof apiConfig.endpoints.updateUser.params>>; body: z.infer<NonNullable<typeof apiConfig.endpoints.updateUser.body>>; }) => Promise<unknown> | unknown;
124
+ }) {
125
+ const queryClient = useQueryClient();
126
+ return useMutation({
127
+ mutationFn: ({ params, body }: { params: z.infer<NonNullable<typeof apiConfig.endpoints.updateUser.params>>; body: z.infer<NonNullable<typeof apiConfig.endpoints.updateUser.body>>; }) => apiClient.updateUser(params, body),
128
+ onSuccess: (data, variables, context) => {
129
+ queryClient.invalidateQueries({ queryKey: queryKeys.users.all });
130
+ options?.onSuccess?.(data, variables, context);
131
+ },
132
+ onError: options?.onError,
133
+ onSettled: options?.onSettled,
134
+ onMutate: options?.onMutate,
135
+ });
136
+ }
137
+
138
+ /**
139
+ * Delete user
140
+ * @tags users
141
+ */
142
+ export function useDeleteUser(options?: {
143
+ onSuccess?: (data: z.infer<NonNullable<typeof apiConfig.endpoints.deleteUser.response>>, variables: z.infer<NonNullable<typeof apiConfig.endpoints.deleteUser.params>>, context: unknown) => void;
144
+ onError?: (error: Error, variables: z.infer<NonNullable<typeof apiConfig.endpoints.deleteUser.params>>, context: unknown) => void;
145
+ onSettled?: (data: z.infer<NonNullable<typeof apiConfig.endpoints.deleteUser.response>> | undefined, error: Error | null, variables: z.infer<NonNullable<typeof apiConfig.endpoints.deleteUser.params>>, context: unknown) => void;
146
+ onMutate?: (variables: z.infer<NonNullable<typeof apiConfig.endpoints.deleteUser.params>>) => Promise<unknown> | unknown;
147
+ }) {
148
+ const queryClient = useQueryClient();
149
+ return useMutation({
150
+ mutationFn: (params: z.infer<NonNullable<typeof apiConfig.endpoints.deleteUser.params>>) => apiClient.deleteUser(params),
151
+ onSuccess: (data, variables, context) => {
152
+ queryClient.invalidateQueries({ queryKey: queryKeys.users.all });
153
+ options?.onSuccess?.(data, variables, context);
154
+ },
155
+ onError: options?.onError,
156
+ onSettled: options?.onSettled,
157
+ onMutate: options?.onMutate,
158
+ });
159
+ }
160
+
161
+ /**
162
+ * Refresh access token
163
+ * @tags auth
164
+ */
165
+ export function useRefreshToken(options?: {
166
+ onSuccess?: (data: z.infer<NonNullable<typeof apiConfig.endpoints.refreshToken.response>>, variables: void, context: unknown) => void;
167
+ onError?: (error: Error, variables: void, context: unknown) => void;
168
+ onSettled?: (data: z.infer<NonNullable<typeof apiConfig.endpoints.refreshToken.response>> | undefined, error: Error | null, variables: void, context: unknown) => void;
169
+ onMutate?: (variables: void) => Promise<unknown> | unknown;
170
+ }) {
171
+
172
+ return useMutation({
173
+ mutationFn: () => apiClient.refreshToken(),
174
+ onSuccess: (data, variables, context) => {
175
+
176
+ options?.onSuccess?.(data, variables, context);
177
+ },
178
+ onError: options?.onError,
179
+ onSettled: options?.onSettled,
180
+ onMutate: options?.onMutate,
181
+ });
182
+ }
@@ -0,0 +1,9 @@
1
+ // Auto-generated exports
2
+ export * from './types';
3
+ export * from './client';
4
+ export * from './query-keys';
5
+ export * from './query-options';
6
+ export * from './hooks';
7
+ export * from './prefetchs';
8
+ export { z } from 'zod';
9
+ export { apiConfig } from '../test-real-endpoints.mjs';
@@ -0,0 +1,25 @@
1
+ // Auto-generated prefetch utilities
2
+ import { type QueryClient } from '@tanstack/react-query';
3
+ import { apiQueryOptions } from './query-options';
4
+ import { z } from 'zod';
5
+ import { apiConfig } from '../config/endpoints';
6
+
7
+ export const prefetchListUsers = async (queryClient: QueryClient) => {
8
+ return await queryClient.ensureQueryData(apiQueryOptions.users.listUsers());
9
+ };
10
+
11
+ export const prefetchGetUser = async (queryClient: QueryClient,
12
+ params: z.infer<NonNullable<typeof apiConfig.endpoints.getUser.params>>) => {
13
+ return await queryClient.ensureQueryData(apiQueryOptions.users.user(params));
14
+ };
15
+
16
+ export const prefetchSearchUsers = async (queryClient: QueryClient,
17
+ filters?: z.infer<NonNullable<typeof apiConfig.endpoints.searchUsers.query>>) => {
18
+ return await queryClient.ensureQueryData(apiQueryOptions.users.searchUsers(filters));
19
+ };
20
+
21
+ export const prefetchGetUserPosts = async (queryClient: QueryClient,
22
+ params: z.infer<NonNullable<typeof apiConfig.endpoints.getUserPosts.params>>,
23
+ filters?: z.infer<NonNullable<typeof apiConfig.endpoints.getUserPosts.query>>) => {
24
+ return await queryClient.ensureQueryData(apiQueryOptions.users.userPosts(params, filters));
25
+ };
@@ -0,0 +1,78 @@
1
+ import { cache } from 'react';
2
+ import { unstable_cache } from 'next/cache';
3
+ import { serverClient } from './server-client';
4
+ import type {
5
+ APIEndpoints,
6
+ ExtractParams,
7
+ ExtractQuery,
8
+ ExtractResponse
9
+ } from './types';
10
+
11
+ /**
12
+ * List all users
13
+ * @tags none
14
+ */
15
+ export const listUsersQuery = cache(async (
16
+
17
+ ): Promise<ExtractResponse<APIEndpoints['listUsers']>> => {
18
+ return unstable_cache(
19
+ async () => serverClient.listUsers(),
20
+ ['listUsers'],
21
+ {
22
+ tags: [],
23
+ revalidate: 3600, // 1 hour default, can be overridden
24
+ }
25
+ )();
26
+ });
27
+
28
+ /**
29
+ * Get user by ID
30
+ * @tags none
31
+ */
32
+ export const getUserQuery = cache(async (
33
+ params: ExtractParams<APIEndpoints['getUser']>
34
+ ): Promise<ExtractResponse<APIEndpoints['getUser']>> => {
35
+ return unstable_cache(
36
+ async () => serverClient.getUser(params),
37
+ ['getUser', JSON.stringify(params)],
38
+ {
39
+ tags: [],
40
+ revalidate: 3600, // 1 hour default, can be overridden
41
+ }
42
+ )();
43
+ });
44
+
45
+ /**
46
+ * Search users
47
+ * @tags none
48
+ */
49
+ export const searchUsersQuery = cache(async (
50
+ query?: ExtractQuery<APIEndpoints['searchUsers']>
51
+ ): Promise<ExtractResponse<APIEndpoints['searchUsers']>> => {
52
+ return unstable_cache(
53
+ async () => serverClient.searchUsers(query),
54
+ ['searchUsers', query ? JSON.stringify(query) : 'no-query'],
55
+ {
56
+ tags: [],
57
+ revalidate: 3600, // 1 hour default, can be overridden
58
+ }
59
+ )();
60
+ });
61
+
62
+ /**
63
+ * Get user posts
64
+ * @tags none
65
+ */
66
+ export const getUserPostsQuery = cache(async (
67
+ params: ExtractParams<APIEndpoints['getUserPosts']>,
68
+ query?: ExtractQuery<APIEndpoints['getUserPosts']>
69
+ ): Promise<ExtractResponse<APIEndpoints['getUserPosts']>> => {
70
+ return unstable_cache(
71
+ async () => serverClient.getUserPosts(params, query),
72
+ ['getUserPosts', JSON.stringify(params), query ? JSON.stringify(query) : 'no-query'],
73
+ {
74
+ tags: [],
75
+ revalidate: 3600, // 1 hour default, can be overridden
76
+ }
77
+ )();
78
+ });
@@ -0,0 +1,16 @@
1
+ // Auto-generated query keys
2
+ import { z } from 'zod';
3
+ import { apiConfig } from '../test-real-endpoints.mjs';
4
+
5
+ export const queryKeys = {
6
+ users: {
7
+ all: ['users'] as const,
8
+ listUsers: () => ['users', 'listUsers'] as const,
9
+ user: (params?: z.infer<NonNullable<typeof apiConfig.endpoints.getUser.params>>) =>
10
+ ['users', 'user', params, undefined] as const,
11
+ searchUsers: (query?: z.infer<NonNullable<typeof apiConfig.endpoints.searchUsers.query>>) =>
12
+ ['users', 'searchUsers', undefined, query] as const,
13
+ userPosts: (params?: z.infer<NonNullable<typeof apiConfig.endpoints.getUserPosts.params>>, query?: z.infer<NonNullable<typeof apiConfig.endpoints.getUserPosts.query>>) =>
14
+ ['users', 'userPosts', params, query] as const,
15
+ },
16
+ } as const;
@@ -0,0 +1,38 @@
1
+ // Auto-generated query options
2
+ import { queryOptions } from '@tanstack/react-query';
3
+ import { apiClient } from './client';
4
+ import { queryKeys } from './query-keys';
5
+ import { z } from 'zod';
6
+ import { apiConfig } from '../test-real-endpoints.mjs';
7
+
8
+ const usersQueryOptions = {
9
+ listUsers: () =>
10
+ queryOptions({
11
+ queryKey: queryKeys.users.listUsers(),
12
+ queryFn: (): Promise<z.infer<NonNullable<typeof apiConfig.endpoints.listUsers.response>>> => apiClient.listUsers(),
13
+ staleTime: 1000 * 60 * 5,
14
+ }),
15
+ user: (params: z.infer<NonNullable<typeof apiConfig.endpoints.getUser.params>>) =>
16
+ queryOptions({
17
+ queryKey: queryKeys.users.user(params),
18
+ queryFn: (): Promise<z.infer<NonNullable<typeof apiConfig.endpoints.getUser.response>>> => apiClient.getUser(params),
19
+ staleTime: 1000 * 60 * 5,
20
+ }),
21
+ searchUsers: (filters?: z.infer<NonNullable<typeof apiConfig.endpoints.searchUsers.query>>) =>
22
+ queryOptions({
23
+ queryKey: queryKeys.users.searchUsers(filters),
24
+ queryFn: (): Promise<z.infer<NonNullable<typeof apiConfig.endpoints.searchUsers.response>>> => apiClient.searchUsers(filters),
25
+ staleTime: 1000 * 60 * 5,
26
+ }),
27
+ userPosts: (params: z.infer<NonNullable<typeof apiConfig.endpoints.getUserPosts.params>>, filters?: z.infer<NonNullable<typeof apiConfig.endpoints.getUserPosts.query>>) =>
28
+ queryOptions({
29
+ queryKey: queryKeys.users.userPosts(params, filters),
30
+ queryFn: (): Promise<z.infer<NonNullable<typeof apiConfig.endpoints.getUserPosts.response>>> => apiClient.getUserPosts(params, filters),
31
+ staleTime: 1000 * 60 * 5,
32
+ }),
33
+ };
34
+
35
+
36
+ export const apiQueryOptions = {
37
+ users: usersQueryOptions,
38
+ } as const;
@@ -0,0 +1,32 @@
1
+ import { createAPIClient } from '@cushin/api-runtime';
2
+ import { apiConfig } from '../test-real-endpoints.mjs';
3
+ import { z } from 'zod';
4
+
5
+ // Type the methods based on endpoints
6
+ type APIClientMethods = {
7
+ [K in keyof typeof apiConfig.endpoints]: (typeof apiConfig.endpoints)[K] extends infer E
8
+ ? E extends { method: "GET"; params: infer P; query: infer Q; response: infer R }
9
+ ? (params: P extends z.ZodType ? z.infer<P> : never, query?: Q extends z.ZodType ? z.infer<Q> : never) => Promise<R extends z.ZodType ? z.infer<R> : never>
10
+ : E extends { method: "GET"; params: infer P; response: infer R }
11
+ ? (params: P extends z.ZodType ? z.infer<P> : never) => Promise<R extends z.ZodType ? z.infer<R> : never>
12
+ : E extends { method: "GET"; query: infer Q; response: infer R }
13
+ ? (query?: Q extends z.ZodType ? z.infer<Q> : never) => Promise<R extends z.ZodType ? z.infer<R> : never>
14
+ : E extends { method: "GET"; response: infer R }
15
+ ? () => Promise<R extends z.ZodType ? z.infer<R> : never>
16
+ : E extends { method: string; params: infer P; body: infer B; response: infer R }
17
+ ? (params: P extends z.ZodType ? z.infer<P> : never, body: B extends z.ZodType ? z.infer<B> : never) => Promise<R extends z.ZodType ? z.infer<R> : never>
18
+ : E extends { method: string; params: infer P; response: infer R }
19
+ ? (params: P extends z.ZodType ? z.infer<P> : never) => Promise<R extends z.ZodType ? z.infer<R> : never>
20
+ : E extends { method: string; body: infer B; response: infer R }
21
+ ? (body: B extends z.ZodType ? z.infer<B> : never) => Promise<R extends z.ZodType ? z.infer<R> : never>
22
+ : E extends { method: string; response: infer R }
23
+ ? () => Promise<R extends z.ZodType ? z.infer<R> : never>
24
+ : never
25
+ : never;
26
+ };
27
+
28
+ /**
29
+ * Server-side API client (no auth, direct API calls)
30
+ * Use this in Server Components, Server Actions, and Route Handlers
31
+ */
32
+ export const serverClient = createAPIClient(apiConfig) as APIClientMethods;
@@ -0,0 +1,61 @@
1
+ // Auto-generated type definitions
2
+ // Do not edit this file manually
3
+
4
+ import type { z } from 'zod';
5
+ import { apiConfig } from '../test-real-endpoints.mjs';
6
+
7
+
8
+ // Re-export endpoint configuration types
9
+ export type { APIConfig, APIEndpoint, HTTPMethod } from '@cushin/api-runtime';
10
+
11
+ /**
12
+ * Type helper to extract params schema from an endpoint
13
+ */
14
+ export type ExtractParams<T> = T extends { params: infer P extends z.ZodType }
15
+ ? z.infer<P>
16
+ : never;
17
+
18
+ /**
19
+ * Type helper to extract query schema from an endpoint
20
+ */
21
+ export type ExtractQuery<T> = T extends { query: infer Q extends z.ZodType }
22
+ ? z.infer<Q>
23
+ : never;
24
+
25
+ /**
26
+ * Type helper to extract body schema from an endpoint
27
+ */
28
+ export type ExtractBody<T> = T extends { body: infer B extends z.ZodType }
29
+ ? z.infer<B>
30
+ : never;
31
+
32
+ /**
33
+ * Type helper to extract response schema from an endpoint
34
+ */
35
+ export type ExtractResponse<T> = T extends { response: infer R extends z.ZodType }
36
+ ? z.infer<R>
37
+ : never;
38
+
39
+ /**
40
+ * Import your API config to get typed endpoints
41
+ *
42
+ */
43
+ export type APIEndpoints = typeof apiConfig.endpoints;
44
+
45
+ export type ListUsersResponse = z.infer<NonNullable<typeof apiConfig.endpoints.listUsers.response>>;
46
+ export type GetUserResponse = z.infer<NonNullable<typeof apiConfig.endpoints.getUser.response>>;
47
+ export type GetUserParams = z.infer<NonNullable<typeof apiConfig.endpoints.getUser.params>>;
48
+ export type SearchUsersResponse = z.infer<NonNullable<typeof apiConfig.endpoints.searchUsers.response>>;
49
+ export type SearchUsersQuery = z.infer<NonNullable<typeof apiConfig.endpoints.searchUsers.query>>;
50
+ export type GetUserPostsResponse = z.infer<NonNullable<typeof apiConfig.endpoints.getUserPosts.response>>;
51
+ export type GetUserPostsQuery = z.infer<NonNullable<typeof apiConfig.endpoints.getUserPosts.query>>;
52
+ export type GetUserPostsParams = z.infer<NonNullable<typeof apiConfig.endpoints.getUserPosts.params>>;
53
+ export type CreateSessionResponse = z.infer<NonNullable<typeof apiConfig.endpoints.createSession.response>>;
54
+ export type CreateUserResponse = z.infer<NonNullable<typeof apiConfig.endpoints.createUser.response>>;
55
+ export type CreateUserInput = z.infer<NonNullable<typeof apiConfig.endpoints.createUser.body>>;
56
+ export type UpdateUserResponse = z.infer<NonNullable<typeof apiConfig.endpoints.updateUser.response>>;
57
+ export type UpdateUserInput = z.infer<NonNullable<typeof apiConfig.endpoints.updateUser.body>>;
58
+ export type UpdateUserParams = z.infer<NonNullable<typeof apiConfig.endpoints.updateUser.params>>;
59
+ export type DeleteUserResponse = z.infer<NonNullable<typeof apiConfig.endpoints.deleteUser.response>>;
60
+ export type DeleteUserParams = z.infer<NonNullable<typeof apiConfig.endpoints.deleteUser.params>>;
61
+ export type RefreshTokenResponse = z.infer<NonNullable<typeof apiConfig.endpoints.refreshToken.response>>;
@@ -0,0 +1,132 @@
1
+ import { z } from 'zod';
2
+ import { defineEndpoint, defineConfig } from './packages/api-runtime/dist/index.js';
3
+
4
+ export const apiConfig = defineConfig({
5
+ baseUrl: 'https://api.example.com',
6
+ endpoints: {
7
+ // Case 1: GET - No params, no query
8
+ listUsers: defineEndpoint({
9
+ path: '/users',
10
+ method: 'GET',
11
+ response: z.object({
12
+ users: z.array(z.object({ id: z.string(), name: z.string() })),
13
+ }),
14
+ description: 'List all users',
15
+ }),
16
+
17
+ // Case 2: GET - Has params only
18
+ getUser: defineEndpoint({
19
+ path: '/users/:id',
20
+ method: 'GET',
21
+ params: z.object({ id: z.string() }),
22
+ response: z.object({
23
+ id: z.string(),
24
+ name: z.string(),
25
+ email: z.string(),
26
+ }),
27
+ description: 'Get user by ID',
28
+ }),
29
+
30
+ // Case 3: GET - Has query only
31
+ searchUsers: defineEndpoint({
32
+ path: '/users/search',
33
+ method: 'GET',
34
+ query: z.object({
35
+ q: z.string(),
36
+ limit: z.number().optional(),
37
+ }),
38
+ response: z.object({
39
+ results: z.array(z.object({ id: z.string(), name: z.string() })),
40
+ }),
41
+ description: 'Search users',
42
+ }),
43
+
44
+ // Case 4: GET - Has params and query
45
+ getUserPosts: defineEndpoint({
46
+ path: '/users/:id/posts',
47
+ method: 'GET',
48
+ params: z.object({ id: z.string() }),
49
+ query: z.object({
50
+ status: z.enum(['draft', 'published']).optional(),
51
+ limit: z.number().optional(),
52
+ }),
53
+ response: z.object({
54
+ posts: z.array(z.object({ id: z.string(), title: z.string() })),
55
+ }),
56
+ description: 'Get user posts',
57
+ }),
58
+
59
+ // Case 5: POST - No params, no body (create session)
60
+ createSession: defineEndpoint({
61
+ path: '/sessions',
62
+ method: 'POST',
63
+ response: z.object({
64
+ sessionId: z.string(),
65
+ expiresAt: z.string(),
66
+ }),
67
+ tags: ['auth'],
68
+ description: 'Create new session',
69
+ }),
70
+
71
+ // Case 6: POST - Has body only
72
+ createUser: defineEndpoint({
73
+ path: '/users',
74
+ method: 'POST',
75
+ body: z.object({
76
+ name: z.string(),
77
+ email: z.string().email(),
78
+ }),
79
+ response: z.object({
80
+ id: z.string(),
81
+ name: z.string(),
82
+ email: z.string(),
83
+ }),
84
+ tags: ['users'],
85
+ description: 'Create new user',
86
+ }),
87
+
88
+ // Case 7: POST - Has params and body
89
+ updateUser: defineEndpoint({
90
+ path: '/users/:id',
91
+ method: 'POST',
92
+ params: z.object({ id: z.string() }),
93
+ body: z.object({
94
+ name: z.string().optional(),
95
+ email: z.string().email().optional(),
96
+ }),
97
+ response: z.object({
98
+ id: z.string(),
99
+ name: z.string(),
100
+ email: z.string(),
101
+ }),
102
+ tags: ['users'],
103
+ description: 'Update user',
104
+ }),
105
+
106
+ // Case 8: DELETE - Has params only
107
+ deleteUser: defineEndpoint({
108
+ path: '/users/:id',
109
+ method: 'DELETE',
110
+ params: z.object({ id: z.string() }),
111
+ response: z.object({
112
+ success: z.boolean(),
113
+ }),
114
+ tags: ['users'],
115
+ description: 'Delete user',
116
+ }),
117
+
118
+ // Case 9: PATCH - No params, no body (refresh token)
119
+ refreshToken: defineEndpoint({
120
+ path: '/auth/refresh',
121
+ method: 'PATCH',
122
+ response: z.object({
123
+ accessToken: z.string(),
124
+ refreshToken: z.string(),
125
+ }),
126
+ tags: ['auth'],
127
+ description: 'Refresh access token',
128
+ }),
129
+ },
130
+ });
131
+
132
+ export default apiConfig;