File

src/registrar/generated/core/params.ts

Index

Properties

Properties

allowExtra
allowExtra: Partial<Record<Slot, boolean>>
Type : Partial<Record<Slot, boolean>>
Optional
args
args: ReadonlyArray<Field>
Type : ReadonlyArray<Field>
Optional
type Slot = 'body' | 'headers' | 'path' | 'query';

export type Field =
    | {
          in: Exclude<Slot, 'body'>;
          key: string;
          map?: string;
      }
    | {
          in: Extract<Slot, 'body'>;
          key?: string;
          map?: string;
      };

export interface Fields {
    allowExtra?: Partial<Record<Slot, boolean>>;
    args?: ReadonlyArray<Field>;
}

export type FieldsConfig = ReadonlyArray<Field | Fields>;

const extraPrefixesMap: Record<string, Slot> = {
    $body_: 'body',
    $headers_: 'headers',
    $path_: 'path',
    $query_: 'query',
};
const extraPrefixes = Object.entries(extraPrefixesMap);

type KeyMap = Map<
    string,
    {
        in: Slot;
        map?: string;
    }
>;

const buildKeyMap = (fields: FieldsConfig, map?: KeyMap): KeyMap => {
    if (!map) {
        map = new Map();
    }

    for (const config of fields) {
        if ('in' in config) {
            if (config.key) {
                map.set(config.key, {
                    in: config.in,
                    map: config.map,
                });
            }
        } else if (config.args) {
            buildKeyMap(config.args, map);
        }
    }

    return map;
};

interface Params {
    body: unknown;
    headers: Record<string, unknown>;
    path: Record<string, unknown>;
    query: Record<string, unknown>;
}

const stripEmptySlots = (params: Params) => {
    for (const [slot, value] of Object.entries(params)) {
        if (value && typeof value === 'object' && !Object.keys(value).length) {
            delete params[slot as Slot];
        }
    }
};

export const buildClientParams = (
    args: ReadonlyArray<unknown>,
    fields: FieldsConfig,
) => {
    const params: Params = {
        body: {},
        headers: {},
        path: {},
        query: {},
    };

    const map = buildKeyMap(fields);

    let config: FieldsConfig[number] | undefined;

    for (const [index, arg] of args.entries()) {
        if (fields[index]) {
            config = fields[index];
        }

        if (!config) {
            continue;
        }

        if ('in' in config) {
            if (config.key) {
                const field = map.get(config.key)!;
                const name = field.map || config.key;
                (params[field.in] as Record<string, unknown>)[name] = arg;
            } else {
                params.body = arg;
            }
        } else {
            for (const [key, value] of Object.entries(arg ?? {})) {
                const field = map.get(key);

                if (field) {
                    const name = field.map || key;
                    (params[field.in] as Record<string, unknown>)[name] = value;
                } else {
                    const extra = extraPrefixes.find(([prefix]) =>
                        key.startsWith(prefix),
                    );

                    if (extra) {
                        const [prefix, slot] = extra;
                        (params[slot] as Record<string, unknown>)[
                            key.slice(prefix.length)
                        ] = value;
                    } else {
                        for (const [slot, allowed] of Object.entries(
                            config.allowExtra ?? {},
                        )) {
                            if (allowed) {
                                (
                                    params[slot as Slot] as Record<
                                        string,
                                        unknown
                                    >
                                )[key] = value;
                                break;
                            }
                        }
                    }
                }
            }
        }
    }

    stripEmptySlots(params);

    return params;
};

results matching ""

    No results matching ""