import type { OptionalKeys } from "./type-utils.ts"; /** Return values for getting the first value of a query param. */ type ParamValuesGet = { [Name in keyof Params]-?: Name extends OptionalKeys ? Params[Name] | null : Params[Name]; }; /** Return values for getting all values of a query param. */ type ParamValuesGetAll = { [Name in keyof Params]-?: Required[Name][]; }; /** * Wrapper around the search params of a request that offers methods for * querying search params with enhanced type-safety from OpenAPI-TS. */ export class QueryParams { #searchParams: URLSearchParams; constructor(request: Request) { this.#searchParams = new URL(request.url).searchParams; } /** * Wraps around {@link URLSearchParams.size}. * * [MDN Reference](https://developer.mozilla.org/docs/Web/API/URLSearchParams/size) */ get size(): number { return this.#searchParams.size; } /** * Wraps around {@link URLSearchParams.get} with type inference from the * provided OpenAPI-TS `paths` definition. * * [MDN Reference](https://developer.mozilla.org/docs/Web/API/URLSearchParams/get) */ get(name: Name): ParamValuesGet[Name] { const value = this.#searchParams.get(name as string); // eslint-disable-next-line @typescript-eslint/no-explicit-any return value as any; } /** * Wraps around {@link URLSearchParams.getAll} with type inference from the * provided OpenAPI-TS `paths` definition. * * [MDN Reference](https://developer.mozilla.org/docs/Web/API/URLSearchParams/getAll) */ getAll( name: Name, ): ParamValuesGetAll[Name] { const values = this.#searchParams.getAll(name as string); // eslint-disable-next-line @typescript-eslint/no-explicit-any return values as any; } /** * Wraps around {@link URLSearchParams.has} with type inference from the * provided OpenAPI-TS `paths` definition. * * [MDN Reference](https://developer.mozilla.org/docs/Web/API/URLSearchParams/has) */ has(name: Name, value?: Params[Name]): boolean { return this.#searchParams.has(name as string, value as string | undefined); } }