{"id":19475470,"url":"https://github.com/artdecocode/idio","last_synced_at":"2026-04-18T12:32:55.053Z","repository":{"id":57271243,"uuid":"102633932","full_name":"artdecocode/idio","owner":"artdecocode","description":"A web-server in koa2 with MongoDB connection, automatic routes initialisation and hot route reload™","archived":false,"fork":false,"pushed_at":"2018-06-05T22:37:40.000Z","size":347,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-10-19T10:45:52.166Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://idio.cc","language":"JavaScript","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/artdecocode.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":"2017-09-06T16:46:29.000Z","updated_at":"2018-06-05T22:37:21.000Z","dependencies_parsed_at":"2022-09-01T00:22:06.537Z","dependency_job_id":null,"html_url":"https://github.com/artdecocode/idio","commit_stats":null,"previous_names":["sobesednik/idio"],"tags_count":16,"template":false,"template_full_name":null,"purl":"pkg:github/artdecocode/idio","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/artdecocode%2Fidio","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/artdecocode%2Fidio/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/artdecocode%2Fidio/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/artdecocode%2Fidio/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/artdecocode","download_url":"https://codeload.github.com/artdecocode/idio/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/artdecocode%2Fidio/sbom","scorecard":{"id":208891,"data":{"date":"2025-08-11","repo":{"name":"github.com/artdecocode/idio","commit":"6fbf9bbd63eafe609e550532801ea33910ff95c7"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":1.4,"checks":[{"name":"Code-Review","score":0,"reason":"Found 0/30 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"SAST","score":0,"reason":"no SAST tool detected","details":["Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Signed-Releases","score":0,"reason":"Project has not signed or included provenance with any releases.","details":["Warn: release artifact v2.5.1 not signed: https://api.github.com/repos/artdecocode/idio/releases/11075518","Warn: release artifact v2.5.1 does not have provenance: https://api.github.com/repos/artdecocode/idio/releases/11075518"],"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: containerImage not pinned by hash: Dockerfile:1: pin your Docker image by updating node:alpine to node:alpine@sha256:e8e882c692a08878d55ec8ff6c5a4a71b3edca25eda0af4406e2a160d8a93cf2","Warn: npmCommand not pinned by hash: Dockerfile:4","Warn: npmCommand not pinned by hash: Dockerfile:8","Info:   0 out of   2 npmCommand dependencies pinned","Info:   0 out of   1 containerImage dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Vulnerabilities","score":0,"reason":"78 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-968p-4wvh-cqc8","Warn: Project is vulnerable to: GHSA-67hx-6x53-jw92","Warn: Project is vulnerable to: GHSA-6chw-6frg-f759","Warn: Project is vulnerable to: GHSA-v88g-cgmw-v5xw","Warn: Project is vulnerable to: GHSA-93q8-gq69-wqmw","Warn: Project is vulnerable to: GHSA-fwr7-v2mv-hh25","Warn: Project is vulnerable to: GHSA-v6h2-p8h4-qcjw","Warn: Project is vulnerable to: GHSA-cwfw-4gq5-mrqx","Warn: Project is vulnerable to: GHSA-g95f-p29q-9xw4","Warn: Project is vulnerable to: GHSA-grv7-fg5c-xmjg","Warn: Project is vulnerable to: GHSA-4jwp-vfvf-657p","Warn: Project is vulnerable to: GHSA-v8w9-2789-6hhr","Warn: Project is vulnerable to: GHSA-c6rq-rjc2-86v2","Warn: Project is vulnerable to: GHSA-3xgq-45jj-v275","Warn: Project is vulnerable to: GHSA-w573-4hg7-7wgq","Warn: Project is vulnerable to: GHSA-hr2v-3952-633q","Warn: Project is vulnerable to: GHSA-wm7h-9275-46v2","Warn: Project is vulnerable to: GHSA-8r6j-v8pm-fqw3","Warn: Project is vulnerable to: MAL-2023-462","Warn: Project is vulnerable to: GHSA-qqgx-2p2h-9c37","Warn: Project is vulnerable to: GHSA-2pr6-76vf-7546","Warn: Project is vulnerable to: GHSA-8j8c-7jfh-h6hx","Warn: Project is vulnerable to: GHSA-9c47-m6qq-7p4h","Warn: Project is vulnerable to: GHSA-6c8f-qphg-qjgp","Warn: Project is vulnerable to: GHSA-593f-38f6-jp5m","Warn: Project is vulnerable to: GHSA-x2rg-q646-7m2v","Warn: Project is vulnerable to: GHSA-jgmv-j7ww-jx2x","Warn: Project is vulnerable to: GHSA-4xc9-xhrj-v574","Warn: Project is vulnerable to: GHSA-x5rq-j2xg-h7qm","Warn: Project is vulnerable to: GHSA-jf85-cpcp-j695","Warn: Project is vulnerable to: GHSA-p6mc-m468-83gw","Warn: Project is vulnerable to: GHSA-29mw-wpgm-hmr9","Warn: Project is vulnerable to: GHSA-35jh-r3h4-6jhm","Warn: Project is vulnerable to: GHSA-952p-6rrq-rcjv","Warn: Project is vulnerable to: GHSA-f8q6-p94x-37v3","Warn: Project is vulnerable to: GHSA-vh95-rmgr-6w4m","Warn: Project is vulnerable to: GHSA-xvch-5gv4-984h","Warn: Project is vulnerable to: GHSA-fhjf-83wg-r2j9","Warn: Project is vulnerable to: GHSA-mh5c-679w-hh4r","Warn: Project is vulnerable to: GHSA-8687-vv9j-hgph","Warn: Project is vulnerable to: GHSA-f825-f98c-gj3g","Warn: Project is vulnerable to: GHSA-h8hf-x3f4-xwgp","Warn: Project is vulnerable to: GHSA-9m93-w8w6-76hh","Warn: Project is vulnerable to: GHSA-m7xq-9374-9rvx","Warn: Project is vulnerable to: GHSA-vg7j-7cwx-8wgw","Warn: Project is vulnerable to: GHSA-h466-j336-74wx","Warn: Project is vulnerable to: GHSA-p92x-r36w-9395","Warn: Project is vulnerable to: GHSA-45q2-34rf-mr94","Warn: Project is vulnerable to: GHSA-44fp-w29j-9vj5","Warn: Project is vulnerable to: GHSA-r683-j2x4-v87g","Warn: Project is vulnerable to: GHSA-hj48-42vr-x3v9","Warn: Project is vulnerable to: GHSA-9wv6-86v2-598j","Warn: Project is vulnerable to: GHSA-hrpp-h998-j3pp","Warn: Project is vulnerable to: GHSA-6g33-f262-xjp4","Warn: Project is vulnerable to: GHSA-mvjj-gqq2-p4hw","Warn: Project is vulnerable to: GHSA-c2qf-rxjj-qqgw","Warn: Project is vulnerable to: GHSA-4g88-fppr-53pp","Warn: Project is vulnerable to: GHSA-4jqc-8m5r-9rpr","Warn: Project is vulnerable to: GHSA-3jfq-g458-7qm9","Warn: Project is vulnerable to: GHSA-r628-mhmh-qjhw","Warn: Project is vulnerable to: GHSA-9r2w-394v-53qc","Warn: Project is vulnerable to: GHSA-5955-9wpr-37jh","Warn: Project is vulnerable to: GHSA-qq89-hq3f-393p","Warn: Project is vulnerable to: GHSA-f5x3-32g6-xq36","Warn: Project is vulnerable to: GHSA-29xr-v42j-r956","Warn: Project is vulnerable to: GHSA-52f5-9888-hmc6","Warn: Project is vulnerable to: GHSA-662x-fhqg-9p8v","Warn: Project is vulnerable to: GHSA-394c-5j6w-4xmx","Warn: Project is vulnerable to: GHSA-78cj-fxph-m83p","Warn: Project is vulnerable to: GHSA-fhg7-m89q-25r3","Warn: Project is vulnerable to: GHSA-3329-pjwv-fjpg","Warn: Project is vulnerable to: GHSA-p6j9-7xhc-rhwp","Warn: Project is vulnerable to: GHSA-89gv-h8wf-cg8r","Warn: Project is vulnerable to: GHSA-gcv8-gh4r-25x6","Warn: Project is vulnerable to: GHSA-gmv4-r438-p67f","Warn: Project is vulnerable to: GHSA-8h2f-7jc4-7m3m","Warn: Project is vulnerable to: GHSA-3vjf-82ff-p4r3","Warn: Project is vulnerable to: GHSA-g694-m8vq-gv9h"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-17T00:21:11.627Z","repository_id":57271243,"created_at":"2025-08-17T00:21:11.627Z","updated_at":"2025-08-17T00:21:11.627Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31969695,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-18T00:39:45.007Z","status":"online","status_checked_at":"2026-04-18T02:00:07.018Z","response_time":103,"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":[],"created_at":"2024-11-10T19:33:01.120Z","updated_at":"2026-04-18T12:32:55.035Z","avatar_url":"https://github.com/artdecocode.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# idio\n\n[![npm version](https://badge.fury.io/js/idio.svg)](https://badge.fury.io/js/idio)\n\n```\nyarn add -E idio\n```\n\n`idio` is a koa2-based web server with some pre-installed middleware and Mongo support out of the box. Its purpose is to be able to quickly create a server with basic functionality. It also supports automatic initialisation of routes from a given directory, and watching those routes for updates (with `idio-dev`). This means that the whole server does not need to restart when a single route changes.\n\n## Example\n\n```js\n/* yarn example */\nimport idio from 'idio'\nimport config, { routesConfig } from './config'\n\n(async () =\u003e {\n  try {\n    const { url } = await idio(config, routesConfig)\n    console.log(url) // eslint-disable-line\n  } catch ({ stack }) {\n    console.log(stack) // eslint-disable-line\n    process.exit(1)\n  }\n})()\n```\n\n```sh\nhttp://localhost:5000\n```\n\n## `idio(config, routesConfig?)`\n\nIdio accepts 2 arguments: the config and optional routes config to read routes from directories.\n\n## Configuration\n\nThe server can be configured using the following structure.\n\n| property    | default                    | description                                              |\n|-------------|----------------------------|----------------------------------------------------------|\n| databaseURL | mongodb:// localhost: 27017 | MongoDB connection string.                               |\n| port        | 5000                       | Web server port.                                         |\n| host        | 0.0.0.0                    | Web server host.                                         |\n| autoConnect | true                       | Whether to automatically connect to the database server. |\n| middleware  |                            | Middleware configuration.                                |\n\n```js\nimport { resolve } from 'path'\n\nconst uploadDir = resolve(__dirname, 'upload')\nconst routesDir = resolve(__dirname, 'routes')\n\nconst DATABASE_URL = process.env.DATABASE_URL || 'mongodb://localhost:27017/idio'\nconst PORT = process.env.PORT || 5000\n\nexport default {\n  databaseURL: DATABASE_URL,\n  port: PORT,\n  middleware: {\n    session: { keys: ['secret-key'] },\n    multer: { config: { dest: uploadDir } },\n    csrf: { },\n    bodyparser: { },\n    checkauth: { },\n    logger: { use: true },\n    koa2Jsx: { use: true, wireframe: true /*, bootstrap: true */ },\n    // ---- custom middleware\n    ip: {\n      function(app, config) {\n        return async (ctx, next) =\u003e {\n          console.log(`${config.text}: ${ctx.request.ip}`)\n          await next()\n        }\n      },\n      config: { text: 'ip' },\n      use: true,\n    },\n  },\n}\n```\n\n### Middleware Configuration\n\n`idio` can instantiate some known middleware shipped with it, as well as additionally specified middleware. Each `middleware` property accepts the following properties:\n\n| property | description                                                                   | default |\n|----------|-------------------------------------------------------------------------------|---------|\n| use      | Whether to use this middleware for every request.                             | false   |\n| config   | Configuration object expected by the middleware constructor.                  | {}      |\n| ...props | Any additional specific properties (see individual middleware configuration). |         |\n\nIt is possible to pass multiple configurations as an array for a single type of middleware, if multiple instances of it need to be created (e.g., for `static`).\n\n\u003c!-- This might not work with routes initialisation when passing getMiddleware function. --\u003e\n\n#### session\n\n[`koa-session`](https://github.com/koajs/session) for handling sessions.\n\n| property | description                                 | default | required |\n|----------|---------------------------------------------|---------|----------|\n| keys     | A set of keys to be installed in `app.keys` | -       | true     |\n| _config_     | `koa-session` configuration | {}       | -     |\n\n#### multer\n\n[`koa-multer`](https://github.com/koa-modules/multer) for file uploads.\n\n| property | description                                 | default | required |\n|----------|---------------------------------------------|---------|----------|\n| config.dest     | An upload directory which will be created on start. | -       | true     |\n| _config_     | `koa-multer` configuration | {}       | -     |\n\n#### csrf\n\n[`koa-csrf`](https://github.com/koajs/csrf) for prevention against CSRF attacks.\n\n| property | description                                 | default | required |\n|----------|---------------------------------------------|---------|----------|\n| _config_     | `koa-csrf` configuration | {}       | -     |\n\n#### bodyparser\n\n[`koa-bodyparser`](https://github.com/koajs/body-parser) to parse data sent to the server.\n\n| property | description                                 | default | required |\n|----------|---------------------------------------------|---------|----------|\n| _config_     | `koa-bodyparser` configuration | {}       | -     |\n\n#### checkauth\n\nA simple middleware which throws if `ctx.session.user` is not set.\n\n#### logger\n\n[`koa-logger`](https://github.com/koajs/logger) to log requests.\n\n| property | description                                 | default | required |\n|----------|---------------------------------------------|---------|----------|\n| _config_     | `koa-logger` configuration | {}       | -     |\n\n#### compress\n\n[`koa-compress`](https://github.com/koajs/compress) to apply compression.\n\n| property | description                                 | default | required |\n|----------|---------------------------------------------|---------|----------|\n| threshold     | Minimum response size in bytes to compress. | 1024       | -     |\n| _config_     | `koa-compress` configuration | {}       | -     |\n\n#### koa2Jsx\n\n[`koa2-jsx`](https://github.com/artdecocode/koa2-jsx) to render JSX pages.\n\n| property | description                                 | default | required |\n|----------|---------------------------------------------|---------|----------|\n| wireframe     | Whether to use a default wireframe. | false       | -     |\n| bootstrap     | Whether to include bootstrap (when using wireframe). | false       | -     |\n| static     | Whether to use `staticNodeStreamRender` rather than `nodeStreamRender` from `react` package. It will strip `react`'s metadata required for hydration. Set to this to `false` when client-side `react` is also used. | true       | -     |\n| pretty     | Return formatted HTML (as a string and not stream, therefore slower) | false       | -     |\n| _config_     | `koa2-jsx` configuration | {}       | -     |\n\n#### static\n\n[`koa-static`](https://github.com/koajs/static) to serve static files.\n\n| property | description                                 | default | required |\n|----------|---------------------------------------------|---------|----------|\n| root     | Root directory as a string or directories as an array of strings. | -       | true     |\n| mount     | Path from which files will be served | `/`       | -     |\n| maxage     | Controls caching time. | 0       | -     |\n| _config_     | `koa-static` configuration | {}       | -     |\n\n```js\nimport { resolve, dirname } from 'path'\nimport idio from 'idio'\n\nconst STATIC = resolve(__dirname, 'static')\nconst react = resolve(dirname(require.resolve('react')), 'umd')\n\n(async () =\u003e {\n  const { url } = await idio({\n    middleware: {\n      static: {\n        use: true,\n        root: ['static', react],\n        mount: '/scripts',\n        maxage: process.env.NODE_ENV == 'production' ?  1000 * 60 * 60 * 24 * 10 : 0,\n      },\n    },\n  })\n})\n```\n\n#### Custom Middleware\n\nOther middleware can be passed as an object which has 3 properties:\n\n- _function_ - constructor function (optional). It will receive the `app` and `config` arguments and should return a middleware function\n\n```js\nconst middlewareConstructor = async (app, config) =\u003e {\n  app.context.usingFunction = true\n\n  return async(ctx, next) =\u003e {\n    await next()\n    if (config.debug) {\n        console.error(ctx.usingFunction)\n    }\n  }\n}\n```\n\n- _config_ - an object that will be passed to the middleware constructor.\n\n```js\nconst config = {\n  debug: process.env.NODE_DEBUG == 'idio',\n}\n```\n\n- _use_ - whether to always use this middleware, which will perform `app.use()` after the constructor returned the middleware.\n\nAll together, setting up a custom middleware looks like this:\n\n```js\nawait idio({\n  middleware: {\n    customMiddleware: {\n      async function(app, config) {\n        app.context.usingFunction = true\n\n        return async(ctx, next) =\u003e {\n          await next()\n          if (config.debug) {\n              console.error(ctx.usingFunction)\n          }\n        }\n      },\n      config: { debug: process.env.NODE_DEBUG == 'idio' },\n      use: true,\n    },\n  },\n})\n```\n\n## Router Configuration\n\nIn most cases, it is desirable to have a router for the application. `idio` provides a means to read files from a directory which is organised by methods (e.g., `routes/get`, `routes/post`). If the router configuration is passed to the `idio` function, the routes will be set up.\n\n| property       | default                    | description                                                                                                                           |\n|----------------|----------------------------|---------------------------------------------------------------------------------------------------------------------------------------|\n| dir            | string                     | Path to the directory where routes are found. Must have `get`, `post`, _etc_ folders inside with files which export a default module. |\n| middleware     | {}                         | A function which determines which middleware not installed with `use` is present for each method.                                     |\n| filter         | `(s) =\u003e /\\.jsx?$/.test(s)` | A function to filter included routes by filename.                                                                                     |\n| defaultImports | true                       | Whether routes are exported with ES6 `export default`.                                                                                |\n| aliases        | {}                         | A map of aliases.                                                                                                                     |\n\n```js\nexport const routesConfig = {\n  dir: routesDir,\n  defaultImports: true,\n  aliases: {\n    get: {\n      '/index': ['/'],\n    },\n  },\n  middleware: {\n    get: route =\u003e ['session', route],\n    post: route =\u003e ['bodyparser', route],\n  },\n}\n```\n\n### middleware\n\n`middleware` property determines the order and installed middleware for each method. Currently it is impossible to control the middleware for each individual route. The strings returned by this function are mapped to the middleware functions created during middleware set-up earlier using the keys from the `idio` config. All middleware specified with this method will be run after the middleware from app configuration with `use` property set to true.\n\n### aliases\n\nA map of aliases for each method, where keys are the routes, and values are arrays to which they should respond.\n\n### Routes\n\nRoutes need to be written as `async` Koa middleware and exported as a default function.\n\n```js\n/* example/routes/index.js */\nexport default async (ctx) =\u003e {\n  const n = ctx.session.views || 1\n  ctx.session.views = n + 1\n  ctx.body = `${n} views`\n}\n```\n\nWhen not using modules, `defaultImports` should be set to false, otherwise no routes will be set up.\n\n```js\n/* example/routes/index.js */\nconst fn = async (ctx) =\u003e {\n  const n = ctx.session.views || 1\n  ctx.session.views = n + 1\n  ctx.body = `${n} views`\n}\n\nmodule.exports = fn\n```\n\n## Connecting to Mongo\n\n`idio` will try to automatically connect to the Mongo database when creating a new app. To prevent this, `autoConnect` option can be set to `false`, and a `connect` property will be set on the returned object, so that a connection can be established manually. This feature is useful when no database is required for a website.\n\n```js\nconst { connect } = await idio({\n  databaseURL: 'mongodb://localhost:27017',\n  autoConnect: false,\n})\nawait connect()\n```\n\n```js\n// when no database is required\nawait idio({\n  autoConnect: false,\n})\n```\n\n## idio-dev\n\nTo separate the server from the developer environment, `idio-dev` is created. It has a method to watch routes updates to run on the server, and also allows to compile JS bundles for the browser.\n\n```\nyarn add -D -E idio\n```\n\n### Watching Bundles\n\nBundles for the client can be compiled with `idio-dev` using `watchBundles`. The method will call `browserify` with `watchify` and `babelify` to transpile files and put them in the required directory (which can be served by a `koa-static` middleware).\n\n```js\nimport { watchBundles } from 'idio-dev'\n\nconst STATIC = resolve(__dirname, 'static')\nconst from = resolve(__dirname, 'scripts')\nconst to = resolve(STATIC, 'scripts')\n\nif (!test \u0026\u0026 !production) await watchBundles({\n  from, to,\n  babelify: {\n    babelrc: false,\n    plugins: [\n      '@babel/plugin-transform-modules-commonjs',\n      '@babel/plugin-proposal-object-rest-spread',\n    ],\n    presets: [\n      '@babel/preset-react',\n    ],\n  },\n})\n```\n\n\n### Watching Routes\n\nIf you use `initRoutes`, for development purposes you can pass returned data to the `watchRoutes` function from `idio-dev` which allows to perform hot route reload without restarting the whole server.\n\n```js\nimport idio from 'idio'\nimport { watchRoutes } from 'idio-dev'\n\nconst ROUTES = resolve(__dirname, 'routes')\n\n(async () =\u003e {\n  const aliases = {\n    get: {\n      '/index': ['/'],\n    },\n  }\n\n  const { url, app, methods, router } = await idio({\n    autoConnect: false,\n    middleware: {\n      static: {\n        function(_, c) {\n          return serve(STATIC, c)\n        },\n        config: {\n          maxage: production ? 1000 * 60 * 60 * 24 * 10 : 0,\n        },\n        use: true,\n      },\n    },\n  }, {\n    dir: ROUTES,\n    aliases,\n  })\n\n  await watchRoutes({\n    dir: ROUTES,\n    methods,\n    router,\n    aliases,\n    url,\n  })\n  return { app, url }\n})\n```\n\n```sh\nhttp://localhost:5000/ip\n  src/routes/get/ip.jsx\n# update routes/ip\n⌁ src/routes/get/ip.jsx\n\u003e hot reloaded GET /ip\n```\n\n\u003c!-- ## Routes and Accessing Middleware\n\nAfter the Koa server has been started, the promise will resolve with an object\ncontaining 4 properties: `{ url, app, router, middleware }`.\n\n- _url_: server url\n- _app_: Koa app\n- _router_: router, not enabled yet (see below)\n- _middleware_: all set up middleware map with keys as names passed to the\n`startApp` method, and functions as values.\n\nNow you can set up routes and assign middleware to them:\n\n```js\nconst { url, app, router, middleware: { session } } = await startApp({\n  // ...\n})\nrouter.get('/', session, async (ctx) =\u003e {\n  const n = ctx.session.views || 1\n  ctx.session.views = n + 1\n  ctx.body = `${n} views`\n})\nconst routes = router.routes()\napp.use(routes)\n\nconsole.log(url) // http://localhost:5000\n```\n\nCongrats, you have your Koa2 server with database in `ctx.app.context`. --\u003e\n\n## destroy Method\n\nAn app can be destroyed (with all connections killed) by using `app.destroy`\nmethod. This can be useful for testing - a database connection and http server\nwill be stopped.\n\n## Database API\n\nThe database object is exported to `context.database`.\n\n_to-write_\n\n## todo\n\n- use subdirectories when reading routes\n- jsdoc for middleware settings\n\n---\n\n(c) [Art Deco Code][1] 2018\n\n[1]: https://artdeco.bz\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fartdecocode%2Fidio","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fartdecocode%2Fidio","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fartdecocode%2Fidio/lists"}