{"id":18110845,"url":"https://github.com/miserylee/koact","last_synced_at":"2026-05-01T14:31:35.035Z","repository":{"id":24091363,"uuid":"133932793","full_name":"miserylee/koact","owner":"miserylee","description":"Smart koa routes manager.","archived":false,"fork":false,"pushed_at":"2022-12-09T08:39:40.000Z","size":72,"stargazers_count":2,"open_issues_count":3,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-09-22T22:52:25.363Z","etag":null,"topics":["api","auto-doc","document","documentation","koa","middleware","router"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/miserylee.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-05-18T09:24:17.000Z","updated_at":"2020-01-18T01:34:19.000Z","dependencies_parsed_at":"2023-01-14T00:23:34.743Z","dependency_job_id":null,"html_url":"https://github.com/miserylee/koact","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/miserylee/koact","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/miserylee%2Fkoact","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/miserylee%2Fkoact/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/miserylee%2Fkoact/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/miserylee%2Fkoact/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/miserylee","download_url":"https://codeload.github.com/miserylee/koact/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/miserylee%2Fkoact/sbom","scorecard":{"id":649548,"data":{"date":"2025-08-11","repo":{"name":"github.com/miserylee/koact","commit":"ca5ef66228a55dbdf9c2d0251bf5b1b2acbdf12f"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":1.3,"checks":[{"name":"Code-Review","score":0,"reason":"Found 0/28 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":"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":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"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":"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":"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":"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":"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":"License","score":0,"reason":"license file not detected","details":["Warn: project does not have a license file"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"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":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 2 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":0,"reason":"20 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-v6h2-p8h4-qcjw","Warn: Project is vulnerable to: GHSA-3xgq-45jj-v275","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-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-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-c2qf-rxjj-qqgw","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-21T13:08:00.173Z","repository_id":24091363,"created_at":"2025-08-21T13:08:00.173Z","updated_at":"2025-08-21T13:08:00.173Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32501399,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-30T13:12:12.517Z","status":"online","status_checked_at":"2026-05-01T02:00:05.856Z","response_time":64,"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":["api","auto-doc","document","documentation","koa","middleware","router"],"created_at":"2024-11-01T00:12:10.125Z","updated_at":"2026-05-01T14:31:34.981Z","avatar_url":"https://github.com/miserylee.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# koact\n\n##  ![NPM version](https://img.shields.io/npm/v/koact.svg?style=flat)\n\n\n### 这是什么？\n\n`koact`是一个便捷的`koa`应用的路由管理器。\n\n### 怎么使用？\n\n```js\n// 使用 yarn 或 npm 安装 koact\nimport koact from 'koact';\nimport * as Koa from 'koa';\n\nconst app = new Koa();\n\nconst router = koact(path.resolve(__dirname, 'routes'));\n\nkoa.use(router);\nkoa.listen(3000);\n```\n\n路由文件放在上面代码指定的`routes`文件夹下即可。\n\n`koact`函数的具体定义如下：\n\n```js\nexport interface IOptions {\n    resolves?: string[]; // 指定ext的文件将会被解析，默认值为['.js', '.ts', '.node']\n    docSecret?: string; // 指定接口文档的访问密钥，默认无密钥，可随意访问\n}\n/*\nroutesPath: 路由文件所在的文件夹\nenhancers: 全局的路由增强器\noptions: 额外的配置，见IOptions\n*/\ndeclare const koact: (routesPath: string, enhancers?: Enhancer[] | undefined, options?: IOptions) =\u003e compose.Middleware\u003cContext\u003e;\n```\n\n### 怎么写路由文件？\n\n每一个路由文件即代表一个API模块，其相对于`routes`的路径即为`pathname`；\n\n文件名的格式为`\u003cmethod\u003e[.version]#\u003capi name\u003e.js|ts`；\n\n例如： `routes/userInfo/GET#获取账户信息.ts` 表示接口`pathname=/userInfo method=GET version=default 接口名=获取账户信息`；\n\n若文件路径中包含了`#param`的部分，则会被解析为`params`参数；\n\n**注意：若文件名以 _ 开头，则认为该文件是非路由文件，会被解析器忽略。**\n\n在路由文件内`export default`一个类型为`IAPI`的模块即可自动解析为API接口，`IAPI`类型的定义如下：\n\n```js\nexport interface IObject {\n  [key: string]: any;\n}\n\nexport type APIHandler\u003cP, Q, B, R\u003e = (data: { params: P, query: Q, body: B, ctx: Context, next: () =\u003e Promise\u003cvoid\u003e }) =\u003e Promise\u003cR\u003e; // 对接口业务函数的定义\n\nexport interface IAPIBase\u003cP = any, Q = any, B = any, R = any\u003e extends IObject {\n  params?: IObject; // 对params进行校验的数据结构模板\n  query?: IObject; // 对query进行校验的数据结构模板\n  body?: IObject; // 对body进行校验的数据结构模板\n  res?: any; // 对返回值responseBody进行数据结构校验的模板\n  handler?: APIHandler\u003cP, Q, B, R\u003e; // 接口执行函数\n  pre?: Middleware[]; // 该接口适用的koa中间件\n  useCustomBodyParser?: boolean; // 标记是否适用自定义的bodyParser模块，适用自定义bodyParser模块时，koact会忽略内置的bodyParser，所以必须在前置中间件中加入自定义的bodyParser模块才可以对body数据进行解析\n}\n\n// 对接口增强器的定义，增强器用于在运行时对接口定义进行改写\nexport type Enhancer = (api: IAPIBase, info: { method: string, name: string, path: string }) =\u003e IAPIBase;\n\n// IAPI 的类型定义\nexport interface IAPI\u003cP = any, Q = any, B = any, R = any\u003e extends IAPIBase\u003cP, Q, B, R\u003e {\n  enhancers?: Enhancer[]; // 该接口的增强器\n}\n```\n\n其中对参数和返回值进行数据校验的数据结构模板，使用了`schema.io`库来进行。在这里[schema.io](https://github.com/miserylee/schema.io)查看具体使用方法。\n\n一个简单的接口定义文件示例：\n\n```js\nimport { IAPI } from 'koact';\n\nexport default {\n  query: {\n    name: String,\n  },\n  res: String,\n  async handler({ query }): Promise\u003cstring\u003e {\n    return `Hello ${query.name}`;\n  },\n  pre: [async (ctx, next) =\u003e {\n    ctx.set('file', __filename);\n    await next();\n  }],\n} as IAPI\u003c{}, {\n  name: string;\n}, {}, string\u003e;\n```\n\n### 自动的接口文档 \u0026 局部接口配置\n\n可以在相应的文件夹下定义`META.ts|js`文件来定义自动化生成的文档入口和局部（即META文件所在目录及所有子目录下）接口的统一配置：\n\n`META`文件中`export default`一个类型为`IMeta`的模块即可被解析，`IMeta`的定义如下：\n\n```js\nexport interface IMetaBase extends IObject {\n  title?: string; // 文档的title\n  description?: string; // 文档的描述\n  notSubDoc?: boolean; // 是否生成子文档，默认true\n}\n\nexport interface IMeta extends IMetaBase {\n  pre?: Middleware[]; // 局部接口配置的前置中间件\n  enhancers?: Enhancer[]; // 局部接口配置的增强器\n}\n```\n\n一个简单的`Meta`文件示例：\n\n```js\nimport { IAPIBase, IMeta } from 'koact';\n\nexport default {\n  title: 'This is the API documents.',\n  plugins: [(api: IAPIBase, { method, name, path }) =\u003e {\n    console.log(name, method, path);\n    if (!api.pre) {\n      api.pre = [];\n    }\n    api.pre.push(async (ctx, next) =\u003e {\n      ctx.set('dir', __dirname);\n      await next();\n    });\n    return api;\n  }],\n} as IMeta;\n```\n\n### 一个完整的路由文件夹的结构\n\n大概长这样\n\n```bash\nroutes\n├── GET#Gateway.ts\n├── META.ts\n├── POST#Test\\ post.ts\n├── manyVersions\n│   ├── META.ts\n│   ├── _private // 该文件夹下的接口会被忽略\n│   │   └── GET#Private\\ interface.ts\n│   └── user\n│       └── #id // 会被解析成params中的id参数\n│           ├── GET#Get\\ a\\ user.ts\n│           └── GET.v2#Get\\ a\\ user.ts // 不同版本的接口，但pathname一样\n├── multipart\n│   └── POST#Test\\ multipart.ts // 对multipart的解析\n├── nested\n│   └── nested\n│       ├── GET#Nested\\ API.ts\n│       ├── META.ts\n│       └── notSub\n│           ├── GET#not\\ sub\\ gateway.ts\n│           └── META.ts // 不生成子文档，仅仅作为局部接口的统一配置\n└── sub\n    └── GET#sub\\ gateway.ts\n```\n\n可以在项目`test/routes`目录下查看具体每个模块文件的详细内容。\n\n### 自动生成的文档\n\n`koact`会自动生成api接口文档，可以通过`http://\u003cyour server host and port\u003e/api.doc`来进行访问。\n\n通过上述地址访问到的为`json`格式的文档数据，也可以使用同一的GUI网页来对文档进行访问：`http://koact-doc.bestneverland.com/`，在页面中输入服务地址和文档密钥即可。\n\n### 自动生成web前端项目的API定义代码\n\n配合[koact-doc-to-definition](https://github.com/miserylee/koact-doc-to-definition)工具，可以在web前端项目中自动生成`koact`路由服务的访问代码。\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmiserylee%2Fkoact","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmiserylee%2Fkoact","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmiserylee%2Fkoact/lists"}