{"id":28249093,"url":"https://github.com/izzyjs/route","last_synced_at":"2025-09-11T18:50:16.074Z","repository":{"id":237812185,"uuid":"795188146","full_name":"izzyjs/route","owner":"izzyjs","description":"Use your AdonisJs routes in your Inertia.js application","archived":false,"fork":false,"pushed_at":"2025-09-03T19:14:31.000Z","size":235,"stargazers_count":32,"open_issues_count":0,"forks_count":2,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-09-03T21:19:45.701Z","etag":null,"topics":["adonisjs","inertiajs","javascript","nodejs","typescript","ziggy"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/@izzyjs/route","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/izzyjs.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":".github/CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":".github/CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-05-02T18:52:59.000Z","updated_at":"2025-09-03T19:14:34.000Z","dependencies_parsed_at":"2025-09-03T21:11:32.994Z","dependency_job_id":"7b33b9a1-8f84-4a00-9406-a3a91dd4dcd9","html_url":"https://github.com/izzyjs/route","commit_stats":null,"previous_names":["izzyjs/route"],"tags_count":16,"template":false,"template_full_name":null,"purl":"pkg:github/izzyjs/route","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/izzyjs%2Froute","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/izzyjs%2Froute/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/izzyjs%2Froute/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/izzyjs%2Froute/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/izzyjs","download_url":"https://codeload.github.com/izzyjs/route/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/izzyjs%2Froute/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":274690022,"owners_count":25331898,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-11T02:00:13.660Z","response_time":74,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["adonisjs","inertiajs","javascript","nodejs","typescript","ziggy"],"created_at":"2025-05-19T13:14:08.882Z","updated_at":"2025-09-11T18:50:15.938Z","avatar_url":"https://github.com/izzyjs.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# @izzyjs/route\n\n[![GitHub Actions Status](https://img.shields.io/github/actions/workflow/status/izzyjs/route/test.yml?branch=main\u0026style=flat)](https://github.com/izzyjs/route/actions?query=workflow:Tests+branch:main)\n[![Coverage Status](https://coveralls.io/repos/github/izzyjs/route/badge.svg?branch=main)](https://coveralls.io/github/izzyjs/route?branch=main)\n[![GitHub issues](https://img.shields.io/github/issues/izzyjs/route)](https://github.com/izzyjs/route/issues)\n[![GitHub pull requests](https://img.shields.io/github/issues-pr/izzyjs/route)](https://github.com/izzyjs/route/pulls)\n[![npm version](https://badge.fury.io/js/%40izzyjs%2Froute.svg)](https://badge.fury.io/js/%40izzyjs%2Froute)\n[![License](https://img.shields.io/github/license/izzyjs/route)](https://img.shields.io/github/license/izzyjs/route)\n\n**_Use your AdonisJs routes in JavaScript with advanced HTTP client capabilities._**\n\nThis package provides a JavaScript `route()` function and a powerful `builder` for generating URLs and making HTTP requests to named routes defined in an AdonisJs application. Features include hash fragments, query parameters, optional parameters, TypeScript support, and automatic CSRF protection.\n\n## Key Features\n\n- 🚀 **Route Generation** - Generate URLs for named AdonisJs routes\n- 🔗 **Hash Fragments** - Support for hash fragments (`/path#section`)\n- 🌐 **Complete URLs** - Generate full URLs with protocol and domain\n- 🔧 **Builder API** - Fluent API for HTTP requests with TypeScript support\n- 🛡️ **CSRF Protection** - Automatic CSRF token handling\n- 📝 **TypeScript** - Full TypeScript support with type inference\n- 🎯 **Query Parameters** - Easy query parameter management\n- 🔄 **HTTP Methods** - Support for GET, POST, PUT, DELETE, PATCH\n- ⚡ **Error Handling** - Global error handling and response management\n- 🎨 **Route Filtering** - Filter routes by patterns or groups\n- 🔀 **Optional Parameters** - Support for both required and optional route parameters\n\n## Quick Start\n\n\u003e **ℹ️ Note**: The `baseUrl` is **mandatory** in your `config/izzyjs.ts` file and will always be available for complete URLs.\n\n```javascript\nimport { route } from '@izzyjs/route/client'\nimport builder from '@izzyjs/route/builder'\n\n// Generate URLs with required parameters\nconst userUrl = route('users.show', { params: { id: '123' } })\nconsole.log(userUrl.path) // \"/users/123\"\nconsole.log(userUrl.url) // \"https://example.com/users/123\" (requires baseUrl config)\n\n// Generate URLs with optional parameters\nconst postsUrl = route('posts.index', { params: { category: 'tech' } })\nconsole.log(postsUrl.path) // \"/posts/tech\"\n\n// Optional parameters can be omitted\nconst allPostsUrl = route('posts.index')\nconsole.log(allPostsUrl.path) // \"/posts\"\n\n// With hash fragments\nconst homeWithHash = route('home', { hash: 'contact' })\nconsole.log(homeWithHash.path) // \"/#contact\"\n\n// Make HTTP requests\nconst result = await builder('users.show', { id: '123' })\n  .withQs({ include: 'profile' })\n  .withHash('details')\n  .request()\n  .successType\u003cUserResponse\u003e()\n  .run()\n\nif (result.data) {\n  console.log('User:', result.data)\n}\n```\n\n## Installation\n\n### Recommended (automatic)\n\nThe following command will install and configure everything automatically (provider, middleware, Japa plugin, config file `config/izzyjs.ts`, and route generation):\n\n```bash\nnode ace add @izzyjs/route\n```\n\n### Manual (step-by-step)\n\nIf you prefer manual setup, install the package with your package manager and then run the configure hook:\n\n```bash\n# npm\nnpm install @izzyjs/route\n\n# yarn\nyarn add @izzyjs/route\n\n# pnpm\npnpm add @izzyjs/route\n\n# then configure\nnode ace configure @izzyjs/route\n```\n\nThe configure step will generate `config/izzyjs.ts`, register the provider/middleware/Japa plugin, and trigger an initial routes generation.\n\n## Configuration\n\nTo use the `route()` function in your JavaScript applications, you need to follow these steps:\n\n### Command\n\nYou can run a command to generate the route definitions from @izzyjs/routes with:\n\n```bash\nnode ace izzy:routes\n```\n\nThese type definitions are only needed in a development environment, so they can be generated automatically in the next step.\n\n### Assemble Hook\n\nAdd the following line to the `adonisrc.ts` file to register the `() =\u003e import('@izzyjs/route/dev_hook')` on `onDevServerStarted` array list.\n\n```javascript\n{\n  // rest of adonisrc.ts file\n  unstable_assembler: {\n    onBuildStarting: [() =\u003e import('@adonisjs/vite/build_hook')],\n    onDevServerStarted: [() =\u003e import('@izzyjs/route/dev_hook')] // Add this line,\n  }\n}\n```\n\n### View Helper\n\nAdd edge plugin in entry view file `@routes` to use the `route()` into javascript.\n\n```html\n// resources/views/inertia_layout.edge\n\n\u003c!doctype html\u003e\n\u003chtml\u003e\n  \u003chead\u003e\n    // rest of the file @routes() // Add this line // rest of the file\n  \u003c/head\u003e\n\n  \u003cbody\u003e\n    @inertia()\n  \u003c/body\u003e\n\u003c/html\u003e\n```\n\n### Route Filtering\n\n@izzyjs/route supports filtering the list of routes it outputs, which is useful if you have certain routes that you don't want to be included and visible in your HTML source.\n\n**Important**: Hiding routes from the output is not a replacement for thorough authentication and authorization. Routes that should not be accessible publicly should be protected by authentication whether they're filtered out or not.\n\n#### Including/Excluding Routes\n\nTo set up route filtering, create a config file in your app at `config/izzyjs.ts` and add either an `only` or `except` key containing an array of route name patterns.\n\n**Note**: You have to choose one or the other. Setting both `only` and `except` will disable filtering altogether and return all named routes.\n\n```typescript\n// config/izzyjs.ts\nimport { defineConfig } from '@izzyjs/route'\n\nexport default defineConfig({\n  baseUrl: 'https://example.com', // ⚠️ MANDATORY - Required for complete URLs\n\n  routes: {\n    // Include only specific routes\n    only: ['home', 'posts.index', 'posts.show'],\n\n    // OR exclude specific routes\n    // except: ['_debugbar.*', 'horizon.*', 'admin.*'],\n  },\n})\n```\n\nYou can use asterisks as wildcards in route filters. In the example below, `admin.*` will exclude routes named `admin.login`, `admin.register`, etc.:\n\n```typescript\n// config/izzyjs.ts\nimport { defineConfig } from '@izzyjs/route'\n\nexport default defineConfig({\n  baseUrl: 'https://example.com',\n\n  routes: {\n    except: ['_debugbar.*', 'horizon.*', 'admin.*'],\n  },\n})\n```\n\n#### Filtering with Groups\n\nYou can also define groups of routes that you want to make available in different places in your app, using a `groups` key in your config file:\n\n```typescript\n// config/izzyjs.ts\nimport { defineConfig } from '@izzyjs/route'\n\nexport default defineConfig({\n  baseUrl: 'https://example.com',\n\n  routes: {\n    groups: {\n      admin: ['admin.*', 'users.*'],\n      author: ['posts.*'],\n      public: ['home', 'about', 'contact'],\n    },\n  },\n})\n```\n\n### Complete URLs\n\nThe `baseUrl` is **mandatory** in your `defineConfig`. When configured, the `route()` function automatically generates complete URLs with protocol, domain, and path. This is useful for:\n\n- External links and redirects\n- API calls to different domains\n- Email templates and notifications\n- Webhook URLs\n- Cross-domain requests\n\n```typescript\n// config/izzyjs.ts\nimport { defineConfig } from '@izzyjs/route'\n\nexport default defineConfig({\n  baseUrl: 'https://api.example.com',\n  routes: {\n    except: ['admin.*'],\n  },\n})\n```\n\nNow when you use the `route()` function, you get both the path and complete URL:\n\n```javascript\nimport { route } from '@izzyjs/route/client'\n\nconst userRoute = route('users.show', { id: '123' })\n\nconsole.log(userRoute.path) // \"/users/123\"\nconsole.log(userRoute.url) // \"https://api.example.com/users/123\"\n\n// Use url for external requests\nfetch(userRoute.url)\nwindow.open(userRoute.url)\n```\n\nThe `baseUrl` can include:\n\n- Protocol: `http://` or `https://`\n- Domain: `example.com` or `api.example.com`\n- Port: `localhost:8080`\n- Subdomain: `admin.example.com`\n\nIf the `baseUrl` is invalid or not configured, `url` falls back to just the path.\n\n#### Domain-Specific URLs\n\nWhen your routes have different domains (not just 'root'), the system automatically uses the route's specific domain instead of the `baseUrl.host`:\n\n```typescript\n// config/izzyjs.ts\nexport default defineConfig({\n  baseUrl: 'https://example.com', // Protocol will be extracted from this\n  routes: { ... }\n})\n\n// Routes with different domains\nconst homeRoute = route('home')           // domain: 'root'\nconst apiRoute = route('api.users.index') // domain: 'api.example.com'\nconst adminRoute = route('admin.dashboard') // domain: 'admin.example.com'\n\nconsole.log(homeRoute.url)   // \"https://example.com/\" (uses baseUrl.host)\nconsole.log(apiRoute.url)    // \"https://api.example.com/users\" (uses route domain)\nconsole.log(adminRoute.url)  // \"https://admin.example.com/dashboard\" (uses route domain)\n```\n\nThis is useful for multi-domain applications where different routes need to point to different subdomains or domains.\n\nWhen groups are configured, they will be available in your generated routes:\n\n```javascript\nimport { routes, groups } from '@izzyjs/route/client'\n\n// Access all routes\nconsole.log(routes)\n\n// Access specific groups\nconsole.log(groups.admin) // Admin routes only\nconsole.log(groups.author) // Author routes only\nconsole.log(groups.public) // Public routes only\n```\n\n## Usage\n\nNow that we've followed all the steps, we're ready to use `route()` on the client side to generate URLs for named routes.\n\n```javascript\nimport { route } from '@izzyjs/route/client'\n\nconst url = route('users.show', { params: { id: '1' } }) // /users/1\n```\n\n### Route\n\nIs a callback class with a parameter for route(), with information about the method, pattern and path itself.\n\n#### API Options\n\nThe `route()` function accepts an options object with the following properties:\n\n- **`params`** - Route parameters (required for routes with parameters)\n- **`qs`** - Query string parameters\n- **`prefix`** - Route prefix\n- **`hash`** - Hash fragment\n\n```javascript\nimport { route } from '@izzyjs/route/client'\n\n// Basic usage\nconst url = route('users.show', { params: { id: '1' } }) // /users/1\n\n// With all options\nconst fullUrl = route('users.show', {\n  params: { id: '1' },\n  qs: { page: '2' },\n  prefix: '/api/v1',\n  hash: 'profile',\n})\n\nurl.method // GET\nurl.pattern // /users/:id\nurl.path // /users/1\nurl.url // \"https://example.com/users/1\" (when baseUrl is configured)\nurl.qs // URLSearchParams object\nurl.hash // hash fragment (if provided)\n```\n\n#### Route Object Properties\n\nThe `route` object also provides additional methods:\n\n```javascript\nimport { route } from '@izzyjs/route/client'\n\n// Check current route\nroute().current() // Returns current route path\nroute().current('users.show', { id: '1' }) // Check if current route matches\n\n// Create new Route instance (alternative to route function)\nroute.new('users.show', { id: '1' }, { page: '2' }, '/api', 'profile')\n\n// Access builder for HTTP requests\nroute.builder('users.show', { id: '1' }).withQs({ page: '2' }).request()\n```\n\n#### Route Parameters (Required and Optional)\n\nThe `route()` function supports both required and optional parameters. The system automatically detects parameter types based on your AdonisJs route definitions:\n\n**Required Parameters:**\n\n```javascript\n// AdonisJs route: router.get('/users/:id', controller).as('users.show')\nconst userUrl = route('users.show', { params: { id: '123' } })\nconsole.log(userUrl.path) // \"/users/123\"\n```\n\n**Optional Parameters:**\n\n```javascript\n// AdonisJs route: router.get('/posts/:category?', controller).as('posts.index')\nconst postsUrl = route('posts.index', { params: { category: 'tech' } })\nconsole.log(postsUrl.path) // \"/posts/tech\"\n\n// Optional parameter can be omitted\nconst allPostsUrl = route('posts.index')\nconsole.log(allPostsUrl.path) // \"/posts\"\n```\n\n**Mixed Parameters:**\n\n```javascript\n// AdonisJs route: router.get('/posts/:id/:slug?', controller).as('posts.show')\nconst postUrl = route('posts.show', {\n  params: { id: '123', slug: 'my-awesome-post' },\n})\nconsole.log(postUrl.path) // \"/posts/123/my-awesome-post\"\n\n// Optional parameter can be omitted\nconst postWithoutSlug = route('posts.show', { params: { id: '123' } })\nconsole.log(postWithoutSlug.path) // \"/posts/123\"\n```\n\n**TypeScript Support:**\nThe generated types automatically provide type safety for both required and optional parameters:\n\n```typescript\n// TypeScript will enforce required parameters\nconst userUrl = route('users.show', { params: { id: '123' } }) // ✅ Valid\nconst userUrlError = route('users.show') // ❌ TypeScript error: missing required parameter\n\n// Optional parameters are... optional!\nconst postsUrl = route('posts.index', { params: { category: 'tech' } }) // ✅ Valid\nconst allPostsUrl = route('posts.index') // ✅ Also valid - optional parameter omitted\n```\n\n**Parameter Structure:**\nThe system generates a structured parameter object with separate arrays for required and optional parameters:\n\n```typescript\n// Generated type structure\ntype RouteWithParams = {\n  readonly name: 'posts.show'\n  readonly path: '/posts/:id/:slug?'\n  readonly method: 'get'\n  readonly params: {\n    readonly required: readonly ['id']\n    readonly optional: readonly ['slug']\n  }\n  readonly domain: 'root'\n}\n```\n\nThis structure allows the `Params\u003cName\u003e` type to work correctly, providing type safety for both required and optional parameters in your route definitions.\n\n#### Hash Fragments\n\nYou can now add hash fragments to your routes for navigation to specific sections of a page:\n\n```javascript\nimport { route } from '@izzyjs/route/client'\n\n// Basic hash usage\nconst homeWithHash = route('home', { hash: 'contact' })\nconsole.log(homeWithHash.path) // \"/#contact\"\nconsole.log(homeWithHash.url) // \"https://example.com/#contact\"\nconsole.log(homeWithHash.hash) // \"contact\"\n\n// Hash with parameters\nconst userWithHash = route('users.show', {\n  params: { id: '123' },\n  hash: 'profile',\n})\nconsole.log(userWithHash.path) // \"/users/123#profile\"\nconsole.log(userWithHash.url) // \"https://example.com/users/123#profile\"\n\n// Hash with query parameters\nconst postsWithHash = route('posts.index', {\n  qs: { page: '2' },\n  hash: 'comments',\n})\nconsole.log(postsWithHash.path) // \"/posts?page=2#comments\"\nconsole.log(postsWithHash.url) // \"https://example.com/posts?page=2#comments\"\n\n// Hash with prefix\nconst apiWithHash = route('api.users.index', {\n  qs: { page: '1' },\n  prefix: '/v1',\n  hash: 'list',\n})\nconsole.log(apiWithHash.path) // \"/v1/api/users?page=1#list\"\nconsole.log(apiWithHash.url) // \"https://api.example.com/v1/users?page=1#list\"\n```\n\n#### Complete URLs\n\nThe `url` property provides complete URLs with protocol and domain, but **requires the `baseUrl` to be configured** in your `config/izzyjs.ts` file.\n\n**Important**: The `baseUrl` is **mandatory** in the `defineConfig` and will always be available.\n\n##### Configuration\n\nThe `baseUrl` is **mandatory** in your `config/izzyjs.ts` file:\n\n```typescript\n// config/izzyjs.ts\nimport { defineConfig } from '@izzyjs/route'\n\nexport default defineConfig({\n  baseUrl: process.env.APP_URL || 'http://localhost:3333',\n  // ... other config\n})\n```\n\n##### How URL Generation Works\n\nThe `url` property always returns complete URLs with protocol and domain, using the configured `baseUrl`.\n\nWhen `baseUrl` is configured, you can access the complete URL with protocol and domain:\n\n```javascript\nimport { route } from '@izzyjs/route/client'\n\nconst userRoute = route('users.show', { params: { id: '123' } })\n\n// Basic properties\nconsole.log(userRoute.path) // \"/users/123\"\nconsole.log(userRoute.url) // \"https://api.example.com/users/123\"\n\n// Use url for external requests\nfetch(userRoute.url)\nwindow.open(userRoute.url)\n\n// With query parameters\nconst postsRoute = route('posts.index', { qs: { page: '2' } })\nconsole.log(postsRoute.url) // \"https://api.example.com/posts?page=2\"\n\n// With prefix\nconst apiRoute = route('api.v1.users.index', { prefix: '/v1' })\nconsole.log(apiRoute.url) // \"https://api.example.com/v1/api/v1/users\"\n```\n\n##### Examples: With vs Without Configuration\n\n**With `baseUrl` configured:**\n\n```javascript\n// config/izzyjs.ts\nexport default defineConfig({\n  baseUrl: 'https://api.example.com',\n})\n\nconst userRoute = route('users.show', { params: { id: '123' } })\nconsole.log(userRoute.path) // \"/users/123\"\nconsole.log(userRoute.url) // \"https://api.example.com/users/123\" ✅ Complete URL\n```\n\n##### Supported `baseUrl` Formats\n\nThe `baseUrl` supports various formats:\n\n```typescript\n// config/izzyjs.ts\nexport default defineConfig({\n  // HTTP\n  baseUrl: 'http://localhost:3333',\n\n  // HTTPS\n  baseUrl: 'https://api.example.com',\n\n  // With port\n  baseUrl: 'http://localhost:8080',\n\n  // With subdomain\n  baseUrl: 'https://api.example.com',\n\n  // Using environment variable (recommended)\n  baseUrl: process.env.APP_URL || 'http://localhost:3333',\n})\n```\n\n##### Domain-Specific URLs\n\nWhen your routes have different domains (not just 'root'), the system automatically uses the route's specific domain:\n\n```typescript\n// config/izzyjs.ts\nexport default defineConfig({\n  baseUrl: 'https://example.com', // Protocol will be extracted from this\n})\n\n// Routes with different domains\nconst homeRoute = route('home') // domain: 'root'\nconst apiRoute = route('api.users.index') // domain: 'api.example.com'\nconst adminRoute = route('admin.dashboard') // domain: 'admin.example.com'\n\nconsole.log(homeRoute.url) // \"https://example.com/\" (uses baseUrl.host)\nconsole.log(apiRoute.url) // \"https://api.example.com/users\" (uses route domain)\nconsole.log(adminRoute.url) // \"https://admin.example.com/dashboard\" (uses route domain)\n```\n\n### Routes\n\nIs a callback class withoout a parameter for route(), with information about the method, partern and path itself.\n\n#### Current\n\nThe current method returns the current URL of the page or the URL of the page that the user is currently on.\n\n```javascript\nimport { route } from '@izzyjs/route/client'\n\n// current /users/1\n\nroute().current() // /users/1\nroute().current('/users/1') // true\nroute().current('/users/2') // false\nroute().current('users.*') // true\n```\n\n#### Has\n\nThe has method returns a boolean value indicating whether the named route exists in the application.\n\n```javascript\n// start/routes.ts\n\nimport router from '@adonisjs/core/services/router'\n\nconst usersConstroller = () =\u003e import('#app/controllers/users_controller')\n\nrouter.get('/users', [usersConstroller, 'index']).as('users.index')\nrouter.get('/users/:id', [usersConstroller, 'show']).as('users.show')\n```\n\n```javascript\nimport { route } from '@izzyjs/route/client'\n\nroute().has('users.show') // true\nroute().has('users.*') // true\nroute().has('dashboard') // false\n```\n\n#### Params\n\nThe params method returns the parameters of the URL of the page that the user is currently on.\n\n```javascript\nimport { route } from '@izzyjs/route/client'\n\nroute().params() // { id: '1' }\n```\n\n### Builder (Advanced HTTP Requests)\n\nThe `builder` provides a powerful, fluent API for making HTTP requests with full TypeScript support. It combines route generation with HTTP client functionality.\n\n```javascript\nimport builder from '@izzyjs/route/builder'\n\n// Basic usage - get route information\nconst route = builder('users.show', { id: '123' })\n  .withQs({ page: '1' })\n  .withHash('profile')\n  .withPrefix('/api/v1')\n  .route()\n\nconsole.log(route.path) // \"/api/v1/users/123?page=1#profile\"\nconsole.log(route.url) // \"https://example.com/api/v1/users/123?page=1#profile\"\n```\n\n#### Making HTTP Requests\n\n```javascript\nimport builder from '@izzyjs/route/builder'\n\n// GET request\nconst result = await builder('users.show', { id: '123' })\n  .withQs({ include: 'profile' })\n  .request()\n  .successType\u003cUserResponse\u003e()\n  .failedType\u003cApiError\u003e()\n  .run()\n\nif (result.data) {\n  console.log('User:', result.data)\n} else {\n  console.log('Error:', result.error)\n}\n\n// POST request with data\nconst createResult = await builder('users.store')\n  .request()\n  .successType\u003cUser\u003e()\n  .failedType\u003cValidationError\u003e()\n  .withData({ name: 'John Doe', email: 'john@example.com' })\n  .run()\n\n// PUT request\nconst updateResult = await builder('users.update', { id: '123' })\n  .request()\n  .withData({ name: 'Jane Doe' })\n  .run()\n\n// DELETE request\nconst deleteResult = await builder('users.destroy', { id: '123' })\n  .request()\n  .run()\n```\n\n#### Advanced Builder Features\n\n```javascript\n// Chain multiple modifiers\nconst result = await builder('posts.index')\n  .withQs({ category: 'tech', page: '2' })\n  .withHash('latest')\n  .withPrefix('/api/v1')\n  .request({\n    headers: { 'Authorization': 'Bearer token' },\n    timeout: 5000\n  })\n  .successType\u003cPostsResponse\u003e()\n  .failedType\u003cApiError\u003e()\n  .run()\n\n// Type-safe request data\ninterface CreateUserData {\n  name: string\n  email: string\n}\n\ninterface UserResponse {\n  id: string\n  name: string\n  email: string\n}\n\nconst result = await builder('users.store')\n  .request()\n  .successType\u003cUserResponse\u003e()\n  .failedType\u003cValidationError\u003e()\n  .withData\u003cCreateUserData\u003e({\n    name: 'John Doe',\n    email: 'john@example.com'\n  })\n  .run()\n```\n\n#### Builder Methods\n\n- **`withQs(qs)`** - Add query parameters\n- **`withHash(hash)`** - Add hash fragment\n- **`withPrefix(prefix)`** - Add route prefix\n- **`route()`** - Get the Route instance\n- **`request(config?)`** - Create RequestBuilder for HTTP requests\n- **`successType\u003cT\u003e()`** - Define success response type\n- **`failedType\u003cT\u003e()`** - Define error response type\n- **`withData\u003cT\u003e(data)`** - Add request data (POST/PUT/PATCH)\n- **`run()`** - Execute the HTTP request\n\n#### Automatic CSRF Protection\n\nThe builder automatically includes CSRF tokens from cookies:\n\n```javascript\n// CSRF token is automatically added from XSRF-TOKEN cookie\nconst result = await builder('users.store').request().withData({ name: 'John' }).run()\n```\n\n#### HTTP Client Configuration\n\nThe builder uses a built-in HTTP client with automatic CSRF protection and error handling. You can configure it per request:\n\n```javascript\n// Request configuration options\nconst result = await builder('users.show', { id: '123' })\n  .request({\n    headers: { Authorization: 'Bearer token' },\n    timeout: 5000,\n    credentials: 'include',\n  })\n  .run()\n```\n\n**Available configuration options:**\n\n- **`headers`** - Custom headers for the request\n- **`timeout`** - Request timeout in milliseconds (default: 30000)\n- **`credentials`** - Credentials policy (default: 'same-origin')\n\n**Automatic Content-Type Detection:**\n\nThe HTTP client automatically detects the appropriate `Content-Type` header based on the request body:\n\n```javascript\n// FormData - no Content-Type set (browser handles boundary)\nconst formData = new FormData()\nformData.append('file', fileInput.files[0])\nawait builder('upload').request().withData(formData).run()\n\n// File - uses file.type or 'application/octet-stream'\nconst file = new File(['content'], 'test.txt', { type: 'text/plain' })\nawait builder('upload').request().withData(file).run()\n\n// Blob - uses blob.type or 'application/octet-stream'\nconst blob = new Blob(['content'], { type: 'application/json' })\nawait builder('upload').request().withData(blob).run()\n\n// ArrayBuffer - 'application/octet-stream'\nconst buffer = new ArrayBuffer(8)\nawait builder('upload').request().withData(buffer).run()\n\n// String - 'text/plain' or 'application/json' (if valid JSON)\nawait builder('api').request().withData('{\"key\": \"value\"}').run() // JSON\nawait builder('api').request().withData('plain text').run() // text/plain\n\n// Object - 'application/json' (automatically stringified)\nawait builder('api').request().withData({ name: 'John' }).run()\n```\n\n#### Global Error Handling\n\nThe builder includes global error handling for common HTTP status codes:\n\n```javascript\n// 401 errors are automatically handled\n// CSRF tokens are automatically added from cookies\nconst result = await builder('protected.route').request().run()\n// If 401, will log warning and reject promise\n```\n\nThese features enable seamless integration of AdonisJs routing within your JavaScript applications, enhancing flexibility and maintainability. By leveraging `route()` and `builder`, you can easily manage and navigate your application routes with ease, ensuring a smooth user experience.\n\n## Contributing\n\nThank you for being interested in making this package better. We encourage everyone to help improve this project with new features, bug fixes, or performance improvements. Please take a little bit of your time to read our guide to make this process faster and easier.\n\n### Contribution Guidelines\n\nTo understand how to submit an issue, commit and create pull requests, check our [Contribution Guidelines](/.github/CONTRIBUTING.md).\n\n### Code of Conduct\n\nWe expect you to follow our [Code of Conduct](/.github/CODE_OF_CONDUCT.md). You can read it to understand what kind of behavior will and will not be tolerated.\n\n## License\n\nMIT License © [IzzyJs](https://github.com/IzzyJs)\n\n\u003cdiv align=\"center\"\u003e\n  \u003csub\u003eBuilt with ❤︎ by \u003ca href=\"https://github.com/lncitador\"\u003eWalaff Fernandes\u003c/a\u003e\n\u003c/div\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fizzyjs%2Froute","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fizzyjs%2Froute","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fizzyjs%2Froute/lists"}