@zerooneit/expressive-tea 1.3.0-beta.5 → 2.0.0
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.
- package/.gitattributes +4 -0
- package/.swcrc +61 -0
- package/README.md +564 -174
- package/classes/Boot.d.ts +94 -3
- package/classes/Boot.js +171 -51
- package/classes/Engine.d.ts +59 -10
- package/classes/Engine.js +72 -11
- package/classes/EngineRegistry.d.ts +154 -0
- package/classes/EngineRegistry.js +247 -0
- package/classes/LoadBalancer.js +2 -5
- package/classes/ProxyRoute.d.ts +3 -3
- package/classes/ProxyRoute.js +5 -5
- package/classes/Settings.d.ts +31 -2
- package/classes/Settings.js +64 -11
- package/decorators/annotations.d.ts +1 -1
- package/decorators/annotations.js +17 -17
- package/decorators/env.d.ts +145 -0
- package/decorators/env.js +177 -0
- package/decorators/health.d.ts +115 -0
- package/decorators/health.js +124 -0
- package/decorators/module.d.ts +15 -15
- package/decorators/module.js +14 -23
- package/decorators/proxy.d.ts +26 -11
- package/decorators/proxy.js +35 -45
- package/decorators/router.d.ts +17 -16
- package/decorators/router.js +32 -52
- package/decorators/server.d.ts +8 -8
- package/decorators/server.js +48 -50
- package/engines/health/index.d.ts +120 -0
- package/engines/health/index.js +179 -0
- package/engines/http/index.d.ts +6 -7
- package/engines/http/index.js +22 -17
- package/engines/index.d.ts +32 -0
- package/engines/index.js +112 -0
- package/engines/socketio/index.d.ts +2 -1
- package/engines/socketio/index.js +16 -6
- package/engines/teacup/index.d.ts +13 -0
- package/engines/teacup/index.js +61 -11
- package/engines/teapot/index.d.ts +15 -2
- package/engines/teapot/index.js +61 -13
- package/engines/websocket/index.d.ts +4 -1
- package/engines/websocket/index.js +10 -2
- package/eslint.config.mjs +138 -0
- package/exceptions/RequestExceptions.d.ts +3 -3
- package/helpers/boot-helper.d.ts +6 -6
- package/helpers/boot-helper.js +30 -24
- package/helpers/decorators.js +7 -6
- package/helpers/promise-helper.d.ts +1 -1
- package/helpers/promise-helper.js +1 -2
- package/helpers/server.d.ts +32 -6
- package/helpers/server.js +101 -61
- package/helpers/teapot-helper.d.ts +5 -8
- package/helpers/teapot-helper.js +39 -11
- package/helpers/websocket-helper.d.ts +3 -5
- package/helpers/websocket-helper.js +3 -3
- package/interfaces/index.d.ts +1 -1
- package/inversify.config.d.ts +4 -4
- package/inversify.config.js +1 -1
- package/libs/utilities.d.ts +21910 -0
- package/libs/utilities.js +420 -0
- package/mixins/module.d.ts +45 -0
- package/mixins/module.js +71 -0
- package/mixins/proxy.d.ts +46 -0
- package/mixins/proxy.js +86 -0
- package/mixins/route.d.ts +48 -0
- package/mixins/route.js +96 -0
- package/package.json +91 -69
- package/services/DependencyInjection.d.ts +95 -7
- package/services/DependencyInjection.js +123 -5
- package/services/WebsocketService.d.ts +4 -6
- package/services/WebsocketService.js +5 -3
- package/types/core.d.ts +14 -0
- package/types/core.js +2 -0
- package/types/injection-types.d.ts +6 -0
- package/types/injection-types.js +10 -0
- package/types/inversify.d.ts +5 -0
- package/types/inversify.js +3 -0
package/README.md
CHANGED
|
@@ -1,237 +1,627 @@
|
|
|
1
1
|
<p align="center">
|
|
2
|
-
|
|
3
|
-
<
|
|
4
|
-
<img alt="npm (scoped)" src="https://img.shields.io/npm/v/@zerooneit/expressive-tea?style=flat-square">
|
|
2
|
+
<a href="https://www.npmjs.com/package/@expressive-tea/core">
|
|
3
|
+
<img alt="npm version" src="https://img.shields.io/npm/v/@expressive-tea/core?style=flat-square">
|
|
5
4
|
</a>
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
<a href="https://www.npmjs.com/package/@zerooneit/expressive-tea">
|
|
9
|
-
<img alt="npm" src="https://img.shields.io/npm/dw/@zerooneit/expressive-tea?style=flat-square">
|
|
5
|
+
<a href="https://www.npmjs.com/package/@expressive-tea/core">
|
|
6
|
+
<img alt="downloads" src="https://img.shields.io/npm/dw/@expressive-tea/core?style=flat-square">
|
|
10
7
|
</a>
|
|
11
|
-
|
|
12
|
-
<!-- Dependencies
|
|
13
|
-
<a href="https://libraries.io/npm/@zerooneit%2Fexpressive-tea">
|
|
14
|
-
<img alt="Libraries.io dependency status for latest release, scoped npm package" src="https://img.shields.io/librariesio/release/npm/@zerooneit/expressive-tea?style=flat-square">
|
|
15
|
-
</a>
|
|
16
|
-
-->
|
|
17
|
-
|
|
18
|
-
<!-- License
|
|
19
|
-
<a href="https://github.com/Expressive-Tea/expresive-tea/blob/develop/LICENSE">
|
|
20
|
-
<img alt="NPM" src="https://img.shields.io/npm/l/@zerooneit/expressive-tea?style=flat-square">
|
|
21
|
-
</a>
|
|
22
|
-
-->
|
|
23
|
-
|
|
24
|
-
<!-- Vulnerabilities -->
|
|
25
8
|
<a href="https://snyk.io//test/github/Expressive-Tea/expresive-tea?targetFile=package.json">
|
|
26
|
-
<img alt="
|
|
27
|
-
</a>
|
|
28
|
-
|
|
29
|
-
<!-- Last Commit
|
|
30
|
-
<a href="https://github.com/Expressive-Tea/expresive-tea">
|
|
31
|
-
<img alt="GitHub last commit" src="https://img.shields.io/github/last-commit/Expressive-Tea/expresive-tea?style=flat-square">
|
|
32
|
-
</a>
|
|
33
|
-
-->
|
|
34
|
-
<!-- Stars -->
|
|
35
|
-
<a href="https://github.com/Expressive-Tea/expresive-tea/stargazers">
|
|
36
|
-
<img alt="GitHub stars" src="https://img.shields.io/github/stars/Expressive-Tea/expresive-tea?style=flat-square">
|
|
37
|
-
</a>
|
|
38
|
-
|
|
39
|
-
<!-- Source Rank
|
|
40
|
-
<a href="https://libraries.io/npm/@zerooneit%2Fexpressive-tea/sourcerank">
|
|
41
|
-
<img alt="Libraries.io SourceRank, scoped npm package" src="https://img.shields.io/librariesio/sourcerank/npm/@zerooneit/expressive-tea?style=flat-square">
|
|
42
|
-
</a>
|
|
43
|
-
-->
|
|
44
|
-
<!-- Rating
|
|
45
|
-
<a href="https://pkgreview.dev/npm/@zerooneit%2Fexpressive-tea">
|
|
46
|
-
<img alt="pkgreview.dev Package Ratings" src="https://img.shields.io/pkgreview/rating/npm/@zerooneit/expressive-tea?style=flat-square">
|
|
47
|
-
</a>
|
|
48
|
-
-->
|
|
49
|
-
<!-- Issues
|
|
50
|
-
<a href="https://github.com/Expressive-Tea/expresive-tea/issues">
|
|
51
|
-
<img alt="GitHub issues" src="https://img.shields.io/github/issues-raw/Zero-Oneit/expresive-tea?style=flat-square">
|
|
52
|
-
</a>
|
|
53
|
-
-->
|
|
54
|
-
<!-- Gitter
|
|
55
|
-
<a href="https://gitter.im/Expressive-Tea/expresive-tea">
|
|
56
|
-
<img alt="Gitter" src="https://img.shields.io/gitter/room/zero-oneit/expresive-tea?style=flat-square">
|
|
9
|
+
<img alt="vulnerabilities" src="https://img.shields.io/snyk/vulnerabilities/github/expressive-tea/expresive-tea?style=flat-square">
|
|
57
10
|
</a>
|
|
58
|
-
-->
|
|
59
|
-
<!-- Test Coverage -->
|
|
60
11
|
<a href="https://codecov.io/gh/Expressive-Tea/expresive-tea">
|
|
61
|
-
<img alt="
|
|
12
|
+
<img alt="coverage" src="https://img.shields.io/codecov/c/github/expressive-tea/expresive-tea?label=coverage&style=flat-square">
|
|
62
13
|
</a>
|
|
63
|
-
|
|
64
|
-
<!-- Build -->
|
|
65
14
|
<a href="https://travis-ci.org/Expressive-Tea/expresive-tea">
|
|
66
|
-
<img alt="
|
|
15
|
+
<img alt="build" src="https://ci.zero-oneit.systems/buildStatus/icon?job=Expressive+Tea&style=flat-square">
|
|
16
|
+
</a>
|
|
17
|
+
<a href="https://github.com/Expressive-Tea/expresive-tea/stargazers">
|
|
18
|
+
<img alt="stars" src="https://img.shields.io/github/stars/Expressive-Tea/expresive-tea?style=flat-square">
|
|
19
|
+
</a>
|
|
20
|
+
<a href="https://github.com/Expressive-Tea/expresive-tea/blob/main/LICENSE">
|
|
21
|
+
<img alt="license" src="https://img.shields.io/github/license/Expressive-Tea/expresive-tea?style=flat-square">
|
|
67
22
|
</a>
|
|
68
23
|
</p>
|
|
69
24
|
|
|
70
|
-
<!-- PROJECT LOGO -->
|
|
71
25
|
<br />
|
|
72
26
|
<p align="center">
|
|
73
27
|
<a href="https://github.com/Expressive-Tea/expresive-tea">
|
|
74
28
|
<img src="images/logo.png" alt="Logo" width="160" />
|
|
75
29
|
</a>
|
|
76
30
|
|
|
77
|
-
<
|
|
31
|
+
<h1 align="center">Expressive Tea</h1>
|
|
78
32
|
|
|
79
33
|
<p align="center">
|
|
80
|
-
A
|
|
34
|
+
<strong>A modern, TypeScript-first framework for building scalable Node.js applications</strong>
|
|
81
35
|
<br />
|
|
82
|
-
<
|
|
36
|
+
<em>Clean architecture • Dependency Injection • Decorator-driven • Express-powered</em>
|
|
83
37
|
<br />
|
|
84
38
|
<br />
|
|
85
|
-
<a href="https://
|
|
39
|
+
<a href="https://zero-oneit.github.io/expresive-tea/"><strong>📚 Documentation</strong></a>
|
|
86
40
|
·
|
|
87
|
-
<a href="https://
|
|
41
|
+
<a href="https://codesandbox.io/s/expressive-tea-2kmg7?fontsize=14&hidenavigation=1&theme=dark"><strong>🚀 Live Demo</strong></a>
|
|
88
42
|
·
|
|
89
|
-
<a href="https://github.com/Expressive-Tea/expresive-tea/issues"
|
|
43
|
+
<a href="https://github.com/Expressive-Tea/expresive-tea/issues"><strong>🐛 Report Bug</strong></a>
|
|
44
|
+
·
|
|
45
|
+
<a href="https://github.com/Expressive-Tea/expresive-tea/issues"><strong>💡 Request Feature</strong></a>
|
|
90
46
|
</p>
|
|
91
47
|
</p>
|
|
92
48
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
* Extends and configuration with plugins and well-defined boot stages.
|
|
135
|
-
* Modules are not hard dependencies and can be shareable between projects.
|
|
136
|
-
* Declare Server Middlewares configuration as hard or soft dependency at server level.
|
|
137
|
-
* Dependency Injection is available for controllers as providers declared in modules using InversifyJs.
|
|
138
|
-
* Declarative Router on Controllers.
|
|
139
|
-
* Declarative Verbs and Middlewares under module and verb level.
|
|
140
|
-
* Declarative Exceptions for a better Error Handling.
|
|
141
|
-
|
|
142
|
-
### Built With
|
|
143
|
-
|
|
144
|
-
* [Express](https://github.com/expressjs/express) - The web framework used
|
|
145
|
-
* [Typescript](https://www.typescriptlang.org/) - Main Language
|
|
146
|
-
* [Inversify](https://github.com/inversify/InversifyJS/) - Used for dependency Injection
|
|
147
|
-
* [Reflect Metadata](https://github.com/rbuckton/reflect-metadata) - Used to get code metadata.
|
|
148
|
-
* [YARN](https://yarnpkg.com/) - Used to build and dependencies.
|
|
149
|
-
|
|
150
|
-
## Getting Started
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
> [!IMPORTANT]
|
|
52
|
+
> ### 📦 Package Renamed: `@expressive-tea/core`
|
|
53
|
+
>
|
|
54
|
+
> **Expressive Tea has a new home on npm!** Starting with v2.0.0, install using:
|
|
55
|
+
>
|
|
56
|
+
> ```bash
|
|
57
|
+
> npm install @expressive-tea/core
|
|
58
|
+
> ```
|
|
59
|
+
>
|
|
60
|
+
> **Legacy package `@zerooneit/expressive-tea` will be maintained until April 30, 2026** for security patches only. Please migrate to `@expressive-tea/core` as soon as possible.
|
|
61
|
+
>
|
|
62
|
+
> **Why the change?**
|
|
63
|
+
> - ✨ Better namespace organization (`@expressive-tea/*`)
|
|
64
|
+
> - 🌍 Community-focused ownership
|
|
65
|
+
> - 🚀 Clearer project identity
|
|
66
|
+
>
|
|
67
|
+
> **Migration is simple:** Just update your `package.json` and imports remain the same!
|
|
68
|
+
> ```diff
|
|
69
|
+
> - "dependencies": { "@zerooneit/expressive-tea": "^1.2.0" }
|
|
70
|
+
> + "dependencies": { "@expressive-tea/core": "^2.0.0" }
|
|
71
|
+
> ```
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
> [!CAUTION]
|
|
76
|
+
> ### ⚠️ CRITICAL: v1.x Security Notice
|
|
77
|
+
>
|
|
78
|
+
> **All versions 1.x are DEPRECATED and UNSUPPORTED** as of January 27, 2026.
|
|
79
|
+
>
|
|
80
|
+
> **v1.3.x Beta** - 🔴 **CRITICAL SECURITY VULNERABILITY** - DO NOT USE
|
|
81
|
+
> Contains critical cryptography flaws in Teapot/Teacup gateway. If you're using this, **STOP IMMEDIATELY** and upgrade to v2.0.0.
|
|
82
|
+
>
|
|
83
|
+
> **v1.2.x Production** - 🟡 No crypto issues, but **deprecated** (InversifyJS v6 EOL)
|
|
84
|
+
>
|
|
85
|
+
> **👉 Upgrade to v2.0.0 NOW** - See [Migration Guide](docs/MIGRATION_GUIDE_v2.md)
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## ⚡ Quick Start
|
|
151
90
|
|
|
152
|
-
|
|
91
|
+
```bash
|
|
92
|
+
# Install the new package
|
|
93
|
+
npm install @expressive-tea/core
|
|
153
94
|
|
|
154
|
-
|
|
155
|
-
|
|
95
|
+
# Or with yarn
|
|
96
|
+
yarn add @expressive-tea/core
|
|
97
|
+
```
|
|
156
98
|
|
|
157
|
-
|
|
158
|
-
|
|
99
|
+
```typescript
|
|
100
|
+
import { ServerSettings, Route, Get, Boot } from '@expressive-tea/core';
|
|
159
101
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
102
|
+
@ServerSettings({ port: 3000 })
|
|
103
|
+
class App extends Boot {}
|
|
104
|
+
|
|
105
|
+
@Route('/hello')
|
|
106
|
+
class HelloController {
|
|
107
|
+
@Get('/')
|
|
108
|
+
sayHello() {
|
|
109
|
+
return { message: 'Hello, World! 🍵' };
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
new App().start();
|
|
114
|
+
// 🎉 Server running on http://localhost:3000
|
|
163
115
|
```
|
|
164
116
|
|
|
165
|
-
|
|
117
|
+
**[Try it live on CodeSandbox →](https://codesandbox.io/s/expressive-tea-2kmg7?fontsize=14&hidenavigation=1&theme=dark)**
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
## 🎯 Why Expressive Tea?
|
|
122
|
+
|
|
123
|
+
### The Problem
|
|
124
|
+
Building Node.js applications is powerful, but messy. You get a blank canvas with Express—no structure, no conventions, just middleware chaos. Sound familiar?
|
|
125
|
+
|
|
126
|
+
### The Solution
|
|
127
|
+
**Expressive Tea** brings the elegance of modern frameworks to Node.js, without the bloat. Think NestJS simplicity meets Express flexibility.
|
|
128
|
+
|
|
129
|
+
### 🌟 What Makes It Special
|
|
130
|
+
|
|
131
|
+
| Feature | What You Get |
|
|
132
|
+
|---------|-------------|
|
|
133
|
+
| 🎨 **Clean Architecture** | Decorators organize your code beautifully—no more spaghetti routes |
|
|
134
|
+
| 🔌 **Plugin Everything** | Share database configs, auth, websockets across projects |
|
|
135
|
+
| 💉 **Smart DI** | Singleton, Transient, Scoped services—InversifyJS under the hood |
|
|
136
|
+
| 🛡️ **Type-Safe** | Full TypeScript strict mode—catch bugs before they ship |
|
|
137
|
+
| 🔒 **Secure by Default** | AES-256-GCM + HKDF crypto, built-in security best practices |
|
|
138
|
+
| ⚡ **Production Ready** | 92%+ test coverage, battle-tested in real applications |
|
|
139
|
+
| 🎯 **Express Compatible** | Use ANY Express middleware—gradual migration friendly |
|
|
140
|
+
| 📦 **Zero Lock-in** | BYOA (Bring Your Own Architecture)—we don't force opinions |
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
## 🚀 What's New in v2.0
|
|
145
|
+
|
|
146
|
+
**Major security and architecture improvements!**
|
|
147
|
+
|
|
148
|
+
```diff
|
|
149
|
+
+ ✅ Security: Fixed critical crypto vulnerabilities (AES-256-GCM + HKDF)
|
|
150
|
+
+ ✅ Type Safety: Full TypeScript strict mode support
|
|
151
|
+
+ ✅ DI: Scoped dependency injection (Singleton/Transient/Scoped)
|
|
152
|
+
+ ✅ Health Checks: Built-in health endpoints for Kubernetes/monitoring
|
|
153
|
+
+ ✅ Environment: .env file support with @Env decorator
|
|
154
|
+
+ ✅ Performance: Native utilities, removed lodash dependencies
|
|
155
|
+
+ ✅ ESLint: Migrated to ESLint v9 flat config
|
|
156
|
+
+ ✅ Quality: 95%+ coverage, all tests passing
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
**⚠️ Breaking Changes:**
|
|
160
|
+
- Cryptography format changed (must re-encrypt data)
|
|
161
|
+
- TypeScript strict mode enabled
|
|
162
|
+
- **Node.js 20+ required** (Node.js 18 reached EOL April 2025)
|
|
163
|
+
- Express 5.x required
|
|
164
|
+
- ESLint v9 (flat config)
|
|
165
|
+
|
|
166
|
+
**[📖 Full Changelog](CHANGELOG.md)** • **[🔄 Migration Guide](docs/MIGRATION_GUIDE_v2.md)**
|
|
167
|
+
|
|
168
|
+
---
|
|
169
|
+
|
|
170
|
+
## 💡 Features That'll Make You Smile
|
|
171
|
+
|
|
172
|
+
### 🎨 Decorator-Driven Development
|
|
173
|
+
```typescript
|
|
174
|
+
@Route('/api/users')
|
|
175
|
+
class UserController {
|
|
176
|
+
@Get('/:id')
|
|
177
|
+
async getUser(@Param('id') id: string) {
|
|
178
|
+
return this.userService.findById(id);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
@Post('/')
|
|
182
|
+
async createUser(@Body() data: CreateUserDto) {
|
|
183
|
+
return this.userService.create(data);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
### 🔌 Pluggable Architecture
|
|
189
|
+
```typescript
|
|
190
|
+
import { AuthPlugin } from '@my-org/auth-plugin';
|
|
191
|
+
import { DatabasePlugin } from '@my-org/db-plugin';
|
|
192
|
+
|
|
193
|
+
@ServerSettings({
|
|
194
|
+
port: 3000,
|
|
195
|
+
plugins: [AuthPlugin, DatabasePlugin]
|
|
196
|
+
})
|
|
197
|
+
class App extends Boot {}
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
### 💉 Dependency Injection
|
|
201
|
+
```typescript
|
|
202
|
+
@injectable()
|
|
203
|
+
class UserService {
|
|
204
|
+
constructor(
|
|
205
|
+
@inject(TYPES.Database) private db: Database,
|
|
206
|
+
@inject(TYPES.Logger) private logger: Logger
|
|
207
|
+
) {}
|
|
208
|
+
}
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
### 🎯 Type-Safe Everything
|
|
212
|
+
```typescript
|
|
213
|
+
// Generics everywhere
|
|
214
|
+
class ApiResponse<T> {
|
|
215
|
+
constructor(
|
|
216
|
+
public data: T,
|
|
217
|
+
public status: number
|
|
218
|
+
) {}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
@Get('/users')
|
|
222
|
+
getUsers(): ApiResponse<User[]> {
|
|
223
|
+
return new ApiResponse(users, 200);
|
|
224
|
+
}
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
### 🏥 Built-in Health Checks
|
|
228
|
+
```typescript
|
|
229
|
+
@HealthCheck({
|
|
230
|
+
checks: [
|
|
231
|
+
{
|
|
232
|
+
name: 'database',
|
|
233
|
+
check: async () => {
|
|
234
|
+
const isConnected = await db.ping();
|
|
235
|
+
return { status: isConnected ? 'pass' : 'fail' };
|
|
236
|
+
},
|
|
237
|
+
critical: true, // Blocks readiness probe if fails
|
|
238
|
+
timeout: 5000
|
|
239
|
+
}
|
|
240
|
+
]
|
|
241
|
+
})
|
|
242
|
+
class App extends Boot {}
|
|
243
|
+
|
|
244
|
+
// Endpoints:
|
|
245
|
+
// GET /health - Detailed health status
|
|
246
|
+
// GET /health/live - Liveness probe (K8s)
|
|
247
|
+
// GET /health/ready - Readiness probe (K8s)
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
### 🌍 Environment Variable Support
|
|
251
|
+
```typescript
|
|
252
|
+
// Load from .env files
|
|
253
|
+
@Env({ path: '.env', required: ['DATABASE_URL', 'API_KEY'] })
|
|
254
|
+
@Env({ path: '.env.local', override: true, silent: true })
|
|
255
|
+
class App extends Boot {}
|
|
256
|
+
|
|
257
|
+
// In your .env:
|
|
258
|
+
// DATABASE_URL=postgres://localhost:5432/mydb
|
|
259
|
+
// API_KEY="secret-key"
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
### 🎯 Type-Safe Environment Variables (v2.0.1+)
|
|
263
|
+
```typescript
|
|
264
|
+
import { z } from 'zod';
|
|
265
|
+
|
|
266
|
+
const EnvSchema = z.object({
|
|
267
|
+
PORT: z.string().transform(Number),
|
|
268
|
+
DATABASE_URL: z.string().url(),
|
|
269
|
+
API_KEY: z.string().min(32)
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
type Env = z.infer<typeof EnvSchema>;
|
|
273
|
+
|
|
274
|
+
@Env<Env>({
|
|
275
|
+
transform: (env) => EnvSchema.parse(env),
|
|
276
|
+
onTransformError: 'throw' // Fail fast on invalid env
|
|
277
|
+
})
|
|
278
|
+
class App extends Boot {
|
|
279
|
+
constructor() {
|
|
280
|
+
super();
|
|
281
|
+
const env = Settings.getInstance().getEnv<Env>();
|
|
282
|
+
console.log(env.PORT); // Type: number (validated!)
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
### 📄 Configuration Files (v2.0.1+)
|
|
288
|
+
```yaml
|
|
289
|
+
# .expressive-tea.yaml (YAML support!)
|
|
290
|
+
port: 3000
|
|
291
|
+
securePort: 4443
|
|
292
|
+
|
|
293
|
+
database:
|
|
294
|
+
host: localhost
|
|
295
|
+
port: 5432
|
|
296
|
+
|
|
297
|
+
# Comments supported!
|
|
298
|
+
cache:
|
|
299
|
+
enabled: true
|
|
300
|
+
ttl: 3600
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
**File Priority**: `.expressive-tea.yaml` > `.expressive-tea.yml` > `.expressive-tea` (JSON)
|
|
304
|
+
|
|
305
|
+
---
|
|
306
|
+
|
|
307
|
+
## 📦 Installation & Setup
|
|
308
|
+
|
|
309
|
+
### Prerequisites
|
|
310
|
+
|
|
311
|
+
- **Node.js** ≥ 20.0.0
|
|
312
|
+
- **TypeScript** ≥ 5.0.0
|
|
313
|
+
- **Express** ≥ 5.0.0
|
|
314
|
+
|
|
315
|
+
> **Note:** Node.js 18 support was dropped in v2.0.0 as it reached End-of-Life in April 2025. We recommend using Node.js 20 LTS or Node.js 22 for the best experience and security updates.
|
|
316
|
+
|
|
317
|
+
### Configure TypeScript
|
|
166
318
|
|
|
167
319
|
```json
|
|
168
320
|
{
|
|
169
321
|
"compilerOptions": {
|
|
170
|
-
"
|
|
171
|
-
"sourceMap": true,
|
|
172
|
-
"noEmit": true,
|
|
173
|
-
"noImplicitAny": true,
|
|
174
|
-
"target": "es6",
|
|
175
|
-
"lib": ["es6", "dom"],
|
|
322
|
+
"target": "ES2017",
|
|
176
323
|
"module": "commonjs",
|
|
177
|
-
"moduleResolution": "node",
|
|
178
324
|
"experimentalDecorators": true,
|
|
179
|
-
"emitDecoratorMetadata": true
|
|
325
|
+
"emitDecoratorMetadata": true,
|
|
326
|
+
|
|
327
|
+
// Recommended for maximum safety
|
|
328
|
+
"strict": true,
|
|
329
|
+
"strictNullChecks": true,
|
|
330
|
+
"noImplicitAny": true
|
|
180
331
|
}
|
|
181
332
|
}
|
|
182
333
|
```
|
|
183
|
-
|
|
184
|
-
|
|
334
|
+
|
|
335
|
+
### Install
|
|
336
|
+
|
|
337
|
+
```bash
|
|
338
|
+
# npm
|
|
339
|
+
npm install @expressive-tea/core reflect-metadata
|
|
340
|
+
|
|
341
|
+
# yarn
|
|
342
|
+
yarn add @expressive-tea/core reflect-metadata
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
---
|
|
346
|
+
|
|
347
|
+
## Local staging with Verdaccio
|
|
348
|
+
|
|
349
|
+
If you want to test publishing locally before pushing to the public registry, use a local Verdaccio instance as a staging registry.
|
|
350
|
+
|
|
351
|
+
Quick steps:
|
|
352
|
+
|
|
353
|
+
1. Start Verdaccio (Docker):
|
|
354
|
+
|
|
355
|
+
```bash
|
|
356
|
+
docker run -d --rm --name verdaccio-expressive-tea -p 4873:4873 verdaccio/verdaccio:latest
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
2. Point npm to local registry and publish:
|
|
360
|
+
|
|
361
|
+
```bash
|
|
362
|
+
# point npm to local registry
|
|
363
|
+
npm set registry http://localhost:4873
|
|
364
|
+
|
|
365
|
+
# publish (from package root)
|
|
366
|
+
npm publish --registry http://localhost:4873
|
|
367
|
+
|
|
368
|
+
# restore default registry
|
|
369
|
+
npm set registry https://registry.npmjs.org/
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
3. Optional: Use the repo-provided Verdaccio config for deterministic behavior:
|
|
373
|
+
|
|
374
|
+
```bash
|
|
375
|
+
docker run -d --rm --name verdaccio-expressive-tea -p 4873:4873 \
|
|
376
|
+
-v $(pwd)/.docs/verdaccio/config.yaml:/verdaccio/conf/config.yaml \
|
|
377
|
+
verdaccio/verdaccio:latest
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
Notes:
|
|
381
|
+
- Default URL: http://localhost:4873
|
|
382
|
+
- Container name: verdaccio-expressive-tea (the agent checks for this name before starting a new container)
|
|
383
|
+
- Anonymous publishing is enabled in the example config (local only). Do not expose to public networks.
|
|
384
|
+
- The config permits overwriting the same package version for easy iterative testing.
|
|
385
|
+
|
|
386
|
+
|
|
387
|
+
### Your First App
|
|
388
|
+
|
|
389
|
+
**1. Create your server:**
|
|
390
|
+
```typescript
|
|
391
|
+
// server.ts
|
|
392
|
+
import 'reflect-metadata';
|
|
393
|
+
import { ServerSettings, Boot } from '@expressive-tea/core';
|
|
394
|
+
|
|
395
|
+
@ServerSettings({
|
|
396
|
+
port: 3000,
|
|
397
|
+
controllers: [HelloController]
|
|
398
|
+
})
|
|
399
|
+
class MyApp extends Boot {}
|
|
400
|
+
|
|
401
|
+
export default MyApp;
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
**2. Add a controller:**
|
|
405
|
+
```typescript
|
|
406
|
+
// controllers/hello.controller.ts
|
|
407
|
+
import { Route, Get } from '@expressive-tea/core';
|
|
408
|
+
|
|
409
|
+
@Route('/hello')
|
|
410
|
+
export class HelloController {
|
|
411
|
+
@Get('/')
|
|
412
|
+
sayHello() {
|
|
413
|
+
return { message: 'Hello, Expressive Tea! 🍵' };
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
**3. Start it up:**
|
|
419
|
+
```typescript
|
|
420
|
+
// main.ts
|
|
421
|
+
import MyApp from './server';
|
|
422
|
+
|
|
423
|
+
const app = new MyApp();
|
|
424
|
+
app.start().then(() => {
|
|
425
|
+
console.log('🚀 Server is running!');
|
|
426
|
+
});
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
**[📚 Full Tutorial →](https://zero-oneit.github.io/expresive-tea/)**
|
|
430
|
+
|
|
431
|
+
---
|
|
432
|
+
|
|
433
|
+
## 🎓 Learn More
|
|
434
|
+
|
|
435
|
+
### 📖 Documentation
|
|
436
|
+
- [Complete Guide](https://zero-oneit.github.io/expresive-tea/) - Full documentation
|
|
437
|
+
- [API Reference](https://zero-oneit.github.io/expresive-tea/api/) - Complete API docs
|
|
438
|
+
- [Examples](https://github.com/Expressive-Tea/expressive-tea-sandbox) - Sample projects
|
|
439
|
+
|
|
440
|
+
### 🆕 v2.0.1 Features
|
|
441
|
+
- [Configuration Files Guide](docs/configuration-files.md) - YAML/JSON config support
|
|
442
|
+
- [Environment Variables Guide](docs/env-decorator.md) - Type-safe env with Zod
|
|
443
|
+
|
|
444
|
+
### 🔄 Migration & Upgrading
|
|
445
|
+
- [Migration Guide v1 → v2](docs/MIGRATION_GUIDE_v2.md) - Step-by-step upgrade
|
|
446
|
+
- [Release Notes v2.0](docs/RELEASE_NOTES_v2.0.0.md) - What's new
|
|
447
|
+
- [Deprecation Notice](docs/DEPRECATION_NOTICE.md) - v1.x timeline
|
|
448
|
+
|
|
449
|
+
### 🛡️ Security
|
|
450
|
+
- [Security Policy](SECURITY.md) - Vulnerability reporting
|
|
451
|
+
- [Changelog](CHANGELOG.md) - Version history
|
|
452
|
+
|
|
453
|
+
---
|
|
454
|
+
|
|
455
|
+
## 🤝 Contributing
|
|
456
|
+
|
|
457
|
+
We love contributions! Whether it's bug fixes, features, or docs.
|
|
458
|
+
|
|
459
|
+
**Quick links:**
|
|
460
|
+
- [Contributing Guide](CONTRIBUTING.md) - How to contribute
|
|
461
|
+
- [Code of Conduct](CODE_OF_CONDUCT.md) - Community guidelines
|
|
462
|
+
- [Issues](https://github.com/Expressive-Tea/expresive-tea/issues) - Report bugs or request features
|
|
463
|
+
|
|
464
|
+
```bash
|
|
465
|
+
# Get started
|
|
466
|
+
git clone https://github.com/Expressive-Tea/expresive-tea.git
|
|
467
|
+
cd expresive-tea
|
|
468
|
+
yarn install
|
|
469
|
+
yarn test
|
|
470
|
+
```
|
|
471
|
+
|
|
472
|
+
### 🤖 AI-Assisted Development & Vibe Coding
|
|
473
|
+
|
|
474
|
+
**We welcome AI-assisted contributions!** Whether you're using GitHub Copilot, Cursor, Claude, or other AI coding assistants, we embrace the future of collaborative development.
|
|
475
|
+
|
|
476
|
+
**⚠️ IMPORTANT: AI-Generated Code Requirements**
|
|
477
|
+
|
|
478
|
+
If you're using AI tools for code generation, you **MUST**:
|
|
479
|
+
|
|
480
|
+
1. **📖 Follow Repository Guidelines**
|
|
481
|
+
- ✅ Read and strictly adhere to [`AGENTS.md`](AGENTS.md) - Agent-specific coding rules
|
|
482
|
+
- ✅ Read and strictly adhere to [`CLAUDE.md`](CLAUDE.md) - Claude AI guidelines
|
|
483
|
+
- ✅ These files contain critical project conventions, style guides, and quality standards
|
|
484
|
+
|
|
485
|
+
2. **👨💻 Human Review is MANDATORY**
|
|
486
|
+
- ✅ **All AI-generated code MUST be reviewed by a human developer** before creating a pull request
|
|
487
|
+
- ✅ Understand the code completely—don't submit code you can't explain
|
|
488
|
+
- ✅ Test thoroughly (aim for 95%+ coverage)
|
|
489
|
+
- ✅ Verify the code follows our architectural patterns and best practices
|
|
490
|
+
|
|
491
|
+
3. **✅ Quality Standards**
|
|
492
|
+
- ✅ All tests must pass (`yarn test`)
|
|
493
|
+
- ✅ Linting must pass (`yarn linter:ci`)
|
|
494
|
+
- ✅ TypeScript must compile without errors (`yarn build`)
|
|
495
|
+
- ✅ Code must match our existing patterns and conventions
|
|
496
|
+
- ✅ Documentation must be updated (JSDoc, README, CHANGELOG)
|
|
497
|
+
|
|
498
|
+
4. **📝 PR Transparency**
|
|
499
|
+
- ✅ Disclose AI assistance in your pull request description
|
|
500
|
+
- ✅ Example: "This PR was developed with assistance from Claude/Copilot/Cursor"
|
|
501
|
+
- ✅ Highlight any sections that were fully AI-generated for extra review
|
|
502
|
+
|
|
503
|
+
**Why These Rules?**
|
|
504
|
+
|
|
505
|
+
- 🛡️ **Quality Assurance** - AI can make subtle mistakes humans catch
|
|
506
|
+
- 🎯 **Consistency** - Ensures code matches our architectural vision
|
|
507
|
+
- 📚 **Knowledge Transfer** - Reviewers understand your contribution
|
|
508
|
+
- 🔒 **Security** - Prevents AI from introducing vulnerabilities
|
|
509
|
+
- 🤝 **Collaboration** - Maintains clear communication in the codebase
|
|
510
|
+
|
|
511
|
+
**Vibe Coding Best Practices:**
|
|
512
|
+
|
|
513
|
+
```typescript
|
|
514
|
+
// ✅ GOOD: AI-generated, reviewed, and refined by human
|
|
515
|
+
@Route('/api/users')
|
|
516
|
+
class UserController {
|
|
517
|
+
@Get('/:id')
|
|
518
|
+
async getUser(@Param('id') id: string): Promise<User> {
|
|
519
|
+
// Human: Added validation per AGENTS.md security guidelines
|
|
520
|
+
if (!id || !validator.isUUID(id)) {
|
|
521
|
+
throw new BadRequestException('Invalid user ID');
|
|
522
|
+
}
|
|
523
|
+
return this.userService.findById(id);
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
// ❌ BAD: AI-generated, unreviewed, missing error handling
|
|
528
|
+
@Route('/api/users')
|
|
529
|
+
class UserController {
|
|
530
|
+
@Get('/:id')
|
|
531
|
+
async getUser(@Param('id') id: string) {
|
|
532
|
+
return this.userService.findById(id); // What if id is invalid?
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
```
|
|
536
|
+
|
|
537
|
+
**📚 Required Reading for AI-Assisted Development:**
|
|
538
|
+
- [`AGENTS.md`](AGENTS.md) - Repository-specific rules for AI agents
|
|
539
|
+
- [`CLAUDE.md`](CLAUDE.md) - Claude AI coding guidelines
|
|
540
|
+
- [`CONTRIBUTING.md`](CONTRIBUTING.md) - General contribution guide
|
|
541
|
+
- [`.prettierrc`](.prettierrc) - Code formatting rules
|
|
542
|
+
- [`eslint.config.js`](eslint.config.js) - Linting configuration
|
|
543
|
+
|
|
544
|
+
**Questions?** Ask in [GitHub Discussions](https://github.com/Expressive-Tea/expresive-tea/discussions) before submitting AI-generated code.
|
|
545
|
+
|
|
546
|
+
---
|
|
547
|
+
|
|
548
|
+
## 💬 Community & Support
|
|
549
|
+
|
|
550
|
+
### Get Help
|
|
551
|
+
- 📖 [Documentation](https://zero-oneit.github.io/expresive-tea/)
|
|
552
|
+
- 💬 [Gitter Chat](https://gitter.im/Expressive-Tea/expresive-tea)
|
|
553
|
+
- 📧 [Email Support](mailto:support@expressive-tea.io)
|
|
554
|
+
- 🐛 [GitHub Issues](https://github.com/Expressive-Tea/expresive-tea/issues)
|
|
555
|
+
- 🔖 [Stack Overflow](https://stackoverflow.com/questions/tagged/expressive-tea) - Use tag `expressive-tea`
|
|
556
|
+
|
|
557
|
+
### Stay Connected
|
|
558
|
+
- 🐦 Twitter: [@expressive_tea](https://twitter.com/expressive_tea)
|
|
559
|
+
- 📧 Email: [support@expressive-tea.io](mailto:support@expressive-tea.io)
|
|
560
|
+
- 👨💻 Author: [Diego Resendez](https://twitter.com/diegoresendez)
|
|
561
|
+
|
|
562
|
+
---
|
|
563
|
+
|
|
564
|
+
## 🌟 Built With
|
|
565
|
+
|
|
566
|
+
| Technology | Purpose |
|
|
567
|
+
|------------|---------|
|
|
568
|
+
| [Express](https://expressjs.com/) | Fast, unopinionated web framework |
|
|
569
|
+
| [TypeScript](https://www.typescriptlang.org/) | Type-safe JavaScript |
|
|
570
|
+
| [InversifyJS](https://inversify.io/) | Powerful dependency injection |
|
|
571
|
+
| [Reflect Metadata](https://github.com/rbuckton/reflect-metadata) | Decorator metadata support |
|
|
572
|
+
|
|
573
|
+
---
|
|
574
|
+
|
|
575
|
+
## 🏆 Sponsors
|
|
576
|
+
|
|
577
|
+
Building Expressive Tea takes time and dedication. If this project helps you, consider sponsoring!
|
|
578
|
+
|
|
579
|
+
**Principal Sponsor:**
|
|
185
580
|
|
|
186
581
|
<p align="center">
|
|
187
|
-
<
|
|
188
|
-
<
|
|
189
|
-
|
|
190
|
-
</a>
|
|
582
|
+
<a href="https://zerooneit.com" target="_blank">
|
|
583
|
+
<img src="images/zero-oneit.png" width="180" alt="Zero-OneIT" />
|
|
584
|
+
</a>
|
|
191
585
|
</p>
|
|
192
586
|
|
|
193
|
-
|
|
587
|
+
**Interested in sponsoring?** Contact [projects@zero-oneit.com](mailto:projects@zero-oneit.com)
|
|
194
588
|
|
|
195
|
-
|
|
589
|
+
---
|
|
196
590
|
|
|
197
|
-
##
|
|
591
|
+
## 📄 License
|
|
198
592
|
|
|
199
|
-
|
|
593
|
+
Apache-2.0 License - see [LICENSE](LICENSE) file for details
|
|
200
594
|
|
|
201
|
-
|
|
595
|
+
<p align="center">
|
|
596
|
+
<a href="https://app.fossa.io/projects/git%2Bgithub.com%2FExpressive-Tea%2Fexpresive-tea?ref=badge_large">
|
|
597
|
+
<img src="https://app.fossa.io/api/projects/git%2Bgithub.com%2FExpressive-Tea%2Fexpresive-tea.svg?type=large" />
|
|
598
|
+
</a>
|
|
599
|
+
</p>
|
|
202
600
|
|
|
203
|
-
|
|
601
|
+
---
|
|
204
602
|
|
|
205
|
-
|
|
603
|
+
## 📌 Versioning
|
|
206
604
|
|
|
207
|
-
|
|
208
|
-
If you are experience any kind of issues we will be happy to help. You can report an issue using the [issues page](https://github.com/Expressive-Tea/expresive-tea/issues) or the [chat](https://gitter.im/Expressive-Tea/expresive-tea). You can also ask questions at [Stack overflow](http://stackoverflow.com/tags/expressive-tea) using the `expressive-tea` tag.
|
|
605
|
+
We use [Semantic Versioning](http://semver.org/) (SemVer). See [tags](https://github.com/Expressive-Tea/expresive-tea/tags) for available versions.
|
|
209
606
|
|
|
210
|
-
|
|
211
|
-
[wiki](https://github.com/Expressive-Tea/expresive-tea/blob/develop/README.md) to learn more about Expressive Tea internals or check our [documentation](https://docs.expressive-tea.io).
|
|
607
|
+
---
|
|
212
608
|
|
|
213
|
-
|
|
214
|
-
#### Principal Sponsors
|
|
609
|
+
## 👥 Contributors
|
|
215
610
|
|
|
216
|
-
|
|
217
|
-
<a href="https://zerooneit.com" target="_blank"><img src="images/zero-oneit.png" width="180" valign="middle" /></a></td><td>
|
|
218
|
-
</tr></table>
|
|
611
|
+
**Lead Developer:** [Diego Resendez](https://github.com/zerooneit)
|
|
219
612
|
|
|
613
|
+
See all [contributors](https://github.com/Expressive-Tea/expresive-tea/contributors) who've helped shape Expressive Tea.
|
|
220
614
|
|
|
221
|
-
|
|
615
|
+
---
|
|
222
616
|
|
|
223
|
-
|
|
224
|
-
* Twitter - [@expressive_tea](https://twitter.com/expressive_tea)
|
|
225
|
-
* Email - [support@expressive-tea.io](support@expressive-tea.io)
|
|
617
|
+
## ❤️ Credits
|
|
226
618
|
|
|
227
|
-
|
|
228
|
-
|
|
619
|
+
Logo and banner designed by [Freepik](http://www.freepik.com)
|
|
620
|
+
|
|
621
|
+
---
|
|
229
622
|
|
|
230
623
|
<p align="center">
|
|
231
|
-
|
|
232
|
-
<
|
|
233
|
-
|
|
624
|
+
Made with ☕ and 🍵 by the Expressive Tea Team
|
|
625
|
+
<br />
|
|
626
|
+
<sub>Start brewing better Node.js apps today!</sub>
|
|
234
627
|
</p>
|
|
235
|
-
|
|
236
|
-
## Disclaimers
|
|
237
|
-
The banner and the logo is a derivate work [Designed by Freepik](http://www.freepik.com)
|