Last active
June 15, 2020 15:45
-
-
Save zoontek/19b8ce70f2ac611e670511da5137f43c to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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