blaizejs 0.3.2 → 0.3.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.
Files changed (30) hide show
  1. package/dist/chunk-DTDGIBMA.js +11 -0
  2. package/dist/{chunk-IFP53BNM.js.map → chunk-DTDGIBMA.js.map} +1 -1
  3. package/dist/{unsupported-media-type-error-VVHRDTUH.js → chunk-EE2VJ6JY.js} +3 -9
  4. package/dist/{chunk-3VK325MM.js.map → chunk-EE2VJ6JY.js.map} +1 -1
  5. package/dist/chunk-HSLLYUVO.js +11 -0
  6. package/dist/{chunk-CQKM74J4.js.map → chunk-HSLLYUVO.js.map} +1 -1
  7. package/dist/chunk-TL4GIFTB.js +11 -0
  8. package/dist/{chunk-HB6MRTGD.js.map → chunk-TL4GIFTB.js.map} +1 -1
  9. package/dist/chunk-VLVWNGUO.js +11 -0
  10. package/dist/{chunk-7IM52S7P.js.map → chunk-VLVWNGUO.js.map} +1 -1
  11. package/dist/index.cjs +12 -3486
  12. package/dist/index.cjs.map +1 -1
  13. package/dist/index.d.cts +2 -2
  14. package/dist/index.d.ts +2 -2
  15. package/dist/index.js +12 -3153
  16. package/dist/index.js.map +1 -1
  17. package/dist/{validation-error-TXMSFWZL.js → internal-server-error-GWBNT3OO.js} +3 -9
  18. package/dist/{internal-server-error-PVME2DGN.js → payload-too-large-error-EBM5BNWG.js} +3 -9
  19. package/dist/{payload-too-large-error-QQG7MKGT.js → unsupported-media-type-error-YQ7GCZ32.js} +3 -9
  20. package/dist/validation-error-6JDCGV2S.js +11 -0
  21. package/package.json +5 -5
  22. package/dist/chunk-3VK325MM.js +0 -31
  23. package/dist/chunk-7IM52S7P.js +0 -31
  24. package/dist/chunk-CQKM74J4.js +0 -39
  25. package/dist/chunk-HB6MRTGD.js +0 -39
  26. package/dist/chunk-IFP53BNM.js +0 -149
  27. /package/dist/{internal-server-error-PVME2DGN.js.map → internal-server-error-GWBNT3OO.js.map} +0 -0
  28. /package/dist/{payload-too-large-error-QQG7MKGT.js.map → payload-too-large-error-EBM5BNWG.js.map} +0 -0
  29. /package/dist/{unsupported-media-type-error-VVHRDTUH.js.map → unsupported-media-type-error-YQ7GCZ32.js.map} +0 -0
  30. /package/dist/{validation-error-TXMSFWZL.js.map → validation-error-6JDCGV2S.js.map} +0 -0
package/dist/index.cjs CHANGED
@@ -1,3505 +1,31 @@
1
1
 
2
2
  /**
3
- * blaizejs v0.3.2
3
+ * blaizejs v0.3.4
4
4
  * A blazing-fast, TypeScript-first Node.js framework with HTTP/2 support, file-based routing, powerful middleware system, and end-to-end type safety for building modern APIs.
5
5
  *
6
6
  * Copyright (c) 2025 BlaizeJS Contributors
7
7
  * @license MIT
8
8
  */
9
9
 
