@robosystems/client 0.2.25 → 0.2.26

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 (93) hide show
  1. package/README.md +7 -6
  2. package/bin/{create-feature → create-feature.sh} +11 -1
  3. package/client/client.gen.js +118 -34
  4. package/client/client.gen.ts +125 -38
  5. package/client/index.d.ts +2 -1
  6. package/client/index.js +3 -1
  7. package/client/index.ts +1 -1
  8. package/client/types.gen.d.ts +11 -16
  9. package/client/types.gen.js +0 -1
  10. package/client/types.gen.ts +44 -64
  11. package/client/utils.gen.d.ts +8 -20
  12. package/client/utils.gen.js +44 -112
  13. package/client/utils.gen.ts +57 -181
  14. package/client.gen.d.ts +3 -3
  15. package/client.gen.js +1 -3
  16. package/client.gen.ts +4 -6
  17. package/core/auth.gen.ts +1 -2
  18. package/core/bodySerializer.gen.d.ts +12 -4
  19. package/core/bodySerializer.gen.js +1 -1
  20. package/core/bodySerializer.gen.ts +17 -25
  21. package/core/params.gen.d.ts +10 -0
  22. package/core/params.gen.js +17 -5
  23. package/core/params.gen.ts +37 -21
  24. package/core/pathSerializer.gen.js +3 -11
  25. package/core/pathSerializer.gen.ts +4 -14
  26. package/core/queryKeySerializer.gen.d.ts +18 -0
  27. package/core/queryKeySerializer.gen.js +98 -0
  28. package/core/queryKeySerializer.gen.ts +117 -0
  29. package/core/serverSentEvents.gen.d.ts +71 -0
  30. package/core/serverSentEvents.gen.js +137 -0
  31. package/core/serverSentEvents.gen.ts +243 -0
  32. package/core/types.gen.d.ts +12 -12
  33. package/core/types.gen.js +0 -1
  34. package/core/types.gen.ts +21 -38
  35. package/core/utils.gen.d.ts +19 -0
  36. package/core/utils.gen.js +93 -0
  37. package/core/utils.gen.ts +140 -0
  38. package/extensions/QueryClient.js +23 -2
  39. package/extensions/QueryClient.test.ts +2 -1
  40. package/extensions/QueryClient.ts +27 -2
  41. package/index.ts +3 -2
  42. package/package.json +9 -7
  43. package/sdk/client/client.gen.js +118 -34
  44. package/sdk/client/client.gen.ts +125 -38
  45. package/sdk/client/index.d.ts +2 -1
  46. package/sdk/client/index.js +3 -1
  47. package/sdk/client/index.ts +1 -1
  48. package/sdk/client/types.gen.d.ts +11 -16
  49. package/sdk/client/types.gen.js +0 -1
  50. package/sdk/client/types.gen.ts +44 -64
  51. package/sdk/client/utils.gen.d.ts +8 -20
  52. package/sdk/client/utils.gen.js +44 -112
  53. package/sdk/client/utils.gen.ts +57 -181
  54. package/sdk/client.gen.d.ts +3 -3
  55. package/sdk/client.gen.js +1 -3
  56. package/sdk/client.gen.ts +4 -6
  57. package/sdk/core/auth.gen.ts +1 -2
  58. package/sdk/core/bodySerializer.gen.d.ts +12 -4
  59. package/sdk/core/bodySerializer.gen.js +1 -1
  60. package/sdk/core/bodySerializer.gen.ts +17 -25
  61. package/sdk/core/params.gen.d.ts +10 -0
  62. package/sdk/core/params.gen.js +17 -5
  63. package/sdk/core/params.gen.ts +37 -21
  64. package/sdk/core/pathSerializer.gen.js +3 -11
  65. package/sdk/core/pathSerializer.gen.ts +4 -14
  66. package/sdk/core/queryKeySerializer.gen.d.ts +18 -0
  67. package/sdk/core/queryKeySerializer.gen.js +98 -0
  68. package/sdk/core/queryKeySerializer.gen.ts +117 -0
  69. package/sdk/core/serverSentEvents.gen.d.ts +71 -0
  70. package/sdk/core/serverSentEvents.gen.js +137 -0
  71. package/sdk/core/serverSentEvents.gen.ts +243 -0
  72. package/sdk/core/types.gen.d.ts +12 -12
  73. package/sdk/core/types.gen.js +0 -1
  74. package/sdk/core/types.gen.ts +21 -38
  75. package/sdk/core/utils.gen.d.ts +19 -0
  76. package/sdk/core/utils.gen.js +93 -0
  77. package/sdk/core/utils.gen.ts +140 -0
  78. package/sdk/index.d.ts +2 -2
  79. package/sdk/index.js +114 -17
  80. package/sdk/index.ts +3 -2
  81. package/sdk/sdk.gen.d.ts +112 -3
  82. package/sdk/sdk.gen.js +778 -1736
  83. package/sdk/sdk.gen.ts +782 -1740
  84. package/sdk/types.gen.d.ts +851 -5
  85. package/sdk/types.gen.ts +852 -6
  86. package/sdk-extensions/QueryClient.js +23 -2
  87. package/sdk-extensions/QueryClient.test.ts +2 -1
  88. package/sdk-extensions/QueryClient.ts +27 -2
  89. package/sdk.gen.d.ts +112 -3
  90. package/sdk.gen.js +778 -1736
  91. package/sdk.gen.ts +782 -1740
  92. package/types.gen.d.ts +851 -5
  93. package/types.gen.ts +852 -6
