speexjs 0.2.2 → 0.3.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/README.md +44 -497
- package/dist/cli/index.js +314 -105
- package/dist/cli/index.js.map +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.js +1048 -285
- package/dist/index.js.map +1 -1
- package/dist/rpc/index.d.ts +1 -1
- package/dist/schema/index.d.ts +36 -30
- package/dist/schema/index.js +12 -229
- package/dist/schema/index.js.map +1 -1
- package/dist/server/auth/index.d.ts +1 -0
- package/dist/server/auth/index.js +18 -12
- package/dist/server/auth/index.js.map +1 -1
- package/dist/server/database/index.d.ts +22 -2
- package/dist/server/database/index.js +993 -30
- package/dist/server/database/index.js.map +1 -1
- package/dist/server/http/index.js +19 -2
- package/dist/server/http/index.js.map +1 -1
- package/dist/server/index.d.ts +4 -3
- package/dist/server/index.js +1028 -48
- package/dist/server/index.js.map +1 -1
- package/dist/server/middleware/index.js +53 -33
- package/dist/server/middleware/index.js.map +1 -1
- package/dist/server/router/index.js +8 -6
- package/dist/server/router/index.js.map +1 -1
- package/dist/{types-CXH8hPei.d.ts → types-aW38f63o.d.ts} +1 -1
- package/package.json +8 -3
|
@@ -376,8 +376,15 @@ var SuperRequest = class {
|
|
|
376
376
|
}
|
|
377
377
|
async readBodyFromStream() {
|
|
378
378
|
const chunks = [];
|
|
379
|
+
const MAX_BODY_SIZE = 10 * 1024 * 1024;
|
|
380
|
+
let totalSize = 0;
|
|
379
381
|
for await (const chunk of this.raw) {
|
|
380
|
-
|
|
382
|
+
const buf = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
|
|
383
|
+
totalSize += buf.length;
|
|
384
|
+
if (totalSize > MAX_BODY_SIZE) {
|
|
385
|
+
throw new Error("Request body too large. Maximum size is 10MB.");
|
|
386
|
+
}
|
|
387
|
+
chunks.push(buf);
|
|
381
388
|
}
|
|
382
389
|
const raw = Buffer.concat(chunks);
|
|
383
390
|
const text = raw.toString("utf-8");
|
|
@@ -642,7 +649,7 @@ function parseContentType(headerSection) {
|
|
|
642
649
|
|
|
643
650
|
// src/server/http/response.ts
|
|
644
651
|
import { createReadStream, stat } from "fs";
|
|
645
|
-
import { basename as basename2, extname as extname2 } from "path";
|
|
652
|
+
import { basename as basename2, extname as extname2, resolve } from "path";
|
|
646
653
|
import { promisify } from "util";
|
|
647
654
|
var statAsync = promisify(stat);
|
|
648
655
|
var MIME_TYPES = {
|
|
@@ -725,6 +732,9 @@ var SuperResponse = class {
|
|
|
725
732
|
return this.send(html, status, "text/html; charset=utf-8");
|
|
726
733
|
}
|
|
727
734
|
redirect(url, status = HttpStatus.FOUND) {
|
|
735
|
+
if (url.includes("\r") || url.includes("\n")) {
|
|
736
|
+
throw new Error("Invalid redirect URL");
|
|
737
|
+
}
|
|
728
738
|
this._statusCode = status;
|
|
729
739
|
this._headers.set("location", url);
|
|
730
740
|
this._body = null;
|
|
@@ -749,6 +759,13 @@ var SuperResponse = class {
|
|
|
749
759
|
}
|
|
750
760
|
async file(filePath, options) {
|
|
751
761
|
const fullPath = options?.root ? joinPath(options.root, filePath) : filePath;
|
|
762
|
+
const resolved = resolve(fullPath);
|
|
763
|
+
const root = options?.root ? resolve(options.root) : null;
|
|
764
|
+
if (root !== null && !resolved.startsWith(root)) {
|
|
765
|
+
this._statusCode = HttpStatus.FORBIDDEN;
|
|
766
|
+
this._body = null;
|
|
767
|
+
return this;
|
|
768
|
+
}
|
|
752
769
|
try {
|
|
753
770
|
const stats = await statAsync(fullPath);
|
|
754
771
|
if (!stats.isFile()) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/server/http/status.ts","../../../src/server/http/headers.ts","../../../src/server/http/cookie.ts","../../../src/server/http/upload.ts","../../../src/server/http/request.ts","../../../src/server/http/response.ts"],"sourcesContent":["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","export class HeadersMap {\n private data: Map<string, string[]>\n\n constructor(initial?: Record<string, string | string[]>) {\n this.data = new Map()\n if (initial) {\n for (const key of Object.keys(initial)) {\n const value = initial[key]\n if (value !== undefined) {\n this.set(key, Array.isArray(value) ? value.join(', ') : value)\n }\n }\n }\n }\n\n get(name: string): string | undefined {\n const values = this.data.get(name.toLowerCase())\n if (values !== undefined && values.length > 0) {\n return values[0]\n }\n return undefined\n }\n\n getAll(name: string): string[] {\n const values = this.data.get(name.toLowerCase())\n return values ?? []\n }\n\n set(name: string, value: string): void {\n this.data.set(name.toLowerCase(), [value])\n }\n\n append(name: string, value: string): void {\n const key = name.toLowerCase()\n const existing = this.data.get(key)\n if (existing !== undefined) {\n existing.push(value)\n } else {\n this.data.set(key, [value])\n }\n }\n\n has(name: string): boolean {\n return this.data.has(name.toLowerCase())\n }\n\n delete(name: string): void {\n this.data.delete(name.toLowerCase())\n }\n\n *entries(): IterableIterator<[string, string]> {\n for (const [key, values] of this.data) {\n for (const value of values) {\n yield [key, value]\n }\n }\n }\n\n *keys(): IterableIterator<string> {\n for (const key of this.data.keys()) {\n yield key\n }\n }\n\n *values(): IterableIterator<string> {\n for (const [, values] of this.data) {\n for (const value of values) {\n yield value\n }\n }\n }\n\n toJSON(): Record<string, string | string[]> {\n const result: Record<string, string | string[]> = {}\n for (const [key, values] of this.data) {\n result[key] = values.length === 1 ? (values[0] as string) : values\n }\n return result\n }\n\n toNodeHeaders(): Record<string, string | string[]> {\n const result: Record<string, string | string[]> = {}\n for (const [key, values] of this.data) {\n if (key === 'set-cookie') {\n result[key] = values\n } else {\n result[key] = values.join(', ')\n }\n }\n return result\n }\n\n get size(): number {\n return this.data.size\n }\n\n [Symbol.iterator](): IterableIterator<[string, string]> {\n return this.entries()\n }\n}\n","export interface CookieOptions {\n maxAge?: number\n expires?: Date\n path?: string\n domain?: string\n secure?: boolean\n httpOnly?: boolean\n sameSite?: 'strict' | 'lax' | 'none'\n signed?: boolean\n}\n\nexport function parseCookies(header: string): Record<string, string> {\n const result: Record<string, string> = {}\n\n if (!header) return result\n\n const pairs = header.split(';')\n\n for (const pair of pairs) {\n const trimmed = pair.trim()\n if (!trimmed) continue\n\n const eqIndex = trimmed.indexOf('=')\n if (eqIndex === -1) {\n result[trimmed] = ''\n continue\n }\n\n const name = trimmed.slice(0, eqIndex).trim()\n let value = trimmed.slice(eqIndex + 1).trim()\n\n if (value.startsWith('\"') && value.endsWith('\"')) {\n value = value.slice(1, -1)\n }\n\n if (name) {\n result[decodeURIComponent(name)] = decodeURIComponent(value)\n }\n }\n\n return result\n}\n\nfunction serializeCookieValue(name: string, value: string): string {\n return `${encodeURIComponent(name)}=${encodeURIComponent(value)}`\n}\n\nexport function serializeCookie(\n name: string,\n value: string,\n options?: CookieOptions,\n): string {\n const parts: string[] = [serializeCookieValue(name, value)]\n\n if (options) {\n if (options.maxAge !== undefined) {\n parts.push(`Max-Age=${Math.floor(options.maxAge)}`)\n }\n\n if (options.expires !== undefined) {\n parts.push(`Expires=${options.expires.toUTCString()}`)\n }\n\n if (options.path !== undefined) {\n parts.push(`Path=${options.path}`)\n } else {\n parts.push('Path=/')\n }\n\n if (options.domain !== undefined) {\n parts.push(`Domain=${options.domain}`)\n }\n\n if (options.secure) {\n parts.push('Secure')\n }\n\n if (options.httpOnly) {\n parts.push('HttpOnly')\n }\n\n if (options.sameSite !== undefined) {\n parts.push(`SameSite=${options.sameSite}`)\n }\n }\n\n return parts.join('; ')\n}\n\nexport function clearCookie(name: string, options?: CookieOptions): string {\n return serializeCookie(name, '', {\n ...options,\n maxAge: 0,\n expires: new Date(0),\n })\n}\n","import { randomUUID } from 'node:crypto'\nimport { writeFile, readFile, unlink, mkdir } from 'node:fs/promises'\nimport { join, extname, basename, dirname } from 'node:path'\nimport { tmpdir } from 'node:os'\n\nexport interface UploadedFile {\n readonly fieldName: string\n readonly originalName: string\n readonly mimeType: string\n readonly size: number\n readonly path: string\n readonly extension: string\n move(destination: string, filename?: string): Promise<string>\n toBuffer(): Promise<Buffer>\n toBase64(): string\n isImage(): boolean\n isVideo(): boolean\n}\n\nconst IMAGE_MIME_TYPES = new Set([\n 'image/jpeg',\n 'image/png',\n 'image/gif',\n 'image/webp',\n 'image/svg+xml',\n 'image/bmp',\n 'image/tiff',\n 'image/avif',\n])\n\nconst VIDEO_MIME_TYPES = new Set([\n 'video/mp4',\n 'video/mpeg',\n 'video/webm',\n 'video/ogg',\n 'video/quicktime',\n 'video/x-msvideo',\n 'video/x-matroska',\n])\n\nexport class SuperUploadedFile implements UploadedFile {\n readonly fieldName: string\n readonly originalName: string\n readonly mimeType: string\n readonly size: number\n readonly path: string\n readonly extension: string\n private buffer: Buffer | null\n\n constructor(opts: {\n fieldName: string\n originalName: string\n mimeType: string\n size: number\n path: string\n buffer?: Buffer\n }) {\n this.fieldName = opts.fieldName\n this.originalName = opts.originalName\n this.mimeType = opts.mimeType\n this.size = opts.size\n this.path = opts.path\n this.extension = extname(opts.originalName).toLowerCase()\n this.buffer = opts.buffer ?? null\n }\n\n async move(destination: string, filename?: string): Promise<string> {\n const destName = filename ?? basename(this.path)\n const destPath = join(destination, destName)\n\n await mkdir(dirname(destPath), { recursive: true })\n\n const buf = await this.toBuffer()\n await writeFile(destPath, buf)\n\n return destPath\n }\n\n async toBuffer(): Promise<Buffer> {\n if (this.buffer !== null) return this.buffer\n this.buffer = await readFile(this.path)\n return this.buffer\n }\n\n toBase64(): string {\n if (this.buffer === null) {\n throw new Error(\n 'Buffer not loaded. Call toBuffer() first or read the file into memory.',\n )\n }\n return this.buffer.toString('base64')\n }\n\n isImage(): boolean {\n return IMAGE_MIME_TYPES.has(this.mimeType)\n }\n\n isVideo(): boolean {\n return VIDEO_MIME_TYPES.has(this.mimeType)\n }\n\n static async createFromBuffer(\n fieldName: string,\n originalName: string,\n mimeType: string,\n buffer: Buffer,\n tempDir?: string,\n ): Promise<SuperUploadedFile> {\n const tmp = tempDir ?? tmpdir()\n const fileName = `${randomUUID()}${extname(originalName)}`\n const filePath = join(tmp, fileName)\n\n await writeFile(filePath, buffer)\n\n return new SuperUploadedFile({\n fieldName,\n originalName,\n mimeType: mimeType || 'application/octet-stream',\n size: buffer.length,\n path: filePath,\n buffer,\n })\n }\n\n async cleanup(): Promise<void> {\n try {\n await unlink(this.path)\n } catch {\n // File may have been moved or already deleted\n }\n }\n}\n","import type { IncomingMessage } from 'node:http'\nimport { HeadersMap } from './headers'\nimport { parseCookies } from './cookie'\nimport { SuperUploadedFile } from './upload'\n\nexport interface Schema<T = unknown> {\n parse(input: unknown): T\n validate(\n input: unknown,\n ): { success: boolean; data?: T; errors?: { message: string; path?: string }[] }\n}\n\ninterface ParsedMultipartField {\n type: 'field'\n name: string\n value: string\n}\n\ninterface ParsedMultipartFile {\n type: 'file'\n name: string\n filename: string\n mimeType: string\n data: Buffer\n}\n\ntype MultipartPart = ParsedMultipartField | ParsedMultipartFile\n\ninterface BodyCache {\n raw: Buffer\n parsed: unknown\n text: string\n json: unknown\n formData: Record<string, string> | null\n files: Record<string, SuperUploadedFile> | null\n multipartParsed: MultipartPart[] | null\n}\n\nexport class SuperRequest {\n private raw: IncomingMessage\n private _headers: HeadersMap\n private _query: Record<string, string | string[]>\n private _cookies: Record<string, string> | null = null\n private _ip: string\n private _params: Record<string, string> = {}\n private bodyCache: BodyCache | null = null\n private _bodyReadPromise: Promise<BodyCache> | null = null\n\n constructor(raw: IncomingMessage) {\n this.raw = raw\n\n this._headers = new HeadersMap(\n raw.headers as Record<string, string | string[]>,\n )\n\n const parsedUrl = new URL(raw.url ?? '/', 'http://localhost')\n this._query = parseQueryParams(parsedUrl.searchParams)\n\n this._ip = parseIp(raw)\n\n this.path = parsedUrl.pathname\n this.url = raw.url ?? '/'\n this.method = (raw.method ?? 'GET').toUpperCase()\n }\n\n readonly method: string\n readonly url: string\n readonly path: string\n\n get headers(): HeadersMap {\n return this._headers\n }\n\n get query(): Record<string, string | string[]> {\n return this._query\n }\n\n get params(): Record<string, string> {\n return this._params\n }\n\n set params(value: Record<string, string>) {\n this._params = value\n }\n\n get ip(): string {\n return this._ip\n }\n\n private async ensureBody(): Promise<BodyCache> {\n if (this.bodyCache !== null) return this.bodyCache\n\n if (this._bodyReadPromise === null) {\n this._bodyReadPromise = this.readBodyFromStream()\n }\n\n this.bodyCache = await this._bodyReadPromise\n return this.bodyCache\n }\n\n private async readBodyFromStream(): Promise<BodyCache> {\n const chunks: Buffer[] = []\n for await (const chunk of this.raw) {\n chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk))\n }\n const raw = Buffer.concat(chunks)\n const text = raw.toString('utf-8')\n\n let json: unknown = undefined\n if (this.isContentType('application/json')) {\n try {\n json = JSON.parse(text)\n } catch {\n json = undefined\n }\n }\n\n let formData: Record<string, string> | null = null\n let multipartParsed: MultipartPart[] | null = null\n let files: Record<string, SuperUploadedFile> | null = null\n\n if (this.isContentType('application/x-www-form-urlencoded')) {\n formData = parseUrlEncoded(text)\n } else if (this.isContentType('multipart/form-data')) {\n const boundary = this.getMultipartBoundary()\n if (boundary !== undefined) {\n multipartParsed = parseMultipartBody(raw, boundary)\n formData = {}\n files = {}\n for (const part of multipartParsed) {\n if (part.type === 'field') {\n formData[part.name] = part.value\n } else if (part.type === 'file') {\n const uploadedFile = await SuperUploadedFile.createFromBuffer(\n part.name,\n part.filename,\n part.mimeType,\n part.data,\n )\n files[part.name] = uploadedFile\n }\n }\n }\n }\n\n return {\n raw,\n text,\n json,\n parsed: json ?? text,\n formData,\n files,\n multipartParsed,\n }\n }\n\n private isContentType(expected: string): boolean {\n const ct = this._headers.get('content-type')\n if (ct === undefined) return false\n return ct.toLowerCase().startsWith(expected)\n }\n\n private getMultipartBoundary(): string | undefined {\n const ct = this._headers.get('content-type')\n if (ct === undefined) return undefined\n const match = ct.match(/boundary=(?:\"([^\"]+)\"|([^;]+))/i)\n if (match !== null) {\n return match[1] ?? match[2]\n }\n return undefined\n }\n\n async body(): Promise<unknown> {\n const cache = await this.ensureBody()\n return cache.parsed\n }\n\n async json<T = unknown>(): Promise<T> {\n const cache = await this.ensureBody()\n if (cache.json !== undefined) return cache.json as T\n throw new Error('Request body is not valid JSON')\n }\n\n async text(): Promise<string> {\n const cache = await this.ensureBody()\n return cache.text\n }\n\n async formData(): Promise<Record<string, string>> {\n const cache = await this.ensureBody()\n if (cache.formData !== null) return cache.formData\n\n if (cache.multipartParsed !== null) {\n const result: Record<string, string> = {}\n for (const part of cache.multipartParsed) {\n if (part.type === 'field') {\n result[part.name] = part.value\n }\n }\n return result\n }\n\n return {}\n }\n\n async file(name: string): Promise<SuperUploadedFile | undefined> {\n const cache = await this.ensureBody()\n if (cache.files !== null) {\n return cache.files[name]\n }\n return undefined\n }\n\n async files(): Promise<Record<string, SuperUploadedFile>> {\n const cache = await this.ensureBody()\n return cache.files ?? {}\n }\n\n cookie(name: string): string | undefined {\n if (this._cookies === null) {\n const cookieHeader = this._headers.get('cookie')\n this._cookies = cookieHeader !== undefined\n ? parseCookies(cookieHeader)\n : {}\n }\n return this._cookies[name]\n }\n\n async validate<T>(schema: Schema<T>): Promise<T> {\n const data = await this.body()\n const result = schema.validate(data)\n if (!result.success) {\n const messages = (result.errors ?? [])\n .map((e) => {\n const path = e.path ?? ''\n return path ? `${path}: ${e.message}` : e.message\n })\n .join('; ')\n throw new ValidationError(messages, result.errors ?? [])\n }\n return result.data as T\n }\n\n isAjax(): boolean {\n const requestedWith = this._headers.get('x-requested-with')\n return requestedWith?.toLowerCase() === 'xmlhttprequest'\n }\n\n wantsJson(): boolean {\n const accept = this._headers.get('accept')\n if (accept !== undefined && accept.includes('application/json')) {\n return true\n }\n return this.isAjax()\n }\n\n bearerToken(): string | undefined {\n const auth = this._headers.get('authorization')\n if (auth === undefined) return undefined\n const match = auth.match(/^Bearer\\s+(.+)$/i)\n return match?.[1]\n }\n\n get rawRequest(): IncomingMessage {\n return this.raw\n }\n}\n\nexport class ValidationError extends Error {\n constructor(\n message: string,\n readonly errors: { message: string; path?: string }[],\n ) {\n super(message)\n this.name = 'ValidationError'\n }\n}\n\nfunction parseQueryParams(\n searchParams: URLSearchParams,\n): Record<string, string | string[]> {\n const result: Record<string, string | string[]> = {}\n for (const key of searchParams.keys()) {\n const values = searchParams.getAll(key)\n result[key] = values.length === 1 ? (values[0] as string) : values\n }\n return result\n}\n\nfunction parseIp(req: IncomingMessage): string {\n const forwarded = req.headers['x-forwarded-for']\n if (forwarded !== undefined) {\n const first = Array.isArray(forwarded) ? forwarded[0] : forwarded.split(',')[0]\n if (first !== undefined) return first.trim()\n }\n\n const realIp = req.headers['x-real-ip']\n if (realIp !== undefined) {\n return Array.isArray(realIp) ? realIp[0] as string : realIp\n }\n\n const remote = req.socket.remoteAddress\n if (remote !== undefined) {\n if (remote.startsWith('::ffff:')) return remote.slice(7)\n return remote\n }\n\n return '127.0.0.1'\n}\n\nfunction parseUrlEncoded(text: string): Record<string, string> {\n const result: Record<string, string> = {}\n const pairs = text.split('&')\n for (const pair of pairs) {\n if (!pair) continue\n const eqIndex = pair.indexOf('=')\n if (eqIndex === -1) {\n result[decodeURIComponent(pair)] = ''\n } else {\n const key = decodeURIComponent(pair.slice(0, eqIndex))\n const value = decodeURIComponent(pair.slice(eqIndex + 1))\n result[key] = value\n }\n }\n return result\n}\n\nfunction parseMultipartBody(\n body: Buffer,\n boundary: string,\n): MultipartPart[] {\n const result: MultipartPart[] = []\n const boundaryBuffer = Buffer.from(`--${boundary}`)\n\n let start = 0\n let searchFrom = 0\n\n while (true) {\n const boundaryIndex = body.indexOf(boundaryBuffer, searchFrom)\n if (boundaryIndex === -1) break\n\n searchFrom = boundaryIndex + boundaryBuffer.length\n\n if (\n searchFrom < body.length &&\n body[searchFrom] === 45 &&\n body[searchFrom + 1] === 45\n ) {\n break\n }\n\n if (searchFrom >= body.length) break\n\n if (body[searchFrom] === 13) searchFrom++\n if (body[searchFrom] === 10) searchFrom++\n\n start = searchFrom\n\n const nextBoundaryIndex = body.indexOf(boundaryBuffer, searchFrom)\n if (nextBoundaryIndex === -1) break\n\n let partEnd = nextBoundaryIndex\n if (partEnd >= 2 && body[partEnd - 2] === 13 && body[partEnd - 1] === 10) {\n partEnd -= 2\n }\n\n const partData = body.slice(start, partEnd)\n\n const headerEndIndex = partData.indexOf(Buffer.from('\\r\\n\\r\\n'))\n if (headerEndIndex === -1) {\n searchFrom = nextBoundaryIndex\n continue\n }\n\n const headerSection = partData.slice(0, headerEndIndex).toString('utf-8')\n const contentData = partData.slice(headerEndIndex + 4)\n\n const disposition = parseDisposition(headerSection)\n if (disposition === undefined) {\n searchFrom = nextBoundaryIndex\n continue\n }\n\n if (disposition.filename !== undefined) {\n const contentType = parseContentType(headerSection)\n result.push({\n type: 'file',\n name: disposition.name,\n filename: disposition.filename,\n mimeType: contentType,\n data: Buffer.from(contentData),\n })\n } else {\n result.push({\n type: 'field',\n name: disposition.name,\n value: contentData.toString('utf-8').trim(),\n })\n }\n\n searchFrom = nextBoundaryIndex\n }\n\n return result\n}\n\ninterface DispositionInfo {\n name: string\n filename?: string\n}\n\nfunction parseDisposition(headerSection: string): DispositionInfo | undefined {\n const match = headerSection.match(\n /content-disposition:\\s*form-data;\\s*(.+)/i,\n )\n if (match === null) return undefined\n\n const params = match[1] as string\n const nameMatch = params.match(/name=\"([^\"]*)\"/i)\n const filenameMatch = params.match(/filename=\"([^\"]*)\"/i)\n\n if (nameMatch === null) return undefined\n\n return {\n name: nameMatch[1] as string,\n filename: filenameMatch?.[1],\n }\n}\n\nfunction parseContentType(headerSection: string): string {\n const match = headerSection.match(/content-type:\\s*([^\\s;]+)/i)\n return match?.[1] ?? 'application/octet-stream'\n}\n","import { createReadStream, stat } from \"node:fs\";\nimport type { ServerResponse } from \"node:http\";\nimport { basename, extname } from \"node:path\";\nimport type { Readable } from \"node:stream\";\nimport { promisify } from \"node:util\";\nimport { type CookieOptions, clearCookie, serializeCookie } from \"./cookie\";\nimport { HeadersMap } from \"./headers\";\nimport { HttpStatus } from \"./status\";\n\nconst statAsync = promisify(stat);\n\nconst MIME_TYPES: Record<string, string> = {\n\t\".html\": \"text/html\",\n\t\".css\": \"text/css\",\n\t\".js\": \"application/javascript\",\n\t\".mjs\": \"application/javascript\",\n\t\".json\": \"application/json\",\n\t\".png\": \"image/png\",\n\t\".jpg\": \"image/jpeg\",\n\t\".jpeg\": \"image/jpeg\",\n\t\".gif\": \"image/gif\",\n\t\".svg\": \"image/svg+xml\",\n\t\".webp\": \"image/webp\",\n\t\".ico\": \"image/x-icon\",\n\t\".pdf\": \"application/pdf\",\n\t\".txt\": \"text/plain\",\n\t\".xml\": \"application/xml\",\n\t\".zip\": \"application/zip\",\n\t\".woff\": \"font/woff\",\n\t\".woff2\": \"font/woff2\",\n\t\".ttf\": \"font/ttf\",\n\t\".eot\": \"application/vnd.ms-fontobject\",\n\t\".mp4\": \"video/mp4\",\n\t\".webm\": \"video/webm\",\n\t\".mp3\": \"audio/mpeg\",\n\t\".wav\": \"audio/wav\",\n};\n\nexport interface FileOptions {\n\troot?: string;\n\tmaxAge?: number;\n\tacceptRanges?: boolean;\n\tcacheControl?: boolean;\n\tetag?: boolean;\n\tlastModified?: boolean;\n\theaders?: Record<string, string>;\n}\n\nexport class SuperResponse {\n\tprivate raw: ServerResponse;\n\tprivate _statusCode: number = HttpStatus.OK;\n\tprivate _headers = new HeadersMap();\n\tprivate _cookies: string[] = [];\n\tprivate _body: string | Buffer | null = null;\n\tprivate _sent = false;\n\tprivate _contentTypeSet = false;\n\n\tconstructor(raw: ServerResponse) {\n\t\tthis.raw = raw;\n\t}\n\n\tstatus(code: number): this {\n\t\tthis._statusCode = code;\n\t\treturn this;\n\t}\n\n\theader(name: string, value: string): this {\n\t\tthis._headers.set(name, value);\n\t\treturn this;\n\t}\n\n\tsetHeader(name: string, value: string): this {\n\t\treturn this.header(name, value);\n\t}\n\n\tgetHeader(name: string): string | undefined {\n\t\treturn this._headers.get(name);\n\t}\n\n\tremoveHeader(name: string): this {\n\t\tthis._headers.delete(name);\n\t\treturn this;\n\t}\n\n\thasHeader(name: string): boolean {\n\t\treturn this._headers.has(name);\n\t}\n\n\ttype(contentType: string): this {\n\t\tthis._headers.set(\"content-type\", contentType);\n\t\tthis._contentTypeSet = true;\n\t\treturn this;\n\t}\n\n\tjson<T>(data: T, status?: number): this {\n\t\tif (status !== undefined) this._statusCode = status;\n\t\tconst body = JSON.stringify(data);\n\t\treturn this.send(body, undefined, \"application/json\");\n\t}\n\n\tsend(body: string | Buffer, status?: number, contentType?: string): this {\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\treturn this;\n\t}\n\n\thtml(html: string, status?: number): this {\n\t\treturn this.send(html, status, \"text/html; charset=utf-8\");\n\t}\n\n\tredirect(\n\t\turl: string,\n\t\tstatus: 301 | 302 | 307 | 308 = HttpStatus.FOUND as 302,\n\t): this {\n\t\tthis._statusCode = status;\n\t\tthis._headers.set(\"location\", url);\n\t\tthis._body = null;\n\t\treturn this;\n\t}\n\n\tstream(stream: Readable, status?: number): this {\n\t\tif (status !== undefined) this._statusCode = status;\n\t\tthis.flushHeaders();\n\t\tthis.raw.statusCode = this._statusCode;\n\t\tstream.pipe(this.raw);\n\t\tstream.on(\"end\", () => {\n\t\t\tthis._sent = true;\n\t\t});\n\t\tstream.on(\"error\", (_err: Error) => {\n\t\t\tif (!this._sent) {\n\t\t\t\tthis._sent = true;\n\t\t\t\tthis.raw.statusCode = HttpStatus.INTERNAL_SERVER_ERROR;\n\t\t\t\tthis.raw.end();\n\t\t\t}\n\t\t});\n\t\treturn this;\n\t}\n\n\tasync file(filePath: string, options?: FileOptions): Promise<this> {\n\t\tconst fullPath = options?.root\n\t\t\t? joinPath(options.root, filePath)\n\t\t\t: filePath;\n\n\t\ttry {\n\t\t\tconst stats = await statAsync(fullPath);\n\n\t\t\tif (!stats.isFile()) {\n\t\t\t\tthis._statusCode = HttpStatus.NOT_FOUND;\n\t\t\t\tthis._body = null;\n\t\t\t\treturn this;\n\t\t\t}\n\n\t\t\tconst ext = extname(fullPath);\n\t\t\tconst mimeType = MIME_TYPES[ext] ?? \"application/octet-stream\";\n\n\t\t\tthis._headers.set(\"content-type\", mimeType);\n\t\t\tthis._headers.set(\"content-length\", String(stats.size));\n\n\t\t\tif (options?.cacheControl !== false) {\n\t\t\t\tconst maxAge = options?.maxAge ?? 0;\n\t\t\t\tthis._headers.set(\"cache-control\", `public, max-age=${maxAge}`);\n\t\t\t}\n\n\t\t\tif (options?.lastModified !== false) {\n\t\t\t\tthis._headers.set(\"last-modified\", stats.mtime.toUTCString());\n\t\t\t}\n\n\t\t\tif (options?.headers !== undefined) {\n\t\t\t\tfor (const [key, value] of Object.entries(options.headers)) {\n\t\t\t\t\tthis._headers.set(key, value);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.flushHeaders();\n\t\t\tthis.raw.statusCode = this._statusCode;\n\t\t\tconst readStream = createReadStream(fullPath);\n\t\t\treadStream.pipe(this.raw);\n\t\t\treadStream.on(\"end\", () => {\n\t\t\t\tthis._sent = true;\n\t\t\t});\n\t\t\treadStream.on(\"error\", () => {\n\t\t\t\tif (!this._sent) {\n\t\t\t\t\tthis._sent = true;\n\t\t\t\t\tthis.raw.statusCode = HttpStatus.INTERNAL_SERVER_ERROR;\n\t\t\t\t\tthis.raw.end();\n\t\t\t\t}\n\t\t\t});\n\t\t} catch {\n\t\t\tthis._statusCode = HttpStatus.NOT_FOUND;\n\t\t\tthis._body = null;\n\t\t}\n\n\t\treturn this;\n\t}\n\n\tasync download(filePath: string, filename?: string): Promise<this> {\n\t\tconst downloadName = filename ?? basename(filePath);\n\n\t\tthis._headers.set(\n\t\t\t\"content-disposition\",\n\t\t\t`attachment; filename=\"${downloadName}\"`,\n\t\t);\n\n\t\tawait this.file(filePath);\n\t\treturn this;\n\t}\n\n\tattachment(filename?: string): this {\n\t\tif (filename !== undefined) {\n\t\t\tthis._headers.set(\n\t\t\t\t\"content-disposition\",\n\t\t\t\t`attachment; filename=\"${filename}\"`,\n\t\t\t);\n\t\t} else {\n\t\t\tthis._headers.set(\"content-disposition\", \"attachment\");\n\t\t}\n\t\treturn this;\n\t}\n\n\tcookie(name: string, value: string, options?: CookieOptions): this {\n\t\tthis._cookies.push(serializeCookie(name, value, options));\n\t\treturn this;\n\t}\n\n\tclearCookie(name: string, options?: CookieOptions): this {\n\t\tthis._cookies.push(clearCookie(name, options));\n\t\treturn this;\n\t}\n\n\tget statusCode(): number {\n\t\treturn this._statusCode;\n\t}\n\n\tget headersSent(): boolean {\n\t\treturn this._sent;\n\t}\n\n\tget rawResponse(): ServerResponse {\n\t\treturn this.raw;\n\t}\n\n\tasync flush(): Promise<void> {\n\t\tif (this._sent) return;\n\t\tthis._sent = true;\n\n\t\tthis.flushHeaders();\n\n\t\tthis.raw.statusCode = this._statusCode;\n\n\t\tif (this._body !== null) {\n\t\t\tthis.raw.end(this._body);\n\t\t} else {\n\t\t\tthis.raw.end();\n\t\t}\n\t}\n\n\tprivate flushHeaders(): void {\n\t\tif (this._cookies.length > 0) {\n\t\t\tthis.raw.setHeader(\"Set-Cookie\", this._cookies);\n\t\t}\n\n\t\tfor (const [name, value] of this._headers.entries()) {\n\t\t\tif (name.toLowerCase() !== \"set-cookie\") {\n\t\t\t\tthis.raw.setHeader(name, value);\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction joinPath(root: string, filePath: string): string {\n\tconst normalizedRoot = root.replace(/\\\\/g, \"/\").replace(/\\/$/, \"\");\n\tconst normalizedPath = filePath.replace(/\\\\/g, \"/\").replace(/^\\//, \"\");\n\treturn `${normalizedRoot}/${normalizedPath}`;\n}\n"],"mappings":"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","names":["basename","extname","extname","basename"]}
|
|
1
|
+
{"version":3,"sources":["../../../src/server/http/status.ts","../../../src/server/http/headers.ts","../../../src/server/http/cookie.ts","../../../src/server/http/upload.ts","../../../src/server/http/request.ts","../../../src/server/http/response.ts"],"sourcesContent":["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","export class HeadersMap {\n private data: Map<string, string[]>\n\n constructor(initial?: Record<string, string | string[]>) {\n this.data = new Map()\n if (initial) {\n for (const key of Object.keys(initial)) {\n const value = initial[key]\n if (value !== undefined) {\n this.set(key, Array.isArray(value) ? value.join(', ') : value)\n }\n }\n }\n }\n\n get(name: string): string | undefined {\n const values = this.data.get(name.toLowerCase())\n if (values !== undefined && values.length > 0) {\n return values[0]\n }\n return undefined\n }\n\n getAll(name: string): string[] {\n const values = this.data.get(name.toLowerCase())\n return values ?? []\n }\n\n set(name: string, value: string): void {\n this.data.set(name.toLowerCase(), [value])\n }\n\n append(name: string, value: string): void {\n const key = name.toLowerCase()\n const existing = this.data.get(key)\n if (existing !== undefined) {\n existing.push(value)\n } else {\n this.data.set(key, [value])\n }\n }\n\n has(name: string): boolean {\n return this.data.has(name.toLowerCase())\n }\n\n delete(name: string): void {\n this.data.delete(name.toLowerCase())\n }\n\n *entries(): IterableIterator<[string, string]> {\n for (const [key, values] of this.data) {\n for (const value of values) {\n yield [key, value]\n }\n }\n }\n\n *keys(): IterableIterator<string> {\n for (const key of this.data.keys()) {\n yield key\n }\n }\n\n *values(): IterableIterator<string> {\n for (const [, values] of this.data) {\n for (const value of values) {\n yield value\n }\n }\n }\n\n toJSON(): Record<string, string | string[]> {\n const result: Record<string, string | string[]> = {}\n for (const [key, values] of this.data) {\n result[key] = values.length === 1 ? (values[0] as string) : values\n }\n return result\n }\n\n toNodeHeaders(): Record<string, string | string[]> {\n const result: Record<string, string | string[]> = {}\n for (const [key, values] of this.data) {\n if (key === 'set-cookie') {\n result[key] = values\n } else {\n result[key] = values.join(', ')\n }\n }\n return result\n }\n\n get size(): number {\n return this.data.size\n }\n\n [Symbol.iterator](): IterableIterator<[string, string]> {\n return this.entries()\n }\n}\n","export interface CookieOptions {\n maxAge?: number\n expires?: Date\n path?: string\n domain?: string\n secure?: boolean\n httpOnly?: boolean\n sameSite?: 'strict' | 'lax' | 'none'\n signed?: boolean\n}\n\nexport function parseCookies(header: string): Record<string, string> {\n const result: Record<string, string> = {}\n\n if (!header) return result\n\n const pairs = header.split(';')\n\n for (const pair of pairs) {\n const trimmed = pair.trim()\n if (!trimmed) continue\n\n const eqIndex = trimmed.indexOf('=')\n if (eqIndex === -1) {\n result[trimmed] = ''\n continue\n }\n\n const name = trimmed.slice(0, eqIndex).trim()\n let value = trimmed.slice(eqIndex + 1).trim()\n\n if (value.startsWith('\"') && value.endsWith('\"')) {\n value = value.slice(1, -1)\n }\n\n if (name) {\n result[decodeURIComponent(name)] = decodeURIComponent(value)\n }\n }\n\n return result\n}\n\nfunction serializeCookieValue(name: string, value: string): string {\n return `${encodeURIComponent(name)}=${encodeURIComponent(value)}`\n}\n\nexport function serializeCookie(\n name: string,\n value: string,\n options?: CookieOptions,\n): string {\n const parts: string[] = [serializeCookieValue(name, value)]\n\n if (options) {\n if (options.maxAge !== undefined) {\n parts.push(`Max-Age=${Math.floor(options.maxAge)}`)\n }\n\n if (options.expires !== undefined) {\n parts.push(`Expires=${options.expires.toUTCString()}`)\n }\n\n if (options.path !== undefined) {\n parts.push(`Path=${options.path}`)\n } else {\n parts.push('Path=/')\n }\n\n if (options.domain !== undefined) {\n parts.push(`Domain=${options.domain}`)\n }\n\n if (options.secure) {\n parts.push('Secure')\n }\n\n if (options.httpOnly) {\n parts.push('HttpOnly')\n }\n\n if (options.sameSite !== undefined) {\n parts.push(`SameSite=${options.sameSite}`)\n }\n }\n\n return parts.join('; ')\n}\n\nexport function clearCookie(name: string, options?: CookieOptions): string {\n return serializeCookie(name, '', {\n ...options,\n maxAge: 0,\n expires: new Date(0),\n })\n}\n","import { randomUUID } from 'node:crypto'\nimport { writeFile, readFile, unlink, mkdir } from 'node:fs/promises'\nimport { join, extname, basename, dirname } from 'node:path'\nimport { tmpdir } from 'node:os'\n\nexport interface UploadedFile {\n readonly fieldName: string\n readonly originalName: string\n readonly mimeType: string\n readonly size: number\n readonly path: string\n readonly extension: string\n move(destination: string, filename?: string): Promise<string>\n toBuffer(): Promise<Buffer>\n toBase64(): string\n isImage(): boolean\n isVideo(): boolean\n}\n\nconst IMAGE_MIME_TYPES = new Set([\n 'image/jpeg',\n 'image/png',\n 'image/gif',\n 'image/webp',\n 'image/svg+xml',\n 'image/bmp',\n 'image/tiff',\n 'image/avif',\n])\n\nconst VIDEO_MIME_TYPES = new Set([\n 'video/mp4',\n 'video/mpeg',\n 'video/webm',\n 'video/ogg',\n 'video/quicktime',\n 'video/x-msvideo',\n 'video/x-matroska',\n])\n\nexport class SuperUploadedFile implements UploadedFile {\n readonly fieldName: string\n readonly originalName: string\n readonly mimeType: string\n readonly size: number\n readonly path: string\n readonly extension: string\n private buffer: Buffer | null\n\n constructor(opts: {\n fieldName: string\n originalName: string\n mimeType: string\n size: number\n path: string\n buffer?: Buffer\n }) {\n this.fieldName = opts.fieldName\n this.originalName = opts.originalName\n this.mimeType = opts.mimeType\n this.size = opts.size\n this.path = opts.path\n this.extension = extname(opts.originalName).toLowerCase()\n this.buffer = opts.buffer ?? null\n }\n\n async move(destination: string, filename?: string): Promise<string> {\n const destName = filename ?? basename(this.path)\n const destPath = join(destination, destName)\n\n await mkdir(dirname(destPath), { recursive: true })\n\n const buf = await this.toBuffer()\n await writeFile(destPath, buf)\n\n return destPath\n }\n\n async toBuffer(): Promise<Buffer> {\n if (this.buffer !== null) return this.buffer\n this.buffer = await readFile(this.path)\n return this.buffer\n }\n\n toBase64(): string {\n if (this.buffer === null) {\n throw new Error(\n 'Buffer not loaded. Call toBuffer() first or read the file into memory.',\n )\n }\n return this.buffer.toString('base64')\n }\n\n isImage(): boolean {\n return IMAGE_MIME_TYPES.has(this.mimeType)\n }\n\n isVideo(): boolean {\n return VIDEO_MIME_TYPES.has(this.mimeType)\n }\n\n static async createFromBuffer(\n fieldName: string,\n originalName: string,\n mimeType: string,\n buffer: Buffer,\n tempDir?: string,\n ): Promise<SuperUploadedFile> {\n const tmp = tempDir ?? tmpdir()\n const fileName = `${randomUUID()}${extname(originalName)}`\n const filePath = join(tmp, fileName)\n\n await writeFile(filePath, buffer)\n\n return new SuperUploadedFile({\n fieldName,\n originalName,\n mimeType: mimeType || 'application/octet-stream',\n size: buffer.length,\n path: filePath,\n buffer,\n })\n }\n\n async cleanup(): Promise<void> {\n try {\n await unlink(this.path)\n } catch {\n // File may have been moved or already deleted\n }\n }\n}\n","import type { IncomingMessage } from 'node:http'\nimport { HeadersMap } from './headers'\nimport { parseCookies } from './cookie'\nimport { SuperUploadedFile } from './upload'\n\nexport interface Schema<T = unknown> {\n parse(input: unknown): T\n validate(\n input: unknown,\n ): { success: boolean; data?: T; errors?: { message: string; path?: string }[] }\n}\n\ninterface ParsedMultipartField {\n type: 'field'\n name: string\n value: string\n}\n\ninterface ParsedMultipartFile {\n type: 'file'\n name: string\n filename: string\n mimeType: string\n data: Buffer\n}\n\ntype MultipartPart = ParsedMultipartField | ParsedMultipartFile\n\ninterface BodyCache {\n raw: Buffer\n parsed: unknown\n text: string\n json: unknown\n formData: Record<string, string> | null\n files: Record<string, SuperUploadedFile> | null\n multipartParsed: MultipartPart[] | null\n}\n\nexport class SuperRequest {\n private raw: IncomingMessage\n private _headers: HeadersMap\n private _query: Record<string, string | string[]>\n private _cookies: Record<string, string> | null = null\n private _ip: string\n private _params: Record<string, string> = {}\n private bodyCache: BodyCache | null = null\n private _bodyReadPromise: Promise<BodyCache> | null = null\n\n constructor(raw: IncomingMessage) {\n this.raw = raw\n\n this._headers = new HeadersMap(\n raw.headers as Record<string, string | string[]>,\n )\n\n const parsedUrl = new URL(raw.url ?? '/', 'http://localhost')\n this._query = parseQueryParams(parsedUrl.searchParams)\n\n this._ip = parseIp(raw)\n\n this.path = parsedUrl.pathname\n this.url = raw.url ?? '/'\n this.method = (raw.method ?? 'GET').toUpperCase()\n }\n\n readonly method: string\n readonly url: string\n readonly path: string\n\n get headers(): HeadersMap {\n return this._headers\n }\n\n get query(): Record<string, string | string[]> {\n return this._query\n }\n\n get params(): Record<string, string> {\n return this._params\n }\n\n set params(value: Record<string, string>) {\n this._params = value\n }\n\n get ip(): string {\n return this._ip\n }\n\n private async ensureBody(): Promise<BodyCache> {\n if (this.bodyCache !== null) return this.bodyCache\n\n if (this._bodyReadPromise === null) {\n this._bodyReadPromise = this.readBodyFromStream()\n }\n\n this.bodyCache = await this._bodyReadPromise\n return this.bodyCache\n }\n\n private async readBodyFromStream(): Promise<BodyCache> {\n const chunks: Buffer[] = []\n const MAX_BODY_SIZE = 10 * 1024 * 1024; // 10MB default\n let totalSize = 0;\n for await (const chunk of this.raw) {\n const buf = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);\n totalSize += buf.length;\n if (totalSize > MAX_BODY_SIZE) {\n throw new Error('Request body too large. Maximum size is 10MB.');\n }\n chunks.push(buf);\n }\n const raw = Buffer.concat(chunks)\n const text = raw.toString('utf-8')\n\n let json: unknown = undefined\n if (this.isContentType('application/json')) {\n try {\n json = JSON.parse(text)\n } catch {\n json = undefined\n }\n }\n\n let formData: Record<string, string> | null = null\n let multipartParsed: MultipartPart[] | null = null\n let files: Record<string, SuperUploadedFile> | null = null\n\n if (this.isContentType('application/x-www-form-urlencoded')) {\n formData = parseUrlEncoded(text)\n } else if (this.isContentType('multipart/form-data')) {\n const boundary = this.getMultipartBoundary()\n if (boundary !== undefined) {\n multipartParsed = parseMultipartBody(raw, boundary)\n formData = {}\n files = {}\n for (const part of multipartParsed) {\n if (part.type === 'field') {\n formData[part.name] = part.value\n } else if (part.type === 'file') {\n const uploadedFile = await SuperUploadedFile.createFromBuffer(\n part.name,\n part.filename,\n part.mimeType,\n part.data,\n )\n files[part.name] = uploadedFile\n }\n }\n }\n }\n\n return {\n raw,\n text,\n json,\n parsed: json ?? text,\n formData,\n files,\n multipartParsed,\n }\n }\n\n private isContentType(expected: string): boolean {\n const ct = this._headers.get('content-type')\n if (ct === undefined) return false\n return ct.toLowerCase().startsWith(expected)\n }\n\n private getMultipartBoundary(): string | undefined {\n const ct = this._headers.get('content-type')\n if (ct === undefined) return undefined\n const match = ct.match(/boundary=(?:\"([^\"]+)\"|([^;]+))/i)\n if (match !== null) {\n return match[1] ?? match[2]\n }\n return undefined\n }\n\n async body(): Promise<unknown> {\n const cache = await this.ensureBody()\n return cache.parsed\n }\n\n async json<T = unknown>(): Promise<T> {\n const cache = await this.ensureBody()\n if (cache.json !== undefined) return cache.json as T\n throw new Error('Request body is not valid JSON')\n }\n\n async text(): Promise<string> {\n const cache = await this.ensureBody()\n return cache.text\n }\n\n async formData(): Promise<Record<string, string>> {\n const cache = await this.ensureBody()\n if (cache.formData !== null) return cache.formData\n\n if (cache.multipartParsed !== null) {\n const result: Record<string, string> = {}\n for (const part of cache.multipartParsed) {\n if (part.type === 'field') {\n result[part.name] = part.value\n }\n }\n return result\n }\n\n return {}\n }\n\n async file(name: string): Promise<SuperUploadedFile | undefined> {\n const cache = await this.ensureBody()\n if (cache.files !== null) {\n return cache.files[name]\n }\n return undefined\n }\n\n async files(): Promise<Record<string, SuperUploadedFile>> {\n const cache = await this.ensureBody()\n return cache.files ?? {}\n }\n\n cookie(name: string): string | undefined {\n if (this._cookies === null) {\n const cookieHeader = this._headers.get('cookie')\n this._cookies = cookieHeader !== undefined\n ? parseCookies(cookieHeader)\n : {}\n }\n return this._cookies[name]\n }\n\n async validate<T>(schema: Schema<T>): Promise<T> {\n const data = await this.body()\n const result = schema.validate(data)\n if (!result.success) {\n const messages = (result.errors ?? [])\n .map((e) => {\n const path = e.path ?? ''\n return path ? `${path}: ${e.message}` : e.message\n })\n .join('; ')\n throw new ValidationError(messages, result.errors ?? [])\n }\n return result.data as T\n }\n\n isAjax(): boolean {\n const requestedWith = this._headers.get('x-requested-with')\n return requestedWith?.toLowerCase() === 'xmlhttprequest'\n }\n\n wantsJson(): boolean {\n const accept = this._headers.get('accept')\n if (accept !== undefined && accept.includes('application/json')) {\n return true\n }\n return this.isAjax()\n }\n\n bearerToken(): string | undefined {\n const auth = this._headers.get('authorization')\n if (auth === undefined) return undefined\n const match = auth.match(/^Bearer\\s+(.+)$/i)\n return match?.[1]\n }\n\n get rawRequest(): IncomingMessage {\n return this.raw\n }\n}\n\nexport class ValidationError extends Error {\n constructor(\n message: string,\n readonly errors: { message: string; path?: string }[],\n ) {\n super(message)\n this.name = 'ValidationError'\n }\n}\n\nfunction parseQueryParams(\n searchParams: URLSearchParams,\n): Record<string, string | string[]> {\n const result: Record<string, string | string[]> = {}\n for (const key of searchParams.keys()) {\n const values = searchParams.getAll(key)\n result[key] = values.length === 1 ? (values[0] as string) : values\n }\n return result\n}\n\nfunction parseIp(req: IncomingMessage): string {\n const forwarded = req.headers['x-forwarded-for']\n if (forwarded !== undefined) {\n const first = Array.isArray(forwarded) ? forwarded[0] : forwarded.split(',')[0]\n if (first !== undefined) return first.trim()\n }\n\n const realIp = req.headers['x-real-ip']\n if (realIp !== undefined) {\n return Array.isArray(realIp) ? realIp[0] as string : realIp\n }\n\n const remote = req.socket.remoteAddress\n if (remote !== undefined) {\n if (remote.startsWith('::ffff:')) return remote.slice(7)\n return remote\n }\n\n return '127.0.0.1'\n}\n\nfunction parseUrlEncoded(text: string): Record<string, string> {\n const result: Record<string, string> = {}\n const pairs = text.split('&')\n for (const pair of pairs) {\n if (!pair) continue\n const eqIndex = pair.indexOf('=')\n if (eqIndex === -1) {\n result[decodeURIComponent(pair)] = ''\n } else {\n const key = decodeURIComponent(pair.slice(0, eqIndex))\n const value = decodeURIComponent(pair.slice(eqIndex + 1))\n result[key] = value\n }\n }\n return result\n}\n\nfunction parseMultipartBody(\n body: Buffer,\n boundary: string,\n): MultipartPart[] {\n const result: MultipartPart[] = []\n const boundaryBuffer = Buffer.from(`--${boundary}`)\n\n let start = 0\n let searchFrom = 0\n\n while (true) {\n const boundaryIndex = body.indexOf(boundaryBuffer, searchFrom)\n if (boundaryIndex === -1) break\n\n searchFrom = boundaryIndex + boundaryBuffer.length\n\n if (\n searchFrom < body.length &&\n body[searchFrom] === 45 &&\n body[searchFrom + 1] === 45\n ) {\n break\n }\n\n if (searchFrom >= body.length) break\n\n if (body[searchFrom] === 13) searchFrom++\n if (body[searchFrom] === 10) searchFrom++\n\n start = searchFrom\n\n const nextBoundaryIndex = body.indexOf(boundaryBuffer, searchFrom)\n if (nextBoundaryIndex === -1) break\n\n let partEnd = nextBoundaryIndex\n if (partEnd >= 2 && body[partEnd - 2] === 13 && body[partEnd - 1] === 10) {\n partEnd -= 2\n }\n\n const partData = body.slice(start, partEnd)\n\n const headerEndIndex = partData.indexOf(Buffer.from('\\r\\n\\r\\n'))\n if (headerEndIndex === -1) {\n searchFrom = nextBoundaryIndex\n continue\n }\n\n const headerSection = partData.slice(0, headerEndIndex).toString('utf-8')\n const contentData = partData.slice(headerEndIndex + 4)\n\n const disposition = parseDisposition(headerSection)\n if (disposition === undefined) {\n searchFrom = nextBoundaryIndex\n continue\n }\n\n if (disposition.filename !== undefined) {\n const contentType = parseContentType(headerSection)\n result.push({\n type: 'file',\n name: disposition.name,\n filename: disposition.filename,\n mimeType: contentType,\n data: Buffer.from(contentData),\n })\n } else {\n result.push({\n type: 'field',\n name: disposition.name,\n value: contentData.toString('utf-8').trim(),\n })\n }\n\n searchFrom = nextBoundaryIndex\n }\n\n return result\n}\n\ninterface DispositionInfo {\n name: string\n filename?: string\n}\n\nfunction parseDisposition(headerSection: string): DispositionInfo | undefined {\n const match = headerSection.match(\n /content-disposition:\\s*form-data;\\s*(.+)/i,\n )\n if (match === null) return undefined\n\n const params = match[1] as string\n const nameMatch = params.match(/name=\"([^\"]*)\"/i)\n const filenameMatch = params.match(/filename=\"([^\"]*)\"/i)\n\n if (nameMatch === null) return undefined\n\n return {\n name: nameMatch[1] as string,\n filename: filenameMatch?.[1],\n }\n}\n\nfunction parseContentType(headerSection: string): string {\n const match = headerSection.match(/content-type:\\s*([^\\s;]+)/i)\n return match?.[1] ?? 'application/octet-stream'\n}\n","import { createReadStream, stat } from \"node:fs\";\nimport type { ServerResponse } from \"node:http\";\nimport { basename, extname, resolve } from \"node:path\";\nimport type { Readable } from \"node:stream\";\nimport { promisify } from \"node:util\";\nimport { type CookieOptions, clearCookie, serializeCookie } from \"./cookie\";\nimport { HeadersMap } from \"./headers\";\nimport { HttpStatus } from \"./status\";\n\nconst statAsync = promisify(stat);\n\nconst MIME_TYPES: Record<string, string> = {\n\t\".html\": \"text/html\",\n\t\".css\": \"text/css\",\n\t\".js\": \"application/javascript\",\n\t\".mjs\": \"application/javascript\",\n\t\".json\": \"application/json\",\n\t\".png\": \"image/png\",\n\t\".jpg\": \"image/jpeg\",\n\t\".jpeg\": \"image/jpeg\",\n\t\".gif\": \"image/gif\",\n\t\".svg\": \"image/svg+xml\",\n\t\".webp\": \"image/webp\",\n\t\".ico\": \"image/x-icon\",\n\t\".pdf\": \"application/pdf\",\n\t\".txt\": \"text/plain\",\n\t\".xml\": \"application/xml\",\n\t\".zip\": \"application/zip\",\n\t\".woff\": \"font/woff\",\n\t\".woff2\": \"font/woff2\",\n\t\".ttf\": \"font/ttf\",\n\t\".eot\": \"application/vnd.ms-fontobject\",\n\t\".mp4\": \"video/mp4\",\n\t\".webm\": \"video/webm\",\n\t\".mp3\": \"audio/mpeg\",\n\t\".wav\": \"audio/wav\",\n};\n\nexport interface FileOptions {\n\troot?: string;\n\tmaxAge?: number;\n\tacceptRanges?: boolean;\n\tcacheControl?: boolean;\n\tetag?: boolean;\n\tlastModified?: boolean;\n\theaders?: Record<string, string>;\n}\n\nexport class SuperResponse {\n\tprivate raw: ServerResponse;\n\tprivate _statusCode: number = HttpStatus.OK;\n\tprivate _headers = new HeadersMap();\n\tprivate _cookies: string[] = [];\n\tprivate _body: string | Buffer | null = null;\n\tprivate _sent = false;\n\tprivate _contentTypeSet = false;\n\n\tconstructor(raw: ServerResponse) {\n\t\tthis.raw = raw;\n\t}\n\n\tstatus(code: number): this {\n\t\tthis._statusCode = code;\n\t\treturn this;\n\t}\n\n\theader(name: string, value: string): this {\n\t\tthis._headers.set(name, value);\n\t\treturn this;\n\t}\n\n\tsetHeader(name: string, value: string): this {\n\t\treturn this.header(name, value);\n\t}\n\n\tgetHeader(name: string): string | undefined {\n\t\treturn this._headers.get(name);\n\t}\n\n\tremoveHeader(name: string): this {\n\t\tthis._headers.delete(name);\n\t\treturn this;\n\t}\n\n\thasHeader(name: string): boolean {\n\t\treturn this._headers.has(name);\n\t}\n\n\ttype(contentType: string): this {\n\t\tthis._headers.set(\"content-type\", contentType);\n\t\tthis._contentTypeSet = true;\n\t\treturn this;\n\t}\n\n\tjson<T>(data: T, status?: number): this {\n\t\tif (status !== undefined) this._statusCode = status;\n\t\tconst body = JSON.stringify(data);\n\t\treturn this.send(body, undefined, \"application/json\");\n\t}\n\n\tsend(body: string | Buffer, status?: number, contentType?: string): this {\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\treturn this;\n\t}\n\n\thtml(html: string, status?: number): this {\n\t\treturn this.send(html, status, \"text/html; charset=utf-8\");\n\t}\n\n\tredirect(\n\t\turl: string,\n\t\tstatus: 301 | 302 | 307 | 308 = HttpStatus.FOUND as 302,\n\t): this {\n\t\t// Prevent open redirect / CRLF injection\n\t\tif (url.includes('\\r') || url.includes('\\n')) {\n\t\t\tthrow new Error('Invalid redirect URL');\n\t\t}\n\t\tthis._statusCode = status;\n\t\tthis._headers.set(\"location\", url);\n\t\tthis._body = null;\n\t\treturn this;\n\t}\n\n\tstream(stream: Readable, status?: number): this {\n\t\tif (status !== undefined) this._statusCode = status;\n\t\tthis.flushHeaders();\n\t\tthis.raw.statusCode = this._statusCode;\n\t\tstream.pipe(this.raw);\n\t\tstream.on(\"end\", () => {\n\t\t\tthis._sent = true;\n\t\t});\n\t\tstream.on(\"error\", (_err: Error) => {\n\t\t\tif (!this._sent) {\n\t\t\t\tthis._sent = true;\n\t\t\t\tthis.raw.statusCode = HttpStatus.INTERNAL_SERVER_ERROR;\n\t\t\t\tthis.raw.end();\n\t\t\t}\n\t\t});\n\t\treturn this;\n\t}\n\n\tasync file(filePath: string, options?: FileOptions): Promise<this> {\n\t\tconst fullPath = options?.root\n\t\t\t? joinPath(options.root, filePath)\n\t\t\t: filePath;\n\n\t\t// Path traversal protection\n\t\tconst resolved = resolve(fullPath);\n\t\tconst root = options?.root ? resolve(options.root) : null;\n\t\tif (root !== null && !resolved.startsWith(root)) {\n\t\t\tthis._statusCode = HttpStatus.FORBIDDEN;\n\t\t\tthis._body = null;\n\t\t\treturn this;\n\t\t}\n\n\t\ttry {\n\t\t\tconst stats = await statAsync(fullPath);\n\n\t\t\tif (!stats.isFile()) {\n\t\t\t\tthis._statusCode = HttpStatus.NOT_FOUND;\n\t\t\t\tthis._body = null;\n\t\t\t\treturn this;\n\t\t\t}\n\n\t\t\tconst ext = extname(fullPath);\n\t\t\tconst mimeType = MIME_TYPES[ext] ?? \"application/octet-stream\";\n\n\t\t\tthis._headers.set(\"content-type\", mimeType);\n\t\t\tthis._headers.set(\"content-length\", String(stats.size));\n\n\t\t\tif (options?.cacheControl !== false) {\n\t\t\t\tconst maxAge = options?.maxAge ?? 0;\n\t\t\t\tthis._headers.set(\"cache-control\", `public, max-age=${maxAge}`);\n\t\t\t}\n\n\t\t\tif (options?.lastModified !== false) {\n\t\t\t\tthis._headers.set(\"last-modified\", stats.mtime.toUTCString());\n\t\t\t}\n\n\t\t\tif (options?.headers !== undefined) {\n\t\t\t\tfor (const [key, value] of Object.entries(options.headers)) {\n\t\t\t\t\tthis._headers.set(key, value);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.flushHeaders();\n\t\t\tthis.raw.statusCode = this._statusCode;\n\t\t\tconst readStream = createReadStream(fullPath);\n\t\t\treadStream.pipe(this.raw);\n\t\t\treadStream.on(\"end\", () => {\n\t\t\t\tthis._sent = true;\n\t\t\t});\n\t\t\treadStream.on(\"error\", () => {\n\t\t\t\tif (!this._sent) {\n\t\t\t\t\tthis._sent = true;\n\t\t\t\t\tthis.raw.statusCode = HttpStatus.INTERNAL_SERVER_ERROR;\n\t\t\t\t\tthis.raw.end();\n\t\t\t\t}\n\t\t\t});\n\t\t} catch {\n\t\t\tthis._statusCode = HttpStatus.NOT_FOUND;\n\t\t\tthis._body = null;\n\t\t}\n\n\t\treturn this;\n\t}\n\n\tasync download(filePath: string, filename?: string): Promise<this> {\n\t\tconst downloadName = filename ?? basename(filePath);\n\n\t\tthis._headers.set(\n\t\t\t\"content-disposition\",\n\t\t\t`attachment; filename=\"${downloadName}\"`,\n\t\t);\n\n\t\tawait this.file(filePath);\n\t\treturn this;\n\t}\n\n\tattachment(filename?: string): this {\n\t\tif (filename !== undefined) {\n\t\t\tthis._headers.set(\n\t\t\t\t\"content-disposition\",\n\t\t\t\t`attachment; filename=\"${filename}\"`,\n\t\t\t);\n\t\t} else {\n\t\t\tthis._headers.set(\"content-disposition\", \"attachment\");\n\t\t}\n\t\treturn this;\n\t}\n\n\tcookie(name: string, value: string, options?: CookieOptions): this {\n\t\tthis._cookies.push(serializeCookie(name, value, options));\n\t\treturn this;\n\t}\n\n\tclearCookie(name: string, options?: CookieOptions): this {\n\t\tthis._cookies.push(clearCookie(name, options));\n\t\treturn this;\n\t}\n\n\tget statusCode(): number {\n\t\treturn this._statusCode;\n\t}\n\n\tget headersSent(): boolean {\n\t\treturn this._sent;\n\t}\n\n\tget rawResponse(): ServerResponse {\n\t\treturn this.raw;\n\t}\n\n\tasync flush(): Promise<void> {\n\t\tif (this._sent) return;\n\t\tthis._sent = true;\n\n\t\tthis.flushHeaders();\n\n\t\tthis.raw.statusCode = this._statusCode;\n\n\t\tif (this._body !== null) {\n\t\t\tthis.raw.end(this._body);\n\t\t} else {\n\t\t\tthis.raw.end();\n\t\t}\n\t}\n\n\tprivate flushHeaders(): void {\n\t\tif (this._cookies.length > 0) {\n\t\t\tthis.raw.setHeader(\"Set-Cookie\", this._cookies);\n\t\t}\n\n\t\tfor (const [name, value] of this._headers.entries()) {\n\t\t\tif (name.toLowerCase() !== \"set-cookie\") {\n\t\t\t\tthis.raw.setHeader(name, value);\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction joinPath(root: string, filePath: string): string {\n\tconst normalizedRoot = root.replace(/\\\\/g, \"/\").replace(/\\/$/, \"\");\n\tconst normalizedPath = filePath.replace(/\\\\/g, \"/\").replace(/^\\//, \"\");\n\treturn `${normalizedRoot}/${normalizedPath}`;\n}\n"],"mappings":"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","names":["basename","extname","extname","basename"]}
|
package/dist/server/index.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { Container } from './container/index.js';
|
|
2
2
|
import { Server } from 'node:http';
|
|
3
3
|
import { S as SuperRequest, a as SuperResponse } from '../response-Ca8KWK5_.js';
|
|
4
|
-
import { a as Router, M as Middleware, b as RouteHandler, C as ControllerClass, S as StaticOptions } from '../index-CMkhSDh7.js';
|
|
4
|
+
import { a as Router, M as Middleware, b as RouteHandler, C as ControllerClass, S as StaticOptions, R as RouteContext } from '../index-CMkhSDh7.js';
|
|
5
5
|
export { Cache, CacheConfig, cacheResponse } from './cache/index.js';
|
|
6
|
-
export { ColumnCompileOptions, ColumnDefinition, ConnectionConfig, DatabaseConnection, DatabaseDriver, Dialect, Driver, ForeignKeyDefinition, MigrationDefinition, MigrationStatusRow, Migrator, MysqlDialect, PaginatedResult, Pagination, PaginationUrl, PostgresqlDialect, QueryBuilder, QueryResult, SchemaBuilder, Seeder, SeederClass, SqliteDialect, TableBlueprint, createDialect, createDriver } from './database/index.js';
|
|
6
|
+
export { ColumnCompileOptions, ColumnDefinition, ConnectionConfig, DatabaseConnection, DatabaseDriver, Dialect, Driver, ForeignKeyDefinition, MigrationDefinition, MigrationStatusRow, Migrator, Model, MysqlDialect, PaginatedResult, Pagination, PaginationUrl, PostgresqlDialect, QueryBuilder, QueryResult, SchemaBuilder, Seeder, SeederClass, SqliteDialect, TableBlueprint, createDialect, createDriver } from './database/index.js';
|
|
7
7
|
export { Event, EventConfig, createEvent, event } from './events/index.js';
|
|
8
8
|
export { LocalDisk, Storage, StorageConfig, createStorage, storage } from './storage/index.js';
|
|
9
9
|
import 'node:stream';
|
|
@@ -75,5 +75,6 @@ declare class SuperApp {
|
|
|
75
75
|
private handleRequest;
|
|
76
76
|
}
|
|
77
77
|
declare function speexjs(options?: AppOptions): SuperApp;
|
|
78
|
+
declare function createControllerInstance(controller: ControllerClass, ctx: RouteContext): object;
|
|
78
79
|
|
|
79
|
-
export { type AppOptions, SuperApp, URLBuilder, type ViewEngine, registerMacro, responseMacros, speexjs, url };
|
|
80
|
+
export { type AppOptions, SuperApp, URLBuilder, type ViewEngine, createControllerInstance, registerMacro, responseMacros, speexjs, url };
|