### Install Routopia Source: https://github.com/ykicchan/routopia/blob/main/README.md Install the package using npm. ```bash npm install routopia ``` -------------------------------- ### Shorthand Syntax Source: https://github.com/ykicchan/routopia/blob/main/README.md Using shorthand to define GET routes by omitting the HTTP method. ```APIDOC ## Shorthand Syntax ### Description Define parameters directly to implicitly create a GET route. ### Usage ```ts import { routes, empty, type } from 'routopia'; const myRoutes = routes({ "/short/[param]": { params: { param: type as string }, queries: { q: type as string | undefined }, hash: type as string, }, }); myRoutes["/short/[param]"].get({ params: { param: "abc" }, queries: { q: "query" }, hash: "anchor", }); // => "/short/abc?q=query#anchor" ``` ``` -------------------------------- ### Define user domain routes Source: https://github.com/ykicchan/routopia/blob/main/README.md Example of defining routes for a user domain using the custom abstraction layer. ```ts // userRoutes.ts import { createMyApiRoutes, schema } from './path/to/createMyApiRoutes'; export const userRoutes = createMyApiRoutes({ "/users": schema.empty, "/users/[id]": { params: { id: schema.type as number, }, }, }); ``` -------------------------------- ### Define post domain routes Source: https://github.com/ykicchan/routopia/blob/main/README.md Example of defining routes for a post domain with various HTTP methods and parameters. ```ts // postRoutes.ts import { createMyApiRoutes, schema } from './path/to/createMyApiRoutes'; export const postRoutes = createMyApiRoutes({ "/posts": { get: { queries: { q: schema.type as string | undefined } }, }, "/posts/[id]": { get: { params: { id: schema.type as number } }, post: { params: { id: schema.type as number } }, put: { params: { id: schema.type as number } }, delete: { params: { id: schema.type as number } }, }, }); ``` -------------------------------- ### Use Shorthand Notation Source: https://github.com/ykicchan/routopia/blob/main/README.md Define endpoints directly without specifying an HTTP method, which defaults to GET. ```ts import { routes, empty, type } from 'routopia'; const myRoutes = routes({ "/short": empty, // = "/short": { get: empty } "/short/[param]": { params: { param: type as string, }, queries: { q: type as string | undefined, }, hash: type as string, }, // = "/short/[param]": { get: { params: {...}, queries: {...}, hash: ... } } }); // Use it by calling the `get` method myRoutes["/short"].get(); // => "/short" myRoutes["/short/[param]"].get({ params: { param: "abc" }, queries: { q: "query" }, hash: "anchor", }); // => "/short/abc?q=query#anchor" ``` -------------------------------- ### Define and mock routes with updated syntax Source: https://github.com/ykicchan/routopia/blob/main/CHANGELOG.md Demonstrates the use of colon-based syntax for path parameters and catch-all parameters in route definitions. ```ts const myRoutes = routes({ "/users/[id]": { params: { id: type as string } }, "/posts/[...slugs]": { params: { slugs: type as string[] } }, "/tags/[[...tags]]": { params: { tags: type as string[] } }, }); myRoutes["/users/[id]"].mock(); // => "/users/:id" myRoutes["/posts/[...slugs]"].mock(); // => "/posts/:slugs+" myRoutes["/tags/[[...tags]]"].mock(); // => "/tags/:tags*" ``` -------------------------------- ### Use Routes Source: https://github.com/ykicchan/routopia/blob/main/README.md Construct URLs by calling the defined route methods with required parameters and queries. ```ts import { myRoutes } from './path/to/myRoutes'; myRoutes["/users"].get(); myRoutes["/users"].post(); // => "/users" myRoutes["/path/[id]"].get({ params: { id: 123 } }); // => "/path/123" myRoutes["/path/[id]"].get({ params: { id: 123 }, queries: { q: "query" } }); // => "/path/123?q=query" ``` -------------------------------- ### Defining and Using Routes Source: https://github.com/ykicchan/routopia/blob/main/README.md How to define routes with query parameters and path parameters using the routes function. ```APIDOC ## Defining Routes ### Description Use the `routes` function to define your API structure. You can specify query parameters, path parameters, and hashes. ### Usage ```ts import { routes, type } from 'routopia'; const myRoutes = routes({ "/path": { get: { queries: { str: type as string, opt: type as string | undefined, }, hash: type as string }, }, }); // Generate URL myRoutes["/path"].get({ queries: { str: "value" }, hash: "anchor" }); ``` ``` -------------------------------- ### Defining and Using Routes Source: https://github.com/ykicchan/routopia/blob/main/README.md How to define routes using the routes function and invoke them to generate URLs. ```APIDOC ## routes(definition) ### Description Defines a set of routes with associated HTTP methods and parameter requirements. ### Parameters - **definition** (object) - Required - An object where keys are path strings and values define the allowed methods (get, post, put, delete) and their parameter constraints. ### Usage Example ```ts import { routes, empty } from 'routopia'; const myRoutes = routes({ "/path": { get: empty, post: empty, }, }); myRoutes["/path"].get(); // => "/path" ``` ``` -------------------------------- ### Mocking URL construction Source: https://github.com/ykicchan/routopia/blob/main/README.md Demonstrates basic usage of the mock method for path and query parameters, including automatic colon syntax for omitted parameters. ```ts import { routes, type } from 'routopia'; const myRoutes = routes({ "/path/[num]": { params: { num: type as number }, queries: { req: type as string, opt: type as number | undefined } } }); myRoutes["/path/[num]"].mock() myRoutes["/path/[num]"].get.mock() // => "/path/:num" myRoutes["/path/[num]"].mock({ params: { num: "abc" }, queries: { opt: "q" } }) myRoutes["/path/[num]"].get.mock({ params: { num: "abc" }, queries: { opt: "q" } }) // => "/path/abc?opt=q" Parameters<(typeof myRoutes)["/path/[num]"]["mock"]> Parameters<(typeof myRoutes)["/path/[num]"]["get"]["mock"]> // ^? [{ // params?: { num?: string | number } }; // queries?: { // req?: string | number | boolean | string[]...; // opt?: string | number | boolean | string[]...; // }; // }] ``` -------------------------------- ### Catch-all Parameters Source: https://github.com/ykicchan/routopia/blob/main/README.md Defining routes that capture multiple path segments. ```APIDOC ## Catch-all Parameters ### Description Use `[...param]` for required catch-all segments or `[[...param]]` for optional catch-all segments. These accept arrays of strings or numbers. ### Usage Example ```ts import { routes, type } from 'routopia'; const myRoutes = routes({ "/path/[...slug]": { get: { params: { slug: type as string[], }, }, }, }); myRoutes["/path/[...slug]"].get({ params: { slug: ["a", "b"] } }); // => "/path/a/b" ``` ``` -------------------------------- ### Base URL Configuration Source: https://github.com/ykicchan/routopia/blob/main/README.md How to prefix routes with a base URL. ```APIDOC ## Base URL ### Description Pass a string as the first argument to the `routes` function to prepend a base URL to all defined routes. ### Usage ```ts import { routes, empty } from 'routopia'; const myApiRoutes = routes("https://api.example.com", { "/path": { get: empty, }, }); myApiRoutes["/path"].get(); // => "https://api.example.com/path" ``` ``` -------------------------------- ### Path Parameters Source: https://github.com/ykicchan/routopia/blob/main/README.md Defining routes with dynamic path segments using bracket syntax. ```APIDOC ## Path Parameters ### Description Use `[param]` syntax in route paths to define dynamic segments. Parameters are validated against the types defined in the `params` object. ### Usage Example ```ts import { routes, type } from 'routopia'; const myRoutes = routes({ "/path/[id]": { get: { params: { id: type as number, }, }, }, }); myRoutes["/path/[id]"].get({ params: { id: 123 } }); // => "/path/123" ``` ``` -------------------------------- ### Consume defined API routes Source: https://github.com/ykicchan/routopia/blob/main/README.md Demonstrates how to import and call the defined route handlers. ```ts // Usage import { userRoutes } from './path/to/userRoutes'; import { postRoutes } from './path/to/postRoutes'; userRoutes["/users"].get(); // => "https://api.example.com/users" postRoutes["/posts/[id]"].get({ params: { id: 123 } }); // => "https://api.example.com/posts/123" ``` -------------------------------- ### Combine HTTP Methods and Shorthand Source: https://github.com/ykicchan/routopia/blob/main/README.md Demonstrates valid and invalid ways to mix shorthand and explicit HTTP method definitions. ```ts import { routes, empty, type } from 'routopia'; // ❌: Cannot combine Shorthand notation with other method definitions within the same endpoint const error = routes({ "/short/mixed": { queries: { q: type as string }, post: empty, // ^^^^^^^^^^^ }, }); // ⚠️: Can be used together across different endpoints, but causes notation inconsistencies const notGood = routes({ "/hoge": empty, // : "/foo": { get: empty }, }); // ✅: Unify notation between endpoints within the same file const good = routes({ "/hoge": { get: empty }, // : "/foo": { get: empty }, }); // ✅: Or split definition files and unify notation by domain // hoge.ts const hogeRoutes = routes({ "/hoge": empty, }); // foo.ts const fooRoutes = routes({ "/foo": { get: empty }, }); ``` -------------------------------- ### mock(options?: MockOptions) Source: https://github.com/ykicchan/routopia/blob/main/README.md The mock method is used to generate URL strings for testing. It accepts optional parameters for path, query, and hash values. If path parameters are omitted, they are replaced with colon syntax (e.g., :id). ```APIDOC ## mock(options?: MockOptions) ### Description Generates a URL string based on defined route parameters. This method is intended for testing purposes only and does not perform URL encoding. ### Parameters - **options** (Object) - Optional - An object containing optional `params`, `queries`, and `hash` fields. - **params** (Object) - Optional - Key-value pairs for path parameters. - **queries** (Object) - Optional - Key-value pairs for query parameters. - **hash** (string) - Optional - The hash fragment for the URL. ### Usage Example ```ts // Using the mock method on an endpoint myRoutes["/path/[num]"].mock({ params: { num: "abc" }, queries: { opt: "q" } }); // => "/path/abc?opt=q" // Omitting parameters to use colon syntax myRoutes["/path/[num]"].mock(); // => "/path/:num" ``` ``` -------------------------------- ### Configure Base URL Source: https://github.com/ykicchan/routopia/blob/main/README.md Pass a string as the first argument to the routes function to prefix all generated paths with a base URL. ```ts import { routes, empty } from 'routopia'; const myUsersRoutes = routes("/users", { "/path": { get: empty, }, }); myUsersRoutes["/path"].get(); // => "/users/path" const myApiRoutes = routes("https://api.example.com", { "/path": { get: empty, }, }); myApiRoutes["/path"].get(); // => "https://api.example.com/path" ``` -------------------------------- ### Mocking catch-all parameters Source: https://github.com/ykicchan/routopia/blob/main/README.md Shows how the mock method handles catch-all parameters defined as string arrays. ```ts import { routes, type } from 'routopia'; const myRoutes = routes({ "/path/[...strArr]": { params: { strArr: type as string[] } } }); Parameters<(typeof myRoutes)["/path/[...strArr]"]["mock"]> Parameters<(typeof myRoutes)["/path/[...strArr]"]["get"]["mock"]> // ^? [{ params?: { strArr?: string[] | number[] } }] ``` -------------------------------- ### Define Catch-all Parameters Source: https://github.com/ykicchan/routopia/blob/main/README.md Use [...param] for required catch-all segments or [[...param]] for optional ones, specifying the type as an array. ```ts import { routes, type } from 'routopia'; const myRoutes = routes({ "/path/[...slug]": { get: { params: { slug: type as string[], }, }, }, "/path/[[...slug]]": { get: { params: { slug: type as number[], }, }, }, }); myRoutes["/path/[...slug]"].get({ params: { slug: ["abc", "def"] }, }); // => "/path/abc/def" myRoutes["/path/[...slug]"].get(); // ^^^^ // Error: Catch-all parameters cannot be omitted when called. myRoutes["/path/[[...slug]]"].get({ params: { slug: [123, 456] }, }); // => "/path/123/456" myRoutes["/path/[[...slug]]"].get(); // => "/path" // Optional Catch-all parameters can be omitted when called. ``` -------------------------------- ### Define Routes with Path Parameters Source: https://github.com/ykicchan/routopia/blob/main/README.md Use square brackets to define path parameters and type assertions to specify their expected types. ```ts import { routes, type } from 'routopia'; const myRoutes = routes({ "/path/[id]": { get: { params: { id: type as number, // type is also OK }, }, }, "/path/[param1]/[param2]": { get: { params: { param1: type as string, param2: type as string | number, }, }, }, }); myRoutes["/path/[id]"].get({ params: { id: 123 } }); // => "/path/123" myRoutes["/path/[id]"].get({ params: { id: "abc" } }); // ^^^^^ // Error: Type 'string' is not assignable to type 'number' myRoutes["/path/[param1]/[param2]"].get({ params: { param1: "abc", param2: 123 }, }); // => "/path/abc/123" myRoutes["/path/[id]"].get(); // ^^^^ // Error: Path parameters cannot be omitted when called. ``` -------------------------------- ### Define and mock routes in TypeScript Source: https://github.com/ykicchan/routopia/blob/main/CHANGELOG.md Use the .mock() method to generate URL patterns for mock servers, optionally providing parameters to replace placeholders. ```ts const myRoutes = routes({ "/users/[id]": { params: { id: type as string } }, }); myRoutes["/users/[id]"].mock(); // => "/users/*" myRoutes["/users/[id]"].mock({ params: { id: "123" } }); // => "/users/123" ``` -------------------------------- ### Create an API abstraction layer Source: https://github.com/ykicchan/routopia/blob/main/README.md Wraps the routopia routes function with a base URL and generic schema support. ```ts // createMyApiRoutes.ts import { routes, empty, type, ExpectedSchema } from 'routopia'; const API_BASE_URL = "https://api.example.com"; export function createMyApiRoutes>(schema: T) { return routes(API_BASE_URL, schema); } export const schema = { empty, type }; ``` -------------------------------- ### Catch-all Parameter Type Inference Source: https://github.com/ykicchan/routopia/blob/main/CHANGELOG.md Demonstrates how catch-all parameters are inferred with and without 'as const' assertions. ```typescript myRoutes["/params/[...params]"].get({ params: ["1"] }) ``` ```typescript myRoutes["/params/[...params]"].get({ params: ["1"] as const }) ``` -------------------------------- ### Combine route definitions Source: https://github.com/ykicchan/routopia/blob/main/README.md Shows how to aggregate multiple route objects, noting that this approach may negatively impact TreeShaking. ```ts // index.ts import { userRoutes } from './path/to/userRoutes'; import { postRoutes } from './path/to/postRoutes'; export const apiRoutes = { ...userRoutes, ...postRoutes, }; // Usage import { apiRoutes } from './path/to/index'; apiRoutes["/users"].get(); apiRoutes["/posts/[id]"].get({ params: { id: 123 } }); // You can search all routes uniformly, but the bundle size will increase ``` -------------------------------- ### Define Routes Without Parameters Source: https://github.com/ykicchan/routopia/blob/main/README.md Use the empty constant to define routes that do not require any parameters. ```ts import { routes, empty } from 'routopia'; const myRoutes = routes({ "/path": { get: empty, post: empty, put: empty, delete: empty, }, }); myRoutes["/path"].get(); myRoutes["/path"].post(); myRoutes["/path"].put(); myRoutes["/path"].delete(); // => All resolve to "/path" ``` -------------------------------- ### Mocking inherited parameters Source: https://github.com/ykicchan/routopia/blob/main/README.md Illustrates how the mock method inherits parameters from endpoint definitions versus specific HTTP method definitions. ```ts import { routes, type } from 'routopia'; const myRoutes = routes({ "/path": { get: { queries: { a: type as string, b: type as string } }, post: { queries: { b: type as number, c: type as number } } } }); Parameters<(typeof myRoutes)["/path"]["mock"]> // ^? [{ // queries?: { // a?: string | number | boolean | string[]...; // b?: string | number | boolean | string[]...; // c?: string | number | boolean | string[]...; // } // }] Parameters<(typeof myRoutes)["/path"]["get"]["mock"]> // ^? [{ // queries?: { // a?: string | number | boolean | string[]...; // b?: string | number | boolean | string[]...; // } // }] Parameters<(typeof myRoutes)["/path"]["post"]["mock"]> // ^? [{ // queries?: { // b?: string | number | boolean | string[]...; // c?: string | number | boolean | string[]...; // } // }] ``` -------------------------------- ### Define Routes Source: https://github.com/ykicchan/routopia/blob/main/README.md Define application routes using the routes function with path parameters and query types. ```ts import { routes, empty, type } from 'routopia'; export const myRoutes = routes({ "/users": { get: empty, post: empty, }, "/path/[id]": { get: { params: { id: type as number, }, queries: { q: type as string | undefined, }, }, }, }); ``` -------------------------------- ### Define URL Hash Source: https://github.com/ykicchan/routopia/blob/main/README.md Use the 'hash' key to define URL fragments. The hash is always omittable. ```ts import { routes, type } from 'routopia'; const myRoutes = routes({ "/path": { get: { hash: type as "anchor1" | "anchor2", }, }, "/any": { get: { hash: type as string, }, }, }); myRoutes["/path"].get({ hash: "anchor1" }); // => "/path#anchor1" myRoutes["/path"].get({ hash: "unknown" }); // ^^^^^ // Error: Type '"unknown"' is not assignable to type '"anchor1" | "anchor2"'. myRoutes["/any"].get({ hash: "unknown" }); // => "/any#unknown" myRoutes["/path"].get(); // => "/path" ``` -------------------------------- ### Define Query Parameters Source: https://github.com/ykicchan/routopia/blob/main/README.md Define required and optional query parameters using the 'queries' object. Including 'undefined' in the type definition makes the parameter optional. ```ts import { routes, type } from 'routopia'; const myRoutes = routes({ "/required": { get: { queries: { str: type as string, num: type as number, bool: type as boolean, arr: type as string[], opt: type as string | undefined, }, }, }, "/optional": { get: { queries: { str: type as string | undefined, num: type as number | undefined, bool: type as boolean | undefined, arr: type as string[] | undefined, }, }, }, }); myRoutes["/required"].get({ queries: { str: "abc", num: 123, bool: true, arr: ["a", "b", "c"] }, }); // => "/required?arr=a&arr=b&arr=c&bool=true&num=123&str=abc" myRoutes["/required"].get(); // ^^^ // Error: Cannot be omitted if there are required query parameters. myRoutes["/optional"].get(); // => "/optional" ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.