generator-kodly-react-app 1.0.15 → 1.0.17
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/generators/app/index.js +15 -1
- package/generators/app/templates/.env.sandbox +4 -3
- package/generators/app/templates/.node-version +1 -0
- package/generators/app/templates/.pnpmfile.cjs +14 -0
- package/generators/app/templates/.prettierignore +13 -0
- package/generators/app/templates/AGENTS.md +14 -0
- package/generators/app/templates/I18N_MIGRATION.md +13 -13
- package/generators/app/templates/STRUCTURE.md +26 -26
- package/generators/app/templates/TESTING.md +30 -0
- package/generators/app/templates/index.html +6 -14
- package/generators/app/templates/openapi-ts.config.ts +16 -12
- package/generators/app/templates/oxlint.config.ts +72 -0
- package/generators/app/templates/package.json +66 -52
- package/generators/app/templates/pnpm-workspace.yaml +19 -0
- package/generators/app/templates/scripts/check-duplicates.mjs +28 -0
- package/generators/app/templates/scripts/generated-files.mjs +21 -0
- package/generators/app/templates/src/app.tsx +20 -20
- package/generators/app/templates/src/components/layout/language-switcher.tsx +20 -16
- package/generators/app/templates/src/components/layout/page-layout.tsx +31 -0
- package/generators/app/templates/src/components/layout/theme-switcher.tsx +16 -15
- package/generators/app/templates/src/components/theme/theme-provider.tsx +20 -13
- package/generators/app/templates/src/components/ui/button.tsx +15 -14
- package/generators/app/templates/src/components/ui/card.tsx +23 -16
- package/generators/app/templates/src/components/ui/field.tsx +35 -35
- package/generators/app/templates/src/components/ui/form.tsx +66 -30
- package/generators/app/templates/src/components/ui/input-group.tsx +22 -28
- package/generators/app/templates/src/components/ui/input.tsx +8 -8
- package/generators/app/templates/src/components/ui/label.tsx +9 -9
- package/generators/app/templates/src/components/ui/select.tsx +0 -1
- package/generators/app/templates/src/components/ui/separator.tsx +10 -10
- package/generators/app/templates/src/components/ui/textarea.tsx +7 -7
- package/generators/app/templates/src/index.css +78 -68
- package/generators/app/templates/src/lib/i18n.ts +40 -31
- package/generators/app/templates/src/lib/routes.ts +2 -3
- package/generators/app/templates/src/lib/utils/error-handler.ts +21 -14
- package/generators/app/templates/src/lib/utils.ts +3 -3
- package/generators/app/templates/src/locales/index.ts +12 -12
- package/generators/app/templates/src/locales/ja/theme.json +0 -1
- package/generators/app/templates/src/main.tsx +10 -12
- package/generators/app/templates/src/modules/app/layouts/app-layout.tsx +14 -25
- package/generators/app/templates/src/modules/app/locales/app-en.json +0 -1
- package/generators/app/templates/src/modules/app/locales/app-ja.json +0 -1
- package/generators/app/templates/src/modules/auth/components/auth-form.tsx +86 -0
- package/generators/app/templates/src/modules/auth/components/forgot-password-form.tsx +27 -52
- package/generators/app/templates/src/modules/auth/components/login-form.tsx +42 -72
- package/generators/app/templates/src/modules/auth/components/login-link.tsx +12 -0
- package/generators/app/templates/src/modules/auth/components/reset-password-form.tsx +46 -92
- package/generators/app/templates/src/modules/auth/components/signup-form.tsx +35 -71
- package/generators/app/templates/src/modules/auth/contexts/auth-context.tsx +10 -6
- package/generators/app/templates/src/modules/auth/hooks/use-auth-hook.ts +54 -39
- package/generators/app/templates/src/modules/auth/layouts/auth-layout.tsx +12 -15
- package/generators/app/templates/src/modules/auth/locales/auth-en.json +0 -1
- package/generators/app/templates/src/modules/auth/locales/auth-ja.json +0 -1
- package/generators/app/templates/src/modules/auth/schemas/form-schemas.ts +14 -10
- package/generators/app/templates/src/modules/landing/components/auth-hero.tsx +20 -18
- package/generators/app/templates/src/modules/landing/components/welcome-hero.tsx +13 -11
- package/generators/app/templates/src/modules/landing/landing-page-layout.tsx +1 -24
- package/generators/app/templates/src/modules/landing/landing-page.tsx +11 -6
- package/generators/app/templates/src/modules/landing/layouts/landing-page-layout.tsx +2 -21
- package/generators/app/templates/src/modules/landing/locales/landing-en.json +0 -1
- package/generators/app/templates/src/openapi-client-config.ts +1 -1
- package/generators/app/templates/src/routeTree.gen.ts +188 -188
- package/generators/app/templates/src/router.tsx +4 -4
- package/generators/app/templates/src/routes/$.tsx +0 -1
- package/generators/app/templates/src/routes/__root.tsx +3 -3
- package/generators/app/templates/src/routes/_landing/index.tsx +3 -3
- package/generators/app/templates/src/routes/_landing/route.tsx +3 -3
- package/generators/app/templates/src/routes/app/index.tsx +6 -6
- package/generators/app/templates/src/routes/app/route.tsx +4 -4
- package/generators/app/templates/src/routes/auth/forgot-password.tsx +1 -1
- package/generators/app/templates/src/routes/auth/login.tsx +3 -3
- package/generators/app/templates/src/routes/auth/reset-password.tsx +3 -3
- package/generators/app/templates/src/routes/auth/route.tsx +16 -8
- package/generators/app/templates/src/routes/auth/signup.tsx +1 -2
- package/generators/app/templates/src/sdk/@tanstack/react-query.gen.ts +157 -76
- package/generators/app/templates/src/sdk/client/client.gen.ts +35 -37
- package/generators/app/templates/src/sdk/client/index.ts +8 -8
- package/generators/app/templates/src/sdk/client/types.gen.ts +22 -19
- package/generators/app/templates/src/sdk/client/utils.gen.ts +53 -45
- package/generators/app/templates/src/sdk/client.gen.ts +14 -5
- package/generators/app/templates/src/sdk/core/auth.gen.ts +6 -6
- package/generators/app/templates/src/sdk/core/bodySerializer.gen.ts +25 -27
- package/generators/app/templates/src/sdk/core/params.gen.ts +12 -12
- package/generators/app/templates/src/sdk/core/pathSerializer.gen.ts +40 -41
- package/generators/app/templates/src/sdk/core/queryKeySerializer.gen.ts +12 -29
- package/generators/app/templates/src/sdk/core/serverSentEvents.gen.ts +26 -24
- package/generators/app/templates/src/sdk/core/types.gen.ts +17 -15
- package/generators/app/templates/src/sdk/core/utils.gen.ts +18 -18
- package/generators/app/templates/src/sdk/index.ts +40 -2
- package/generators/app/templates/src/sdk/schemas.gen.ts +108 -166
- package/generators/app/templates/src/sdk/sdk.gen.ts +145 -63
- package/generators/app/templates/src/sdk/types.gen.ts +90 -84
- package/generators/app/templates/src/sdk/zod.gen.ts +57 -74
- package/generators/app/templates/src/types/i18n.d.ts +0 -1
- package/generators/app/templates/stylelint.config.js +55 -0
- package/generators/app/templates/tailwind.config.js +0 -1
- package/generators/app/templates/tests/form-controls.test.tsx +39 -0
- package/generators/app/templates/tests/sdk.test.ts +49 -0
- package/generators/app/templates/tests/setup.ts +5 -0
- package/generators/app/templates/tsconfig.app.json +0 -2
- package/generators/app/templates/tsconfig.json +2 -2
- package/generators/app/templates/tsr.config.json +4 -0
- package/generators/app/templates/vite.config.js +14 -16
- package/generators/app/templates/vitest.config.ts +14 -0
- package/package.json +9 -10
- package/generators/app/templates/postcss.config.js +0 -6
|
@@ -1,14 +1,19 @@
|
|
|
1
1
|
// This file is auto-generated by @hey-api/openapi-ts
|
|
2
2
|
|
|
3
|
-
import { getAuthToken } from
|
|
4
|
-
import type { QuerySerializerOptions } from
|
|
3
|
+
import { getAuthToken } from "../core/auth.gen";
|
|
4
|
+
import type { QuerySerializerOptions } from "../core/bodySerializer.gen";
|
|
5
5
|
import {
|
|
6
6
|
serializeArrayParam,
|
|
7
7
|
serializeObjectParam,
|
|
8
8
|
serializePrimitiveParam,
|
|
9
|
-
} from
|
|
10
|
-
import { getUrl } from
|
|
11
|
-
import type {
|
|
9
|
+
} from "../core/pathSerializer.gen";
|
|
10
|
+
import { getUrl } from "../core/utils.gen";
|
|
11
|
+
import type {
|
|
12
|
+
Client,
|
|
13
|
+
ClientOptions,
|
|
14
|
+
Config,
|
|
15
|
+
RequestOptions,
|
|
16
|
+
} from "./types.gen";
|
|
12
17
|
|
|
13
18
|
export const createQuerySerializer = <T = unknown>({
|
|
14
19
|
parameters = {},
|
|
@@ -16,7 +21,7 @@ export const createQuerySerializer = <T = unknown>({
|
|
|
16
21
|
}: QuerySerializerOptions = {}) => {
|
|
17
22
|
const querySerializer = (queryParams: T) => {
|
|
18
23
|
const search: string[] = [];
|
|
19
|
-
if (queryParams && typeof queryParams ===
|
|
24
|
+
if (queryParams && typeof queryParams === "object") {
|
|
20
25
|
for (const name in queryParams) {
|
|
21
26
|
const value = queryParams[name];
|
|
22
27
|
|
|
@@ -31,17 +36,17 @@ export const createQuerySerializer = <T = unknown>({
|
|
|
31
36
|
allowReserved: options.allowReserved,
|
|
32
37
|
explode: true,
|
|
33
38
|
name,
|
|
34
|
-
style:
|
|
39
|
+
style: "form",
|
|
35
40
|
value,
|
|
36
41
|
...options.array,
|
|
37
42
|
});
|
|
38
43
|
if (serializedArray) search.push(serializedArray);
|
|
39
|
-
} else if (typeof value ===
|
|
44
|
+
} else if (typeof value === "object") {
|
|
40
45
|
const serializedObject = serializeObjectParam({
|
|
41
46
|
allowReserved: options.allowReserved,
|
|
42
47
|
explode: true,
|
|
43
48
|
name,
|
|
44
|
-
style:
|
|
49
|
+
style: "deepObject",
|
|
45
50
|
value: value as Record<string, unknown>,
|
|
46
51
|
...options.object,
|
|
47
52
|
});
|
|
@@ -56,14 +61,14 @@ export const createQuerySerializer = <T = unknown>({
|
|
|
56
61
|
}
|
|
57
62
|
}
|
|
58
63
|
}
|
|
59
|
-
return search.join(
|
|
64
|
+
return search.join("&");
|
|
60
65
|
};
|
|
61
66
|
return querySerializer;
|
|
62
67
|
};
|
|
63
68
|
|
|
64
69
|
const checkForExistence = (
|
|
65
|
-
options: Pick<RequestOptions,
|
|
66
|
-
headers: Record<
|
|
70
|
+
options: Pick<RequestOptions, "auth" | "query"> & {
|
|
71
|
+
headers: Record<string, unknown>;
|
|
67
72
|
},
|
|
68
73
|
name?: string,
|
|
69
74
|
): boolean => {
|
|
@@ -74,11 +79,11 @@ const checkForExistence = (
|
|
|
74
79
|
return true;
|
|
75
80
|
}
|
|
76
81
|
if (
|
|
77
|
-
|
|
78
|
-
options.headers[
|
|
79
|
-
typeof options.headers[
|
|
82
|
+
"Cookie" in options.headers &&
|
|
83
|
+
options.headers["Cookie"] &&
|
|
84
|
+
typeof options.headers["Cookie"] === "string"
|
|
80
85
|
) {
|
|
81
|
-
return options.headers[
|
|
86
|
+
return options.headers["Cookie"].includes(`${name}=`);
|
|
82
87
|
}
|
|
83
88
|
return false;
|
|
84
89
|
};
|
|
@@ -86,9 +91,9 @@ const checkForExistence = (
|
|
|
86
91
|
export const setAuthParams = async ({
|
|
87
92
|
security,
|
|
88
93
|
...options
|
|
89
|
-
}: Pick<Required<RequestOptions>,
|
|
90
|
-
Pick<RequestOptions,
|
|
91
|
-
headers: Record<
|
|
94
|
+
}: Pick<Required<RequestOptions>, "security"> &
|
|
95
|
+
Pick<RequestOptions, "auth" | "query"> & {
|
|
96
|
+
headers: Record<string, unknown>;
|
|
92
97
|
}) => {
|
|
93
98
|
for (const auth of security) {
|
|
94
99
|
if (checkForExistence(options, auth.name)) {
|
|
@@ -100,25 +105,25 @@ export const setAuthParams = async ({
|
|
|
100
105
|
continue;
|
|
101
106
|
}
|
|
102
107
|
|
|
103
|
-
const name = auth.name ??
|
|
108
|
+
const name = auth.name ?? "Authorization";
|
|
104
109
|
|
|
105
110
|
switch (auth.in) {
|
|
106
|
-
case
|
|
111
|
+
case "query":
|
|
107
112
|
if (!options.query) {
|
|
108
113
|
options.query = {};
|
|
109
114
|
}
|
|
110
115
|
options.query[name] = token;
|
|
111
116
|
break;
|
|
112
|
-
case
|
|
117
|
+
case "cookie": {
|
|
113
118
|
const value = `${name}=${token}`;
|
|
114
|
-
if (
|
|
115
|
-
options.headers[
|
|
119
|
+
if ("Cookie" in options.headers && options.headers["Cookie"]) {
|
|
120
|
+
options.headers["Cookie"] = `${options.headers["Cookie"]}; ${value}`;
|
|
116
121
|
} else {
|
|
117
|
-
options.headers[
|
|
122
|
+
options.headers["Cookie"] = value;
|
|
118
123
|
}
|
|
119
124
|
break;
|
|
120
125
|
}
|
|
121
|
-
case
|
|
126
|
+
case "header":
|
|
122
127
|
default:
|
|
123
128
|
options.headers[name] = token;
|
|
124
129
|
break;
|
|
@@ -126,11 +131,11 @@ export const setAuthParams = async ({
|
|
|
126
131
|
}
|
|
127
132
|
};
|
|
128
133
|
|
|
129
|
-
export const buildUrl: Client[
|
|
134
|
+
export const buildUrl: Client["buildUrl"] = (options) => {
|
|
130
135
|
const instanceBaseUrl = options.axios?.defaults?.baseURL;
|
|
131
136
|
|
|
132
137
|
const baseUrl =
|
|
133
|
-
!!options.baseURL && typeof options.baseURL ===
|
|
138
|
+
!!options.baseURL && typeof options.baseURL === "string"
|
|
134
139
|
? options.baseURL
|
|
135
140
|
: instanceBaseUrl;
|
|
136
141
|
|
|
@@ -140,7 +145,7 @@ export const buildUrl: Client['buildUrl'] = (options) => {
|
|
|
140
145
|
// let `paramsSerializer()` handle query params if it exists
|
|
141
146
|
query: !options.paramsSerializer ? options.query : undefined,
|
|
142
147
|
querySerializer:
|
|
143
|
-
typeof options.querySerializer ===
|
|
148
|
+
typeof options.querySerializer === "function"
|
|
144
149
|
? options.querySerializer
|
|
145
150
|
: createQuerySerializer(options.querySerializer),
|
|
146
151
|
url: options.url,
|
|
@@ -157,21 +162,21 @@ export const mergeConfigs = (a: Config, b: Config): Config => {
|
|
|
157
162
|
* Special Axios headers keywords allowing to set headers by request method.
|
|
158
163
|
*/
|
|
159
164
|
export const axiosHeadersKeywords = [
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
165
|
+
"common",
|
|
166
|
+
"delete",
|
|
167
|
+
"get",
|
|
168
|
+
"head",
|
|
169
|
+
"patch",
|
|
170
|
+
"post",
|
|
171
|
+
"put",
|
|
167
172
|
] as const;
|
|
168
173
|
|
|
169
174
|
export const mergeHeaders = (
|
|
170
|
-
...headers: Array<Required<Config>[
|
|
171
|
-
): Record<
|
|
172
|
-
const mergedHeaders: Record<
|
|
175
|
+
...headers: Array<Required<Config>["headers"] | undefined>
|
|
176
|
+
): Record<string, unknown> => {
|
|
177
|
+
const mergedHeaders: Record<string, unknown> = {};
|
|
173
178
|
for (const header of headers) {
|
|
174
|
-
if (!header || typeof header !==
|
|
179
|
+
if (!header || typeof header !== "object") {
|
|
175
180
|
continue;
|
|
176
181
|
}
|
|
177
182
|
|
|
@@ -182,24 +187,27 @@ export const mergeHeaders = (
|
|
|
182
187
|
axiosHeadersKeywords.includes(
|
|
183
188
|
key as (typeof axiosHeadersKeywords)[number],
|
|
184
189
|
) &&
|
|
185
|
-
typeof value ===
|
|
190
|
+
typeof value === "object"
|
|
186
191
|
) {
|
|
187
192
|
mergedHeaders[key] = {
|
|
188
|
-
...(mergedHeaders[key] as Record<
|
|
193
|
+
...(mergedHeaders[key] as Record<string, unknown>),
|
|
189
194
|
...value,
|
|
190
195
|
};
|
|
191
196
|
} else if (value === null) {
|
|
192
197
|
delete mergedHeaders[key];
|
|
193
198
|
} else if (Array.isArray(value)) {
|
|
194
199
|
for (const v of value) {
|
|
195
|
-
|
|
196
|
-
mergedHeaders[key] = [
|
|
200
|
+
const previous = mergedHeaders[key];
|
|
201
|
+
mergedHeaders[key] = [
|
|
202
|
+
...(Array.isArray(previous) ? previous : []),
|
|
203
|
+
v as string,
|
|
204
|
+
];
|
|
197
205
|
}
|
|
198
206
|
} else if (value !== undefined) {
|
|
199
207
|
// assume object headers are meant to be JSON stringified, i.e. their
|
|
200
208
|
// content value in OpenAPI specification is 'application/json'
|
|
201
209
|
mergedHeaders[key] =
|
|
202
|
-
typeof value ===
|
|
210
|
+
typeof value === "object" ? JSON.stringify(value) : (value as string);
|
|
203
211
|
}
|
|
204
212
|
}
|
|
205
213
|
}
|
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
// This file is auto-generated by @hey-api/openapi-ts
|
|
2
2
|
|
|
3
|
-
import { createClientConfig } from
|
|
3
|
+
import { createClientConfig } from "@/openapi-client-config.ts";
|
|
4
4
|
|
|
5
|
-
import {
|
|
6
|
-
|
|
5
|
+
import {
|
|
6
|
+
type ClientOptions,
|
|
7
|
+
type Config,
|
|
8
|
+
createClient,
|
|
9
|
+
createConfig,
|
|
10
|
+
} from "./client";
|
|
11
|
+
import type { ClientOptions as ClientOptions2 } from "./types.gen";
|
|
7
12
|
|
|
8
13
|
/**
|
|
9
14
|
* The `createClientConfig()` function will be called on client initialization
|
|
@@ -13,6 +18,10 @@ import type { ClientOptions as ClientOptions2 } from './types.gen';
|
|
|
13
18
|
* `setConfig()`. This is useful for example if you're using Next.js
|
|
14
19
|
* to ensure your client always has the correct values.
|
|
15
20
|
*/
|
|
16
|
-
export type CreateClientConfig<T extends ClientOptions = ClientOptions2> = (
|
|
21
|
+
export type CreateClientConfig<T extends ClientOptions = ClientOptions2> = (
|
|
22
|
+
override?: Config<ClientOptions & T>,
|
|
23
|
+
) => Config<Required<ClientOptions> & T>;
|
|
17
24
|
|
|
18
|
-
export const client = createClient(
|
|
25
|
+
export const client = createClient(
|
|
26
|
+
createClientConfig(createConfig<ClientOptions2>()),
|
|
27
|
+
);
|
|
@@ -8,15 +8,15 @@ export interface Auth {
|
|
|
8
8
|
*
|
|
9
9
|
* @default 'header'
|
|
10
10
|
*/
|
|
11
|
-
in?:
|
|
11
|
+
in?: "header" | "query" | "cookie";
|
|
12
12
|
/**
|
|
13
13
|
* Header or query parameter name.
|
|
14
14
|
*
|
|
15
15
|
* @default 'Authorization'
|
|
16
16
|
*/
|
|
17
17
|
name?: string;
|
|
18
|
-
scheme?:
|
|
19
|
-
type:
|
|
18
|
+
scheme?: "basic" | "bearer";
|
|
19
|
+
type: "apiKey" | "http";
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
export const getAuthToken = async (
|
|
@@ -24,17 +24,17 @@ export const getAuthToken = async (
|
|
|
24
24
|
callback: ((auth: Auth) => Promise<AuthToken> | AuthToken) | AuthToken,
|
|
25
25
|
): Promise<string | undefined> => {
|
|
26
26
|
const token =
|
|
27
|
-
typeof callback ===
|
|
27
|
+
typeof callback === "function" ? await callback(auth) : callback;
|
|
28
28
|
|
|
29
29
|
if (!token) {
|
|
30
30
|
return;
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
if (auth.scheme ===
|
|
33
|
+
if (auth.scheme === "bearer") {
|
|
34
34
|
return `Bearer ${token}`;
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
if (auth.scheme ===
|
|
37
|
+
if (auth.scheme === "basic") {
|
|
38
38
|
return `Basic ${btoa(token)}`;
|
|
39
39
|
}
|
|
40
40
|
|
|
@@ -4,11 +4,11 @@ import type {
|
|
|
4
4
|
ArrayStyle,
|
|
5
5
|
ObjectStyle,
|
|
6
6
|
SerializerOptions,
|
|
7
|
-
} from
|
|
7
|
+
} from "./pathSerializer.gen";
|
|
8
8
|
|
|
9
9
|
export type QuerySerializer = (query: Record<string, unknown>) => string;
|
|
10
10
|
|
|
11
|
-
export type BodySerializer = (body:
|
|
11
|
+
export type BodySerializer = (body: unknown) => unknown;
|
|
12
12
|
|
|
13
13
|
type QuerySerializerOptionsObject = {
|
|
14
14
|
allowReserved?: boolean;
|
|
@@ -29,7 +29,7 @@ const serializeFormDataPair = (
|
|
|
29
29
|
key: string,
|
|
30
30
|
value: unknown,
|
|
31
31
|
): void => {
|
|
32
|
-
if (typeof value ===
|
|
32
|
+
if (typeof value === "string" || value instanceof Blob) {
|
|
33
33
|
data.append(key, value);
|
|
34
34
|
} else if (value instanceof Date) {
|
|
35
35
|
data.append(key, value.toISOString());
|
|
@@ -43,29 +43,34 @@ const serializeUrlSearchParamsPair = (
|
|
|
43
43
|
key: string,
|
|
44
44
|
value: unknown,
|
|
45
45
|
): void => {
|
|
46
|
-
if (typeof value ===
|
|
46
|
+
if (typeof value === "string") {
|
|
47
47
|
data.append(key, value);
|
|
48
48
|
} else {
|
|
49
49
|
data.append(key, JSON.stringify(value));
|
|
50
50
|
}
|
|
51
51
|
};
|
|
52
52
|
|
|
53
|
+
function appendBodyValues<T extends FormData | URLSearchParams>(
|
|
54
|
+
body: Record<string, unknown> | Array<Record<string, unknown>>,
|
|
55
|
+
data: T,
|
|
56
|
+
append: (data: T, key: string, value: unknown) => void,
|
|
57
|
+
) {
|
|
58
|
+
for (const [key, value] of Object.entries(body)) {
|
|
59
|
+
if (value === undefined || value === null) continue;
|
|
60
|
+
for (const item of Array.isArray(value) ? value : [value])
|
|
61
|
+
append(data, key, item);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
53
65
|
export const formDataBodySerializer = {
|
|
54
|
-
bodySerializer: <
|
|
66
|
+
bodySerializer: <
|
|
67
|
+
T extends Record<string, unknown> | Array<Record<string, unknown>>,
|
|
68
|
+
>(
|
|
55
69
|
body: T,
|
|
56
70
|
): FormData => {
|
|
57
71
|
const data = new FormData();
|
|
58
72
|
|
|
59
|
-
|
|
60
|
-
if (value === undefined || value === null) {
|
|
61
|
-
return;
|
|
62
|
-
}
|
|
63
|
-
if (Array.isArray(value)) {
|
|
64
|
-
value.forEach((v) => serializeFormDataPair(data, key, v));
|
|
65
|
-
} else {
|
|
66
|
-
serializeFormDataPair(data, key, value);
|
|
67
|
-
}
|
|
68
|
-
});
|
|
73
|
+
appendBodyValues(body, data, serializeFormDataPair);
|
|
69
74
|
|
|
70
75
|
return data;
|
|
71
76
|
},
|
|
@@ -74,26 +79,19 @@ export const formDataBodySerializer = {
|
|
|
74
79
|
export const jsonBodySerializer = {
|
|
75
80
|
bodySerializer: <T>(body: T): string =>
|
|
76
81
|
JSON.stringify(body, (_key, value) =>
|
|
77
|
-
typeof value ===
|
|
82
|
+
typeof value === "bigint" ? value.toString() : value,
|
|
78
83
|
),
|
|
79
84
|
};
|
|
80
85
|
|
|
81
86
|
export const urlSearchParamsBodySerializer = {
|
|
82
|
-
bodySerializer: <
|
|
87
|
+
bodySerializer: <
|
|
88
|
+
T extends Record<string, unknown> | Array<Record<string, unknown>>,
|
|
89
|
+
>(
|
|
83
90
|
body: T,
|
|
84
91
|
): string => {
|
|
85
92
|
const data = new URLSearchParams();
|
|
86
93
|
|
|
87
|
-
|
|
88
|
-
if (value === undefined || value === null) {
|
|
89
|
-
return;
|
|
90
|
-
}
|
|
91
|
-
if (Array.isArray(value)) {
|
|
92
|
-
value.forEach((v) => serializeUrlSearchParamsPair(data, key, v));
|
|
93
|
-
} else {
|
|
94
|
-
serializeUrlSearchParamsPair(data, key, value);
|
|
95
|
-
}
|
|
96
|
-
});
|
|
94
|
+
appendBodyValues(body, data, serializeUrlSearchParamsPair);
|
|
97
95
|
|
|
98
96
|
return data.toString();
|
|
99
97
|
},
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
// This file is auto-generated by @hey-api/openapi-ts
|
|
2
2
|
|
|
3
|
-
type Slot =
|
|
3
|
+
type Slot = "body" | "headers" | "path" | "query";
|
|
4
4
|
|
|
5
5
|
export type Field =
|
|
6
6
|
| {
|
|
7
|
-
in: Exclude<Slot,
|
|
7
|
+
in: Exclude<Slot, "body">;
|
|
8
8
|
/**
|
|
9
9
|
* Field name. This is the name we want the user to see and use.
|
|
10
10
|
*/
|
|
@@ -16,7 +16,7 @@ export type Field =
|
|
|
16
16
|
map?: string;
|
|
17
17
|
}
|
|
18
18
|
| {
|
|
19
|
-
in: Extract<Slot,
|
|
19
|
+
in: Extract<Slot, "body">;
|
|
20
20
|
/**
|
|
21
21
|
* Key isn't required for bodies.
|
|
22
22
|
*/
|
|
@@ -43,10 +43,10 @@ export interface Fields {
|
|
|
43
43
|
export type FieldsConfig = ReadonlyArray<Field | Fields>;
|
|
44
44
|
|
|
45
45
|
const extraPrefixesMap: Record<string, Slot> = {
|
|
46
|
-
$body_:
|
|
47
|
-
$headers_:
|
|
48
|
-
$path_:
|
|
49
|
-
$query_:
|
|
46
|
+
$body_: "body",
|
|
47
|
+
$headers_: "headers",
|
|
48
|
+
$path_: "path",
|
|
49
|
+
$query_: "query",
|
|
50
50
|
};
|
|
51
51
|
const extraPrefixes = Object.entries(extraPrefixesMap);
|
|
52
52
|
|
|
@@ -68,14 +68,14 @@ const buildKeyMap = (fields: FieldsConfig, map?: KeyMap): KeyMap => {
|
|
|
68
68
|
}
|
|
69
69
|
|
|
70
70
|
for (const config of fields) {
|
|
71
|
-
if (
|
|
71
|
+
if ("in" in config) {
|
|
72
72
|
if (config.key) {
|
|
73
73
|
map.set(config.key, {
|
|
74
74
|
in: config.in,
|
|
75
75
|
map: config.map,
|
|
76
76
|
});
|
|
77
77
|
}
|
|
78
|
-
} else if (
|
|
78
|
+
} else if ("key" in config) {
|
|
79
79
|
map.set(config.key, {
|
|
80
80
|
map: config.map,
|
|
81
81
|
});
|
|
@@ -96,7 +96,7 @@ interface Params {
|
|
|
96
96
|
|
|
97
97
|
const stripEmptySlots = (params: Params) => {
|
|
98
98
|
for (const [slot, value] of Object.entries(params)) {
|
|
99
|
-
if (value && typeof value ===
|
|
99
|
+
if (value && typeof value === "object" && !Object.keys(value).length) {
|
|
100
100
|
delete params[slot as Slot];
|
|
101
101
|
}
|
|
102
102
|
}
|
|
@@ -126,7 +126,7 @@ export const buildClientParams = (
|
|
|
126
126
|
continue;
|
|
127
127
|
}
|
|
128
128
|
|
|
129
|
-
if (
|
|
129
|
+
if ("in" in config) {
|
|
130
130
|
if (config.key) {
|
|
131
131
|
const field = map.get(config.key)!;
|
|
132
132
|
const name = field.map || config.key;
|
|
@@ -157,7 +157,7 @@ export const buildClientParams = (
|
|
|
157
157
|
(params[slot] as Record<string, unknown>)[
|
|
158
158
|
key.slice(prefix.length)
|
|
159
159
|
] = value;
|
|
160
|
-
} else if (
|
|
160
|
+
} else if ("allowExtra" in config && config.allowExtra) {
|
|
161
161
|
for (const [slot, allowed] of Object.entries(config.allowExtra)) {
|
|
162
162
|
if (allowed) {
|
|
163
163
|
(params[slot as Slot] as Record<string, unknown>)[key] = value;
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
// This file is auto-generated by @hey-api/openapi-ts
|
|
2
2
|
|
|
3
3
|
interface SerializeOptions<T>
|
|
4
|
-
extends SerializePrimitiveOptions,
|
|
5
|
-
SerializerOptions<T> {}
|
|
4
|
+
extends SerializePrimitiveOptions, SerializerOptions<T> {}
|
|
6
5
|
|
|
7
6
|
interface SerializePrimitiveOptions {
|
|
8
7
|
allowReserved?: boolean;
|
|
@@ -17,10 +16,10 @@ export interface SerializerOptions<T> {
|
|
|
17
16
|
style: T;
|
|
18
17
|
}
|
|
19
18
|
|
|
20
|
-
export type ArrayStyle =
|
|
19
|
+
export type ArrayStyle = "form" | "spaceDelimited" | "pipeDelimited";
|
|
21
20
|
export type ArraySeparatorStyle = ArrayStyle | MatrixStyle;
|
|
22
|
-
type MatrixStyle =
|
|
23
|
-
export type ObjectStyle =
|
|
21
|
+
type MatrixStyle = "label" | "matrix" | "simple";
|
|
22
|
+
export type ObjectStyle = "form" | "deepObject";
|
|
24
23
|
type ObjectSeparatorStyle = ObjectStyle | MatrixStyle;
|
|
25
24
|
|
|
26
25
|
interface SerializePrimitiveParam extends SerializePrimitiveOptions {
|
|
@@ -29,40 +28,40 @@ interface SerializePrimitiveParam extends SerializePrimitiveOptions {
|
|
|
29
28
|
|
|
30
29
|
export const separatorArrayExplode = (style: ArraySeparatorStyle) => {
|
|
31
30
|
switch (style) {
|
|
32
|
-
case
|
|
33
|
-
return
|
|
34
|
-
case
|
|
35
|
-
return
|
|
36
|
-
case
|
|
37
|
-
return
|
|
31
|
+
case "label":
|
|
32
|
+
return ".";
|
|
33
|
+
case "matrix":
|
|
34
|
+
return ";";
|
|
35
|
+
case "simple":
|
|
36
|
+
return ",";
|
|
38
37
|
default:
|
|
39
|
-
return
|
|
38
|
+
return "&";
|
|
40
39
|
}
|
|
41
40
|
};
|
|
42
41
|
|
|
43
42
|
export const separatorArrayNoExplode = (style: ArraySeparatorStyle) => {
|
|
44
43
|
switch (style) {
|
|
45
|
-
case
|
|
46
|
-
return
|
|
47
|
-
case
|
|
48
|
-
return
|
|
49
|
-
case
|
|
50
|
-
return
|
|
44
|
+
case "form":
|
|
45
|
+
return ",";
|
|
46
|
+
case "pipeDelimited":
|
|
47
|
+
return "|";
|
|
48
|
+
case "spaceDelimited":
|
|
49
|
+
return "%20";
|
|
51
50
|
default:
|
|
52
|
-
return
|
|
51
|
+
return ",";
|
|
53
52
|
}
|
|
54
53
|
};
|
|
55
54
|
|
|
56
55
|
export const separatorObjectExplode = (style: ObjectSeparatorStyle) => {
|
|
57
56
|
switch (style) {
|
|
58
|
-
case
|
|
59
|
-
return
|
|
60
|
-
case
|
|
61
|
-
return
|
|
62
|
-
case
|
|
63
|
-
return
|
|
57
|
+
case "label":
|
|
58
|
+
return ".";
|
|
59
|
+
case "matrix":
|
|
60
|
+
return ";";
|
|
61
|
+
case "simple":
|
|
62
|
+
return ",";
|
|
64
63
|
default:
|
|
65
|
-
return
|
|
64
|
+
return "&";
|
|
66
65
|
}
|
|
67
66
|
};
|
|
68
67
|
|
|
@@ -80,11 +79,11 @@ export const serializeArrayParam = ({
|
|
|
80
79
|
allowReserved ? value : value.map((v) => encodeURIComponent(v as string))
|
|
81
80
|
).join(separatorArrayNoExplode(style));
|
|
82
81
|
switch (style) {
|
|
83
|
-
case
|
|
82
|
+
case "label":
|
|
84
83
|
return `.${joinedValues}`;
|
|
85
|
-
case
|
|
84
|
+
case "matrix":
|
|
86
85
|
return `;${name}=${joinedValues}`;
|
|
87
|
-
case
|
|
86
|
+
case "simple":
|
|
88
87
|
return joinedValues;
|
|
89
88
|
default:
|
|
90
89
|
return `${name}=${joinedValues}`;
|
|
@@ -94,7 +93,7 @@ export const serializeArrayParam = ({
|
|
|
94
93
|
const separator = separatorArrayExplode(style);
|
|
95
94
|
const joinedValues = value
|
|
96
95
|
.map((v) => {
|
|
97
|
-
if (style ===
|
|
96
|
+
if (style === "label" || style === "simple") {
|
|
98
97
|
return allowReserved ? v : encodeURIComponent(v as string);
|
|
99
98
|
}
|
|
100
99
|
|
|
@@ -105,7 +104,7 @@ export const serializeArrayParam = ({
|
|
|
105
104
|
});
|
|
106
105
|
})
|
|
107
106
|
.join(separator);
|
|
108
|
-
return style ===
|
|
107
|
+
return style === "label" || style === "matrix"
|
|
109
108
|
? separator + joinedValues
|
|
110
109
|
: joinedValues;
|
|
111
110
|
};
|
|
@@ -116,12 +115,12 @@ export const serializePrimitiveParam = ({
|
|
|
116
115
|
value,
|
|
117
116
|
}: SerializePrimitiveParam) => {
|
|
118
117
|
if (value === undefined || value === null) {
|
|
119
|
-
return
|
|
118
|
+
return "";
|
|
120
119
|
}
|
|
121
120
|
|
|
122
|
-
if (typeof value ===
|
|
121
|
+
if (typeof value === "object") {
|
|
123
122
|
throw new Error(
|
|
124
|
-
|
|
123
|
+
"Deeply-nested arrays/objects aren’t supported. Provide your own `querySerializer()` to handle these.",
|
|
125
124
|
);
|
|
126
125
|
}
|
|
127
126
|
|
|
@@ -143,7 +142,7 @@ export const serializeObjectParam = ({
|
|
|
143
142
|
return valueOnly ? value.toISOString() : `${name}=${value.toISOString()}`;
|
|
144
143
|
}
|
|
145
144
|
|
|
146
|
-
if (style !==
|
|
145
|
+
if (style !== "deepObject" && !explode) {
|
|
147
146
|
let values: string[] = [];
|
|
148
147
|
Object.entries(value).forEach(([key, v]) => {
|
|
149
148
|
values = [
|
|
@@ -152,13 +151,13 @@ export const serializeObjectParam = ({
|
|
|
152
151
|
allowReserved ? (v as string) : encodeURIComponent(v as string),
|
|
153
152
|
];
|
|
154
153
|
});
|
|
155
|
-
const joinedValues = values.join(
|
|
154
|
+
const joinedValues = values.join(",");
|
|
156
155
|
switch (style) {
|
|
157
|
-
case
|
|
156
|
+
case "form":
|
|
158
157
|
return `${name}=${joinedValues}`;
|
|
159
|
-
case
|
|
158
|
+
case "label":
|
|
160
159
|
return `.${joinedValues}`;
|
|
161
|
-
case
|
|
160
|
+
case "matrix":
|
|
162
161
|
return `;${name}=${joinedValues}`;
|
|
163
162
|
default:
|
|
164
163
|
return joinedValues;
|
|
@@ -170,12 +169,12 @@ export const serializeObjectParam = ({
|
|
|
170
169
|
.map(([key, v]) =>
|
|
171
170
|
serializePrimitiveParam({
|
|
172
171
|
allowReserved,
|
|
173
|
-
name: style ===
|
|
172
|
+
name: style === "deepObject" ? `${name}[${key}]` : key,
|
|
174
173
|
value: v as string,
|
|
175
174
|
}),
|
|
176
175
|
)
|
|
177
176
|
.join(separator);
|
|
178
|
-
return style ===
|
|
177
|
+
return style === "label" || style === "matrix"
|
|
179
178
|
? separator + joinedValues
|
|
180
179
|
: joinedValues;
|
|
181
180
|
};
|