feat(api): enhance KeyMap and FieldsConfig handling for improved flexibility
- Added support for unmapped fields in `KeyMap` definitions and parsing. - Updated `buildKeyMap` to allow aliasing keys without transport layer mappings. - Improved parameter assignment logic to handle optional `in` mappings. - Enhanced handling of `allowExtra` fields for more concise and robust configurations.
This commit is contained in:
@@ -152,7 +152,7 @@ type BuildUrlFn = <
|
||||
url: string;
|
||||
},
|
||||
>(
|
||||
options: Pick<TData, 'url'> & Options<TData>,
|
||||
options: TData & Options<TData>,
|
||||
) => string;
|
||||
|
||||
export type Client = CoreClient<
|
||||
@@ -195,7 +195,7 @@ export type Options<
|
||||
RequestOptions<TResponse, ThrowOnError>,
|
||||
'body' | 'path' | 'query' | 'url'
|
||||
> &
|
||||
Omit<TData, 'url'>;
|
||||
([TData] extends [never] ? unknown : Omit<TData, 'url'>);
|
||||
|
||||
export type OptionsLegacyParser<
|
||||
TData = unknown,
|
||||
|
||||
@@ -23,6 +23,17 @@ export type Field =
|
||||
*/
|
||||
key?: string;
|
||||
map?: string;
|
||||
}
|
||||
| {
|
||||
/**
|
||||
* Field name. This is the name we want the user to see and use.
|
||||
*/
|
||||
key: string;
|
||||
/**
|
||||
* Field mapped name. This is the name we want to use in the request.
|
||||
* If `in` is omitted, `map` aliases `key` to the transport layer.
|
||||
*/
|
||||
map: Slot;
|
||||
};
|
||||
|
||||
export interface Fields {
|
||||
@@ -42,10 +53,14 @@ const extraPrefixes = Object.entries(extraPrefixesMap);
|
||||
|
||||
type KeyMap = Map<
|
||||
string,
|
||||
{
|
||||
in: Slot;
|
||||
map?: string;
|
||||
}
|
||||
| {
|
||||
in: Slot;
|
||||
map?: string;
|
||||
}
|
||||
| {
|
||||
in?: never;
|
||||
map: Slot;
|
||||
}
|
||||
>;
|
||||
|
||||
const buildKeyMap = (fields: FieldsConfig, map?: KeyMap): KeyMap => {
|
||||
@@ -61,6 +76,10 @@ const buildKeyMap = (fields: FieldsConfig, map?: KeyMap): KeyMap => {
|
||||
map: config.map,
|
||||
});
|
||||
}
|
||||
} else if ('key' in config) {
|
||||
map.set(config.key, {
|
||||
map: config.map,
|
||||
});
|
||||
} else if (config.args) {
|
||||
buildKeyMap(config.args, map);
|
||||
}
|
||||
@@ -112,7 +131,9 @@ export const buildClientParams = (
|
||||
if (config.key) {
|
||||
const field = map.get(config.key)!;
|
||||
const name = field.map || config.key;
|
||||
(params[field.in] as Record<string, unknown>)[name] = arg;
|
||||
if (field.in) {
|
||||
(params[field.in] as Record<string, unknown>)[name] = arg;
|
||||
}
|
||||
} else {
|
||||
params.body = arg;
|
||||
}
|
||||
@@ -121,8 +142,12 @@ export const buildClientParams = (
|
||||
const field = map.get(key);
|
||||
|
||||
if (field) {
|
||||
const name = field.map || key;
|
||||
(params[field.in] as Record<string, unknown>)[name] = value;
|
||||
if (field.in) {
|
||||
const name = field.map || key;
|
||||
(params[field.in] as Record<string, unknown>)[name] = value;
|
||||
} else {
|
||||
params[field.map] = value;
|
||||
}
|
||||
} else {
|
||||
const extra = extraPrefixes.find(([prefix]) =>
|
||||
key.startsWith(prefix),
|
||||
@@ -133,10 +158,8 @@ export const buildClientParams = (
|
||||
(params[slot] as Record<string, unknown>)[
|
||||
key.slice(prefix.length)
|
||||
] = value;
|
||||
} else {
|
||||
for (const [slot, allowed] of Object.entries(
|
||||
config.allowExtra ?? {},
|
||||
)) {
|
||||
} else if ('allowExtra' in config && config.allowExtra) {
|
||||
for (const [slot, allowed] of Object.entries(config.allowExtra)) {
|
||||
if (allowed) {
|
||||
(params[slot as Slot] as Record<string, unknown>)[key] = value;
|
||||
break;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* For custom handler behavior, use src/mocks/handlers/overrides.ts
|
||||
*
|
||||
* Generated: 2025-11-26T12:21:51.098Z
|
||||
* Generated: 2026-03-01T17:00:19.178Z
|
||||
*/
|
||||
|
||||
import { http, HttpResponse, delay } from 'msw';
|
||||
|
||||
Reference in New Issue
Block a user