@@ -1,103 +1,19 @@
1
1
  // This file is auto-generated by @hey-api/openapi-ts
2
2
 
3
3
  import { getAuthToken } from '../core/auth.gen';
4
- import type {
5
- QuerySerializer,
6
- QuerySerializerOptions,
7
- } from '../core/bodySerializer.gen';
4
+ import type { QuerySerializerOptions } from '../core/bodySerializer.gen';
8
5
  import { jsonBodySerializer } from '../core/bodySerializer.gen';
9
6
  import {
10
7
  serializeArrayParam,
11
8
  serializeObjectParam,
12
9
  serializePrimitiveParam,
13
10
  } from '../core/pathSerializer.gen';
11
+ import { getUrl } from '../core/utils.gen';
14
12
  import type { Client, ClientOptions, Config, RequestOptions } from './types.gen';
15
13
 
16
- interface PathSerializer {
17
- path: Record<string, unknown>;
18
- url: string;
19
- }
20
-
21
- const PATH_PARAM_RE = /\{[^{}]+\}/g;
22
-
23
- type ArrayStyle = 'form' | 'spaceDelimited' | 'pipeDelimited';
24
- type MatrixStyle = 'label' | 'matrix' | 'simple';
25
- type ArraySeparatorStyle = ArrayStyle | MatrixStyle;
26
-
27
- const defaultPathSerializer = ({ path, url: _url }: PathSerializer) => {
28
- let url = _url;
29
- const matches = _url.match(PATH_PARAM_RE);
30
- if (matches) {
31
- for (const match of matches) {
32
- let explode = false;
33
- let name = match.substring(1, match.length - 1);
34
- let style: ArraySeparatorStyle = 'simple';
35
-
36
- if (name.endsWith('*')) {
37
- explode = true;
38
- name = name.substring(0, name.length - 1);
39
- }
40
-
41
- if (name.startsWith('.')) {
42
- name = name.substring(1);
43
- style = 'label';
44
- } else if (name.startsWith(';')) {
45
- name = name.substring(1);
46
- style = 'matrix';
47
- }
48
-
49
- const value = path[name];
50
-
51
- if (value === undefined || value === null) {
52
- continue;
53
- }
54
-
55
- if (Array.isArray(value)) {
56
- url = url.replace(
57
- match,
58
- serializeArrayParam({ explode, name, style, value }),
59
- );
60
- continue;
61
- }
62
-
63
- if (typeof value === 'object') {
64
- url = url.replace(
65
- match,
66
- serializeObjectParam({
67
- explode,
68
- name,
69
- style,
70
- value: value as Record<string, unknown>,
71
- valueOnly: true,
72
- }),
73
- );
74
- continue;
75
- }
76
-
77
- if (style === 'matrix') {
78
- url = url.replace(
79
- match,
80
- `;${serializePrimitiveParam({
81
- name,
82
- value: value as string,
83
- })}`,
84
- );
85
- continue;
86
- }
87
-
88
- const replaceValue = encodeURIComponent(
89
- style === 'label' ? `.${value as string}` : (value as string),
90
- );
91
- url = url.replace(match, replaceValue);
92
- }
93
- }
94
- return url;
95
- };
96
-
97
14
  export const createQuerySerializer = <T = unknown>({
98
- allowReserved,
99
- array,
100
- object,
15
+ parameters = {},
16
+ ...args
101
17
  }: QuerySerializerOptions = {}) => {
102
18
  const querySerializer = (queryParams: T) => {
103
19
  const search: string[] = [];
@@ -109,29 +25,31 @@ export const createQuerySerializer = <T = unknown>({
109
25
  continue;
110
26
  }
111
27
 
28
+ const options = parameters[name] || args;
29
+
112
30
  if (Array.isArray(value)) {
113
31
  const serializedArray = serializeArrayParam({
114
- allowReserved,
32
+ allowReserved: options.allowReserved,
115
33
  explode: true,
116
34
  name,
117
35
  style: 'form',
118
36
  value,
119
- ...array,
37
+ ...options.array,
120
38
  });
121
39
  if (serializedArray) search.push(serializedArray);
122
40
  } else if (typeof value === 'object') {
123
41
  const serializedObject = serializeObjectParam({
124
- allowReserved,
42
+ allowReserved: options.allowReserved,
125
43
  explode: true,
126
44
  name,
127
45
  style: 'deepObject',
128
46
  value: value as Record<string, unknown>,
129
- ...object,
47
+ ...options.object,
130
48
  });
131
49
  if (serializedObject) search.push(serializedObject);
132
50
  } else {
133
51
  const serializedPrimitive = serializePrimitiveParam({
134
- allowReserved,
52
+ allowReserved: options.allowReserved,
135
53
  name,
136
54
  value: value as string,
137
55
  });
@@ -147,9 +65,7 @@ export const createQuerySerializer = <T = unknown>({
147
65
  /**
148
66
  * Infers parseAs value from provided Content-Type header.
149
67
  */
150
- export const getParseAs = (
151
- contentType: string | null,
152
- ): Exclude<Config['parseAs'], 'auto'> => {
68
+ export const getParseAs = (contentType: string | null): Exclude<Config['parseAs'], 'auto'> => {
153
69
  if (!contentType) {
154
70
  // If no Content-Type header is provided, the best we can do is return the raw response body,
155
71
  // which is effectively the same as the 'stream' option.
@@ -162,10 +78,7 @@ export const getParseAs = (
162
78
  return;
163
79
  }
164
80
 
165
- if (
166
- cleanContent.startsWith('application/json') ||
167
- cleanContent.endsWith('+json')
168
- ) {
81
+ if (cleanContent.startsWith('application/json') || cleanContent.endsWith('+json')) {
169
82
  return 'json';
170
83
  }
171
84
 
@@ -174,9 +87,7 @@ export const getParseAs = (
174
87
  }
175
88
 
176
89
  if (
177
- ['application/', 'audio/', 'image/', 'video/'].some((type) =>
178
- cleanContent.startsWith(type),
179
- )
90
+ ['application/', 'audio/', 'image/', 'video/'].some((type) => cleanContent.startsWith(type))
180
91
  ) {
181
92
  return 'blob';
182
93
  }
@@ -245,8 +156,8 @@ export const setAuthParams = async ({
245
156
  }
246
157
  };
247
158
 
248
- export const buildUrl: Client['buildUrl'] = (options) => {
249
- const url = getUrl({
159
+ export const buildUrl: Client['buildUrl'] = (options) =>
160
+ getUrl({
250
161
  baseUrl: options.baseUrl as string,
251
162
  path: options.path,
252
163
  query: options.query,
@@ -256,36 +167,6 @@ export const buildUrl: Client['buildUrl'] = (options) => {
256
167
  : createQuerySerializer(options.querySerializer),
257
168
  url: options.url,
258
169
  });
259
- return url;
260
- };
261
-
262
- export const getUrl = ({
263
- baseUrl,
264
- path,
265
- query,
266
- querySerializer,
267
- url: _url,
268
- }: {
269
- baseUrl?: string;
270
- path?: Record<string, unknown>;
271
- query?: Record<string, unknown>;
272
- querySerializer: QuerySerializer;
273
- url: string;
274
- }) => {
275
- const pathUrl = _url.startsWith('/') ? _url : `/${_url}`;
276
- let url = (baseUrl ?? '') + pathUrl;
277
- if (path) {
278
- url = defaultPathSerializer({ path, url });
279
- }
280
- let search = query ? querySerializer(query) : '';
281
- if (search.startsWith('?')) {
282
- search = search.substring(1);
283
- }
284
- if (search) {
285
- url += `?${search}`;
286
- }
287
- return url;
288
- };
289
170
 
290
171
  export const mergeConfigs = (a: Config, b: Config): Config => {
291
172
  const config = { ...a, ...b };
@@ -296,17 +177,24 @@ export const mergeConfigs = (a: Config, b: Config): Config => {
296
177
  return config;
297
178
  };
298
179
 
180
+ const headersEntries = (headers: Headers): Array<[string, string]> => {
181
+ const entries: Array<[string, string]> = [];
182
+ headers.forEach((value, key) => {
183
+ entries.push([key, value]);
184
+ });
185
+ return entries;
186
+ };
187
+
299
188
  export const mergeHeaders = (
300
189
  ...headers: Array<Required<Config>['headers'] | undefined>
301
190
  ): Headers => {
302
191
  const mergedHeaders = new Headers();
303
192
  for (const header of headers) {
304
- if (!header || typeof header !== 'object') {
193
+ if (!header) {
305
194
  continue;
306
195
  }
307
196
 
308
- const iterator =
309
- header instanceof Headers ? header.entries() : Object.entries(header);
197
+ const iterator = header instanceof Headers ? headersEntries(header) : Object.entries(header);
310
198
 
311
199
  for (const [key, value] of iterator) {
312
200
  if (value === null) {
@@ -335,10 +223,7 @@ type ErrInterceptor<Err, Res, Req, Options> = (
335
223
  options: Options,
336
224
  ) => Err | Promise<Err>;
337
225
 
338
- type ReqInterceptor<Req, Options> = (
339
- request: Req,
340
- options: Options,
341
- ) => Req | Promise<Req>;
226
+ type ReqInterceptor<Req, Options> = (request: Req, options: Options) => Req | Promise<Req>;
342
227
 
343
228
  type ResInterceptor<Res, Req, Options> = (
344
229
  response: Res,
@@ -347,67 +232,58 @@ type ResInterceptor<Res, Req, Options> = (
347
232
  ) => Res | Promise<Res>;
348
233
 
349
234
  class Interceptors<Interceptor> {
350
- _fns: (Interceptor | null)[];
235
+ fns: Array<Interceptor | null> = [];
351
236
 
352
- constructor() {
353
- this._fns = [];
237
+ clear(): void {
238
+ this.fns = [];
354
239
  }
355
240
 
356
- clear() {
357
- this._fns = [];
358
- }
359
-
360
- getInterceptorIndex(id: number | Interceptor): number {
361
- if (typeof id === 'number') {
362
- return this._fns[id] ? id : -1;
363
- } else {
364
- return this._fns.indexOf(id);
241
+ eject(id: number | Interceptor): void {
242
+ const index = this.getInterceptorIndex(id);
243
+ if (this.fns[index]) {
244
+ this.fns[index] = null;
365
245
  }
366
246
  }
367
- exists(id: number | Interceptor) {
247
+
248
+ exists(id: number | Interceptor): boolean {
368
249
  const index = this.getInterceptorIndex(id);
369
- return !!this._fns[index];
250
+ return Boolean(this.fns[index]);
370
251
  }
371
252
 
372
- eject(id: number | Interceptor) {
373
- const index = this.getInterceptorIndex(id);
374
- if (this._fns[index]) {
375
- this._fns[index] = null;
253
+ getInterceptorIndex(id: number | Interceptor): number {
254
+ if (typeof id === 'number') {
255
+ return this.fns[id] ? id : -1;
376
256
  }
257
+ return this.fns.indexOf(id);
377
258
  }
378
259
 
379
- update(id: number | Interceptor, fn: Interceptor) {
260
+ update(id: number | Interceptor, fn: Interceptor): number | Interceptor | false {
380
261
  const index = this.getInterceptorIndex(id);
381
- if (this._fns[index]) {
382
- this._fns[index] = fn;
262
+ if (this.fns[index]) {
263
+ this.fns[index] = fn;
383
264
  return id;
384
- } else {
385
- return false;
386
265
  }
266
+ return false;
387
267
  }
388
268
 
389
- use(fn: Interceptor) {
390
- this._fns = [...this._fns, fn];
391
- return this._fns.length - 1;
269
+ use(fn: Interceptor): number {
270
+ this.fns.push(fn);
271
+ return this.fns.length - 1;
392
272
  }
393
273
  }
394
274
 
395
- // `createInterceptors()` response, meant for external use as it does not
396
- // expose internals
397
275
  export interface Middleware<Req, Res, Err, Options> {
398
- error: Pick<
399
- Interceptors<ErrInterceptor<Err, Res, Req, Options>>,
400
- 'eject' | 'use'
401
- >;
402
- request: Pick<Interceptors<ReqInterceptor<Req, Options>>, 'eject' | 'use'>;
403
- response: Pick<
404
- Interceptors<ResInterceptor<Res, Req, Options>>,
405
- 'eject' | 'use'
406
- >;
276
+ error: Interceptors<ErrInterceptor<Err, Res, Req, Options>>;
277
+ request: Interceptors<ReqInterceptor<Req, Options>>;
278
+ response: Interceptors<ResInterceptor<Res, Req, Options>>;
407
279
  }
408
280
 
409
- // do not add `Middleware` as return type so we can use _fns internally
410
- export const createInterceptors = <Req, Res, Err, Options>() => ({
281
+ export const createInterceptors = <Req, Res, Err, Options>(): Middleware<
282
+ Req,
283
+ Res,
284
+ Err,
285
+ Options
286
+ > => ({
411
287
  error: new Interceptors<ErrInterceptor<Err, Res, Req, Options>>(),
412
288
  request: new Interceptors<ReqInterceptor<Req, Options>>(),
413
289
  response: new Interceptors<ResInterceptor<Res, Req, Options>>(),
package/client.gen.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import type { ClientOptions } from './types.gen';
2
- import { type Config, type ClientOptions as DefaultClientOptions } from './client';
1
+ import { type ClientOptions, type Config } from './client';
2
+ import type { ClientOptions as ClientOptions2 } from './types.gen';
3
3
  /**
4
4
  * The `createClientConfig()` function will be called on client initialization
5
5
  * and the returned object will become the client's initial configuration.
@@ -8,5 +8,5 @@ import { type Config, type ClientOptions as DefaultClientOptions } from './clien
8
8
  * `setConfig()`. This is useful for example if you're using Next.js
9
9
  * to ensure your client always has the correct values.
10
10
  */
11
- export type CreateClientConfig<T extends DefaultClientOptions = ClientOptions> = (override?: Config<DefaultClientOptions & T>) => Config<Required<DefaultClientOptions> & T>;
11
+ export type CreateClientConfig<T extends ClientOptions = ClientOptions2> = (override?: Config<ClientOptions & T>) => Config<Required<ClientOptions> & T>;
12
12
  export declare const client: import("./client").Client;
package/client.gen.js CHANGED
@@ -3,6 +3,4 @@
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
4
  exports.client = void 0;
5
5
  const client_1 = require("./client");
6
- exports.client = (0, client_1.createClient)((0, client_1.createConfig)({
7
- baseUrl: 'http://localhost:8000'
8
- }));
6
+ exports.client = (0, client_1.createClient)((0, client_1.createConfig)({ baseUrl: 'http://localhost:8000' }));
package/client.gen.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  // This file is auto-generated by @hey-api/openapi-ts
2
2
 
3
- import type { ClientOptions } from './types.gen';
4
- import { type Config, type ClientOptions as DefaultClientOptions, createClient, createConfig } from './client';
3
+ import { type ClientOptions, type Config, createClient, createConfig } from './client';
4
+ import type { ClientOptions as ClientOptions2 } from './types.gen';
5
5
 
6
6
  /**
7
7
  * The `createClientConfig()` function will be called on client initialization
@@ -11,8 +11,6 @@ import { type Config, type ClientOptions as DefaultClientOptions, createClient,
11
11
  * `setConfig()`. This is useful for example if you're using Next.js
12
12
  * to ensure your client always has the correct values.
13
13
  */
14
- export type CreateClientConfig<T extends DefaultClientOptions = ClientOptions> = (override?: Config<DefaultClientOptions & T>) => Config<Required<DefaultClientOptions> & T>;
14
+ export type CreateClientConfig<T extends ClientOptions = ClientOptions2> = (override?: Config<ClientOptions & T>) => Config<Required<ClientOptions> & T>;
15
15
 
16
- export const client = createClient(createConfig<ClientOptions>({
17
- baseUrl: 'http://localhost:8000'
18
- }));
16
+ export const client = createClient(createConfig<ClientOptions2>({ baseUrl: 'http://localhost:8000' }));
package/core/auth.gen.ts CHANGED
@@ -23,8 +23,7 @@ export const getAuthToken = async (
23
23
  auth: Auth,
24
24
  callback: ((auth: Auth) => Promise<AuthToken> | AuthToken) | AuthToken,
25
25
  ): Promise<string | undefined> => {
26
- const token =
27
- typeof callback === 'function' ? await callback(auth) : callback;
26
+ const token = typeof callback === 'function' ? await callback(auth) : callback;
28
27
 
29
28
  if (!token) {
30
29
  return;
@@ -1,11 +1,18 @@
1
1
  import type { ArrayStyle, ObjectStyle, SerializerOptions } from './pathSerializer.gen';
2
2
  export type QuerySerializer = (query: Record<string, unknown>) => string;
3
3
  export type BodySerializer = (body: any) => any;
4
- export interface QuerySerializerOptions {
4
+ type QuerySerializerOptionsObject = {
5
5
  allowReserved?: boolean;
6
- array?: SerializerOptions<ArrayStyle>;
7
- object?: SerializerOptions<ObjectStyle>;
8
- }
6
+ array?: Partial<SerializerOptions<ArrayStyle>>;
7
+ object?: Partial<SerializerOptions<ObjectStyle>>;
8
+ };
9
+ export type QuerySerializerOptions = QuerySerializerOptionsObject & {
10
+ /**
11
+ * Per-parameter serialization overrides. When provided, these settings
12
+ * override the global array/object settings for specific parameter names.
13
+ */
14
+ parameters?: Record<string, QuerySerializerOptionsObject>;
15
+ };
9
16
  export declare const formDataBodySerializer: {
10
17
  bodySerializer: <T extends Record<string, any> | Array<Record<string, any>>>(body: T) => FormData;
11
18
  };
@@ -15,3 +22,4 @@ export declare const jsonBodySerializer: {
15
22
  export declare const urlSearchParamsBodySerializer: {
16
23
  bodySerializer: <T extends Record<string, any> | Array<Record<string, any>>>(body: T) => string;
17
24
  };
25
+ export {};
@@ -39,7 +39,7 @@ exports.formDataBodySerializer = {
39
39
  },
40
40
  };
41
41
  exports.jsonBodySerializer = {
42
- bodySerializer: (body) => JSON.stringify(body, (_key, value) => typeof value === 'bigint' ? value.toString() : value),
42
+ bodySerializer: (body) => JSON.stringify(body, (_key, value) => (typeof value === 'bigint' ? value.toString() : value)),
43
43
  };
44
44
  exports.urlSearchParamsBodySerializer = {
45
45
  bodySerializer: (body) => {
@@ -1,26 +1,26 @@
1
1
  // This file is auto-generated by @hey-api/openapi-ts
2
2
 
3
- import type {
4
- ArrayStyle,
5
- ObjectStyle,
6
- SerializerOptions,
7
- } from './pathSerializer.gen';
3
+ import type { ArrayStyle, ObjectStyle, SerializerOptions } from './pathSerializer.gen';
8
4
 
9
5
  export type QuerySerializer = (query: Record<string, unknown>) => string;
10
6
 
11
7
  export type BodySerializer = (body: any) => any;
12
8
 
13
- export interface QuerySerializerOptions {
9
+ type QuerySerializerOptionsObject = {
14
10
  allowReserved?: boolean;
15
- array?: SerializerOptions<ArrayStyle>;
16
- object?: SerializerOptions<ObjectStyle>;
17
- }
11
+ array?: Partial<SerializerOptions<ArrayStyle>>;
12
+ object?: Partial<SerializerOptions<ObjectStyle>>;
13
+ };
14
+
15
+ export type QuerySerializerOptions = QuerySerializerOptionsObject & {
16
+ /**
17
+ * Per-parameter serialization overrides. When provided, these settings
18
+ * override the global array/object settings for specific parameter names.
19
+ */
20
+ parameters?: Record<string, QuerySerializerOptionsObject>;
21
+ };
18
22
 
19
- const serializeFormDataPair = (
20
- data: FormData,
21
- key: string,
22
- value: unknown,
23
- ): void => {
23
+ const serializeFormDataPair = (data: FormData, key: string, value: unknown): void => {
24
24
  if (typeof value === 'string' || value instanceof Blob) {
25
25
  data.append(key, value);
26
26
  } else if (value instanceof Date) {
@@ -30,11 +30,7 @@ const serializeFormDataPair = (
30
30
  }
31
31
  };
32
32
 
33
- const serializeUrlSearchParamsPair = (
34
- data: URLSearchParams,
35
- key: string,
36
- value: unknown,
37
- ): void => {
33
+ const serializeUrlSearchParamsPair = (data: URLSearchParams, key: string, value: unknown): void => {
38
34
  if (typeof value === 'string') {
39
35
  data.append(key, value);
40
36
  } else {
@@ -65,15 +61,11 @@ export const formDataBodySerializer = {
65
61
 
66
62
  export const jsonBodySerializer = {
67
63
  bodySerializer: <T>(body: T): string =>
68
- JSON.stringify(body, (_key, value) =>
69
- typeof value === 'bigint' ? value.toString() : value,
70
- ),
64
+ JSON.stringify(body, (_key, value) => (typeof value === 'bigint' ? value.toString() : value)),
71
65
  };
72
66
 
73
67
  export const urlSearchParamsBodySerializer = {
74
- bodySerializer: <T extends Record<string, any> | Array<Record<string, any>>>(
75
- body: T,
76
- ): string => {
68
+ bodySerializer: <T extends Record<string, any> | Array<Record<string, any>>>(body: T): string => {
77
69
  const data = new URLSearchParams();
78
70
 
79
71
  Object.entries(body).forEach(([key, value]) => {
@@ -17,6 +17,16 @@ export type Field = {
17
17
  */
18
18
  key?: string;
19
19
  map?: string;
20
+ } | {
21
+ /**
22
+ * Field name. This is the name we want the user to see and use.
23
+ */
24
+ key: string;
25
+ /**
26
+ * Field mapped name. This is the name we want to use in the request.
27
+ * If `in` is omitted, `map` aliases `key` to the transport layer.
28
+ */
29
+ map: Slot;
20
30
  };
21
31
  export interface Fields {
22
32
  allowExtra?: Partial<Record<Slot, boolean>>;
@@ -22,6 +22,11 @@ const buildKeyMap = (fields, map) => {
22
22
  });
23
23
  }
24
24
  }
25
+ else if ('key' in config) {
26
+ map.set(config.key, {
27
+ map: config.map,
28
+ });
29
+ }
25
30
  else if (config.args) {
26
31
  buildKeyMap(config.args, map);
27
32
  }
@@ -55,7 +60,9 @@ const buildClientParams = (args, fields) => {
55
60
  if (config.key) {
56
61
  const field = map.get(config.key);
57
62
  const name = field.map || config.key;
58
- params[field.in][name] = arg;
63
+ if (field.in) {
64
+ params[field.in][name] = arg;
65
+ }
59
66
  }
60
67
  else {
61
68
  params.body = arg;
@@ -65,8 +72,13 @@ const buildClientParams = (args, fields) => {
65
72
  for (const [key, value] of Object.entries(arg ?? {})) {
66
73
  const field = map.get(key);
67
74
  if (field) {
68
- const name = field.map || key;
69
- params[field.in][name] = value;
75
+ if (field.in) {
76
+ const name = field.map || key;
77
+ params[field.in][name] = value;
78
+ }
79
+ else {
80
+ params[field.map] = value;
81
+ }
70
82
  }
71
83
  else {
72
84
  const extra = extraPrefixes.find(([prefix]) => key.startsWith(prefix));
@@ -74,8 +86,8 @@ const buildClientParams = (args, fields) => {
74
86
  const [prefix, slot] = extra;
75
87
  params[slot][key.slice(prefix.length)] = value;
76
88
  }
77
- else {
78
- for (const [slot, allowed] of Object.entries(config.allowExtra ?? {})) {
89
+ else if ('allowExtra' in config && config.allowExtra) {
90
+ for (const [slot, allowed] of Object.entries(config.allowExtra)) {
79
91
  if (allowed) {
80
92
  params[slot][key] = value;
81
93
  break;