Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(types): Configuration of path and nest methods #59

Merged
merged 1 commit into from
Dec 14, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 38 additions & 17 deletions src/lib/Routeways.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,15 @@ type PathVarsCapture<P extends PathLike> =
: never;

/**
* Creates a mapped type where the keys must be the captures from `P` and the
* values the codec from `V` on each key.
* Conditional constraint for path variables based on the result of capturing
* the literals on the {@link PathLike} string.
*
* @param P the {@link PathLike} string
* @param V the path vars codec record
*/
type PathVars<
P extends PathLike,
V extends Record<PathVarsCapture<P>, Codec<unknown>>,
> = { [K in PathVarsCapture<P>]: V[K] };
type PathVars<P extends PathLike> =
PathVarsCapture<P> extends never
? Record<never, never>
: Record<PathVarsCapture<P>, Codec<unknown>>;

/**
* Conditionally create the `makeUrl` function based on the codec map of path
Expand Down Expand Up @@ -159,24 +158,46 @@ type GetResultRoute<S extends Routeway, V1 extends Record<string, unknown>> =
>
: never;

type PathConfig<
/**
* Conditionally create a route configuratiion based on the `path` property
* string. If the path contains path variables, the `pathVars` property is
* required and it must be defined with path variables names as its keys.
*
* @param N the name of the route
* @param P the {@link PathLike} string
* @param V the path vars codec record
* @param Q the query param codec record
*/
export type PathConfig<
N extends string,
P extends PathLike,
V extends Record<PathVarsCapture<P>, Codec<unknown>>,
V extends PathVars<P>,
Q extends CodecMap,
> = PathVarsCapture<P> extends never
? { name: N; path: P; queryParams?: Q; }
: { name: N; path: P; pathVars: PathVars<P, V>; queryParams?: Q; };
: { name: N; path: P; pathVars: V; queryParams?: Q; };

type NestConfig<
/**
* Conditionally create a route configuratiion based on the `path` property
* string. If the path contains path variables, the `pathVars` property is
* required and it must be defined with path variables names as its keys.
* Aditionally, this configuration requires a `subRoutes` property.
*
* @param N the name of the route
* @param P the {@link PathLike} string
* @param V the path vars codec record
* @param Q the query param codec record
* @param S the `RoutewaysBuilder` for the subroutes
*/
export type NestConfig<
N extends string,
P extends PathLike,
V extends Record<PathVarsCapture<P>, Codec<unknown>>,
V extends PathVars<P>,
Q extends CodecMap,
S extends RoutewaysBuilder<Record<string, Routeway>>,
> = PathVarsCapture<P> extends never
? { name: N; path: P; queryParams?: Q; subRoutes: S; }
: { name: N; path: P; pathVars: PathVars<P, V>; queryParams?: Q; subRoutes: S; };
: { name: N; path: P; pathVars: V; queryParams?: Q; subRoutes: S; };

/**
* The Routeways builder API.
Expand Down Expand Up @@ -211,7 +232,7 @@ export class RoutewaysBuilder<M extends Record<string, Routeway>> {
Q extends CodecMap,
>(
config: PathConfig<N, P, V, Q>,
): RoutewaysBuilder<{ [K in keyof M]: M[K]; } & { [K in N]: Routeway<P, PathVars<P, V>, Q>; }> {
): RoutewaysBuilder<{ [K in keyof M]: M[K]; } & { [K in N]: Routeway<P, V, Q>; }> {
const { name, path, pathVars, queryParams = { } as Q } = "pathVars" in config
? config
: { ...config, pathVars: { } as V };
Expand Down Expand Up @@ -247,18 +268,18 @@ export class RoutewaysBuilder<M extends Record<string, Routeway>> {
public nest<
N extends string,
P extends PathLike,
V extends Record<PathVarsCapture<P>, Codec<unknown>>,
V extends PathVars<P>,
Q extends CodecMap,
S extends RoutewaysBuilder<DefinedSubRoutes<S>>,
>(
config: NestConfig<N, P, V, Q, S>,
): RoutewaysBuilder<{ [K in keyof M]: M[K] } & { [K in N]: Routeway<P, PathVars<P, V>, Q, ResultSubRoutes<S, V>> }> {
): RoutewaysBuilder<{ [K in keyof M]: M[K] } & { [K in N]: Routeway<P, V, Q, ResultSubRoutes<S, V>> }> {
const { name, path, pathVars, queryParams = { } as Q, subRoutes } = "pathVars" in config
? config
: { ...config, pathVars: { } as V };
const subRouteRecord = subRoutes.routes as ResultSubRoutes<S, V>;

const newRoute: Routeway<P, PathVars<P, V>, Q, ResultSubRoutes<S, V>> = {
const newRoute: Routeway<P, V, Q, ResultSubRoutes<S, V>> = {
$config: () => ({
pathVars,
queryParams,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { expect } from "@stackbuilders/assertive-ts";

import { Codecs } from "../../../src/lib/Codecs";
import { CodecsToRecord, InferQueryParams, PathLike, RouteParams } from "../../../src/lib/helpers/common";
import { TestRoutes } from "../../TestRoutes";
import { Codecs } from "../../../../src/lib/Codecs";
import { CodecsToRecord, InferQueryParams, PathLike, RouteParams } from "../../../../src/lib/helpers/common";
import { TestRoutes } from "../../../TestRoutes";

describe("[Unit] Commons.types.test.ts", () => {
describe("PathLike", () => {
Expand Down