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.
- package/.changeset/README.md +8 -0
- package/.changeset/config.json +14 -0
- package/.claude/settings.local.json +44 -0
- package/CHANGELOG.md +93 -0
- package/LICENSE +0 -0
- package/README.md +482 -0
- package/biome.json +34 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +1552 -0
- package/dist/cli.js.map +1 -0
- package/dist/config/index.d.ts +84 -0
- package/dist/config/index.js +69 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/schema.d.ts +43 -0
- package/dist/config/schema.js +14 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.js +1666 -0
- package/dist/index.js.map +1 -0
- package/dist/runtime/client.d.ts +40 -0
- package/dist/runtime/client.js +260 -0
- package/dist/runtime/client.js.map +1 -0
- package/package.json +41 -0
- package/packages/api-codegen/CHANGELOG.md +86 -0
- package/packages/api-codegen/biome.json +34 -0
- package/packages/api-codegen/dist/cli.js +1038 -0
- package/packages/api-codegen/dist/cli.js.map +1 -0
- package/packages/api-codegen/dist/index.d.ts +103 -0
- package/packages/api-codegen/dist/index.js +1026 -0
- package/packages/api-codegen/dist/index.js.map +1 -0
- package/packages/api-codegen/node_modules/.bin/acorn +21 -0
- package/packages/api-codegen/node_modules/.bin/conventional-changelog +21 -0
- package/packages/api-codegen/node_modules/.bin/conventional-commits-parser +21 -0
- package/packages/api-codegen/node_modules/.bin/esbuild +21 -0
- package/packages/api-codegen/node_modules/.bin/eslint +21 -0
- package/packages/api-codegen/node_modules/.bin/jiti +21 -0
- package/packages/api-codegen/node_modules/.bin/next +21 -0
- package/packages/api-codegen/node_modules/.bin/tsc +21 -0
- package/packages/api-codegen/node_modules/.bin/tsserver +21 -0
- package/packages/api-codegen/node_modules/.bin/tsup +21 -0
- package/packages/api-codegen/node_modules/.bin/tsup-node +21 -0
- package/packages/api-codegen/node_modules/.bin/vitest +21 -0
- package/packages/api-codegen/package.json +88 -0
- package/packages/api-runtime/CHANGELOG.md +46 -0
- package/packages/api-runtime/README.md +95 -0
- package/packages/api-runtime/dist/chunk-3FFXWCVP.js +17 -0
- package/packages/api-runtime/dist/chunk-3FFXWCVP.js.map +1 -0
- package/packages/api-runtime/dist/chunk-EZ5P7OPH.js +267 -0
- package/packages/api-runtime/dist/chunk-EZ5P7OPH.js.map +1 -0
- package/packages/api-runtime/dist/client.d.ts +40 -0
- package/packages/api-runtime/dist/client.js +13 -0
- package/packages/api-runtime/dist/client.js.map +1 -0
- package/packages/api-runtime/dist/index.d.ts +3 -0
- package/packages/api-runtime/dist/index.js +21 -0
- package/packages/api-runtime/dist/index.js.map +1 -0
- package/packages/api-runtime/dist/schema.d.ts +45 -0
- package/packages/api-runtime/dist/schema.js +11 -0
- package/packages/api-runtime/dist/schema.js.map +1 -0
- package/packages/api-runtime/node_modules/.bin/esbuild +21 -0
- package/packages/api-runtime/node_modules/.bin/jiti +21 -0
- package/packages/api-runtime/node_modules/.bin/tsc +21 -0
- package/packages/api-runtime/node_modules/.bin/tsserver +21 -0
- package/packages/api-runtime/node_modules/.bin/tsup +21 -0
- package/packages/api-runtime/node_modules/.bin/tsup-node +21 -0
- package/packages/api-runtime/package.json +54 -0
- package/packages/cli/CHANGELOG.md +34 -0
- package/packages/cli/biome.json +34 -0
- package/packages/cli/dist/index.d.ts +27 -0
- package/packages/cli/dist/index.js +183 -0
- package/packages/cli/dist/index.js.map +1 -0
- package/packages/cli/node_modules/.bin/esbuild +21 -0
- package/packages/cli/node_modules/.bin/jiti +21 -0
- package/packages/cli/node_modules/.bin/tsc +21 -0
- package/packages/cli/node_modules/.bin/tsserver +21 -0
- package/packages/cli/node_modules/.bin/tsup +21 -0
- package/packages/cli/node_modules/.bin/tsup-node +21 -0
- package/packages/cli/package.json +47 -0
- package/pnpm-workspace.yaml +2 -0
- package/test-config.js +9 -0
- package/test-content-type-handling.mjs +100 -0
- package/test-endpoints-config.mjs +144 -0
- package/test-formdata-content-type-protection.mjs +127 -0
- package/test-formdata-runtime.mjs +127 -0
- package/test-full-integration.mjs +90 -0
- package/test-headers-formdata.mjs +97 -0
- package/test-headers-runtime.mjs +106 -0
- package/test-headers.mjs +79 -0
- package/test-internal-calls.mjs +57 -0
- package/test-ky-formdata.mjs +81 -0
- package/test-output/actions.ts +134 -0
- package/test-output/client.ts +81 -0
- package/test-output/hooks.ts +182 -0
- package/test-output/index.ts +9 -0
- package/test-output/prefetchs.ts +25 -0
- package/test-output/queries.ts +78 -0
- package/test-output/query-keys.ts +16 -0
- package/test-output/query-options.ts +38 -0
- package/test-output/server-client.ts +32 -0
- package/test-output/types.ts +61 -0
- package/test-real-endpoints.mjs +132 -0
- package/test-runtime-params.mjs +160 -0
- package/test-simple-config.mjs +71 -0
- 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;
|