te.js 2.0.0 → 2.0.3
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 +25 -0
- package/docs/README.md +1 -1
- package/docs/getting-started.md +34 -0
- package/package.json +13 -2
- package/.cursor/plans/ai_native_framework_features_5bb1a20a.plan.md +0 -234
- package/.cursor/plans/auto_error_fix_agent_e68979c5.plan.md +0 -356
- package/.cursor/plans/tejas_framework_test_suite_5e3c6fad.plan.md +0 -168
- package/.prettierignore +0 -31
- package/.prettierrc +0 -5
- package/example/API_OVERVIEW.md +0 -77
- package/example/README.md +0 -155
- package/example/index.js +0 -29
- package/example/middlewares/auth.js +0 -9
- package/example/middlewares/global.midair.js +0 -6
- package/example/openapi.json +0 -390
- package/example/package.json +0 -23
- package/example/services/cache.service.js +0 -25
- package/example/services/user.service.js +0 -42
- package/example/start-redis.js +0 -2
- package/example/targets/cache.target.js +0 -35
- package/example/targets/index.target.js +0 -16
- package/example/targets/users.target.js +0 -60
- package/example/tejas.config.json +0 -22
- package/tests/auto-docs/handler-analyzer.test.js +0 -44
- package/tests/auto-docs/openapi-generator.test.js +0 -103
- package/tests/auto-docs/parse.test.js +0 -63
- package/tests/auto-docs/source-resolver.test.js +0 -58
- package/tests/helpers/index.js +0 -37
- package/tests/helpers/mock-http.js +0 -342
- package/tests/helpers/test-utils.js +0 -446
- package/tests/setup.test.js +0 -148
- package/vitest.config.js +0 -54
|
@@ -1,342 +0,0 @@
|
|
|
1
|
-
import { EventEmitter } from 'events';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Mock HTTP IncomingMessage (request) object
|
|
5
|
-
* Simulates Node.js http.IncomingMessage for testing
|
|
6
|
-
*/
|
|
7
|
-
export class MockRequest extends EventEmitter {
|
|
8
|
-
constructor(options = {}) {
|
|
9
|
-
super();
|
|
10
|
-
|
|
11
|
-
this.method = options.method || 'GET';
|
|
12
|
-
this.url = options.url || '/';
|
|
13
|
-
this.headers = options.headers || {};
|
|
14
|
-
this.httpVersion = options.httpVersion || '1.1';
|
|
15
|
-
this.socket = options.socket || {
|
|
16
|
-
remoteAddress: options.ip || '127.0.0.1',
|
|
17
|
-
encrypted: options.encrypted || false,
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
// Body handling
|
|
21
|
-
this._body = options.body || '';
|
|
22
|
-
this._bodyChunks = [];
|
|
23
|
-
|
|
24
|
-
// Connection info
|
|
25
|
-
this.connection = this.socket;
|
|
26
|
-
|
|
27
|
-
// Normalize headers to lowercase
|
|
28
|
-
this.headers = Object.keys(this.headers).reduce((acc, key) => {
|
|
29
|
-
acc[key.toLowerCase()] = this.headers[key];
|
|
30
|
-
return acc;
|
|
31
|
-
}, {});
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Simulate incoming data by emitting chunks
|
|
36
|
-
*/
|
|
37
|
-
simulateBody(body) {
|
|
38
|
-
if (typeof body === 'string') {
|
|
39
|
-
this.emit('data', Buffer.from(body));
|
|
40
|
-
} else if (Buffer.isBuffer(body)) {
|
|
41
|
-
this.emit('data', body);
|
|
42
|
-
} else if (typeof body === 'object') {
|
|
43
|
-
this.emit('data', Buffer.from(JSON.stringify(body)));
|
|
44
|
-
}
|
|
45
|
-
this.emit('end');
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* Immediately emit body data (for sync tests)
|
|
50
|
-
*/
|
|
51
|
-
pipe(destination) {
|
|
52
|
-
if (this._body) {
|
|
53
|
-
destination.write(this._body);
|
|
54
|
-
}
|
|
55
|
-
return destination;
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* Mock HTTP ServerResponse (response) object
|
|
61
|
-
* Simulates Node.js http.ServerResponse for testing
|
|
62
|
-
*/
|
|
63
|
-
export class MockResponse extends EventEmitter {
|
|
64
|
-
constructor() {
|
|
65
|
-
super();
|
|
66
|
-
|
|
67
|
-
this.statusCode = 200;
|
|
68
|
-
this.statusMessage = '';
|
|
69
|
-
this.headers = {};
|
|
70
|
-
this._body = '';
|
|
71
|
-
this._chunks = [];
|
|
72
|
-
|
|
73
|
-
// Response state flags
|
|
74
|
-
this.headersSent = false;
|
|
75
|
-
this.writableEnded = false;
|
|
76
|
-
this.finished = false;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* Set response status code and headers
|
|
81
|
-
*/
|
|
82
|
-
writeHead(statusCode, statusMessage, headers) {
|
|
83
|
-
if (this.headersSent) {
|
|
84
|
-
throw new Error('Headers already sent');
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
this.statusCode = statusCode;
|
|
88
|
-
|
|
89
|
-
// Handle optional statusMessage
|
|
90
|
-
if (typeof statusMessage === 'object') {
|
|
91
|
-
headers = statusMessage;
|
|
92
|
-
statusMessage = '';
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
this.statusMessage = statusMessage || '';
|
|
96
|
-
|
|
97
|
-
if (headers) {
|
|
98
|
-
Object.keys(headers).forEach((key) => {
|
|
99
|
-
this.headers[key.toLowerCase()] = headers[key];
|
|
100
|
-
});
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
this.headersSent = true;
|
|
104
|
-
return this;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
/**
|
|
108
|
-
* Set a single header
|
|
109
|
-
*/
|
|
110
|
-
setHeader(name, value) {
|
|
111
|
-
if (this.headersSent) {
|
|
112
|
-
throw new Error('Headers already sent');
|
|
113
|
-
}
|
|
114
|
-
this.headers[name.toLowerCase()] = value;
|
|
115
|
-
return this;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
/**
|
|
119
|
-
* Get a header value
|
|
120
|
-
*/
|
|
121
|
-
getHeader(name) {
|
|
122
|
-
return this.headers[name.toLowerCase()];
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
/**
|
|
126
|
-
* Remove a header
|
|
127
|
-
*/
|
|
128
|
-
removeHeader(name) {
|
|
129
|
-
delete this.headers[name.toLowerCase()];
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
/**
|
|
133
|
-
* Check if a header has been set
|
|
134
|
-
*/
|
|
135
|
-
hasHeader(name) {
|
|
136
|
-
return name.toLowerCase() in this.headers;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
/**
|
|
140
|
-
* Write data to response body
|
|
141
|
-
*/
|
|
142
|
-
write(chunk, encoding, callback) {
|
|
143
|
-
if (this.writableEnded) {
|
|
144
|
-
throw new Error('Write after end');
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
if (chunk !== undefined && chunk !== null && chunk !== '') {
|
|
148
|
-
this._chunks.push(chunk);
|
|
149
|
-
this._body += typeof chunk === 'string' ? chunk : chunk.toString();
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
if (typeof encoding === 'function') {
|
|
153
|
-
callback = encoding;
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
if (typeof callback === 'function') {
|
|
157
|
-
callback();
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
return true;
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
/**
|
|
164
|
-
* End the response
|
|
165
|
-
*/
|
|
166
|
-
end(data, encoding, callback) {
|
|
167
|
-
if (this.writableEnded) {
|
|
168
|
-
return this;
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
if (typeof data === 'function') {
|
|
172
|
-
callback = data;
|
|
173
|
-
data = undefined;
|
|
174
|
-
} else if (typeof encoding === 'function') {
|
|
175
|
-
callback = encoding;
|
|
176
|
-
encoding = undefined;
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
if (data !== undefined && data !== null && data !== '') {
|
|
180
|
-
this.write(data, encoding);
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
this.writableEnded = true;
|
|
184
|
-
this.finished = true;
|
|
185
|
-
|
|
186
|
-
this.emit('finish');
|
|
187
|
-
|
|
188
|
-
if (typeof callback === 'function') {
|
|
189
|
-
callback();
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
return this;
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
/**
|
|
196
|
-
* Get the response body as a string
|
|
197
|
-
*/
|
|
198
|
-
getBody() {
|
|
199
|
-
return this._body;
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
/**
|
|
203
|
-
* Get the response body parsed as JSON
|
|
204
|
-
*/
|
|
205
|
-
getJsonBody() {
|
|
206
|
-
try {
|
|
207
|
-
return JSON.parse(this._body);
|
|
208
|
-
} catch {
|
|
209
|
-
return null;
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
/**
|
|
214
|
-
* Reset the response for reuse
|
|
215
|
-
*/
|
|
216
|
-
reset() {
|
|
217
|
-
this.statusCode = 200;
|
|
218
|
-
this.statusMessage = '';
|
|
219
|
-
this.headers = {};
|
|
220
|
-
this._body = '';
|
|
221
|
-
this._chunks = [];
|
|
222
|
-
this.headersSent = false;
|
|
223
|
-
this.writableEnded = false;
|
|
224
|
-
this.finished = false;
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
/**
|
|
229
|
-
* Create a mock request with common defaults
|
|
230
|
-
*/
|
|
231
|
-
export function createMockRequest(options = {}) {
|
|
232
|
-
const defaults = {
|
|
233
|
-
method: 'GET',
|
|
234
|
-
url: '/',
|
|
235
|
-
headers: {
|
|
236
|
-
'host': 'localhost:3000',
|
|
237
|
-
'user-agent': 'test-agent',
|
|
238
|
-
'accept': '*/*',
|
|
239
|
-
},
|
|
240
|
-
ip: '127.0.0.1',
|
|
241
|
-
};
|
|
242
|
-
|
|
243
|
-
return new MockRequest({ ...defaults, ...options });
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
/**
|
|
247
|
-
* Create a mock response
|
|
248
|
-
*/
|
|
249
|
-
export function createMockResponse() {
|
|
250
|
-
return new MockResponse();
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
/**
|
|
254
|
-
* Create a mock request/response pair
|
|
255
|
-
*/
|
|
256
|
-
export function createMockPair(requestOptions = {}) {
|
|
257
|
-
return {
|
|
258
|
-
req: createMockRequest(requestOptions),
|
|
259
|
-
res: createMockResponse(),
|
|
260
|
-
};
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
/**
|
|
264
|
-
* Create a JSON request with proper headers
|
|
265
|
-
*/
|
|
266
|
-
export function createJsonRequest(options = {}) {
|
|
267
|
-
return createMockRequest({
|
|
268
|
-
...options,
|
|
269
|
-
headers: {
|
|
270
|
-
'content-type': 'application/json',
|
|
271
|
-
'accept': 'application/json',
|
|
272
|
-
...options.headers,
|
|
273
|
-
},
|
|
274
|
-
});
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
/**
|
|
278
|
-
* Create a form-urlencoded request with proper headers
|
|
279
|
-
*/
|
|
280
|
-
export function createFormRequest(options = {}) {
|
|
281
|
-
return createMockRequest({
|
|
282
|
-
method: 'POST',
|
|
283
|
-
...options,
|
|
284
|
-
headers: {
|
|
285
|
-
'content-type': 'application/x-www-form-urlencoded',
|
|
286
|
-
...options.headers,
|
|
287
|
-
},
|
|
288
|
-
});
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
/**
|
|
292
|
-
* Create a multipart form-data request with proper headers
|
|
293
|
-
*/
|
|
294
|
-
export function createMultipartRequest(boundary, options = {}) {
|
|
295
|
-
return createMockRequest({
|
|
296
|
-
method: 'POST',
|
|
297
|
-
...options,
|
|
298
|
-
headers: {
|
|
299
|
-
'content-type': `multipart/form-data; boundary=${boundary}`,
|
|
300
|
-
...options.headers,
|
|
301
|
-
},
|
|
302
|
-
});
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
/**
|
|
306
|
-
* Helper to create multipart form body
|
|
307
|
-
*/
|
|
308
|
-
export function createMultipartBody(boundary, fields = [], files = []) {
|
|
309
|
-
let body = '';
|
|
310
|
-
|
|
311
|
-
// Add regular fields
|
|
312
|
-
for (const field of fields) {
|
|
313
|
-
body += `--${boundary}\r\n`;
|
|
314
|
-
body += `Content-Disposition: form-data; name="${field.name}"\r\n\r\n`;
|
|
315
|
-
body += `${field.value}\r\n`;
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
// Add files
|
|
319
|
-
for (const file of files) {
|
|
320
|
-
body += `--${boundary}\r\n`;
|
|
321
|
-
body += `Content-Disposition: form-data; name="${file.fieldName}"; filename="${file.filename}"\r\n`;
|
|
322
|
-
body += `Content-Type: ${file.contentType || 'application/octet-stream'}\r\n\r\n`;
|
|
323
|
-
body += `${file.content}\r\n`;
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
body += `--${boundary}--\r\n`;
|
|
327
|
-
return body;
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
export default {
|
|
331
|
-
MockRequest,
|
|
332
|
-
MockResponse,
|
|
333
|
-
createMockRequest,
|
|
334
|
-
createMockResponse,
|
|
335
|
-
createMockPair,
|
|
336
|
-
createJsonRequest,
|
|
337
|
-
createFormRequest,
|
|
338
|
-
createMultipartRequest,
|
|
339
|
-
createMultipartBody,
|
|
340
|
-
};
|
|
341
|
-
|
|
342
|
-
|