{"id":18317903,"url":"https://github.com/idiocc/router","last_synced_at":"2025-04-09T13:51:16.389Z","repository":{"id":57117950,"uuid":"158018490","full_name":"idiocc/router","owner":"idiocc","description":"The Router Utility For The Idio Web Server With Automatic Initialisation And Live Reload.","archived":false,"fork":false,"pushed_at":"2020-02-26T15:44:07.000Z","size":184,"stargazers_count":1,"open_issues_count":2,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-03-16T02:17:57.673Z","etag":null,"topics":["goa","middleware","router","server"],"latest_commit_sha":null,"homepage":"https://www.idio.cc","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/idiocc.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-11-17T19:40:04.000Z","updated_at":"2020-02-26T15:44:10.000Z","dependencies_parsed_at":"2022-08-23T03:50:07.671Z","dependency_job_id":null,"html_url":"https://github.com/idiocc/router","commit_stats":null,"previous_names":[],"tags_count":11,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/idiocc%2Frouter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/idiocc%2Frouter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/idiocc%2Frouter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/idiocc%2Frouter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/idiocc","download_url":"https://codeload.github.com/idiocc/router/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248054218,"owners_count":21039951,"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","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":["goa","middleware","router","server"],"created_at":"2024-11-05T18:07:49.618Z","updated_at":"2025-04-09T13:51:16.372Z","avatar_url":"https://github.com/idiocc.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# @idio/router\n\n[![npm version](https://badge.fury.io/js/%40idio%2Frouter.svg)](https://www.npmjs.com/package/@idio/router)\n![Node.js CI](https://github.com/idiocc/router/workflows/Node.js%20CI/badge.svg)\n\n`@idio/router` Is A Router Utility For The [_Idio Web Server_](https://github.com/idiocc/idio) With Automatic Initialisation From Folders And Live Reload.\n\n```sh\nyarn add @idio/router\nnpm i @idio/router\n```\n\n## Table Of Contents\n\n- [Table Of Contents](#table-of-contents)\n- [API](#api)\n- [`async initRoutes(router, dir, config=): !WatchConfig`](#async-initroutesrouter-_goarouterdir-stringconfig-routesconfig-watchconfig)\n  * [`RoutesConfig`](#type-routesconfig)\n  * [`chainRoute(route: !Middleware): !Array\u003cstring|!Middleware\u003e`](#chainrouteroute-middleware-arraystringmiddleware)\n- [`async watchRoutes(watchConfig): !fs.FSWatcher`](#async-watchrouteswatchconfig-watchconfig-fsfswatcher)\n- [Copyright \u0026 License](#copyright--license)\n\n\u003cp align=\"center\"\u003e\u003ca href=\"#table-of-contents\"\u003e\n  \u003cimg src=\"/.documentary/section-breaks/0.svg?sanitize=true\"\u003e\n\u003c/a\u003e\u003c/p\u003e\n\n## API\n\nThe package is available by importing its default function:\n\n```js\nimport initRoutes, { watchRoutes } from '@idio/router'\n```\n\n\n\u003cp align=\"center\"\u003e\u003ca href=\"#table-of-contents\"\u003e\n  \u003cimg src=\"/.documentary/section-breaks/1.svg?sanitize=true\"\u003e\n\u003c/a\u003e\u003c/p\u003e\n\n## \u003ccode\u003easync \u003cins\u003einitRoutes\u003c/ins\u003e(\u003c/code\u003e\u003csub\u003e\u003cbr/\u003e\u0026nbsp;\u0026nbsp;`router: !_goa.Router,`\u003cbr/\u003e\u0026nbsp;\u0026nbsp;`dir: string,`\u003cbr/\u003e\u0026nbsp;\u0026nbsp;`config=: !RoutesConfig,`\u003cbr/\u003e\u003c/sub\u003e\u003ccode\u003e): \u003ci\u003e!WatchConfig\u003c/i\u003e\u003c/code\u003e\nThe `init` function will scan files in the passed `dir` folder and add routes found for each method to the router. The default `dir` is `src/routes` and the config should be passed to control how the middleware and aliases are set up for each method.\n\n - \u003ckbd\u003e\u003cstrong\u003erouter*\u003c/strong\u003e\u003c/kbd\u003e \u003cem\u003e`!_goa.Router`\u003c/em\u003e: An instance of the router.\n - \u003ckbd\u003e\u003cstrong\u003edir*\u003c/strong\u003e\u003c/kbd\u003e \u003cem\u003e`string`\u003c/em\u003e: The directory from where to init routes.\n - \u003ckbd\u003econfig\u003c/kbd\u003e \u003cem\u003e\u003ccode\u003e\u003ca href=\"#type-routesconfig\" title=\"Options for the router.\"\u003e!RoutesConfig\u003c/a\u003e\u003c/code\u003e\u003c/em\u003e (optional): Additional configuration.\n\nThere are some rules when using this method:\n\n1. Each route module should export the default function which will be initialised as the middleware.\n1. The modules can also export the `aliases` property with an array of strings that are aliases for the route (alternatively, aliases can be specified via the configuration object \u0026mdash; or when both ways are used, they are combined).\n1. The exported `middleware` property specifies any middleware chain constructor that will take precedence over the method middleware chain constructor from the config. When strings are passed, the middleware functions will be looked up in the `middleware` object returned by the `idio`'s `start` method and passed in the configuration.\n1. If the exported `middleware` property is an array, the route will be the last one in the chain call. Otherwise, exporting a middleware chain constructor as a function allows to control the order of execution.\n\n__\u003ca name=\"type-routesconfig\"\u003e`RoutesConfig`\u003c/a\u003e__: Options for the router.\n\u003ctable\u003e\n \u003cthead\u003e\u003ctr\u003e\n  \u003cth\u003eName\u003c/th\u003e\n  \u003cth\u003eType \u0026amp; Description\u003c/th\u003e\n \u003c/tr\u003e\u003c/thead\u003e\n \u003ctr\u003e\n  \u003ctd rowSpan=\"3\" align=\"center\"\u003emiddlewareConfig\u003c/td\u003e\n  \u003ctd\u003e\u003cem\u003e!Object\u0026lt;string, \u003ca href=\"#chainrouteroute-middleware-arraystringmiddleware\" title=\"Receives the route and returns an ordered array of middleware.\"\u003e!chainRoute\u003c/a\u003e\u0026gt;\u003c/em\u003e\u003c/td\u003e\n \u003c/tr\u003e\n \u003ctr\u003e\u003c/tr\u003e\n \u003ctr\u003e\n  \u003ctd\u003e\n   The method-level middleware configuration: for each method it specifies how to construct the middleware chain. If the string is found in the chain, the middleware will be looked up in the \u003ccode\u003emiddleware\u003c/code\u003e object.\n  \u003c/td\u003e\n \u003c/tr\u003e\n \u003ctr\u003e\n  \u003ctd rowSpan=\"3\" align=\"center\"\u003emiddleware\u003c/td\u003e\n  \u003ctd\u003e\u003cem\u003e\u003ca href=\"#type-configuredmiddleware\"\u003e!ConfiguredMiddleware\u003c/a\u003e\u003c/em\u003e\u003c/td\u003e\n \u003c/tr\u003e\n \u003ctr\u003e\u003c/tr\u003e\n \u003ctr\u003e\n  \u003ctd\u003e\n   The configured middleware object return by the Idio's \u003ccode\u003estart\u003c/code\u003e method.\n  \u003c/td\u003e\n \u003c/tr\u003e\n \u003ctr\u003e\n  \u003ctd rowSpan=\"3\" align=\"center\"\u003ealiases\u003c/td\u003e\n  \u003ctd\u003e\u003cem\u003e!Object\u0026lt;string, !Array\u0026lt;string\u0026gt;\u0026gt;\u003c/em\u003e\u003c/td\u003e\n \u003c/tr\u003e\n \u003ctr\u003e\u003c/tr\u003e\n \u003ctr\u003e\n  \u003ctd\u003e\n   The map of aliases. Aliases can also be specified in routes by exporting the \u003ccode\u003ealiases\u003c/code\u003e property.\n  \u003c/td\u003e\n \u003c/tr\u003e\n \u003ctr\u003e\n  \u003ctd rowSpan=\"3\" align=\"center\"\u003efilter\u003c/td\u003e\n  \u003ctd\u003e\u003cem\u003e(filename: string) =\u003e boolean\u003c/em\u003e\u003c/td\u003e\n \u003c/tr\u003e\n \u003ctr\u003e\u003c/tr\u003e\n \u003ctr\u003e\n  \u003ctd\u003e\n   The filter for filenames. Defaults to importing JS and JSX.\u003cbr/\u003e\n   \u003ckbd\u003e\u003cstrong\u003efilename*\u003c/strong\u003e\u003c/kbd\u003e \u003cem\u003e\u003ccode\u003estring\u003c/code\u003e\u003c/em\u003e: The filename.\n  \u003c/td\u003e\n \u003c/tr\u003e\n\u003c/table\u003e\n\n\nFor example, we can specify 1 `GET` and 1 `POST` route in the `example/routes` directory:\n\n```m\nexample/routes\n├── get\n│   └── index.js\n└── post\n    └── example.js\n```\n\n*example/routes/get/index.js*\n```js\nexport default async (ctx) =\u003e {\n  const { test } = ctx\n  ctx.body = `example get response: ${test}`\n}\n\nexport const aliases = ['/']\n\n// The router util will lookup the middleware by its name.\n// The constructor is used to control the order.\nexport const middleware = (route) =\u003e {\n  return ['example', route]\n}\n\n// Another way to write middleware is to use a plain array.\n/* export const middleware = ['example'] */\n```\n*example/routes/post/example.js*\n```js\nexport default async (ctx) =\u003e {\n  const { message } = ctx.request.body\n  ctx.body = `example post response: ${message}`\n}\n\n// The aliases exported in the module will extend\n// the ones specified in the config\nexport const aliases = ['/']\n```\n\nThen the router can be automatically configured.\n\n```js\nimport core from '@idio/idio'\nimport initRoutes from '@idio/router'\n\nconst Server = async () =\u003e {\n  const { app, url, router, middleware } = await core({\n    bodyparser: {\n      middlewareConstructor() {\n        return async (ctx, next) =\u003e {\n          const data = await collect(ctx.req)\n          ctx.req.body = JSON.parse(data)\n          ctx.request.body = JSON.parse(data)\n          await next()\n        }\n      },\n    },\n    example: {\n      middlewareConstructor() {\n        return async (ctx, next) =\u003e {\n          ctx.test = 'test'\n          await next()\n        }\n      },\n    },\n  })\n  await initRoutes(router, 'example/routes', {\n    middlewareConfig: {\n      post(route) {\n        return ['bodyparser', route]\n      },\n    },\n    aliases: {\n      post: {\n        '/example': ['/example.html'],\n      },\n    },\n    middleware,\n  })\n  app.use(router.routes())\n  return { app, url }\n}\n```\n```\nhttp://localhost:5000\nGET /\n :: example get response: test\nPOST \"hello world\" \u003e / \n :: example post response: hello world\n```\n\n### \u003ccode\u003e\u003cins\u003echainRoute\u003c/ins\u003e(\u003c/code\u003e\u003csub\u003e\u003cbr/\u003e\u0026nbsp;\u0026nbsp;`route: !Middleware,`\u003cbr/\u003e\u003c/sub\u003e\u003ccode\u003e): \u003ci\u003e!Array\u003cstring|!Middleware\u003e\u003c/i\u003e\u003c/code\u003e\nReceives the route and returns an ordered array of middleware.\n\n - \u003ckbd\u003e\u003cstrong\u003eroute*\u003c/strong\u003e\u003c/kbd\u003e \u003cem\u003e\u003ccode\u003e\u003ca href=\"https://github.com/idiocc/idio/wiki/Home#middlewarectx-contextnext-function-promisevoid\" title=\"The function to handle requests which can be installed with the `.use` method.\"\u003e!Middleware\u003c/a\u003e\u003c/code\u003e\u003c/em\u003e: The route.\n\n\u003cp align=\"center\"\u003e\u003ca href=\"#table-of-contents\"\u003e\n  \u003cimg src=\"/.documentary/section-breaks/2.svg?sanitize=true\"\u003e\n\u003c/a\u003e\u003c/p\u003e\n\n## \u003ccode\u003easync \u003cins\u003ewatchRoutes\u003c/ins\u003e(\u003c/code\u003e\u003csub\u003e\u003cbr/\u003e\u0026nbsp;\u0026nbsp;`watchConfig: !WatchConfig,`\u003cbr/\u003e\u003c/sub\u003e\u003ccode\u003e): \u003ci\u003e!fs.FSWatcher\u003c/i\u003e\u003c/code\u003e\nAfter the routes were initialised, it is possible to pass the value returned by the `initRoutes` method to the `watchRoutes` function to enable hot-route reload on the development environment. Every change to the module source code will trigger an update of the route including its aliases. *The middleware and aliases changes are not currently implemented.*\n\n - \u003ckbd\u003e\u003cstrong\u003ewatchConfig*\u003c/strong\u003e\u003c/kbd\u003e \u003cem\u003e`!WatchConfig`\u003c/em\u003e: The watch config returned by the `initRoutes` method.\n\n```js\nimport idio from '@idio/idio'\nimport initRoutes, { watchRoutes } from '@idio/router'\n\nconst Server = async () =\u003e {\n  const { app, url, router } = await idio({}, { port: 5001 })\n  const w = await initRoutes(router, 'example/watch-routes')\n  app.use(router.routes())\n  let watcher\n  if (process.env.NODE_ENV != 'production') {\n    watcher = await watchRoutes(w)\n  }\n  return { app, url, watcher }\n}\n```\n```\nhttp://localhost:5001\nGET / RESULT:\n┌────────────────────────────────┐\n│ [initial] example get response │\n└────────────────────────────────┘\nUpdate routes/get/index.js\n⌁ example/watch-routes/get/index.js\n.\u003e hot reloaded GET /index /\nGET / RESULT:\n┌────────────────────────────────┐\n│ [updated] example get response │\n└────────────────────────────────┘\n```\n\n\u003cp align=\"center\"\u003e\u003ca href=\"#table-of-contents\"\u003e\n  \u003cimg src=\"/.documentary/section-breaks/3.svg?sanitize=true\"\u003e\n\u003c/a\u003e\u003c/p\u003e\n\n## Copyright \u0026 License\n\nGNU Affero General Public License v3.0\n\n\u003ctable\u003e\n  \u003ctr\u003e\n    \u003cth\u003e\n      \u003ca href=\"https://www.artd.eco\"\u003e\n        \u003cimg width=\"100\" src=\"https://raw.githubusercontent.com/wrote/wrote/master/images/artdeco.png\"\n          alt=\"Art Deco\"\u003e\n      \u003c/a\u003e\n    \u003c/th\u003e\n    \u003cth\u003e© \u003ca href=\"https://www.artd.eco\"\u003eArt Deco™\u003c/a\u003e for \u003ca href=\"https://idio.cc\"\u003eIdio\u003c/a\u003e 2020\u003c/th\u003e\n    \u003cth\u003e\n      \u003ca href=\"https://idio.cc\"\u003e\n        \u003cimg src=\"https://avatars3.githubusercontent.com/u/40834161?s=100\" width=\"100\" alt=\"Idio\"\u003e\n      \u003c/a\u003e\n    \u003c/th\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\n\u003cp align=\"center\"\u003e\u003ca href=\"#table-of-contents\"\u003e\n  \u003cimg src=\"/.documentary/section-breaks/-1.svg?sanitize=true\"\u003e\n\u003c/a\u003e\u003c/p\u003e","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fidiocc%2Frouter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fidiocc%2Frouter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fidiocc%2Frouter/lists"}