@mini2/core 2.0.1-beta.0 → 2.0.1-beta.4
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/Readme.MD +177 -0
- package/dist/api-docs/postman.d.ts +123 -0
- package/dist/api-docs/postman.d.ts.map +1 -0
- package/dist/api-docs/postman.js +358 -0
- package/dist/api-docs/postman.js.map +1 -0
- package/dist/{swagger.d.ts → api-docs/swagger.d.ts} +1 -1
- package/dist/api-docs/swagger.d.ts.map +1 -0
- package/dist/{swagger.js → api-docs/swagger.js} +122 -91
- package/dist/api-docs/swagger.js.map +1 -0
- package/dist/app.d.ts.map +1 -1
- package/dist/app.js +17 -1
- package/dist/app.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/interfaces/config.interface.d.ts +1 -0
- package/dist/interfaces/config.interface.d.ts.map +1 -1
- package/dist/local-test-server/index.d.ts +2 -0
- package/dist/local-test-server/index.d.ts.map +1 -0
- package/dist/local-test-server/index.js +23 -0
- package/dist/local-test-server/index.js.map +1 -0
- package/dist/local-test-server/local-test-controller.d.ts +14 -0
- package/dist/local-test-server/local-test-controller.d.ts.map +1 -0
- package/dist/local-test-server/local-test-controller.js +160 -0
- package/dist/local-test-server/local-test-controller.js.map +1 -0
- package/dist/notations/controller/rest.types.d.ts +13 -8
- package/dist/notations/controller/rest.types.d.ts.map +1 -1
- package/local-test-server/Local Test Server.postman_collection.json +359 -0
- package/package.json +2 -1
- package/dist/swagger.d.ts.map +0 -1
- package/dist/swagger.js.map +0 -1
package/Readme.MD
CHANGED
|
@@ -6,10 +6,14 @@
|
|
|
6
6
|
|
|
7
7
|
- 🚀 **Decorator-Based Routing**: Easy route definition with decorators like `@get`, `@post`
|
|
8
8
|
- 📝 **Automatic Swagger Documentation**: API documentation generated automatically
|
|
9
|
+
- 🧪 **Example-Driven OpenAPI**: Generate request/response schemas and examples from `RouteOptions.examples`
|
|
10
|
+
- 🧰 **Postman-Friendly Metadata**: Attach `@preRequestScript` / `@testScript` to operations via OpenAPI vendor extensions
|
|
9
11
|
- 🔧 **Dependency Injection**: Powerful DI container based on InversifyJS
|
|
10
12
|
- 🛡️ **Security Middlewares**: Authentication, authorization, and validation
|
|
13
|
+
- 🔒 **Swagger Basic Auth**: Optionally protect Swagger UI and JSON spec endpoints with Basic Authentication
|
|
11
14
|
- 📦 **Full TypeScript Support**: Type-safe API development
|
|
12
15
|
- 🎯 **Response Builder**: Consistent API responses
|
|
16
|
+
- 🧭 **Autoload Controllers/Injectables**: Optional filesystem-based autoload to discover modules automatically
|
|
13
17
|
- ⚡ **Quick Setup**: Minimal configuration required
|
|
14
18
|
|
|
15
19
|
## 📦 Installation
|
|
@@ -264,6 +268,43 @@ async downloadFile(@req() req: Request, @res() res: Response) {
|
|
|
264
268
|
}
|
|
265
269
|
```
|
|
266
270
|
|
|
271
|
+
#### **@body() / @query() / @params() / @headers()**
|
|
272
|
+
|
|
273
|
+
Inject validated/normalized request data into method parameters. When validation is enabled via `@validate(...)`, these decorators prefer the validated instance (class-transformer + class-validator) and fall back to raw Express data.
|
|
274
|
+
|
|
275
|
+
```typescript
|
|
276
|
+
@put('/:id')
|
|
277
|
+
@validate({
|
|
278
|
+
params: IdParamsDto,
|
|
279
|
+
query: SearchQueryDto,
|
|
280
|
+
body: UpdateDto,
|
|
281
|
+
headers: MyHeadersDto,
|
|
282
|
+
})
|
|
283
|
+
async update(
|
|
284
|
+
@params() params: IdParamsDto,
|
|
285
|
+
@query() query: SearchQueryDto,
|
|
286
|
+
@body() body: UpdateDto,
|
|
287
|
+
@headers() headers: MyHeadersDto,
|
|
288
|
+
) {
|
|
289
|
+
return new ResponseBuilder().ok({ params, query, body, headers });
|
|
290
|
+
}
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
#### **@next()**
|
|
294
|
+
|
|
295
|
+
Injects Express `next` into your handler (useful for `next(err)` patterns when you want to delegate error handling).
|
|
296
|
+
|
|
297
|
+
```typescript
|
|
298
|
+
@get('/health')
|
|
299
|
+
health(@next() next: NextFunction) {
|
|
300
|
+
try {
|
|
301
|
+
// ...
|
|
302
|
+
} catch (e) {
|
|
303
|
+
next(e);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
```
|
|
307
|
+
|
|
267
308
|
### 🛡️ Security Decorators
|
|
268
309
|
|
|
269
310
|
#### **@authenticated()**
|
|
@@ -314,6 +355,16 @@ async getReports(@req() req: Request) {
|
|
|
314
355
|
- Uses OR logic: user needs ANY of the specified permissions
|
|
315
356
|
- Throws `ForbiddenException` if insufficient permissions
|
|
316
357
|
|
|
358
|
+
#### **Default Header-Based Auth (for local/test setups)**
|
|
359
|
+
|
|
360
|
+
The built-in `authenticatedMiddleware` and `authorizedMiddleware` support a simple header-based flow that is convenient for local development and tests:
|
|
361
|
+
|
|
362
|
+
- `x-authenticated`: `"true" | "1" | "yes" | "y"` (required for authenticated routes)
|
|
363
|
+
- `x-user-id`: user identifier (optional)
|
|
364
|
+
- `x-user-permissions`: comma-separated permissions (optional, e.g. `"admin,reader"`)
|
|
365
|
+
|
|
366
|
+
If authentication fails, an `UnauthorizedException` is thrown; if authorization fails, a `ForbiddenException` is thrown.
|
|
367
|
+
|
|
317
368
|
### ✅ Validation Decorators
|
|
318
369
|
|
|
319
370
|
#### **@validate(options: ValidationOptions)**
|
|
@@ -340,6 +391,7 @@ async createUser(@req() req: Request) {
|
|
|
340
391
|
- `body`: DTO class for request body validation
|
|
341
392
|
- `params`: DTO class for URL parameters validation
|
|
342
393
|
- `query`: DTO class for query parameters validation
|
|
394
|
+
- `headers`: DTO class for header validation
|
|
343
395
|
|
|
344
396
|
**Example DTO Classes:**
|
|
345
397
|
|
|
@@ -604,6 +656,16 @@ async createUser(@req() req: Request) {
|
|
|
604
656
|
- `body` - Request body validation
|
|
605
657
|
- `params` - URL parameters validation
|
|
606
658
|
- `query` - Query parameters validation
|
|
659
|
+
- `headers` - Request header validation
|
|
660
|
+
|
|
661
|
+
**Advanced options (via `@validate`)**
|
|
662
|
+
|
|
663
|
+
Each validation entry can be configured with:
|
|
664
|
+
|
|
665
|
+
- `transformOptions`: class-transformer options
|
|
666
|
+
- `validatorOptions`: class-validator options
|
|
667
|
+
- `logging`: debug logs for source/transformed payloads
|
|
668
|
+
- `customHttpError`: override the default 400 response with a custom `HttpException`
|
|
607
669
|
|
|
608
670
|
#### **authenticatedMiddleware**
|
|
609
671
|
|
|
@@ -855,6 +917,58 @@ const swaggerOptions = {
|
|
|
855
917
|
};
|
|
856
918
|
```
|
|
857
919
|
|
|
920
|
+
#### **🧪 Example-Driven OpenAPI (Schemas + Examples)**
|
|
921
|
+
|
|
922
|
+
You can provide concrete request/response examples per route. If `examples` are present, Swagger generation prefers them to:
|
|
923
|
+
|
|
924
|
+
- Build request body schemas and attach `example`
|
|
925
|
+
- Generate path/query/header parameters (with examples when available)
|
|
926
|
+
- Generate **all response status codes** with `example` and `examples.default` for compatibility
|
|
927
|
+
|
|
928
|
+
Example (simplified):
|
|
929
|
+
|
|
930
|
+
```typescript
|
|
931
|
+
@post('/create', 'Create', {
|
|
932
|
+
examples: [{
|
|
933
|
+
request: {
|
|
934
|
+
body: { title: 'Test Item', order: 1 },
|
|
935
|
+
params: { id: '123' },
|
|
936
|
+
query: { page: 1 },
|
|
937
|
+
headers: { 'x-echo': 'hello' },
|
|
938
|
+
},
|
|
939
|
+
response: {
|
|
940
|
+
201: { description: 'Created', data: { ok: true } },
|
|
941
|
+
400: { description: 'Validation error', data: { error: 'Validation failed' } },
|
|
942
|
+
},
|
|
943
|
+
}],
|
|
944
|
+
})
|
|
945
|
+
create() { /* ... */ }
|
|
946
|
+
```
|
|
947
|
+
|
|
948
|
+
#### **🧰 Postman Scripts via OpenAPI Vendor Extensions**
|
|
949
|
+
|
|
950
|
+
Attach Postman-compatible scripts to a route:
|
|
951
|
+
|
|
952
|
+
- `@preRequestScript(script: string)` → `x-postman-prerequest`
|
|
953
|
+
- `@testScript(script: string)` → `x-postman-test`
|
|
954
|
+
|
|
955
|
+
Swagger/OpenAPI will include them as vendor extensions on the operation, and also as a combined `x-postman-events` list (when present). This is useful for tooling that can import OpenAPI and preserve Postman behaviors.
|
|
956
|
+
|
|
957
|
+
#### **🔒 Protect Swagger with Basic Auth**
|
|
958
|
+
|
|
959
|
+
To protect Swagger UI and the raw OpenAPI JSON spec, set `swaggerBasicAuth` in `IConfig`:
|
|
960
|
+
|
|
961
|
+
```typescript
|
|
962
|
+
await app.init({
|
|
963
|
+
host: 'localhost',
|
|
964
|
+
port: 3000,
|
|
965
|
+
applicationName: 'Protected API',
|
|
966
|
+
swaggerBasicAuth: { username: 'admin', password: 'secret123' },
|
|
967
|
+
});
|
|
968
|
+
```
|
|
969
|
+
|
|
970
|
+
This will protect both `docsPath` and `jsonPath` endpoints (defaults: `/api-docs` and `/api-docs.json`).
|
|
971
|
+
|
|
858
972
|
#### **🔐 Security Documentation**
|
|
859
973
|
|
|
860
974
|
Security decorators automatically add authentication requirements:
|
|
@@ -898,6 +1012,36 @@ async createUser(@req() req: Request) {
|
|
|
898
1012
|
- OpenAPI JSON can be used with external documentation tools
|
|
899
1013
|
- All validation errors are automatically documented with examples
|
|
900
1014
|
|
|
1015
|
+
### 🧭 Autoload (Filesystem Discovery)
|
|
1016
|
+
|
|
1017
|
+
The framework can automatically discover and load controllers/injectables from a directory (useful for local dev, tests, and modular apps).
|
|
1018
|
+
|
|
1019
|
+
```typescript
|
|
1020
|
+
await app.init(
|
|
1021
|
+
{ host: 'localhost', port: 3000, applicationName: 'My API' },
|
|
1022
|
+
{
|
|
1023
|
+
autoload: true,
|
|
1024
|
+
workingDirectory: __dirname,
|
|
1025
|
+
extensions: ['.ts', '.mts', '.cts'],
|
|
1026
|
+
patterns: ['**/*.(ts|js)'],
|
|
1027
|
+
logging: true,
|
|
1028
|
+
}
|
|
1029
|
+
);
|
|
1030
|
+
```
|
|
1031
|
+
|
|
1032
|
+
Notes:
|
|
1033
|
+
|
|
1034
|
+
- Files starting with `//mini-dont-auto-load` are skipped.
|
|
1035
|
+
- In production you typically point `workingDirectory` to your compiled output (e.g. `dist`).
|
|
1036
|
+
|
|
1037
|
+
### 🧪 Local Test Server + Postman Collection
|
|
1038
|
+
|
|
1039
|
+
This repo includes a runnable demo server and an example Postman collection to quickly validate Swagger generation, examples, and Postman script extensions:
|
|
1040
|
+
|
|
1041
|
+
- `local-test-server/index.ts`: starts the server with autoload enabled
|
|
1042
|
+
- `local-test-server/local-test-controller.ts`: demonstrates `examples`, `@preRequestScript`, and `@testScript`
|
|
1043
|
+
- `local-test-server/Local Test Server.postman_collection.json`: ready-to-import collection
|
|
1044
|
+
|
|
901
1045
|
### 📝 TypeScript Support
|
|
902
1046
|
|
|
903
1047
|
Full TypeScript support with type-safe API development:
|
|
@@ -1016,6 +1160,39 @@ export class UserController {
|
|
|
1016
1160
|
}
|
|
1017
1161
|
```
|
|
1018
1162
|
|
|
1163
|
+
### 🔎 DI Auto Discovery (`autoBind` + `bindDiscovered`)
|
|
1164
|
+
|
|
1165
|
+
For modular apps, you can register bindings via decorators and then bind them in one shot.
|
|
1166
|
+
|
|
1167
|
+
```typescript
|
|
1168
|
+
import { autoBind, bindDiscovered, MINI_TYPES } from '@mini2/core';
|
|
1169
|
+
|
|
1170
|
+
@autoBind(MINI_TYPES.IController, { scope: 'Transient', priority: 10 })
|
|
1171
|
+
@controller('/api/users')
|
|
1172
|
+
export class UserController extends Controller {}
|
|
1173
|
+
|
|
1174
|
+
// After loading modules (or using autoload), bind everything discovered:
|
|
1175
|
+
bindDiscovered();
|
|
1176
|
+
```
|
|
1177
|
+
|
|
1178
|
+
Notes:
|
|
1179
|
+
|
|
1180
|
+
- Supported scopes: `Singleton`, `Transient`, `Request`
|
|
1181
|
+
- `priority` controls binding order (lower first)
|
|
1182
|
+
|
|
1183
|
+
### 🧩 Custom Route Metadata (`@custom`)
|
|
1184
|
+
|
|
1185
|
+
If you want to attach arbitrary metadata to a route (e.g., for tooling), use `@custom(key, value)` which stores data in `RouteOptions.extraData`.
|
|
1186
|
+
|
|
1187
|
+
```typescript
|
|
1188
|
+
@get('/reports')
|
|
1189
|
+
@custom('x-internal-owner', 'analytics')
|
|
1190
|
+
@custom('x-stability', 'beta')
|
|
1191
|
+
async reports() {
|
|
1192
|
+
return new ResponseBuilder().ok({ ok: true });
|
|
1193
|
+
}
|
|
1194
|
+
```
|
|
1195
|
+
|
|
1019
1196
|
## 📋 Complete Export List
|
|
1020
1197
|
|
|
1021
1198
|
```typescript
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import 'reflect-metadata';
|
|
2
|
+
import { Express } from 'express';
|
|
3
|
+
import { ISwaggerBasicAuth } from '../interfaces/config.interface';
|
|
4
|
+
type PostmanScript = {
|
|
5
|
+
type: 'text/javascript';
|
|
6
|
+
exec: string[];
|
|
7
|
+
};
|
|
8
|
+
type PostmanEvent = {
|
|
9
|
+
listen: 'prerequest' | 'test';
|
|
10
|
+
script: PostmanScript;
|
|
11
|
+
};
|
|
12
|
+
type PostmanHeader = {
|
|
13
|
+
key: string;
|
|
14
|
+
value: string;
|
|
15
|
+
};
|
|
16
|
+
type PostmanQuery = {
|
|
17
|
+
key: string;
|
|
18
|
+
value: string;
|
|
19
|
+
};
|
|
20
|
+
type PostmanVariable = {
|
|
21
|
+
key: string;
|
|
22
|
+
value: string;
|
|
23
|
+
};
|
|
24
|
+
type PostmanUrl = {
|
|
25
|
+
raw: string;
|
|
26
|
+
host: string[];
|
|
27
|
+
path: string[];
|
|
28
|
+
query?: PostmanQuery[];
|
|
29
|
+
variable?: PostmanVariable[];
|
|
30
|
+
};
|
|
31
|
+
type PostmanRequest = {
|
|
32
|
+
method: string;
|
|
33
|
+
header: PostmanHeader[];
|
|
34
|
+
url: PostmanUrl;
|
|
35
|
+
description?: string;
|
|
36
|
+
body?: {
|
|
37
|
+
mode: 'raw';
|
|
38
|
+
raw: string;
|
|
39
|
+
options: {
|
|
40
|
+
raw: {
|
|
41
|
+
language: 'json';
|
|
42
|
+
examples?: unknown[];
|
|
43
|
+
};
|
|
44
|
+
};
|
|
45
|
+
};
|
|
46
|
+
};
|
|
47
|
+
type PostmanResponse = {
|
|
48
|
+
name: string;
|
|
49
|
+
originalRequest: PostmanRequest;
|
|
50
|
+
status: string;
|
|
51
|
+
code: number;
|
|
52
|
+
_postman_previewlanguage: 'json' | 'text';
|
|
53
|
+
header: PostmanHeader[];
|
|
54
|
+
cookie: unknown[];
|
|
55
|
+
body: string;
|
|
56
|
+
};
|
|
57
|
+
type PostmanRequestItem = {
|
|
58
|
+
name: string;
|
|
59
|
+
event?: PostmanEvent[];
|
|
60
|
+
request: PostmanRequest;
|
|
61
|
+
response: PostmanResponse[];
|
|
62
|
+
};
|
|
63
|
+
type PostmanFolderItem = {
|
|
64
|
+
name: string;
|
|
65
|
+
item: PostmanRequestItem[];
|
|
66
|
+
};
|
|
67
|
+
type PostmanCollection = {
|
|
68
|
+
info: {
|
|
69
|
+
_postman_id: string;
|
|
70
|
+
name: string;
|
|
71
|
+
description: string;
|
|
72
|
+
schema: string;
|
|
73
|
+
};
|
|
74
|
+
item: PostmanFolderItem[];
|
|
75
|
+
variable: Array<{
|
|
76
|
+
key: string;
|
|
77
|
+
value: string;
|
|
78
|
+
}>;
|
|
79
|
+
};
|
|
80
|
+
export interface IPostmanIntegrationOptions {
|
|
81
|
+
title?: string;
|
|
82
|
+
description?: string;
|
|
83
|
+
version?: string;
|
|
84
|
+
servers?: Array<{
|
|
85
|
+
url: string;
|
|
86
|
+
description: string;
|
|
87
|
+
}>;
|
|
88
|
+
jsonPath?: string;
|
|
89
|
+
basicAuth?: ISwaggerBasicAuth;
|
|
90
|
+
baseUrlVariableName?: string;
|
|
91
|
+
}
|
|
92
|
+
export declare class PostmanIntegration {
|
|
93
|
+
private postmanCollection;
|
|
94
|
+
private options;
|
|
95
|
+
constructor(options?: IPostmanIntegrationOptions);
|
|
96
|
+
generatePostmanCollection(controllers: any[]): void;
|
|
97
|
+
setupPostman(app: Express): void;
|
|
98
|
+
getPostmanCollection(): PostmanCollection | null;
|
|
99
|
+
private buildRequestItem;
|
|
100
|
+
private buildRequest;
|
|
101
|
+
private extractBodyExamples;
|
|
102
|
+
private buildResponses;
|
|
103
|
+
private createDefaultResponse;
|
|
104
|
+
private buildEvents;
|
|
105
|
+
private toPostmanScript;
|
|
106
|
+
private buildQuery;
|
|
107
|
+
private buildPathVariables;
|
|
108
|
+
private extractPathVariables;
|
|
109
|
+
private extractPostmanPath;
|
|
110
|
+
private defaultStatusForMethod;
|
|
111
|
+
private stringifyScalar;
|
|
112
|
+
private isRecord;
|
|
113
|
+
private generateSummary;
|
|
114
|
+
private generateDescription;
|
|
115
|
+
private extractControllerFolderName;
|
|
116
|
+
private extractResourceName;
|
|
117
|
+
private getDefaultBaseUrl;
|
|
118
|
+
private buildCollectionDescription;
|
|
119
|
+
private generateCollectionId;
|
|
120
|
+
private basicAuthMiddleware;
|
|
121
|
+
}
|
|
122
|
+
export default PostmanIntegration;
|
|
123
|
+
//# sourceMappingURL=postman.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"postman.d.ts","sourceRoot":"","sources":["../../api-docs/postman.ts"],"names":[],"mappings":"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"}
|