@objectstack/runtime 0.6.1 → 0.7.1
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/CHANGELOG.md +10 -0
- package/dist/app-plugin.js +34 -6
- package/dist/driver-plugin.js +6 -2
- package/dist/http-server.d.ts +84 -0
- package/dist/http-server.js +125 -0
- package/dist/index.d.ts +6 -2
- package/dist/index.js +7 -2
- package/dist/middleware.d.ts +111 -0
- package/dist/middleware.js +176 -0
- package/dist/rest-server.d.ts +74 -0
- package/dist/rest-server.js +490 -0
- package/dist/route-manager.d.ts +153 -0
- package/dist/route-manager.js +251 -0
- package/package.json +4 -4
- package/src/app-plugin.ts +37 -6
- package/src/driver-plugin.ts +6 -2
- package/src/http-server.ts +140 -0
- package/src/index.ts +9 -2
- package/src/middleware.ts +220 -0
- package/src/rest-server.ts +579 -0
- package/src/route-manager.ts +305 -0
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
import { Middleware, IHttpRequest, IHttpResponse } from '@objectstack/core';
|
|
2
|
+
import { MiddlewareConfig, MiddlewareType } from '@objectstack/spec/system';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Middleware Entry
|
|
6
|
+
* Internal representation of registered middleware
|
|
7
|
+
*/
|
|
8
|
+
interface MiddlewareEntry {
|
|
9
|
+
name: string;
|
|
10
|
+
type: MiddlewareType;
|
|
11
|
+
middleware: Middleware;
|
|
12
|
+
order: number;
|
|
13
|
+
enabled: boolean;
|
|
14
|
+
paths?: {
|
|
15
|
+
include?: string[];
|
|
16
|
+
exclude?: string[];
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* MiddlewareManager
|
|
22
|
+
*
|
|
23
|
+
* Manages middleware registration, ordering, and execution.
|
|
24
|
+
* Provides fine-grained control over middleware chains with:
|
|
25
|
+
* - Execution order management
|
|
26
|
+
* - Path-based filtering
|
|
27
|
+
* - Enable/disable individual middleware
|
|
28
|
+
* - Middleware categorization by type
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* const manager = new MiddlewareManager();
|
|
32
|
+
*
|
|
33
|
+
* // Register middleware with configuration
|
|
34
|
+
* manager.register({
|
|
35
|
+
* name: 'auth',
|
|
36
|
+
* type: 'authentication',
|
|
37
|
+
* order: 10,
|
|
38
|
+
* paths: { exclude: ['/health', '/metrics'] }
|
|
39
|
+
* }, authMiddleware);
|
|
40
|
+
*
|
|
41
|
+
* // Get sorted middleware chain
|
|
42
|
+
* const chain = manager.getMiddlewareChain();
|
|
43
|
+
* chain.forEach(mw => server.use(mw));
|
|
44
|
+
*/
|
|
45
|
+
export class MiddlewareManager {
|
|
46
|
+
private middlewares: Map<string, MiddlewareEntry>;
|
|
47
|
+
|
|
48
|
+
constructor() {
|
|
49
|
+
this.middlewares = new Map();
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Register middleware with configuration
|
|
54
|
+
* @param config - Middleware configuration
|
|
55
|
+
* @param middleware - Middleware function
|
|
56
|
+
*/
|
|
57
|
+
register(config: MiddlewareConfig, middleware: Middleware): void {
|
|
58
|
+
const entry: MiddlewareEntry = {
|
|
59
|
+
name: config.name,
|
|
60
|
+
type: config.type,
|
|
61
|
+
middleware,
|
|
62
|
+
order: config.order ?? 100,
|
|
63
|
+
enabled: config.enabled ?? true,
|
|
64
|
+
paths: config.paths,
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
this.middlewares.set(config.name, entry);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Unregister middleware by name
|
|
72
|
+
* @param name - Middleware name
|
|
73
|
+
*/
|
|
74
|
+
unregister(name: string): void {
|
|
75
|
+
this.middlewares.delete(name);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Enable middleware by name
|
|
80
|
+
* @param name - Middleware name
|
|
81
|
+
*/
|
|
82
|
+
enable(name: string): void {
|
|
83
|
+
const entry = this.middlewares.get(name);
|
|
84
|
+
if (entry) {
|
|
85
|
+
entry.enabled = true;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Disable middleware by name
|
|
91
|
+
* @param name - Middleware name
|
|
92
|
+
*/
|
|
93
|
+
disable(name: string): void {
|
|
94
|
+
const entry = this.middlewares.get(name);
|
|
95
|
+
if (entry) {
|
|
96
|
+
entry.enabled = false;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Get middleware entry by name
|
|
102
|
+
* @param name - Middleware name
|
|
103
|
+
*/
|
|
104
|
+
get(name: string): MiddlewareEntry | undefined {
|
|
105
|
+
return this.middlewares.get(name);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Get all middleware entries
|
|
110
|
+
*/
|
|
111
|
+
getAll(): MiddlewareEntry[] {
|
|
112
|
+
return Array.from(this.middlewares.values());
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Get middleware by type
|
|
117
|
+
* @param type - Middleware type
|
|
118
|
+
*/
|
|
119
|
+
getByType(type: MiddlewareType): MiddlewareEntry[] {
|
|
120
|
+
return this.getAll().filter(entry => entry.type === type);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Get middleware chain sorted by order
|
|
125
|
+
* Returns only enabled middleware
|
|
126
|
+
*/
|
|
127
|
+
getMiddlewareChain(): Middleware[] {
|
|
128
|
+
return this.getAll()
|
|
129
|
+
.filter(entry => entry.enabled)
|
|
130
|
+
.sort((a, b) => a.order - b.order)
|
|
131
|
+
.map(entry => entry.middleware);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Get middleware chain with path filtering
|
|
136
|
+
* @param path - Request path to match against
|
|
137
|
+
*/
|
|
138
|
+
getMiddlewareChainForPath(path: string): Middleware[] {
|
|
139
|
+
return this.getAll()
|
|
140
|
+
.filter(entry => {
|
|
141
|
+
if (!entry.enabled) return false;
|
|
142
|
+
|
|
143
|
+
// Check path filters
|
|
144
|
+
if (entry.paths) {
|
|
145
|
+
// Check exclude patterns
|
|
146
|
+
if (entry.paths.exclude) {
|
|
147
|
+
const excluded = entry.paths.exclude.some(pattern =>
|
|
148
|
+
this.matchPath(path, pattern)
|
|
149
|
+
);
|
|
150
|
+
if (excluded) return false;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// Check include patterns (if specified)
|
|
154
|
+
if (entry.paths.include) {
|
|
155
|
+
const included = entry.paths.include.some(pattern =>
|
|
156
|
+
this.matchPath(path, pattern)
|
|
157
|
+
);
|
|
158
|
+
if (!included) return false;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
return true;
|
|
163
|
+
})
|
|
164
|
+
.sort((a, b) => a.order - b.order)
|
|
165
|
+
.map(entry => entry.middleware);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Match path against pattern (simple glob matching)
|
|
170
|
+
* @param path - Request path
|
|
171
|
+
* @param pattern - Pattern to match (supports * wildcard)
|
|
172
|
+
*/
|
|
173
|
+
private matchPath(path: string, pattern: string): boolean {
|
|
174
|
+
// Convert glob pattern to regex
|
|
175
|
+
const regexPattern = pattern
|
|
176
|
+
.replace(/\*/g, '.*')
|
|
177
|
+
.replace(/\?/g, '.');
|
|
178
|
+
|
|
179
|
+
const regex = new RegExp(`^${regexPattern}$`);
|
|
180
|
+
return regex.test(path);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Clear all middleware
|
|
185
|
+
*/
|
|
186
|
+
clear(): void {
|
|
187
|
+
this.middlewares.clear();
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Get middleware count
|
|
192
|
+
*/
|
|
193
|
+
count(): number {
|
|
194
|
+
return this.middlewares.size;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Create a composite middleware from the chain
|
|
199
|
+
* This can be used to apply all middleware at once
|
|
200
|
+
*/
|
|
201
|
+
createCompositeMiddleware(): Middleware {
|
|
202
|
+
const chain = this.getMiddlewareChain();
|
|
203
|
+
|
|
204
|
+
return async (req: IHttpRequest, res: IHttpResponse, next: () => void | Promise<void>) => {
|
|
205
|
+
let index = 0;
|
|
206
|
+
|
|
207
|
+
const executeNext = async (): Promise<void> => {
|
|
208
|
+
if (index >= chain.length) {
|
|
209
|
+
await next();
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
const middleware = chain[index++];
|
|
214
|
+
await middleware(req, res, executeNext);
|
|
215
|
+
};
|
|
216
|
+
|
|
217
|
+
await executeNext();
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
}
|