10
- "use strict";
11
- var __create = Object.create;
12
- var __defProp = Object.defineProperty;
13
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
14
- var __getOwnPropNames = Object.getOwnPropertyNames;
15
- var __getProtoOf = Object.getPrototypeOf;
16
- var __hasOwnProp = Object.prototype.hasOwnProperty;
17
- var __esm = (fn, res) => function __init() {
18
- return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
19
- };
20
- var __export = (target, all) => {
21
- for (var name in all)
22
- __defProp(target, name, { get: all[name], enumerable: true });
23
- };
24
- var __copyProps = (to, from, except, desc) => {
25
- if (from && typeof from === "object" || typeof from === "function") {
26
- for (let key of __getOwnPropNames(from))
27
- if (!__hasOwnProp.call(to, key) && key !== except)
28
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
29
- }
30
- return to;
31
- };
32
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
33
- // If the importer is in node compatibility mode or this is not an ESM
34
- // file that has been converted to a CommonJS file using a Babel-
35
- // compatible transform (i.e. "__esModule" has not been set), then set
36
- // "default" to the CommonJS "module.exports" for node compatibility.
37
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
38
- mod
39
- ));
40
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
41
-
42
- // ../blaize-types/src/errors.ts
43
- function isBodyParseError(error) {
44
- return typeof error === "object" && error !== null && "type" in error && "message" in error && "error" in error && typeof error.type === "string" && typeof error.message === "string";
45
- }
46
- var ErrorType, ErrorSeverity, BlaizeError;
47
- var init_errors = __esm({
48
- "../blaize-types/src/errors.ts"() {
49
- "use strict";
50
- ErrorType = /* @__PURE__ */ ((ErrorType2) => {
51
- ErrorType2["VALIDATION_ERROR"] = "VALIDATION_ERROR";
52
- ErrorType2["NOT_FOUND"] = "NOT_FOUND";
53
- ErrorType2["UNAUTHORIZED"] = "UNAUTHORIZED";
54
- ErrorType2["FORBIDDEN"] = "FORBIDDEN";
55
- ErrorType2["CONFLICT"] = "CONFLICT";
56
- ErrorType2["RATE_LIMITED"] = "RATE_LIMITED";
57
- ErrorType2["INTERNAL_SERVER_ERROR"] = "INTERNAL_SERVER_ERROR";
58
- ErrorType2["PAYLOAD_TOO_LARGE"] = "PAYLOAD_TOO_LARGE";
59
- ErrorType2["UNSUPPORTED_MEDIA_TYPE"] = "UNSUPPORTED_MEDIA_TYPE";
60
- ErrorType2["UPLOAD_TIMEOUT"] = "UPLOAD_TIMEOUT";
61
- ErrorType2["UNPROCESSABLE_ENTITY"] = "UNPROCESSABLE_ENTITY";
62
- ErrorType2["NETWORK_ERROR"] = "NETWORK_ERROR";
63
- ErrorType2["TIMEOUT_ERROR"] = "TIMEOUT_ERROR";
64
- ErrorType2["PARSE_ERROR"] = "PARSE_ERROR";
65
- ErrorType2["HTTP_ERROR"] = "HTTP_ERROR";
66
- return ErrorType2;
67
- })(ErrorType || {});
68
- ErrorSeverity = /* @__PURE__ */ ((ErrorSeverity2) => {
69
- ErrorSeverity2["LOW"] = "low";
70
- ErrorSeverity2["MEDIUM"] = "medium";
71
- ErrorSeverity2["HIGH"] = "high";
72
- ErrorSeverity2["CRITICAL"] = "critical";
73
- return ErrorSeverity2;
74
- })(ErrorSeverity || {});
75
- BlaizeError = class extends Error {
76
- /**
77
- * Error type identifier from the ErrorType enum
78
- * Used for programmatic error handling and client-side error routing
79
- */
80
- type;
81
- /**
82
- * Human-readable error title/message
83
- * Should be descriptive enough for debugging but safe for end users
84
- */
85
- title;
86
- /**
87
- * HTTP status code associated with this error
88
- * Used by the error boundary to set appropriate response status
89
- */
90
- status;
91
- /**
92
- * Correlation ID for request tracing
93
- * Links this error to the specific request that generated it
94
- */
95
- correlationId;
96
- /**
97
- * Timestamp when the error occurred
98
- * Useful for debugging and log correlation
99
- */
100
- timestamp;
101
- /**
102
- * Additional error-specific details
103
- * Type-safe error context that varies by error type
104
- */
105
- details;
106
- /**
107
- * Creates a new BlaizeError instance
108
- *
109
- * @param type - Error type from the ErrorType enum
110
- * @param title - Human-readable error message
111
- * @param status - HTTP status code
112
- * @param correlationId - Request correlation ID for tracing
113
- * @param details - Optional error-specific details
114
- */
115
- constructor(type, title, status, correlationId, details) {
116
- super(title);
117
- this.name = this.constructor.name;
118
- this.type = type;
119
- this.title = title;
120
- this.status = status;
121
- this.correlationId = correlationId;
122
- this.timestamp = /* @__PURE__ */ new Date();
123
- this.details = details;
124
- Object.setPrototypeOf(this, new.target.prototype);
125
- if (Error.captureStackTrace) {
126
- Error.captureStackTrace(this, this.constructor);
127
- }
128
- }
129
- /**
130
- * Serializes the error to a plain object suitable for HTTP responses
131
- *
132
- * @returns Object representation of the error
133
- */
134
- toJSON() {
135
- const base = {
136
- type: this.type,
137
- title: this.title,
138
- status: this.status,
139
- correlationId: this.correlationId,
140
- timestamp: this.timestamp.toISOString()
141
- };
142
- if (this.details !== void 0) {
143
- return { ...base, details: this.details };
144
- }
145
- return base;
146
- }
147
- /**
148
- * Returns a string representation of the error
149
- * Includes correlation ID for easier debugging
150
- */
151
- toString() {
152
- return `${this.name}: ${this.title} [${this.correlationId}]`;
153
- }
154
- };
155
- }
156
- });
157
-
158
- // src/errors/correlation.ts
159
- function generateCorrelationId() {
160
- const timestamp = Date.now().toString(36);
161
- const random = Math.random().toString(36).substr(2, 9);
162
- return `req_${timestamp}_${random}`;
163
- }
164
- function getCurrentCorrelationId() {
165
- const stored = correlationStorage.getStore();
166
- return stored && stored.trim() ? stored : "unknown";
167
- }
168
- var import_node_async_hooks2, correlationStorage;
169
- var init_correlation = __esm({
170
- "src/errors/correlation.ts"() {
171
- "use strict";
172
- import_node_async_hooks2 = require("async_hooks");
173
- correlationStorage = new import_node_async_hooks2.AsyncLocalStorage();
174
- }
175
- });
176
-
177
- // src/errors/internal-server-error.ts
178
- var internal_server_error_exports = {};
179
- __export(internal_server_error_exports, {
180
- InternalServerError: () => InternalServerError
181
- });
182
- var InternalServerError;
183
- var init_internal_server_error = __esm({
184
- "src/errors/internal-server-error.ts"() {
185
- "use strict";
186
- init_errors();
187
- init_correlation();
188
- InternalServerError = class extends BlaizeError {
189
- /**
190
- * Creates a new InternalServerError instance
191
- *
192
- * @param title - Human-readable error message
193
- * @param details - Optional debugging context
194
- * @param correlationId - Optional correlation ID (uses current context if not provided)
195
- */
196
- constructor(title, details = void 0, correlationId = void 0) {
197
- super(
198
- "INTERNAL_SERVER_ERROR" /* INTERNAL_SERVER_ERROR */,
199
- title,
200
- 500,
201
- // HTTP 500 Internal Server Error
202
- correlationId ?? getCurrentCorrelationId(),
203
- details
204
- );
205
- }
206
- };
207
- }
208
- });
209
-
210
- // src/errors/validation-error.ts
211
- var validation_error_exports = {};
212
- __export(validation_error_exports, {
213
- ValidationError: () => ValidationError
214
- });
215
- var ValidationError;
216
- var init_validation_error = __esm({
217
- "src/errors/validation-error.ts"() {
218
- "use strict";
219
- init_errors();
220
- init_correlation();
221
- ValidationError = class extends BlaizeError {
222
- /**
223
- * Creates a new ValidationError instance
224
- *
225
- * @param title - Human-readable error message
226
- * @param details - Optional structured validation details
227
- * @param correlationId - Optional correlation ID (uses current context if not provided)
228
- */
229
- constructor(title, details = void 0, correlationId = void 0) {
230
- super(
231
- "VALIDATION_ERROR" /* VALIDATION_ERROR */,
232
- title,
233
- 400,
234
- // HTTP 400 Bad Request
235
- correlationId ?? getCurrentCorrelationId(),
236
- details
237
- );
238
- }
239
- };
240
- }
241
- });
242
-
243
- // src/errors/payload-too-large-error.ts
244
- var payload_too_large_error_exports = {};
245
- __export(payload_too_large_error_exports, {
246
- PayloadTooLargeError: () => PayloadTooLargeError
247
- });
248
- var PayloadTooLargeError;
249
- var init_payload_too_large_error = __esm({
250
- "src/errors/payload-too-large-error.ts"() {
251
- "use strict";
252
- init_correlation();
253
- init_errors();
254
- PayloadTooLargeError = class extends BlaizeError {
255
- constructor(title, details, correlationId) {
256
- super(
257
- "PAYLOAD_TOO_LARGE" /* PAYLOAD_TOO_LARGE */,
258
- title,
259
- 413,
260
- correlationId ?? getCurrentCorrelationId(),
261
- details
262
- );
263
- }
264
- };
265
- }
266
- });
267
-
268
- // src/errors/unsupported-media-type-error.ts
269
- var unsupported_media_type_error_exports = {};
270
- __export(unsupported_media_type_error_exports, {
271
- UnsupportedMediaTypeError: () => UnsupportedMediaTypeError
272
- });
273
- var UnsupportedMediaTypeError;
274
- var init_unsupported_media_type_error = __esm({
275
- "src/errors/unsupported-media-type-error.ts"() {
276
- "use strict";
277
- init_correlation();
278
- init_errors();
279
- UnsupportedMediaTypeError = class extends BlaizeError {
280
- constructor(title, details, correlationId) {
281
- super(
282
- "UNSUPPORTED_MEDIA_TYPE" /* UNSUPPORTED_MEDIA_TYPE */,
283
- title,
284
- 415,
285
- correlationId ?? getCurrentCorrelationId(),
286
- details
287
- );
288
- }
289
- };
290
- }
291
- });
292
-
293
- // src/index.ts
294
- var index_exports = {};
295
- __export(index_exports, {
296
- Blaize: () => Blaize,
297
- BlaizeError: () => BlaizeError,
298
- ConflictError: () => ConflictError,
299
- ErrorSeverity: () => ErrorSeverity,
300
- ErrorType: () => ErrorType,
301
- ForbiddenError: () => ForbiddenError,
302
- InternalServerError: () => InternalServerError,
303
- MiddlewareAPI: () => MiddlewareAPI,
304
- NotFoundError: () => NotFoundError,
305
- PayloadTooLargeError: () => PayloadTooLargeError,
306
- PluginsAPI: () => PluginsAPI,
307
- RateLimitError: () => RateLimitError,
308
- RequestTimeoutError: () => RequestTimeoutError,
309
- RouterAPI: () => RouterAPI,
310
- ServerAPI: () => ServerAPI,
311
- UnauthorizedError: () => UnauthorizedError,
312
- UnprocessableEntityError: () => UnprocessableEntityError,
313
- UnsupportedMediaTypeError: () => UnsupportedMediaTypeError,
314
- VERSION: () => VERSION,
315
- ValidationError: () => ValidationError,
316
- compose: () => compose,
317
- createDeleteRoute: () => createDeleteRoute,
318
- createGetRoute: () => createGetRoute,
319
- createHeadRoute: () => createHeadRoute,
320
- createMiddleware: () => create,
321
- createOptionsRoute: () => createOptionsRoute,
322
- createPatchRoute: () => createPatchRoute,
323
- createPlugin: () => create2,
324
- createPostRoute: () => createPostRoute,
325
- createPutRoute: () => createPutRoute,
326
- createServer: () => create3,
327
- default: () => index_default,
328
- isBodyParseError: () => isBodyParseError
329
- });
330
- module.exports = __toCommonJS(index_exports);
331
-
332
- // src/middleware/execute.ts
333
- function execute(middleware, ctx, next) {
334
- if (!middleware) {
335
- return Promise.resolve(next());
336
- }
337
- if (middleware.skip && middleware.skip(ctx)) {
338
- return Promise.resolve(next());
339
- }
340
- try {
341
- const result = middleware.execute(ctx, next);
342
- if (result instanceof Promise) {
343
- return result;
344
- } else {
345
- return Promise.resolve(result);
346
- }
347
- } catch (error) {
348
- return Promise.reject(error);
349
- }
350
- }
351
-
352
- // src/middleware/compose.ts
353
- function compose(middlewareStack) {
354
- if (middlewareStack.length === 0) {
355
- return async (_, next) => {
356
- await Promise.resolve(next());
357
- };
358
- }
359
- return async function(ctx, finalHandler) {
360
- const called = /* @__PURE__ */ new Set();
361
- const dispatch = async (i) => {
362
- if (i >= middlewareStack.length) {
363
- return Promise.resolve(finalHandler());
364
- }
365
- const middleware = middlewareStack[i];
366
- const nextDispatch = () => {
367
- if (called.has(i)) {
368
- throw new Error("next() called multiple times");
369
- }
370
- called.add(i);
371
- return dispatch(i + 1);
372
- };
373
- return execute(middleware, ctx, nextDispatch);
374
- };
375
- return dispatch(0);
376
- };
377
- }
378
-
379
- // src/middleware/create.ts
380
- function create(handlerOrOptions) {
381
- if (typeof handlerOrOptions === "function") {
382
- return {
383
- name: "anonymous",
384
- // Default name for function middleware
385
- execute: handlerOrOptions,
386
- debug: false
387
- };
388
- }
389
- const { name = "anonymous", handler, skip, debug = false } = handlerOrOptions;
390
- const middleware = {
391
- name,
392
- execute: handler,
393
- debug
394
- };
395
- if (skip !== void 0) {
396
- return {
397
- ...middleware,
398
- skip
399
- };
400
- }
401
- return middleware;
402
- }
403
-
404
- // src/plugins/create.ts
405
- function create2(name, version, setup, defaultOptions = {}) {
406
- if (!name || typeof name !== "string") {
407
- throw new Error("Plugin name must be a non-empty string");
408
- }
409
- if (!version || typeof version !== "string") {
410
- throw new Error("Plugin version must be a non-empty string");
411
- }
412
- if (typeof setup !== "function") {
413
- throw new Error("Plugin setup must be a function");
414
- }
415
- return function pluginFactory(userOptions) {
416
- const mergedOptions = { ...defaultOptions, ...userOptions };
417
- const plugin = {
418
- name,
419
- version,
420
- // The register hook calls the user's setup function
421
- register: async (app) => {
422
- const result = await setup(app, mergedOptions);
423
- if (result && typeof result === "object") {
424
- Object.assign(plugin, result);
425
- }
426
- }
427
- };
428
- return plugin;
429
- };
430
- }
431
-
432
- // src/router/create.ts
433
- var import_node_url = require("url");
434
-
435
- // src/config.ts
436
- var config = {};
437
- function setRuntimeConfig(newConfig) {
438
- config = { ...config, ...newConfig };
439
- }
440
- function getRoutesDir() {
441
- if (!config.routesDir) {
442
- throw new Error("Routes directory not configured. Make sure server is properly initialized.");
443
- }
444
- return config.routesDir;
445
- }
446
-
447
- // src/router/discovery/parser.ts
448
- var path = __toESM(require("path"), 1);
449
- function parseRoutePath(filePath, basePath) {
450
- if (filePath.startsWith("file://")) {
451
- filePath = filePath.replace("file://", "");
452
- }
453
- if (basePath.startsWith("file://")) {
454
- basePath = basePath.replace("file://", "");
455
- }
456
- const forwardSlashFilePath = filePath.replace(/\\/g, "/");
457
- const forwardSlashBasePath = basePath.replace(/\\/g, "/");
458
- const normalizedBasePath = forwardSlashBasePath.endsWith("/") ? forwardSlashBasePath : `${forwardSlashBasePath}/`;
459
- let relativePath = forwardSlashFilePath;
460
- if (forwardSlashFilePath.startsWith(normalizedBasePath)) {
461
- relativePath = forwardSlashFilePath.substring(normalizedBasePath.length);
462
- } else if (forwardSlashFilePath.startsWith(forwardSlashBasePath)) {
463
- relativePath = forwardSlashFilePath.substring(forwardSlashBasePath.length);
464
- if (relativePath.startsWith("/")) {
465
- relativePath = relativePath.substring(1);
466
- }
467
- } else {
468
- relativePath = path.relative(forwardSlashBasePath, forwardSlashFilePath).replace(/\\/g, "/");
469
- }
470
- relativePath = relativePath.replace(/\.[^.]+$/, "");
471
- const segments = relativePath.split("/").filter(Boolean);
472
- const params = [];
473
- const routeSegments = segments.map((segment) => {
474
- if (segment.startsWith("[") && segment.endsWith("]")) {
475
- const paramName = segment.slice(1, -1);
476
- params.push(paramName);
477
- return `:${paramName}`;
478
- }
479
- return segment;
480
- });
481
- let routePath = routeSegments.length > 0 ? `/${routeSegments.join("/")}` : "/";
482
- if (routePath.endsWith("/index")) {
483
- routePath = routePath.slice(0, -6) || "/";
484
- }
485
- return {
486
- filePath,
487
- routePath,
488
- params
489
- };
490
- }
491
-
492
- // src/router/create.ts
493
- function getCallerFilePath() {
494
- const originalPrepareStackTrace = Error.prepareStackTrace;
495
- try {
496
- Error.prepareStackTrace = (_, stack2) => stack2;
497
- const stack = new Error().stack;
498
- const callerFrame = stack[3];
499
- if (!callerFrame || typeof callerFrame.getFileName !== "function") {
500
- throw new Error("Unable to determine caller file frame");
501
- }
502
- const fileName = callerFrame.getFileName();
503
- if (!fileName) {
504
- throw new Error("Unable to determine caller file name");
505
- }
506
- if (fileName.startsWith("file://")) {
507
- return (0, import_node_url.fileURLToPath)(fileName);
508
- }
509
- return fileName;
510
- } finally {
511
- Error.prepareStackTrace = originalPrepareStackTrace;
512
- }
513
- }
514
- function getRoutePath() {
515
- const callerPath = getCallerFilePath();
516
- const routesDir = getRoutesDir();
517
- const parsedRoute = parseRoutePath(callerPath, routesDir);
518
- console.log(`\u{1F50E} Parsed route path: ${parsedRoute.routePath} from file: ${callerPath}`);
519
- return parsedRoute.routePath;
520
- }
521
- var createGetRoute = (config2) => {
522
- validateMethodConfig("GET", config2);
523
- const path6 = getRoutePath();
524
- return {
525
- GET: config2,
526
- // Let TypeScript infer the proper types
527
- path: path6
528
- };
529
- };
530
- var createPostRoute = (config2) => {
531
- validateMethodConfig("POST", config2);
532
- const path6 = getRoutePath();
533
- return {
534
- POST: config2,
535
- // Let TypeScript infer the proper types
536
- path: path6
537
- };
538
- };
539
- var createPutRoute = (config2) => {
540
- validateMethodConfig("PUT", config2);
541
- const path6 = getRoutePath();
542
- return {
543
- PUT: config2,
544
- // Let TypeScript infer the proper types
545
- path: path6
546
- };
547
- };
548
- var createDeleteRoute = (config2) => {
549
- validateMethodConfig("DELETE", config2);
550
- const path6 = getRoutePath();
551
- return {
552
- DELETE: config2,
553
- // Let TypeScript infer the proper types
554
- path: path6
555
- };
556
- };
557
- var createPatchRoute = (config2) => {
558
- validateMethodConfig("PATCH", config2);
559
- const path6 = getRoutePath();
560
- return {
561
- PATCH: config2,
562
- // Let TypeScript infer the proper types
563
- path: path6
564
- };
565
- };
566
- var createHeadRoute = (config2) => {
567
- validateMethodConfig("HEAD", config2);
568
- const path6 = getRoutePath();
569
- return {
570
- HEAD: config2,
571
- // Let TypeScript infer the proper types
572
- path: path6
573
- };
574
- };
575
- var createOptionsRoute = (config2) => {
576
- validateMethodConfig("OPTIONS", config2);
577
- const path6 = getRoutePath();
578
- return {
579
- OPTIONS: config2,
580
- // Let TypeScript infer the proper types
581
- path: path6
582
- };
583
- };
584
- function validateMethodConfig(method, config2) {
585
- if (!config2.handler || typeof config2.handler !== "function") {
586
- throw new Error(`Handler for method ${method} must be a function`);
587
- }
588
- if (config2.middleware && !Array.isArray(config2.middleware)) {
589
- throw new Error(`Middleware for method ${method} must be an array`);
590
- }
591
- if (config2.schema) {
592
- validateSchema(method, config2.schema);
593
- }
594
- switch (method) {
595
- case "GET":
596
- case "HEAD":
597
- case "DELETE":
598
- if (config2.schema?.body) {
599
- console.warn(`Warning: ${method} requests typically don't have request bodies`);
600
- }
601
- break;
602
- }
603
- }
604
- function validateSchema(method, schema) {
605
- const { params, query, body, response } = schema;
606
- if (params && (!params._def || typeof params.parse !== "function")) {
607
- throw new Error(`Params schema for ${method} must be a valid Zod schema`);
608
- }
609
- if (query && (!query._def || typeof query.parse !== "function")) {
610
- throw new Error(`Query schema for ${method} must be a valid Zod schema`);
611
- }
612
- if (body && (!body._def || typeof body.parse !== "function")) {
613
- throw new Error(`Body schema for ${method} must be a valid Zod schema`);
614
- }
615
- if (response && (!response._def || typeof response.parse !== "function")) {
616
- throw new Error(`Response schema for ${method} must be a valid Zod schema`);
617
- }
618
- }
619
-
620
- // src/server/create.ts
621
- var import_node_async_hooks3 = require("async_hooks");
622
- var import_node_events = __toESM(require("events"), 1);
623
-
624
- // src/server/start.ts
625
- var fs2 = __toESM(require("fs"), 1);
626
- var http = __toESM(require("http"), 1);
627
- var http2 = __toESM(require("http2"), 1);
628
-
629
- // src/server/dev-certificate.ts
630
- var fs = __toESM(require("fs"), 1);
631
- var path2 = __toESM(require("path"), 1);
632
- var selfsigned = __toESM(require("selfsigned"), 1);
633
- async function generateDevCertificates() {
634
- const certDir = path2.join(process.cwd(), ".blaizejs", "certs");
635
- const keyPath = path2.join(certDir, "dev.key");
636
- const certPath = path2.join(certDir, "dev.cert");
637
- if (fs.existsSync(keyPath) && fs.existsSync(certPath)) {
638
- return {
639
- keyFile: keyPath,
640
- certFile: certPath
641
- };
642
- }
643
- if (!fs.existsSync(certDir)) {
644
- fs.mkdirSync(certDir, { recursive: true });
645
- }
646
- const attrs = [{ name: "commonName", value: "localhost" }];
647
- const options = {
648
- days: 365,
649
- algorithm: "sha256",
650
- keySize: 2048,
651
- extensions: [
652
- { name: "basicConstraints", cA: true },
653
- {
654
- name: "keyUsage",
655
- keyCertSign: true,
656
- digitalSignature: true,
657
- nonRepudiation: true,
658
- keyEncipherment: true,
659
- dataEncipherment: true
660
- },
661
- {
662
- name: "extKeyUsage",
663
- serverAuth: true,
664
- clientAuth: true
665
- },
666
- {
667
- name: "subjectAltName",
668
- altNames: [
669
- { type: 2, value: "localhost" },
670
- { type: 7, ip: "127.0.0.1" }
671
- ]
672
- }
673
- ]
674
- };
675
- const pems = selfsigned.generate(attrs, options);
676
- fs.writeFileSync(keyPath, Buffer.from(pems.private, "utf-8"));
677
- fs.writeFileSync(certPath, Buffer.from(pems.cert, "utf-8"));
678
- console.log(`
679
- \u{1F512} Generated self-signed certificates for development at ${certDir}
680
- `);
681
- return {
682
- keyFile: keyPath,
683
- certFile: certPath
684
- };
685
- }
686
-
687
- // src/context/errors.ts
688
- var ResponseSentError = class extends Error {
689
- constructor(message = "\u274C Response has already been sent") {
690
- super(message);
691
- this.name = "ResponseSentError";
692
- }
693
- };
694
- var ResponseSentHeaderError = class extends ResponseSentError {
695
- constructor(message = "Cannot set header after response has been sent") {
696
- super(message);
697
- }
698
- };
699
- var ResponseSentContentError = class extends ResponseSentError {
700
- constructor(message = "Cannot set content type after response has been sent") {
701
- super(message);
702
- }
703
- };
704
- var ParseUrlError = class extends ResponseSentError {
705
- constructor(message = "Invalide URL") {
706
- super(message);
707
- }
708
- };
709
-
710
- // src/context/store.ts
711
- var import_node_async_hooks = require("async_hooks");
712
- var contextStorage = new import_node_async_hooks.AsyncLocalStorage();
713
- function runWithContext(context, callback) {
714
- return contextStorage.run(context, callback);
715
- }
716
-
717
- // src/upload/multipart-parser.ts
718
- var import_node_crypto = require("crypto");
719
- var import_node_fs = require("fs");
720
- var import_node_os = require("os");
721
- var import_node_path = require("path");
722
- var import_node_stream = require("stream");
723
-
724
- // src/upload/utils.ts
725
- var BOUNDARY_REGEX = /boundary=([^;]+)/i;
726
- var CONTENT_DISPOSITION_REGEX = /Content-Disposition:\s*form-data;\s*name="([^"]+)"(?:;[\s\r\n]*filename="([^"]*)")?/i;
727
- var CONTENT_TYPE_REGEX = /Content-Type:\s*([^\r\n]+)/i;
728
- var MULTIPART_REGEX = /multipart\/form-data/i;
729
- function extractBoundary(contentType) {
730
- const match = contentType.match(BOUNDARY_REGEX);
731
- if (!match || !match[1]) return null;
732
- let boundary = match[1].trim();
733
- if (boundary.startsWith('"') && boundary.endsWith('"')) {
734
- boundary = boundary.slice(1, -1);
735
- }
736
- return boundary || null;
737
- }
738
- function parseContentDisposition(headers) {
739
- const match = headers.match(CONTENT_DISPOSITION_REGEX);
740
- if (!match || !match[1]) return null;
741
- return {
742
- name: match[1],
743
- filename: match[2] !== void 0 ? match[2] : void 0
744
- };
745
- }
746
- function parseContentType(headers) {
747
- const match = headers.match(CONTENT_TYPE_REGEX);
748
- return match && match[1]?.trim() ? match[1].trim() : "application/octet-stream";
749
- }
750
- function isMultipartContent(contentType) {
751
- return MULTIPART_REGEX.test(contentType);
752
- }
753
-
754
- // src/upload/multipart-parser.ts
755
- var DEFAULT_OPTIONS = {
756
- maxFileSize: 10 * 1024 * 1024,
757
- // 10MB
758
- maxFiles: 10,
759
- maxFieldSize: 1 * 1024 * 1024,
760
- // 1MB
761
- allowedMimeTypes: [],
762
- allowedExtensions: [],
763
- strategy: "stream",
764
- tempDir: (0, import_node_os.tmpdir)(),
765
- computeHash: false
766
- };
767
- function createParserState(boundary, options = {}) {
768
- return {
769
- boundary: Buffer.from(`--${boundary}`),
770
- options: { ...DEFAULT_OPTIONS, ...options },
771
- fields: /* @__PURE__ */ new Map(),
772
- files: /* @__PURE__ */ new Map(),
773
- buffer: Buffer.alloc(0),
774
- stage: "boundary",
775
- currentHeaders: "",
776
- currentField: null,
777
- currentFilename: void 0,
778
- currentMimetype: "application/octet-stream",
779
- currentContentLength: 0,
780
- fileCount: 0,
781
- fieldCount: 0,
782
- currentBufferChunks: [],
783
- currentStream: null,
784
- currentTempPath: null,
785
- currentWriteStream: null,
786
- streamController: null,
787
- cleanupTasks: [],
788
- // Track validation state
789
- hasFoundValidBoundary: false,
790
- hasProcessedAnyPart: false,
791
- isFinished: false
792
- };
793
- }
794
- async function processChunk(state, chunk) {
795
- const newBuffer = Buffer.concat([state.buffer, chunk]);
796
- let currentState = { ...state, buffer: newBuffer };
797
- while (currentState.buffer.length > 0 && !currentState.isFinished) {
798
- const nextState = await processCurrentStage(currentState);
799
- if (nextState === currentState) break;
800
- currentState = nextState;
801
- }
802
- return currentState;
803
- }
804
- async function processCurrentStage(state) {
805
- switch (state.stage) {
806
- case "boundary":
807
- return processBoundary(state);
808
- case "headers":
809
- return processHeaders(state);
810
- case "content":
811
- return processContent(state);
812
- default: {
813
- const { InternalServerError: InternalServerError2 } = await Promise.resolve().then(() => (init_internal_server_error(), internal_server_error_exports));
814
- throw new InternalServerError2(`Invalid parser stage`, {
815
- operation: state.stage
816
- });
817
- }
818
- }
819
- }
820
- function processBoundary(state) {
821
- const boundaryIndex = state.buffer.indexOf(state.boundary);
822
- if (boundaryIndex === -1) return state;
823
- const hasFoundValidBoundary = true;
824
- let buffer = state.buffer.subarray(boundaryIndex + state.boundary.length);
825
- if (buffer.length >= 2 && buffer.subarray(0, 2).equals(Buffer.from("--"))) {
826
- return {
827
- ...state,
828
- buffer,
829
- hasFoundValidBoundary,
830
- isFinished: true,
831
- stage: "boundary"
832
- };
833
- }
834
- if (buffer.length >= 2 && buffer.subarray(0, 2).equals(Buffer.from("\r\n"))) {
835
- buffer = buffer.subarray(2);
836
- }
837
- return {
838
- ...state,
839
- buffer,
840
- hasFoundValidBoundary,
841
- stage: "headers",
842
- currentHeaders: ""
843
- };
844
- }
845
- async function processHeaders(state) {
846
- const headerEnd = state.buffer.indexOf("\r\n\r\n");
847
- if (headerEnd === -1) return state;
848
- const headers = state.buffer.subarray(0, headerEnd).toString("utf8");
849
- const buffer = state.buffer.subarray(headerEnd + 4);
850
- const disposition = parseContentDisposition(headers);
851
- if (!disposition) {
852
- const { ValidationError: ValidationError2 } = await Promise.resolve().then(() => (init_validation_error(), validation_error_exports));
853
- throw new ValidationError2("Missing or invalid Content-Disposition header");
854
- }
855
- const mimetype = parseContentType(headers);
856
- const isFile = disposition.filename !== void 0;
857
- if (isFile && state.fileCount >= state.options.maxFiles) {
858
- const { PayloadTooLargeError: PayloadTooLargeError2 } = await Promise.resolve().then(() => (init_payload_too_large_error(), payload_too_large_error_exports));
859
- throw new PayloadTooLargeError2("Too many files in upload", {
860
- fileCount: state.fileCount + 1,
861
- maxFiles: state.options.maxFiles,
862
- filename: disposition.filename
863
- });
864
- }
865
- if (isFile && state.options.allowedMimeTypes.length > 0 && !state.options.allowedMimeTypes.includes(mimetype)) {
866
- const { UnsupportedMediaTypeError: UnsupportedMediaTypeError2 } = await Promise.resolve().then(() => (init_unsupported_media_type_error(), unsupported_media_type_error_exports));
867
- throw new UnsupportedMediaTypeError2("File type not allowed", {
868
- receivedMimeType: mimetype,
869
- allowedMimeTypes: state.options.allowedMimeTypes,
870
- filename: disposition.filename
871
- });
872
- }
873
- return {
874
- ...state,
875
- buffer,
876
- stage: "content",
877
- currentHeaders: headers,
878
- currentField: disposition.name,
879
- currentFilename: disposition.filename,
880
- currentMimetype: mimetype,
881
- currentContentLength: 0,
882
- fileCount: isFile ? state.fileCount + 1 : state.fileCount,
883
- fieldCount: isFile ? state.fieldCount : state.fieldCount + 1,
884
- currentBufferChunks: []
885
- };
886
- }
887
- async function processContent(state) {
888
- const nextBoundaryIndex = state.buffer.indexOf(state.boundary);
889
- let contentChunk;
890
- let isComplete = false;
891
- let buffer = state.buffer;
892
- if (nextBoundaryIndex === -1) {
893
- const safeLength = Math.max(0, state.buffer.length - state.boundary.length);
894
- if (safeLength === 0) return state;
895
- contentChunk = state.buffer.subarray(0, safeLength);
896
- buffer = state.buffer.subarray(safeLength);
897
- } else {
898
- const contentEnd = Math.max(0, nextBoundaryIndex - 2);
899
- contentChunk = state.buffer.subarray(0, contentEnd);
900
- buffer = state.buffer.subarray(nextBoundaryIndex);
901
- isComplete = true;
902
- }
903
- let updatedState = { ...state, buffer };
904
- if (contentChunk.length > 0) {
905
- updatedState = await processContentChunk(updatedState, contentChunk);
906
- }
907
- if (isComplete) {
908
- updatedState = await finalizeCurrentPart(updatedState);
909
- updatedState = {
910
- ...updatedState,
911
- stage: "boundary",
912
- hasProcessedAnyPart: true
913
- // Mark that we've processed at least one part
914
- };
915
- }
916
- return updatedState;
917
- }
918
- async function processContentChunk(state, chunk) {
919
- const newContentLength = state.currentContentLength + chunk.length;
920
- const maxSize = state.currentFilename !== void 0 ? state.options.maxFileSize : state.options.maxFieldSize;
921
- if (newContentLength > maxSize) {
922
- const isFile = state.currentFilename !== void 0;
923
- const { PayloadTooLargeError: PayloadTooLargeError2 } = await Promise.resolve().then(() => (init_payload_too_large_error(), payload_too_large_error_exports));
924
- const payloadErrorDetals = state.currentField ? {
925
- contentType: isFile ? "file" : "field",
926
- currentSize: newContentLength,
927
- maxSize,
928
- field: state.currentField,
929
- filename: state.currentFilename
930
- } : {
931
- contentType: isFile ? "file" : "field",
932
- currentSize: newContentLength,
933
- maxSize,
934
- filename: state.currentFilename
935
- };
936
- throw new PayloadTooLargeError2(
937
- `${isFile ? "File" : "Field"} size exceeds limit`,
938
- payloadErrorDetals
939
- );
940
- }
941
- if (state.currentFilename !== void 0) {
942
- return processFileChunk(state, chunk, newContentLength);
943
- } else {
944
- return {
945
- ...state,
946
- currentContentLength: newContentLength,
947
- currentBufferChunks: [...state.currentBufferChunks, chunk]
948
- };
949
- }
950
- }
951
- async function processFileChunk(state, chunk, newContentLength) {
952
- switch (state.options.strategy) {
953
- case "memory":
954
- return {
955
- ...state,
956
- currentContentLength: newContentLength,
957
- currentBufferChunks: [...state.currentBufferChunks, chunk]
958
- };
959
- case "stream":
960
- if (state.streamController) {
961
- state.streamController.enqueue(chunk);
962
- }
963
- return { ...state, currentContentLength: newContentLength };
964
- case "temp":
965
- if (state.currentWriteStream) {
966
- await writeToStream(state.currentWriteStream, chunk);
967
- }
968
- return { ...state, currentContentLength: newContentLength };
969
- default: {
970
- const { ValidationError: ValidationError2 } = await Promise.resolve().then(() => (init_validation_error(), validation_error_exports));
971
- throw new ValidationError2(`Invalid parsing strategy`);
972
- }
973
- }
974
- }
975
- async function initializeFileProcessing(state) {
976
- if (state.currentFilename === void 0) return state;
977
- switch (state.options.strategy) {
978
- case "memory":
979
- return { ...state, currentBufferChunks: [] };
980
- case "stream": {
981
- let streamController = null;
982
- const stream = new ReadableStream({
983
- start: (controller) => {
984
- streamController = controller;
985
- }
986
- });
987
- return {
988
- ...state,
989
- currentStream: stream,
990
- // Type cast for Node.js compatibility
991
- streamController
992
- };
993
- }
994
- case "temp": {
995
- const tempPath = (0, import_node_path.join)(state.options.tempDir, `upload-${(0, import_node_crypto.randomUUID)()}`);
996
- const writeStream = (0, import_node_fs.createWriteStream)(tempPath);
997
- const cleanupTask = async () => {
998
- try {
999
- const { unlink } = await import("fs/promises");
1000
- await unlink(tempPath);
1001
- } catch (error) {
1002
- console.warn(`Failed to cleanup temp file: ${tempPath}`, error);
1003
- }
1004
- };
1005
- return {
1006
- ...state,
1007
- currentTempPath: tempPath,
1008
- currentWriteStream: writeStream,
1009
- cleanupTasks: [...state.cleanupTasks, cleanupTask]
1010
- };
1011
- }
1012
- default: {
1013
- const { ValidationError: ValidationError2 } = await Promise.resolve().then(() => (init_validation_error(), validation_error_exports));
1014
- throw new ValidationError2(`Invalid file processing strategy`);
1015
- }
1016
- }
1017
- }
1018
- async function finalizeCurrentPart(state) {
1019
- if (!state.currentField) return resetCurrentPart(state);
1020
- if (state.currentFilename !== void 0) {
1021
- return finalizeFile(state);
1022
- } else {
1023
- return finalizeField(state);
1024
- }
1025
- }
1026
- async function finalizeFile(state) {
1027
- if (!state.currentField || state.currentFilename === void 0) {
1028
- return resetCurrentPart(state);
1029
- }
1030
- let stream;
1031
- let buffer;
1032
- let tempPath;
1033
- switch (state.options.strategy) {
1034
- case "memory":
1035
- buffer = Buffer.concat(state.currentBufferChunks);
1036
- stream = import_node_stream.Readable.from(buffer);
1037
- break;
1038
- case "stream":
1039
- if (state.streamController) {
1040
- state.streamController.close();
1041
- }
1042
- stream = state.currentStream;
1043
- break;
1044
- case "temp":
1045
- if (state.currentWriteStream) {
1046
- await closeStream(state.currentWriteStream);
1047
- }
1048
- tempPath = state.currentTempPath;
1049
- stream = import_node_stream.Readable.from(Buffer.alloc(0));
1050
- break;
1051
- default: {
1052
- const { ValidationError: ValidationError2 } = await Promise.resolve().then(() => (init_validation_error(), validation_error_exports));
1053
- throw new ValidationError2(`Invalid file finalization strategy`);
1054
- }
1055
- }
1056
- const file = {
1057
- filename: state.currentFilename,
1058
- fieldname: state.currentField,
1059
- mimetype: state.currentMimetype,
1060
- size: state.currentContentLength,
1061
- stream,
1062
- buffer,
1063
- tempPath
1064
- };
1065
- const updatedFiles = addToCollection(state.files, state.currentField, file);
1066
- return {
1067
- ...resetCurrentPart(state),
1068
- files: updatedFiles
1069
- };
1070
- }
1071
- function finalizeField(state) {
1072
- if (!state.currentField) return resetCurrentPart(state);
1073
- const value = Buffer.concat(state.currentBufferChunks).toString("utf8");
1074
- const updatedFields = addToCollection(state.fields, state.currentField, value);
1075
- return {
1076
- ...resetCurrentPart(state),
1077
- fields: updatedFields
1078
- };
1079
- }
1080
- function resetCurrentPart(state) {
1081
- return {
1082
- ...state,
1083
- currentField: null,
1084
- currentFilename: void 0,
1085
- currentContentLength: 0,
1086
- currentBufferChunks: [],
1087
- currentStream: null,
1088
- streamController: null,
1089
- currentTempPath: null,
1090
- currentWriteStream: null
1091
- };
1092
- }
1093
- function addToCollection(collection, key, value) {
1094
- const newCollection = new Map(collection);
1095
- const existing = newCollection.get(key) || [];
1096
- newCollection.set(key, [...existing, value]);
1097
- return newCollection;
1098
- }
1099
- async function finalize(state) {
1100
- if (!state.hasFoundValidBoundary) {
1101
- const { ValidationError: ValidationError2 } = await Promise.resolve().then(() => (init_validation_error(), validation_error_exports));
1102
- throw new ValidationError2("No valid multipart boundary found");
1103
- }
1104
- if (state.hasFoundValidBoundary && !state.hasProcessedAnyPart) {
1105
- const { ValidationError: ValidationError2 } = await Promise.resolve().then(() => (init_validation_error(), validation_error_exports));
1106
- throw new ValidationError2("Empty multipart request");
1107
- }
1108
- const fields = {};
1109
- for (const [key, values] of state.fields.entries()) {
1110
- fields[key] = values.length === 1 ? values[0] : values;
1111
- }
1112
- const files = {};
1113
- for (const [key, fileList] of state.files.entries()) {
1114
- files[key] = fileList.length === 1 ? fileList[0] : fileList;
1115
- }
1116
- return { fields, files };
1117
- }
1118
- async function cleanup(state) {
1119
- await Promise.allSettled(state.cleanupTasks.map((task) => task()));
1120
- if (state.streamController) {
1121
- state.streamController.close();
1122
- }
1123
- if (state.currentWriteStream) {
1124
- await closeStream(state.currentWriteStream);
1125
- }
1126
- }
1127
- async function writeToStream(stream, chunk) {
1128
- return new Promise((resolve3, reject) => {
1129
- stream.write(chunk, (error) => {
1130
- if (error) reject(error);
1131
- else resolve3();
1132
- });
1133
- });
1134
- }
1135
- async function closeStream(stream) {
1136
- return new Promise((resolve3) => {
1137
- stream.end(() => resolve3());
1138
- });
1139
- }
1140
- async function parseMultipartRequest(request, options = {}) {
1141
- const contentType = request.headers["content-type"] || "";
1142
- const boundary = extractBoundary(contentType);
1143
- if (!boundary) {
1144
- const { UnsupportedMediaTypeError: UnsupportedMediaTypeError2 } = await Promise.resolve().then(() => (init_unsupported_media_type_error(), unsupported_media_type_error_exports));
1145
- throw new UnsupportedMediaTypeError2("Missing boundary in multipart content-type", {
1146
- receivedContentType: contentType,
1147
- expectedFormat: "multipart/form-data; boundary=..."
1148
- });
1149
- }
1150
- let state = createParserState(boundary, options);
1151
- if (state.currentFilename !== void 0) {
1152
- state = await initializeFileProcessing(state);
1153
- }
1154
- try {
1155
- for await (const chunk of request) {
1156
- state = await processChunk(state, chunk);
1157
- }
1158
- return finalize(state);
1159
- } finally {
1160
- await cleanup(state);
1161
- }
1162
- }
1163
-
1164
- // src/context/create.ts
1165
- var CONTENT_TYPE_HEADER = "Content-Type";
1166
- var DEFAULT_BODY_LIMITS = {
1167
- json: 512 * 1024,
1168
- // 512KB - Most APIs should be much smaller
1169
- form: 1024 * 1024,
1170
- // 1MB - Reasonable for form submissions
1171
- text: 5 * 1024 * 1024,
1172
- // 5MB - Documents, logs, code files
1173
- multipart: {
1174
- maxFileSize: 50 * 1024 * 1024,
1175
- // 50MB per file
1176
- maxTotalSize: 100 * 1024 * 1024,
1177
- // 100MB total request
1178
- maxFiles: 10,
1179
- maxFieldSize: 1024 * 1024
1180
- // 1MB for form fields
1181
- },
1182
- raw: 10 * 1024 * 1024
1183
- // 10MB for unknown content types
1184
- };
1185
- function parseRequestUrl(req) {
1186
- const originalUrl = req.url || "/";
1187
- const host = req.headers.host || "localhost";
1188
- const protocol = req.socket && req.socket.encrypted ? "https" : "http";
1189
- const fullUrl = `${protocol}://${host}${originalUrl.startsWith("/") ? "" : "/"}${originalUrl}`;
1190
- try {
1191
- const url = new URL(fullUrl);
1192
- const path6 = url.pathname;
1193
- const query = {};
1194
- url.searchParams.forEach((value, key) => {
1195
- if (query[key] !== void 0) {
1196
- if (Array.isArray(query[key])) {
1197
- query[key].push(value);
1198
- } else {
1199
- query[key] = [query[key], value];
1200
- }
1201
- } else {
1202
- query[key] = value;
1203
- }
1204
- });
1205
- return { path: path6, url, query };
1206
- } catch (error) {
1207
- console.warn(`Invalid URL: ${fullUrl}`, error);
1208
- throw new ParseUrlError(`Invalid URL: ${fullUrl}`);
1209
- }
1210
- }
1211
- function isHttp2Request(req) {
1212
- return "stream" in req || "httpVersionMajor" in req && req.httpVersionMajor === 2;
1213
- }
1214
- function getProtocol(req) {
1215
- const encrypted = req.socket && req.socket.encrypted;
1216
- const forwardedProto = req.headers["x-forwarded-proto"];
1217
- if (forwardedProto) {
1218
- if (Array.isArray(forwardedProto)) {
1219
- return forwardedProto[0]?.split(",")[0]?.trim() || "http";
1220
- } else {
1221
- return forwardedProto.split(",")[0]?.trim() || "http";
1222
- }
1223
- }
1224
- return encrypted ? "https" : "http";
1225
- }
1226
- async function createContext(req, res, options = {}) {
1227
- const { path: path6, url, query } = parseRequestUrl(req);
1228
- const method = req.method || "GET";
1229
- const isHttp2 = isHttp2Request(req);
1230
- const protocol = getProtocol(req);
1231
- const params = {};
1232
- const state = { ...options.initialState || {} };
1233
- const responseState = { sent: false };
1234
- const ctx = {
1235
- request: createRequestObject(req, {
1236
- path: path6,
1237
- url,
1238
- query,
1239
- params,
1240
- method,
1241
- isHttp2,
1242
- protocol
1243
- }),
1244
- response: {},
1245
- state
1246
- };
1247
- ctx.response = createResponseObject(res, responseState, ctx);
1248
- if (options.parseBody) {
1249
- await parseBodyIfNeeded(req, ctx, options);
1250
- }
1251
- return ctx;
1252
- }
1253
- function createRequestObject(req, info) {
1254
- return {
1255
- raw: req,
1256
- ...info,
1257
- header: createRequestHeaderGetter(req),
1258
- headers: createRequestHeadersGetter(req),
1259
- body: void 0
1260
- };
1261
- }
1262
- function createRequestHeaderGetter(req) {
1263
- return (name) => {
1264
- const value = req.headers[name.toLowerCase()];
1265
- if (Array.isArray(value)) {
1266
- return value.join(", ");
1267
- }
1268
- return value || void 0;
1269
- };
1270
- }
1271
- function createRequestHeadersGetter(req) {
1272
- const headerGetter = createRequestHeaderGetter(req);
1273
- return (names) => {
1274
- if (names && Array.isArray(names) && names.length > 0) {
1275
- return names.reduce((acc, name) => {
1276
- acc[name] = headerGetter(name);
1277
- return acc;
1278
- }, {});
1279
- } else {
1280
- return Object.entries(req.headers).reduce(
1281
- (acc, [key, value]) => {
1282
- acc[key] = Array.isArray(value) ? value.join(", ") : value || void 0;
1283
- return acc;
1284
- },
1285
- {}
1286
- );
1287
- }
1288
- };
1289
- }
1290
- function createResponseObject(res, responseState, ctx) {
1291
- return {
1292
- raw: res,
1293
- get sent() {
1294
- return responseState.sent;
1295
- },
1296
- status: createStatusSetter(res, responseState, ctx),
1297
- header: createHeaderSetter(res, responseState, ctx),
1298
- headers: createHeadersSetter(res, responseState, ctx),
1299
- type: createContentTypeSetter(res, responseState, ctx),
1300
- json: createJsonResponder(res, responseState),
1301
- text: createTextResponder(res, responseState),
1302
- html: createHtmlResponder(res, responseState),
1303
- redirect: createRedirectResponder(res, responseState),
1304
- stream: createStreamResponder(res, responseState)
1305
- };
1306
- }
1307
- function createStatusSetter(res, responseState, ctx) {
1308
- return function statusSetter(code) {
1309
- if (responseState.sent) {
1310
- throw new ResponseSentError();
1311
- }
1312
- res.statusCode = code;
1313
- return ctx.response;
1314
- };
1315
- }
1316
- function createHeaderSetter(res, responseState, ctx) {
1317
- return function headerSetter(name, value) {
1318
- if (responseState.sent) {
1319
- throw new ResponseSentHeaderError();
1320
- }
1321
- res.setHeader(name, value);
1322
- return ctx.response;
1323
- };
1324
- }
1325
- function createHeadersSetter(res, responseState, ctx) {
1326
- return function headersSetter(headers) {
1327
- if (responseState.sent) {
1328
- throw new ResponseSentHeaderError();
1329
- }
1330
- for (const [name, value] of Object.entries(headers)) {
1331
- res.setHeader(name, value);
1332
- }
1333
- return ctx.response;
1334
- };
1335
- }
1336
- function createContentTypeSetter(res, responseState, ctx) {
1337
- return function typeSetter(type) {
1338
- if (responseState.sent) {
1339
- throw new ResponseSentContentError();
1340
- }
1341
- res.setHeader(CONTENT_TYPE_HEADER, type);
1342
- return ctx.response;
1343
- };
1344
- }
1345
- function createJsonResponder(res, responseState) {
1346
- return function jsonResponder(body, status) {
1347
- if (responseState.sent) {
1348
- throw new ResponseSentError();
1349
- }
1350
- if (status !== void 0) {
1351
- res.statusCode = status;
1352
- }
1353
- res.setHeader(CONTENT_TYPE_HEADER, "application/json");
1354
- res.end(JSON.stringify(body));
1355
- responseState.sent = true;
1356
- };
1357
- }
1358
- function createTextResponder(res, responseState) {
1359
- return function textResponder(body, status) {
1360
- if (responseState.sent) {
1361
- throw new ResponseSentError();
1362
- }
1363
- if (status !== void 0) {
1364
- res.statusCode = status;
1365
- }
1366
- res.setHeader(CONTENT_TYPE_HEADER, "text/plain");
1367
- res.end(body);
1368
- responseState.sent = true;
1369
- };
1370
- }
1371
- function createHtmlResponder(res, responseState) {
1372
- return function htmlResponder(body, status) {
1373
- if (responseState.sent) {
1374
- throw new ResponseSentError();
1375
- }
1376
- if (status !== void 0) {
1377
- res.statusCode = status;
1378
- }
1379
- res.setHeader(CONTENT_TYPE_HEADER, "text/html");
1380
- res.end(body);
1381
- responseState.sent = true;
1382
- };
1383
- }
1384
- function createRedirectResponder(res, responseState) {
1385
- return function redirectResponder(url, status = 302) {
1386
- if (responseState.sent) {
1387
- throw new ResponseSentError();
1388
- }
1389
- res.statusCode = status;
1390
- res.setHeader("Location", url);
1391
- res.end();
1392
- responseState.sent = true;
1393
- };
1394
- }
1395
- function createStreamResponder(res, responseState) {
1396
- return function streamResponder(readable, options = {}) {
1397
- if (responseState.sent) {
1398
- throw new ResponseSentError();
1399
- }
1400
- if (options.status !== void 0) {
1401
- res.statusCode = options.status;
1402
- }
1403
- if (options.contentType) {
1404
- res.setHeader(CONTENT_TYPE_HEADER, options.contentType);
1405
- }
1406
- if (options.headers) {
1407
- for (const [name, value] of Object.entries(options.headers)) {
1408
- res.setHeader(name, value);
1409
- }
1410
- }
1411
- readable.pipe(res);
1412
- readable.on("end", () => {
1413
- responseState.sent = true;
1414
- });
1415
- readable.on("error", (err) => {
1416
- console.error("Stream error:", err);
1417
- if (!responseState.sent) {
1418
- res.statusCode = 500;
1419
- res.end("Stream error");
1420
- responseState.sent = true;
1421
- }
1422
- });
1423
- };
1424
- }
1425
- async function parseBodyIfNeeded(req, ctx, options = {}) {
1426
- if (shouldSkipParsing(req.method)) {
1427
- return;
1428
- }
1429
- const contentType = req.headers["content-type"] || "";
1430
- const contentLength = parseInt(req.headers["content-length"] || "0", 10);
1431
- if (contentLength === 0) {
1432
- return;
1433
- }
1434
- const limits = {
1435
- json: options.bodyLimits?.json ?? DEFAULT_BODY_LIMITS.json,
1436
- form: options.bodyLimits?.form ?? DEFAULT_BODY_LIMITS.form,
1437
- text: options.bodyLimits?.text ?? DEFAULT_BODY_LIMITS.text,
1438
- raw: options.bodyLimits?.raw ?? DEFAULT_BODY_LIMITS.raw,
1439
- multipart: {
1440
- maxFileSize: options.bodyLimits?.multipart?.maxFileSize ?? DEFAULT_BODY_LIMITS.multipart.maxFileSize,
1441
- maxFiles: options.bodyLimits?.multipart?.maxFiles ?? DEFAULT_BODY_LIMITS.multipart.maxFiles,
1442
- maxFieldSize: options.bodyLimits?.multipart?.maxFieldSize ?? DEFAULT_BODY_LIMITS.multipart.maxFieldSize,
1443
- maxTotalSize: options.bodyLimits?.multipart?.maxTotalSize ?? DEFAULT_BODY_LIMITS.multipart.maxTotalSize
1444
- }
1445
- };
1446
- try {
1447
- if (contentType.includes("application/json")) {
1448
- if (contentLength > limits.json) {
1449
- throw new Error(`JSON body too large: ${contentLength} > ${limits.json} bytes`);
1450
- }
1451
- await parseJsonBody(req, ctx);
1452
- } else if (contentType.includes("application/x-www-form-urlencoded")) {
1453
- if (contentLength > limits.form) {
1454
- throw new Error(`Form body too large: ${contentLength} > ${limits.form} bytes`);
1455
- }
1456
- await parseFormUrlEncodedBody(req, ctx);
1457
- } else if (contentType.includes("text/")) {
1458
- if (contentLength > limits.text) {
1459
- throw new Error(`Text body too large: ${contentLength} > ${limits.text} bytes`);
1460
- }
1461
- await parseTextBody(req, ctx);
1462
- } else if (isMultipartContent(contentType)) {
1463
- await parseMultipartBody(req, ctx, limits.multipart);
1464
- } else {
1465
- if (contentLength > limits.raw) {
1466
- throw new Error(`Request body too large: ${contentLength} > ${limits.raw} bytes`);
1467
- }
1468
- return;
1469
- }
1470
- } catch (error) {
1471
- const errorType = contentType.includes("multipart") ? "multipart_parse_error" : "body_read_error";
1472
- setBodyError(ctx, errorType, "Error reading request body", error);
1473
- }
1474
- }
1475
- function shouldSkipParsing(method) {
1476
- const skipMethods = ["GET", "HEAD", "OPTIONS"];
1477
- return skipMethods.includes(method || "GET");
1478
- }
1479
- async function parseJsonBody(req, ctx) {
1480
- const body = await readRequestBody(req);
1481
- if (!body) {
1482
- console.warn("Empty body, skipping JSON parsing");
1483
- return;
1484
- }
1485
- if (body.trim() === "null") {
1486
- console.warn('Body is the string "null"');
1487
- ctx.request.body = null;
1488
- return;
1489
- }
1490
- try {
1491
- const json = JSON.parse(body);
1492
- ctx.request.body = json;
1493
- } catch (error) {
1494
- ctx.request.body = null;
1495
- setBodyError(ctx, "json_parse_error", "Invalid JSON in request body", error);
1496
- }
1497
- }
1498
- async function parseFormUrlEncodedBody(req, ctx) {
1499
- const body = await readRequestBody(req);
1500
- if (!body) return;
1501
- try {
1502
- ctx.request.body = parseUrlEncodedData(body);
1503
- } catch (error) {
1504
- ctx.request.body = null;
1505
- setBodyError(ctx, "form_parse_error", "Invalid form data in request body", error);
1506
- }
1507
- }
1508
- function parseUrlEncodedData(body) {
1509
- const params = new URLSearchParams(body);
1510
- const formData = {};
1511
- params.forEach((value, key) => {
1512
- if (formData[key] !== void 0) {
1513
- if (Array.isArray(formData[key])) {
1514
- formData[key].push(value);
1515
- } else {
1516
- formData[key] = [formData[key], value];
1517
- }
1518
- } else {
1519
- formData[key] = value;
1520
- }
1521
- });
1522
- return formData;
1523
- }
1524
- async function parseTextBody(req, ctx) {
1525
- const body = await readRequestBody(req);
1526
- if (body) {
1527
- ctx.request.body = body;
1528
- }
1529
- }
1530
- async function parseMultipartBody(req, ctx, multipartLimits) {
1531
- try {
1532
- const limits = multipartLimits || DEFAULT_BODY_LIMITS.multipart;
1533
- const multipartData = await parseMultipartRequest(req, {
1534
- strategy: "stream",
1535
- maxFileSize: limits.maxFileSize,
1536
- maxFiles: limits.maxFiles,
1537
- maxFieldSize: limits.maxFieldSize
1538
- // Could add total size validation here
1539
- });
1540
- ctx.request.multipart = multipartData;
1541
- ctx.request.files = multipartData.files;
1542
- ctx.request.body = multipartData.fields;
1543
- } catch (error) {
1544
- ctx.request.body = null;
1545
- setBodyError(ctx, "multipart_parse_error", "Failed to parse multipart data", error);
1546
- }
1547
- }
1548
- function setBodyError(ctx, type, message, error) {
1549
- const bodyError = { type, message, error };
1550
- ctx.state._bodyError = bodyError;
1551
- }
1552
- async function readRequestBody(req) {
1553
- return new Promise((resolve3, reject) => {
1554
- const chunks = [];
1555
- req.on("data", (chunk) => {
1556
- chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
1557
- });
1558
- req.on("end", () => {
1559
- resolve3(Buffer.concat(chunks).toString("utf8"));
1560
- });
1561
- req.on("error", (err) => {
1562
- reject(err);
1563
- });
1564
- });
1565
- }
1566
-
1567
- // src/errors/not-found-error.ts
1568
- init_errors();
1569
- init_correlation();
1570
- var NotFoundError = class extends BlaizeError {
1571
- /**
1572
- * Creates a new NotFoundError instance
1573
- *
1574
- * @param title - Human-readable error message
1575
- * @param details - Optional context about the missing resource
1576
- * @param correlationId - Optional correlation ID (uses current context if not provided)
1577
- */
1578
- constructor(title, details = void 0, correlationId = void 0) {
1579
- super(
1580
- "NOT_FOUND" /* NOT_FOUND */,
1581
- title,
1582
- 404,
1583
- // HTTP 404 Not Found
1584
- correlationId ?? getCurrentCorrelationId(),
1585
- details
1586
- );
1587
- }
1588
- };
1589
-
1590
- // src/errors/boundary.ts
1591
- init_errors();
1592
- init_correlation();
1593
- init_internal_server_error();
1594
- function isHandledError(error) {
1595
- return error instanceof BlaizeError;
1596
- }
1597
- function formatErrorResponse(error) {
1598
- if (isHandledError(error)) {
1599
- return {
1600
- type: error.type,
1601
- title: error.title,
1602
- status: error.status,
1603
- correlationId: error.correlationId,
1604
- timestamp: error.timestamp.toISOString(),
1605
- details: error.details
1606
- };
1607
- }
1608
- const correlationId = generateCorrelationId();
1609
- let originalMessage;
1610
- if (error instanceof Error) {
1611
- originalMessage = error.message;
1612
- } else if (error === null || error === void 0) {
1613
- originalMessage = "Unknown error occurred";
1614
- } else {
1615
- originalMessage = String(error);
1616
- }
1617
- const wrappedError = new InternalServerError(
1618
- "Internal Server Error",
1619
- { originalMessage },
1620
- correlationId
1621
- );
1622
- return {
1623
- type: wrappedError.type,
1624
- title: wrappedError.title,
1625
- status: wrappedError.status,
1626
- correlationId: wrappedError.correlationId,
1627
- timestamp: wrappedError.timestamp.toISOString(),
1628
- details: wrappedError.details
1629
- };
1630
- }
1631
- function extractOrGenerateCorrelationId(headerGetter) {
1632
- return headerGetter("x-correlation-id") ?? generateCorrelationId();
1633
- }
1634
- function setErrorResponseHeaders(headerSetter, correlationId) {
1635
- headerSetter("x-correlation-id", correlationId);
1636
- }
1637
-
1638
- // src/middleware/error-boundary.ts
1639
- function createErrorBoundary(options = {}) {
1640
- const { debug = false } = options;
1641
- const middlewareFn = async (ctx, next) => {
1642
- try {
1643
- await next();
1644
- } catch (error) {
1645
- if (ctx.response.sent) {
1646
- if (debug) {
1647
- console.error("Error occurred after response was sent:", error);
1648
- }
1649
- return;
1650
- }
1651
- if (debug) {
1652
- console.error("Error boundary caught error:", error);
1653
- }
1654
- const correlationId = extractOrGenerateCorrelationId(ctx.request.header);
1655
- const errorResponse = formatErrorResponse(error);
1656
- errorResponse.correlationId = correlationId;
1657
- setErrorResponseHeaders(ctx.response.header, correlationId);
1658
- ctx.response.status(errorResponse.status).json(errorResponse);
1659
- }
1660
- };
1661
- return {
1662
- name: "ErrorBoundary",
1663
- execute: middlewareFn,
1664
- debug
1665
- };
1666
- }
1667
-
1668
- // src/server/request-handler.ts
1669
- function createRequestHandler(serverInstance) {
1670
- return async (req, res) => {
1671
- try {
1672
- const context = await createContext(req, res, {
1673
- parseBody: true
1674
- // Enable automatic body parsing
1675
- });
1676
- const errorBoundary = createErrorBoundary();
1677
- const allMiddleware = [errorBoundary, ...serverInstance.middleware];
1678
- const handler = compose(allMiddleware);
1679
- await runWithContext(context, async () => {
1680
- await handler(context, async () => {
1681
- if (!context.response.sent) {
1682
- await serverInstance.router.handleRequest(context);
1683
- if (!context.response.sent) {
1684
- throw new NotFoundError(
1685
- `Route not found: ${context.request.method} ${context.request.path}`
1686
- );
1687
- }
1688
- }
1689
- });
1690
- });
1691
- } catch (error) {
1692
- console.error("Error creating context:", error);
1693
- res.writeHead(500, { "Content-Type": "application/json" });
1694
- res.end(
1695
- JSON.stringify({
1696
- error: "Internal Server Error",
1697
- message: "Failed to process request"
1698
- })
1699
- );
1700
- }
1701
- };
1702
- }
1703
-
1704
- // src/server/start.ts
1705
- async function prepareCertificates(http2Options) {
1706
- if (!http2Options.enabled) {
1707
- return {};
1708
- }
1709
- const { keyFile, certFile } = http2Options;
1710
- const isDevMode = process.env.NODE_ENV === "development";
1711
- const certificatesMissing = !keyFile || !certFile;
1712
- if (certificatesMissing && isDevMode) {
1713
- const devCerts = await generateDevCertificates();
1714
- return devCerts;
1715
- }
1716
- if (certificatesMissing) {
1717
- throw new Error(
1718
- "HTTP/2 requires SSL certificates. Provide keyFile and certFile in http2 options. In development, set NODE_ENV=development to generate them automatically."
1719
- );
1720
- }
1721
- return { keyFile, certFile };
1722
- }
1723
- function createServerInstance(isHttp2, certOptions) {
1724
- if (!isHttp2) {
1725
- return http.createServer();
1726
- }
1727
- const http2ServerOptions = {
1728
- allowHTTP1: true
1729
- // Allow fallback to HTTP/1.1
1730
- };
1731
- try {
1732
- if (certOptions.keyFile) {
1733
- http2ServerOptions.key = fs2.readFileSync(certOptions.keyFile);
1734
- }
1735
- if (certOptions.certFile) {
1736
- http2ServerOptions.cert = fs2.readFileSync(certOptions.certFile);
1737
- }
1738
- } catch (err) {
1739
- throw new Error(
1740
- `Failed to read certificate files: ${err instanceof Error ? err.message : String(err)}`
1741
- );
1742
- }
1743
- return http2.createSecureServer(http2ServerOptions);
1744
- }
1745
- function listenOnPort(server, port, host, isHttp2) {
1746
- return new Promise((resolve3, reject) => {
1747
- server.listen(port, host, () => {
1748
- const protocol = isHttp2 ? "https" : "http";
1749
- const url = `${protocol}://${host}:${port}`;
1750
- console.log(`
10
+ "use strict";var lr=Object.create;var te=Object.defineProperty;var cr=Object.getOwnPropertyDescriptor;var dr=Object.getOwnPropertyNames;var pr=Object.getPrototypeOf,fr=Object.prototype.hasOwnProperty;var q=(e,t)=>()=>(e&&(t=e(e=0)),t);var Q=(e,t)=>{for(var r in t)te(e,r,{get:t[r],enumerable:!0})},Ye=(e,t,r,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of dr(t))!fr.call(e,n)&&n!==r&&te(e,n,{get:()=>t[n],enumerable:!(o=cr(t,n))||o.enumerable});return e};var T=(e,t,r)=>(r=e!=null?lr(pr(e)):{},Ye(t||!e||!e.__esModule?te(r,"default",{value:e,enumerable:!0}):r,e)),mr=e=>Ye(te({},"__esModule",{value:!0}),e);function Er(e){return typeof e=="object"&&e!==null&&"type"in e&&"message"in e&&"error"in e&&typeof e.type=="string"&&typeof e.message=="string"}var P,dt,h,x=q(()=>{"use strict";P=(d=>(d.VALIDATION_ERROR="VALIDATION_ERROR",d.NOT_FOUND="NOT_FOUND",d.UNAUTHORIZED="UNAUTHORIZED",d.FORBIDDEN="FORBIDDEN",d.CONFLICT="CONFLICT",d.RATE_LIMITED="RATE_LIMITED",d.INTERNAL_SERVER_ERROR="INTERNAL_SERVER_ERROR",d.PAYLOAD_TOO_LARGE="PAYLOAD_TOO_LARGE",d.UNSUPPORTED_MEDIA_TYPE="UNSUPPORTED_MEDIA_TYPE",d.UPLOAD_TIMEOUT="UPLOAD_TIMEOUT",d.UNPROCESSABLE_ENTITY="UNPROCESSABLE_ENTITY",d.NETWORK_ERROR="NETWORK_ERROR",d.TIMEOUT_ERROR="TIMEOUT_ERROR",d.PARSE_ERROR="PARSE_ERROR",d.HTTP_ERROR="HTTP_ERROR",d))(P||{}),dt=(n=>(n.LOW="low",n.MEDIUM="medium",n.HIGH="high",n.CRITICAL="critical",n))(dt||{}),h=class extends Error{type;title;status;correlationId;timestamp;details;constructor(t,r,o,n,i){super(r),this.name=this.constructor.name,this.type=t,this.title=r,this.status=o,this.correlationId=n,this.timestamp=new Date,this.details=i,Object.setPrototypeOf(this,new.target.prototype),Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor)}toJSON(){let t={type:this.type,title:this.title,status:this.status,correlationId:this.correlationId,timestamp:this.timestamp.toISOString()};return this.details!==void 0?{...t,details:this.details}:t}toString(){return`${this.name}: ${this.title} [${this.correlationId}]`}}});function De(){let e=Date.now().toString(36),t=Math.random().toString(36).substr(2,9);return`req_${e}_${t}`}function R(){let e=xr.getStore();return e&&e.trim()?e:"unknown"}var pt,xr,v=q(()=>{"use strict";pt=require("async_hooks"),xr=new pt.AsyncLocalStorage});var ft={};Q(ft,{InternalServerError:()=>D});var D,W=q(()=>{"use strict";x();v();D=class extends h{constructor(t,r=void 0,o=void 0){super("INTERNAL_SERVER_ERROR",t,500,o??R(),r)}}});var H={};Q(H,{ValidationError:()=>k});var k,z=q(()=>{"use strict";x();v();k=class extends h{constructor(t,r=void 0,o=void 0){super("VALIDATION_ERROR",t,400,o??R(),r)}}});var ke={};Q(ke,{PayloadTooLargeError:()=>G});var G,le=q(()=>{"use strict";v();x();G=class extends h{constructor(t,r,o){super("PAYLOAD_TOO_LARGE",t,413,o??R(),r)}}});var ze={};Q(ze,{UnsupportedMediaTypeError:()=>Z});var Z,ce=q(()=>{"use strict";v();x();Z=class extends h{constructor(t,r,o){super("UNSUPPORTED_MEDIA_TYPE",t,415,o??R(),r)}}});var Uo={};Q(Uo,{Blaize:()=>Ao,BlaizeError:()=>h,ConflictError:()=>Se,ErrorSeverity:()=>dt,ErrorType:()=>P,ForbiddenError:()=>Re,InternalServerError:()=>D,MiddlewareAPI:()=>ar,NotFoundError:()=>$,PayloadTooLargeError:()=>G,PluginsAPI:()=>ur,RateLimitError:()=>Te,RequestTimeoutError:()=>Ee,RouterAPI:()=>sr,ServerAPI:()=>ir,UnauthorizedError:()=>we,UnprocessableEntityError:()=>xe,UnsupportedMediaTypeError:()=>Z,VERSION:()=>nr,ValidationError:()=>k,compose:()=>A,createDeleteRoute:()=>Ce,createGetRoute:()=>be,createHeadRoute:()=>Me,createMiddleware:()=>re,createOptionsRoute:()=>Oe,createPatchRoute:()=>Fe,createPlugin:()=>oe,createPostRoute:()=>Pe,createPutRoute:()=>ve,createServer:()=>he,isBodyParseError:()=>Er});module.exports=mr(Uo);function Ke(e,t,r){if(!e||e.skip&&e.skip(t))return Promise.resolve(r());try{let o=e.execute(t,r);return o instanceof Promise?o:Promise.resolve(o)}catch(o){return Promise.reject(o)}}function A(e){return e.length===0?async(t,r)=>{await Promise.resolve(r())}:async function(t,r){let o=new Set,n=async i=>{if(i>=e.length)return Promise.resolve(r());let s=e[i];return Ke(s,t,()=>{if(o.has(i))throw new Error("next() called multiple times");return o.add(i),n(i+1)})};return n(0)}}function re(e){if(typeof e=="function")return{name:"anonymous",execute:e,debug:!1};let{name:t="anonymous",handler:r,skip:o,debug:n=!1}=e,i={name:t,execute:r,debug:n};return o!==void 0?{...i,skip:o}:i}function oe(e,t,r,o={}){if(!e||typeof e!="string")throw new Error("Plugin name must be a non-empty string");if(!t||typeof t!="string")throw new Error("Plugin version must be a non-empty string");if(typeof r!="function")throw new Error("Plugin setup must be a function");return function(i){let s={...o,...i},a={name:e,version:t,register:async u=>{let c=await r(u,s);c&&typeof c=="object"&&Object.assign(a,c)}};return a}}var rt=require("url");var ne={};function Xe(e){ne={...ne,...e}}function et(){if(!ne.routesDir)throw new Error("Routes directory not configured. Make sure server is properly initialized.");return ne.routesDir}var tt=T(require("path"),1);function ie(e,t){e.startsWith("file://")&&(e=e.replace("file://","")),t.startsWith("file://")&&(t=t.replace("file://",""));let r=e.replace(/\\/g,"/"),o=t.replace(/\\/g,"/"),n=o.endsWith("/")?o:`${o}/`,i=r;r.startsWith(n)?i=r.substring(n.length):r.startsWith(o)?(i=r.substring(o.length),i.startsWith("/")&&(i=i.substring(1))):i=tt.relative(o,r).replace(/\\/g,"/"),i=i.replace(/\.[^.]+$/,"");let s=i.split("/").filter(Boolean),a=[],u=s.map(S=>{if(S.startsWith("[")&&S.endsWith("]")){let p=S.slice(1,-1);return a.push(p),`:${p}`}return S}),c=u.length>0?`/${u.join("/")}`:"/";return c.endsWith("/index")&&(c=c.slice(0,-6)||"/"),{filePath:e,routePath:c,params:a}}function gr(){let e=Error.prepareStackTrace;try{Error.prepareStackTrace=(n,i)=>i;let r=new Error().stack[3];if(!r||typeof r.getFileName!="function")throw new Error("Unable to determine caller file frame");let o=r.getFileName();if(!o)throw new Error("Unable to determine caller file name");return o.startsWith("file://")?(0,rt.fileURLToPath)(o):o}finally{Error.prepareStackTrace=e}}function U(){let e=gr(),t=et(),r=ie(e,t);return console.log(`\u{1F50E} Parsed route path: ${r.routePath} from file: ${e}`),r.routePath}var be=e=>{L("GET",e);let t=U();return{GET:e,path:t}},Pe=e=>{L("POST",e);let t=U();return{POST:e,path:t}},ve=e=>{L("PUT",e);let t=U();return{PUT:e,path:t}},Ce=e=>{L("DELETE",e);let t=U();return{DELETE:e,path:t}},Fe=e=>{L("PATCH",e);let t=U();return{PATCH:e,path:t}},Me=e=>{L("HEAD",e);let t=U();return{HEAD:e,path:t}},Oe=e=>{L("OPTIONS",e);let t=U();return{OPTIONS:e,path:t}};function L(e,t){if(!t.handler||typeof t.handler!="function")throw new Error(`Handler for method ${e} must be a function`);if(t.middleware&&!Array.isArray(t.middleware))throw new Error(`Middleware for method ${e} must be an array`);switch(t.schema&&yr(e,t.schema),e){case"GET":case"HEAD":case"DELETE":t.schema?.body&&console.warn(`Warning: ${e} requests typically don't have request bodies`);break}}function yr(e,t){let{params:r,query:o,body:n,response:i}=t;if(r&&(!r._def||typeof r.parse!="function"))throw new Error(`Params schema for ${e} must be a valid Zod schema`);if(o&&(!o._def||typeof o.parse!="function"))throw new Error(`Query schema for ${e} must be a valid Zod schema`);if(n&&(!n._def||typeof n.parse!="function"))throw new Error(`Body schema for ${e} must be a valid Zod schema`);if(i&&(!i._def||typeof i.parse!="function"))throw new Error(`Response schema for ${e} must be a valid Zod schema`)}var rr=require("async_hooks"),or=T(require("events"),1);var Ne=T(require("fs"),1),Ft=T(require("http"),1),Mt=T(require("http2"),1);var O=T(require("fs"),1),se=T(require("path"),1),ot=T(require("selfsigned"),1);async function nt(){let e=se.join(process.cwd(),".blaizejs","certs"),t=se.join(e,"dev.key"),r=se.join(e,"dev.cert");if(O.existsSync(t)&&O.existsSync(r))return{keyFile:t,certFile:r};O.existsSync(e)||O.mkdirSync(e,{recursive:!0});let i=ot.generate([{name:"commonName",value:"localhost"}],{days:365,algorithm:"sha256",keySize:2048,extensions:[{name:"basicConstraints",cA:!0},{name:"keyUsage",keyCertSign:!0,digitalSignature:!0,nonRepudiation:!0,keyEncipherment:!0,dataEncipherment:!0},{name:"extKeyUsage",serverAuth:!0,clientAuth:!0},{name:"subjectAltName",altNames:[{type:2,value:"localhost"},{type:7,ip:"127.0.0.1"}]}]});return O.writeFileSync(t,Buffer.from(i.private,"utf-8")),O.writeFileSync(r,Buffer.from(i.cert,"utf-8")),console.log(`
11
+ \u{1F512} Generated self-signed certificates for development at ${e}
12
+ `),{keyFile:t,certFile:r}}var C=class extends Error{constructor(t="\u274C Response has already been sent"){super(t),this.name="ResponseSentError"}},V=class extends C{constructor(t="Cannot set header after response has been sent"){super(t)}},ae=class extends C{constructor(t="Cannot set content type after response has been sent"){super(t)}},ue=class extends C{constructor(t="Invalide URL"){super(t)}};var it=require("async_hooks"),hr=new it.AsyncLocalStorage;function st(e,t){return hr.run(e,t)}var mt=T(require("crypto"),1),gt=require("fs"),yt=require("os"),ht=require("path"),Be=require("stream");var wr=/boundary=([^;]+)/i,Rr=/Content-Disposition:\s*form-data;\s*name="([^"]+)"(?:;[\s\r\n]*filename="([^"]*)")?/i,Sr=/Content-Type:\s*([^\r\n]+)/i,Tr=/multipart\/form-data/i;function at(e){let t=e.match(wr);if(!t||!t[1])return null;let r=t[1].trim();return r.startsWith('"')&&r.endsWith('"')&&(r=r.slice(1,-1)),r||null}function ut(e){let t=e.match(Rr);return!t||!t[1]?null:{name:t[1],filename:t[2]!==void 0?t[2]:void 0}}function lt(e){let t=e.match(Sr);return t&&t[1]?.trim()?t[1].trim():"application/octet-stream"}function ct(e){return Tr.test(e)}var br={maxFileSize:10*1024*1024,maxFiles:10,maxFieldSize:1*1024*1024,allowedMimeTypes:[],allowedExtensions:[],strategy:"stream",tempDir:(0,yt.tmpdir)(),computeHash:!1};function Pr(e,t={}){return{boundary:Buffer.from(`--${e}`),options:{...br,...t},fields:new Map,files:new Map,buffer:Buffer.alloc(0),stage:"boundary",currentHeaders:"",currentField:null,currentFilename:void 0,currentMimetype:"application/octet-stream",currentContentLength:0,fileCount:0,fieldCount:0,currentBufferChunks:[],currentStream:null,currentTempPath:null,currentWriteStream:null,streamController:null,cleanupTasks:[],hasFoundValidBoundary:!1,hasProcessedAnyPart:!1,isFinished:!1}}async function vr(e,t){let r=Buffer.concat([e.buffer,t]),o={...e,buffer:r};for(;o.buffer.length>0&&!o.isFinished;){let n=await Cr(o);if(n===o)break;o=n}return o}async function Cr(e){switch(e.stage){case"boundary":return Fr(e);case"headers":return Mr(e);case"content":return Or(e);default:{let{InternalServerError:t}=await Promise.resolve().then(()=>(W(),ft));throw new t("Invalid parser stage",{operation:e.stage})}}}function Fr(e){let t=e.buffer.indexOf(e.boundary);if(t===-1)return e;let r=!0,o=e.buffer.subarray(t+e.boundary.length);return o.length>=2&&o.subarray(0,2).equals(Buffer.from("--"))?{...e,buffer:o,hasFoundValidBoundary:r,isFinished:!0,stage:"boundary"}:(o.length>=2&&o.subarray(0,2).equals(Buffer.from(`\r
13
+ `))&&(o=o.subarray(2)),{...e,buffer:o,hasFoundValidBoundary:r,stage:"headers",currentHeaders:""})}async function Mr(e){let t=e.buffer.indexOf(`\r
14
+ \r
15
+ `);if(t===-1)return e;let r=e.buffer.subarray(0,t).toString("utf8"),o=e.buffer.subarray(t+4),n=ut(r);if(!n){let{ValidationError:a}=await Promise.resolve().then(()=>(z(),H));throw new a("Missing or invalid Content-Disposition header")}let i=lt(r),s=n.filename!==void 0;if(s&&e.fileCount>=e.options.maxFiles){let{PayloadTooLargeError:a}=await Promise.resolve().then(()=>(le(),ke));throw new a("Too many files in upload",{fileCount:e.fileCount+1,maxFiles:e.options.maxFiles,filename:n.filename})}if(s&&e.options.allowedMimeTypes.length>0&&!e.options.allowedMimeTypes.includes(i)){let{UnsupportedMediaTypeError:a}=await Promise.resolve().then(()=>(ce(),ze));throw new a("File type not allowed",{receivedMimeType:i,allowedMimeTypes:e.options.allowedMimeTypes,filename:n.filename})}return{...e,buffer:o,stage:"content",currentHeaders:r,currentField:n.name,currentFilename:n.filename,currentMimetype:i,currentContentLength:0,fileCount:s?e.fileCount+1:e.fileCount,fieldCount:s?e.fieldCount:e.fieldCount+1,currentBufferChunks:[]}}async function Or(e){let t=e.buffer.indexOf(e.boundary),r,o=!1,n=e.buffer;if(t===-1){let s=Math.max(0,e.buffer.length-e.boundary.length);if(s===0)return e;r=e.buffer.subarray(0,s),n=e.buffer.subarray(s)}else{let s=Math.max(0,t-2);r=e.buffer.subarray(0,s),n=e.buffer.subarray(t),o=!0}let i={...e,buffer:n};return r.length>0&&(i=await Dr(i,r)),o&&(i=await Br(i),i={...i,stage:"boundary",hasProcessedAnyPart:!0}),i}async function Dr(e,t){let r=e.currentContentLength+t.length,o=e.currentFilename!==void 0?e.options.maxFileSize:e.options.maxFieldSize;if(r>o){let n=e.currentFilename!==void 0,{PayloadTooLargeError:i}=await Promise.resolve().then(()=>(le(),ke)),s=e.currentField?{contentType:n?"file":"field",currentSize:r,maxSize:o,field:e.currentField,filename:e.currentFilename}:{contentType:n?"file":"field",currentSize:r,maxSize:o,filename:e.currentFilename};throw new i(`${n?"File":"Field"} size exceeds limit`,s)}return e.currentFilename!==void 0?kr(e,t,r):{...e,currentContentLength:r,currentBufferChunks:[...e.currentBufferChunks,t]}}async function kr(e,t,r){switch(e.options.strategy){case"memory":return{...e,currentContentLength:r,currentBufferChunks:[...e.currentBufferChunks,t]};case"stream":return e.streamController&&e.streamController.enqueue(t),{...e,currentContentLength:r};case"temp":return e.currentWriteStream&&await Ar(e.currentWriteStream,t),{...e,currentContentLength:r};default:{let{ValidationError:o}=await Promise.resolve().then(()=>(z(),H));throw new o("Invalid parsing strategy")}}}async function zr(e){if(e.currentFilename===void 0)return e;switch(e.options.strategy){case"memory":return{...e,currentBufferChunks:[]};case"stream":{let t=null,r=new ReadableStream({start:o=>{t=o}});return{...e,currentStream:r,streamController:t}}case"temp":{let t=(0,ht.join)(e.options.tempDir,`upload-${mt.randomUUID()}`),r=(0,gt.createWriteStream)(t),o=async()=>{try{let{unlink:n}=await import("fs/promises");await n(t)}catch(n){console.warn(`Failed to cleanup temp file: ${t}`,n)}};return{...e,currentTempPath:t,currentWriteStream:r,cleanupTasks:[...e.cleanupTasks,o]}}default:{let{ValidationError:t}=await Promise.resolve().then(()=>(z(),H));throw new t("Invalid file processing strategy")}}}async function Br(e){return e.currentField?e.currentFilename!==void 0?$r(e):Nr(e):J(e)}async function $r(e){if(!e.currentField||e.currentFilename===void 0)return J(e);let t,r,o;switch(e.options.strategy){case"memory":r=Buffer.concat(e.currentBufferChunks),t=Be.Readable.from(r);break;case"stream":e.streamController&&e.streamController.close(),t=e.currentStream;break;case"temp":e.currentWriteStream&&await Rt(e.currentWriteStream),o=e.currentTempPath,t=Be.Readable.from(Buffer.alloc(0));break;default:{let{ValidationError:s}=await Promise.resolve().then(()=>(z(),H));throw new s("Invalid file finalization strategy")}}let n={filename:e.currentFilename,fieldname:e.currentField,mimetype:e.currentMimetype,size:e.currentContentLength,stream:t,buffer:r,tempPath:o},i=wt(e.files,e.currentField,n);return{...J(e),files:i}}function Nr(e){if(!e.currentField)return J(e);let t=Buffer.concat(e.currentBufferChunks).toString("utf8"),r=wt(e.fields,e.currentField,t);return{...J(e),fields:r}}function J(e){return{...e,currentField:null,currentFilename:void 0,currentContentLength:0,currentBufferChunks:[],currentStream:null,streamController:null,currentTempPath:null,currentWriteStream:null}}function wt(e,t,r){let o=new Map(e),n=o.get(t)||[];return o.set(t,[...n,r]),o}async function Ir(e){if(!e.hasFoundValidBoundary){let{ValidationError:o}=await Promise.resolve().then(()=>(z(),H));throw new o("No valid multipart boundary found")}if(e.hasFoundValidBoundary&&!e.hasProcessedAnyPart){let{ValidationError:o}=await Promise.resolve().then(()=>(z(),H));throw new o("Empty multipart request")}let t={};for(let[o,n]of e.fields.entries())t[o]=n.length===1?n[0]:n;let r={};for(let[o,n]of e.files.entries())r[o]=n.length===1?n[0]:n;return{fields:t,files:r}}async function _r(e){await Promise.allSettled(e.cleanupTasks.map(t=>t())),e.streamController&&e.streamController.close(),e.currentWriteStream&&await Rt(e.currentWriteStream)}async function Ar(e,t){return new Promise((r,o)=>{e.write(t,n=>{n?o(n):r()})})}async function Rt(e){return new Promise(t=>{e.end(()=>t())})}async function St(e,t={}){let r=e.headers["content-type"]||"",o=at(r);if(!o){let{UnsupportedMediaTypeError:i}=await Promise.resolve().then(()=>(ce(),ze));throw new i("Missing boundary in multipart content-type",{receivedContentType:r,expectedFormat:"multipart/form-data; boundary=..."})}let n=Pr(o,t);n.currentFilename!==void 0&&(n=await zr(n));try{for await(let i of e)n=await vr(n,i);return Ir(n)}finally{await _r(n)}}var Y="Content-Type",B={json:512*1024,form:1024*1024,text:5*1024*1024,multipart:{maxFileSize:50*1024*1024,maxTotalSize:100*1024*1024,maxFiles:10,maxFieldSize:1024*1024},raw:10*1024*1024};function Ur(e){let t=e.url||"/",r=e.headers.host||"localhost",n=`${e.socket&&e.socket.encrypted?"https":"http"}://${r}${t.startsWith("/")?"":"/"}${t}`;try{let i=new URL(n),s=i.pathname,a={};return i.searchParams.forEach((u,c)=>{a[c]!==void 0?Array.isArray(a[c])?a[c].push(u):a[c]=[a[c],u]:a[c]=u}),{path:s,url:i,query:a}}catch(i){throw console.warn(`Invalid URL: ${n}`,i),new ue(`Invalid URL: ${n}`)}}function Lr(e){return"stream"in e||"httpVersionMajor"in e&&e.httpVersionMajor===2}function Hr(e){let t=e.socket&&e.socket.encrypted,r=e.headers["x-forwarded-proto"];return r?Array.isArray(r)?r[0]?.split(",")[0]?.trim()||"http":r.split(",")[0]?.trim()||"http":t?"https":"http"}async function Tt(e,t,r={}){let{path:o,url:n,query:i}=Ur(e),s=e.method||"GET",a=Lr(e),u=Hr(e),c={},S={...r.initialState||{}},p={sent:!1},g={request:qr(e,{path:o,url:n,query:i,params:c,method:s,isHttp2:a,protocol:u}),response:{},state:S};return g.response=Qr(t,p,g),r.parseBody&&await to(e,g,r),g}function qr(e,t){return{raw:e,...t,header:Et(e),headers:jr(e),body:void 0}}function Et(e){return t=>{let r=e.headers[t.toLowerCase()];return Array.isArray(r)?r.join(", "):r||void 0}}function jr(e){let t=Et(e);return r=>r&&Array.isArray(r)&&r.length>0?r.reduce((o,n)=>(o[n]=t(n),o),{}):Object.entries(e.headers).reduce((o,[n,i])=>(o[n]=Array.isArray(i)?i.join(", "):i||void 0,o),{})}function Qr(e,t,r){return{raw:e,get sent(){return t.sent},status:Vr(e,t,r),header:Wr(e,t,r),headers:Gr(e,t,r),type:Zr(e,t,r),json:Jr(e,t),text:Yr(e,t),html:Kr(e,t),redirect:Xr(e,t),stream:eo(e,t)}}function Vr(e,t,r){return function(n){if(t.sent)throw new C;return e.statusCode=n,r.response}}function Wr(e,t,r){return function(n,i){if(t.sent)throw new V;return e.setHeader(n,i),r.response}}function Gr(e,t,r){return function(n){if(t.sent)throw new V;for(let[i,s]of Object.entries(n))e.setHeader(i,s);return r.response}}function Zr(e,t,r){return function(n){if(t.sent)throw new ae;return e.setHeader(Y,n),r.response}}function Jr(e,t){return function(o,n){if(t.sent)throw new C;n!==void 0&&(e.statusCode=n),e.setHeader(Y,"application/json"),e.end(JSON.stringify(o)),t.sent=!0}}function Yr(e,t){return function(o,n){if(t.sent)throw new C;n!==void 0&&(e.statusCode=n),e.setHeader(Y,"text/plain"),e.end(o),t.sent=!0}}function Kr(e,t){return function(o,n){if(t.sent)throw new C;n!==void 0&&(e.statusCode=n),e.setHeader(Y,"text/html"),e.end(o),t.sent=!0}}function Xr(e,t){return function(o,n=302){if(t.sent)throw new C;e.statusCode=n,e.setHeader("Location",o),e.end(),t.sent=!0}}function eo(e,t){return function(o,n={}){if(t.sent)throw new C;if(n.status!==void 0&&(e.statusCode=n.status),n.contentType&&e.setHeader(Y,n.contentType),n.headers)for(let[i,s]of Object.entries(n.headers))e.setHeader(i,s);o.pipe(e),o.on("end",()=>{t.sent=!0}),o.on("error",i=>{console.error("Stream error:",i),t.sent||(e.statusCode=500,e.end("Stream error"),t.sent=!0)})}}async function to(e,t,r={}){if(ro(e.method))return;let o=e.headers["content-type"]||"",n=parseInt(e.headers["content-length"]||"0",10);if(n===0)return;let i={json:r.bodyLimits?.json??B.json,form:r.bodyLimits?.form??B.form,text:r.bodyLimits?.text??B.text,raw:r.bodyLimits?.raw??B.raw,multipart:{maxFileSize:r.bodyLimits?.multipart?.maxFileSize??B.multipart.maxFileSize,maxFiles:r.bodyLimits?.multipart?.maxFiles??B.multipart.maxFiles,maxFieldSize:r.bodyLimits?.multipart?.maxFieldSize??B.multipart.maxFieldSize,maxTotalSize:r.bodyLimits?.multipart?.maxTotalSize??B.multipart.maxTotalSize}};try{if(o.includes("application/json")){if(n>i.json)throw new Error(`JSON body too large: ${n} > ${i.json} bytes`);await oo(e,t)}else if(o.includes("application/x-www-form-urlencoded")){if(n>i.form)throw new Error(`Form body too large: ${n} > ${i.form} bytes`);await no(e,t)}else if(o.includes("text/")){if(n>i.text)throw new Error(`Text body too large: ${n} > ${i.text} bytes`);await so(e,t)}else if(ct(o))await ao(e,t,i.multipart);else{if(n>i.raw)throw new Error(`Request body too large: ${n} > ${i.raw} bytes`);return}}catch(s){let a=o.includes("multipart")?"multipart_parse_error":"body_read_error";de(t,a,"Error reading request body",s)}}function ro(e){return["GET","HEAD","OPTIONS"].includes(e||"GET")}async function oo(e,t){let r=await $e(e);if(!r){console.warn("Empty body, skipping JSON parsing");return}if(r.trim()==="null"){console.warn('Body is the string "null"'),t.request.body=null;return}try{let o=JSON.parse(r);t.request.body=o}catch(o){t.request.body=null,de(t,"json_parse_error","Invalid JSON in request body",o)}}async function no(e,t){let r=await $e(e);if(r)try{t.request.body=io(r)}catch(o){t.request.body=null,de(t,"form_parse_error","Invalid form data in request body",o)}}function io(e){let t=new URLSearchParams(e),r={};return t.forEach((o,n)=>{r[n]!==void 0?Array.isArray(r[n])?r[n].push(o):r[n]=[r[n],o]:r[n]=o}),r}async function so(e,t){let r=await $e(e);r&&(t.request.body=r)}async function ao(e,t,r){try{let o=r||B.multipart,n=await St(e,{strategy:"stream",maxFileSize:o.maxFileSize,maxFiles:o.maxFiles,maxFieldSize:o.maxFieldSize});t.request.multipart=n,t.request.files=n.files,t.request.body=n.fields}catch(o){t.request.body=null,de(t,"multipart_parse_error","Failed to parse multipart data",o)}}function de(e,t,r,o){let n={type:t,message:r,error:o};e.state._bodyError=n}async function $e(e){return new Promise((t,r)=>{let o=[];e.on("data",n=>{o.push(Buffer.isBuffer(n)?n:Buffer.from(n))}),e.on("end",()=>{t(Buffer.concat(o).toString("utf8"))}),e.on("error",n=>{r(n)})})}x();v();var $=class extends h{constructor(t,r=void 0,o=void 0){super("NOT_FOUND",t,404,o??R(),r)}};x();v();W();function uo(e){return e instanceof h}function xt(e){if(uo(e))return{type:e.type,title:e.title,status:e.status,correlationId:e.correlationId,timestamp:e.timestamp.toISOString(),details:e.details};let t=De(),r;e instanceof Error?r=e.message:e==null?r="Unknown error occurred":r=String(e);let o=new D("Internal Server Error",{originalMessage:r},t);return{type:o.type,title:o.title,status:o.status,correlationId:o.correlationId,timestamp:o.timestamp.toISOString(),details:o.details}}function bt(e){return e("x-correlation-id")??De()}function Pt(e,t){e("x-correlation-id",t)}function vt(e={}){let{debug:t=!1}=e;return{name:"ErrorBoundary",execute:async(o,n)=>{try{await n()}catch(i){if(o.response.sent){t&&console.error("Error occurred after response was sent:",i);return}t&&console.error("Error boundary caught error:",i);let s=bt(o.request.header),a=xt(i);a.correlationId=s,Pt(o.response.header,s),o.response.status(a.status).json(a)}},debug:t}}function Ct(e){return async(t,r)=>{try{let o=await Tt(t,r,{parseBody:!0}),i=[vt(),...e.middleware],s=A(i);await st(o,async()=>{await s(o,async()=>{if(!o.response.sent&&(await e.router.handleRequest(o),!o.response.sent))throw new $(`Route not found: ${o.request.method} ${o.request.path}`)})})}catch(o){console.error("Error creating context:",o),r.writeHead(500,{"Content-Type":"application/json"}),r.end(JSON.stringify({error:"Internal Server Error",message:"Failed to process request"}))}}}async function lo(e){if(!e.enabled)return{};let{keyFile:t,certFile:r}=e,o=process.env.NODE_ENV==="development",n=!t||!r;if(n&&o)return await nt();if(n)throw new Error("HTTP/2 requires SSL certificates. Provide keyFile and certFile in http2 options. In development, set NODE_ENV=development to generate them automatically.");return{keyFile:t,certFile:r}}function co(e,t){if(!e)return Ft.createServer();let r={allowHTTP1:!0};try{t.keyFile&&(r.key=Ne.readFileSync(t.keyFile)),t.certFile&&(r.cert=Ne.readFileSync(t.certFile))}catch(o){throw new Error(`Failed to read certificate files: ${o instanceof Error?o.message:String(o)}`)}return Mt.createSecureServer(r)}function po(e,t,r,o){return new Promise((n,i)=>{e.listen(t,r,()=>{let a=`${o?"https":"http"}://${r}:${t}`;console.log(`
1751
16
  \u{1F525}\u{1F525}\u{1F525}\u{1F525}\u{1F525}\u{1F525}\u{1F525}\u{1F525}\u{1F525}\u{1F525}\u{1F525}\u{1F525}\u{1F525}\u{1F525}\u{1F525}\u{1F525}\u{1F525}\u{1F525}\u{1F525}\u{1F525}\u{1F525}\u{1F525}\u{1F525}\u{1F525}\u{1F525}\u{1F525}\u{1F525}\u{1F525}\u{1F525}\u{1F525}\u{1F525}
1752
17
 
1753
18
  \u26A1 BlaizeJS DEVELOPMENT SERVER HOT AND READY \u26A1
1754
19
 
1755
- \u{1F680} Server: ${url}
20
+ \u{1F680} Server: ${a}
1756
21
  \u{1F525} Hot Reload: Enabled
1757
22
  \u{1F6E0}\uFE0F Mode: Development
1758
23
 
1759
24
  Time to build something amazing! \u{1F680}
1760
25
 
1761
26
  \u{1F525}\u{1F525}\u{1F525}\u{1F525}\u{1F525}\u{1F525}\u{1F525}\u{1F525}\u{1F525}\u{1F525}\u{1F525}\u{1F525}\u{1F525}\u{1F525}\u{1F525}\u{1F525}\u{1F525}\u{1F525}\u{1F525}\u{1F525}\u{1F525}\u{1F525}\u{1F525}\u{1F525}\u{1F525}\u{1F525}\u{1F525}\u{1F525}\u{1F525}\u{1F525}\u{1F525}
1762
- `);
1763
- resolve3();
1764
- });
1765
- server.on("error", (err) => {
1766
- console.error("Server error:", err);
1767
- reject(err);
1768
- });
1769
- });
1770
- }
1771
- async function initializePlugins(serverInstance) {
1772
- for (const plugin of serverInstance.plugins) {
1773
- if (typeof plugin.initialize === "function") {
1774
- await plugin.initialize(serverInstance);
1775
- }
1776
- }
1777
- }
1778
- async function startServer(serverInstance, serverOptions) {
1779
- if (serverInstance.server) {
1780
- return;
1781
- }
1782
- try {
1783
- const port = serverOptions.port;
1784
- const host = serverOptions.host;
1785
- await initializePlugins(serverInstance);
1786
- const http2Options = serverOptions.http2 || { enabled: true };
1787
- const isHttp2 = !!http2Options.enabled;
1788
- const certOptions = await prepareCertificates(http2Options);
1789
- if (serverOptions.http2 && certOptions.keyFile && certOptions.certFile) {
1790
- serverOptions.http2.keyFile = certOptions.keyFile;
1791
- serverOptions.http2.certFile = certOptions.certFile;
1792
- }
1793
- const server = createServerInstance(isHttp2, certOptions);
1794
- serverInstance.server = server;
1795
- serverInstance.port = port;
1796
- serverInstance.host = host;
1797
- const requestHandler = createRequestHandler(serverInstance);
1798
- server.on("request", requestHandler);
1799
- await listenOnPort(server, port, host, isHttp2);
1800
- } catch (error) {
1801
- console.error("Failed to start server:", error);
1802
- throw error;
1803
- }
1804
- }
1805
-
1806
- // src/server/stop.ts
1807
- var isShuttingDown = false;
1808
- async function stopServer(serverInstance, options = {}) {
1809
- const server = serverInstance.server;
1810
- const events = serverInstance.events;
1811
- if (isShuttingDown) {
1812
- console.log("\u26A0\uFE0F Shutdown already in progress, ignoring duplicate shutdown request");
1813
- return;
1814
- }
1815
- if (!server) {
1816
- return;
1817
- }
1818
- isShuttingDown = true;
1819
- const timeout = options.timeout || 5e3;
1820
- try {
1821
- if (options.onStopping) {
1822
- await options.onStopping();
1823
- }
1824
- events.emit("stopping");
1825
- if (serverInstance.router && typeof serverInstance.router.close === "function") {
1826
- console.log("\u{1F50C} Closing router watchers...");
1827
- try {
1828
- await Promise.race([
1829
- serverInstance.router.close(),
1830
- new Promise(
1831
- (_, reject) => setTimeout(() => reject(new Error("Router close timeout")), 2e3)
1832
- )
1833
- ]);
1834
- console.log("\u2705 Router watchers closed");
1835
- } catch (error) {
1836
- console.error("\u274C Error closing router watchers:", error);
1837
- }
1838
- }
1839
- try {
1840
- await Promise.race([
1841
- serverInstance.pluginManager.onServerStop(serverInstance, server),
1842
- new Promise(
1843
- (_, reject) => setTimeout(() => reject(new Error("Plugin stop timeout")), 2e3)
1844
- )
1845
- ]);
1846
- } catch (error) {
1847
- console.error("\u274C Plugin stop timeout:", error);
1848
- }
1849
- const closePromise = new Promise((resolve3, reject) => {
1850
- server.close((err) => {
1851
- if (err) return reject(err);
1852
- resolve3();
1853
- });
1854
- });
1855
- const timeoutPromise = new Promise((_, reject) => {
1856
- setTimeout(() => {
1857
- reject(new Error("Server shutdown timeout"));
1858
- }, timeout);
1859
- });
1860
- await Promise.race([closePromise, timeoutPromise]);
1861
- try {
1862
- await Promise.race([
1863
- serverInstance.pluginManager.terminatePlugins(serverInstance),
1864
- new Promise(
1865
- (_, reject) => setTimeout(() => reject(new Error("Plugin terminate timeout")), 1e3)
1866
- )
1867
- ]);
1868
- } catch (error) {
1869
- console.error("\u274C Plugin terminate timeout:", error);
1870
- }
1871
- if (options.onStopped) {
1872
- await options.onStopped();
1873
- }
1874
- events.emit("stopped");
1875
- serverInstance.server = null;
1876
- console.log("\u2705 Graceful shutdown completed");
1877
- isShuttingDown = false;
1878
- } catch (error) {
1879
- isShuttingDown = false;
1880
- console.error("\u26A0\uFE0F Shutdown error (forcing exit):", error);
1881
- if (server && typeof server.close === "function") {
1882
- server.close();
1883
- }
1884
- if (process.env.NODE_ENV === "development") {
1885
- console.log("\u{1F504} Forcing exit for development restart...");
1886
- process.exit(0);
1887
- }
1888
- events.emit("error", error);
1889
- throw error;
1890
- }
1891
- }
1892
- function registerSignalHandlers(stopFn) {
1893
- const isDevelopment = process.env.NODE_ENV === "development";
1894
- if (isDevelopment) {
1895
- const sigintHandler = () => {
1896
- console.log("\u{1F4E4} SIGINT received, forcing exit for development restart...");
1897
- process.exit(0);
1898
- };
1899
- const sigtermHandler = () => {
1900
- console.log("\u{1F4E4} SIGTERM received, forcing exit for development restart...");
1901
- process.exit(0);
1902
- };
1903
- process.on("SIGINT", sigintHandler);
1904
- process.on("SIGTERM", sigtermHandler);
1905
- return {
1906
- unregister: () => {
1907
- process.removeListener("SIGINT", sigintHandler);
1908
- process.removeListener("SIGTERM", sigtermHandler);
1909
- }
1910
- };
1911
- } else {
1912
- const sigintHandler = () => {
1913
- console.log("\u{1F4E4} SIGINT received, starting graceful shutdown...");
1914
- stopFn().catch(console.error);
1915
- };
1916
- const sigtermHandler = () => {
1917
- console.log("\u{1F4E4} SIGTERM received, starting graceful shutdown...");
1918
- stopFn().catch(console.error);
1919
- };
1920
- process.on("SIGINT", sigintHandler);
1921
- process.on("SIGTERM", sigtermHandler);
1922
- return {
1923
- unregister: () => {
1924
- process.removeListener("SIGINT", sigintHandler);
1925
- process.removeListener("SIGTERM", sigtermHandler);
1926
- }
1927
- };
1928
- }
1929
- }
1930
-
1931
- // src/server/validation.ts
1932
- var import_zod = require("zod");
1933
- var middlewareSchema = import_zod.z.custom(
1934
- (data) => data !== null && typeof data === "object" && "execute" in data && typeof data.execute === "function",
1935
- {
1936
- message: "Expected middleware to have an execute function"
1937
- }
1938
- );
1939
- var pluginSchema = import_zod.z.custom(
1940
- (data) => data !== null && typeof data === "object" && "register" in data && typeof data.register === "function",
1941
- {
1942
- message: "Expected a valid plugin object with a register method"
1943
- }
1944
- );
1945
- var http2Schema = import_zod.z.object({
1946
- enabled: import_zod.z.boolean().optional().default(true),
1947
- keyFile: import_zod.z.string().optional(),
1948
- certFile: import_zod.z.string().optional()
1949
- }).refine(
1950
- (data) => {
1951
- if (data.enabled && process.env.NODE_ENV === "production") {
1952
- return data.keyFile && data.certFile;
1953
- }
1954
- return true;
1955
- },
1956
- {
1957
- message: "When HTTP/2 is enabled (outside of development mode), both keyFile and certFile must be provided"
1958
- }
1959
- );
1960
- var serverOptionsSchema = import_zod.z.object({
1961
- port: import_zod.z.number().int().positive().optional().default(3e3),
1962
- host: import_zod.z.string().optional().default("localhost"),
1963
- routesDir: import_zod.z.string().optional().default("./routes"),
1964
- http2: http2Schema.optional().default({
1965
- enabled: true
1966
- }),
1967
- middleware: import_zod.z.array(middlewareSchema).optional().default([]),
1968
- plugins: import_zod.z.array(pluginSchema).optional().default([])
1969
- });
1970
- function validateServerOptions(options) {
1971
- try {
1972
- return serverOptionsSchema.parse(options);
1973
- } catch (error) {
1974
- if (error instanceof import_zod.z.ZodError) {
1975
- const formattedError = error.format();
1976
- throw new Error(`Invalid server options: ${JSON.stringify(formattedError, null, 2)}`);
1977
- }
1978
- throw new Error(`Invalid server options: ${String(error)}`);
1979
- }
1980
- }
1981
-
1982
- // src/plugins/lifecycle.ts
1983
- function createPluginLifecycleManager(options = {}) {
1984
- const { continueOnError = true, debug = false, onError } = options;
1985
- function log(message, ...args) {
1986
- if (debug) {
1987
- console.log(`[PluginLifecycle] ${message}`, ...args);
1988
- }
1989
- }
1990
- function handleError(plugin, phase, error) {
1991
- const errorMessage = `Plugin ${plugin.name} failed during ${phase}: ${error.message}`;
1992
- if (onError) {
1993
- onError(plugin, phase, error);
1994
- } else {
1995
- console.error(errorMessage, error);
1996
- }
1997
- if (!continueOnError) {
1998
- throw new Error(errorMessage);
1999
- }
2000
- }
2001
- return {
2002
- /**
2003
- * Initialize all plugins
2004
- */
2005
- async initializePlugins(server) {
2006
- log("Initializing plugins...");
2007
- for (const plugin of server.plugins) {
2008
- if (plugin.initialize) {
2009
- try {
2010
- log(`Initializing plugin: ${plugin.name}`);
2011
- await plugin.initialize(server);
2012
- } catch (error) {
2013
- handleError(plugin, "initialize", error);
2014
- }
2015
- }
2016
- }
2017
- log(`Initialized ${server.plugins.length} plugins`);
2018
- },
2019
- /**
2020
- * Terminate all plugins in reverse order
2021
- */
2022
- async terminatePlugins(server) {
2023
- log("Terminating plugins...");
2024
- const pluginsToTerminate = [...server.plugins].reverse();
2025
- for (const plugin of pluginsToTerminate) {
2026
- if (plugin.terminate) {
2027
- try {
2028
- log(`Terminating plugin: ${plugin.name}`);
2029
- await plugin.terminate(server);
2030
- } catch (error) {
2031
- handleError(plugin, "terminate", error);
2032
- }
2033
- }
2034
- }
2035
- log(`Terminated ${pluginsToTerminate.length} plugins`);
2036
- },
2037
- /**
2038
- * Notify plugins that the server has started
2039
- */
2040
- async onServerStart(server, httpServer) {
2041
- log("Notifying plugins of server start...");
2042
- for (const plugin of server.plugins) {
2043
- if (plugin.onServerStart) {
2044
- try {
2045
- log(`Notifying plugin of server start: ${plugin.name}`);
2046
- await plugin.onServerStart(httpServer);
2047
- } catch (error) {
2048
- handleError(plugin, "onServerStart", error);
2049
- }
2050
- }
2051
- }
2052
- },
2053
- /**
2054
- * Notify plugins that the server is stopping
2055
- */
2056
- async onServerStop(server, httpServer) {
2057
- log("Notifying plugins of server stop...");
2058
- const pluginsToNotify = [...server.plugins].reverse();
2059
- for (const plugin of pluginsToNotify) {
2060
- if (plugin.onServerStop) {
2061
- try {
2062
- log(`Notifying plugin of server stop: ${plugin.name}`);
2063
- await plugin.onServerStop(httpServer);
2064
- } catch (error) {
2065
- handleError(plugin, "onServerStop", error);
2066
- }
2067
- }
2068
- }
2069
- }
2070
- };
2071
- }
2072
-
2073
- // src/plugins/errors.ts
2074
- var PluginValidationError = class extends Error {
2075
- constructor(pluginName, message) {
2076
- super(`Plugin validation error${pluginName ? ` for "${pluginName}"` : ""}: ${message}`);
2077
- this.pluginName = pluginName;
2078
- this.name = "PluginValidationError";
2079
- }
2080
- };
2081
-
2082
- // src/plugins/validation.ts
2083
- var RESERVED_NAMES = /* @__PURE__ */ new Set([
2084
- "core",
2085
- "server",
2086
- "router",
2087
- "middleware",
2088
- "context",
2089
- "blaize",
2090
- "blaizejs"
2091
- ]);
2092
- var VALID_NAME_PATTERN = /^[a-z]([a-z0-9-]*[a-z0-9])?$/;
2093
- var VALID_VERSION_PATTERN = /^\d+\.\d+\.\d+(?:-[a-zA-Z0-9-.]+)?(?:\+[a-zA-Z0-9-.]+)?$/;
2094
- function validatePlugin(plugin, options = {}) {
2095
- const { requireVersion = true, validateNameFormat = true, checkReservedNames = true } = options;
2096
- if (!plugin || typeof plugin !== "object") {
2097
- throw new PluginValidationError("", "Plugin must be an object");
2098
- }
2099
- const p = plugin;
2100
- if (!p.name || typeof p.name !== "string") {
2101
- throw new PluginValidationError("", "Plugin must have a name (string)");
2102
- }
2103
- if (validateNameFormat && !VALID_NAME_PATTERN.test(p.name)) {
2104
- throw new PluginValidationError(
2105
- p.name,
2106
- "Plugin name must be lowercase letters, numbers, and hyphens only"
2107
- );
2108
- }
2109
- if (checkReservedNames && RESERVED_NAMES.has(p.name.toLowerCase())) {
2110
- throw new PluginValidationError(p.name, `Plugin name "${p.name}" is reserved`);
2111
- }
2112
- if (requireVersion) {
2113
- if (!p.version || typeof p.version !== "string") {
2114
- throw new PluginValidationError(p.name, "Plugin must have a version (string)");
2115
- }
2116
- if (!VALID_VERSION_PATTERN.test(p.version)) {
2117
- throw new PluginValidationError(
2118
- p.name,
2119
- 'Plugin version must follow semantic versioning (e.g., "1.0.0")'
2120
- );
2121
- }
2122
- }
2123
- if (!p.register || typeof p.register !== "function") {
2124
- throw new PluginValidationError(p.name, "Plugin must have a register method (function)");
2125
- }
2126
- const lifecycleMethods = ["initialize", "terminate", "onServerStart", "onServerStop"];
2127
- for (const method of lifecycleMethods) {
2128
- if (p[method] && typeof p[method] !== "function") {
2129
- throw new PluginValidationError(p.name, `Plugin ${method} must be a function if provided`);
2130
- }
2131
- }
2132
- }
2133
-
2134
- // src/router/discovery/cache.ts
2135
- var crypto = __toESM(require("crypto"), 1);
2136
- var fs3 = __toESM(require("fs/promises"), 1);
2137
- var import_node_module = require("module");
2138
- var path3 = __toESM(require("path"), 1);
2139
-
2140
- // src/router/discovery/loader.ts
2141
- async function dynamicImport(filePath) {
2142
- const cacheBuster = `?t=${Date.now()}`;
2143
- const importPath = filePath + cacheBuster;
2144
- try {
2145
- const module2 = await import(importPath);
2146
- console.log(`\u2705 Successfully imported module`);
2147
- return module2;
2148
- } catch (error) {
2149
- const errorMessage = error instanceof Error ? error.message : String(error);
2150
- console.log(`\u26A0\uFE0F Error importing with cache buster, trying original path:`, errorMessage);
2151
- return import(filePath);
2152
- }
2153
- }
2154
- async function loadRouteModule(filePath, basePath) {
2155
- try {
2156
- const parsedRoute = parseRoutePath(filePath, basePath);
2157
- const module2 = await dynamicImport(filePath);
2158
- console.log("\u{1F4E6} Module exports:", Object.keys(module2));
2159
- const routes = [];
2160
- if (module2.default && typeof module2.default === "object") {
2161
- const route = {
2162
- ...module2.default,
2163
- path: parsedRoute.routePath
2164
- };
2165
- routes.push(route);
2166
- }
2167
- Object.entries(module2).forEach(([exportName, exportValue]) => {
2168
- if (exportName === "default" || !exportValue || typeof exportValue !== "object") {
2169
- return;
2170
- }
2171
- const potentialRoute = exportValue;
2172
- if (isValidRoute(potentialRoute)) {
2173
- const route = {
2174
- ...potentialRoute,
2175
- // Use the route's own path if it has one, otherwise derive from file
2176
- path: parsedRoute.routePath
2177
- };
2178
- routes.push(route);
2179
- }
2180
- });
2181
- if (routes.length === 0) {
2182
- console.warn(`Route file ${filePath} does not export any valid route definitions`);
2183
- return [];
2184
- }
2185
- console.log(`\u2705 Successfully Loaded ${routes.length} route(s)`);
2186
- return routes;
2187
- } catch (error) {
2188
- console.error(`Failed to load route module ${filePath}:`, error);
2189
- return [];
2190
- }
2191
- }
2192
- function isValidRoute(obj) {
2193
- if (!obj || typeof obj !== "object") {
2194
- return false;
2195
- }
2196
- const httpMethods = ["GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS"];
2197
- const hasHttpMethod = httpMethods.some(
2198
- (method) => obj[method] && typeof obj[method] === "object" && obj[method].handler
2199
- );
2200
- return hasHttpMethod;
2201
- }
2202
-
2203
- // src/router/discovery/cache.ts
2204
- var import_meta = {};
2205
- var fileRouteCache = /* @__PURE__ */ new Map();
2206
- async function processChangedFile(filePath, routesDir, updateCache = true) {
2207
- const stat3 = await fs3.stat(filePath);
2208
- const lastModified = stat3.mtime.getTime();
2209
- const cachedEntry = fileRouteCache.get(filePath);
2210
- if (updateCache && cachedEntry && cachedEntry.timestamp === lastModified) {
2211
- return cachedEntry.routes;
2212
- }
2213
- invalidateModuleCache(filePath);
2214
- const routes = await loadRouteModule(filePath, routesDir);
2215
- if (updateCache) {
2216
- const hash = hashRoutes(routes);
2217
- fileRouteCache.set(filePath, {
2218
- routes,
2219
- timestamp: lastModified,
2220
- hash
2221
- });
2222
- }
2223
- return routes;
2224
- }
2225
- function hasRouteContentChanged(filePath, newRoutes) {
2226
- const cachedEntry = fileRouteCache.get(filePath);
2227
- if (!cachedEntry) {
2228
- return true;
2229
- }
2230
- const newHash = hashRoutes(newRoutes);
2231
- return cachedEntry.hash !== newHash;
2232
- }
2233
- function clearFileCache(filePath) {
2234
- if (filePath) {
2235
- fileRouteCache.delete(filePath);
2236
- } else {
2237
- fileRouteCache.clear();
2238
- }
2239
- }
2240
- function hashRoutes(routes) {
2241
- const routeData = routes.map((route) => ({
2242
- path: route.path,
2243
- methods: Object.keys(route).filter((key) => key !== "path").sort().map((method) => {
2244
- const methodDef = route[method];
2245
- const handlerString = methodDef?.handler ? methodDef.handler.toString() : null;
2246
- return {
2247
- method,
2248
- // Include handler function string for change detection
2249
- handler: handlerString,
2250
- // Include middleware if present
2251
- middleware: methodDef?.middleware ? methodDef.middleware.length : 0,
2252
- // Include schema structure (but not full serialization which can be unstable)
2253
- hasSchema: !!methodDef?.schema,
2254
- schemaKeys: methodDef?.schema ? Object.keys(methodDef.schema).sort() : []
2255
- };
2256
- })
2257
- }));
2258
- const dataString = JSON.stringify(routeData);
2259
- const hash = crypto.createHash("md5").update(dataString).digest("hex");
2260
- return hash;
2261
- }
2262
- function invalidateModuleCache(filePath) {
2263
- try {
2264
- const absolutePath = path3.resolve(filePath);
2265
- if (typeof require !== "undefined") {
2266
- delete require.cache[absolutePath];
2267
- try {
2268
- const resolvedPath = require.resolve(absolutePath);
2269
- delete require.cache[resolvedPath];
2270
- } catch (resolveError) {
2271
- const errorMessage = resolveError instanceof Error ? resolveError.message : String(resolveError);
2272
- console.log(`\u26A0\uFE0F Could not resolve path: ${errorMessage}`);
2273
- }
2274
- } else {
2275
- try {
2276
- const require2 = (0, import_node_module.createRequire)(import_meta.url);
2277
- delete require2.cache[absolutePath];
2278
- try {
2279
- const resolvedPath = require2.resolve(absolutePath);
2280
- delete require2.cache[resolvedPath];
2281
- } catch {
2282
- console.log(`\u26A0\uFE0F Could not resolve ESM path`);
2283
- }
2284
- } catch {
2285
- console.log(`\u26A0\uFE0F createRequire not available in pure ESM`);
2286
- }
2287
- }
2288
- } catch (error) {
2289
- console.log(`\u26A0\uFE0F Error during module cache invalidation for ${filePath}:`, error);
2290
- }
2291
- }
2292
-
2293
- // src/router/discovery/parallel.ts
2294
- var os = __toESM(require("os"), 1);
2295
-
2296
- // src/router/discovery/finder.ts
2297
- var fs4 = __toESM(require("fs/promises"), 1);
2298
- var path4 = __toESM(require("path"), 1);
2299
- async function findRouteFiles(routesDir, options = {}) {
2300
- const absoluteDir = path4.isAbsolute(routesDir) ? routesDir : path4.resolve(process.cwd(), routesDir);
2301
- console.log("Creating router with routes directory:", absoluteDir);
2302
- try {
2303
- const stats = await fs4.stat(absoluteDir);
2304
- if (!stats.isDirectory()) {
2305
- throw new Error(`Route directory is not a directory: ${absoluteDir}`);
2306
- }
2307
- } catch (error) {
2308
- if (error.code === "ENOENT") {
2309
- throw new Error(`Route directory not found: ${absoluteDir}`);
2310
- }
2311
- throw error;
2312
- }
2313
- const routeFiles = [];
2314
- const ignore = options.ignore || ["node_modules", ".git"];
2315
- async function scanDirectory(dir) {
2316
- const entries = await fs4.readdir(dir, { withFileTypes: true });
2317
- for (const entry of entries) {
2318
- const fullPath = path4.join(dir, entry.name);
2319
- if (entry.isDirectory() && ignore.includes(entry.name)) {
2320
- continue;
2321
- }
2322
- if (entry.isDirectory()) {
2323
- await scanDirectory(fullPath);
2324
- } else if (isRouteFile(entry.name)) {
2325
- routeFiles.push(fullPath);
2326
- }
2327
- }
2328
- }
2329
- await scanDirectory(absoluteDir);
2330
- return routeFiles;
2331
- }
2332
- function isRouteFile(filename) {
2333
- return !filename.startsWith("_") && (filename.endsWith(".ts") || filename.endsWith(".js"));
2334
- }
2335
-
2336
- // src/router/discovery/parallel.ts
2337
- async function processFilesInParallel(filePaths, processor, concurrency = Math.max(1, Math.floor(os.cpus().length / 2))) {
2338
- const chunks = chunkArray(filePaths, concurrency);
2339
- const results = [];
2340
- for (const chunk of chunks) {
2341
- const chunkResults = await Promise.allSettled(chunk.map((filePath) => processor(filePath)));
2342
- const successfulResults = chunkResults.filter((result) => result.status === "fulfilled").map((result) => result.value);
2343
- results.push(...successfulResults);
2344
- }
2345
- return results;
2346
- }
2347
- async function loadInitialRoutesParallel(routesDir) {
2348
- const files = await findRouteFiles(routesDir);
2349
- const routeArrays = await processFilesInParallel(
2350
- files,
2351
- (filePath) => processChangedFile(filePath, routesDir)
2352
- );
2353
- return routeArrays.flat();
2354
- }
2355
- function chunkArray(array, chunkSize) {
2356
- const chunks = [];
2357
- for (let i = 0; i < array.length; i += chunkSize) {
2358
- chunks.push(array.slice(i, i + chunkSize));
2359
- }
2360
- return chunks;
2361
- }
2362
-
2363
- // src/router/discovery/profiler.ts
2364
- var profilerState = {
2365
- fileChanges: 0,
2366
- totalReloadTime: 0,
2367
- averageReloadTime: 0,
2368
- slowReloads: []
2369
- };
2370
- function trackReloadPerformance(filePath, startTime) {
2371
- const duration = Date.now() - startTime;
2372
- profilerState.fileChanges++;
2373
- profilerState.totalReloadTime += duration;
2374
- profilerState.averageReloadTime = profilerState.totalReloadTime / profilerState.fileChanges;
2375
- if (duration > 100) {
2376
- profilerState.slowReloads.push({ file: filePath, time: duration });
2377
- if (profilerState.slowReloads.length > 10) {
2378
- profilerState.slowReloads.shift();
2379
- }
2380
- }
2381
- if (process.env.NODE_ENV === "development") {
2382
- const emoji = duration < 50 ? "\u26A1" : duration < 100 ? "\u{1F504}" : "\u{1F40C}";
2383
- console.log(`${emoji} Route reload: ${filePath} (${duration}ms)`);
2384
- }
2385
- }
2386
- function withPerformanceTracking(fn, filePath) {
2387
- console.log(`Tracking performance for: ${filePath}`);
2388
- return async (...args) => {
2389
- const startTime = Date.now();
2390
- try {
2391
- const result = await fn(...args);
2392
- trackReloadPerformance(filePath, startTime);
2393
- return result;
2394
- } catch (error) {
2395
- trackReloadPerformance(filePath, startTime);
2396
- throw error;
2397
- }
2398
- };
2399
- }
2400
-
2401
- // src/router/discovery/watchers.ts
2402
- var path5 = __toESM(require("path"), 1);
2403
- var import_chokidar = require("chokidar");
2404
- function watchRoutes(routesDir, options = {}) {
2405
- const debounceMs = options.debounceMs || 16;
2406
- const debouncedCallbacks = /* @__PURE__ */ new Map();
2407
- function createDebouncedCallback(fn, filePath) {
2408
- return (...args) => {
2409
- const existingTimeout = debouncedCallbacks.get(filePath);
2410
- if (existingTimeout) {
2411
- clearTimeout(existingTimeout);
2412
- }
2413
- const timeoutId = setTimeout(() => {
2414
- fn(...args);
2415
- debouncedCallbacks.delete(filePath);
2416
- }, debounceMs);
2417
- debouncedCallbacks.set(filePath, timeoutId);
2418
- };
2419
- }
2420
- const routesByPath = /* @__PURE__ */ new Map();
2421
- async function loadInitialRoutes() {
2422
- try {
2423
- const files = await findRouteFiles(routesDir, {
2424
- ignore: options.ignore
2425
- });
2426
- for (const filePath of files) {
2427
- await loadAndNotify(filePath);
2428
- }
2429
- } catch (error) {
2430
- handleError(error);
2431
- }
2432
- }
2433
- async function loadAndNotify(filePath) {
2434
- try {
2435
- const existingRoutes = routesByPath.get(filePath);
2436
- const newRoutes = await processChangedFile(filePath, routesDir, false);
2437
- if (!newRoutes || newRoutes.length === 0) {
2438
- return;
2439
- }
2440
- if (existingRoutes && !hasRouteContentChanged(filePath, newRoutes)) {
2441
- return;
2442
- }
2443
- await processChangedFile(filePath, routesDir, true);
2444
- const normalizedPath = path5.normalize(filePath);
2445
- if (existingRoutes) {
2446
- routesByPath.set(filePath, newRoutes);
2447
- if (options.onRouteChanged) {
2448
- options.onRouteChanged(normalizedPath, newRoutes);
2449
- }
2450
- } else {
2451
- routesByPath.set(filePath, newRoutes);
2452
- if (options.onRouteAdded) {
2453
- options.onRouteAdded(normalizedPath, newRoutes);
2454
- }
2455
- }
2456
- } catch (error) {
2457
- console.log(`\u26A0\uFE0F Error processing file ${filePath}:`, error);
2458
- handleError(error);
2459
- }
2460
- }
2461
- function handleRemoved(filePath) {
2462
- const normalizedPath = path5.normalize(filePath);
2463
- const routes = routesByPath.get(normalizedPath);
2464
- if (routes && routes.length > 0 && options.onRouteRemoved) {
2465
- options.onRouteRemoved(normalizedPath, routes);
2466
- }
2467
- routesByPath.delete(normalizedPath);
2468
- }
2469
- function handleError(error) {
2470
- if (options.onError && error instanceof Error) {
2471
- options.onError(error);
2472
- } else {
2473
- console.error("\u26A0\uFE0F Route watcher error:", error);
2474
- }
2475
- }
2476
- const watcher = (0, import_chokidar.watch)(routesDir, {
2477
- // Much faster response times
2478
- awaitWriteFinish: {
2479
- stabilityThreshold: 50,
2480
- // Reduced from 300ms
2481
- pollInterval: 10
2482
- // Reduced from 100ms
2483
- },
2484
- // Performance optimizations
2485
- usePolling: false,
2486
- atomic: true,
2487
- followSymlinks: false,
2488
- depth: 10,
2489
- // More aggressive ignoring
2490
- ignored: [
2491
- /(^|[/\\])\../,
2492
- /node_modules/,
2493
- /\.git/,
2494
- /\.DS_Store/,
2495
- /Thumbs\.db/,
2496
- /\.(test|spec)\.(ts|js)$/,
2497
- /\.d\.ts$/,
2498
- /\.map$/,
2499
- /~$/,
2500
- ...options.ignore || []
2501
- ]
2502
- });
2503
- watcher.on("add", (filePath) => {
2504
- const debouncedLoad = createDebouncedCallback(loadAndNotify, filePath);
2505
- debouncedLoad(filePath);
2506
- }).on("change", (filePath) => {
2507
- const debouncedLoad = createDebouncedCallback(loadAndNotify, filePath);
2508
- debouncedLoad(filePath);
2509
- }).on("unlink", (filePath) => {
2510
- const debouncedRemove = createDebouncedCallback(handleRemoved, filePath);
2511
- debouncedRemove(filePath);
2512
- }).on("error", handleError);
2513
- loadInitialRoutes().catch(handleError);
2514
- return {
2515
- close: () => {
2516
- debouncedCallbacks.forEach((timeout) => clearTimeout(timeout));
2517
- debouncedCallbacks.clear();
2518
- return watcher.close();
2519
- },
2520
- getRoutes: () => {
2521
- const allRoutes = [];
2522
- for (const routes of routesByPath.values()) {
2523
- allRoutes.push(...routes);
2524
- }
2525
- return allRoutes;
2526
- },
2527
- getRoutesByFile: () => new Map(routesByPath)
2528
- };
2529
- }
2530
-
2531
- // src/router/validation/schema.ts
2532
- var import_zod6 = require("zod");
2533
-
2534
- // src/router/validation/body.ts
2535
- var import_zod2 = require("zod");
2536
- function validateBody(body, schema) {
2537
- if (schema instanceof import_zod2.z.ZodObject) {
2538
- return schema.strict().parse(body);
2539
- }
2540
- return schema.parse(body);
2541
- }
2542
-
2543
- // src/router/validation/params.ts
2544
- var import_zod3 = require("zod");
2545
- function validateParams(params, schema) {
2546
- if (schema instanceof import_zod3.z.ZodObject) {
2547
- return schema.strict().parse(params);
2548
- }
2549
- return schema.parse(params);
2550
- }
2551
-
2552
- // src/router/validation/query.ts
2553
- var import_zod4 = require("zod");
2554
- function validateQuery(query, schema) {
2555
- if (schema instanceof import_zod4.z.ZodObject) {
2556
- return schema.strict().parse(query);
2557
- }
2558
- return schema.parse(query);
2559
- }
2560
-
2561
- // src/router/validation/response.ts
2562
- var import_zod5 = require("zod");
2563
- function validateResponse(response, schema) {
2564
- if (schema instanceof import_zod5.z.ZodObject) {
2565
- return schema.strict().parse(response);
2566
- }
2567
- return schema.parse(response);
2568
- }
2569
-
2570
- // src/router/validation/schema.ts
2571
- init_internal_server_error();
2572
- init_validation_error();
2573
- function createRequestValidator(schema, debug = false) {
2574
- const middlewareFn = async (ctx, next) => {
2575
- if (schema.params && ctx.request.params) {
2576
- try {
2577
- ctx.request.params = validateParams(ctx.request.params, schema.params);
2578
- } catch (error) {
2579
- const fieldErrors = extractZodFieldErrors(error);
2580
- const errorCount = fieldErrors.reduce((sum, fe) => sum + fe.messages.length, 0);
2581
- throw new ValidationError("Request validation failed", {
2582
- fields: fieldErrors,
2583
- errorCount,
2584
- section: "params"
2585
- });
2586
- }
2587
- }
2588
- if (schema.query && ctx.request.query) {
2589
- try {
2590
- ctx.request.query = validateQuery(ctx.request.query, schema.query);
2591
- } catch (error) {
2592
- const fieldErrors = extractZodFieldErrors(error);
2593
- const errorCount = fieldErrors.reduce((sum, fe) => sum + fe.messages.length, 0);
2594
- throw new ValidationError("Request validation failed", {
2595
- fields: fieldErrors,
2596
- errorCount,
2597
- section: "query"
2598
- });
2599
- }
2600
- }
2601
- if (schema.body) {
2602
- try {
2603
- ctx.request.body = validateBody(ctx.request.body, schema.body);
2604
- } catch (error) {
2605
- const fieldErrors = extractZodFieldErrors(error);
2606
- const errorCount = fieldErrors.reduce((sum, fe) => sum + fe.messages.length, 0);
2607
- throw new ValidationError("Request validation failed", {
2608
- fields: fieldErrors,
2609
- errorCount,
2610
- section: "body"
2611
- });
2612
- }
2613
- }
2614
- await next();
2615
- };
2616
- return {
2617
- name: "RequestValidator",
2618
- execute: middlewareFn,
2619
- debug
2620
- };
2621
- }
2622
- function createResponseValidator(responseSchema, debug = false) {
2623
- const middlewareFn = async (ctx, next) => {
2624
- const originalJson = ctx.response.json;
2625
- ctx.response.json = (body, status) => {
2626
- try {
2627
- const validatedBody = validateResponse(body, responseSchema);
2628
- ctx.response.json = originalJson;
2629
- return originalJson.call(ctx.response, validatedBody, status);
2630
- } catch (error) {
2631
- ctx.response.json = originalJson;
2632
- throw new InternalServerError("Response validation failed", {
2633
- responseSchema: responseSchema.description || "Unknown schema",
2634
- validationError: extractZodFieldErrors(error),
2635
- originalResponse: body
2636
- });
2637
- }
2638
- };
2639
- await next();
2640
- };
2641
- return {
2642
- name: "ResponseValidator",
2643
- execute: middlewareFn,
2644
- debug
2645
- };
2646
- }
2647
- function extractZodFieldErrors(error) {
2648
- if (error instanceof import_zod6.z.ZodError) {
2649
- const fieldErrorMap = /* @__PURE__ */ new Map();
2650
- for (const issue of error.issues) {
2651
- const fieldPath = issue.path.length > 0 ? issue.path.join(".") : "root";
2652
- if (!fieldErrorMap.has(fieldPath)) {
2653
- fieldErrorMap.set(fieldPath, []);
2654
- }
2655
- fieldErrorMap.get(fieldPath).push(issue.message);
2656
- }
2657
- return Array.from(fieldErrorMap.entries()).map(([field, messages]) => ({
2658
- field,
2659
- messages
2660
- }));
2661
- }
2662
- if (error instanceof Error) {
2663
- return [{ field: "unknown", messages: [error.message] }];
2664
- }
2665
- return [{ field: "unknown", messages: [String(error)] }];
2666
- }
2667
-
2668
- // src/router/handlers/executor.ts
2669
- async function executeHandler(ctx, routeOptions, params) {
2670
- const middleware = [...routeOptions.middleware || []];
2671
- if (routeOptions.schema) {
2672
- if (routeOptions.schema.params || routeOptions.schema.query || routeOptions.schema.body) {
2673
- middleware.unshift(createRequestValidator(routeOptions.schema));
2674
- }
2675
- if (routeOptions.schema.response) {
2676
- middleware.push(createResponseValidator(routeOptions.schema.response));
2677
- }
2678
- }
2679
- const handler = compose([...middleware]);
2680
- await handler(ctx, async () => {
2681
- const result = await routeOptions.handler(ctx, params);
2682
- if (!ctx.response.sent && result !== void 0) {
2683
- ctx.response.json(result);
2684
- }
2685
- });
2686
- }
2687
-
2688
- // src/router/matching/params.ts
2689
- function extractParams(path6, pattern, paramNames) {
2690
- const match = pattern.exec(path6);
2691
- if (!match) {
2692
- return {};
2693
- }
2694
- const params = {};
2695
- for (let i = 0; i < paramNames.length; i++) {
2696
- params[paramNames[i]] = match[i + 1] || "";
2697
- }
2698
- return params;
2699
- }
2700
- function compilePathPattern(path6) {
2701
- const paramNames = [];
2702
- if (path6 === "/") {
2703
- return {
2704
- pattern: /^\/$/,
2705
- paramNames: []
2706
- };
2707
- }
2708
- let patternString = path6.replace(/([.+*?^$(){}|\\])/g, "\\$1");
2709
- patternString = patternString.replace(/\/:([^/]+)/g, (_, paramName) => {
2710
- paramNames.push(paramName);
2711
- return "/([^/]+)";
2712
- }).replace(/\/\[([^\]]+)\]/g, (_, paramName) => {
2713
- paramNames.push(paramName);
2714
- return "/([^/]+)";
2715
- });
2716
- patternString = `${patternString}(?:/)?`;
2717
- const pattern = new RegExp(`^${patternString}$`);
2718
- return {
2719
- pattern,
2720
- paramNames
2721
- };
2722
- }
2723
-
2724
- // src/router/matching/matcher.ts
2725
- function createMatcher() {
2726
- const routes = [];
2727
- return {
2728
- /**
2729
- * Add a route to the matcher
2730
- */
2731
- add(path6, method, routeOptions) {
2732
- const { pattern, paramNames } = compilePathPattern(path6);
2733
- const newRoute = {
2734
- path: path6,
2735
- method,
2736
- pattern,
2737
- paramNames,
2738
- routeOptions
2739
- };
2740
- const insertIndex = routes.findIndex((route) => paramNames.length < route.paramNames.length);
2741
- if (insertIndex === -1) {
2742
- routes.push(newRoute);
2743
- } else {
2744
- routes.splice(insertIndex, 0, newRoute);
2745
- }
2746
- },
2747
- /**
2748
- * Remove a route from the matcher by path
2749
- */
2750
- remove(path6) {
2751
- for (let i = routes.length - 1; i >= 0; i--) {
2752
- if (routes[i].path === path6) {
2753
- routes.splice(i, 1);
2754
- }
2755
- }
2756
- },
2757
- /**
2758
- * Clear all routes from the matcher
2759
- */
2760
- clear() {
2761
- routes.length = 0;
2762
- },
2763
- /**
2764
- * Match a URL path to a route
2765
- */
2766
- match(path6, method) {
2767
- const pathname = path6.split("?")[0];
2768
- if (!pathname) return null;
2769
- for (const route of routes) {
2770
- if (route.method !== method) continue;
2771
- const match = route.pattern.exec(pathname);
2772
- if (match) {
2773
- const params = extractParams(path6, route.pattern, route.paramNames);
2774
- return {
2775
- route: route.routeOptions,
2776
- params
2777
- };
2778
- }
2779
- }
2780
- const matchingPath = routes.find(
2781
- (route) => route.method !== method && route.pattern.test(path6)
2782
- );
2783
- if (matchingPath) {
2784
- return {
2785
- route: null,
2786
- params: {},
2787
- methodNotAllowed: true,
2788
- allowedMethods: routes.filter((route) => route.pattern.test(path6)).map((route) => route.method)
2789
- };
2790
- }
2791
- return null;
2792
- },
2793
- /**
2794
- * Get all registered routes
2795
- */
2796
- getRoutes() {
2797
- return routes.map((route) => ({
2798
- path: route.path,
2799
- method: route.method
2800
- }));
2801
- },
2802
- /**
2803
- * Find routes matching a specific path
2804
- */
2805
- findRoutes(path6) {
2806
- return routes.filter((route) => route.pattern.test(path6)).map((route) => ({
2807
- path: route.path,
2808
- method: route.method,
2809
- params: extractParams(path6, route.pattern, route.paramNames)
2810
- }));
2811
- }
2812
- };
2813
- }
2814
-
2815
- // src/router/registry/fast-registry.ts
2816
- function createRouteRegistry() {
2817
- return {
2818
- routesByPath: /* @__PURE__ */ new Map(),
2819
- routesByFile: /* @__PURE__ */ new Map(),
2820
- pathToFile: /* @__PURE__ */ new Map()
2821
- };
2822
- }
2823
- function updateRoutesFromFile(registry, filePath, newRoutes) {
2824
- console.log(`Updating routes from file: ${filePath}`);
2825
- const oldPaths = registry.routesByFile.get(filePath) || /* @__PURE__ */ new Set();
2826
- const newPaths = new Set(newRoutes.map((r) => r.path));
2827
- const added = newRoutes.filter((r) => !oldPaths.has(r.path));
2828
- const removed = Array.from(oldPaths).filter((p) => !newPaths.has(p));
2829
- const potentiallyChanged = newRoutes.filter((r) => oldPaths.has(r.path));
2830
- const changed = potentiallyChanged.filter((route) => {
2831
- const existingRoute = registry.routesByPath.get(route.path);
2832
- return !existingRoute || !routesEqual(existingRoute, route);
2833
- });
2834
- applyRouteUpdates(registry, filePath, { added, removed, changed });
2835
- return { added, removed, changed };
2836
- }
2837
- function getAllRoutesFromRegistry(registry) {
2838
- return Array.from(registry.routesByPath.values());
2839
- }
2840
- function applyRouteUpdates(registry, filePath, updates) {
2841
- const { added, removed, changed } = updates;
2842
- removed.forEach((path6) => {
2843
- registry.routesByPath.delete(path6);
2844
- registry.pathToFile.delete(path6);
2845
- });
2846
- [...added, ...changed].forEach((route) => {
2847
- registry.routesByPath.set(route.path, route);
2848
- registry.pathToFile.set(route.path, filePath);
2849
- });
2850
- const allPathsForFile = /* @__PURE__ */ new Set([
2851
- ...added.map((r) => r.path),
2852
- ...changed.map((r) => r.path),
2853
- ...Array.from(registry.routesByFile.get(filePath) || []).filter((p) => !removed.includes(p))
2854
- ]);
2855
- if (allPathsForFile.size > 0) {
2856
- registry.routesByFile.set(filePath, allPathsForFile);
2857
- } else {
2858
- registry.routesByFile.delete(filePath);
2859
- }
2860
- }
2861
- function routesEqual(route1, route2) {
2862
- if (route1.path !== route2.path) return false;
2863
- const methods1 = Object.keys(route1).filter((k) => k !== "path").sort();
2864
- const methods2 = Object.keys(route2).filter((k) => k !== "path").sort();
2865
- if (methods1.length !== methods2.length) return false;
2866
- return methods1.every((method) => {
2867
- const handler1 = route1[method];
2868
- const handler2 = route2[method];
2869
- return typeof handler1 === typeof handler2;
2870
- });
2871
- }
2872
-
2873
- // src/router/utils/matching-helpers.ts
2874
- function addRouteToMatcher(route, matcher) {
2875
- Object.entries(route).forEach(([method, methodOptions]) => {
2876
- if (method === "path" || !methodOptions) return;
2877
- matcher.add(route.path, method, methodOptions);
2878
- });
2879
- }
2880
- function removeRouteFromMatcher(path6, matcher) {
2881
- if ("remove" in matcher && typeof matcher.remove === "function") {
2882
- matcher.remove(path6);
2883
- } else {
2884
- console.warn("Matcher does not support selective removal, consider adding remove() method");
2885
- }
2886
- }
2887
- function updateRouteInMatcher(route, matcher) {
2888
- removeRouteFromMatcher(route.path, matcher);
2889
- addRouteToMatcher(route, matcher);
2890
- }
2891
-
2892
- // src/router/router.ts
2893
- var DEFAULT_ROUTER_OPTIONS = {
2894
- routesDir: "./routes",
2895
- basePath: "/",
2896
- watchMode: process.env.NODE_ENV === "development"
2897
- };
2898
- function createRouter(options) {
2899
- const routerOptions = {
2900
- ...DEFAULT_ROUTER_OPTIONS,
2901
- ...options
2902
- };
2903
- if (options.basePath && !options.basePath.startsWith("/")) {
2904
- console.warn("Base path does nothing");
2905
- }
2906
- const registry = createRouteRegistry();
2907
- const matcher = createMatcher();
2908
- let initialized = false;
2909
- let initializationPromise = null;
2910
- let _watchers = null;
2911
- const routeDirectories = /* @__PURE__ */ new Set([routerOptions.routesDir]);
2912
- function applyMatcherChanges(changes) {
2913
- console.log("\n\u{1F527} APPLYING MATCHER CHANGES:");
2914
- console.log(` Adding ${changes.added.length} routes`);
2915
- console.log(` Removing ${changes.removed.length} routes`);
2916
- console.log(` Updating ${changes.changed.length} routes`);
2917
- changes.removed.forEach((routePath) => {
2918
- console.log(` \u2796 Removing: ${routePath}`);
2919
- removeRouteFromMatcher(routePath, matcher);
2920
- });
2921
- changes.added.forEach((route) => {
2922
- const methods = Object.keys(route).filter((key) => key !== "path");
2923
- console.log(` \u2795 Adding: ${route.path} [${methods.join(", ")}]`);
2924
- addRouteToMatcher(route, matcher);
2925
- });
2926
- changes.changed.forEach((route) => {
2927
- const methods = Object.keys(route).filter((key) => key !== "path");
2928
- console.log(` \u{1F504} Updating: ${route.path} [${methods.join(", ")}]`);
2929
- updateRouteInMatcher(route, matcher);
2930
- });
2931
- console.log("\u2705 Matcher changes applied\n");
2932
- }
2933
- function addRoutesWithSource(routes, source) {
2934
- try {
2935
- const changes = updateRoutesFromFile(registry, source, routes);
2936
- applyMatcherChanges(changes);
2937
- return changes;
2938
- } catch (error) {
2939
- console.error(`\u26A0\uFE0F Route conflicts from ${source}:`, error);
2940
- throw error;
2941
- }
2942
- }
2943
- async function loadRoutesFromDirectory(directory, source, prefix) {
2944
- try {
2945
- const discoveredRoutes = await loadInitialRoutesParallel(directory);
2946
- const finalRoutes = discoveredRoutes.map(
2947
- (route) => prefix ? { ...route, path: `${prefix}${route.path}` } : route
2948
- );
2949
- const changes = addRoutesWithSource(finalRoutes, source);
2950
- console.log(
2951
- `Loaded ${discoveredRoutes.length} routes from ${source}${prefix ? ` with prefix ${prefix}` : ""} (${changes.added.length} added, ${changes.changed.length} changed, ${changes.removed.length} removed)`
2952
- );
2953
- } catch (error) {
2954
- console.error(`\u26A0\uFE0F Failed to load routes from ${source}:`, error);
2955
- throw error;
2956
- }
2957
- }
2958
- async function initialize() {
2959
- if (initialized || initializationPromise) {
2960
- return initializationPromise;
2961
- }
2962
- initializationPromise = (async () => {
2963
- try {
2964
- await Promise.all(
2965
- Array.from(routeDirectories).map(
2966
- (directory) => loadRoutesFromDirectory(directory, directory)
2967
- )
2968
- );
2969
- if (routerOptions.watchMode) {
2970
- setupOptimizedWatching();
2971
- }
2972
- initialized = true;
2973
- } catch (error) {
2974
- console.error("\u26A0\uFE0F Failed to initialize router:", error);
2975
- throw error;
2976
- }
2977
- })();
2978
- return initializationPromise;
2979
- }
2980
- function setupOptimizedWatching() {
2981
- if (!_watchers) {
2982
- _watchers = /* @__PURE__ */ new Map();
2983
- }
2984
- for (const directory of routeDirectories) {
2985
- if (!_watchers.has(directory)) {
2986
- const watcher = watchRoutes(directory, {
2987
- debounceMs: 16,
2988
- // ~60fps debouncing
2989
- ignore: ["node_modules", ".git"],
2990
- onRouteAdded: (filepath, addedRoutes) => {
2991
- try {
2992
- const changes = updateRoutesFromFile(registry, filepath, addedRoutes);
2993
- applyMatcherChanges(changes);
2994
- } catch (error) {
2995
- console.error(`Error adding routes from ${directory}:`, error);
2996
- }
2997
- },
2998
- onRouteChanged: withPerformanceTracking(
2999
- async (filepath, changedRoutes) => {
3000
- try {
3001
- console.log(`Processing changes for ${filepath}`);
3002
- const changes = updateRoutesFromFile(registry, filepath, changedRoutes);
3003
- console.log(
3004
- `Changes detected: ${changes.added.length} added, ${changes.changed.length} changed, ${changes.removed.length} removed`
3005
- );
3006
- applyMatcherChanges(changes);
3007
- console.log(
3008
- `Route changes applied: ${changes.added.length} added, ${changes.changed.length} changed, ${changes.removed.length} removed`
3009
- );
3010
- } catch (error) {
3011
- console.error(`\u26A0\uFE0F Error updating routes from ${directory}:`, error);
3012
- }
3013
- },
3014
- directory
3015
- ),
3016
- onRouteRemoved: (filePath, removedRoutes) => {
3017
- console.log(`File removed: ${filePath} with ${removedRoutes.length} routes`);
3018
- try {
3019
- removedRoutes.forEach((route) => {
3020
- removeRouteFromMatcher(route.path, matcher);
3021
- });
3022
- clearFileCache(filePath);
3023
- } catch (error) {
3024
- console.error(`\u26A0\uFE0F Error removing routes from ${filePath}:`, error);
3025
- }
3026
- },
3027
- onError: (error) => {
3028
- console.error(`\u26A0\uFE0F Route watcher error for ${directory}:`, error);
3029
- }
3030
- });
3031
- _watchers.set(directory, watcher);
3032
- }
3033
- }
3034
- }
3035
- function setupWatcherForNewDirectory(directory, prefix) {
3036
- if (!_watchers) {
3037
- _watchers = /* @__PURE__ */ new Map();
3038
- }
3039
- const watcher = watchRoutes(directory, {
3040
- debounceMs: 16,
3041
- ignore: ["node_modules", ".git"],
3042
- onRouteAdded: (filePath, addedRoutes) => {
3043
- try {
3044
- const finalRoutes = addedRoutes.map(
3045
- (route) => prefix ? { ...route, path: `${prefix}${route.path}` } : route
3046
- );
3047
- const changes = updateRoutesFromFile(registry, filePath, finalRoutes);
3048
- applyMatcherChanges(changes);
3049
- } catch (error) {
3050
- console.error(`\u26A0\uFE0F Error adding routes from ${directory}:`, error);
3051
- }
3052
- },
3053
- onRouteChanged: withPerformanceTracking(async (filePath, changedRoutes) => {
3054
- try {
3055
- const finalRoutes = changedRoutes.map(
3056
- (route) => prefix ? { ...route, path: `${prefix}${route.path}` } : route
3057
- );
3058
- const changes = updateRoutesFromFile(registry, filePath, finalRoutes);
3059
- applyMatcherChanges(changes);
3060
- } catch (error) {
3061
- console.error(`\u26A0\uFE0F Error updating routes from ${directory}:`, error);
3062
- }
3063
- }, directory),
3064
- onRouteRemoved: (filePath, removedRoutes) => {
3065
- try {
3066
- removedRoutes.forEach((route) => {
3067
- const finalPath = prefix ? `${prefix}${route.path}` : route.path;
3068
- removeRouteFromMatcher(finalPath, matcher);
3069
- });
3070
- clearFileCache(filePath);
3071
- } catch (error) {
3072
- console.error(`Error removing routes from ${filePath}:`, error);
3073
- }
3074
- },
3075
- onError: (error) => {
3076
- console.error(`\u26A0\uFE0F Route watcher error for ${directory}:`, error);
3077
- }
3078
- });
3079
- _watchers.set(directory, watcher);
3080
- return watcher;
3081
- }
3082
- initialize().catch((error) => {
3083
- console.error("\u26A0\uFE0F Failed to initialize router on creation:", error);
3084
- });
3085
- return {
3086
- /**
3087
- * Handle an incoming request
3088
- */
3089
- async handleRequest(ctx) {
3090
- if (!initialized) {
3091
- console.log("\u{1F504} Router not initialized, initializing...");
3092
- await initialize();
3093
- }
3094
- const { method, path: path6 } = ctx.request;
3095
- console.log(`
3096
- \u{1F4E5} Handling request: ${method} ${path6}`);
3097
- const match = matcher.match(path6, method);
3098
- if (!match) {
3099
- console.log(`\u274C No match found for: ${method} ${path6}`);
3100
- throw new NotFoundError("Not found");
3101
- }
3102
- console.log(`\u2705 Route matched: ${method} ${path6}`);
3103
- console.log(` Params: ${JSON.stringify(match.params)}`);
3104
- if (match.methodNotAllowed) {
3105
- ctx.response.status(405).json({
3106
- error: "\u274C Method Not Allowed",
3107
- allowed: match.allowedMethods
3108
- });
3109
- if (match.allowedMethods && match.allowedMethods.length > 0) {
3110
- ctx.response.header("Allow", match.allowedMethods.join(", "));
3111
- }
3112
- return;
3113
- }
3114
- ctx.request.params = match.params;
3115
- await executeHandler(ctx, match.route, match.params);
3116
- },
3117
- /**
3118
- * Get all registered routes (using optimized registry)
3119
- */
3120
- getRoutes() {
3121
- return getAllRoutesFromRegistry(registry);
3122
- },
3123
- /**
3124
- * Add a route programmatically
3125
- */
3126
- addRoute(route) {
3127
- const changes = updateRoutesFromFile(registry, "programmatic", [route]);
3128
- applyMatcherChanges(changes);
3129
- },
3130
- /**
3131
- * Add multiple routes programmatically with batch processing
3132
- */
3133
- addRoutes(routes) {
3134
- const changes = updateRoutesFromFile(registry, "programmatic", routes);
3135
- applyMatcherChanges(changes);
3136
- return changes;
3137
- },
3138
- /**
3139
- * Add a route directory (for plugins) with optimized loading
3140
- */
3141
- async addRouteDirectory(directory, options2 = {}) {
3142
- if (routeDirectories.has(directory)) {
3143
- console.warn(`Route directory ${directory} already registered`);
3144
- return;
3145
- }
3146
- routeDirectories.add(directory);
3147
- if (initialized) {
3148
- await loadRoutesFromDirectory(directory, directory, options2.prefix);
3149
- if (routerOptions.watchMode) {
3150
- setupWatcherForNewDirectory(directory, options2.prefix);
3151
- }
3152
- }
3153
- },
3154
- /**
3155
- * Get route conflicts (using registry)
3156
- */
3157
- getRouteConflicts() {
3158
- const conflicts = [];
3159
- return conflicts;
3160
- },
3161
- /**
3162
- * Close watchers and cleanup (useful for testing)
3163
- */
3164
- async close() {
3165
- if (_watchers) {
3166
- for (const watcher of _watchers.values()) {
3167
- await watcher.close();
3168
- }
3169
- _watchers.clear();
3170
- }
3171
- }
3172
- };
3173
- }
3174
-
3175
- // src/server/create.ts
3176
- var DEFAULT_OPTIONS2 = {
3177
- port: 3e3,
3178
- host: "localhost",
3179
- routesDir: "./routes",
3180
- http2: {
3181
- enabled: true
3182
- },
3183
- middleware: [],
3184
- plugins: []
3185
- };
3186
- function createServerOptions(options = {}) {
3187
- const baseOptions = { ...DEFAULT_OPTIONS2 };
3188
- setRuntimeConfig({ routesDir: options.routesDir || baseOptions.routesDir });
3189
- return {
3190
- port: options.port ?? baseOptions.port,
3191
- host: options.host ?? baseOptions.host,
3192
- routesDir: options.routesDir ?? baseOptions.routesDir,
3193
- http2: {
3194
- enabled: options.http2?.enabled ?? baseOptions.http2?.enabled,
3195
- keyFile: options.http2?.keyFile ?? baseOptions.http2?.keyFile,
3196
- certFile: options.http2?.certFile ?? baseOptions.http2?.certFile
3197
- },
3198
- middleware: [...baseOptions.middleware || [], ...options.middleware || []],
3199
- plugins: [...baseOptions.plugins || [], ...options.plugins || []]
3200
- };
3201
- }
3202
- function createListenMethod(serverInstance, validatedOptions, initialMiddleware, initialPlugins) {
3203
- return async () => {
3204
- await initializeComponents(serverInstance, initialMiddleware, initialPlugins);
3205
- await serverInstance.pluginManager.initializePlugins(serverInstance);
3206
- await startServer(serverInstance, validatedOptions);
3207
- await serverInstance.pluginManager.onServerStart(serverInstance, serverInstance.server);
3208
- setupServerLifecycle(serverInstance);
3209
- return serverInstance;
3210
- };
3211
- }
3212
- async function initializeComponents(serverInstance, initialMiddleware, initialPlugins) {
3213
- for (const mw of initialMiddleware) {
3214
- serverInstance.use(mw);
3215
- }
3216
- for (const p of initialPlugins) {
3217
- await serverInstance.register(p);
3218
- }
3219
- }
3220
- function setupServerLifecycle(serverInstance) {
3221
- const signalHandlers = registerSignalHandlers(() => serverInstance.close());
3222
- serverInstance._signalHandlers = signalHandlers;
3223
- serverInstance.events.emit("started");
3224
- }
3225
- function createCloseMethod(serverInstance) {
3226
- return async (stopOptions) => {
3227
- if (!serverInstance.server) {
3228
- return;
3229
- }
3230
- const options = { ...stopOptions };
3231
- if (serverInstance._signalHandlers) {
3232
- serverInstance._signalHandlers.unregister();
3233
- delete serverInstance._signalHandlers;
3234
- }
3235
- await stopServer(serverInstance, options);
3236
- };
3237
- }
3238
- function createUseMethod(serverInstance) {
3239
- return (middleware) => {
3240
- const middlewareArray = Array.isArray(middleware) ? middleware : [middleware];
3241
- serverInstance.middleware.push(...middlewareArray);
3242
- return serverInstance;
3243
- };
3244
- }
3245
- function createRegisterMethod(serverInstance) {
3246
- return async (plugin) => {
3247
- validatePlugin(plugin);
3248
- serverInstance.plugins.push(plugin);
3249
- await plugin.register(serverInstance);
3250
- return serverInstance;
3251
- };
3252
- }
3253
- function create3(options = {}) {
3254
- const mergedOptions = createServerOptions(options);
3255
- let validatedOptions;
3256
- try {
3257
- validatedOptions = validateServerOptions(mergedOptions);
3258
- } catch (error) {
3259
- if (error instanceof Error) {
3260
- throw new Error(`Failed to create server: ${error.message}`);
3261
- }
3262
- throw new Error(`Failed to create server: ${String(error)}`);
3263
- }
3264
- const { port, host, middleware, plugins } = validatedOptions;
3265
- const initialMiddleware = Array.isArray(middleware) ? [...middleware] : [];
3266
- const initialPlugins = Array.isArray(plugins) ? [...plugins] : [];
3267
- const contextStorage2 = new import_node_async_hooks3.AsyncLocalStorage();
3268
- const router = createRouter({
3269
- routesDir: validatedOptions.routesDir,
3270
- watchMode: process.env.NODE_ENV === "development"
3271
- });
3272
- const pluginManager = createPluginLifecycleManager({
3273
- debug: process.env.NODE_ENV === "development",
3274
- continueOnError: true
3275
- });
3276
- const events = new import_node_events.default();
3277
- const serverInstance = {
3278
- server: null,
3279
- port,
3280
- host,
3281
- context: contextStorage2,
3282
- events,
3283
- plugins: [],
3284
- middleware: [],
3285
- _signalHandlers: { unregister: () => {
3286
- } },
3287
- use: () => serverInstance,
3288
- register: async () => serverInstance,
3289
- listen: async () => serverInstance,
3290
- close: async () => {
3291
- },
3292
- router,
3293
- pluginManager
3294
- };
3295
- serverInstance.listen = createListenMethod(
3296
- serverInstance,
3297
- validatedOptions,
3298
- initialMiddleware,
3299
- initialPlugins
3300
- );
3301
- serverInstance.close = createCloseMethod(serverInstance);
3302
- serverInstance.use = createUseMethod(serverInstance);
3303
- serverInstance.register = createRegisterMethod(serverInstance);
3304
- return serverInstance;
3305
- }
3306
-
3307
- // ../blaize-types/src/index.ts
3308
- init_errors();
3309
-
3310
- // src/index.ts
3311
- init_validation_error();
3312
-
3313
- // src/errors/unauthorized-error.ts
3314
- init_errors();
3315
- init_correlation();
3316
- var UnauthorizedError = class extends BlaizeError {
3317
- /**
3318
- * Creates a new UnauthorizedError instance
3319
- *
3320
- * @param title - Human-readable error message
3321
- * @param details - Optional authentication context
3322
- * @param correlationId - Optional correlation ID (uses current context if not provided)
3323
- */
3324
- constructor(title, details = void 0, correlationId = void 0) {
3325
- super(
3326
- "UNAUTHORIZED" /* UNAUTHORIZED */,
3327
- title,
3328
- 401,
3329
- // HTTP 401 Unauthorized
3330
- correlationId ?? getCurrentCorrelationId(),
3331
- details
3332
- );
3333
- }
3334
- };
3335
-
3336
- // src/errors/forbidden-error.ts
3337
- init_errors();
3338
- init_correlation();
3339
- var ForbiddenError = class extends BlaizeError {
3340
- /**
3341
- * Creates a new ForbiddenError instance
3342
- *
3343
- * @param title - Human-readable error message
3344
- * @param details - Optional permission context
3345
- * @param correlationId - Optional correlation ID (uses current context if not provided)
3346
- */
3347
- constructor(title, details = void 0, correlationId = void 0) {
3348
- super(
3349
- "FORBIDDEN" /* FORBIDDEN */,
3350
- title,
3351
- 403,
3352
- // HTTP 403 Forbidden
3353
- correlationId ?? getCurrentCorrelationId(),
3354
- details
3355
- );
3356
- }
3357
- };
3358
-
3359
- // src/errors/conflict-error.ts
3360
- init_errors();
3361
- init_correlation();
3362
- var ConflictError = class extends BlaizeError {
3363
- /**
3364
- * Creates a new ConflictError instance
3365
- *
3366
- * @param title - Human-readable error message
3367
- * @param details - Optional conflict context
3368
- * @param correlationId - Optional correlation ID (uses current context if not provided)
3369
- */
3370
- constructor(title, details = void 0, correlationId = void 0) {
3371
- super(
3372
- "CONFLICT" /* CONFLICT */,
3373
- title,
3374
- 409,
3375
- // HTTP 409 Conflict
3376
- correlationId ?? getCurrentCorrelationId(),
3377
- details
3378
- );
3379
- }
3380
- };
3381
-
3382
- // src/errors/rate-limit-error.ts
3383
- init_errors();
3384
- init_correlation();
3385
- var RateLimitError = class extends BlaizeError {
3386
- /**
3387
- * Creates a new RateLimitError instance
3388
- *
3389
- * @param title - Human-readable error message
3390
- * @param details - Optional rate limit context
3391
- * @param correlationId - Optional correlation ID (uses current context if not provided)
3392
- */
3393
- constructor(title, details = void 0, correlationId = void 0) {
3394
- super(
3395
- "RATE_LIMITED" /* RATE_LIMITED */,
3396
- title,
3397
- 429,
3398
- // HTTP 429 Too Many Requests
3399
- correlationId ?? getCurrentCorrelationId(),
3400
- details
3401
- );
3402
- }
3403
- };
3404
-
3405
- // src/index.ts
3406
- init_internal_server_error();
3407
- init_payload_too_large_error();
3408
-
3409
- // src/errors/request-timeout-error.ts
3410
- init_correlation();
3411
- init_errors();
3412
- var RequestTimeoutError = class extends BlaizeError {
3413
- constructor(title, details, correlationId) {
3414
- super(
3415
- "UPLOAD_TIMEOUT" /* UPLOAD_TIMEOUT */,
3416
- title,
3417
- 408,
3418
- correlationId ?? getCurrentCorrelationId(),
3419
- details
3420
- );
3421
- }
3422
- };
3423
-
3424
- // src/index.ts
3425
- init_unsupported_media_type_error();
3426
-
3427
- // src/errors/unprocessable-entity-error.ts
3428
- init_correlation();
3429
- init_errors();
3430
- var UnprocessableEntityError = class extends BlaizeError {
3431
- constructor(title, details, correlationId) {
3432
- super(
3433
- "UNPROCESSABLE_ENTITY" /* UNPROCESSABLE_ENTITY */,
3434
- title,
3435
- 422,
3436
- correlationId ?? getCurrentCorrelationId(),
3437
- details
3438
- );
3439
- }
3440
- };
3441
-
3442
- // src/index.ts
3443
- var VERSION = "0.1.0";
3444
- var ServerAPI = { createServer: create3 };
3445
- var RouterAPI = {
3446
- createDeleteRoute,
3447
- createGetRoute,
3448
- createHeadRoute,
3449
- createOptionsRoute,
3450
- createPatchRoute,
3451
- createPostRoute,
3452
- createPutRoute
3453
- };
3454
- var MiddlewareAPI = { createMiddleware: create, compose };
3455
- var PluginsAPI = { createPlugin: create2 };
3456
- var Blaize = {
3457
- // Core functions
3458
- createServer: create3,
3459
- createMiddleware: create,
3460
- createPlugin: create2,
3461
- // Namespaces (using the non-conflicting names)
3462
- Server: ServerAPI,
3463
- Router: RouterAPI,
3464
- Middleware: MiddlewareAPI,
3465
- Plugins: PluginsAPI,
3466
- // Constants
3467
- VERSION
3468
- };
3469
- var index_default = Blaize;
3470
- // Annotate the CommonJS export names for ESM import in node:
3471
- 0 && (module.exports = {
3472
- Blaize,
3473
- BlaizeError,
3474
- ConflictError,
3475
- ErrorSeverity,
3476
- ErrorType,
3477
- ForbiddenError,
3478
- InternalServerError,
3479
- MiddlewareAPI,
3480
- NotFoundError,
3481
- PayloadTooLargeError,
3482
- PluginsAPI,
3483
- RateLimitError,
3484
- RequestTimeoutError,
3485
- RouterAPI,
3486
- ServerAPI,
3487
- UnauthorizedError,
3488
- UnprocessableEntityError,
3489
- UnsupportedMediaTypeError,
3490
- VERSION,
3491
- ValidationError,
3492
- compose,
3493
- createDeleteRoute,
3494
- createGetRoute,
3495
- createHeadRoute,
3496
- createMiddleware,
3497
- createOptionsRoute,
3498
- createPatchRoute,
3499
- createPlugin,
3500
- createPostRoute,
3501
- createPutRoute,
3502
- createServer,
3503
- isBodyParseError
3504
- });
27
+ `),n()}),e.on("error",s=>{console.error("Server error:",s),i(s)})})}async function fo(e){for(let t of e.plugins)typeof t.initialize=="function"&&await t.initialize(e)}async function Ot(e,t){if(!e.server)try{let r=t.port,o=t.host;await fo(e);let n=t.http2||{enabled:!0},i=!!n.enabled,s=await lo(n);t.http2&&s.keyFile&&s.certFile&&(t.http2.keyFile=s.keyFile,t.http2.certFile=s.certFile);let a=co(i,s);e.server=a,e.port=r,e.host=o;let u=Ct(e);a.on("request",u),await po(a,r,o,i)}catch(r){throw console.error("Failed to start server:",r),r}}var pe=!1;async function Dt(e,t={}){let r=e.server,o=e.events;if(pe){console.log("\u26A0\uFE0F Shutdown already in progress, ignoring duplicate shutdown request");return}if(!r)return;pe=!0;let n=t.timeout||5e3;try{if(t.onStopping&&await t.onStopping(),o.emit("stopping"),e.router&&typeof e.router.close=="function"){console.log("\u{1F50C} Closing router watchers...");try{await Promise.race([e.router.close(),new Promise((a,u)=>setTimeout(()=>u(new Error("Router close timeout")),2e3))]),console.log("\u2705 Router watchers closed")}catch(a){console.error("\u274C Error closing router watchers:",a)}}try{await Promise.race([e.pluginManager.onServerStop(e,r),new Promise((a,u)=>setTimeout(()=>u(new Error("Plugin stop timeout")),2e3))])}catch(a){console.error("\u274C Plugin stop timeout:",a)}let i=new Promise((a,u)=>{r.close(c=>{if(c)return u(c);a()})}),s=new Promise((a,u)=>{setTimeout(()=>{u(new Error("Server shutdown timeout"))},n)});await Promise.race([i,s]);try{await Promise.race([e.pluginManager.terminatePlugins(e),new Promise((a,u)=>setTimeout(()=>u(new Error("Plugin terminate timeout")),1e3))])}catch(a){console.error("\u274C Plugin terminate timeout:",a)}t.onStopped&&await t.onStopped(),o.emit("stopped"),e.server=null,console.log("\u2705 Graceful shutdown completed"),pe=!1}catch(i){throw pe=!1,console.error("\u26A0\uFE0F Shutdown error (forcing exit):",i),r&&typeof r.close=="function"&&r.close(),process.env.NODE_ENV==="development"&&(console.log("\u{1F504} Forcing exit for development restart..."),process.exit(0)),o.emit("error",i),i}}function kt(e){if(process.env.NODE_ENV==="development"){let r=()=>{console.log("\u{1F4E4} SIGINT received, forcing exit for development restart..."),process.exit(0)},o=()=>{console.log("\u{1F4E4} SIGTERM received, forcing exit for development restart..."),process.exit(0)};return process.on("SIGINT",r),process.on("SIGTERM",o),{unregister:()=>{process.removeListener("SIGINT",r),process.removeListener("SIGTERM",o)}}}else{let r=()=>{console.log("\u{1F4E4} SIGINT received, starting graceful shutdown..."),e().catch(console.error)},o=()=>{console.log("\u{1F4E4} SIGTERM received, starting graceful shutdown..."),e().catch(console.error)};return process.on("SIGINT",r),process.on("SIGTERM",o),{unregister:()=>{process.removeListener("SIGINT",r),process.removeListener("SIGTERM",o)}}}}var b=require("zod"),mo=b.z.custom(e=>e!==null&&typeof e=="object"&&"execute"in e&&typeof e.execute=="function",{message:"Expected middleware to have an execute function"}),go=b.z.custom(e=>e!==null&&typeof e=="object"&&"register"in e&&typeof e.register=="function",{message:"Expected a valid plugin object with a register method"}),yo=b.z.object({enabled:b.z.boolean().optional().default(!0),keyFile:b.z.string().optional(),certFile:b.z.string().optional()}).refine(e=>e.enabled&&process.env.NODE_ENV==="production"?e.keyFile&&e.certFile:!0,{message:"When HTTP/2 is enabled (outside of development mode), both keyFile and certFile must be provided"}),ho=b.z.object({port:b.z.number().int().positive().optional().default(3e3),host:b.z.string().optional().default("localhost"),routesDir:b.z.string().optional().default("./routes"),http2:yo.optional().default({enabled:!0}),middleware:b.z.array(mo).optional().default([]),plugins:b.z.array(go).optional().default([])});function zt(e){try{return ho.parse(e)}catch(t){if(t instanceof b.z.ZodError){let r=t.format();throw new Error(`Invalid server options: ${JSON.stringify(r,null,2)}`)}throw new Error(`Invalid server options: ${String(t)}`)}}function Bt(e={}){let{continueOnError:t=!0,debug:r=!1,onError:o}=e;function n(s,...a){r&&console.log(`[PluginLifecycle] ${s}`,...a)}function i(s,a,u){let c=`Plugin ${s.name} failed during ${a}: ${u.message}`;if(o?o(s,a,u):console.error(c,u),!t)throw new Error(c)}return{async initializePlugins(s){n("Initializing plugins...");for(let a of s.plugins)if(a.initialize)try{n(`Initializing plugin: ${a.name}`),await a.initialize(s)}catch(u){i(a,"initialize",u)}n(`Initialized ${s.plugins.length} plugins`)},async terminatePlugins(s){n("Terminating plugins...");let a=[...s.plugins].reverse();for(let u of a)if(u.terminate)try{n(`Terminating plugin: ${u.name}`),await u.terminate(s)}catch(c){i(u,"terminate",c)}n(`Terminated ${a.length} plugins`)},async onServerStart(s,a){n("Notifying plugins of server start...");for(let u of s.plugins)if(u.onServerStart)try{n(`Notifying plugin of server start: ${u.name}`),await u.onServerStart(a)}catch(c){i(u,"onServerStart",c)}},async onServerStop(s,a){n("Notifying plugins of server stop...");let u=[...s.plugins].reverse();for(let c of u)if(c.onServerStop)try{n(`Notifying plugin of server stop: ${c.name}`),await c.onServerStop(a)}catch(S){i(c,"onServerStop",S)}}}}var F=class extends Error{constructor(r,o){super(`Plugin validation error${r?` for "${r}"`:""}: ${o}`);this.pluginName=r;this.name="PluginValidationError"}};var wo=new Set(["core","server","router","middleware","context","blaize","blaizejs"]),Ro=/^[a-z]([a-z0-9-]*[a-z0-9])?$/,So=/^\d+\.\d+\.\d+(?:-[a-zA-Z0-9-.]+)?(?:\+[a-zA-Z0-9-.]+)?$/;function $t(e,t={}){let{requireVersion:r=!0,validateNameFormat:o=!0,checkReservedNames:n=!0}=t;if(!e||typeof e!="object")throw new F("","Plugin must be an object");let i=e;if(!i.name||typeof i.name!="string")throw new F("","Plugin must have a name (string)");if(o&&!Ro.test(i.name))throw new F(i.name,"Plugin name must be lowercase letters, numbers, and hyphens only");if(n&&wo.has(i.name.toLowerCase()))throw new F(i.name,`Plugin name "${i.name}" is reserved`);if(r){if(!i.version||typeof i.version!="string")throw new F(i.name,"Plugin must have a version (string)");if(!So.test(i.version))throw new F(i.name,'Plugin version must follow semantic versioning (e.g., "1.0.0")')}if(!i.register||typeof i.register!="function")throw new F(i.name,"Plugin must have a register method (function)");let s=["initialize","terminate","onServerStart","onServerStop"];for(let a of s)if(i[a]&&typeof i[a]!="function")throw new F(i.name,`Plugin ${a} must be a function if provided`)}var It=T(require("crypto"),1),_t=T(require("fs/promises"),1),At=require("module"),Ut=T(require("path"),1);async function To(e){let t=`?t=${Date.now()}`,r=e+t;try{let o=await import(r);return console.log("\u2705 Successfully imported module"),o}catch(o){let n=o instanceof Error?o.message:String(o);return console.log("\u26A0\uFE0F Error importing with cache buster, trying original path:",n),import(e)}}async function Nt(e,t){try{let r=ie(e,t),o=await To(e);console.log("\u{1F4E6} Module exports:",Object.keys(o));let n=[];if(o.default&&typeof o.default=="object"){let i={...o.default,path:r.routePath};n.push(i)}return Object.entries(o).forEach(([i,s])=>{if(i==="default"||!s||typeof s!="object")return;let a=s;if(Eo(a)){let u={...a,path:r.routePath};n.push(u)}}),n.length===0?(console.warn(`Route file ${e} does not export any valid route definitions`),[]):(console.log(`\u2705 Successfully Loaded ${n.length} route(s)`),n)}catch(r){return console.error(`Failed to load route module ${e}:`,r),[]}}function Eo(e){return!e||typeof e!="object"?!1:["GET","POST","PUT","DELETE","PATCH","HEAD","OPTIONS"].some(o=>e[o]&&typeof e[o]=="object"&&e[o].handler)}var bo={},K=new Map;async function X(e,t,r=!0){let n=(await _t.stat(e)).mtime.getTime(),i=K.get(e);if(r&&i&&i.timestamp===n)return i.routes;xo(e);let s=await Nt(e,t);if(r){let a=Ht(s);K.set(e,{routes:s,timestamp:n,hash:a})}return s}function Lt(e,t){let r=K.get(e);if(!r)return!0;let o=Ht(t);return r.hash!==o}function Ie(e){e?K.delete(e):K.clear()}function Ht(e){let t=e.map(n=>({path:n.path,methods:Object.keys(n).filter(i=>i!=="path").sort().map(i=>{let s=n[i],a=s?.handler?s.handler.toString():null;return{method:i,handler:a,middleware:s?.middleware?s.middleware.length:0,hasSchema:!!s?.schema,schemaKeys:s?.schema?Object.keys(s.schema).sort():[]}})})),r=JSON.stringify(t);return It.createHash("md5").update(r).digest("hex")}function xo(e){try{let t=Ut.resolve(e);if(typeof require<"u"){delete require.cache[t];try{let r=require.resolve(t);delete require.cache[r]}catch(r){let o=r instanceof Error?r.message:String(r);console.log(`\u26A0\uFE0F Could not resolve path: ${o}`)}}else try{let r=(0,At.createRequire)(bo.url);delete r.cache[t];try{let o=r.resolve(t);delete r.cache[o]}catch{console.log("\u26A0\uFE0F Could not resolve ESM path")}}catch{console.log("\u26A0\uFE0F createRequire not available in pure ESM")}}catch(t){console.log(`\u26A0\uFE0F Error during module cache invalidation for ${e}:`,t)}}var qt=T(require("os"),1);var fe=T(require("fs/promises"),1),j=T(require("path"),1);async function me(e,t={}){let r=j.isAbsolute(e)?e:j.resolve(process.cwd(),e);console.log("Creating router with routes directory:",r);try{if(!(await fe.stat(r)).isDirectory())throw new Error(`Route directory is not a directory: ${r}`)}catch(s){throw s.code==="ENOENT"?new Error(`Route directory not found: ${r}`):s}let o=[],n=t.ignore||["node_modules",".git"];async function i(s){let a=await fe.readdir(s,{withFileTypes:!0});for(let u of a){let c=j.join(s,u.name);u.isDirectory()&&n.includes(u.name)||(u.isDirectory()?await i(c):Po(u.name)&&o.push(c))}}return await i(r),o}function Po(e){return!e.startsWith("_")&&(e.endsWith(".ts")||e.endsWith(".js"))}async function vo(e,t,r=Math.max(1,Math.floor(qt.cpus().length/2))){let o=Co(e,r),n=[];for(let i of o){let a=(await Promise.allSettled(i.map(u=>t(u)))).filter(u=>u.status==="fulfilled").map(u=>u.value);n.push(...a)}return n}async function jt(e){let t=await me(e);return(await vo(t,o=>X(o,e))).flat()}function Co(e,t){let r=[];for(let o=0;o<e.length;o+=t)r.push(e.slice(o,o+t));return r}var N={fileChanges:0,totalReloadTime:0,averageReloadTime:0,slowReloads:[]};function Qt(e,t){let r=Date.now()-t;if(N.fileChanges++,N.totalReloadTime+=r,N.averageReloadTime=N.totalReloadTime/N.fileChanges,r>100&&(N.slowReloads.push({file:e,time:r}),N.slowReloads.length>10&&N.slowReloads.shift()),process.env.NODE_ENV==="development"){let o=r<50?"\u26A1":r<100?"\u{1F504}":"\u{1F40C}";console.log(`${o} Route reload: ${e} (${r}ms)`)}}function _e(e,t){return console.log(`Tracking performance for: ${t}`),async(...r)=>{let o=Date.now();try{let n=await e(...r);return Qt(t,o),n}catch(n){throw Qt(t,o),n}}}var Ae=T(require("path"),1),Vt=require("chokidar");function Ue(e,t={}){let r=t.debounceMs||16,o=new Map;function n(p,g){return(...y)=>{let l=o.get(g);l&&clearTimeout(l);let d=setTimeout(()=>{p(...y),o.delete(g)},r);o.set(g,d)}}let i=new Map;async function s(){try{let p=await me(e,{ignore:t.ignore});for(let g of p)await a(g)}catch(p){c(p)}}async function a(p){try{let g=i.get(p),y=await X(p,e,!1);if(!y||y.length===0||g&&!Lt(p,y))return;await X(p,e,!0);let l=Ae.normalize(p);g?(i.set(p,y),t.onRouteChanged&&t.onRouteChanged(l,y)):(i.set(p,y),t.onRouteAdded&&t.onRouteAdded(l,y))}catch(g){console.log(`\u26A0\uFE0F Error processing file ${p}:`,g),c(g)}}function u(p){let g=Ae.normalize(p),y=i.get(g);y&&y.length>0&&t.onRouteRemoved&&t.onRouteRemoved(g,y),i.delete(g)}function c(p){t.onError&&p instanceof Error?t.onError(p):console.error("\u26A0\uFE0F Route watcher error:",p)}let S=(0,Vt.watch)(e,{awaitWriteFinish:{stabilityThreshold:50,pollInterval:10},usePolling:!1,atomic:!0,followSymlinks:!1,depth:10,ignored:[/(^|[/\\])\../,/node_modules/,/\.git/,/\.DS_Store/,/Thumbs\.db/,/\.(test|spec)\.(ts|js)$/,/\.d\.ts$/,/\.map$/,/~$/,...t.ignore||[]]});return S.on("add",p=>{n(a,p)(p)}).on("change",p=>{n(a,p)(p)}).on("unlink",p=>{n(u,p)(p)}).on("error",c),s().catch(c),{close:()=>(o.forEach(p=>clearTimeout(p)),o.clear(),S.close()),getRoutes:()=>{let p=[];for(let g of i.values())p.push(...g);return p},getRoutesByFile:()=>new Map(i)}}var Yt=require("zod");var Wt=require("zod");function Le(e,t){return t instanceof Wt.z.ZodObject?t.strict().parse(e):t.parse(e)}var Gt=require("zod");function He(e,t){return t instanceof Gt.z.ZodObject?t.strict().parse(e):t.parse(e)}var Zt=require("zod");function qe(e,t){return t instanceof Zt.z.ZodObject?t.strict().parse(e):t.parse(e)}var Jt=require("zod");function je(e,t){return t instanceof Jt.z.ZodObject?t.strict().parse(e):t.parse(e)}W();z();function Qe(e,t=!1){return{name:"RequestValidator",execute:async(o,n)=>{if(e.params&&o.request.params)try{o.request.params=He(o.request.params,e.params)}catch(i){let s=ge(i),a=s.reduce((u,c)=>u+c.messages.length,0);throw new k("Request validation failed",{fields:s,errorCount:a,section:"params"})}if(e.query&&o.request.query)try{o.request.query=qe(o.request.query,e.query)}catch(i){let s=ge(i),a=s.reduce((u,c)=>u+c.messages.length,0);throw new k("Request validation failed",{fields:s,errorCount:a,section:"query"})}if(e.body)try{o.request.body=Le(o.request.body,e.body)}catch(i){let s=ge(i),a=s.reduce((u,c)=>u+c.messages.length,0);throw new k("Request validation failed",{fields:s,errorCount:a,section:"body"})}await n()},debug:t}}function Ve(e,t=!1){return{name:"ResponseValidator",execute:async(o,n)=>{let i=o.response.json;o.response.json=(s,a)=>{try{let u=je(s,e);return o.response.json=i,i.call(o.response,u,a)}catch(u){throw o.response.json=i,new D("Response validation failed",{responseSchema:e.description||"Unknown schema",validationError:ge(u),originalResponse:s})}},await n()},debug:t}}function ge(e){if(e instanceof Yt.z.ZodError){let t=new Map;for(let r of e.issues){let o=r.path.length>0?r.path.join("."):"root";t.has(o)||t.set(o,[]),t.get(o).push(r.message)}return Array.from(t.entries()).map(([r,o])=>({field:r,messages:o}))}return e instanceof Error?[{field:"unknown",messages:[e.message]}]:[{field:"unknown",messages:[String(e)]}]}async function We(e,t,r){let o=[...t.middleware||[]];t.schema&&((t.schema.params||t.schema.query||t.schema.body)&&o.unshift(Qe(t.schema)),t.schema.response&&o.push(Ve(t.schema.response))),await A([...o])(e,async()=>{let i=await t.handler(e,r);!e.response.sent&&i!==void 0&&e.response.json(i)})}function ye(e,t,r){let o=t.exec(e);if(!o)return{};let n={};for(let i=0;i<r.length;i++)n[r[i]]=o[i+1]||"";return n}function Ge(e){let t=[];if(e==="/")return{pattern:/^\/$/,paramNames:[]};let r=e.replace(/([.+*?^$(){}|\\])/g,"\\$1");return r=r.replace(/\/:([^/]+)/g,(n,i)=>(t.push(i),"/([^/]+)")).replace(/\/\[([^\]]+)\]/g,(n,i)=>(t.push(i),"/([^/]+)")),r=`${r}(?:/)?`,{pattern:new RegExp(`^${r}$`),paramNames:t}}function Ze(){let e=[];return{add(t,r,o){let{pattern:n,paramNames:i}=Ge(t),s={path:t,method:r,pattern:n,paramNames:i,routeOptions:o},a=e.findIndex(u=>i.length<u.paramNames.length);a===-1?e.push(s):e.splice(a,0,s)},remove(t){for(let r=e.length-1;r>=0;r--)e[r].path===t&&e.splice(r,1)},clear(){e.length=0},match(t,r){let o=t.split("?")[0];if(!o)return null;for(let i of e){if(i.method!==r)continue;if(i.pattern.exec(o)){let a=ye(t,i.pattern,i.paramNames);return{route:i.routeOptions,params:a}}}return e.find(i=>i.method!==r&&i.pattern.test(t))?{route:null,params:{},methodNotAllowed:!0,allowedMethods:e.filter(i=>i.pattern.test(t)).map(i=>i.method)}:null},getRoutes(){return e.map(t=>({path:t.path,method:t.method}))},findRoutes(t){return e.filter(r=>r.pattern.test(t)).map(r=>({path:r.path,method:r.method,params:ye(t,r.pattern,r.paramNames)}))}}}function Kt(){return{routesByPath:new Map,routesByFile:new Map,pathToFile:new Map}}function I(e,t,r){console.log(`Updating routes from file: ${t}`);let o=e.routesByFile.get(t)||new Set,n=new Set(r.map(c=>c.path)),i=r.filter(c=>!o.has(c.path)),s=Array.from(o).filter(c=>!n.has(c)),u=r.filter(c=>o.has(c.path)).filter(c=>{let S=e.routesByPath.get(c.path);return!S||!Mo(S,c)});return Fo(e,t,{added:i,removed:s,changed:u}),{added:i,removed:s,changed:u}}function Xt(e){return Array.from(e.routesByPath.values())}function Fo(e,t,r){let{added:o,removed:n,changed:i}=r;n.forEach(a=>{e.routesByPath.delete(a),e.pathToFile.delete(a)}),[...o,...i].forEach(a=>{e.routesByPath.set(a.path,a),e.pathToFile.set(a.path,t)});let s=new Set([...o.map(a=>a.path),...i.map(a=>a.path),...Array.from(e.routesByFile.get(t)||[]).filter(a=>!n.includes(a))]);s.size>0?e.routesByFile.set(t,s):e.routesByFile.delete(t)}function Mo(e,t){if(e.path!==t.path)return!1;let r=Object.keys(e).filter(n=>n!=="path").sort(),o=Object.keys(t).filter(n=>n!=="path").sort();return r.length!==o.length?!1:r.every(n=>{let i=e[n],s=t[n];return typeof i==typeof s})}function Je(e,t){Object.entries(e).forEach(([r,o])=>{r==="path"||!o||t.add(e.path,r,o)})}function ee(e,t){"remove"in t&&typeof t.remove=="function"?t.remove(e):console.warn("Matcher does not support selective removal, consider adding remove() method")}function er(e,t){ee(e.path,t),Je(e,t)}var Oo={routesDir:"./routes",basePath:"/",watchMode:process.env.NODE_ENV==="development"};function tr(e){let t={...Oo,...e};e.basePath&&!e.basePath.startsWith("/")&&console.warn("Base path does nothing");let r=Kt(),o=Ze(),n=!1,i=null,s=null,a=new Set([t.routesDir]);function u(l){console.log(`
28
+ \u{1F527} APPLYING MATCHER CHANGES:`),console.log(` Adding ${l.added.length} routes`),console.log(` Removing ${l.removed.length} routes`),console.log(` Updating ${l.changed.length} routes`),l.removed.forEach(d=>{console.log(` \u2796 Removing: ${d}`),ee(d,o)}),l.added.forEach(d=>{let m=Object.keys(d).filter(f=>f!=="path");console.log(` \u2795 Adding: ${d.path} [${m.join(", ")}]`),Je(d,o)}),l.changed.forEach(d=>{let m=Object.keys(d).filter(f=>f!=="path");console.log(` \u{1F504} Updating: ${d.path} [${m.join(", ")}]`),er(d,o)}),console.log(`\u2705 Matcher changes applied
29
+ `)}function c(l,d){try{let m=I(r,d,l);return u(m),m}catch(m){throw console.error(`\u26A0\uFE0F Route conflicts from ${d}:`,m),m}}async function S(l,d,m){try{let f=await jt(l),w=f.map(M=>m?{...M,path:`${m}${M.path}`}:M),E=c(w,d);console.log(`Loaded ${f.length} routes from ${d}${m?` with prefix ${m}`:""} (${E.added.length} added, ${E.changed.length} changed, ${E.removed.length} removed)`)}catch(f){throw console.error(`\u26A0\uFE0F Failed to load routes from ${d}:`,f),f}}async function p(){return n||i||(i=(async()=>{try{await Promise.all(Array.from(a).map(l=>S(l,l))),t.watchMode&&g(),n=!0}catch(l){throw console.error("\u26A0\uFE0F Failed to initialize router:",l),l}})()),i}function g(){s||(s=new Map);for(let l of a)if(!s.has(l)){let d=Ue(l,{debounceMs:16,ignore:["node_modules",".git"],onRouteAdded:(m,f)=>{try{let w=I(r,m,f);u(w)}catch(w){console.error(`Error adding routes from ${l}:`,w)}},onRouteChanged:_e(async(m,f)=>{try{console.log(`Processing changes for ${m}`);let w=I(r,m,f);console.log(`Changes detected: ${w.added.length} added, ${w.changed.length} changed, ${w.removed.length} removed`),u(w),console.log(`Route changes applied: ${w.added.length} added, ${w.changed.length} changed, ${w.removed.length} removed`)}catch(w){console.error(`\u26A0\uFE0F Error updating routes from ${l}:`,w)}},l),onRouteRemoved:(m,f)=>{console.log(`File removed: ${m} with ${f.length} routes`);try{f.forEach(w=>{ee(w.path,o)}),Ie(m)}catch(w){console.error(`\u26A0\uFE0F Error removing routes from ${m}:`,w)}},onError:m=>{console.error(`\u26A0\uFE0F Route watcher error for ${l}:`,m)}});s.set(l,d)}}function y(l,d){s||(s=new Map);let m=Ue(l,{debounceMs:16,ignore:["node_modules",".git"],onRouteAdded:(f,w)=>{try{let E=w.map(_=>d?{..._,path:`${d}${_.path}`}:_),M=I(r,f,E);u(M)}catch(E){console.error(`\u26A0\uFE0F Error adding routes from ${l}:`,E)}},onRouteChanged:_e(async(f,w)=>{try{let E=w.map(_=>d?{..._,path:`${d}${_.path}`}:_),M=I(r,f,E);u(M)}catch(E){console.error(`\u26A0\uFE0F Error updating routes from ${l}:`,E)}},l),onRouteRemoved:(f,w)=>{try{w.forEach(E=>{let M=d?`${d}${E.path}`:E.path;ee(M,o)}),Ie(f)}catch(E){console.error(`Error removing routes from ${f}:`,E)}},onError:f=>{console.error(`\u26A0\uFE0F Route watcher error for ${l}:`,f)}});return s.set(l,m),m}return p().catch(l=>{console.error("\u26A0\uFE0F Failed to initialize router on creation:",l)}),{async handleRequest(l){n||(console.log("\u{1F504} Router not initialized, initializing..."),await p());let{method:d,path:m}=l.request;console.log(`
30
+ \u{1F4E5} Handling request: ${d} ${m}`);let f=o.match(m,d);if(!f)throw console.log(`\u274C No match found for: ${d} ${m}`),new $("Not found");if(console.log(`\u2705 Route matched: ${d} ${m}`),console.log(` Params: ${JSON.stringify(f.params)}`),f.methodNotAllowed){l.response.status(405).json({error:"\u274C Method Not Allowed",allowed:f.allowedMethods}),f.allowedMethods&&f.allowedMethods.length>0&&l.response.header("Allow",f.allowedMethods.join(", "));return}l.request.params=f.params,await We(l,f.route,f.params)},getRoutes(){return Xt(r)},addRoute(l){let d=I(r,"programmatic",[l]);u(d)},addRoutes(l){let d=I(r,"programmatic",l);return u(d),d},async addRouteDirectory(l,d={}){if(a.has(l)){console.warn(`Route directory ${l} already registered`);return}a.add(l),n&&(await S(l,l,d.prefix),t.watchMode&&y(l,d.prefix))},getRouteConflicts(){return[]},async close(){if(s){for(let l of s.values())await l.close();s.clear()}}}}var Do={port:3e3,host:"localhost",routesDir:"./routes",http2:{enabled:!0},middleware:[],plugins:[]};function ko(e={}){let t={...Do};return Xe({routesDir:e.routesDir||t.routesDir}),{port:e.port??t.port,host:e.host??t.host,routesDir:e.routesDir??t.routesDir,http2:{enabled:e.http2?.enabled??t.http2?.enabled,keyFile:e.http2?.keyFile??t.http2?.keyFile,certFile:e.http2?.certFile??t.http2?.certFile},middleware:[...t.middleware||[],...e.middleware||[]],plugins:[...t.plugins||[],...e.plugins||[]]}}function zo(e,t,r,o){return async()=>(await Bo(e,r,o),await e.pluginManager.initializePlugins(e),await Ot(e,t),await e.pluginManager.onServerStart(e,e.server),$o(e),e)}async function Bo(e,t,r){for(let o of t)e.use(o);for(let o of r)await e.register(o)}function $o(e){let t=kt(()=>e.close());e._signalHandlers=t,e.events.emit("started")}function No(e){return async t=>{if(!e.server)return;let r={...t};e._signalHandlers&&(e._signalHandlers.unregister(),delete e._signalHandlers),await Dt(e,r)}}function Io(e){return t=>{let r=Array.isArray(t)?t:[t];return e.middleware.push(...r),e}}function _o(e){return async t=>($t(t),e.plugins.push(t),await t.register(e),e)}function he(e={}){let t=ko(e),r;try{r=zt(t)}catch(l){throw l instanceof Error?new Error(`Failed to create server: ${l.message}`):new Error(`Failed to create server: ${String(l)}`)}let{port:o,host:n,middleware:i,plugins:s}=r,a=Array.isArray(i)?[...i]:[],u=Array.isArray(s)?[...s]:[],c=new rr.AsyncLocalStorage,S=tr({routesDir:r.routesDir,watchMode:process.env.NODE_ENV==="development"}),p=Bt({debug:process.env.NODE_ENV==="development",continueOnError:!0}),g=new or.default,y={server:null,port:o,host:n,context:c,events:g,plugins:[],middleware:[],_signalHandlers:{unregister:()=>{}},use:()=>y,register:async()=>y,listen:async()=>y,close:async()=>{},router:S,pluginManager:p};return y.listen=zo(y,r,a,u),y.close=No(y),y.use=Io(y),y.register=_o(y),y}x();z();x();v();var we=class extends h{constructor(t,r=void 0,o=void 0){super("UNAUTHORIZED",t,401,o??R(),r)}};x();v();var Re=class extends h{constructor(t,r=void 0,o=void 0){super("FORBIDDEN",t,403,o??R(),r)}};x();v();var Se=class extends h{constructor(t,r=void 0,o=void 0){super("CONFLICT",t,409,o??R(),r)}};x();v();var Te=class extends h{constructor(t,r=void 0,o=void 0){super("RATE_LIMITED",t,429,o??R(),r)}};W();le();v();x();var Ee=class extends h{constructor(t,r,o){super("UPLOAD_TIMEOUT",t,408,o??R(),r)}};ce();v();x();var xe=class extends h{constructor(t,r,o){super("UNPROCESSABLE_ENTITY",t,422,o??R(),r)}};var nr="0.1.0",ir={createServer:he},sr={createDeleteRoute:Ce,createGetRoute:be,createHeadRoute:Me,createOptionsRoute:Oe,createPatchRoute:Fe,createPostRoute:Pe,createPutRoute:ve},ar={createMiddleware:re,compose:A},ur={createPlugin:oe},Ao={createServer:he,createMiddleware:re,createPlugin:oe,Server:ir,Router:sr,Middleware:ar,Plugins:ur,VERSION:nr};0&&(module.exports={Blaize,BlaizeError,ConflictError,ErrorSeverity,ErrorType,ForbiddenError,InternalServerError,MiddlewareAPI,NotFoundError,PayloadTooLargeError,PluginsAPI,RateLimitError,RequestTimeoutError,RouterAPI,ServerAPI,UnauthorizedError,UnprocessableEntityError,UnsupportedMediaTypeError,VERSION,ValidationError,compose,createDeleteRoute,createGetRoute,createHeadRoute,createMiddleware,createOptionsRoute,createPatchRoute,createPlugin,createPostRoute,createPutRoute,createServer,isBodyParseError});
3505
31
  //# sourceMappingURL=index.cjs.map