{"id":18947669,"url":"https://github.com/asciphx/thinkts","last_synced_at":"2025-10-08T03:33:04.895Z","repository":{"id":169801424,"uuid":"287132512","full_name":"asciphx/ThinkTs","owner":"asciphx","description":"Based on koa and typeorm,asynchronous non blocking reactive coding and a real MVC web framework, inspired by [ThinkPHP + Nestjs + FastAPI], it is also the fastest development speed and fastest performance.","archived":false,"fork":false,"pushed_at":"2023-06-06T06:58:35.000Z","size":1911,"stargazers_count":6,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-16T02:55:58.452Z","etag":null,"topics":["framework","full-stack","koa","mvc","typeorm","typescript","webframework"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/asciphx.png","metadata":{"files":{"readme":"README-zh_CN.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"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}},"created_at":"2020-08-12T23:05:27.000Z","updated_at":"2023-02-02T23:47:19.000Z","dependencies_parsed_at":null,"dependency_job_id":"44cea5aa-cbc5-440b-841c-7045c4d3b633","html_url":"https://github.com/asciphx/ThinkTs","commit_stats":null,"previous_names":["asciphx/thinkts"],"tags_count":23,"template":false,"template_full_name":null,"purl":"pkg:github/asciphx/ThinkTs","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/asciphx%2FThinkTs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/asciphx%2FThinkTs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/asciphx%2FThinkTs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/asciphx%2FThinkTs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/asciphx","download_url":"https://codeload.github.com/asciphx/ThinkTs/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/asciphx%2FThinkTs/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278885890,"owners_count":26062969,"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-10-08T02:00:06.501Z","response_time":56,"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":["framework","full-stack","koa","mvc","typeorm","typescript","webframework"],"created_at":"2024-11-08T13:10:53.794Z","updated_at":"2025-10-08T03:33:04.890Z","avatar_url":"https://github.com/asciphx.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ThinkTs\n- 支持 **TypeORM**，最好的 Typescript ORM 框架，轻松编写 DAO 层的各类逻辑\n- 允许使用静态类型修饰、类型推断，为后端开发和维护提供支持\n- 模块化开发，让应用程序更容易分层，提供了易于使用的模块化管理机制\n- 最低调编写 AOP 代码，面向切面编程，却轻松实现日志、拦截器、过滤器等功能\n- 最快，最迅速，最猛烈构建 MVC、API、websocket、微服务等系统\n- 配置大于编码，优先自动实现增删改查以及分页等五个方法，方便权限后台系统搭建\n- 服务类能够implements接口，快速定位每个方法，轻松维护代码复杂繁多的service\n- 字段级别的rbac，加上可插拔的中间件装饰器，组装功能具有无限的可能\n- 支持serverless，在控制器方法引入ROUTER，即可让网页轻松改后台，甚至写入文件\n- 可以用各种typeORM允许的关系型数据库，目前先提供mysql，postgres\n- 增加socketIo版demo已放example目录[默认为管理版（需redis）]\n- 能够使用方法覆盖override，从而不用再担心路由是否存在冗余\n- 来自ES6魔法函数Generator生成器，再加全程异步让效率提升，所以稳定、极速\n- 由大拿的方法生成路由文件到./routes，让前端不手写axios路由，真正拿来即用\n# [ThinkTs讨论区](http://www.91huanwei.com/)\nThinkTs是参考了[ThinkPHP+Nestjs+FastAPI]这四种的实现，当然目的也是为产品经理打造的，理念是每一天都有可能实现一个小目标(项目)……\n\n## [Benchmarks](https://www.fastify.cn/benchmarks/)🚀\n\n## 使用**ThinkTs**让你的controller看起来像是:\n```typescript\n@Class([\"add\",\"del\",\"fix\",\"info\",\"page\"])//or @Class(\"/admin\",……)or @Class(\"admin\",……)\nclass Admin extends Controller{\n  @Inject(Admin$) readonly a_:Admin$\n  @Inject(User$) readonly u_:User$\n\n  @Middle(W.Log,W.V_B(\"account|1#3~10\",\"pwd#6~23|1\"))\n  @app.post(\"register\")\n  add(@B b,@R r:Response) {\n    r.status=202;//设置状态码\n    return this.u_.register(b.account,b.pwd)\n  }\n}\n/** Here's how to show EJS template rendering */\nclass View{\n  @Get() @Get(\"index.html\")\n  index(ctx:Context){\n    html(ctx,{test:\"test\",author:\"asciphx\"}).next().value\n  }\n  @Get(\"login.html\")\n  login(ctx:Context){\n    html(ctx,{test:\"test\",author:\"Login\"}).next().value\n  }\n}\n```\n### 让你的service看起来像是:\n```typescript\nexport default class User$ extends $ implements F{\n  constructor(\n    private u=Inject(User),private r=Inject(Role)\n  ) {\n    super({\n      leftJoin:{e:\"u.roles\",a:'role'},\n      addSelect:['role.id','role.name'],\n      where: query =\u003e new Brackets(qb =\u003e {\n        if (query.account) qb.where('account like :v', { v: `%${query.account}%` })\n        if (query.id) qb.andWhere('u.id \u003e:i', { i: query.id })\n      }),\n      orderBy: { \"u.id\": \"desc\" }\n    },\"u\")\n  }\n}\n```\n### 让你的interface看起来像是:\n```typescript\nexport default interface UserFace{\n  /** register one*/register(entity)\n  /** login one*/login(entity)\n  /** search all*/all()\n}\n```\n### 让你的entity看起来像是[TypeORM](https://github.com/typeorm/typeorm)中的写法\n\n### Cache用法：[Cache](https://github.com/typeorm/typeorm/blob/master/docs/caching.md)\n\n## 特征\n- [x] Class类装饰器默认值为 \"/\"+实体类名 ,当然也可以自定义\n- [x] 自动扫描entity目录，载入到Cache，相当于一个容器,可以避免entity被多次实例化\n- [x] 自动扫描controller目录，并且配置Routes路由\n- [x] 自动生成配置路由文件以便查阅，在routes目录下，也可删除，或者去app/config.ts下更改printRoute为false\n- [x] 有近似于nest.js+fastify架构的速度，还有java:SpringBoot框架的可维护性\n- [x] 如不采用typeORM库，也可以使用Sequelize，并重写entity类\n- [x] 现在增加基础控制器、服务层，控制器装饰器可以自定义自动实现增删改查以及分页\n- [x] 增加参数装饰器，更加便捷美观，并且不会影响到运行速度\n- [x] 装饰器可以横着放，并且，可以堆叠，顺序是从右往左依次执行\n- [x] 来自ES6的魔法生成器函数，加上node全程异步编程特征，让速度得到飞跃\n\n## 新版自定义JWT鉴权说明\n\u003e Headers请求头现在为2个参数，原版jwt不变。现增加一个secret，算法是在cryptoUtil.ts里并由后端额外提供动态secret，此项目只是个高度安全的案例，只要后端代码加强算法并不泄露，就难破解。\n\u003e ```javascript\n\u003e t:`${token}`\n\u003e s:`${secret}`\n\u003e ```\n\u003e 特别地，localhost:8080/index.html是Postman界面，记住登陆后记录token和sercet，并像上面使用即可。前端目前还在实现中，先暂给大家用Postman尝鲜\n\u003e 在正式环境下启动的指令，windows使用的是`npm run pro`,Mac或者Linux是`npm run prod`.正式环境下请使用`npm run pm2`开启多核心。\n\u003e 新增redis，为了每个线程上的服务可同步缓存,在app/config.ts下设置synchronize，默认6秒，redis密码在config配置\n\u003e 允许使用postgres(在ormconfig.js中配置)，win用户得用登录win账户名，我是Asciphx（其他系统记得改下），并且也需在pgsql中创建spring这个database\n\u003e 若启动时出现QueryFailedError请用对应sql文件在查询窗口/工具 内粘贴进去执行（即相当于导入功能），导入暂时还没测，注意mysql必须用utf8mb4编码\n\u003e socketIo版和普通版放到了example目录下，如需使用请覆盖到顶级目录即可\n\u003e 注意：布尔类型字段，尽量用application/json的格式传输,这样后台就不用对这样的字段处理了\n\u003e 压测前请把pm2开启，并且使用cluster集群模式，instances最好是max，生产环境下多核测试性能方面相当于.net core的75%\n\u003e ./.vscode目录下包含正式环境下压测图，本机是i5的6核心cpu，启动1分钟后，每个核心占用50M+内存，一共300M+[非常少]，rps大概在1350左右。\n## 目录结构\n1. app:`后端文件入口`\n2. app/controller:`控制层`\n3. app/entity:`实体层`\n4. app/interface:`接口层`\n5. app/service:`服务层`\n6. app/think:`基础层`\n7. app/utils:`工具层`\n8. dist:`后台ejs模板渲染文件夹/前端打包文件夹`\n9. lib:`windows用到linux的rm与cp指令程序，需放环境变量目录`\n10. routes:`提供前端的路由文件，每个controller会创建一个`\n11. upload:`上传文件的存储目录`\n12. build:`后端打包到正式环境的目录`\n13. log:`pm2输出日志目录`\n14. example:`存放SocketIo的模板，还有普通的模板`\n## [微服务](https://docs.nestjs.cn/7/microservices?id=kafka)\n请参考nestjs的微服务模式文档，基本上可以实现\n## 权限管理（如需其他版本请看example目录）\n[example目录下面其他版本直接覆盖到顶层目录即可替换]\nPATH路径，自动生成的（匹配规则）  \n增加：POST/admin  \n删除：DELETE/admin/  \n修改：PUT/admin/  \n查询：GET/admin/  \n分页：GET/admin  \n菜单只包含目录结构，没有请求路径。  路由的上级节点只能是菜单，包含请求路径。  \n按钮的上级节点只能是路由，而且必须没有请求路径，是因为按钮的功能都基于spa单页应用。  \nput方法实际上跟patch方法等同，如果局部修改也不会影响其他，所以没写patch装饰器。  \normconfig.js注释中包含是否输出log或错误，取消注释即可使用。 JWT默认禁用，方便测试。\n其中synchronize设置为true是自动同步，若是修改了实体类，自动同步可能会导致修改的字段数据清空。\n所以保存之前，重启服务前，先在数据库改，比如字段长度。然后在实体类改成一样的并保存，最后再重启服务。\n或，synchronize设置false，修改实体类重启服务则不同步 ，然后手动在数据库修改成与实体类一样的属性。\nrestful规范中的返回值实际太费带宽，而我认为前端只需判断返回是字符串还是对象，如字符串就直接显示(前端弹窗就行)，\n如返回对象，请求状态码一定是200，所以只拿重要数据而不需code状态码和massage提示成功(那两东西完全是浪费流量)。  \n该项目离serverless又更近了一步，目前是发布版,redis会自动重连。自动生成的curd也附带了参数校验。\n## **请赞助本项目**\n如你觉有收获，请给我打赏\n\n![微信打赏](https://images.gitee.com/uploads/images/2020/0811/142549_9e012161_685448.jpeg)\n![支付宝打赏](https://images.gitee.com/uploads/images/2020/0811/142549_5db6c4cc_685448.jpeg)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fasciphx%2Fthinkts","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fasciphx%2Fthinkts","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fasciphx%2Fthinkts/lists"}