Skip to content

Instantly share code, notes, and snippets.

@zoontek
Last active June 15, 2020 15:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zoontek/19b8ce70f2ac611e670511da5137f43c to your computer and use it in GitHub Desktop.
Save zoontek/19b8ce70f2ac611e670511da5137f43c to your computer and use it in GitHub Desktop.
// Libs internal
type Segment<T> = {
test: (value: unknown) => boolean;
parse: (string: string) => T;
stringify: (value: T) => string;
};
const string: Segment<string> = {
test: (value) => typeof value === "string",
parse: (string) => string,
stringify: (value) => value,
};
const boolean: Segment<boolean> = {
test: (value) => typeof value === "boolean",
parse: (string) => string === "true",
stringify: (value) => "" + value,
};
const number: Segment<number> = {
test: (value) => typeof value === "number",
parse: (string) => Number(string),
stringify: (value) => "" + value,
};
const t = { string, boolean, number };
const MULTIPLE = "multiple";
const NULLABLE = "nullable";
type MultipleSegment<T> = [typeof MULTIPLE, Segment<T>];
type NullableSegment<T> = [typeof NULLABLE, Segment<T>];
const m = {
multiple: <T>(segment: Segment<T>): MultipleSegment<T> => [MULTIPLE, segment],
nullable: <T>(segment: Segment<T>): NullableSegment<T> => [NULLABLE, segment],
};
// Usage
const [getMatchHook, getURL] = create((_) => ({
// static routes
foo: {
path: ["projects"],
},
// dynamic routes
bar: _(
{
projectId: t.string, // custom matcher can be created! think UUID, date, etc
accountId: t.string,
acceptation: m.nullable(t.boolean),
},
({ projectId, accountId, acceptation }) => ({
path: ["project", projectId, "account", accountId],
search: { acceptation },
})
),
}));
getURL(basePath, "foo"); // -> "/projects"
getURL(basePath, "bar", { projectId: "1", accountId: "2" }); // "acceptation" is optional here
const useMatch = getMatchHook({
exact: ["foo"], // will match on "/projects"
nested: ["bar"], // will match on /projects/:projectId/account/:accountId/*
});
const matched = useMatch("/"); // with basePath
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment