typespeed 2.5.0 → 2.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/README.en.md +169 -0
  3. package/README.md +123 -37
  4. package/dist/default/rabbitmq.class.js +18 -1
  5. package/dist/default/redis.class.js +14 -1
  6. package/dist/default/socket-io.class.js +53 -4
  7. package/dist/typespeed.d.ts +7 -7
  8. package/package.json +7 -2
  9. package/.github/workflows/test.yml +0 -50
  10. package/app/nodemon.json +0 -5
  11. package/app/package.json +0 -17
  12. package/app/src/aop-test.class.ts +0 -29
  13. package/app/src/config-development.json +0 -26
  14. package/app/src/config-production.json +0 -15
  15. package/app/src/config.json +0 -50
  16. package/app/src/custom-log.class.ts +0 -33
  17. package/app/src/entities/mutil-users.class.ts +0 -5
  18. package/app/src/entities/user-dto.class.ts +0 -3
  19. package/app/src/first-page.class.ts +0 -46
  20. package/app/src/jwt-authentication.class.ts +0 -30
  21. package/app/src/main.ts +0 -24
  22. package/app/src/second-page.class.ts +0 -43
  23. package/app/src/test-bind.class.ts +0 -41
  24. package/app/src/test-database.class.ts +0 -81
  25. package/app/src/test-log.class.ts +0 -11
  26. package/app/src/test-mq.class.ts +0 -21
  27. package/app/src/test-orm.class.ts +0 -63
  28. package/app/src/test-redis.class.ts +0 -45
  29. package/app/src/test-request.class.ts +0 -37
  30. package/app/src/test-socket.class.ts +0 -56
  31. package/app/src/user-model.class.ts +0 -50
  32. package/app/src/views/index.html +0 -1
  33. package/app/src/views/socket.html +0 -23
  34. package/app/src/views/upload.html +0 -14
  35. package/app/static/favicon.ico +0 -0
  36. package/app/static/k.jpg +0 -0
  37. package/app/tsconfig.json +0 -20
  38. package/introduction/decorator/example-import.class.ts +0 -6
  39. package/introduction/decorator/main-app.ts +0 -6
  40. package/introduction/decorator/main-decorator.ts +0 -108
  41. package/introduction/decorator/main-import.ts +0 -1
  42. package/introduction/decorator/main-reflect.ts +0 -25
  43. package/introduction/decorator-next/dist/main.js +0 -116
  44. package/introduction/decorator-next/package.json +0 -14
  45. package/introduction/decorator-next/src/main.ts +0 -64
  46. package/introduction/decorator-next/tsconfig.json +0 -17
  47. package/introduction/decorator-next//346/225/231/347/250/213.md +0 -384
  48. package/introduction/tsconfig.json +0 -23
  49. package/introduction/web-services/db-init.ts +0 -39
  50. package/introduction/web-services/db-singleton.ts +0 -59
  51. package/introduction/web-services/http-if.ts +0 -10
  52. package/introduction/web-services/http-init.ts +0 -6
  53. package/introduction/web-services/http-router.ts +0 -28
  54. package/src/bind.decorator.ts +0 -50
  55. package/src/core.decorator.ts +0 -184
  56. package/src/database.decorator.ts +0 -446
  57. package/src/decorator-utils.ts +0 -53
  58. package/src/default/default-authentication.class.ts +0 -10
  59. package/src/default/express-server.class.ts +0 -150
  60. package/src/default/log-default.class.ts +0 -9
  61. package/src/default/node-cache.class.ts +0 -40
  62. package/src/default/pages/404.html +0 -226
  63. package/src/default/pages/500.html +0 -713
  64. package/src/default/rabbitmq.class.ts +0 -61
  65. package/src/default/read-write-db.class.ts +0 -53
  66. package/src/default/redis.class.ts +0 -79
  67. package/src/default/socket-io.class.ts +0 -81
  68. package/src/factory/authentication-factory.class.ts +0 -9
  69. package/src/factory/cache-factory.class.ts +0 -7
  70. package/src/factory/data-source-factory.class.ts +0 -4
  71. package/src/factory/log-factory.class.ts +0 -8
  72. package/src/factory/server-factory.class.ts +0 -6
  73. package/src/route.decorator.ts +0 -334
  74. package/src/scaffold/command.ts +0 -40
  75. package/src/scaffold/templates/front-page.class.ts.tpl +0 -12
  76. package/src/scaffold/templates/main.ts.tpl +0 -13
  77. package/src/scaffold/templates/nodemon.json.tpl +0 -7
  78. package/src/scaffold/templates/package.json.tpl +0 -16
  79. package/src/scaffold/templates/tsconfig.json.tpl +0 -17
  80. package/src/typespeed.d.ts +0 -403
  81. package/src/typespeed.ts +0 -139
  82. package/test/bind.test.ts +0 -28
  83. package/test/database.test.ts +0 -76
  84. package/test/decorator-utils.test.ts +0 -42
  85. package/test/first-page.test.ts +0 -42
  86. package/test/hooks.ts +0 -13
  87. package/test/mq.test.ts +0 -17
  88. package/test/orm.test.ts +0 -66
  89. package/test/redis.test.ts +0 -48
  90. package/test/request.test.ts +0 -51
  91. package/test/second-page.test.ts +0 -50
  92. package/test/socket.test.ts +0 -60
  93. package/test-env/docker-compose.test.yml +0 -31
  94. package/test-env/mysql-init/init.sql +0 -8
  95. package/test-env//346/234/254/345/234/260Docker/346/265/213/350/257/225/346/226/271/346/241/210.md +0 -69
  96. package/tsconfig.json +0 -25
package/CHANGELOG.md CHANGED
@@ -4,6 +4,8 @@ typespeed 版本演进记录。本文件 2026-09-06 从 git 历史反推建立
4
4
 
5
5
  ## 2.5.x
6
6
 
7
+ - **2.5.2**:README 重写(专业丰富版:30+ 装饰器分类、书籍体系突出)+ 新增英文版 `README.en.md`(中英切换,默认中文)(2026-09-07)
8
+ - **2.5.1**:补全 `default/` 族装饰器双签名(`rabbitListener` / `redisSubscriber` / `SocketIo.onEvent`/`onError`/`onDisconnect`/`onConnected`);打包瘦身(`files` 白名单 108→31 文件);`npm pkg fix` 修正 bin 字段;修正 `redisSubscriber` 的 d.ts 签名(2026-09-07)
7
9
  - **2.5.0**:装饰器双轨——支持 TC39 标准装饰器(Stage 2.7),legacy 装饰器零破坏。单份源码运行时双签名感知(`isStd` 判据),覆盖 core/route/database 三族 + 入口 `app`/`value`;新增方法级 `@bind` 装饰器(route 参数名→来源、database 占位符→索引,替代标准模式删除的参数装饰器);`@autoware`/`@resource`/`@bean` 支持显式 token(标准模式无 `design:type`);类型声明宽松化;新增标准模式示例 `introduction/decorator-next/` + `isStd` 单测(2026-09-07)
8
10
 
9
11
  ## 2.4.x
package/README.en.md ADDED
@@ -0,0 +1,169 @@
1
+ <p align="center">
2
+ <h1 align="center">TypeSpeed</h1>
3
+ <p align="center">A decorator-driven TypeScript web framework — build web services declaratively with decorators</p>
4
+ </p>
5
+
6
+ <p align="center">
7
+ <a href="README.md">简体中文</a> · <b>English</b>
8
+ </p>
9
+
10
+ <p align="center">
11
+ <a href="https://www.npmjs.com/package/typespeed"><img src="https://badgen.net/npm/v/typespeed?color=cyan" alt="npm version"></a>
12
+ <a href="https://www.npmjs.com/package/typespeed"><img src="https://badgen.net/npm/dt/typespeed?color=pink" alt="npm downloads"></a>
13
+ <a href="https://github.com/speedphp/typespeed/blob/main/LICENSE"><img src="https://badgen.net/github/license/speedphp/typespeed" alt="license"></a>
14
+ <a href="https://github.com/speedphp/typespeed/actions"><img src="https://img.shields.io/github/actions/workflow/status/speedphp/typespeed/test.yml?label=CI" alt="build"></a>
15
+ <a href="https://badgen.net/badge/icon/TypeScript?icon=typescript&label"><img src="https://badgen.net/badge/icon/TypeScript?icon=typescript&label" alt="TypeScript"></a>
16
+ </p>
17
+
18
+ ---
19
+
20
+ TypeSpeed is a **web framework written in TypeScript**, built on top of [Express](https://expressjs.com/). It organizes your application declaratively through **decorators** — dependency injection, routing, database, caching, authentication, and message queues are all declared with decorators, with zero configuration to start.
21
+
22
+ > 📖 The companion book **《TypeScript 框架开发实践(微课视频版)》(TypeScript Framework Development in Practice, Tsinghua University Press)** systematically explains the design and implementation of this framework, taking you from zero to building a framework.
23
+
24
+ ---
25
+
26
+ ## ✨ Features
27
+
28
+ ### 🎯 Decorator-Driven
29
+ Provides **30+ decorators** covering the full spectrum of web development — object management, web routing, parameter binding, database operations, caching, authentication, message queues, and sockets. One annotation, one feature:
30
+
31
+ | Category | Decorators | Description |
32
+ |---|---|---|
33
+ | **Object management** | `@component` `@bean` `@autoware` `@resource` | Component registration & dependency injection |
34
+ | **Web routing** | `@getMapping` `@postMapping` `@requestMapping` | REST route declaration |
35
+ | **Route parameters** | `@req` `@res` `@next` `@reqBody` `@reqParam` `@reqQuery` `@reqForm` | Request parameter injection |
36
+ | **AOP** | `@before` `@after` | Before / after interception |
37
+ | **Database** | `@insert` `@update` `@remove` `@select` `@param` `@resultType` `@cache` | Declarative SQL operations |
38
+ | **Security / upload** | `@jwt` `@upload` | JWT authentication, file upload |
39
+ | **Scheduling / config** | `@schedule` `@value` `@config` | Scheduled tasks, config injection |
40
+ | **Messaging / cache** | `@rabbitListener` `@redisSubscriber` | MQ listener, Redis subscriber |
41
+ | **Socket.IO** | `@SocketIo.onEvent` `@onConnected` `@onDisconnect` `@onError` | Real-time communication events |
42
+ | **Parameter binding** (2.5+) | `@bind` | Method-level parameter binding under standard decorators |
43
+
44
+ ### 🧩 Core Mechanisms
45
+ - **Dependency Injection (DI)**: `@autoware` / `@resource` auto-inject instances, `@bean` provides factory methods, with explicit token support (standard decorator mode)
46
+ - **AOP**: `@before` / `@after` intercept methods non-invasively
47
+ - **Middleware**: pluggable middleware chain + global authentication (`AuthenticationFactory`)
48
+ - **Startup scanning**: automatically scans core and application modules, zero-config startup
49
+
50
+ ### 🗄️ Database (two styles)
51
+ - **Decorator style**: `@select("SQL")` + `@param` / `@resultType` / `@cache` — declarative SQL execution, result type mapping, automatic caching
52
+ - **Model ORM style**: extend `Model` — `findAll` / `find` / `create` / `update` / `delete` / `findCount` / `incr` / `decr` / `pager`, chainable queries, condition building, pagination
53
+
54
+ ### 🔌 Built-in Components
55
+ - **Cache**: `NodeCache` (in-memory) + Redis (extensible via `CacheFactory`)
56
+ - **Message queue**: RabbitMQ wrapper (`RabbitMQ` / `@rabbitListener`)
57
+ - **Redis**: connection management + `@redisSubscriber` + leaderboards (`zranking` / `zrevranking`)
58
+ - **Socket.IO**: event decorators + rooms + connection management
59
+ - **Session / static / templates / upload**: session (Redis store), static assets, multi template engines (consolidate), file upload
60
+
61
+ ### 🚀 Standard Decorator Dual-Track (2.5+)
62
+ Supports both **legacy decorators** (`experimentalDecorators: true`, the book's style) and **TC39 standard decorators** (Stage 2.7, `experimentalDecorators: false`), auto-detected at runtime from a single codebase — legacy code works unchanged.
63
+
64
+ ---
65
+
66
+ ## 📦 Quick Start
67
+
68
+ **Requirements**: Node.js 16+ (18/20/22 recommended), TypeScript.
69
+
70
+ ```bash
71
+ # 1. Install the CLI globally
72
+ npm install typespeed -g
73
+
74
+ # 2. Create a project (zero config)
75
+ typespeed new blog
76
+ cd blog
77
+
78
+ # 3. Install dependencies and start
79
+ npm install
80
+ npm run start
81
+ ```
82
+
83
+ ---
84
+
85
+ ## 📝 Example
86
+
87
+ A minimal example combining component, routing, database, and caching:
88
+
89
+ ```typescript
90
+ import { component, app, autoware, getMapping, insert, select, resultType, cache, CacheFactory, ServerFactory } from "typespeed";
91
+
92
+ // Component (service)
93
+ @component
94
+ class UserService {
95
+
96
+ // Dependency injection
97
+ @autoware
98
+ private cacheBean: CacheFactory;
99
+
100
+ // Route + parameter injection
101
+ @getMapping("/user/:id")
102
+ async getUser(@reqParam id: number, @res res) {
103
+ res.json({ id, name: "typespeed" });
104
+ }
105
+
106
+ // Database: declarative SQL
107
+ @insert("Insert into `user` (id, name) values (#{id}, #{name})")
108
+ async addUser(@param("id") id: number, @param("name") name: string) {}
109
+
110
+ // Query + result type mapping + caching
111
+ @cache(1800)
112
+ @select("Select * from `user` where id = #{id}")
113
+ @resultType(UserDto)
114
+ async findUser(@param("id") id: number): Promise<UserDto[]> { return; }
115
+ }
116
+
117
+ // Application entry: @app auto-starts main()
118
+ @app
119
+ class Main {
120
+ @autoware
121
+ private server: ServerFactory;
122
+
123
+ main() {
124
+ this.server.start(8081);
125
+ }
126
+ }
127
+ ```
128
+
129
+ > See the [`app/`](https://github.com/speedphp/typespeed/tree/main/app) directory and the book's companion source for more complete examples.
130
+
131
+ ---
132
+
133
+ ## 📚 Learning Resources
134
+
135
+ TypeSpeed is not just a framework — it comes with a complete **"book + video + dual source code" learning system**:
136
+
137
+ | Resource | Description | Link |
138
+ |---|---|---|
139
+ | 📖 **Book** | 《TypeScript 框架开发实践(微课视频版)》by 曾振中, Tsinghua University Press | [JD.com](https://item.jd.com/14275373.html) |
140
+ | 🎬 **Video course** | Accompanying micro-lecture videos, one source snapshot per lesson | Bundled with the book |
141
+ | 📂 **Book source · ts-book** | Organized by chapter (chapter01~chapter06), runnable examples per chapter | [github.com/speedphp/ts-book](https://github.com/speedphp/ts-book) |
142
+ | 🏷️ **Video code · ts-practice** | Tagged by book section number (e.g. `4.10.4` = Chapter 4, Section 10, Step 4), one runnable snapshot per lesson | [github.com/speedphp/ts-practice](https://github.com/speedphp/ts-practice) |
143
+
144
+ > To learn the framework's design and implementation systematically, start with the book + ts-book; to follow along hands-on, use ts-practice.
145
+
146
+ ---
147
+
148
+ ## 🗺️ Roadmap
149
+
150
+ | Version | Content | Status |
151
+ |---|---|---|
152
+ | 2.4.x | Documentation revival, CI modernization, all tests green | ✅ Released |
153
+ | 2.5.x | **Standard decorator dual-track** (TC39 Stage 2.7) + `@bind` + explicit token | ✅ Released (latest) |
154
+ | 2.6.x | Node/TS upgrade + health checks + graceful shutdown + Docker/k8s manifests | 🚧 In progress |
155
+
156
+ ---
157
+
158
+ ## 🤝 Contributing
159
+
160
+ Issues and pull requests are welcome. Development and testing:
161
+
162
+ ```bash
163
+ npm run build # compile
164
+ npm test # test (requires MySQL / Redis / RabbitMQ)
165
+ ```
166
+
167
+ ## 📄 License
168
+
169
+ [MIT](LICENSE) © [speedphp](https://github.com/speedphp)
package/README.md CHANGED
@@ -1,83 +1,169 @@
1
- # TypeSpeed Framework
1
+ <p align="center">
2
+ <h1 align="center">TypeSpeed</h1>
3
+ <p align="center">一个装饰器驱动的 TypeScript Web 框架 —— 用声明式装饰器,快速构建 Web 服务</p>
4
+ </p>
2
5
 
6
+ <p align="center">
7
+ <b>简体中文</b> · <a href="README.en.md">English</a>
8
+ </p>
3
9
 
10
+ <p align="center">
11
+ <a href="https://www.npmjs.com/package/typespeed"><img src="https://badgen.net/npm/v/typespeed?color=cyan" alt="npm version"></a>
12
+ <a href="https://www.npmjs.com/package/typespeed"><img src="https://badgen.net/npm/dt/typespeed?color=pink" alt="npm downloads"></a>
13
+ <a href="https://github.com/speedphp/typespeed/blob/main/LICENSE"><img src="https://badgen.net/github/license/speedphp/typespeed" alt="license"></a>
14
+ <a href="https://github.com/speedphp/typespeed/actions"><img src="https://img.shields.io/github/actions/workflow/status/speedphp/typespeed/test.yml?label=CI" alt="build"></a>
15
+ <a href="https://badgen.net/badge/icon/TypeScript?icon=typescript&label"><img src="https://badgen.net/badge/icon/TypeScript?icon=typescript&label" alt="TypeScript"></a>
16
+ </p>
4
17
 
5
- ![typescript](https://badgen.net/badge/icon/TypeScript?icon=typescript\&label)
18
+ ---
6
19
 
20
+ TypeSpeed 是一个 **TypeScript 编写的 Web 框架**,底层基于 [Express](https://expressjs.com/),通过**装饰器**以声明式的方式组织你的应用——依赖注入、路由、数据库、缓存、鉴权、消息队列,全部用装饰器声明,零配置启动。
7
21
 
22
+ > 📖 配套图书 **《TypeScript 框架开发实践(微课视频版)》**(曾振中 著,清华大学出版社)系统讲解本框架的设计与实现,从零带你写出一个框架。
8
23
 
9
- ![npm](https://badgen.net/npm/v/typespeed?color=cyan)
24
+ ---
10
25
 
26
+ ## ✨ 特性
11
27
 
28
+ ### 🎯 装饰器驱动
29
+ 提供 **30+ 个装饰器**,覆盖 Web 开发全流程——对象管理、Web 路由、参数绑定、数据库操作、缓存、鉴权、消息队列、Socket,一个注解搞定一个功能:
12
30
 
13
- ![downloads](https://badgen.net/npm/dt/typespeed?color=pink)
31
+ | 分类 | 装饰器 | 说明 |
32
+ |---|---|---|
33
+ | **对象管理** | `@component` `@bean` `@autoware` `@resource` | 组件注册与依赖注入 |
34
+ | **Web 路由** | `@getMapping` `@postMapping` `@requestMapping` | REST 路由声明 |
35
+ | **路由参数** | `@req` `@res` `@next` `@reqBody` `@reqParam` `@reqQuery` `@reqForm` | 请求参数注入 |
36
+ | **切面 AOP** | `@before` `@after` | 前置 / 后置拦截 |
37
+ | **数据库** | `@insert` `@update` `@remove` `@select` `@param` `@resultType` `@cache` | SQL 声明式操作 |
38
+ | **安全 / 上传** | `@jwt` `@upload` | JWT 鉴权、文件上传 |
39
+ | **定时 / 配置** | `@schedule` `@value` `@config` | 定时任务、配置注入 |
40
+ | **消息 / 缓存** | `@rabbitListener` `@redisSubscriber` | MQ 监听、Redis 订阅 |
41
+ | **Socket.IO** | `@SocketIo.onEvent` `@onConnected` `@onDisconnect` `@onError` | 实时通信事件 |
42
+ | **参数绑定**(2.5+) | `@bind` | 标准装饰器下的方法级参数绑定 |
14
43
 
44
+ ### 🧩 核心机制
45
+ - **依赖注入(DI)**:`@autoware` / `@resource` 自动注入实例,`@bean` 提供工厂方法,支持显式 token(标准装饰器模式)
46
+ - **AOP 切面**:`@before` / `@after` 无侵入拦截方法
47
+ - **中间件**:可插拔中间件链 + 全局认证(`AuthenticationFactory`)
48
+ - **启动扫描**:自动扫描核心模块与应用模块,零配置启动
15
49
 
50
+ ### 🗄️ 数据库(两种风格)
51
+ - **装饰器风格**:`@select("SQL")` + `@param` / `@resultType` / `@cache`,SQL 声明式执行、结果类型映射、自动缓存
52
+ - **Model ORM 风格**:继承 `Model`,`findAll` / `find` / `create` / `update` / `delete` / `findCount` / `incr` / `decr` / `pager`,链式查询、条件构建、分页
16
53
 
17
- ![license](https://badgen.net/github/license/speedphp/typespeed)
54
+ ### 🔌 内置组件
55
+ - **缓存**:`NodeCache`(内存)+ Redis(`CacheFactory` 可扩展)
56
+ - **消息队列**:RabbitMQ 封装(`RabbitMQ` / `@rabbitListener`)
57
+ - **Redis**:连接管理 + `@redisSubscriber` 订阅 + 排行榜(`zranking` / `zrevranking`)
58
+ - **Socket.IO**:事件装饰器 + 房间 + 连接管理
59
+ - **会话 / 静态 / 模板 / 上传**:session(Redis 存储)、静态资源、多模板引擎(consolidate)、文件上传
18
60
 
61
+ ### 🚀 标准装饰器双轨(2.5+)
62
+ 同时支持 **legacy 装饰器**(`experimentalDecorators: true`,书中写法)与 **TC39 标准装饰器**(Stage 2.7,`experimentalDecorators: false`),单份源码运行时自动识别,旧代码零改动。
19
63
 
64
+ ---
20
65
 
21
- ![GitHub Build Status](https://img.shields.io/github/actions/workflow/status/speedphp/typespeed/test.yml)
66
+ ## 📦 快速开始
22
67
 
68
+ **环境要求**:Node.js 16+(推荐 18/20/22),TypeScript。
23
69
 
70
+ ```bash
71
+ # 1. 全局安装脚手架
72
+ npm install typespeed -g
24
73
 
25
- ![Codecov](https://img.shields.io/codecov/c/github/speedphp/typespeed)
26
-
27
- ### 资料体系
28
-
29
- TypeSpeed 不只提供一个框架,还配有完整的「书 + 视频 + 双源码」学习资料:
30
-
31
-
74
+ # 2. 创建项目(零配置)
75
+ typespeed new blog
76
+ cd blog
32
77
 
33
- * **书**:《TypeScript 框架开发实践(微课视频版)》(曾振中 著,清华大学出版社)——[京东购买](https://item.jd.com/14275373.html)
78
+ # 3. 安装依赖并启动
79
+ npm install
80
+ npm run start
81
+ ```
34
82
 
35
- * **视频课程**:随书微课视频(每节配套源码快照见 ts-practice)
83
+ ---
36
84
 
37
- * **附书源码・ts-book**:[https://github.com/speedphp/ts-book](https://github.com/speedphp/ts-book)—— 按章组织(chapter01 \~ chapter06),每章含可运行示例
85
+ ## 📝 示例
38
86
 
39
- * **视频代码・ts-practice**:[https://github.com/speedphp/ts-practice](https://github.com/speedphp/ts-practice)—— 按书籍章节号打 tag(如 `4.10.4` = 第 4 章第 10 节第 4 步),每节视频对应一份可跑源码快照
87
+ 一个组件 + 路由 + 数据库 + 缓存的最小示例:
40
88
 
41
- ### 特点
89
+ ```typescript
90
+ import { component, app, autoware, getMapping, insert, select, resultType, cache, CacheFactory, ServerFactory } from "typespeed";
42
91
 
92
+ // 组件(服务)
93
+ @component
94
+ class UserService {
43
95
 
96
+ // 依赖注入
97
+ @autoware
98
+ private cacheBean: CacheFactory;
44
99
 
45
- * 遵循 MIT 许可的开源项目。
100
+ // 路由 + 参数注入
101
+ @getMapping("/user/:id")
102
+ async getUser(@reqParam id: number, @res res) {
103
+ res.json({ id, name: "typespeed" });
104
+ }
46
105
 
47
- * 提供 31 个 TypeScript 装饰器,这些装饰器构成了完整的 Web 框架功能,包括对象管理、Web 路由、数据库操作等。
106
+ // 数据库:声明式 SQL
107
+ @insert("Insert into `user` (id, name) values (#{id}, #{name})")
108
+ async addUser(@param("id") id: number, @param("name") name: string) {}
48
109
 
49
- * 通过命令行脚手架,可以快速创建项目,零配置启动。
110
+ // 查询 + 结果类型映射 + 缓存
111
+ @cache(1800)
112
+ @select("Select * from `user` where id = #{id}")
113
+ @resultType(UserDto)
114
+ async findUser(@param("id") id: number): Promise<UserDto[]> { return; }
115
+ }
50
116
 
51
- * 基于依赖注入、AOP、中间件和启动扫描等编程理念开发实现。
117
+ // 应用入口:@app 自动启动 main()
118
+ @app
119
+ class Main {
120
+ @autoware
121
+ private server: ServerFactory;
52
122
 
53
- * 底层采用 ExpressJS 实现,提供稳定、快速的 Web 服务。
123
+ main() {
124
+ this.server.start(8081);
125
+ }
126
+ }
127
+ ```
54
128
 
55
- * 框架提供了两种风格不同却各具优点的数据操作模式。
129
+ > 更多完整示例见仓库 [`app/`](https://github.com/speedphp/typespeed/tree/main/app) 目录与随书源码。
56
130
 
57
- ### 安装
131
+ ---
58
132
 
59
- TypeSpeed 环境要求 NodeJS 16+,TypeScript 运行时。
133
+ ## 📚 学习资料体系
60
134
 
135
+ TypeSpeed 不只是一个框架,还配有**完整的「书 + 视频 + 双源码」学习体系**:
61
136
 
137
+ | 资料 | 说明 | 链接 |
138
+ |---|---|---|
139
+ | 📖 **图书** | 《TypeScript 框架开发实践(微课视频版)》曾振中 著,清华大学出版社 | [京东购买](https://item.jd.com/14275373.html) |
140
+ | 🎬 **视频课程** | 随书微课视频,每节配套源码 | 随书附带 |
141
+ | 📂 **附书源码 ts-book** | 按章组织(chapter01~chapter06),每章可运行示例 | [github.com/speedphp/ts-book](https://github.com/speedphp/ts-book) |
142
+ | 🏷️ **视频代码 ts-practice** | 按书籍章节号打 tag(如 `4.10.4` = 第 4 章第 10 节第 4 步),每节对应可跑源码快照 | [github.com/speedphp/ts-practice](https://github.com/speedphp/ts-practice) |
62
143
 
63
- ```
64
- npm install typespeed -g
65
- ```
144
+ > 想系统学习框架原理与实现,从图书 + ts-book 入手;想跟随视频动手,用 ts-practice。
66
145
 
67
- ### 使用
146
+ ---
68
147
 
148
+ ## 🗺️ 版本路线图
69
149
 
150
+ | 版本 | 内容 | 状态 |
151
+ |---|---|---|
152
+ | 2.4.x | 文档复活、CI 现代化、测试全绿 | ✅ 已发布 |
153
+ | 2.5.x | **标准装饰器双轨**(TC39 Stage 2.7)+ `@bind` + 显式 token | ✅ 已发布(latest) |
154
+ | 2.6.x | Node/TS 升级 + 健康检查 + 优雅停机 + Docker/k8s 部署清单 | 🚧 进行中 |
70
155
 
71
- ```
72
- typespeed new blog
156
+ ---
73
157
 
74
- cd ./blog
158
+ ## 🤝 参与贡献
75
159
 
76
- npm install
160
+ 欢迎提交 Issue 与 Pull Request。开发与测试:
77
161
 
78
- npm run test
162
+ ```bash
163
+ npm run build # 编译
164
+ npm test # 测试(需 MySQL / Redis / RabbitMQ)
79
165
  ```
80
166
 
81
- ### 开源协议
167
+ ## 📄 开源协议
82
168
 
83
- [MIT](LICENSE) © speedphp
169
+ [MIT](LICENSE) © [speedphp](https://github.com/speedphp)
@@ -13,6 +13,7 @@ exports.rabbitListener = exports.RabbitMQ = void 0;
13
13
  const core_decorator_1 = require("../core.decorator");
14
14
  const typespeed_1 = require("../typespeed");
15
15
  const amqplib_1 = require("amqplib");
16
+ const decorator_utils_1 = require("../decorator-utils");
16
17
  let rabbitConnection = null;
17
18
  class RabbitMQ {
18
19
  getRabbitMQ() {
@@ -58,7 +59,23 @@ async function getChannel() {
58
59
  return channel;
59
60
  }
60
61
  function rabbitListener(queue) {
61
- return (target, propertyKey) => {
62
+ return (...args) => {
63
+ if ((0, decorator_utils_1.isStd)(args)) {
64
+ const [, ctx] = (0, decorator_utils_1.getStdArgs)(args);
65
+ ctx.addInitializer(function () {
66
+ const targetConstructor = this.constructor;
67
+ const methodName = String(ctx.name);
68
+ (async function () {
69
+ const channel = await getChannel();
70
+ await channel.assertQueue(queue);
71
+ const targetBean = (0, core_decorator_1.getComponent)(targetConstructor);
72
+ await channel.consume(queue, targetBean[methodName], { noAck: true });
73
+ }());
74
+ });
75
+ return;
76
+ }
77
+ const target = args[0];
78
+ const propertyKey = args[1];
62
79
  (async function () {
63
80
  const channel = await getChannel();
64
81
  await channel.assertQueue(queue);
@@ -13,6 +13,7 @@ exports.redisSubscriber = exports.Redis = void 0;
13
13
  const core_decorator_1 = require("../core.decorator");
14
14
  const ioredis_1 = require("ioredis");
15
15
  const typespeed_1 = require("../typespeed");
16
+ const decorator_utils_1 = require("../decorator-utils");
16
17
  const redisSubscribers = {};
17
18
  class Redis extends ioredis_1.default {
18
19
  getRedis() {
@@ -75,7 +76,19 @@ function redisSubscriber(channel) {
75
76
  console.error(err);
76
77
  }
77
78
  });
78
- return function (target, propertyKey) {
79
+ return function (...args) {
80
+ if ((0, decorator_utils_1.isStd)(args)) {
81
+ const [, ctx] = (0, decorator_utils_1.getStdArgs)(args);
82
+ ctx.addInitializer(function () {
83
+ redisSubscribers[channel] = {
84
+ target: this,
85
+ propertyKey: String(ctx.name)
86
+ };
87
+ });
88
+ return;
89
+ }
90
+ const target = args[0];
91
+ const propertyKey = args[1];
79
92
  redisSubscribers[channel] = {
80
93
  target: target,
81
94
  propertyKey: propertyKey
@@ -4,6 +4,7 @@ exports.io = exports.SocketIo = void 0;
4
4
  const socket_io_1 = require("socket.io");
5
5
  const http_1 = require("http");
6
6
  const core_decorator_1 = require("../core.decorator");
7
+ const decorator_utils_1 = require("../decorator-utils");
7
8
  let io = null;
8
9
  exports.io = io;
9
10
  const listeners = { "event": [], "disconnect": null, "error": null, "connected": null };
@@ -48,26 +49,74 @@ class SocketIo {
48
49
  return httpServer;
49
50
  }
50
51
  static onEvent(event) {
51
- return (target, propertyKey) => {
52
+ return (...args) => {
53
+ if ((0, decorator_utils_1.isStd)(args)) {
54
+ const [, ctx] = (0, decorator_utils_1.getStdArgs)(args);
55
+ ctx.addInitializer(function () {
56
+ listeners["event"].push([{
57
+ target: this,
58
+ propertyKey: String(ctx.name)
59
+ }, event]);
60
+ });
61
+ return;
62
+ }
63
+ const target = args[0];
64
+ const propertyKey = args[1];
52
65
  listeners["event"].push([{
53
66
  target: target,
54
67
  propertyKey: propertyKey
55
68
  }, event]);
56
69
  };
57
70
  }
58
- static onError(target, propertyKey) {
71
+ static onError(...args) {
72
+ if ((0, decorator_utils_1.isStd)(args)) {
73
+ const [, ctx] = (0, decorator_utils_1.getStdArgs)(args);
74
+ ctx.addInitializer(function () {
75
+ listeners["error"] = {
76
+ target: this,
77
+ propertyKey: String(ctx.name)
78
+ };
79
+ });
80
+ return;
81
+ }
82
+ const target = args[0];
83
+ const propertyKey = args[1];
59
84
  listeners["error"] = {
60
85
  target: target,
61
86
  propertyKey: propertyKey
62
87
  };
63
88
  }
64
- static onDisconnect(target, propertyKey) {
89
+ static onDisconnect(...args) {
90
+ if ((0, decorator_utils_1.isStd)(args)) {
91
+ const [, ctx] = (0, decorator_utils_1.getStdArgs)(args);
92
+ ctx.addInitializer(function () {
93
+ listeners["disconnect"] = {
94
+ target: this,
95
+ propertyKey: String(ctx.name)
96
+ };
97
+ });
98
+ return;
99
+ }
100
+ const target = args[0];
101
+ const propertyKey = args[1];
65
102
  listeners["disconnect"] = {
66
103
  target: target,
67
104
  propertyKey: propertyKey
68
105
  };
69
106
  }
70
- static onConnected(target, propertyKey) {
107
+ static onConnected(...args) {
108
+ if ((0, decorator_utils_1.isStd)(args)) {
109
+ const [, ctx] = (0, decorator_utils_1.getStdArgs)(args);
110
+ ctx.addInitializer(function () {
111
+ listeners["connected"] = {
112
+ target: this,
113
+ propertyKey: String(ctx.name)
114
+ };
115
+ });
116
+ return;
117
+ }
118
+ const target = args[0];
119
+ const propertyKey = args[1];
71
120
  listeners["connected"] = {
72
121
  target: target,
73
122
  propertyKey: propertyKey
@@ -175,9 +175,9 @@ declare function after(constructorFunction: any, methodName: string): (...args:
175
175
  /**定时程序装饰器,参数支持 crontab 格式字符串,可根据参数定时执行被装饰的方法 */
176
176
  declare function schedule(cronTime: string | Date): (...args: any[]) => any;
177
177
  /**RabbitMQ 监听装饰器,参数是监听的队列名称,当接受到消息时将执行被装饰方法 */
178
- declare function rabbitListener(queue: string): (target: any, propertyKey: string) => void;
179
- /**Redis 监听装饰器,参数是监听的队列名称,当接受到消息时将执行被装饰方法 */
180
- declare function redisSubscriber(target: any, propertyKey: string): void;
178
+ declare function rabbitListener(queue: string): (...args: any[]) => any;
179
+ /**Redis 监听装饰器,参数是监听的频道名称,当接受到消息时将执行被装饰方法 */
180
+ declare function redisSubscriber(channel: string): (...args: any[]) => any;
181
181
  /** request 对象装饰器,作为路由页面方法参数,获取 request 对象 */
182
182
  declare function req(target: any, propertyKey: string, parameterIndex: number): void;
183
183
  /** response 对象装饰器,作为路由页面方法参数,获取 response 对象 */
@@ -389,13 +389,13 @@ declare class SocketIo {
389
389
  * Socket IO 事件装饰器
390
390
  * @param event 事件名称
391
391
  */
392
- public static onEvent(event: string): (target: any, propertyKey: string) => void;
392
+ public static onEvent(event: string): (...args: any[]) => any;
393
393
  /**Socket IO 错误捕获装饰器 */
394
- public static onError(target: any, propertyKey: string): void;
394
+ public static onError(...args: any[]): any;
395
395
  /**Socket IO 客户端断开连接事件装饰器 */
396
- public static onDisconnect(target: any, propertyKey: string): void;
396
+ public static onDisconnect(...args: any[]): any;
397
397
  /**Socket IO 客户端连接成功事件装饰器 */
398
- public static onConnected(target: any, propertyKey: string): void;
398
+ public static onConnected(...args: any[]): any;
399
399
  }
400
400
  /**Socket IO 服务实现类 */
401
401
  declare const io: IoServer;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "typespeed",
3
- "version": "2.5.0",
3
+ "version": "2.5.2",
4
4
  "description": "A new Framework for TypeScript.",
5
5
  "author": "speedphp",
6
6
  "license": "MIT License",
@@ -13,8 +13,13 @@
13
13
  "prebuild": "rm -rf dist"
14
14
  },
15
15
  "main": "dist/typespeed.js",
16
+ "files": [
17
+ "dist",
18
+ "CHANGELOG.md",
19
+ "README.en.md"
20
+ ],
16
21
  "bin": {
17
- "typespeed": "./dist/scaffold/command.js"
22
+ "typespeed": "dist/scaffold/command.js"
18
23
  },
19
24
  "homepage": "https://github.com/speedphp/typespeed#readme",
20
25
  "repository": {
@@ -1,50 +0,0 @@
1
- name: Tests
2
- 'on':
3
- push:
4
- branches:
5
- - main
6
-
7
- jobs:
8
- test:
9
- name: 'Test TypeSpeed'
10
- runs-on: ubuntu-latest
11
- services:
12
- redis:
13
- image: redis
14
- ports:
15
- - 6379:6379
16
- rabbitmq:
17
- image: rabbitmq:3.8
18
- env:
19
- RABBITMQ_DEFAULT_USER: guest
20
- RABBITMQ_DEFAULT_PASS: guest
21
- ports:
22
- - 5672
23
- steps:
24
- - uses: actions/checkout@v4
25
- - uses: actions/setup-node@v4
26
- with:
27
- node-version: 22
28
- - name: Setup MySQL
29
- run: |
30
- sudo /etc/init.d/mysql start
31
- mysql -e 'CREATE DATABASE test;USE test; \
32
- CREATE TABLE `user` (`id` int(11) NOT NULL AUTO_INCREMENT,`name` varchar(100) DEFAULT NULL,PRIMARY KEY (`id`)) \
33
- ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;SHOW TABLES;' -uroot -proot
34
- - name: 'Cache node_modules'
35
- uses: actions/cache@v4
36
- with:
37
- path: ~/.npm
38
- key: ${{ runner.os }}-node-v22-${{ hashFiles('**/package.json') }}
39
- restore-keys: |
40
- ${{ runner.os }}-node-v22-
41
- - name: Install Dependencies
42
- run: npm install
43
- - name: Run Tests with Coverage
44
- run: npm run test-with-coverage
45
- env:
46
- LOCAL_HOST: localhost
47
- - name: Upload coverage reports to Codecov
48
- uses: codecov/codecov-action@v3
49
- env:
50
- CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
package/app/nodemon.json DELETED
@@ -1,5 +0,0 @@
1
- {
2
- "watch": ["src", "../dist", "../src", "../test"],
3
- "ext": "ts,json",
4
- "exec": "npm test"
5
- }