speexjs 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{index-CMkhSDh7.d.ts → index-C4xilc_E.d.ts} +4 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2706 -2344
- package/dist/index.js.map +1 -1
- package/dist/server/auth/index.d.ts +2 -1
- package/dist/server/cache/index.d.ts +2 -1
- package/dist/server/controller/index.d.ts +2 -1
- package/dist/server/database/index.d.ts +14 -2
- package/dist/server/database/index.js +123 -15
- package/dist/server/database/index.js.map +1 -1
- package/dist/server/gate/index.d.ts +2 -1
- package/dist/server/index.d.ts +56 -3
- package/dist/server/index.js +1940 -1578
- package/dist/server/index.js.map +1 -1
- package/dist/server/middleware/index.d.ts +2 -1
- package/dist/server/middleware/index.js +32 -1
- package/dist/server/middleware/index.js.map +1 -1
- package/dist/server/router/index.d.ts +2 -1
- package/dist/server/router/index.js.map +1 -1
- package/package.json +142 -141
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
export { d as CorsOptions, M as Middleware, e as MiddlewarePipeline, f as SessionOptions, S as StaticOptions, g as auth, h as bodyParser, i as compress, j as cors, k as csrf, l as helmet, m as logger, s as session, n as staticFiles, t as throttle } from '../../index-
|
|
1
|
+
export { d as CorsOptions, M as Middleware, e as MiddlewarePipeline, f as SessionOptions, S as StaticOptions, g as auth, h as bodyParser, i as compress, j as cors, k as csrf, l as helmet, m as logger, s as session, n as staticFiles, t as throttle, v as validate, o as validateQuery } from '../../index-C4xilc_E.js';
|
|
2
|
+
import '../../types-aW38f63o.js';
|
|
2
3
|
import '../container/index.js';
|
|
3
4
|
import '../../response-Ca8KWK5_.js';
|
|
4
5
|
import 'node:http';
|
|
@@ -390,6 +390,35 @@ function helmet() {
|
|
|
390
390
|
return next();
|
|
391
391
|
};
|
|
392
392
|
}
|
|
393
|
+
function validate(schema) {
|
|
394
|
+
return async (ctx, next) => {
|
|
395
|
+
const data = await ctx.request.body();
|
|
396
|
+
const result = schema.safeParse(data);
|
|
397
|
+
if (!result.success) {
|
|
398
|
+
ctx.response.status(422).json({
|
|
399
|
+
error: "VALIDATION_ERROR",
|
|
400
|
+
message: result.error
|
|
401
|
+
});
|
|
402
|
+
return;
|
|
403
|
+
}
|
|
404
|
+
ctx.validated = result.data;
|
|
405
|
+
return next();
|
|
406
|
+
};
|
|
407
|
+
}
|
|
408
|
+
function validateQuery(schema) {
|
|
409
|
+
return async (ctx, next) => {
|
|
410
|
+
const result = schema.safeParse(ctx.request.query);
|
|
411
|
+
if (!result.success) {
|
|
412
|
+
ctx.response.status(422).json({
|
|
413
|
+
error: "VALIDATION_ERROR",
|
|
414
|
+
message: result.error
|
|
415
|
+
});
|
|
416
|
+
return;
|
|
417
|
+
}
|
|
418
|
+
ctx.validatedQuery = result.data;
|
|
419
|
+
return next();
|
|
420
|
+
};
|
|
421
|
+
}
|
|
393
422
|
var MiddlewarePipeline = class {
|
|
394
423
|
middlewares = [];
|
|
395
424
|
use(middleware) {
|
|
@@ -431,6 +460,8 @@ export {
|
|
|
431
460
|
logger,
|
|
432
461
|
session,
|
|
433
462
|
staticFiles,
|
|
434
|
-
throttle
|
|
463
|
+
throttle,
|
|
464
|
+
validate,
|
|
465
|
+
validateQuery
|
|
435
466
|
};
|
|
436
467
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/server/middleware/index.ts","../../../src/server/http/status.ts"],"sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport { createReadStream, existsSync, statSync } from \"node:fs\";\nimport { extname, join, resolve } from \"node:path\";\nimport { gzipSync } from \"node:zlib\";\nimport { HttpStatus } from \"../http/status\";\nimport type { RouteContext } from \"../router\";\n\nexport type Middleware = (\n\tctx: RouteContext,\n\tnext: () => Promise<void>,\n) => void | Promise<void>;\n\nexport interface CorsOptions {\n\torigin?: string | string[];\n\tmethods?: string[];\n\tallowedHeaders?: string[];\n\texposedHeaders?: string[];\n\tcredentials?: boolean;\n\tmaxAge?: number;\n}\n\nexport function cors(options?: CorsOptions): Middleware {\n\tconst opts: Required<CorsOptions> = {\n\t\torigin: \"*\",\n\t\tmethods: [\"GET\", \"POST\", \"PUT\", \"PATCH\", \"DELETE\", \"OPTIONS\"],\n\t\tallowedHeaders: [\"Content-Type\", \"Authorization\"],\n\t\texposedHeaders: [],\n\t\tcredentials: false,\n\t\tmaxAge: 86400,\n\t\t...options,\n\t};\n\n\treturn (ctx: RouteContext, next: () => Promise<void>) => {\n\t\tconst { request, response } = ctx;\n\t\tconst origin = request.headers.get(\"origin\");\n\n\t\tif (origin !== undefined) {\n\t\t\tif (opts.origin === \"*\") {\n\t\t\t\tresponse.header(\"access-control-allow-origin\", \"*\");\n\t\t\t} else if (typeof opts.origin === \"string\") {\n\t\t\t\tresponse.header(\"access-control-allow-origin\", opts.origin);\n\t\t\t} else if (opts.origin.includes(origin)) {\n\t\t\t\tresponse.header(\"access-control-allow-origin\", origin);\n\t\t\t}\n\n\t\t\tif (opts.credentials) {\n\t\t\t\tresponse.header(\"access-control-allow-credentials\", \"true\");\n\t\t\t}\n\n\t\t\tif (opts.exposedHeaders.length > 0) {\n\t\t\t\tresponse.header(\n\t\t\t\t\t\"access-control-expose-headers\",\n\t\t\t\t\topts.exposedHeaders.join(\", \"),\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tif (request.method === \"OPTIONS\") {\n\t\t\tresponse.header(\"access-control-allow-methods\", opts.methods.join(\", \"));\n\t\t\tresponse.header(\n\t\t\t\t\"access-control-allow-headers\",\n\t\t\t\topts.allowedHeaders.join(\", \"),\n\t\t\t);\n\t\t\tresponse.header(\"access-control-max-age\", String(opts.maxAge));\n\t\t\tresponse.status(HttpStatus.NO_CONTENT);\n\t\t\treturn;\n\t\t}\n\n\t\treturn next();\n\t};\n}\n\nexport function bodyParser(): Middleware {\n\treturn async (ctx: RouteContext, next: () => Promise<void>) => {\n\t\tconst { request } = ctx;\n\t\tconst method = request.method;\n\n\t\tif ([\"POST\", \"PUT\", \"PATCH\", \"DELETE\"].includes(method)) {\n\t\t\tawait request.body();\n\t\t}\n\n\t\treturn next();\n\t};\n}\n\nexport interface SessionOptions {\n\tname?: string;\n\tsecret?: string;\n\tmaxAge?: number;\n\thttpOnly?: boolean;\n\tsecure?: boolean;\n\tsameSite?: \"strict\" | \"lax\" | \"none\";\n}\n\nexport function session(options?: SessionOptions): Middleware {\n\tconst opts = {\n\t\tname: \"speexjs_session\",\n\t\tsecret: options?.secret ?? (process.env.NODE_ENV === 'production' \n ? (() => { throw new Error('Session secret must be configured in production via secret option or SESSION_SECRET env var') })() \n : 'speexjs-dev-secret'),\n\t\tmaxAge: 7200,\n\t\thttpOnly: true,\n\t\tsecure: false,\n\t\tsameSite: \"lax\" as const,\n\t\t...options,\n\t};\n\n\tinterface SessionEntry {\n\t\tdata: Record<string, unknown>;\n\t\tcreatedAt: number;\n\t}\n\tconst sessions = new Map<string, SessionEntry>();\n\tconst SESSION_TTL = (opts.maxAge || 7200) * 1000;\n\n\tfunction generateSessionId(): string {\n\t\treturn randomUUID();\n\t}\n\n\treturn (ctx: RouteContext, next: () => Promise<void>) => {\n\t\tconst { request, response } = ctx;\n\t\tconst sessionId = request.cookie(opts.name) ?? generateSessionId();\n\t\tconst id = sessionId;\n\n\t\t// Clean expired sessions periodically (every 100 requests)\n\t\tif (Math.random() < 0.01) {\n\t\t\tconst now = Date.now();\n\t\t\tfor (const [key, entry] of sessions) {\n\t\t\t\tif (now - entry.createdAt > SESSION_TTL) {\n\t\t\t\t\tsessions.delete(key);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Check if existing session is expired\n\t\tconst existing = sessions.get(id);\n\t\tif (existing && (Date.now() - existing.createdAt > SESSION_TTL)) {\n\t\t\tsessions.delete(id);\n\t\t}\n\n\t\tif (!sessions.has(id)) {\n\t\t\tsessions.set(id, { data: {}, createdAt: Date.now() });\n\t\t}\n\t\tconst sessionData = sessions.get(id)!.data;\n\n\t\t(ctx as unknown as Record<string, unknown>).session = sessionData;\n\n\t\tif (request.cookie(opts.name) === undefined) {\n\t\t\tresponse.cookie(opts.name, id, {\n\t\t\t\tmaxAge: opts.maxAge,\n\t\t\t\thttpOnly: opts.httpOnly,\n\t\t\t\tsecure: opts.secure,\n\t\t\t\tsameSite: opts.sameSite,\n\t\t\t\tpath: \"/\",\n\t\t\t});\n\t\t}\n\n\t\treturn next();\n\t};\n}\n\nexport function auth(guard?: string): Middleware {\n\tconst guardName = guard ?? \"default\";\n\n\treturn (ctx: RouteContext, next: () => Promise<void>) => {\n\t\tconst user = ctx.container.resolve(`auth.${guardName}`);\n\n\t\tif (user === undefined || user === null) {\n\t\t\tif (ctx.request.wantsJson()) {\n\t\t\t\tctx.response.status(HttpStatus.UNAUTHORIZED).json({\n\t\t\t\t\terror: \"Unauthenticated\",\n\t\t\t\t\tmessage: \"Authentication is required to access this resource\",\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tctx.response.redirect(\"/login\", HttpStatus.FOUND as 302);\n\t\t\treturn;\n\t\t}\n\n\t\t(ctx as unknown as Record<string, unknown>).user = user;\n\n\t\treturn next();\n\t};\n}\n\nexport function throttle(limit?: number, window?: number): Middleware {\n\tconst maxRequests = limit ?? 60;\n\tconst timeWindow = (window ?? 60) * 1000;\n\tconst hits = new Map<string, { count: number; resetAt: number }>();\n\n\tconst cleanup = setInterval(() => {\n\t\tconst now = Date.now();\n\t\tfor (const [key, value] of hits) {\n\t\t\tif (value.resetAt < now) {\n\t\t\t\thits.delete(key);\n\t\t\t}\n\t\t}\n\t}, 60000);\n\n\tif (cleanup.unref !== undefined) {\n\t\tcleanup.unref();\n\t}\n\n\treturn (ctx: RouteContext, next: () => Promise<void>) => {\n\t\tconst key = ctx.request.ip;\n\n\t\tconst now = Date.now();\n\t\tconst hit = hits.get(key);\n\n\t\tif (hit === undefined || hit.resetAt < now) {\n\t\t\thits.set(key, { count: 1, resetAt: now + timeWindow });\n\t\t\tctx.response.header(\"x-ratelimit-limit\", String(maxRequests));\n\t\t\tctx.response.header(\"x-ratelimit-remaining\", String(maxRequests - 1));\n\t\t\treturn next();\n\t\t}\n\n\t\thit.count++;\n\t\tconst remaining = Math.max(0, maxRequests - hit.count);\n\t\tctx.response.header(\"x-ratelimit-limit\", String(maxRequests));\n\t\tctx.response.header(\"x-ratelimit-remaining\", String(remaining));\n\n\t\tif (hit.count > maxRequests) {\n\t\t\tconst retryAfter = Math.ceil((hit.resetAt - now) / 1000);\n\t\t\tctx.response.header(\"retry-after\", String(retryAfter));\n\t\t\tctx.response.status(HttpStatus.TOO_MANY_REQUESTS).json({\n\t\t\t\terror: \"Too Many Requests\",\n\t\t\t\tmessage: `Rate limit exceeded. Try again in ${retryAfter} seconds.`,\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\n\t\treturn next();\n\t};\n}\n\nexport function logger(): Middleware {\n\treturn (ctx: RouteContext, next: () => Promise<void>) => {\n\t\tconst start = Date.now();\n\t\tconst { method, path, ip } = ctx.request;\n\n\t\tconst result = next();\n\n\t\tif (result instanceof Promise) {\n\t\t\treturn result.then(() => {\n\t\t\t\tconst duration = Date.now() - start;\n\t\t\t\tconst status = ctx.response.statusCode;\n\t\t\t\tconsole.log(\n\t\t\t\t\t`[${new Date().toISOString()}] ${method} ${path} ${status} ${duration}ms - ${ip}`,\n\t\t\t\t);\n\t\t\t});\n\t\t}\n\n\t\tconst duration = Date.now() - start;\n\t\tconst status = ctx.response.statusCode;\n\t\tconsole.log(\n\t\t\t`[${new Date().toISOString()}] ${method} ${path} ${status} ${duration}ms - ${ip}`,\n\t\t);\n\t};\n}\n\nexport interface StaticOptions {\n\tmaxAge?: number;\n\tindex?: string;\n\tdotfiles?: \"allow\" | \"deny\";\n\textensions?: string[];\n}\n\nexport function staticFiles(root: string, options?: StaticOptions): Middleware {\n\tconst opts = {\n\t\tmaxAge: 0,\n\t\tindex: \"index.html\",\n\t\tdotfiles: \"deny\" as const,\n\t\textensions: [] as string[],\n\t\t...options,\n\t};\n\n\tconst MIME_TYPES: Record<string, string> = {\n\t\t\".html\": \"text/html\",\n\t\t\".css\": \"text/css\",\n\t\t\".js\": \"application/javascript\",\n\t\t\".json\": \"application/json\",\n\t\t\".png\": \"image/png\",\n\t\t\".jpg\": \"image/jpeg\",\n\t\t\".jpeg\": \"image/jpeg\",\n\t\t\".gif\": \"image/gif\",\n\t\t\".svg\": \"image/svg+xml\",\n\t\t\".webp\": \"image/webp\",\n\t\t\".ico\": \"image/x-icon\",\n\t\t\".txt\": \"text/plain\",\n\t\t\".pdf\": \"application/pdf\",\n\t\t\".woff\": \"font/woff\",\n\t\t\".woff2\": \"font/woff2\",\n\t\t\".ttf\": \"font/ttf\",\n\t};\n\n\treturn (ctx: RouteContext, next: () => Promise<void>) => {\n\t\tconst { request, response } = ctx;\n\t\tconst filePath = request.path;\n\n\t\tif (opts.dotfiles === \"deny\") {\n\t\t\tconst segments = filePath.split(\"/\");\n\t\t\tfor (const segment of segments) {\n\t\t\t\tif (segment.startsWith(\".\")) {\n\t\t\t\t\treturn next();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tlet fullPath = join(root, filePath);\n\n\t\t// Path traversal protection\n\t\tconst resolvedRoot = resolve(root);\n\t\tconst resolvedPath = resolve(fullPath);\n\t\tif (!resolvedPath.startsWith(resolvedRoot)) {\n\t\t\treturn next();\n\t\t}\n\n\t\tif (!existsSync(fullPath)) {\n\t\t\tlet found = false;\n\t\t\tfor (const ext of opts.extensions) {\n\t\t\t\tconst tryPath = fullPath + ext;\n\t\t\t\tif (existsSync(tryPath)) {\n\t\t\t\t\tfullPath = tryPath;\n\t\t\t\t\tfound = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!found) return next();\n\t\t}\n\n\t\tconst stats = statSync(fullPath);\n\t\tif (!stats.isFile()) {\n\t\t\tif (stats.isDirectory()) {\n\t\t\t\tconst indexPath = join(fullPath, opts.index);\n\t\t\t\tif (existsSync(indexPath) && statSync(indexPath).isFile()) {\n\t\t\t\t\tfullPath = indexPath;\n\t\t\t\t} else {\n\t\t\t\t\treturn next();\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\treturn next();\n\t\t\t}\n\t\t}\n\n\t\tconst ext = extname(fullPath);\n\t\tconst mimeType = MIME_TYPES[ext] ?? \"application/octet-stream\";\n\n\t\tresponse\n\t\t\t.header(\"content-type\", mimeType)\n\t\t\t.header(\"content-length\", String(stats.size))\n\t\t\t.header(\"cache-control\", `public, max-age=${opts.maxAge}`)\n\t\t\t.header(\"last-modified\", stats.mtime.toUTCString());\n\n\t\tconst readStream = createReadStream(fullPath);\n\t\treadStream.pipe(response.rawResponse);\n\t\tresponse.rawResponse.statusCode = HttpStatus.OK;\n\n\t\treturn new Promise<void>((resolve, reject) => {\n\t\t\treadStream.on(\"end\", () => resolve());\n\t\t\treadStream.on(\"error\", (err: Error) => reject(err));\n\t\t});\n\t};\n}\n\nexport function csrf(): Middleware {\n\tconst tokens = new Map<string, number>(); // token → expiresAt\n\tconst MAX_TOKENS = 10000;\n\tconst TTL = 60 * 60 * 1000; // 1 hour\n\n\tfunction generateToken(): string {\n\t\t// Cleanup expired tokens\n\t\tconst now = Date.now();\n\t\tfor (const [token, expiresAt] of tokens) {\n\t\t\tif (expiresAt < now) tokens.delete(token);\n\t\t}\n\t\t// Enforce max size\n\t\tif (tokens.size >= MAX_TOKENS) {\n\t\t\tconst oldest = tokens.entries().next().value;\n\t\t\tif (oldest) tokens.delete(oldest[0]);\n\t\t}\n\t\tconst token = randomUUID();\n\t\ttokens.set(token, now + TTL);\n\t\treturn token;\n\t}\n\n\tfunction skipCsrf(method: string): boolean {\n\t\treturn [\"GET\", \"HEAD\", \"OPTIONS\"].includes(method.toUpperCase());\n\t}\n\n\treturn (ctx: RouteContext, next: () => Promise<void>) => {\n\t\tconst { request, response } = ctx;\n\n\t\tif (request.path === \"/csrf-token\") {\n\t\t\tconst token = generateToken();\n\t\t\tresponse.json({ token });\n\t\t\treturn;\n\t\t}\n\n\t\tif (skipCsrf(request.method)) {\n\t\t\treturn next();\n\t\t}\n\n\t\tconst token =\n\t\t\trequest.headers.get(\"x-csrf-token\") ??\n\t\t\trequest.headers.get(\"x-xsrf-token\");\n\n\t\tif (token === undefined || !tokens.has(token)) {\n\t\t\tresponse.status(HttpStatus.FORBIDDEN).json({\n\t\t\t\terror: \"CSRF token mismatch\",\n\t\t\t\tmessage: \"Invalid or missing CSRF token\",\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\n\t\ttokens.delete(token);\n\n\t\treturn next();\n\t};\n}\n\nexport function compress(): Middleware {\n\treturn (ctx: RouteContext, next: () => Promise<void>) => {\n\t\tconst { request } = ctx;\n\t\tconst acceptEncoding = request.headers.get(\"accept-encoding\") ?? \"\";\n\n\t\tif (acceptEncoding.includes(\"gzip\")) {\n\t\t\treturn compressWith(ctx, next, \"gzip\");\n\t\t}\n\n\t\treturn next();\n\t};\n}\n\nfunction compressWith(\n\tctx: RouteContext,\n\tnext: () => Promise<void>,\n\t_encoding: string,\n): Promise<void> {\n\t(ctx.response as any).send = function(body: string | Buffer, status?: number, contentType?: string) {\n\t\tif (status !== undefined) this._statusCode = status;\n\t\tthis._body = body;\n\t\tif (contentType !== undefined && !this._contentTypeSet) {\n\t\t\tthis._headers.set(\"content-type\", contentType);\n\t\t}\n\t\tconst input = Buffer.isBuffer(body) ? body : Buffer.from(String(body));\n\t\tconst compressed = gzipSync(input);\n\n\t\tthis._headers.set(\"content-encoding\", \"gzip\");\n\t\tthis._headers.set(\"content-length\", String(compressed.length));\n\t\tthis._body = compressed;\n\t\treturn this;\n\t};\n\n\treturn next();\n}\n\nexport function helmet(): Middleware {\n\treturn (ctx: RouteContext, next: () => Promise<void>) => {\n\t\tconst { response } = ctx;\n\n\t\tresponse\n\t\t\t.header(\"x-content-type-options\", \"nosniff\")\n\t\t\t.header(\"x-frame-options\", \"SAMEORIGIN\")\n\t\t\t.header(\"x-xss-protection\", \"1; mode=block\")\n\t\t\t.header(\n\t\t\t\t\"strict-transport-security\",\n\t\t\t\t\"max-age=15552000; includeSubDomains\",\n\t\t\t)\n\t\t\t.header(\"referrer-policy\", \"no-referrer-when-downgrade\")\n\t\t\t.header(\n\t\t\t\t\"content-security-policy\",\n\t\t\t\t\"default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'\",\n\t\t\t)\n\t\t\t.header(\"permissions-policy\", \"camera=(), microphone=(), geolocation=()\");\n\n\t\treturn next();\n\t};\n}\n\nexport class MiddlewarePipeline {\n\tprivate middlewares: Middleware[] = [];\n\n\tuse(middleware: Middleware): this {\n\t\tthis.middlewares.push(middleware);\n\t\treturn this;\n\t}\n\n\tprepend(middleware: Middleware): this {\n\t\tthis.middlewares.unshift(middleware);\n\t\treturn this;\n\t}\n\n\tremove(name: string): void {\n\t\tthis.middlewares = this.middlewares.filter((mw) => mw.name !== name);\n\t}\n\n\tasync run(ctx: RouteContext, final: () => Promise<void>): Promise<void> {\n\t\tlet index = 0;\n\n\t\tconst next = async (): Promise<void> => {\n\t\t\tif (index >= this.middlewares.length) {\n\t\t\t\tawait final();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst middleware = this.middlewares[index] as Middleware;\n\t\t\tindex++;\n\t\t\tawait middleware(ctx, next);\n\t\t};\n\n\t\tawait next();\n\t}\n\n\tgetMiddlewares(): Middleware[] {\n\t\treturn [...this.middlewares];\n\t}\n}\n","export const HttpStatus = {\n OK: 200,\n CREATED: 201,\n ACCEPTED: 202,\n NO_CONTENT: 204,\n RESET_CONTENT: 205,\n PARTIAL_CONTENT: 206,\n\n MOVED_PERMANENTLY: 301,\n FOUND: 302,\n SEE_OTHER: 303,\n NOT_MODIFIED: 304,\n TEMPORARY_REDIRECT: 307,\n PERMANENT_REDIRECT: 308,\n\n BAD_REQUEST: 400,\n UNAUTHORIZED: 401,\n PAYMENT_REQUIRED: 402,\n FORBIDDEN: 403,\n NOT_FOUND: 404,\n METHOD_NOT_ALLOWED: 405,\n NOT_ACCEPTABLE: 406,\n REQUEST_TIMEOUT: 408,\n CONFLICT: 409,\n GONE: 410,\n LENGTH_REQUIRED: 411,\n PRECONDITION_FAILED: 412,\n PAYLOAD_TOO_LARGE: 413,\n URI_TOO_LONG: 414,\n UNSUPPORTED_MEDIA_TYPE: 415,\n UNPROCESSABLE_ENTITY: 422,\n TOO_MANY_REQUESTS: 429,\n\n INTERNAL_SERVER_ERROR: 500,\n NOT_IMPLEMENTED: 501,\n BAD_GATEWAY: 502,\n SERVICE_UNAVAILABLE: 503,\n GATEWAY_TIMEOUT: 504,\n HTTP_VERSION_NOT_SUPPORTED: 505,\n} as const\n\nexport type HttpStatusCode = (typeof HttpStatus)[keyof typeof HttpStatus]\n\nconst statusTextMap: Record<number, string> = {\n 200: 'OK',\n 201: 'Created',\n 202: 'Accepted',\n 204: 'No Content',\n 205: 'Reset Content',\n 206: 'Partial Content',\n 301: 'Moved Permanently',\n 302: 'Found',\n 303: 'See Other',\n 304: 'Not Modified',\n 307: 'Temporary Redirect',\n 308: 'Permanent Redirect',\n 400: 'Bad Request',\n 401: 'Unauthorized',\n 402: 'Payment Required',\n 403: 'Forbidden',\n 404: 'Not Found',\n 405: 'Method Not Allowed',\n 406: 'Not Acceptable',\n 408: 'Request Timeout',\n 409: 'Conflict',\n 410: 'Gone',\n 411: 'Length Required',\n 412: 'Precondition Failed',\n 413: 'Payload Too Large',\n 414: 'URI Too Long',\n 415: 'Unsupported Media Type',\n 422: 'Unprocessable Entity',\n 429: 'Too Many Requests',\n 500: 'Internal Server Error',\n 501: 'Not Implemented',\n 502: 'Bad Gateway',\n 503: 'Service Unavailable',\n 504: 'Gateway Timeout',\n 505: 'HTTP Version Not Supported',\n}\n\nexport function statusText(code: number): string {\n const text = statusTextMap[code]\n if (text !== undefined) return text\n if (code >= 100 && code < 200) return 'Informational'\n if (code >= 200 && code < 300) return 'Success'\n if (code >= 300 && code < 400) return 'Redirection'\n if (code >= 400 && code < 500) return 'Client Error'\n if (code >= 500 && code < 600) return 'Server Error'\n return 'Unknown'\n}\n"],"mappings":";AAAA,SAAS,kBAAkB;AAC3B,SAAS,kBAAkB,YAAY,gBAAgB;AACvD,SAAS,SAAS,MAAM,eAAe;AACvC,SAAS,gBAAgB;;;ACHlB,IAAM,aAAa;AAAA,EACxB,IAAI;AAAA,EACJ,SAAS;AAAA,EACT,UAAU;AAAA,EACV,YAAY;AAAA,EACZ,eAAe;AAAA,EACf,iBAAiB;AAAA,EAEjB,mBAAmB;AAAA,EACnB,OAAO;AAAA,EACP,WAAW;AAAA,EACX,cAAc;AAAA,EACd,oBAAoB;AAAA,EACpB,oBAAoB;AAAA,EAEpB,aAAa;AAAA,EACb,cAAc;AAAA,EACd,kBAAkB;AAAA,EAClB,WAAW;AAAA,EACX,WAAW;AAAA,EACX,oBAAoB;AAAA,EACpB,gBAAgB;AAAA,EAChB,iBAAiB;AAAA,EACjB,UAAU;AAAA,EACV,MAAM;AAAA,EACN,iBAAiB;AAAA,EACjB,qBAAqB;AAAA,EACrB,mBAAmB;AAAA,EACnB,cAAc;AAAA,EACd,wBAAwB;AAAA,EACxB,sBAAsB;AAAA,EACtB,mBAAmB;AAAA,EAEnB,uBAAuB;AAAA,EACvB,iBAAiB;AAAA,EACjB,aAAa;AAAA,EACb,qBAAqB;AAAA,EACrB,iBAAiB;AAAA,EACjB,4BAA4B;AAC9B;;;ADlBO,SAAS,KAAK,SAAmC;AACvD,QAAM,OAA8B;AAAA,IACnC,QAAQ;AAAA,IACR,SAAS,CAAC,OAAO,QAAQ,OAAO,SAAS,UAAU,SAAS;AAAA,IAC5D,gBAAgB,CAAC,gBAAgB,eAAe;AAAA,IAChD,gBAAgB,CAAC;AAAA,IACjB,aAAa;AAAA,IACb,QAAQ;AAAA,IACR,GAAG;AAAA,EACJ;AAEA,SAAO,CAAC,KAAmB,SAA8B;AACxD,UAAM,EAAE,SAAS,SAAS,IAAI;AAC9B,UAAM,SAAS,QAAQ,QAAQ,IAAI,QAAQ;AAE3C,QAAI,WAAW,QAAW;AACzB,UAAI,KAAK,WAAW,KAAK;AACxB,iBAAS,OAAO,+BAA+B,GAAG;AAAA,MACnD,WAAW,OAAO,KAAK,WAAW,UAAU;AAC3C,iBAAS,OAAO,+BAA+B,KAAK,MAAM;AAAA,MAC3D,WAAW,KAAK,OAAO,SAAS,MAAM,GAAG;AACxC,iBAAS,OAAO,+BAA+B,MAAM;AAAA,MACtD;AAEA,UAAI,KAAK,aAAa;AACrB,iBAAS,OAAO,oCAAoC,MAAM;AAAA,MAC3D;AAEA,UAAI,KAAK,eAAe,SAAS,GAAG;AACnC,iBAAS;AAAA,UACR;AAAA,UACA,KAAK,eAAe,KAAK,IAAI;AAAA,QAC9B;AAAA,MACD;AAAA,IACD;AAEA,QAAI,QAAQ,WAAW,WAAW;AACjC,eAAS,OAAO,gCAAgC,KAAK,QAAQ,KAAK,IAAI,CAAC;AACvE,eAAS;AAAA,QACR;AAAA,QACA,KAAK,eAAe,KAAK,IAAI;AAAA,MAC9B;AACA,eAAS,OAAO,0BAA0B,OAAO,KAAK,MAAM,CAAC;AAC7D,eAAS,OAAO,WAAW,UAAU;AACrC;AAAA,IACD;AAEA,WAAO,KAAK;AAAA,EACb;AACD;AAEO,SAAS,aAAyB;AACxC,SAAO,OAAO,KAAmB,SAA8B;AAC9D,UAAM,EAAE,QAAQ,IAAI;AACpB,UAAM,SAAS,QAAQ;AAEvB,QAAI,CAAC,QAAQ,OAAO,SAAS,QAAQ,EAAE,SAAS,MAAM,GAAG;AACxD,YAAM,QAAQ,KAAK;AAAA,IACpB;AAEA,WAAO,KAAK;AAAA,EACb;AACD;AAWO,SAAS,QAAQ,SAAsC;AAC7D,QAAM,OAAO;AAAA,IACZ,MAAM;AAAA,IACN,QAAQ,SAAS,WAAW,QAAQ,IAAI,aAAa,gBAChD,MAAM;AAAE,YAAM,IAAI,MAAM,6FAA6F;AAAA,IAAE,GAAG,IAC3H;AAAA,IACJ,QAAQ;AAAA,IACR,UAAU;AAAA,IACV,QAAQ;AAAA,IACR,UAAU;AAAA,IACV,GAAG;AAAA,EACJ;AAMA,QAAM,WAAW,oBAAI,IAA0B;AAC/C,QAAM,eAAe,KAAK,UAAU,QAAQ;AAE5C,WAAS,oBAA4B;AACpC,WAAO,WAAW;AAAA,EACnB;AAEA,SAAO,CAAC,KAAmB,SAA8B;AACxD,UAAM,EAAE,SAAS,SAAS,IAAI;AAC9B,UAAM,YAAY,QAAQ,OAAO,KAAK,IAAI,KAAK,kBAAkB;AACjE,UAAM,KAAK;AAGX,QAAI,KAAK,OAAO,IAAI,MAAM;AACzB,YAAM,MAAM,KAAK,IAAI;AACrB,iBAAW,CAAC,KAAK,KAAK,KAAK,UAAU;AACpC,YAAI,MAAM,MAAM,YAAY,aAAa;AACxC,mBAAS,OAAO,GAAG;AAAA,QACpB;AAAA,MACD;AAAA,IACD;AAGA,UAAM,WAAW,SAAS,IAAI,EAAE;AAChC,QAAI,YAAa,KAAK,IAAI,IAAI,SAAS,YAAY,aAAc;AAChE,eAAS,OAAO,EAAE;AAAA,IACnB;AAEA,QAAI,CAAC,SAAS,IAAI,EAAE,GAAG;AACtB,eAAS,IAAI,IAAI,EAAE,MAAM,CAAC,GAAG,WAAW,KAAK,IAAI,EAAE,CAAC;AAAA,IACrD;AACA,UAAM,cAAc,SAAS,IAAI,EAAE,EAAG;AAEtC,IAAC,IAA2C,UAAU;AAEtD,QAAI,QAAQ,OAAO,KAAK,IAAI,MAAM,QAAW;AAC5C,eAAS,OAAO,KAAK,MAAM,IAAI;AAAA,QAC9B,QAAQ,KAAK;AAAA,QACb,UAAU,KAAK;AAAA,QACf,QAAQ,KAAK;AAAA,QACb,UAAU,KAAK;AAAA,QACf,MAAM;AAAA,MACP,CAAC;AAAA,IACF;AAEA,WAAO,KAAK;AAAA,EACb;AACD;AAEO,SAAS,KAAK,OAA4B;AAChD,QAAM,YAAY,SAAS;AAE3B,SAAO,CAAC,KAAmB,SAA8B;AACxD,UAAM,OAAO,IAAI,UAAU,QAAQ,QAAQ,SAAS,EAAE;AAEtD,QAAI,SAAS,UAAa,SAAS,MAAM;AACxC,UAAI,IAAI,QAAQ,UAAU,GAAG;AAC5B,YAAI,SAAS,OAAO,WAAW,YAAY,EAAE,KAAK;AAAA,UACjD,OAAO;AAAA,UACP,SAAS;AAAA,QACV,CAAC;AACD;AAAA,MACD;AAEA,UAAI,SAAS,SAAS,UAAU,WAAW,KAAY;AACvD;AAAA,IACD;AAEA,IAAC,IAA2C,OAAO;AAEnD,WAAO,KAAK;AAAA,EACb;AACD;AAEO,SAAS,SAAS,OAAgB,QAA6B;AACrE,QAAM,cAAc,SAAS;AAC7B,QAAM,cAAc,UAAU,MAAM;AACpC,QAAM,OAAO,oBAAI,IAAgD;AAEjE,QAAM,UAAU,YAAY,MAAM;AACjC,UAAM,MAAM,KAAK,IAAI;AACrB,eAAW,CAAC,KAAK,KAAK,KAAK,MAAM;AAChC,UAAI,MAAM,UAAU,KAAK;AACxB,aAAK,OAAO,GAAG;AAAA,MAChB;AAAA,IACD;AAAA,EACD,GAAG,GAAK;AAER,MAAI,QAAQ,UAAU,QAAW;AAChC,YAAQ,MAAM;AAAA,EACf;AAEA,SAAO,CAAC,KAAmB,SAA8B;AACxD,UAAM,MAAM,IAAI,QAAQ;AAExB,UAAM,MAAM,KAAK,IAAI;AACrB,UAAM,MAAM,KAAK,IAAI,GAAG;AAExB,QAAI,QAAQ,UAAa,IAAI,UAAU,KAAK;AAC3C,WAAK,IAAI,KAAK,EAAE,OAAO,GAAG,SAAS,MAAM,WAAW,CAAC;AACrD,UAAI,SAAS,OAAO,qBAAqB,OAAO,WAAW,CAAC;AAC5D,UAAI,SAAS,OAAO,yBAAyB,OAAO,cAAc,CAAC,CAAC;AACpE,aAAO,KAAK;AAAA,IACb;AAEA,QAAI;AACJ,UAAM,YAAY,KAAK,IAAI,GAAG,cAAc,IAAI,KAAK;AACrD,QAAI,SAAS,OAAO,qBAAqB,OAAO,WAAW,CAAC;AAC5D,QAAI,SAAS,OAAO,yBAAyB,OAAO,SAAS,CAAC;AAE9D,QAAI,IAAI,QAAQ,aAAa;AAC5B,YAAM,aAAa,KAAK,MAAM,IAAI,UAAU,OAAO,GAAI;AACvD,UAAI,SAAS,OAAO,eAAe,OAAO,UAAU,CAAC;AACrD,UAAI,SAAS,OAAO,WAAW,iBAAiB,EAAE,KAAK;AAAA,QACtD,OAAO;AAAA,QACP,SAAS,qCAAqC,UAAU;AAAA,MACzD,CAAC;AACD;AAAA,IACD;AAEA,WAAO,KAAK;AAAA,EACb;AACD;AAEO,SAAS,SAAqB;AACpC,SAAO,CAAC,KAAmB,SAA8B;AACxD,UAAM,QAAQ,KAAK,IAAI;AACvB,UAAM,EAAE,QAAQ,MAAM,GAAG,IAAI,IAAI;AAEjC,UAAM,SAAS,KAAK;AAEpB,QAAI,kBAAkB,SAAS;AAC9B,aAAO,OAAO,KAAK,MAAM;AACxB,cAAMA,YAAW,KAAK,IAAI,IAAI;AAC9B,cAAMC,UAAS,IAAI,SAAS;AAC5B,gBAAQ;AAAA,UACP,KAAI,oBAAI,KAAK,GAAE,YAAY,CAAC,KAAK,MAAM,IAAI,IAAI,IAAIA,OAAM,IAAID,SAAQ,QAAQ,EAAE;AAAA,QAChF;AAAA,MACD,CAAC;AAAA,IACF;AAEA,UAAM,WAAW,KAAK,IAAI,IAAI;AAC9B,UAAM,SAAS,IAAI,SAAS;AAC5B,YAAQ;AAAA,MACP,KAAI,oBAAI,KAAK,GAAE,YAAY,CAAC,KAAK,MAAM,IAAI,IAAI,IAAI,MAAM,IAAI,QAAQ,QAAQ,EAAE;AAAA,IAChF;AAAA,EACD;AACD;AASO,SAAS,YAAY,MAAc,SAAqC;AAC9E,QAAM,OAAO;AAAA,IACZ,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,UAAU;AAAA,IACV,YAAY,CAAC;AAAA,IACb,GAAG;AAAA,EACJ;AAEA,QAAM,aAAqC;AAAA,IAC1C,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,UAAU;AAAA,IACV,QAAQ;AAAA,EACT;AAEA,SAAO,CAAC,KAAmB,SAA8B;AACxD,UAAM,EAAE,SAAS,SAAS,IAAI;AAC9B,UAAM,WAAW,QAAQ;AAEzB,QAAI,KAAK,aAAa,QAAQ;AAC7B,YAAM,WAAW,SAAS,MAAM,GAAG;AACnC,iBAAW,WAAW,UAAU;AAC/B,YAAI,QAAQ,WAAW,GAAG,GAAG;AAC5B,iBAAO,KAAK;AAAA,QACb;AAAA,MACD;AAAA,IACD;AAEA,QAAI,WAAW,KAAK,MAAM,QAAQ;AAGlC,UAAM,eAAe,QAAQ,IAAI;AACjC,UAAM,eAAe,QAAQ,QAAQ;AACrC,QAAI,CAAC,aAAa,WAAW,YAAY,GAAG;AAC3C,aAAO,KAAK;AAAA,IACb;AAEA,QAAI,CAAC,WAAW,QAAQ,GAAG;AAC1B,UAAI,QAAQ;AACZ,iBAAWE,QAAO,KAAK,YAAY;AAClC,cAAM,UAAU,WAAWA;AAC3B,YAAI,WAAW,OAAO,GAAG;AACxB,qBAAW;AACX,kBAAQ;AACR;AAAA,QACD;AAAA,MACD;AACA,UAAI,CAAC,MAAO,QAAO,KAAK;AAAA,IACzB;AAEA,UAAM,QAAQ,SAAS,QAAQ;AAC/B,QAAI,CAAC,MAAM,OAAO,GAAG;AACpB,UAAI,MAAM,YAAY,GAAG;AACxB,cAAM,YAAY,KAAK,UAAU,KAAK,KAAK;AAC3C,YAAI,WAAW,SAAS,KAAK,SAAS,SAAS,EAAE,OAAO,GAAG;AAC1D,qBAAW;AAAA,QACZ,OAAO;AACN,iBAAO,KAAK;AAAA,QACb;AAAA,MACD,OAAO;AACN,eAAO,KAAK;AAAA,MACb;AAAA,IACD;AAEA,UAAM,MAAM,QAAQ,QAAQ;AAC5B,UAAM,WAAW,WAAW,GAAG,KAAK;AAEpC,aACE,OAAO,gBAAgB,QAAQ,EAC/B,OAAO,kBAAkB,OAAO,MAAM,IAAI,CAAC,EAC3C,OAAO,iBAAiB,mBAAmB,KAAK,MAAM,EAAE,EACxD,OAAO,iBAAiB,MAAM,MAAM,YAAY,CAAC;AAEnD,UAAM,aAAa,iBAAiB,QAAQ;AAC5C,eAAW,KAAK,SAAS,WAAW;AACpC,aAAS,YAAY,aAAa,WAAW;AAE7C,WAAO,IAAI,QAAc,CAACC,UAAS,WAAW;AAC7C,iBAAW,GAAG,OAAO,MAAMA,SAAQ,CAAC;AACpC,iBAAW,GAAG,SAAS,CAAC,QAAe,OAAO,GAAG,CAAC;AAAA,IACnD,CAAC;AAAA,EACF;AACD;AAEO,SAAS,OAAmB;AAClC,QAAM,SAAS,oBAAI,IAAoB;AACvC,QAAM,aAAa;AACnB,QAAM,MAAM,KAAK,KAAK;AAEtB,WAAS,gBAAwB;AAEhC,UAAM,MAAM,KAAK,IAAI;AACrB,eAAW,CAACC,QAAO,SAAS,KAAK,QAAQ;AACxC,UAAI,YAAY,IAAK,QAAO,OAAOA,MAAK;AAAA,IACzC;AAEA,QAAI,OAAO,QAAQ,YAAY;AAC9B,YAAM,SAAS,OAAO,QAAQ,EAAE,KAAK,EAAE;AACvC,UAAI,OAAQ,QAAO,OAAO,OAAO,CAAC,CAAC;AAAA,IACpC;AACA,UAAM,QAAQ,WAAW;AACzB,WAAO,IAAI,OAAO,MAAM,GAAG;AAC3B,WAAO;AAAA,EACR;AAEA,WAAS,SAAS,QAAyB;AAC1C,WAAO,CAAC,OAAO,QAAQ,SAAS,EAAE,SAAS,OAAO,YAAY,CAAC;AAAA,EAChE;AAEA,SAAO,CAAC,KAAmB,SAA8B;AACxD,UAAM,EAAE,SAAS,SAAS,IAAI;AAE9B,QAAI,QAAQ,SAAS,eAAe;AACnC,YAAMA,SAAQ,cAAc;AAC5B,eAAS,KAAK,EAAE,OAAAA,OAAM,CAAC;AACvB;AAAA,IACD;AAEA,QAAI,SAAS,QAAQ,MAAM,GAAG;AAC7B,aAAO,KAAK;AAAA,IACb;AAEA,UAAM,QACL,QAAQ,QAAQ,IAAI,cAAc,KAClC,QAAQ,QAAQ,IAAI,cAAc;AAEnC,QAAI,UAAU,UAAa,CAAC,OAAO,IAAI,KAAK,GAAG;AAC9C,eAAS,OAAO,WAAW,SAAS,EAAE,KAAK;AAAA,QAC1C,OAAO;AAAA,QACP,SAAS;AAAA,MACV,CAAC;AACD;AAAA,IACD;AAEA,WAAO,OAAO,KAAK;AAEnB,WAAO,KAAK;AAAA,EACb;AACD;AAEO,SAAS,WAAuB;AACtC,SAAO,CAAC,KAAmB,SAA8B;AACxD,UAAM,EAAE,QAAQ,IAAI;AACpB,UAAM,iBAAiB,QAAQ,QAAQ,IAAI,iBAAiB,KAAK;AAEjE,QAAI,eAAe,SAAS,MAAM,GAAG;AACpC,aAAO,aAAa,KAAK,MAAM,MAAM;AAAA,IACtC;AAEA,WAAO,KAAK;AAAA,EACb;AACD;AAEA,SAAS,aACR,KACA,MACA,WACgB;AAChB,EAAC,IAAI,SAAiB,OAAO,SAAS,MAAuB,QAAiB,aAAsB;AACnG,QAAI,WAAW,OAAW,MAAK,cAAc;AAC7C,SAAK,QAAQ;AACb,QAAI,gBAAgB,UAAa,CAAC,KAAK,iBAAiB;AACvD,WAAK,SAAS,IAAI,gBAAgB,WAAW;AAAA,IAC9C;AACA,UAAM,QAAQ,OAAO,SAAS,IAAI,IAAI,OAAO,OAAO,KAAK,OAAO,IAAI,CAAC;AACrE,UAAM,aAAa,SAAS,KAAK;AAEjC,SAAK,SAAS,IAAI,oBAAoB,MAAM;AAC5C,SAAK,SAAS,IAAI,kBAAkB,OAAO,WAAW,MAAM,CAAC;AAC7D,SAAK,QAAQ;AACb,WAAO;AAAA,EACR;AAEA,SAAO,KAAK;AACb;AAEO,SAAS,SAAqB;AACpC,SAAO,CAAC,KAAmB,SAA8B;AACxD,UAAM,EAAE,SAAS,IAAI;AAErB,aACE,OAAO,0BAA0B,SAAS,EAC1C,OAAO,mBAAmB,YAAY,EACtC,OAAO,oBAAoB,eAAe,EAC1C;AAAA,MACA;AAAA,MACA;AAAA,IACD,EACC,OAAO,mBAAmB,4BAA4B,EACtD;AAAA,MACA;AAAA,MACA;AAAA,IACD,EACC,OAAO,sBAAsB,0CAA0C;AAEzE,WAAO,KAAK;AAAA,EACb;AACD;AAEO,IAAM,qBAAN,MAAyB;AAAA,EACvB,cAA4B,CAAC;AAAA,EAErC,IAAI,YAA8B;AACjC,SAAK,YAAY,KAAK,UAAU;AAChC,WAAO;AAAA,EACR;AAAA,EAEA,QAAQ,YAA8B;AACrC,SAAK,YAAY,QAAQ,UAAU;AACnC,WAAO;AAAA,EACR;AAAA,EAEA,OAAO,MAAoB;AAC1B,SAAK,cAAc,KAAK,YAAY,OAAO,CAAC,OAAO,GAAG,SAAS,IAAI;AAAA,EACpE;AAAA,EAEA,MAAM,IAAI,KAAmB,OAA2C;AACvE,QAAI,QAAQ;AAEZ,UAAM,OAAO,YAA2B;AACvC,UAAI,SAAS,KAAK,YAAY,QAAQ;AACrC,cAAM,MAAM;AACZ;AAAA,MACD;AAEA,YAAM,aAAa,KAAK,YAAY,KAAK;AACzC;AACA,YAAM,WAAW,KAAK,IAAI;AAAA,IAC3B;AAEA,UAAM,KAAK;AAAA,EACZ;AAAA,EAEA,iBAA+B;AAC9B,WAAO,CAAC,GAAG,KAAK,WAAW;AAAA,EAC5B;AACD;","names":["duration","status","ext","resolve","token"]}
|
|
1
|
+
{"version":3,"sources":["../../../src/server/middleware/index.ts","../../../src/server/http/status.ts"],"sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport { createReadStream, existsSync, statSync } from \"node:fs\";\nimport { extname, join, resolve } from \"node:path\";\nimport { gzipSync } from \"node:zlib\";\nimport { HttpStatus } from \"../http/status\";\nimport type { RouteContext } from \"../router\";\nimport type { Schema } from \"../../schema/types.js\";\nexport type Middleware = (\n\tctx: RouteContext,\n\tnext: () => Promise<void>,\n) => void | Promise<void>;\n\nexport interface CorsOptions {\n\torigin?: string | string[];\n\tmethods?: string[];\n\tallowedHeaders?: string[];\n\texposedHeaders?: string[];\n\tcredentials?: boolean;\n\tmaxAge?: number;\n}\n\nexport function cors(options?: CorsOptions): Middleware {\n\tconst opts: Required<CorsOptions> = {\n\t\torigin: \"*\",\n\t\tmethods: [\"GET\", \"POST\", \"PUT\", \"PATCH\", \"DELETE\", \"OPTIONS\"],\n\t\tallowedHeaders: [\"Content-Type\", \"Authorization\"],\n\t\texposedHeaders: [],\n\t\tcredentials: false,\n\t\tmaxAge: 86400,\n\t\t...options,\n\t};\n\n\treturn (ctx: RouteContext, next: () => Promise<void>) => {\n\t\tconst { request, response } = ctx;\n\t\tconst origin = request.headers.get(\"origin\");\n\n\t\tif (origin !== undefined) {\n\t\t\tif (opts.origin === \"*\") {\n\t\t\t\tresponse.header(\"access-control-allow-origin\", \"*\");\n\t\t\t} else if (typeof opts.origin === \"string\") {\n\t\t\t\tresponse.header(\"access-control-allow-origin\", opts.origin);\n\t\t\t} else if (opts.origin.includes(origin)) {\n\t\t\t\tresponse.header(\"access-control-allow-origin\", origin);\n\t\t\t}\n\n\t\t\tif (opts.credentials) {\n\t\t\t\tresponse.header(\"access-control-allow-credentials\", \"true\");\n\t\t\t}\n\n\t\t\tif (opts.exposedHeaders.length > 0) {\n\t\t\t\tresponse.header(\n\t\t\t\t\t\"access-control-expose-headers\",\n\t\t\t\t\topts.exposedHeaders.join(\", \"),\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tif (request.method === \"OPTIONS\") {\n\t\t\tresponse.header(\"access-control-allow-methods\", opts.methods.join(\", \"));\n\t\t\tresponse.header(\n\t\t\t\t\"access-control-allow-headers\",\n\t\t\t\topts.allowedHeaders.join(\", \"),\n\t\t\t);\n\t\t\tresponse.header(\"access-control-max-age\", String(opts.maxAge));\n\t\t\tresponse.status(HttpStatus.NO_CONTENT);\n\t\t\treturn;\n\t\t}\n\n\t\treturn next();\n\t};\n}\n\nexport function bodyParser(): Middleware {\n\treturn async (ctx: RouteContext, next: () => Promise<void>) => {\n\t\tconst { request } = ctx;\n\t\tconst method = request.method;\n\n\t\tif ([\"POST\", \"PUT\", \"PATCH\", \"DELETE\"].includes(method)) {\n\t\t\tawait request.body();\n\t\t}\n\n\t\treturn next();\n\t};\n}\n\nexport interface SessionOptions {\n\tname?: string;\n\tsecret?: string;\n\tmaxAge?: number;\n\thttpOnly?: boolean;\n\tsecure?: boolean;\n\tsameSite?: \"strict\" | \"lax\" | \"none\";\n}\n\nexport function session(options?: SessionOptions): Middleware {\n\tconst opts = {\n\t\tname: \"speexjs_session\",\n\t\tsecret: options?.secret ?? (process.env.NODE_ENV === 'production' \n ? (() => { throw new Error('Session secret must be configured in production via secret option or SESSION_SECRET env var') })() \n : 'speexjs-dev-secret'),\n\t\tmaxAge: 7200,\n\t\thttpOnly: true,\n\t\tsecure: false,\n\t\tsameSite: \"lax\" as const,\n\t\t...options,\n\t};\n\n\tinterface SessionEntry {\n\t\tdata: Record<string, unknown>;\n\t\tcreatedAt: number;\n\t}\n\tconst sessions = new Map<string, SessionEntry>();\n\tconst SESSION_TTL = (opts.maxAge || 7200) * 1000;\n\n\tfunction generateSessionId(): string {\n\t\treturn randomUUID();\n\t}\n\n\treturn (ctx: RouteContext, next: () => Promise<void>) => {\n\t\tconst { request, response } = ctx;\n\t\tconst sessionId = request.cookie(opts.name) ?? generateSessionId();\n\t\tconst id = sessionId;\n\n\t\t// Clean expired sessions periodically (every 100 requests)\n\t\tif (Math.random() < 0.01) {\n\t\t\tconst now = Date.now();\n\t\t\tfor (const [key, entry] of sessions) {\n\t\t\t\tif (now - entry.createdAt > SESSION_TTL) {\n\t\t\t\t\tsessions.delete(key);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Check if existing session is expired\n\t\tconst existing = sessions.get(id);\n\t\tif (existing && (Date.now() - existing.createdAt > SESSION_TTL)) {\n\t\t\tsessions.delete(id);\n\t\t}\n\n\t\tif (!sessions.has(id)) {\n\t\t\tsessions.set(id, { data: {}, createdAt: Date.now() });\n\t\t}\n\t\tconst sessionData = sessions.get(id)!.data;\n\n\t\t(ctx as unknown as Record<string, unknown>).session = sessionData;\n\n\t\tif (request.cookie(opts.name) === undefined) {\n\t\t\tresponse.cookie(opts.name, id, {\n\t\t\t\tmaxAge: opts.maxAge,\n\t\t\t\thttpOnly: opts.httpOnly,\n\t\t\t\tsecure: opts.secure,\n\t\t\t\tsameSite: opts.sameSite,\n\t\t\t\tpath: \"/\",\n\t\t\t});\n\t\t}\n\n\t\treturn next();\n\t};\n}\n\nexport function auth(guard?: string): Middleware {\n\tconst guardName = guard ?? \"default\";\n\n\treturn (ctx: RouteContext, next: () => Promise<void>) => {\n\t\tconst user = ctx.container.resolve(`auth.${guardName}`);\n\n\t\tif (user === undefined || user === null) {\n\t\t\tif (ctx.request.wantsJson()) {\n\t\t\t\tctx.response.status(HttpStatus.UNAUTHORIZED).json({\n\t\t\t\t\terror: \"Unauthenticated\",\n\t\t\t\t\tmessage: \"Authentication is required to access this resource\",\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tctx.response.redirect(\"/login\", HttpStatus.FOUND as 302);\n\t\t\treturn;\n\t\t}\n\n\t\t(ctx as unknown as Record<string, unknown>).user = user;\n\n\t\treturn next();\n\t};\n}\n\nexport function throttle(limit?: number, window?: number): Middleware {\n\tconst maxRequests = limit ?? 60;\n\tconst timeWindow = (window ?? 60) * 1000;\n\tconst hits = new Map<string, { count: number; resetAt: number }>();\n\n\tconst cleanup = setInterval(() => {\n\t\tconst now = Date.now();\n\t\tfor (const [key, value] of hits) {\n\t\t\tif (value.resetAt < now) {\n\t\t\t\thits.delete(key);\n\t\t\t}\n\t\t}\n\t}, 60000);\n\n\tif (cleanup.unref !== undefined) {\n\t\tcleanup.unref();\n\t}\n\n\treturn (ctx: RouteContext, next: () => Promise<void>) => {\n\t\tconst key = ctx.request.ip;\n\n\t\tconst now = Date.now();\n\t\tconst hit = hits.get(key);\n\n\t\tif (hit === undefined || hit.resetAt < now) {\n\t\t\thits.set(key, { count: 1, resetAt: now + timeWindow });\n\t\t\tctx.response.header(\"x-ratelimit-limit\", String(maxRequests));\n\t\t\tctx.response.header(\"x-ratelimit-remaining\", String(maxRequests - 1));\n\t\t\treturn next();\n\t\t}\n\n\t\thit.count++;\n\t\tconst remaining = Math.max(0, maxRequests - hit.count);\n\t\tctx.response.header(\"x-ratelimit-limit\", String(maxRequests));\n\t\tctx.response.header(\"x-ratelimit-remaining\", String(remaining));\n\n\t\tif (hit.count > maxRequests) {\n\t\t\tconst retryAfter = Math.ceil((hit.resetAt - now) / 1000);\n\t\t\tctx.response.header(\"retry-after\", String(retryAfter));\n\t\t\tctx.response.status(HttpStatus.TOO_MANY_REQUESTS).json({\n\t\t\t\terror: \"Too Many Requests\",\n\t\t\t\tmessage: `Rate limit exceeded. Try again in ${retryAfter} seconds.`,\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\n\t\treturn next();\n\t};\n}\n\nexport function logger(): Middleware {\n\treturn (ctx: RouteContext, next: () => Promise<void>) => {\n\t\tconst start = Date.now();\n\t\tconst { method, path, ip } = ctx.request;\n\n\t\tconst result = next();\n\n\t\tif (result instanceof Promise) {\n\t\t\treturn result.then(() => {\n\t\t\t\tconst duration = Date.now() - start;\n\t\t\t\tconst status = ctx.response.statusCode;\n\t\t\t\tconsole.log(\n\t\t\t\t\t`[${new Date().toISOString()}] ${method} ${path} ${status} ${duration}ms - ${ip}`,\n\t\t\t\t);\n\t\t\t});\n\t\t}\n\n\t\tconst duration = Date.now() - start;\n\t\tconst status = ctx.response.statusCode;\n\t\tconsole.log(\n\t\t\t`[${new Date().toISOString()}] ${method} ${path} ${status} ${duration}ms - ${ip}`,\n\t\t);\n\t};\n}\n\nexport interface StaticOptions {\n\tmaxAge?: number;\n\tindex?: string;\n\tdotfiles?: \"allow\" | \"deny\";\n\textensions?: string[];\n}\n\nexport function staticFiles(root: string, options?: StaticOptions): Middleware {\n\tconst opts = {\n\t\tmaxAge: 0,\n\t\tindex: \"index.html\",\n\t\tdotfiles: \"deny\" as const,\n\t\textensions: [] as string[],\n\t\t...options,\n\t};\n\n\tconst MIME_TYPES: Record<string, string> = {\n\t\t\".html\": \"text/html\",\n\t\t\".css\": \"text/css\",\n\t\t\".js\": \"application/javascript\",\n\t\t\".json\": \"application/json\",\n\t\t\".png\": \"image/png\",\n\t\t\".jpg\": \"image/jpeg\",\n\t\t\".jpeg\": \"image/jpeg\",\n\t\t\".gif\": \"image/gif\",\n\t\t\".svg\": \"image/svg+xml\",\n\t\t\".webp\": \"image/webp\",\n\t\t\".ico\": \"image/x-icon\",\n\t\t\".txt\": \"text/plain\",\n\t\t\".pdf\": \"application/pdf\",\n\t\t\".woff\": \"font/woff\",\n\t\t\".woff2\": \"font/woff2\",\n\t\t\".ttf\": \"font/ttf\",\n\t};\n\n\treturn (ctx: RouteContext, next: () => Promise<void>) => {\n\t\tconst { request, response } = ctx;\n\t\tconst filePath = request.path;\n\n\t\tif (opts.dotfiles === \"deny\") {\n\t\t\tconst segments = filePath.split(\"/\");\n\t\t\tfor (const segment of segments) {\n\t\t\t\tif (segment.startsWith(\".\")) {\n\t\t\t\t\treturn next();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tlet fullPath = join(root, filePath);\n\n\t\t// Path traversal protection\n\t\tconst resolvedRoot = resolve(root);\n\t\tconst resolvedPath = resolve(fullPath);\n\t\tif (!resolvedPath.startsWith(resolvedRoot)) {\n\t\t\treturn next();\n\t\t}\n\n\t\tif (!existsSync(fullPath)) {\n\t\t\tlet found = false;\n\t\t\tfor (const ext of opts.extensions) {\n\t\t\t\tconst tryPath = fullPath + ext;\n\t\t\t\tif (existsSync(tryPath)) {\n\t\t\t\t\tfullPath = tryPath;\n\t\t\t\t\tfound = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!found) return next();\n\t\t}\n\n\t\tconst stats = statSync(fullPath);\n\t\tif (!stats.isFile()) {\n\t\t\tif (stats.isDirectory()) {\n\t\t\t\tconst indexPath = join(fullPath, opts.index);\n\t\t\t\tif (existsSync(indexPath) && statSync(indexPath).isFile()) {\n\t\t\t\t\tfullPath = indexPath;\n\t\t\t\t} else {\n\t\t\t\t\treturn next();\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\treturn next();\n\t\t\t}\n\t\t}\n\n\t\tconst ext = extname(fullPath);\n\t\tconst mimeType = MIME_TYPES[ext] ?? \"application/octet-stream\";\n\n\t\tresponse\n\t\t\t.header(\"content-type\", mimeType)\n\t\t\t.header(\"content-length\", String(stats.size))\n\t\t\t.header(\"cache-control\", `public, max-age=${opts.maxAge}`)\n\t\t\t.header(\"last-modified\", stats.mtime.toUTCString());\n\n\t\tconst readStream = createReadStream(fullPath);\n\t\treadStream.pipe(response.rawResponse);\n\t\tresponse.rawResponse.statusCode = HttpStatus.OK;\n\n\t\treturn new Promise<void>((resolve, reject) => {\n\t\t\treadStream.on(\"end\", () => resolve());\n\t\t\treadStream.on(\"error\", (err: Error) => reject(err));\n\t\t});\n\t};\n}\n\nexport function csrf(): Middleware {\n\tconst tokens = new Map<string, number>(); // token → expiresAt\n\tconst MAX_TOKENS = 10000;\n\tconst TTL = 60 * 60 * 1000; // 1 hour\n\n\tfunction generateToken(): string {\n\t\t// Cleanup expired tokens\n\t\tconst now = Date.now();\n\t\tfor (const [token, expiresAt] of tokens) {\n\t\t\tif (expiresAt < now) tokens.delete(token);\n\t\t}\n\t\t// Enforce max size\n\t\tif (tokens.size >= MAX_TOKENS) {\n\t\t\tconst oldest = tokens.entries().next().value;\n\t\t\tif (oldest) tokens.delete(oldest[0]);\n\t\t}\n\t\tconst token = randomUUID();\n\t\ttokens.set(token, now + TTL);\n\t\treturn token;\n\t}\n\n\tfunction skipCsrf(method: string): boolean {\n\t\treturn [\"GET\", \"HEAD\", \"OPTIONS\"].includes(method.toUpperCase());\n\t}\n\n\treturn (ctx: RouteContext, next: () => Promise<void>) => {\n\t\tconst { request, response } = ctx;\n\n\t\tif (request.path === \"/csrf-token\") {\n\t\t\tconst token = generateToken();\n\t\t\tresponse.json({ token });\n\t\t\treturn;\n\t\t}\n\n\t\tif (skipCsrf(request.method)) {\n\t\t\treturn next();\n\t\t}\n\n\t\tconst token =\n\t\t\trequest.headers.get(\"x-csrf-token\") ??\n\t\t\trequest.headers.get(\"x-xsrf-token\");\n\n\t\tif (token === undefined || !tokens.has(token)) {\n\t\t\tresponse.status(HttpStatus.FORBIDDEN).json({\n\t\t\t\terror: \"CSRF token mismatch\",\n\t\t\t\tmessage: \"Invalid or missing CSRF token\",\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\n\t\ttokens.delete(token);\n\n\t\treturn next();\n\t};\n}\n\nexport function compress(): Middleware {\n\treturn (ctx: RouteContext, next: () => Promise<void>) => {\n\t\tconst { request } = ctx;\n\t\tconst acceptEncoding = request.headers.get(\"accept-encoding\") ?? \"\";\n\n\t\tif (acceptEncoding.includes(\"gzip\")) {\n\t\t\treturn compressWith(ctx, next, \"gzip\");\n\t\t}\n\n\t\treturn next();\n\t};\n}\n\nfunction compressWith(\n\tctx: RouteContext,\n\tnext: () => Promise<void>,\n\t_encoding: string,\n): Promise<void> {\n\t(ctx.response as any).send = function(body: string | Buffer, status?: number, contentType?: string) {\n\t\tif (status !== undefined) this._statusCode = status;\n\t\tthis._body = body;\n\t\tif (contentType !== undefined && !this._contentTypeSet) {\n\t\t\tthis._headers.set(\"content-type\", contentType);\n\t\t}\n\t\tconst input = Buffer.isBuffer(body) ? body : Buffer.from(String(body));\n\t\tconst compressed = gzipSync(input);\n\n\t\tthis._headers.set(\"content-encoding\", \"gzip\");\n\t\tthis._headers.set(\"content-length\", String(compressed.length));\n\t\tthis._body = compressed;\n\t\treturn this;\n\t};\n\n\treturn next();\n}\n\nexport function helmet(): Middleware {\n\treturn (ctx: RouteContext, next: () => Promise<void>) => {\n\t\tconst { response } = ctx;\n\n\t\tresponse\n\t\t\t.header(\"x-content-type-options\", \"nosniff\")\n\t\t\t.header(\"x-frame-options\", \"SAMEORIGIN\")\n\t\t\t.header(\"x-xss-protection\", \"1; mode=block\")\n\t\t\t.header(\n\t\t\t\t\"strict-transport-security\",\n\t\t\t\t\"max-age=15552000; includeSubDomains\",\n\t\t\t)\n\t\t\t.header(\"referrer-policy\", \"no-referrer-when-downgrade\")\n\t\t\t.header(\n\t\t\t\t\"content-security-policy\",\n\t\t\t\t\"default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'\",\n\t\t\t)\n\t\t\t.header(\"permissions-policy\", \"camera=(), microphone=(), geolocation=()\");\n\n\t\treturn next();\n\t};\n}\n\n// ─── Request Validation Middleware ───────────────────────────\n\nexport function validate(schema: Schema<unknown>): Middleware {\n return async (ctx: RouteContext, next: () => Promise<void>) => {\n const data = await ctx.request.body()\n const result = schema.safeParse(data)\n if (!result.success) {\n ctx.response.status(422).json({\n error: 'VALIDATION_ERROR',\n message: result.error,\n })\n return\n }\n (ctx as any).validated = result.data\n return next()\n }\n}\n\nexport function validateQuery(schema: Schema<unknown>): Middleware {\n return async (ctx: RouteContext, next: () => Promise<void>) => {\n const result = schema.safeParse(ctx.request.query)\n if (!result.success) {\n ctx.response.status(422).json({\n error: 'VALIDATION_ERROR',\n message: result.error,\n })\n return\n }\n (ctx as any).validatedQuery = result.data\n return next()\n }\n}\n\nexport class MiddlewarePipeline {\n\tprivate middlewares: Middleware[] = [];\n\n\tuse(middleware: Middleware): this {\n\t\tthis.middlewares.push(middleware);\n\t\treturn this;\n\t}\n\n\tprepend(middleware: Middleware): this {\n\t\tthis.middlewares.unshift(middleware);\n\t\treturn this;\n\t}\n\n\tremove(name: string): void {\n\t\tthis.middlewares = this.middlewares.filter((mw) => mw.name !== name);\n\t}\n\n\tasync run(ctx: RouteContext, final: () => Promise<void>): Promise<void> {\n\t\tlet index = 0;\n\n\t\tconst next = async (): Promise<void> => {\n\t\t\tif (index >= this.middlewares.length) {\n\t\t\t\tawait final();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst middleware = this.middlewares[index] as Middleware;\n\t\t\tindex++;\n\t\t\tawait middleware(ctx, next);\n\t\t};\n\n\t\tawait next();\n\t}\n\n\tgetMiddlewares(): Middleware[] {\n\t\treturn [...this.middlewares];\n\t}\n}\n","export const HttpStatus = {\n OK: 200,\n CREATED: 201,\n ACCEPTED: 202,\n NO_CONTENT: 204,\n RESET_CONTENT: 205,\n PARTIAL_CONTENT: 206,\n\n MOVED_PERMANENTLY: 301,\n FOUND: 302,\n SEE_OTHER: 303,\n NOT_MODIFIED: 304,\n TEMPORARY_REDIRECT: 307,\n PERMANENT_REDIRECT: 308,\n\n BAD_REQUEST: 400,\n UNAUTHORIZED: 401,\n PAYMENT_REQUIRED: 402,\n FORBIDDEN: 403,\n NOT_FOUND: 404,\n METHOD_NOT_ALLOWED: 405,\n NOT_ACCEPTABLE: 406,\n REQUEST_TIMEOUT: 408,\n CONFLICT: 409,\n GONE: 410,\n LENGTH_REQUIRED: 411,\n PRECONDITION_FAILED: 412,\n PAYLOAD_TOO_LARGE: 413,\n URI_TOO_LONG: 414,\n UNSUPPORTED_MEDIA_TYPE: 415,\n UNPROCESSABLE_ENTITY: 422,\n TOO_MANY_REQUESTS: 429,\n\n INTERNAL_SERVER_ERROR: 500,\n NOT_IMPLEMENTED: 501,\n BAD_GATEWAY: 502,\n SERVICE_UNAVAILABLE: 503,\n GATEWAY_TIMEOUT: 504,\n HTTP_VERSION_NOT_SUPPORTED: 505,\n} as const\n\nexport type HttpStatusCode = (typeof HttpStatus)[keyof typeof HttpStatus]\n\nconst statusTextMap: Record<number, string> = {\n 200: 'OK',\n 201: 'Created',\n 202: 'Accepted',\n 204: 'No Content',\n 205: 'Reset Content',\n 206: 'Partial Content',\n 301: 'Moved Permanently',\n 302: 'Found',\n 303: 'See Other',\n 304: 'Not Modified',\n 307: 'Temporary Redirect',\n 308: 'Permanent Redirect',\n 400: 'Bad Request',\n 401: 'Unauthorized',\n 402: 'Payment Required',\n 403: 'Forbidden',\n 404: 'Not Found',\n 405: 'Method Not Allowed',\n 406: 'Not Acceptable',\n 408: 'Request Timeout',\n 409: 'Conflict',\n 410: 'Gone',\n 411: 'Length Required',\n 412: 'Precondition Failed',\n 413: 'Payload Too Large',\n 414: 'URI Too Long',\n 415: 'Unsupported Media Type',\n 422: 'Unprocessable Entity',\n 429: 'Too Many Requests',\n 500: 'Internal Server Error',\n 501: 'Not Implemented',\n 502: 'Bad Gateway',\n 503: 'Service Unavailable',\n 504: 'Gateway Timeout',\n 505: 'HTTP Version Not Supported',\n}\n\nexport function statusText(code: number): string {\n const text = statusTextMap[code]\n if (text !== undefined) return text\n if (code >= 100 && code < 200) return 'Informational'\n if (code >= 200 && code < 300) return 'Success'\n if (code >= 300 && code < 400) return 'Redirection'\n if (code >= 400 && code < 500) return 'Client Error'\n if (code >= 500 && code < 600) return 'Server Error'\n return 'Unknown'\n}\n"],"mappings":"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","names":["duration","status","ext","resolve","token"]}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import '../container/index.js';
|
|
2
2
|
import '../../response-Ca8KWK5_.js';
|
|
3
|
-
export { C as ControllerClass, c as ResolvedRoute, R as RouteContext, b as RouteHandler, a as Router } from '../../index-
|
|
3
|
+
export { C as ControllerClass, c as ResolvedRoute, R as RouteContext, b as RouteHandler, a as Router } from '../../index-C4xilc_E.js';
|
|
4
4
|
import 'node:http';
|
|
5
5
|
import 'node:stream';
|
|
6
|
+
import '../../types-aW38f63o.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/server/index.ts","../../../src/server/router/index.ts"],"sourcesContent":["import { Container } from \"./container\";\nimport { getControllerPrefix, getControllerRoutes } from \"./controller\";\nimport { NodeEngine, type ServerEngine, type ServerInstance } from \"./engine\";\nimport type { SuperRequest } from \"./http/request\";\nimport type { SuperResponse } from \"./http/response\";\nimport { HttpStatus } from \"./http/status\";\nimport {\n\ttype Middleware,\n\tMiddlewarePipeline,\n\ttype StaticOptions,\n\tstaticFiles as staticFilesMiddleware,\n} from \"./middleware\";\nimport type { ControllerClass } from \"./router\";\nimport { type RouteContext, type RouteHandler, Router } from \"./router\";\n\nexport { Cache, type CacheConfig, cacheResponse } from \"./cache\";\nexport * from \"./database/index.js\";\nexport { createEvent, Event, type EventConfig, event } from \"./events\";\nexport { registerMacro, responseMacros, URLBuilder, url } from \"./helpers\";\nexport {\n\tcreateStorage,\n\tLocalDisk,\n\tStorage,\n\ttype StorageConfig,\n\tstorage,\n} from \"./storage\";\n\nexport interface ViewEngine {\n\trender(\n\t\ttemplate: string,\n\t\tdata: Record<string, unknown>,\n\t): string | Promise<string>;\n}\n\nexport interface AppOptions {\n\tengine?: ServerEngine;\n\tcontainer?: Container;\n}\n\nexport class SuperApp {\n\treadonly router: Router;\n\treadonly container: Container;\n\tprivate engine: ServerEngine;\n\tprivate serverInstance: ServerInstance | undefined;\n\tprivate globalPipeline: MiddlewarePipeline;\n\tprivate started = false;\n\tprivate serverPromise: Promise<void> | undefined;\n\n\tconstructor(options: AppOptions = {}) {\n\t\tthis.container = options.container ?? new Container();\n\t\tthis.router = new Router();\n\t\tthis.engine = options.engine ?? new NodeEngine();\n\t\tthis.globalPipeline = new MiddlewarePipeline();\n\n\t\tthis.container.instance(\"app\", this);\n\t\tthis.container.instance(\"router\", this.router);\n\t\tthis.container.instance(\"container\", this.container);\n\t}\n\n\tuse(middleware: Middleware): this {\n\t\tthis.globalPipeline.use(middleware);\n\t\treturn this;\n\t}\n\n\tget(path: string, handler: RouteHandler): this {\n\t\tthis.router.get(path, handler);\n\t\treturn this;\n\t}\n\n\tpost(path: string, handler: RouteHandler): this {\n\t\tthis.router.post(path, handler);\n\t\treturn this;\n\t}\n\n\tput(path: string, handler: RouteHandler): this {\n\t\tthis.router.put(path, handler);\n\t\treturn this;\n\t}\n\n\tpatch(path: string, handler: RouteHandler): this {\n\t\tthis.router.patch(path, handler);\n\t\treturn this;\n\t}\n\n\tdelete(path: string, handler: RouteHandler): this {\n\t\tthis.router.delete(path, handler);\n\t\treturn this;\n\t}\n\n\toptions(path: string, handler: RouteHandler): this {\n\t\tthis.router.options(path, handler);\n\t\treturn this;\n\t}\n\n\tany(path: string, handler: RouteHandler): this {\n\t\tthis.router.any(path, handler);\n\t\treturn this;\n\t}\n\n\tmatch(methods: string[], path: string, handler: RouteHandler): this {\n\t\tthis.router.match(methods, path, handler);\n\t\treturn this;\n\t}\n\n\tgroup(prefix: string, callback: (router: Router) => void): this {\n\t\tthis.router.group(prefix, callback);\n\t\treturn this;\n\t}\n\n\tresource(name: string, controller: ControllerClass): this {\n\t\tthis.router.resource(name, controller);\n\t\treturn this;\n\t}\n\n\tapiResource(name: string, controller: ControllerClass): this {\n\t\tthis.router.apiResource(name, controller);\n\t\treturn this;\n\t}\n\n\tcontroller(ctrl: ControllerClass): this {\n\t\tconst prefix = getControllerPrefix(ctrl as object);\n\t\tconst routes = getControllerRoutes(ctrl.prototype);\n\n\t\tfor (const route of routes) {\n\t\t\tconst handlerPath = `${prefix}${route.path}`;\n\t\t\tconst handlerName = String(route.handler);\n\n\t\t\tthis.router.match(\n\t\t\t\t[route.method],\n\t\t\t\thandlerPath,\n\t\t\t\tasync (ctx: RouteContext) => {\n\t\t\t\t\tconst instance = createControllerInstance(ctrl, ctx);\n\t\t\t\t\tconst handlerFn = (instance as Record<string, unknown>)[handlerName];\n\n\t\t\t\t\tif (typeof handlerFn === \"function\") {\n\t\t\t\t\t\tawait handlerFn.call(instance, ctx);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t`Handler ${handlerName} not found on controller ${ctrl.name}`,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t);\n\t\t}\n\n\t\treturn this;\n\t}\n\n\tmiddleware(middleware: Middleware | Middleware[]): this {\n\t\tthis.router.middleware(middleware);\n\t\treturn this;\n\t}\n\n\tsetEngine(engine: ServerEngine): this {\n\t\tif (this.started) {\n\t\t\tthrow new Error(\"Cannot change engine after server has started\");\n\t\t}\n\t\tthis.engine = engine;\n\t\treturn this;\n\t}\n\n\tstatic(path: string, options?: StaticOptions): this {\n\t\tthis.use(staticFilesMiddleware(path, options));\n\t\treturn this;\n\t}\n\n\tview(_engine: ViewEngine): this {\n\t\treturn this;\n\t}\n\n\tgetServer(): ServerInstance | undefined {\n\t\treturn this.serverInstance;\n\t}\n\n\tasync start(port?: number, host?: string): Promise<void> {\n\t\tif (this.started) {\n\t\t\tthrow new Error(\"Server has already been started\");\n\t\t}\n\t\tthis.started = true;\n\n\t\tthis.serverInstance = await this.engine.createServer(\n\t\t\tasync (req: SuperRequest, res: SuperResponse) => {\n\t\t\t\tawait this.handleRequest(req, res);\n\t\t\t},\n\t\t);\n\n\t\tconst listenPort = port ?? 3000;\n\t\tconst listenHost = host ?? \"0.0.0.0\";\n\n\t\treturn new Promise<void>((resolve) => {\n\t\t\tconst raw = this.serverInstance!.raw;\n\t\t\traw.listen(listenPort, listenHost, () => {\n\t\t\t\tresolve();\n\t\t\t});\n\t\t});\n\t}\n\n\tlisten(port?: number, callback?: () => void): void {\n\t\tthis.serverPromise = this.start(port).then(() => {\n\t\t\tcallback?.();\n\t\t});\n\t}\n\n\tasync close(): Promise<void> {\n\t\tif (this.serverInstance !== undefined) {\n\t\t\tawait this.engine.close(this.serverInstance);\n\t\t\tthis.serverInstance = undefined;\n\t\t\tthis.started = false;\n\t\t}\n\t}\n\n\tasync ready(): Promise<void> {\n\t\tif (this.serverPromise !== undefined) {\n\t\t\tawait this.serverPromise;\n\t\t}\n\t}\n\n\tprivate async handleRequest(\n\t\treq: SuperRequest,\n\t\tres: SuperResponse,\n\t): Promise<void> {\n\t\tconst resolvedRoute = this.router.resolve(req.method, req.path);\n\n\t\tif (resolvedRoute === null) {\n\t\t\tres.status(HttpStatus.NOT_FOUND).json({\n\t\t\t\terror: \"Not Found\",\n\t\t\t\tmessage: `Route ${req.method} ${req.path} not found`,\n\t\t\t});\n\t\t\tawait res.flush();\n\t\t\treturn;\n\t\t}\n\n\t\treq.params = resolvedRoute.params;\n\n\t\tconst ctx: RouteContext = {\n\t\t\trequest: req,\n\t\t\tresponse: res,\n\t\t\tparams: resolvedRoute.params,\n\t\t\tquery: req.query,\n\t\t\tcontainer: this.container,\n\t\t};\n\n\t\tawait this.globalPipeline.run(ctx, async () => {\n\t\t\tconst routePipeline = new MiddlewarePipeline();\n\t\t\tfor (const mw of resolvedRoute.middleware) {\n\t\t\t\troutePipeline.use(mw);\n\t\t\t}\n\n\t\t\tawait routePipeline.run(ctx, async () => {\n\t\t\t\tawait resolvedRoute.handler(ctx);\n\t\t\t});\n\t\t});\n\n\t\tif (!res.headersSent) {\n\t\t\tawait res.flush();\n\t\t}\n\t}\n}\n\nexport function speexjs(options?: AppOptions): SuperApp {\n\treturn new SuperApp(options);\n}\n\nexport function createControllerInstance(\n\tcontroller: ControllerClass,\n\tctx: RouteContext,\n): object {\n\tconst instance = new controller();\n\t(instance as Record<string, unknown>).__ctx = ctx;\n\t(instance as Record<string, unknown>).__container = ctx.container;\n\treturn instance;\n}\n","import type { Container } from \"../container\";\nimport type { SuperRequest } from \"../http/request\";\nimport type { SuperResponse } from \"../http/response\";\nimport type { Middleware } from \"../middleware\";\nimport { createControllerInstance } from \"../index.js\";\n\nexport type RouteHandler = (ctx: RouteContext) => void | Promise<void>;\n\nexport interface RouteContext {\n\trequest: SuperRequest;\n\tresponse: SuperResponse;\n\tparams: Record<string, string>;\n\tquery: Record<string, string | string[]>;\n\tcontainer: Container;\n}\n\nexport interface ResolvedRoute {\n\thandler: RouteHandler;\n\tparams: Record<string, string>;\n\tmiddleware: Middleware[];\n}\n\ninterface RouteEntry {\n\tmethods: string[];\n\tpath: string;\n\thandler: RouteHandler;\n\tmiddleware: Middleware[];\n\tname?: string;\n\tregexp: RegExp;\n\tparamKeys: string[];\n}\n\nexport interface ControllerClass {\n\tnew (...args: unknown[]): object;\n}\n\ninterface ResourceActions {\n\tindex?: string;\n\tcreate?: string;\n\tstore?: string;\n\tshow?: string;\n\tedit?: string;\n\tupdate?: string;\n\tdestroy?: string;\n}\n\nexport class Router {\n\tprivate routes: RouteEntry[] = [];\n\tprivate groupMiddleware: Middleware[] = [];\n\tprivate groupPrefix = \"\";\n\tprivate namedRoutes = new Map<string, RouteEntry>();\n\n\tget(path: string, handler: RouteHandler): this {\n\t\treturn this.match([\"GET\"], path, handler);\n\t}\n\n\tpost(path: string, handler: RouteHandler): this {\n\t\treturn this.match([\"POST\"], path, handler);\n\t}\n\n\tput(path: string, handler: RouteHandler): this {\n\t\treturn this.match([\"PUT\"], path, handler);\n\t}\n\n\tpatch(path: string, handler: RouteHandler): this {\n\t\treturn this.match([\"PATCH\"], path, handler);\n\t}\n\n\tdelete(path: string, handler: RouteHandler): this {\n\t\treturn this.match([\"DELETE\"], path, handler);\n\t}\n\n\toptions(path: string, handler: RouteHandler): this {\n\t\treturn this.match([\"OPTIONS\"], path, handler);\n\t}\n\n\tany(path: string, handler: RouteHandler): this {\n\t\treturn this.match(\n\t\t\t[\"GET\", \"POST\", \"PUT\", \"PATCH\", \"DELETE\", \"OPTIONS\"],\n\t\t\tpath,\n\t\t\thandler,\n\t\t);\n\t}\n\n\tmatch(methods: string[], path: string, handler: RouteHandler): this {\n\t\tconst fullPath = this.groupPrefix + normalizePath(path);\n\t\tconst { regexp, keys } = pathToRegexp(fullPath);\n\n\t\tthis.routes.push({\n\t\t\tmethods: methods.map((m) => m.toUpperCase()),\n\t\t\tpath: fullPath,\n\t\t\thandler,\n\t\t\tmiddleware: [...this.groupMiddleware],\n\t\t\tregexp,\n\t\t\tparamKeys: keys,\n\t\t});\n\n\t\treturn this;\n\t}\n\n\tgroup(prefix: string, callback: (router: Router) => void): this {\n\t\tconst previousPrefix = this.groupPrefix;\n\t\tconst previousMiddleware = [...this.groupMiddleware];\n\n\t\tthis.groupPrefix = previousPrefix + normalizePath(prefix);\n\n\t\tcallback(this);\n\n\t\tthis.groupPrefix = previousPrefix;\n\t\tthis.groupMiddleware = previousMiddleware;\n\n\t\treturn this;\n\t}\n\n\tresource(name: string, controller: ControllerClass): this {\n\t\tconst actions: ResourceActions = {\n\t\t\tindex: \"index\",\n\t\t\tcreate: \"create\",\n\t\t\tstore: \"store\",\n\t\t\tshow: \"show\",\n\t\t\tedit: \"edit\",\n\t\t\tupdate: \"update\",\n\t\t\tdestroy: \"destroy\",\n\t\t};\n\n\t\treturn this.registerResourceRoutes(name, controller, actions);\n\t}\n\n\tapiResource(name: string, controller: ControllerClass): this {\n\t\tconst actions: ResourceActions = {\n\t\t\tindex: \"index\",\n\t\t\tstore: \"store\",\n\t\t\tshow: \"show\",\n\t\t\tupdate: \"update\",\n\t\t\tdestroy: \"destroy\",\n\t\t};\n\n\t\treturn this.registerResourceRoutes(name, controller, actions);\n\t}\n\n\tprivate registerResourceRoutes(\n\t\tname: string,\n\t\tcontroller: ControllerClass,\n\t\tactions: ResourceActions,\n\t): this {\n\t\tconst basePath = normalizePath(name);\n\t\tconst paramName = singularize(name);\n\n\t\tif (actions.index !== undefined) {\n\t\t\tthis.get(\n\t\t\t\tbasePath,\n\t\t\t\tthis.createControllerHandler(controller, actions.index),\n\t\t\t);\n\t\t}\n\n\t\tif (actions.create !== undefined) {\n\t\t\tthis.get(\n\t\t\t\t`${basePath}/create`,\n\t\t\t\tthis.createControllerHandler(controller, actions.create),\n\t\t\t);\n\t\t}\n\n\t\tif (actions.store !== undefined) {\n\t\t\tthis.post(\n\t\t\t\tbasePath,\n\t\t\t\tthis.createControllerHandler(controller, actions.store),\n\t\t\t);\n\t\t}\n\n\t\tif (actions.show !== undefined) {\n\t\t\tthis.get(\n\t\t\t\t`${basePath}/:${paramName}`,\n\t\t\t\tthis.createControllerHandler(controller, actions.show),\n\t\t\t);\n\t\t}\n\n\t\tif (actions.edit !== undefined) {\n\t\t\tthis.get(\n\t\t\t\t`${basePath}/:${paramName}/edit`,\n\t\t\t\tthis.createControllerHandler(controller, actions.edit),\n\t\t\t);\n\t\t}\n\n\t\tif (actions.update !== undefined) {\n\t\t\tthis.put(\n\t\t\t\t`${basePath}/:${paramName}`,\n\t\t\t\tthis.createControllerHandler(controller, actions.update),\n\t\t\t);\n\t\t\tthis.patch(\n\t\t\t\t`${basePath}/:${paramName}`,\n\t\t\t\tthis.createControllerHandler(controller, actions.update),\n\t\t\t);\n\t\t}\n\n\t\tif (actions.destroy !== undefined) {\n\t\t\tthis.delete(\n\t\t\t\t`${basePath}/:${paramName}`,\n\t\t\t\tthis.createControllerHandler(controller, actions.destroy),\n\t\t\t);\n\t\t}\n\n\t\treturn this;\n\t}\n\n\tprivate createControllerHandler(\n\t\tcontroller: ControllerClass,\n\t\taction: string,\n\t): RouteHandler {\n\t\treturn async (ctx: RouteContext) => {\n\t\t\tconst instance = createControllerInstance(controller, ctx);\n\t\t\tconst handler = (instance as Record<string, unknown>)[action];\n\t\t\tif (typeof handler === \"function\") {\n\t\t\t\tawait handler.call(instance, ctx);\n\t\t\t} else {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Action ${action} not found on controller ${controller.name}`,\n\t\t\t\t);\n\t\t\t}\n\t\t};\n\t}\n\n\tmiddleware(middleware: Middleware | Middleware[]): this {\n\t\tconst mw = Array.isArray(middleware) ? middleware : [middleware];\n\t\tthis.groupMiddleware.push(...mw);\n\t\treturn this;\n\t}\n\n\tname(name: string): this {\n\t\tif (this.routes.length > 0) {\n\t\t\tconst lastRoute = this.routes[this.routes.length - 1];\n\t\t\tif (lastRoute !== undefined) {\n\t\t\t\tlastRoute.name = name;\n\t\t\t\tthis.namedRoutes.set(name, lastRoute);\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t}\n\n\troute(name: string, params?: Record<string, string>): string {\n\t\tconst entry = this.namedRoutes.get(name);\n\t\tif (entry === undefined) {\n\t\t\tthrow new Error(`Route not found: ${name}`);\n\t\t}\n\n\t\tlet url = entry.path;\n\t\tif (params !== undefined) {\n\t\t\tfor (const [key, value] of Object.entries(params)) {\n\t\t\t\turl = url.replace(`:${key}`, encodeURIComponent(value));\n\t\t\t}\n\t\t}\n\n\t\treturn url;\n\t}\n\n\tresolve(method: string, path: string): ResolvedRoute | null {\n\t\tconst normalizedPath = normalizePath(path);\n\t\tconst upperMethod = method.toUpperCase();\n\n\t\tfor (const route of this.routes) {\n\t\t\tif (!route.methods.includes(upperMethod)) continue;\n\n\t\t\tconst match = normalizedPath.match(route.regexp);\n\t\t\tif (match === null) continue;\n\n\t\t\tconst params: Record<string, string> = {};\n\t\t\tfor (let i = 0; i < route.paramKeys.length; i++) {\n\t\t\t\tconst key = route.paramKeys[i];\n\t\t\t\tconst value = match[i + 1];\n\t\t\t\tif (key !== undefined && value !== undefined) {\n\t\t\t\t\tparams[key] = decodeURIComponent(value);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\thandler: route.handler,\n\t\t\t\tparams,\n\t\t\t\tmiddleware: route.middleware,\n\t\t\t};\n\t\t}\n\n\t\treturn null;\n\t}\n\n\tgetRoutes(): RouteEntry[] {\n\t\treturn [...this.routes];\n\t}\n\n\tgetNamedRoutes(): Map<string, RouteEntry> {\n\t\treturn new Map(this.namedRoutes);\n\t}\n}\n\nfunction normalizePath(path: string): string {\n\tlet normalized = path.replace(/\\\\/g, \"/\");\n\n\tif (!normalized.startsWith(\"/\")) {\n\t\tnormalized = \"/\" + normalized;\n\t}\n\n\tif (normalized.length > 1 && normalized.endsWith(\"/\")) {\n\t\tnormalized = normalized.slice(0, -1);\n\t}\n\n\treturn normalized;\n}\n\nfunction pathToRegexp(pattern: string): { regexp: RegExp; keys: string[] } {\n\tconst keys: string[] = [];\n\n\tconst regexpStr = pattern\n\t\t.replace(/:([a-zA-Z_][a-zA-Z0-9_]*)/g, (_match: string, key: string) => {\n\t\t\tkeys.push(key);\n\t\t\treturn \"([^/]+)\";\n\t\t})\n\t\t.replace(/\\*/g, \".*?\");\n\n\treturn { regexp: new RegExp(`^${regexpStr}$`), keys };\n}\n\nfunction singularize(word: string): string {\n\tconst lastChar = word[word.length - 1];\n\tif (lastChar === \"s\") return word.slice(0, -1);\n\tif (lastChar === \"S\") return word.slice(0, -1);\n\treturn word;\n}\n\n\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../src/server/index.ts","../../../src/server/router/index.ts"],"sourcesContent":["import { Container } from \"./container\";\nimport { getControllerPrefix, getControllerRoutes } from \"./controller\";\nimport { NodeEngine, type ServerEngine, type ServerInstance } from \"./engine\";\nimport type { SuperRequest } from \"./http/request\";\nimport type { SuperResponse } from \"./http/response\";\nimport { HttpStatus } from \"./http/status\";\nimport {\n\ttype Middleware,\n\tMiddlewarePipeline,\n\ttype StaticOptions,\n\tstaticFiles as staticFilesMiddleware,\n} from \"./middleware\";\nimport type { ControllerClass } from \"./router\";\nimport { type RouteContext, type RouteHandler, Router } from \"./router\";\n\nexport { Cache, type CacheConfig, cacheResponse } from \"./cache\";\nexport * from \"./database/index.js\";\nexport { createEvent, Event, type EventConfig, event } from \"./events\";\nexport { registerMacro, responseMacros, URLBuilder, url } from \"./helpers\";\nexport {\n\tcreateStorage,\n\tLocalDisk,\n\tStorage,\n\ttype StorageConfig,\n\tstorage,\n} from \"./storage\";\nexport {\n\tHttpException,\n\tBadRequestException,\n\tUnauthorizedException,\n\tForbiddenException,\n\tNotFoundException,\n\tMethodNotAllowedException,\n\tConflictException,\n\tUnprocessableEntityException,\n\tTooManyRequestsException,\n\tInternalServerErrorException,\n\tServiceUnavailableException,\n\tValidationException,\n\tregisterExceptionHandler,\n\tnormalizeError,\n} from \"./errors\";\n\nexport interface ViewEngine {\n\trender(\n\t\ttemplate: string,\n\t\tdata: Record<string, unknown>,\n\t): string | Promise<string>;\n}\n\nexport interface AppOptions {\n\tengine?: ServerEngine;\n\tcontainer?: Container;\n}\n\nexport class SuperApp {\n\treadonly router: Router;\n\treadonly container: Container;\n\tprivate engine: ServerEngine;\n\tprivate serverInstance: ServerInstance | undefined;\n\tprivate globalPipeline: MiddlewarePipeline;\n\tprivate started = false;\n\tprivate serverPromise: Promise<void> | undefined;\n\tprivate onErrorHandler: ((err: Error, ctx: RouteContext) => void | Promise<void>) | null = null;\n\tprivate onNotFoundHandler: ((ctx: RouteContext) => void | Promise<void>) | null = null;\n\tprivate shutdownHandlers: (() => void | Promise<void>)[] = [];\n\tprivate shuttingDown = false;\n\n\tconstructor(options: AppOptions = {}) {\n\t\tthis.container = options.container ?? new Container();\n\t\tthis.router = new Router();\n\t\tthis.engine = options.engine ?? new NodeEngine();\n\t\tthis.globalPipeline = new MiddlewarePipeline();\n\n\t\tthis.container.instance(\"app\", this);\n\t\tthis.container.instance(\"router\", this.router);\n\t\tthis.container.instance(\"container\", this.container);\n\t}\n\n\tuse(middleware: Middleware): this {\n\t\tthis.globalPipeline.use(middleware);\n\t\treturn this;\n\t}\n\n\tget(path: string, handler: RouteHandler): this {\n\t\tthis.router.get(path, handler);\n\t\treturn this;\n\t}\n\n\tpost(path: string, handler: RouteHandler): this {\n\t\tthis.router.post(path, handler);\n\t\treturn this;\n\t}\n\n\tput(path: string, handler: RouteHandler): this {\n\t\tthis.router.put(path, handler);\n\t\treturn this;\n\t}\n\n\tpatch(path: string, handler: RouteHandler): this {\n\t\tthis.router.patch(path, handler);\n\t\treturn this;\n\t}\n\n\tdelete(path: string, handler: RouteHandler): this {\n\t\tthis.router.delete(path, handler);\n\t\treturn this;\n\t}\n\n\toptions(path: string, handler: RouteHandler): this {\n\t\tthis.router.options(path, handler);\n\t\treturn this;\n\t}\n\n\tany(path: string, handler: RouteHandler): this {\n\t\tthis.router.any(path, handler);\n\t\treturn this;\n\t}\n\n\tmatch(methods: string[], path: string, handler: RouteHandler): this {\n\t\tthis.router.match(methods, path, handler);\n\t\treturn this;\n\t}\n\n\tgroup(prefix: string, callback: (router: Router) => void): this {\n\t\tthis.router.group(prefix, callback);\n\t\treturn this;\n\t}\n\n\tresource(name: string, controller: ControllerClass): this {\n\t\tthis.router.resource(name, controller);\n\t\treturn this;\n\t}\n\n\tapiResource(name: string, controller: ControllerClass): this {\n\t\tthis.router.apiResource(name, controller);\n\t\treturn this;\n\t}\n\n\tcontroller(ctrl: ControllerClass): this {\n\t\tconst prefix = getControllerPrefix(ctrl as object);\n\t\tconst routes = getControllerRoutes(ctrl.prototype);\n\n\t\tfor (const route of routes) {\n\t\t\tconst handlerPath = `${prefix}${route.path}`;\n\t\t\tconst handlerName = String(route.handler);\n\n\t\t\tthis.router.match(\n\t\t\t\t[route.method],\n\t\t\t\thandlerPath,\n\t\t\t\tasync (ctx: RouteContext) => {\n\t\t\t\t\tconst instance = createControllerInstance(ctrl, ctx);\n\t\t\t\t\tconst handlerFn = (instance as Record<string, unknown>)[handlerName];\n\n\t\t\t\t\tif (typeof handlerFn === \"function\") {\n\t\t\t\t\t\tawait handlerFn.call(instance, ctx);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t`Handler ${handlerName} not found on controller ${ctrl.name}`,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t);\n\t\t}\n\n\t\treturn this;\n\t}\n\n\tmiddleware(middleware: Middleware | Middleware[]): this {\n\t\tthis.router.middleware(middleware);\n\t\treturn this;\n\t}\n\n\tsetEngine(engine: ServerEngine): this {\n\t\tif (this.started) {\n\t\t\tthrow new Error(\"Cannot change engine after server has started\");\n\t\t}\n\t\tthis.engine = engine;\n\t\treturn this;\n\t}\n\n\tstatic(path: string, options?: StaticOptions): this {\n\t\tthis.use(staticFilesMiddleware(path, options));\n\t\treturn this;\n\t}\n\n\tview(_engine: ViewEngine): this {\n\t\treturn this;\n\t}\n\n\tonError(handler: (err: Error, ctx: RouteContext) => void | Promise<void>): this {\n\t\tthis.onErrorHandler = handler;\n\t\treturn this;\n\t}\n\n\tnotFound(handler: (ctx: RouteContext) => void | Promise<void>): this {\n\t\tthis.onNotFoundHandler = handler;\n\t\treturn this;\n\t}\n\n\tonShutdown(handler: () => void | Promise<void>): this {\n\t\tthis.shutdownHandlers.push(handler);\n\t\treturn this;\n\t}\n\n\tgetServer(): ServerInstance | undefined {\n\t\treturn this.serverInstance;\n\t}\n\n\tasync start(port?: number, host?: string): Promise<void> {\n\t\tif (this.started) {\n\t\t\tthrow new Error(\"Server has already been started\");\n\t\t}\n\t\tthis.started = true;\n\n\t\tthis.serverInstance = await this.engine.createServer(\n\t\t\tasync (req: SuperRequest, res: SuperResponse) => {\n\t\t\t\tawait this.handleRequest(req, res);\n\t\t\t},\n\t\t);\n\n\t\tconst listenPort = port ?? 3000;\n\t\tconst listenHost = host ?? \"0.0.0.0\";\n\n\t\treturn new Promise<void>((resolve) => {\n\t\t\tconst raw = this.serverInstance!.raw;\n\t\t\traw.listen(listenPort, listenHost, () => {\n\t\t\t\tresolve();\n\t\t\t});\n\t\t});\n\t}\n\n\tlisten(port?: number, callback?: () => void): this {\n\t\tthis.serverPromise = this.start(port).then(() => {\n\t\t\tconst shutdown = async (signal: string) => {\n\t\t\t\tif (this.shuttingDown) return;\n\t\t\t\tthis.shuttingDown = true;\n\n\t\t\t\tconsole.log(`\\n⚠️ Received ${signal}. Starting graceful shutdown...`);\n\n\t\t\t\tfor (const handler of this.shutdownHandlers) {\n\t\t\t\t\ttry { await handler(); } catch { /* ignore shutdown errors */ }\n\t\t\t\t}\n\n\t\t\t\tawait this.close();\n\t\t\t\tconsole.log('✓ Server shut down gracefully');\n\t\t\t\tprocess.exit(0);\n\t\t\t};\n\n\t\t\tprocess.on('SIGINT', () => shutdown('SIGINT'));\n\t\t\tprocess.on('SIGTERM', () => shutdown('SIGTERM'));\n\n\t\t\tif (process.stdin && process.stdin.isTTY) {\n\t\t\t\tprocess.stdin.on('end', () => shutdown('stdin end'));\n\t\t\t}\n\n\t\t\tcallback?.();\n\t\t});\n\t\treturn this;\n\t}\n\n\tasync close(): Promise<void> {\n\t\tif (this.serverInstance !== undefined) {\n\t\t\tawait this.engine.close(this.serverInstance);\n\t\t\tthis.serverInstance = undefined;\n\t\t\tthis.started = false;\n\t\t}\n\t}\n\n\tasync ready(): Promise<void> {\n\t\tif (this.serverPromise !== undefined) {\n\t\t\tawait this.serverPromise;\n\t\t}\n\t}\n\n\tprivate async handleRequest(\n\t\treq: SuperRequest,\n\t\tres: SuperResponse,\n\t): Promise<void> {\n\t\tconst resolvedRoute = this.router.resolve(req.method, req.path);\n\n\t\tif (resolvedRoute === null) {\n\t\t\tif (this.onNotFoundHandler !== null) {\n\t\t\t\tconst ctx: RouteContext = {\n\t\t\t\t\trequest: req,\n\t\t\t\t\tresponse: res,\n\t\t\t\t\tparams: {},\n\t\t\t\t\tquery: req.query,\n\t\t\t\t\tcontainer: this.container,\n\t\t\t\t};\n\t\t\t\tawait this.onNotFoundHandler(ctx);\n\t\t\t\tif (!res.headersSent) await res.flush();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tres.status(HttpStatus.NOT_FOUND).json({\n\t\t\t\terror: 'NOT_FOUND',\n\t\t\t\tmessage: `Route ${req.method} ${req.path} not found`,\n\t\t\t});\n\t\t\tawait res.flush();\n\t\t\treturn;\n\t\t}\n\n\t\treq.params = resolvedRoute.params;\n\n\t\tconst ctx: RouteContext = {\n\t\t\trequest: req,\n\t\t\tresponse: res,\n\t\t\tparams: resolvedRoute.params,\n\t\t\tquery: req.query,\n\t\t\tcontainer: this.container,\n\t\t};\n\n\t\ttry {\n\t\t\tawait this.globalPipeline.run(ctx, async () => {\n\t\t\t\tconst routePipeline = new MiddlewarePipeline();\n\t\t\t\tfor (const mw of resolvedRoute.middleware) {\n\t\t\t\t\troutePipeline.use(mw);\n\t\t\t\t}\n\t\t\t\tawait routePipeline.run(ctx, async () => {\n\t\t\t\t\tawait resolvedRoute.handler(ctx);\n\t\t\t\t});\n\t\t\t});\n\t\t} catch (err: unknown) {\n\t\t\tif (this.onErrorHandler !== null) {\n\t\t\t\tawait this.onErrorHandler(\n\t\t\t\t\terr instanceof Error ? err : new Error(String(err)),\n\t\t\t\t\tctx,\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tthrow err;\n\t\t\t}\n\t\t}\n\n\t\tif (!res.headersSent) {\n\t\t\tawait res.flush();\n\t\t}\n\t}\n}\n\nexport function speexjs(options?: AppOptions): SuperApp {\n\treturn new SuperApp(options);\n}\n\nexport function createControllerInstance(\n\tcontroller: ControllerClass,\n\tctx: RouteContext,\n): object {\n\tconst instance = new controller();\n\t(instance as Record<string, unknown>).__ctx = ctx;\n\t(instance as Record<string, unknown>).__container = ctx.container;\n\treturn instance;\n}\n","import type { Container } from \"../container\";\nimport type { SuperRequest } from \"../http/request\";\nimport type { SuperResponse } from \"../http/response\";\nimport type { Middleware } from \"../middleware\";\nimport { createControllerInstance } from \"../index.js\";\n\nexport type RouteHandler = (ctx: RouteContext) => void | Promise<void>;\n\nexport interface RouteContext {\n\trequest: SuperRequest;\n\tresponse: SuperResponse;\n\tparams: Record<string, string>;\n\tquery: Record<string, string | string[]>;\n\tcontainer: Container;\n}\n\nexport interface ResolvedRoute {\n\thandler: RouteHandler;\n\tparams: Record<string, string>;\n\tmiddleware: Middleware[];\n}\n\ninterface RouteEntry {\n\tmethods: string[];\n\tpath: string;\n\thandler: RouteHandler;\n\tmiddleware: Middleware[];\n\tname?: string;\n\tregexp: RegExp;\n\tparamKeys: string[];\n}\n\nexport interface ControllerClass {\n\tnew (...args: unknown[]): object;\n}\n\ninterface ResourceActions {\n\tindex?: string;\n\tcreate?: string;\n\tstore?: string;\n\tshow?: string;\n\tedit?: string;\n\tupdate?: string;\n\tdestroy?: string;\n}\n\nexport class Router {\n\tprivate routes: RouteEntry[] = [];\n\tprivate groupMiddleware: Middleware[] = [];\n\tprivate groupPrefix = \"\";\n\tprivate namedRoutes = new Map<string, RouteEntry>();\n\n\tget(path: string, handler: RouteHandler): this {\n\t\treturn this.match([\"GET\"], path, handler);\n\t}\n\n\tpost(path: string, handler: RouteHandler): this {\n\t\treturn this.match([\"POST\"], path, handler);\n\t}\n\n\tput(path: string, handler: RouteHandler): this {\n\t\treturn this.match([\"PUT\"], path, handler);\n\t}\n\n\tpatch(path: string, handler: RouteHandler): this {\n\t\treturn this.match([\"PATCH\"], path, handler);\n\t}\n\n\tdelete(path: string, handler: RouteHandler): this {\n\t\treturn this.match([\"DELETE\"], path, handler);\n\t}\n\n\toptions(path: string, handler: RouteHandler): this {\n\t\treturn this.match([\"OPTIONS\"], path, handler);\n\t}\n\n\tany(path: string, handler: RouteHandler): this {\n\t\treturn this.match(\n\t\t\t[\"GET\", \"POST\", \"PUT\", \"PATCH\", \"DELETE\", \"OPTIONS\"],\n\t\t\tpath,\n\t\t\thandler,\n\t\t);\n\t}\n\n\tmatch(methods: string[], path: string, handler: RouteHandler): this {\n\t\tconst fullPath = this.groupPrefix + normalizePath(path);\n\t\tconst { regexp, keys } = pathToRegexp(fullPath);\n\n\t\tthis.routes.push({\n\t\t\tmethods: methods.map((m) => m.toUpperCase()),\n\t\t\tpath: fullPath,\n\t\t\thandler,\n\t\t\tmiddleware: [...this.groupMiddleware],\n\t\t\tregexp,\n\t\t\tparamKeys: keys,\n\t\t});\n\n\t\treturn this;\n\t}\n\n\tgroup(prefix: string, callback: (router: Router) => void): this {\n\t\tconst previousPrefix = this.groupPrefix;\n\t\tconst previousMiddleware = [...this.groupMiddleware];\n\n\t\tthis.groupPrefix = previousPrefix + normalizePath(prefix);\n\n\t\tcallback(this);\n\n\t\tthis.groupPrefix = previousPrefix;\n\t\tthis.groupMiddleware = previousMiddleware;\n\n\t\treturn this;\n\t}\n\n\tresource(name: string, controller: ControllerClass): this {\n\t\tconst actions: ResourceActions = {\n\t\t\tindex: \"index\",\n\t\t\tcreate: \"create\",\n\t\t\tstore: \"store\",\n\t\t\tshow: \"show\",\n\t\t\tedit: \"edit\",\n\t\t\tupdate: \"update\",\n\t\t\tdestroy: \"destroy\",\n\t\t};\n\n\t\treturn this.registerResourceRoutes(name, controller, actions);\n\t}\n\n\tapiResource(name: string, controller: ControllerClass): this {\n\t\tconst actions: ResourceActions = {\n\t\t\tindex: \"index\",\n\t\t\tstore: \"store\",\n\t\t\tshow: \"show\",\n\t\t\tupdate: \"update\",\n\t\t\tdestroy: \"destroy\",\n\t\t};\n\n\t\treturn this.registerResourceRoutes(name, controller, actions);\n\t}\n\n\tprivate registerResourceRoutes(\n\t\tname: string,\n\t\tcontroller: ControllerClass,\n\t\tactions: ResourceActions,\n\t): this {\n\t\tconst basePath = normalizePath(name);\n\t\tconst paramName = singularize(name);\n\n\t\tif (actions.index !== undefined) {\n\t\t\tthis.get(\n\t\t\t\tbasePath,\n\t\t\t\tthis.createControllerHandler(controller, actions.index),\n\t\t\t);\n\t\t}\n\n\t\tif (actions.create !== undefined) {\n\t\t\tthis.get(\n\t\t\t\t`${basePath}/create`,\n\t\t\t\tthis.createControllerHandler(controller, actions.create),\n\t\t\t);\n\t\t}\n\n\t\tif (actions.store !== undefined) {\n\t\t\tthis.post(\n\t\t\t\tbasePath,\n\t\t\t\tthis.createControllerHandler(controller, actions.store),\n\t\t\t);\n\t\t}\n\n\t\tif (actions.show !== undefined) {\n\t\t\tthis.get(\n\t\t\t\t`${basePath}/:${paramName}`,\n\t\t\t\tthis.createControllerHandler(controller, actions.show),\n\t\t\t);\n\t\t}\n\n\t\tif (actions.edit !== undefined) {\n\t\t\tthis.get(\n\t\t\t\t`${basePath}/:${paramName}/edit`,\n\t\t\t\tthis.createControllerHandler(controller, actions.edit),\n\t\t\t);\n\t\t}\n\n\t\tif (actions.update !== undefined) {\n\t\t\tthis.put(\n\t\t\t\t`${basePath}/:${paramName}`,\n\t\t\t\tthis.createControllerHandler(controller, actions.update),\n\t\t\t);\n\t\t\tthis.patch(\n\t\t\t\t`${basePath}/:${paramName}`,\n\t\t\t\tthis.createControllerHandler(controller, actions.update),\n\t\t\t);\n\t\t}\n\n\t\tif (actions.destroy !== undefined) {\n\t\t\tthis.delete(\n\t\t\t\t`${basePath}/:${paramName}`,\n\t\t\t\tthis.createControllerHandler(controller, actions.destroy),\n\t\t\t);\n\t\t}\n\n\t\treturn this;\n\t}\n\n\tprivate createControllerHandler(\n\t\tcontroller: ControllerClass,\n\t\taction: string,\n\t): RouteHandler {\n\t\treturn async (ctx: RouteContext) => {\n\t\t\tconst instance = createControllerInstance(controller, ctx);\n\t\t\tconst handler = (instance as Record<string, unknown>)[action];\n\t\t\tif (typeof handler === \"function\") {\n\t\t\t\tawait handler.call(instance, ctx);\n\t\t\t} else {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Action ${action} not found on controller ${controller.name}`,\n\t\t\t\t);\n\t\t\t}\n\t\t};\n\t}\n\n\tmiddleware(middleware: Middleware | Middleware[]): this {\n\t\tconst mw = Array.isArray(middleware) ? middleware : [middleware];\n\t\tthis.groupMiddleware.push(...mw);\n\t\treturn this;\n\t}\n\n\tname(name: string): this {\n\t\tif (this.routes.length > 0) {\n\t\t\tconst lastRoute = this.routes[this.routes.length - 1];\n\t\t\tif (lastRoute !== undefined) {\n\t\t\t\tlastRoute.name = name;\n\t\t\t\tthis.namedRoutes.set(name, lastRoute);\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t}\n\n\troute(name: string, params?: Record<string, string>): string {\n\t\tconst entry = this.namedRoutes.get(name);\n\t\tif (entry === undefined) {\n\t\t\tthrow new Error(`Route not found: ${name}`);\n\t\t}\n\n\t\tlet url = entry.path;\n\t\tif (params !== undefined) {\n\t\t\tfor (const [key, value] of Object.entries(params)) {\n\t\t\t\turl = url.replace(`:${key}`, encodeURIComponent(value));\n\t\t\t}\n\t\t}\n\n\t\treturn url;\n\t}\n\n\tresolve(method: string, path: string): ResolvedRoute | null {\n\t\tconst normalizedPath = normalizePath(path);\n\t\tconst upperMethod = method.toUpperCase();\n\n\t\tfor (const route of this.routes) {\n\t\t\tif (!route.methods.includes(upperMethod)) continue;\n\n\t\t\tconst match = normalizedPath.match(route.regexp);\n\t\t\tif (match === null) continue;\n\n\t\t\tconst params: Record<string, string> = {};\n\t\t\tfor (let i = 0; i < route.paramKeys.length; i++) {\n\t\t\t\tconst key = route.paramKeys[i];\n\t\t\t\tconst value = match[i + 1];\n\t\t\t\tif (key !== undefined && value !== undefined) {\n\t\t\t\t\tparams[key] = decodeURIComponent(value);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\thandler: route.handler,\n\t\t\t\tparams,\n\t\t\t\tmiddleware: route.middleware,\n\t\t\t};\n\t\t}\n\n\t\treturn null;\n\t}\n\n\tgetRoutes(): RouteEntry[] {\n\t\treturn [...this.routes];\n\t}\n\n\tgetNamedRoutes(): Map<string, RouteEntry> {\n\t\treturn new Map(this.namedRoutes);\n\t}\n}\n\nfunction normalizePath(path: string): string {\n\tlet normalized = path.replace(/\\\\/g, \"/\");\n\n\tif (!normalized.startsWith(\"/\")) {\n\t\tnormalized = \"/\" + normalized;\n\t}\n\n\tif (normalized.length > 1 && normalized.endsWith(\"/\")) {\n\t\tnormalized = normalized.slice(0, -1);\n\t}\n\n\treturn normalized;\n}\n\nfunction pathToRegexp(pattern: string): { regexp: RegExp; keys: string[] } {\n\tconst keys: string[] = [];\n\n\tconst regexpStr = pattern\n\t\t.replace(/:([a-zA-Z_][a-zA-Z0-9_]*)/g, (_match: string, key: string) => {\n\t\t\tkeys.push(key);\n\t\t\treturn \"([^/]+)\";\n\t\t})\n\t\t.replace(/\\*/g, \".*?\");\n\n\treturn { regexp: new RegExp(`^${regexpStr}$`), keys };\n}\n\nfunction singularize(word: string): string {\n\tconst lastChar = word[word.length - 1];\n\tif (lastChar === \"s\") return word.slice(0, -1);\n\tif (lastChar === \"S\") return word.slice(0, -1);\n\treturn word;\n}\n\n\n"],"mappings":";AAuVO,SAAS,yBACf,YACA,KACS;AACT,QAAM,WAAW,IAAI,WAAW;AAChC,EAAC,SAAqC,QAAQ;AAC9C,EAAC,SAAqC,cAAc,IAAI;AACxD,SAAO;AACR;;;ACjTO,IAAM,SAAN,MAAa;AAAA,EACX,SAAuB,CAAC;AAAA,EACxB,kBAAgC,CAAC;AAAA,EACjC,cAAc;AAAA,EACd,cAAc,oBAAI,IAAwB;AAAA,EAElD,IAAI,MAAc,SAA6B;AAC9C,WAAO,KAAK,MAAM,CAAC,KAAK,GAAG,MAAM,OAAO;AAAA,EACzC;AAAA,EAEA,KAAK,MAAc,SAA6B;AAC/C,WAAO,KAAK,MAAM,CAAC,MAAM,GAAG,MAAM,OAAO;AAAA,EAC1C;AAAA,EAEA,IAAI,MAAc,SAA6B;AAC9C,WAAO,KAAK,MAAM,CAAC,KAAK,GAAG,MAAM,OAAO;AAAA,EACzC;AAAA,EAEA,MAAM,MAAc,SAA6B;AAChD,WAAO,KAAK,MAAM,CAAC,OAAO,GAAG,MAAM,OAAO;AAAA,EAC3C;AAAA,EAEA,OAAO,MAAc,SAA6B;AACjD,WAAO,KAAK,MAAM,CAAC,QAAQ,GAAG,MAAM,OAAO;AAAA,EAC5C;AAAA,EAEA,QAAQ,MAAc,SAA6B;AAClD,WAAO,KAAK,MAAM,CAAC,SAAS,GAAG,MAAM,OAAO;AAAA,EAC7C;AAAA,EAEA,IAAI,MAAc,SAA6B;AAC9C,WAAO,KAAK;AAAA,MACX,CAAC,OAAO,QAAQ,OAAO,SAAS,UAAU,SAAS;AAAA,MACnD;AAAA,MACA;AAAA,IACD;AAAA,EACD;AAAA,EAEA,MAAM,SAAmB,MAAc,SAA6B;AACnE,UAAM,WAAW,KAAK,cAAc,cAAc,IAAI;AACtD,UAAM,EAAE,QAAQ,KAAK,IAAI,aAAa,QAAQ;AAE9C,SAAK,OAAO,KAAK;AAAA,MAChB,SAAS,QAAQ,IAAI,CAAC,MAAM,EAAE,YAAY,CAAC;AAAA,MAC3C,MAAM;AAAA,MACN;AAAA,MACA,YAAY,CAAC,GAAG,KAAK,eAAe;AAAA,MACpC;AAAA,MACA,WAAW;AAAA,IACZ,CAAC;AAED,WAAO;AAAA,EACR;AAAA,EAEA,MAAM,QAAgB,UAA0C;AAC/D,UAAM,iBAAiB,KAAK;AAC5B,UAAM,qBAAqB,CAAC,GAAG,KAAK,eAAe;AAEnD,SAAK,cAAc,iBAAiB,cAAc,MAAM;AAExD,aAAS,IAAI;AAEb,SAAK,cAAc;AACnB,SAAK,kBAAkB;AAEvB,WAAO;AAAA,EACR;AAAA,EAEA,SAAS,MAAc,YAAmC;AACzD,UAAM,UAA2B;AAAA,MAChC,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,OAAO;AAAA,MACP,MAAM;AAAA,MACN,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,SAAS;AAAA,IACV;AAEA,WAAO,KAAK,uBAAuB,MAAM,YAAY,OAAO;AAAA,EAC7D;AAAA,EAEA,YAAY,MAAc,YAAmC;AAC5D,UAAM,UAA2B;AAAA,MAChC,OAAO;AAAA,MACP,OAAO;AAAA,MACP,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,SAAS;AAAA,IACV;AAEA,WAAO,KAAK,uBAAuB,MAAM,YAAY,OAAO;AAAA,EAC7D;AAAA,EAEQ,uBACP,MACA,YACA,SACO;AACP,UAAM,WAAW,cAAc,IAAI;AACnC,UAAM,YAAY,YAAY,IAAI;AAElC,QAAI,QAAQ,UAAU,QAAW;AAChC,WAAK;AAAA,QACJ;AAAA,QACA,KAAK,wBAAwB,YAAY,QAAQ,KAAK;AAAA,MACvD;AAAA,IACD;AAEA,QAAI,QAAQ,WAAW,QAAW;AACjC,WAAK;AAAA,QACJ,GAAG,QAAQ;AAAA,QACX,KAAK,wBAAwB,YAAY,QAAQ,MAAM;AAAA,MACxD;AAAA,IACD;AAEA,QAAI,QAAQ,UAAU,QAAW;AAChC,WAAK;AAAA,QACJ;AAAA,QACA,KAAK,wBAAwB,YAAY,QAAQ,KAAK;AAAA,MACvD;AAAA,IACD;AAEA,QAAI,QAAQ,SAAS,QAAW;AAC/B,WAAK;AAAA,QACJ,GAAG,QAAQ,KAAK,SAAS;AAAA,QACzB,KAAK,wBAAwB,YAAY,QAAQ,IAAI;AAAA,MACtD;AAAA,IACD;AAEA,QAAI,QAAQ,SAAS,QAAW;AAC/B,WAAK;AAAA,QACJ,GAAG,QAAQ,KAAK,SAAS;AAAA,QACzB,KAAK,wBAAwB,YAAY,QAAQ,IAAI;AAAA,MACtD;AAAA,IACD;AAEA,QAAI,QAAQ,WAAW,QAAW;AACjC,WAAK;AAAA,QACJ,GAAG,QAAQ,KAAK,SAAS;AAAA,QACzB,KAAK,wBAAwB,YAAY,QAAQ,MAAM;AAAA,MACxD;AACA,WAAK;AAAA,QACJ,GAAG,QAAQ,KAAK,SAAS;AAAA,QACzB,KAAK,wBAAwB,YAAY,QAAQ,MAAM;AAAA,MACxD;AAAA,IACD;AAEA,QAAI,QAAQ,YAAY,QAAW;AAClC,WAAK;AAAA,QACJ,GAAG,QAAQ,KAAK,SAAS;AAAA,QACzB,KAAK,wBAAwB,YAAY,QAAQ,OAAO;AAAA,MACzD;AAAA,IACD;AAEA,WAAO;AAAA,EACR;AAAA,EAEQ,wBACP,YACA,QACe;AACf,WAAO,OAAO,QAAsB;AACnC,YAAM,WAAW,yBAAyB,YAAY,GAAG;AACzD,YAAM,UAAW,SAAqC,MAAM;AAC5D,UAAI,OAAO,YAAY,YAAY;AAClC,cAAM,QAAQ,KAAK,UAAU,GAAG;AAAA,MACjC,OAAO;AACN,cAAM,IAAI;AAAA,UACT,UAAU,MAAM,4BAA4B,WAAW,IAAI;AAAA,QAC5D;AAAA,MACD;AAAA,IACD;AAAA,EACD;AAAA,EAEA,WAAW,YAA6C;AACvD,UAAM,KAAK,MAAM,QAAQ,UAAU,IAAI,aAAa,CAAC,UAAU;AAC/D,SAAK,gBAAgB,KAAK,GAAG,EAAE;AAC/B,WAAO;AAAA,EACR;AAAA,EAEA,KAAK,MAAoB;AACxB,QAAI,KAAK,OAAO,SAAS,GAAG;AAC3B,YAAM,YAAY,KAAK,OAAO,KAAK,OAAO,SAAS,CAAC;AACpD,UAAI,cAAc,QAAW;AAC5B,kBAAU,OAAO;AACjB,aAAK,YAAY,IAAI,MAAM,SAAS;AAAA,MACrC;AAAA,IACD;AACA,WAAO;AAAA,EACR;AAAA,EAEA,MAAM,MAAc,QAAyC;AAC5D,UAAM,QAAQ,KAAK,YAAY,IAAI,IAAI;AACvC,QAAI,UAAU,QAAW;AACxB,YAAM,IAAI,MAAM,oBAAoB,IAAI,EAAE;AAAA,IAC3C;AAEA,QAAI,MAAM,MAAM;AAChB,QAAI,WAAW,QAAW;AACzB,iBAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,MAAM,GAAG;AAClD,cAAM,IAAI,QAAQ,IAAI,GAAG,IAAI,mBAAmB,KAAK,CAAC;AAAA,MACvD;AAAA,IACD;AAEA,WAAO;AAAA,EACR;AAAA,EAEA,QAAQ,QAAgB,MAAoC;AAC3D,UAAM,iBAAiB,cAAc,IAAI;AACzC,UAAM,cAAc,OAAO,YAAY;AAEvC,eAAW,SAAS,KAAK,QAAQ;AAChC,UAAI,CAAC,MAAM,QAAQ,SAAS,WAAW,EAAG;AAE1C,YAAM,QAAQ,eAAe,MAAM,MAAM,MAAM;AAC/C,UAAI,UAAU,KAAM;AAEpB,YAAM,SAAiC,CAAC;AACxC,eAAS,IAAI,GAAG,IAAI,MAAM,UAAU,QAAQ,KAAK;AAChD,cAAM,MAAM,MAAM,UAAU,CAAC;AAC7B,cAAM,QAAQ,MAAM,IAAI,CAAC;AACzB,YAAI,QAAQ,UAAa,UAAU,QAAW;AAC7C,iBAAO,GAAG,IAAI,mBAAmB,KAAK;AAAA,QACvC;AAAA,MACD;AAEA,aAAO;AAAA,QACN,SAAS,MAAM;AAAA,QACf;AAAA,QACA,YAAY,MAAM;AAAA,MACnB;AAAA,IACD;AAEA,WAAO;AAAA,EACR;AAAA,EAEA,YAA0B;AACzB,WAAO,CAAC,GAAG,KAAK,MAAM;AAAA,EACvB;AAAA,EAEA,iBAA0C;AACzC,WAAO,IAAI,IAAI,KAAK,WAAW;AAAA,EAChC;AACD;AAEA,SAAS,cAAc,MAAsB;AAC5C,MAAI,aAAa,KAAK,QAAQ,OAAO,GAAG;AAExC,MAAI,CAAC,WAAW,WAAW,GAAG,GAAG;AAChC,iBAAa,MAAM;AAAA,EACpB;AAEA,MAAI,WAAW,SAAS,KAAK,WAAW,SAAS,GAAG,GAAG;AACtD,iBAAa,WAAW,MAAM,GAAG,EAAE;AAAA,EACpC;AAEA,SAAO;AACR;AAEA,SAAS,aAAa,SAAqD;AAC1E,QAAM,OAAiB,CAAC;AAExB,QAAM,YAAY,QAChB,QAAQ,8BAA8B,CAAC,QAAgB,QAAgB;AACvE,SAAK,KAAK,GAAG;AACb,WAAO;AAAA,EACR,CAAC,EACA,QAAQ,OAAO,KAAK;AAEtB,SAAO,EAAE,QAAQ,IAAI,OAAO,IAAI,SAAS,GAAG,GAAG,KAAK;AACrD;AAEA,SAAS,YAAY,MAAsB;AAC1C,QAAM,WAAW,KAAK,KAAK,SAAS,CAAC;AACrC,MAAI,aAAa,IAAK,QAAO,KAAK,MAAM,GAAG,EAAE;AAC7C,MAAI,aAAa,IAAK,QAAO,KAAK,MAAM,GAAG,EAAE;AAC7C,SAAO;AACR;","names":[]}
|
package/package.json
CHANGED
|
@@ -1,141 +1,142 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "speexjs",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Fullstack JavaScript/TypeScript framework — Server, Client, RPC, Schema, CLI, Database, Auth, Cache, Storage. Zero dependencies.",
|
|
5
|
-
"type": "module",
|
|
6
|
-
"main": "./dist/index.js",
|
|
7
|
-
"module": "./dist/index.js",
|
|
8
|
-
"types": "./dist/index.d.ts",
|
|
9
|
-
"bin": {
|
|
10
|
-
"speexjs": "dist/cli/index.js"
|
|
11
|
-
},
|
|
12
|
-
"exports": {
|
|
13
|
-
".": {
|
|
14
|
-
"import": "./dist/index.js",
|
|
15
|
-
"types": "./dist/index.d.ts"
|
|
16
|
-
},
|
|
17
|
-
"./server": {
|
|
18
|
-
"import": "./dist/server/index.js",
|
|
19
|
-
"types": "./dist/server/index.d.ts"
|
|
20
|
-
},
|
|
21
|
-
"./server/http": {
|
|
22
|
-
"import": "./dist/server/http/index.js",
|
|
23
|
-
"types": "./dist/server/http/index.d.ts"
|
|
24
|
-
},
|
|
25
|
-
"./server/router": {
|
|
26
|
-
"import": "./dist/server/router/index.js",
|
|
27
|
-
"types": "./dist/server/router/index.d.ts"
|
|
28
|
-
},
|
|
29
|
-
"./server/middleware": {
|
|
30
|
-
"import": "./dist/server/middleware/index.js",
|
|
31
|
-
"types": "./dist/server/middleware/index.d.ts"
|
|
32
|
-
},
|
|
33
|
-
"./server/controller": {
|
|
34
|
-
"import": "./dist/server/controller/index.js",
|
|
35
|
-
"types": "./dist/server/controller/index.d.ts"
|
|
36
|
-
},
|
|
37
|
-
"./server/container": {
|
|
38
|
-
"import": "./dist/server/container/index.js",
|
|
39
|
-
"types": "./dist/server/container/index.d.ts"
|
|
40
|
-
},
|
|
41
|
-
"./server/auth": {
|
|
42
|
-
"import": "./dist/server/auth/index.js",
|
|
43
|
-
"types": "./dist/server/auth/index.d.ts"
|
|
44
|
-
},
|
|
45
|
-
"./server/gate": {
|
|
46
|
-
"import": "./dist/server/gate/index.js",
|
|
47
|
-
"types": "./dist/server/gate/index.d.ts"
|
|
48
|
-
},
|
|
49
|
-
"./server/cache": {
|
|
50
|
-
"import": "./dist/server/cache/index.js",
|
|
51
|
-
"types": "./dist/server/cache/index.d.ts"
|
|
52
|
-
},
|
|
53
|
-
"./server/storage": {
|
|
54
|
-
"import": "./dist/server/storage/index.js",
|
|
55
|
-
"types": "./dist/server/storage/index.d.ts"
|
|
56
|
-
},
|
|
57
|
-
"./server/events": {
|
|
58
|
-
"import": "./dist/server/events/index.js",
|
|
59
|
-
"types": "./dist/server/events/index.d.ts"
|
|
60
|
-
},
|
|
61
|
-
"./server/database": {
|
|
62
|
-
"import": "./dist/server/database/index.js",
|
|
63
|
-
"types": "./dist/server/database/index.d.ts"
|
|
64
|
-
},
|
|
65
|
-
"./client": {
|
|
66
|
-
"import": "./dist/client/index.js",
|
|
67
|
-
"types": "./dist/client/index.d.ts"
|
|
68
|
-
},
|
|
69
|
-
"./client/signals": {
|
|
70
|
-
"import": "./dist/client/signals/index.js",
|
|
71
|
-
"types": "./dist/client/signals/index.d.ts"
|
|
72
|
-
},
|
|
73
|
-
"./client/vdom": {
|
|
74
|
-
"import": "./dist/client/vdom/index.js",
|
|
75
|
-
"types": "./dist/client/vdom/index.d.ts"
|
|
76
|
-
},
|
|
77
|
-
"./client/vdom/jsx-runtime": {
|
|
78
|
-
"import": "./dist/client/vdom/jsx-runtime.js",
|
|
79
|
-
"types": "./dist/client/vdom/jsx-runtime.d.ts"
|
|
80
|
-
},
|
|
81
|
-
"./rpc": {
|
|
82
|
-
"import": "./dist/rpc/index.js",
|
|
83
|
-
"types": "./dist/rpc/index.d.ts"
|
|
84
|
-
},
|
|
85
|
-
"./schema": {
|
|
86
|
-
"import": "./dist/schema/index.js",
|
|
87
|
-
"types": "./dist/schema/index.d.ts"
|
|
88
|
-
}
|
|
89
|
-
},
|
|
90
|
-
"sideEffects": false,
|
|
91
|
-
"files": [
|
|
92
|
-
"dist"
|
|
93
|
-
],
|
|
94
|
-
"scripts": {
|
|
95
|
-
"build": "tsup",
|
|
96
|
-
"dev": "tsup --watch",
|
|
97
|
-
"test": "vitest run",
|
|
98
|
-
"test:watch": "vitest",
|
|
99
|
-
"test:coverage": "vitest run --coverage",
|
|
100
|
-
"typecheck": "tsc --noEmit",
|
|
101
|
-
"build:all": "npm run build"
|
|
102
|
-
},
|
|
103
|
-
"dependencies": {
|
|
104
|
-
"tsx": "^4.19.0"
|
|
105
|
-
},
|
|
106
|
-
"devDependencies": {
|
|
107
|
-
"@biomejs/biome": "^2.5.1",
|
|
108
|
-
"@types/node": "^26.0.1",
|
|
109
|
-
"@vitest/coverage-v8": "^2.1.9",
|
|
110
|
-
"tsup": "^8.3.0",
|
|
111
|
-
"typescript": "^5.7.0",
|
|
112
|
-
"vite": "^8.1.0",
|
|
113
|
-
"vitest": "^2.1.0"
|
|
114
|
-
},
|
|
115
|
-
"keywords": [
|
|
116
|
-
"fullstack",
|
|
117
|
-
"framework",
|
|
118
|
-
"typescript",
|
|
119
|
-
"server",
|
|
120
|
-
"client",
|
|
121
|
-
"rpc",
|
|
122
|
-
"validation",
|
|
123
|
-
"database",
|
|
124
|
-
"auth",
|
|
125
|
-
"indonesia"
|
|
126
|
-
],
|
|
127
|
-
"publishConfig": {
|
|
128
|
-
"access": "public"
|
|
129
|
-
},
|
|
130
|
-
"repository": {
|
|
131
|
-
"type": "git",
|
|
132
|
-
"url": "git+https://github.com/superdevids/speexjs.git"
|
|
133
|
-
},
|
|
134
|
-
"license": "MIT",
|
|
135
|
-
"engines": {
|
|
136
|
-
"node": ">=18.0.0"
|
|
137
|
-
},
|
|
138
|
-
"optionalDependencies": {
|
|
139
|
-
"better-sqlite3": "^12.11.1"
|
|
140
|
-
|
|
141
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "speexjs",
|
|
3
|
+
"version": "0.4.0",
|
|
4
|
+
"description": "Fullstack JavaScript/TypeScript framework — Server, Client, RPC, Schema, CLI, Database, Auth, Cache, Storage. Zero dependencies.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"module": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"bin": {
|
|
10
|
+
"speexjs": "dist/cli/index.js"
|
|
11
|
+
},
|
|
12
|
+
"exports": {
|
|
13
|
+
".": {
|
|
14
|
+
"import": "./dist/index.js",
|
|
15
|
+
"types": "./dist/index.d.ts"
|
|
16
|
+
},
|
|
17
|
+
"./server": {
|
|
18
|
+
"import": "./dist/server/index.js",
|
|
19
|
+
"types": "./dist/server/index.d.ts"
|
|
20
|
+
},
|
|
21
|
+
"./server/http": {
|
|
22
|
+
"import": "./dist/server/http/index.js",
|
|
23
|
+
"types": "./dist/server/http/index.d.ts"
|
|
24
|
+
},
|
|
25
|
+
"./server/router": {
|
|
26
|
+
"import": "./dist/server/router/index.js",
|
|
27
|
+
"types": "./dist/server/router/index.d.ts"
|
|
28
|
+
},
|
|
29
|
+
"./server/middleware": {
|
|
30
|
+
"import": "./dist/server/middleware/index.js",
|
|
31
|
+
"types": "./dist/server/middleware/index.d.ts"
|
|
32
|
+
},
|
|
33
|
+
"./server/controller": {
|
|
34
|
+
"import": "./dist/server/controller/index.js",
|
|
35
|
+
"types": "./dist/server/controller/index.d.ts"
|
|
36
|
+
},
|
|
37
|
+
"./server/container": {
|
|
38
|
+
"import": "./dist/server/container/index.js",
|
|
39
|
+
"types": "./dist/server/container/index.d.ts"
|
|
40
|
+
},
|
|
41
|
+
"./server/auth": {
|
|
42
|
+
"import": "./dist/server/auth/index.js",
|
|
43
|
+
"types": "./dist/server/auth/index.d.ts"
|
|
44
|
+
},
|
|
45
|
+
"./server/gate": {
|
|
46
|
+
"import": "./dist/server/gate/index.js",
|
|
47
|
+
"types": "./dist/server/gate/index.d.ts"
|
|
48
|
+
},
|
|
49
|
+
"./server/cache": {
|
|
50
|
+
"import": "./dist/server/cache/index.js",
|
|
51
|
+
"types": "./dist/server/cache/index.d.ts"
|
|
52
|
+
},
|
|
53
|
+
"./server/storage": {
|
|
54
|
+
"import": "./dist/server/storage/index.js",
|
|
55
|
+
"types": "./dist/server/storage/index.d.ts"
|
|
56
|
+
},
|
|
57
|
+
"./server/events": {
|
|
58
|
+
"import": "./dist/server/events/index.js",
|
|
59
|
+
"types": "./dist/server/events/index.d.ts"
|
|
60
|
+
},
|
|
61
|
+
"./server/database": {
|
|
62
|
+
"import": "./dist/server/database/index.js",
|
|
63
|
+
"types": "./dist/server/database/index.d.ts"
|
|
64
|
+
},
|
|
65
|
+
"./client": {
|
|
66
|
+
"import": "./dist/client/index.js",
|
|
67
|
+
"types": "./dist/client/index.d.ts"
|
|
68
|
+
},
|
|
69
|
+
"./client/signals": {
|
|
70
|
+
"import": "./dist/client/signals/index.js",
|
|
71
|
+
"types": "./dist/client/signals/index.d.ts"
|
|
72
|
+
},
|
|
73
|
+
"./client/vdom": {
|
|
74
|
+
"import": "./dist/client/vdom/index.js",
|
|
75
|
+
"types": "./dist/client/vdom/index.d.ts"
|
|
76
|
+
},
|
|
77
|
+
"./client/vdom/jsx-runtime": {
|
|
78
|
+
"import": "./dist/client/vdom/jsx-runtime.js",
|
|
79
|
+
"types": "./dist/client/vdom/jsx-runtime.d.ts"
|
|
80
|
+
},
|
|
81
|
+
"./rpc": {
|
|
82
|
+
"import": "./dist/rpc/index.js",
|
|
83
|
+
"types": "./dist/rpc/index.d.ts"
|
|
84
|
+
},
|
|
85
|
+
"./schema": {
|
|
86
|
+
"import": "./dist/schema/index.js",
|
|
87
|
+
"types": "./dist/schema/index.d.ts"
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
"sideEffects": false,
|
|
91
|
+
"files": [
|
|
92
|
+
"dist"
|
|
93
|
+
],
|
|
94
|
+
"scripts": {
|
|
95
|
+
"build": "tsup",
|
|
96
|
+
"dev": "tsup --watch",
|
|
97
|
+
"test": "vitest run",
|
|
98
|
+
"test:watch": "vitest",
|
|
99
|
+
"test:coverage": "vitest run --coverage",
|
|
100
|
+
"typecheck": "tsc --noEmit",
|
|
101
|
+
"build:all": "npm run build"
|
|
102
|
+
},
|
|
103
|
+
"dependencies": {
|
|
104
|
+
"tsx": "^4.19.0"
|
|
105
|
+
},
|
|
106
|
+
"devDependencies": {
|
|
107
|
+
"@biomejs/biome": "^2.5.1",
|
|
108
|
+
"@types/node": "^26.0.1",
|
|
109
|
+
"@vitest/coverage-v8": "^2.1.9",
|
|
110
|
+
"tsup": "^8.3.0",
|
|
111
|
+
"typescript": "^5.7.0",
|
|
112
|
+
"vite": "^8.1.0",
|
|
113
|
+
"vitest": "^2.1.0"
|
|
114
|
+
},
|
|
115
|
+
"keywords": [
|
|
116
|
+
"fullstack",
|
|
117
|
+
"framework",
|
|
118
|
+
"typescript",
|
|
119
|
+
"server",
|
|
120
|
+
"client",
|
|
121
|
+
"rpc",
|
|
122
|
+
"validation",
|
|
123
|
+
"database",
|
|
124
|
+
"auth",
|
|
125
|
+
"indonesia"
|
|
126
|
+
],
|
|
127
|
+
"publishConfig": {
|
|
128
|
+
"access": "public"
|
|
129
|
+
},
|
|
130
|
+
"repository": {
|
|
131
|
+
"type": "git",
|
|
132
|
+
"url": "git+https://github.com/superdevids/speexjs.git"
|
|
133
|
+
},
|
|
134
|
+
"license": "MIT",
|
|
135
|
+
"engines": {
|
|
136
|
+
"node": ">=18.0.0"
|
|
137
|
+
},
|
|
138
|
+
"optionalDependencies": {
|
|
139
|
+
"better-sqlite3": "^12.11.1",
|
|
140
|
+
"ws": "^8.18.0"
|
|
141
|
+
}
|
|
142
|
+
}
|