@danceroutine/tango-core 1.11.13 → 1.11.15

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.
@@ -1,2 +1,2 @@
1
- import { a as TangoHeaders, i as TangoRequest, n as TangoResponse, o as JsonValue, r as TangoQueryParams, s as TangoBody } from "../index-D8o4DOOG.js";
1
+ import { a as TangoHeaders, i as TangoRequest, n as TangoResponse, o as JsonValue, r as TangoQueryParams, s as TangoBody } from "../index-Ds43ITu5.js";
2
2
  export { type JsonValue, TangoBody, TangoHeaders, TangoQueryParams, TangoRequest, TangoResponse };
@@ -1,2 +1,2 @@
1
- import { a as TangoHeaders, i as TangoQueryParams, n as TangoResponse, o as TangoBody, r as TangoRequest } from "../http-6e0y_vd6.js";
1
+ import { a as TangoHeaders, i as TangoQueryParams, n as TangoResponse, o as TangoBody, r as TangoRequest } from "../http-BJPRtBGV.js";
2
2
  export { TangoBody, TangoHeaders, TangoQueryParams, TangoRequest, TangoResponse };
@@ -1104,10 +1104,26 @@ var TangoResponse = class TangoResponse {
1104
1104
  /**
1105
1105
  * Create a `405 Method Not Allowed` response and optionally populate `Allow`.
1106
1106
  */
1107
- static methodNotAllowed(allow, detail = "Method not allowed.", init) {
1107
+ static methodNotAllowed(allow, detail, init) {
1108
1108
  const headers = new TangoHeaders(init?.headers);
1109
1109
  if (allow && allow.length > 0) headers.set("Allow", allow.join(", "));
1110
- return TangoResponse.json({ error: detail }, {
1110
+ if (TangoError.isTangoError(detail) || TangoError.isProblemDetails(detail)) return TangoResponse.error(detail, {
1111
+ ...init,
1112
+ status: 405,
1113
+ headers
1114
+ });
1115
+ if (typeof detail === "string") return TangoResponse.error({
1116
+ code: "method_not_allowed",
1117
+ message: detail
1118
+ }, {
1119
+ ...init,
1120
+ status: 405,
1121
+ headers
1122
+ });
1123
+ return TangoResponse.error({
1124
+ code: "method_not_allowed",
1125
+ message: "Method not allowed."
1126
+ }, {
1111
1127
  ...init,
1112
1128
  status: 405,
1113
1129
  headers
@@ -1641,4 +1657,4 @@ var http_exports = /* @__PURE__ */ __exportAll({
1641
1657
  //#endregion
1642
1658
  export { TangoHeaders as a, TangoQueryParams as i, TangoResponse as n, TangoBody as o, TangoRequest as r, http_exports as t };
1643
1659
 
1644
- //# sourceMappingURL=http-6e0y_vd6.js.map
1660
+ //# sourceMappingURL=http-BJPRtBGV.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"http-6e0y_vd6.js","names":[],"sources":["../src/http/TangoBody.ts","../src/http/TangoHeaders.ts","../src/http/TangoQueryParams.ts","../src/http/TangoRequest.ts","../src/http/TangoResponse.ts","../src/http/index.ts"],"sourcesContent":["import {\n isArrayBuffer,\n isBlob,\n isFile,\n isFormData,\n isNil,\n isReadableStream,\n isUint8Array,\n isURLSearchParams,\n} from '../runtime/index';\n\n/**\n * The full type of body that TangoResponse/TangoBody supports.\n * Unlike the fetch spec BodyInit, this can be directly:\n * - a string, ArrayBuffer, Uint8Array, Blob, FormData, ReadableStream, or JSON-like object, or null/undefined.\n */\n\ntype HeadersLike = { get?: (arg: string) => string | null };\n\ntype TangoBodySource = BodyInit | JsonValue | null;\n\n/** Recursive JSON value contract used by Tango HTTP helpers. */\nexport type JsonValue = string | number | boolean | null | JsonValue[] | { [key: string]: JsonValue };\n\n/**\n * Unified body reader/clone utility for Tango request/response wrappers.\n */\nexport class TangoBody {\n static readonly BRAND = 'tango.http.body' as const;\n readonly __tangoBrand: typeof TangoBody.BRAND = TangoBody.BRAND;\n private bodySourceInternal: TangoBodySource;\n private bodyUsedInternal: boolean;\n private headers?: HeadersLike;\n\n constructor(bodySource: TangoBodySource, headers?: HeadersLike) {\n this.bodySourceInternal = bodySource;\n this.bodyUsedInternal = false;\n this.headers = headers;\n }\n\n /**\n * Narrow an unknown value to `TangoBody`.\n */\n static isTangoBody(value: unknown): value is TangoBody {\n return (\n typeof value === 'object' &&\n value !== null &&\n (value as { __tangoBrand?: unknown }).__tangoBrand === TangoBody.BRAND\n );\n }\n\n /**\n * Expose the original body source for cloning and adapter integration.\n */\n public get bodySource(): TangoBodySource {\n return this.bodySourceInternal;\n }\n\n /**\n * Report whether a reader method has already consumed this body.\n */\n get bodyUsed(): boolean {\n return this.bodyUsedInternal;\n }\n\n /**\n * Describe the current body shape in a way that is useful for diagnostics.\n */\n get bodyType(): string {\n const body = this.bodySourceInternal;\n if (isNil(body)) return 'null';\n if (typeof body === 'string') return 'string';\n if (isArrayBuffer(body)) return 'ArrayBuffer';\n if (isUint8Array(body)) return 'Uint8Array';\n if (isBlob(body)) return 'Blob';\n if (isFormData(body)) return 'FormData';\n if (isURLSearchParams(body)) return 'URLSearchParams';\n if (isReadableStream(body)) return 'ReadableStream';\n if (TangoBody.isJsonValue(body)) return 'JsonValue';\n return typeof body;\n }\n\n /**\n * Returns true if value is a valid JSON value (recursively).\n */\n public static isJsonValue(v: unknown): v is JsonValue {\n if (v === null || typeof v === 'string' || typeof v === 'number' || typeof v === 'boolean') {\n return true;\n }\n if (Array.isArray(v)) {\n return v.every(TangoBody.isJsonValue);\n }\n if (typeof v === 'object' && v !== null && Object.prototype.toString.call(v) === '[object Object]') {\n return Object.values(v).every(TangoBody.isJsonValue);\n }\n return false;\n }\n\n /**\n * Deep clone utility for body values. Preserves types and values as in the legacy implementation.\n * If the source is a stream, the stream will be cloned if readable, otherwise throws.\n */\n static deepCloneBody(body: TangoBodySource): TangoBodySource {\n if (isNil(body)) {\n return null;\n }\n if (typeof body === 'string') {\n return body;\n }\n if (isArrayBuffer(body)) {\n return body.slice(0);\n }\n if (isUint8Array(body)) {\n return new Uint8Array(body);\n }\n if (isBlob(body)) {\n return body.slice(0, body.size, body.type);\n }\n if (isFormData(body)) {\n // Deep clone FormData: only text fields (files not handled)\n // This is the best we can do in cross-platform without File support.\n const cloned = new FormData();\n for (const [k, v] of body) {\n // If value is File, attempt to clone (not fully implemented)\n if (isFile(v)) {\n // Note: Cloning File loses prototype, but rarely needed\n const file = new File([v], v.name, { type: v.type, lastModified: v.lastModified });\n cloned.append(k, file);\n } else {\n cloned.append(k, v as string);\n }\n }\n return cloned;\n }\n if (isReadableStream(body)) {\n throw new TypeError('Cannot deep clone a ReadableStream directly; use TangoBody.clone()');\n }\n if (TangoBody.isJsonValue(body)) {\n return JSON.parse(JSON.stringify(body));\n }\n return null;\n }\n\n /**\n * Read a `ReadableStream` into an `ArrayBuffer`.\n */\n static async readStreamToArrayBuffer(stream: ReadableStream<Uint8Array>): Promise<ArrayBuffer> {\n const chunks: Uint8Array[] = [];\n const reader = stream.getReader();\n let total = 0;\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n chunks.push(value);\n total += value.length;\n }\n const joined = new Uint8Array(total);\n let off = 0;\n for (const chunk of chunks) {\n joined.set(chunk, off);\n off += chunk.length;\n }\n return joined.buffer.slice(0, joined.byteLength) as ArrayBuffer;\n }\n\n /**\n * Read a `ReadableStream` into a `Uint8Array`.\n */\n static async readStreamToUint8Array(stream: ReadableStream<Uint8Array>): Promise<Uint8Array<ArrayBuffer>> {\n const buf = await TangoBody.readStreamToArrayBuffer(stream);\n return new Uint8Array(buf) as Uint8Array<ArrayBuffer>;\n }\n\n /**\n * Read a `ReadableStream` into UTF-8 text.\n */\n static async readStreamToText(stream: ReadableStream<Uint8Array>): Promise<string> {\n const arr = await TangoBody.readStreamToUint8Array(stream);\n return new TextDecoder().decode(arr);\n }\n\n /**\n * Determine the content type for this body, if possible.\n * Respects an explicitly passed header, otherwise infers from value type.\n */\n static detectContentType(body: TangoBodySource, providedType?: string): string | undefined {\n if (providedType) return providedType;\n if (isNil(body)) return undefined;\n if (typeof body === 'string') return 'text/plain; charset=utf-8';\n if (isArrayBuffer(body) || isUint8Array(body)) return 'application/octet-stream';\n if (isBlob(body)) {\n if (body.type) return body.type;\n return 'application/octet-stream';\n }\n if (isFormData(body)) return undefined;\n if (typeof body === 'object' && TangoBody.isJsonValue(body)) return 'application/json; charset=utf-8';\n if (isReadableStream(body)) return undefined;\n return undefined;\n }\n\n /**\n * Attempt to determine the content length, in bytes, for this body.\n * Only available for certain body types, otherwise returns undefined.\n */\n static async getContentLength(body: TangoBodySource): Promise<number | undefined> {\n if (isNil(body)) return 0;\n if (typeof body === 'string') return new TextEncoder().encode(body).length;\n if (isUint8Array(body)) return body.byteLength;\n if (isArrayBuffer(body)) return body.byteLength;\n if (isBlob(body)) return body.size;\n if (TangoBody.isJsonValue(body)) return new TextEncoder().encode(JSON.stringify(body)).length;\n return undefined;\n }\n\n /**\n * Reads the body as an ArrayBuffer.\n */\n async arrayBuffer(): Promise<ArrayBuffer> {\n return this.consumeBody(async (input) => {\n if (isArrayBuffer(input)) return input;\n if (isUint8Array(input)) {\n const copy = new Uint8Array(input.byteLength);\n copy.set(input);\n return copy.buffer;\n }\n if (typeof input === 'string') return new TextEncoder().encode(input).buffer as ArrayBuffer;\n if (isBlob(input)) return input.arrayBuffer();\n if (isReadableStream(input)) {\n return TangoBody.readStreamToArrayBuffer(input);\n }\n if (TangoBody.isJsonValue(input)) {\n // If body is object/array, encode as JSON and return buffer\n return new TextEncoder().encode(JSON.stringify(input)).buffer as ArrayBuffer;\n }\n throw new TypeError('Body is not an ArrayBuffer, Blob, string, stream, or JSON serializable object');\n });\n }\n\n /**\n * Reads the body as a Blob (browser only).\n */\n async blob(): Promise<Blob> {\n return this.consumeBody(async (input) => {\n if (isBlob(input)) return input;\n if (typeof input === 'string') return new Blob([input]);\n if (isArrayBuffer(input)) return new Blob([input]);\n if (isUint8Array(input)) return new Blob([new Uint8Array(input)]);\n if (isReadableStream(input)) {\n const buf = await TangoBody.readStreamToArrayBuffer(input);\n return new Blob([buf]);\n }\n if (TangoBody.isJsonValue(input)) {\n return new Blob([JSON.stringify(input)], { type: 'application/json' });\n }\n throw new TypeError(\n 'Body is not a Blob, string, ArrayBuffer, Uint8Array, stream, or JSON serializable object'\n );\n });\n }\n\n /**\n * Reads the body as a Uint8Array.\n */\n async bytes(): Promise<Uint8Array<ArrayBuffer>> {\n return this.consumeBody(async (input) => {\n if (isUint8Array(input)) return new Uint8Array(input);\n if (isArrayBuffer(input)) return new Uint8Array(input);\n if (typeof input === 'string') return new TextEncoder().encode(input);\n if (isBlob(input)) return new Uint8Array(await input.arrayBuffer());\n if (isReadableStream(input)) {\n return TangoBody.readStreamToUint8Array(input);\n }\n if (TangoBody.isJsonValue(input)) {\n return new TextEncoder().encode(JSON.stringify(input));\n }\n throw new TypeError('Body is not bytes, ArrayBuffer, Blob, string, stream, or JSON serializable object');\n });\n }\n\n /**\n * Reads the body as FormData.\n * Accepts FormData, or if type is urlencoded or multipart parses a string/bytes.\n */\n async formData(): Promise<FormData> {\n return this.consumeBody(async (input) => {\n if (isFormData(input)) return input;\n\n let contentType: string | undefined = undefined;\n if (this.headers && typeof this.headers.get === 'function') {\n const raw = this.headers.get('Content-Type');\n if (typeof raw === 'string') contentType = raw.toLowerCase();\n }\n\n let raw: string;\n if (typeof input === 'string') {\n raw = input;\n } else if (isArrayBuffer(input)) {\n raw = new TextDecoder().decode(input);\n } else if (isUint8Array(input)) {\n raw = new TextDecoder().decode(input);\n } else {\n throw new TypeError('Body is not valid for FormData');\n }\n\n // application/x-www-form-urlencoded\n if (contentType && contentType.includes('application/x-www-form-urlencoded')) {\n const form = new FormData();\n const params = new URLSearchParams(raw);\n params.forEach((value, key) => form.append(key, value));\n return form;\n }\n // multipart/form-data\n if (contentType && contentType.startsWith('multipart/form-data')) {\n const boundaryMatch = /boundary=([^\\s;]+)/i.exec(contentType);\n if (!boundaryMatch) throw new TypeError('Missing boundary in multipart/form-data');\n const boundary = boundaryMatch[1];\n\n // Warning: minimal multipart parsing, no file support\n const parts = raw.split(`--${boundary}`);\n const form = new FormData();\n for (const part of parts) {\n const trimmed = part.trim();\n if (!trimmed || trimmed === '--' || trimmed === '') continue;\n\n const [rawHeaders = '', ...rawBodyParts] = trimmed.split(/\\r?\\n\\r?\\n/);\n const body = rawBodyParts.join('\\n\\n').replace(/\\r?\\n$/, '');\n const dispositionMatch = /Content-Disposition:\\s*form-data;\\s*name=\"([^\"]+)\"/i.exec(rawHeaders);\n if (!dispositionMatch) continue;\n const name = dispositionMatch[1]!;\n form.append(name, body);\n }\n return form;\n }\n throw new TypeError('Body is not FormData, nor a supported form encoding');\n });\n }\n\n /**\n * Reads and parses the body as JSON (if possible).\n */\n async json<T = unknown>(): Promise<T> {\n return this.consumeBody(async (input) => {\n if (typeof input === 'string') return JSON.parse(input) as T;\n if (TangoBody.isJsonValue(input)) return input as T;\n if (isArrayBuffer(input) || isUint8Array(input)) {\n const text = new TextDecoder().decode(isUint8Array(input) ? input : new Uint8Array(input));\n return JSON.parse(text) as T;\n }\n if (isReadableStream(input)) {\n const text = await TangoBody.readStreamToText(input);\n return JSON.parse(text) as T;\n }\n throw new TypeError('Body is not valid JSON');\n });\n }\n\n /**\n * Reads the body as UTF-8 string.\n */\n async text(): Promise<string> {\n return this.consumeBody(async (input) => {\n if (typeof input === 'string') return input;\n if (isArrayBuffer(input)) return new TextDecoder().decode(input);\n if (isUint8Array(input)) return new TextDecoder().decode(input);\n if (isBlob(input)) return await input.text();\n if (isReadableStream(input)) return await TangoBody.readStreamToText(input);\n if (TangoBody.isJsonValue(input)) return JSON.stringify(input);\n throw new TypeError('Body is not text, ArrayBuffer, Uint8Array, Blob, stream, or JSON serializable object');\n });\n }\n\n /**\n * Returns the original body value (may be used for streaming or clone).\n */\n getRawBodyInit(): TangoBodySource {\n return this.bodySourceInternal;\n }\n\n /**\n * Clone the body instance and stream if possible.\n * If the source is a stream, the stream will be cloned if readable, otherwise throws.\n */\n clone(): TangoBody {\n if (this.bodyUsedInternal) throw new TypeError('Body has already been used.');\n if (isReadableStream(this.bodySourceInternal)) {\n if (typeof this.bodySourceInternal.tee !== 'function') {\n throw new TypeError('Cannot clone: body is a ReadableStream and tee() is not available');\n }\n const [streamForOriginal, streamForClone] = this.bodySourceInternal.tee();\n this.bodySourceInternal = streamForOriginal;\n return new TangoBody(streamForClone, this.headers);\n }\n const cloneSource = TangoBody.deepCloneBody(this.bodySourceInternal);\n return new TangoBody(cloneSource, this.headers);\n }\n\n /**\n * Helper for all readers. Only allows reading once.\n */\n private async consumeBody<T>(parser: (input: TangoBodySource) => Promise<T>): Promise<T> {\n if (this.bodyUsedInternal) {\n throw new TypeError('Body has already been consumed.');\n }\n this.bodyUsedInternal = true;\n return parser(this.bodySourceInternal);\n }\n}\n","import { isArrayBuffer, isBlob, isUint8Array } from '../runtime/index';\n\n/**\n * TangoHeaders extends the Web Headers class, adding ergonomic helpers\n * for common HTTP header patterns, convenience features, and a consistent API for\n * setting, appending, and deleting headers and cookies. This is designed to be\n * used by TangoResponse and other Tango HTTP utilities.\n * Additionally, provides helpers for safely setting Content-Length based on a known body,\n * and setting Content-Disposition for inline or attachment filenames.\n *\n * Includes helpers for request tracing and correlation headers:\n * - X-Request-Id\n * - traceparent (W3C Trace Context)\n * - Server-Timing\n * - X-Response-Time\n */\nexport class TangoHeaders extends Headers {\n static readonly BRAND = 'tango.http.headers' as const;\n readonly __tangoBrand: typeof TangoHeaders.BRAND = TangoHeaders.BRAND;\n\n /**\n * Narrow an unknown value to `TangoHeaders`.\n */\n static isTangoHeaders(value: unknown): value is TangoHeaders {\n return (\n typeof value === 'object' &&\n value !== null &&\n (value as { __tangoBrand?: unknown }).__tangoBrand === TangoHeaders.BRAND\n );\n }\n\n /**\n * Serialize a cookie for the Set-Cookie header line.\n */\n private static serializeCookie(\n name: string,\n value: string,\n options: {\n domain?: string;\n expires?: Date;\n httpOnly?: boolean;\n maxAge?: number;\n path?: string;\n sameSite?: 'Strict' | 'Lax' | 'None';\n secure?: boolean;\n priority?: 'Low' | 'Medium' | 'High';\n partitioned?: boolean;\n } = {}\n ): string {\n let cookie = encodeURIComponent(name) + '=' + encodeURIComponent(value ?? '');\n if (options.domain) cookie += `; Domain=${options.domain}`;\n if (options.path) cookie += `; Path=${options.path}`;\n else cookie += '; Path=/';\n if (options.expires) cookie += `; Expires=${options.expires.toUTCString()}`;\n if (typeof options.maxAge === 'number') cookie += `; Max-Age=${options.maxAge}`;\n if (options.secure) cookie += '; Secure';\n if (options.httpOnly) cookie += '; HttpOnly';\n if (options.sameSite) cookie += `; SameSite=${options.sameSite}`;\n if (options.priority) cookie += `; Priority=${options.priority}`;\n if (options.partitioned) cookie += '; Partitioned';\n return cookie;\n }\n\n private static hasNumberSize(value: unknown): value is { size: number } {\n return typeof value === 'object' && value !== null && typeof (value as { size?: unknown }).size === 'number';\n }\n\n private static hasNumberLength(value: unknown): value is { length: number } {\n return (\n typeof value === 'object' && value !== null && typeof (value as { length?: unknown }).length === 'number'\n );\n }\n\n private static isNodeBuffer(value: unknown): value is { length: number } {\n const maybeBuffer = Buffer as unknown as { isBuffer?: (input: unknown) => boolean };\n return (\n typeof Buffer !== 'undefined' && typeof maybeBuffer.isBuffer === 'function' && maybeBuffer.isBuffer(value)\n );\n }\n\n /**\n * Sets the Content-Disposition header with type \"inline\" and the specified filename.\n * This is useful to indicate that the content should be displayed inline in the browser,\n * but with a suggested filename for saving.\n *\n * @param filename The filename to include in the Content-Disposition header.\n */\n setContentDispositionInline(filename: string): void {\n const encoded = encodeURIComponent(filename);\n this.set('Content-Disposition', `inline; filename=\"${encoded}\"; filename*=UTF-8''${encoded}`);\n }\n\n /**\n * Sets the Content-Disposition header with type \"attachment\" and the specified filename.\n * This is useful to indicate that the response should be downloaded as a file.\n *\n * @param filename The filename to include in the Content-Disposition header.\n */\n setContentDispositionAttachment(filename: string): void {\n const encoded = encodeURIComponent(filename);\n this.set('Content-Disposition', `attachment; filename=\"${encoded}\"; filename*=UTF-8''${encoded}`);\n }\n\n /**\n * Create a copy that preserves all header names and values.\n */\n clone(): TangoHeaders {\n const copy = new TangoHeaders();\n for (const [name, value] of this.entries()) {\n copy.append(name, value);\n }\n return copy;\n }\n\n /**\n * Set a header, replacing the existing value.\n */\n setHeader(name: string, value: string): void {\n this.set(name, value);\n }\n\n /**\n * Append a header, adding to existing value(s) for the name.\n */\n appendHeader(name: string, value: string): void {\n this.append(name, value);\n }\n\n /**\n * Get a header value (first value if header is repeated).\n */\n getHeader(name: string): string | null {\n return this.get(name);\n }\n\n /**\n * Check if a header exists.\n */\n hasHeader(name: string): boolean {\n return this.has(name);\n }\n\n /**\n * Delete a header.\n */\n deleteHeader(name: string): void {\n this.delete(name);\n }\n\n /**\n * Ensure a header is present only once and fully replaces the old value.\n */\n ensureUnique(name: string, value: string): void {\n this.delete(name);\n this.set(name, value);\n }\n\n /**\n * Add a field (or fields) to the Vary header, merging with existing values.\n */\n vary(...fields: string[]): void {\n if (fields.length === 0) return;\n const key = 'Vary';\n const prev = this.get(key);\n const nextSet = new Set<string>();\n if (prev) {\n for (const v of prev.split(',')) {\n if (v.trim()) nextSet.add(v.trim());\n }\n }\n for (const f of fields) {\n if (f.trim()) nextSet.add(f.trim());\n }\n this.set(key, Array.from(nextSet).join(', '));\n }\n\n /**\n * Set a cookie header (for Set-Cookie).\n * @param name\n * @param value\n * @param options\n */\n setCookie(\n name: string,\n value: string,\n options?: {\n domain?: string;\n expires?: Date;\n httpOnly?: boolean;\n maxAge?: number;\n path?: string;\n sameSite?: 'Strict' | 'Lax' | 'None';\n secure?: boolean;\n priority?: 'Low' | 'Medium' | 'High';\n partitioned?: boolean;\n }\n ): void {\n this.append('Set-Cookie', TangoHeaders.serializeCookie(name, value, options));\n }\n\n /**\n * Append (additionally) a new cookie.\n */\n appendCookie(\n name: string,\n value: string,\n options?: {\n domain?: string;\n expires?: Date;\n httpOnly?: boolean;\n maxAge?: number;\n path?: string;\n sameSite?: 'Strict' | 'Lax' | 'None';\n secure?: boolean;\n priority?: 'Low' | 'Medium' | 'High';\n partitioned?: boolean;\n }\n ): void {\n this.append('Set-Cookie', TangoHeaders.serializeCookie(name, value, options));\n }\n\n /**\n * Delete a cookie (\"unset\" it via expired date).\n */\n deleteCookie(\n name: string,\n options?: {\n domain?: string;\n path?: string;\n sameSite?: 'Strict' | 'Lax' | 'None';\n secure?: boolean;\n priority?: 'Low' | 'Medium' | 'High';\n partitioned?: boolean;\n }\n ): void {\n this.setCookie(name, '', {\n ...options,\n expires: new Date(0),\n maxAge: 0,\n });\n }\n\n /**\n * Add or override Cache-Control header with helpers for common policies.\n */\n cacheControl(control: string | Record<string, string | number | boolean | undefined>): void {\n if (typeof control === 'string') {\n this.set('Cache-Control', control);\n return;\n }\n // Compose Cache-Control from object\n const parts: string[] = [];\n for (const [k, v] of Object.entries(control)) {\n if (typeof v === 'boolean') {\n if (v) parts.push(k.replace(/[A-Z]/g, (c) => '-' + c.toLowerCase()));\n } else if (typeof v === 'number' || (typeof v === 'string' && v.length > 0)) {\n parts.push(`${k.replace(/[A-Z]/g, (c) => '-' + c.toLowerCase())}=${v}`);\n }\n }\n if (parts.length) {\n this.set('Cache-Control', parts.join(', '));\n }\n }\n\n /**\n * Set the Location header.\n */\n location(url: string): void {\n this.set('Location', url);\n }\n\n /**\n * Set the Content-Type header.\n */\n contentType(mime: string): void {\n this.set('Content-Type', mime);\n }\n\n /**\n * Attempt to guess and set the Content-Type header from a file (string or Blob) and optional filename.\n *\n * @param file File-like input (string or Blob)\n * @param filename Optional filename to help guess mime type by extension\n */\n setContentTypeByFile(file: unknown, filename?: string): void {\n // do not overwrite explicit content-type\n if (this.has('Content-Type')) return;\n\n // If file is a string and a filename is provided or can be guessed from file path\n if (typeof file === 'string' && filename) {\n // Guess type by extension\n const dotIndex = filename.lastIndexOf('.');\n const ext = dotIndex >= 0 ? filename.slice(dotIndex + 1).toLowerCase() : '';\n const map: Record<string, string> = {\n txt: 'text/plain',\n text: 'text/plain',\n html: 'text/html',\n css: 'text/css',\n js: 'application/javascript',\n json: 'application/json',\n jpg: 'image/jpeg',\n jpeg: 'image/jpeg',\n png: 'image/png',\n gif: 'image/gif',\n webp: 'image/webp',\n pdf: 'application/pdf',\n svg: 'image/svg+xml',\n ico: 'image/x-icon',\n md: 'text/markdown',\n };\n const mime = map[ext];\n if (mime) {\n this.set('Content-Type', mime);\n } else {\n this.set('Content-Type', 'application/octet-stream');\n }\n return;\n }\n\n // If it's a Blob, use its type, or fallback\n if (isBlob(file)) {\n if (file.type && file.type !== '') {\n this.set('Content-Type', file.type);\n } else {\n this.set('Content-Type', 'application/octet-stream');\n }\n return;\n }\n\n // Fallback\n this.set('Content-Type', 'application/octet-stream');\n }\n\n /**\n * Sets the Content-Length header, inferring it from the body if not explicitly provided.\n * If the body is a string, ArrayBuffer, Uint8Array, Blob/Buffer (or has a .size or .length property),\n * the length is computed. For unsupported types, does nothing.\n * Mirrors logic from TangoResponse.ts, but generalized for use anywhere.\n */\n setContentLengthFromBody(body: unknown): void {\n if (this.has('Content-Length') || body === null || body === undefined) {\n return;\n }\n\n let len: number | undefined;\n\n if (typeof body === 'string') {\n len = new TextEncoder().encode(body).length;\n } else if (isArrayBuffer(body)) {\n len = body.byteLength;\n }\n // Node.js Buffer support (Buffer.isBuffer and .length)\n else if (TangoHeaders.isNodeBuffer(body)) {\n len = (body as { length: number }).length;\n } else if (isUint8Array(body)) {\n len = body.byteLength;\n } else if (isBlob(body)) {\n len = body.size;\n }\n // Generic \"size\" (number) property\n else if (TangoHeaders.hasNumberSize(body)) {\n len = (body as { size: number }).size;\n }\n // Generic \"length\" (number) property but not string/ArrayBuffer/Uint8Array/etc\n else if (\n TangoHeaders.hasNumberLength(body) &&\n typeof body !== 'string' &&\n !isArrayBuffer(body) &&\n !isUint8Array(body)\n ) {\n len = (body as { length: number }).length;\n }\n\n if (typeof len === 'number') {\n this.set('Content-Length', len.toString());\n }\n }\n\n /**\n * Set or update the X-Request-Id header. Used for associating a request/response with a unique id.\n * @param id The request id value to set.\n */\n withRequestId(id: string): this {\n this.set('X-Request-Id', id);\n return this;\n }\n\n /**\n * Set or update the traceparent header. Used for distributed trace context propagation (W3C Trace Context).\n * @param value The traceparent value (should be a valid traceparent header value).\n */\n withTraceParent(value: string): this {\n this.set('traceparent', value);\n return this;\n }\n\n /**\n * Set or append a value to the Server-Timing header.\n * For a single metric, supply name, and optionally dur and desc.\n * For advanced usage (many metrics), set the value directly or use appendServerTimingRaw.\n *\n * @param name Name of the server-timing metric (e.g., 'total', 'db').\n * @param dur Optional duration in ms.\n * @param desc Optional string description.\n */\n withServerTiming(name: string, dur?: number, desc?: string): this {\n // Build the metric string per spec: <metric>=<value>;dur=<duration>;desc=\"<description>\"\n let metric = name;\n if (typeof dur === 'number') {\n metric += `;dur=${dur}`;\n }\n if (desc) {\n metric += `;desc=\"${desc.replace(/\"/g, '\\\\\"')}\"`;\n }\n\n // Set or append. If header exists, append, separated by comma.\n const prev = this.get('Server-Timing');\n if (prev && prev.length > 0) {\n this.set('Server-Timing', prev + ', ' + metric);\n } else {\n this.set('Server-Timing', metric);\n }\n return this;\n }\n\n /**\n * Directly append a raw Server-Timing metric value.\n * This is useful for advanced cases where you have multiple metrics assembled.\n * @param value The server-timing value chunk to append.\n */\n appendServerTimingRaw(value: string): this {\n const prev = this.get('Server-Timing');\n if (prev && prev.length > 0) {\n this.set('Server-Timing', prev + ', ' + value);\n } else {\n this.set('Server-Timing', value);\n }\n return this;\n }\n\n /**\n * Set or update X-Response-Time header.\n * @param ms Elapsed time in milliseconds (number or string for flexibility).\n */\n withResponseTime(ms: number | string): this {\n this.set('X-Response-Time', typeof ms === 'number' ? `${ms}ms` : ms);\n return this;\n }\n\n /**\n * Return the current value of X-Request-Id.\n */\n getRequestId(): string | null {\n return this.get('X-Request-Id');\n }\n\n /**\n * Return the current value of traceparent header.\n */\n getTraceParent(): string | null {\n return this.get('traceparent');\n }\n\n /**\n * Return the current Server-Timing string, if set.\n */\n getServerTiming(): string | null {\n return this.get('Server-Timing');\n }\n\n /**\n * Return the current X-Response-Time string, if set.\n */\n getResponseTime(): string | null {\n return this.get('X-Response-Time');\n }\n}\n","import type { TangoRequest } from './TangoRequest';\n\ntype QueryParamRecord = Record<string, string | string[] | undefined>;\ntype QueryParamMutationValue = string | number | readonly (string | number)[] | null | undefined;\ntype QueryParamMutationRecord = Record<string, QueryParamMutationValue>;\n\n/**\n * Immutable query parameter helper that normalizes framework-specific shapes\n * into one Tango-owned API.\n */\nexport class TangoQueryParams {\n static readonly BRAND = 'tango.http.query_params' as const;\n readonly __tangoBrand: typeof TangoQueryParams.BRAND = TangoQueryParams.BRAND;\n private readonly values: Map<string, readonly string[]>;\n\n private constructor(values: Map<string, readonly string[]>) {\n this.values = values;\n }\n\n /**\n * Narrow an unknown value to `TangoQueryParams`.\n */\n static isTangoQueryParams(value: unknown): value is TangoQueryParams {\n return (\n typeof value === 'object' &&\n value !== null &&\n (value as { __tangoBrand?: unknown }).__tangoBrand === TangoQueryParams.BRAND\n );\n }\n\n /**\n * Build query params from a `URLSearchParams` instance.\n */\n static fromURLSearchParams(params: URLSearchParams): TangoQueryParams {\n const values = new Map<string, string[]>();\n\n for (const [key, value] of params.entries()) {\n const current = values.get(key);\n if (current) {\n current.push(value);\n continue;\n }\n values.set(key, [value]);\n }\n\n return new TangoQueryParams(values);\n }\n\n /**\n * Build query params from framework record-style search params.\n */\n static fromRecord(params: QueryParamRecord): TangoQueryParams {\n const values = new Map<string, string[]>();\n\n for (const [key, value] of Object.entries(params)) {\n if (Array.isArray(value)) {\n const normalized = value.filter((entry) => typeof entry === 'string');\n if (normalized.length > 0) {\n values.set(key, normalized);\n }\n continue;\n }\n\n if (typeof value === 'string') {\n values.set(key, [value]);\n }\n }\n\n return new TangoQueryParams(values);\n }\n\n /**\n * Build query params from a full URL string or URL object.\n */\n static fromURL(input: string | URL): TangoQueryParams {\n const url = typeof input === 'string' ? new URL(input) : input;\n return TangoQueryParams.fromURLSearchParams(url.searchParams);\n }\n\n /**\n * Build query params from a request-like object with a URL.\n */\n static fromRequest(request: Request | TangoRequest): TangoQueryParams {\n return TangoQueryParams.fromURL(request.url);\n }\n\n /**\n * Get the first value for a query param.\n */\n get(name: string): string | undefined {\n return this.values.get(name)?.[0];\n }\n\n /**\n * Get all values for a query param.\n */\n getAll(name: string): string[] {\n return [...(this.values.get(name) ?? [])];\n }\n\n /**\n * Check whether a query param exists.\n */\n has(name: string): boolean {\n return (this.values.get(name)?.length ?? 0) > 0;\n }\n\n /**\n * Iterate key -> values entries.\n */\n *entries(): IterableIterator<[string, string[]]> {\n for (const [key, values] of this.values.entries()) {\n yield [key, [...values]];\n }\n }\n\n /**\n * Iterate keys present in the query params.\n */\n *keys(): IterableIterator<string> {\n yield* this.values.keys();\n }\n\n /**\n * Convert back to a native `URLSearchParams` object.\n */\n toURLSearchParams(): URLSearchParams {\n const params = new URLSearchParams();\n\n for (const [key, values] of this.values.entries()) {\n for (const value of values) {\n params.append(key, value);\n }\n }\n\n return params;\n }\n\n /**\n * Return a new query param set with selected keys replaced or removed.\n *\n * `undefined`, `null`, and empty arrays remove the key entirely.\n */\n withValues(updates: QueryParamMutationRecord): TangoQueryParams {\n const next = new Map<string, string[]>();\n\n for (const [key, values] of this.values.entries()) {\n next.set(key, [...values]);\n }\n\n for (const [key, value] of Object.entries(updates)) {\n if (value === undefined || value === null) {\n next.delete(key);\n continue;\n }\n\n const normalized = Array.isArray(value) ? value.map((entry) => String(entry)) : [String(value)];\n if (normalized.length === 0) {\n next.delete(key);\n continue;\n }\n\n next.set(key, normalized);\n }\n\n return new TangoQueryParams(next);\n }\n\n /**\n * Convert to a relative query string suitable for links.\n */\n toRelativeURL(): string {\n const query = this.toURLSearchParams().toString();\n return query.length > 0 ? `?${query}` : '';\n }\n\n /**\n * Get a trimmed value, omitting blank strings.\n */\n getTrimmed(name: string): string | undefined {\n const value = this.get(name)?.trim();\n return value ? value : undefined;\n }\n\n /**\n * Get the free-text search param using Tango's default key.\n */\n getSearch(key: string = 'search'): string | undefined {\n return this.getTrimmed(key);\n }\n\n /**\n * Get the ordering param as trimmed field tokens.\n */\n getOrdering(key: string = 'ordering'): string[] {\n const value = this.get(key);\n if (!value) {\n return [];\n }\n\n return value\n .split(',')\n .map((token) => token.trim())\n .filter((token) => token.length > 0);\n }\n}\n","import type { JsonValue } from './TangoBody';\nimport { TangoQueryParams } from './TangoQueryParams';\nimport {\n isArrayBuffer,\n isBlob,\n isFormData,\n isNil,\n isReadableStream,\n isUint8Array,\n isURLSearchParams,\n} from '../runtime/index';\n\ntype TangoRequestInit = {\n method?: string;\n headers?: HeadersInit;\n body?: BodyInit | JsonValue | null;\n redirect?: RequestRedirect;\n cache?: RequestCache;\n credentials?: RequestCredentials;\n integrity?: string;\n keepalive?: boolean;\n mode?: RequestMode;\n referrer?: string;\n referrerPolicy?: ReferrerPolicy;\n signal?: AbortSignal;\n};\n\n/**\n * Framework request wrapper that normalizes JSON-like bodies and preserves\n * fetch `Request` compatibility for downstream handlers.\n */\nexport class TangoRequest implements Request {\n static readonly BRAND = 'tango.http.request' as const;\n readonly __tangoBrand: typeof TangoRequest.BRAND = TangoRequest.BRAND;\n private request: Request;\n private bodySourceValue: BodyInit | JsonValue | null;\n private queryParamsValue?: TangoQueryParams;\n\n constructor(input: string | Request, init: TangoRequestInit = {}) {\n const sourceRequest = typeof input === 'string' ? undefined : input;\n const method = (init.method ?? sourceRequest?.method ?? 'GET').toUpperCase();\n const headers = new Headers(init.headers ?? sourceRequest?.headers);\n const normalizedBody = this.normalizeBody(init.body, headers, method);\n\n const requestInit: RequestInit & { duplex?: 'half' } = {\n method,\n headers,\n redirect: init.redirect ?? sourceRequest?.redirect,\n cache: init.cache ?? sourceRequest?.cache,\n credentials: init.credentials ?? sourceRequest?.credentials,\n integrity: init.integrity ?? sourceRequest?.integrity,\n keepalive: init.keepalive ?? sourceRequest?.keepalive,\n mode: init.mode ?? sourceRequest?.mode,\n referrer: init.referrer ?? sourceRequest?.referrer,\n referrerPolicy: init.referrerPolicy ?? sourceRequest?.referrerPolicy,\n signal: init.signal ?? sourceRequest?.signal,\n };\n\n if (normalizedBody !== undefined) {\n requestInit.body = normalizedBody;\n if (isReadableStream(normalizedBody)) {\n requestInit.duplex = 'half';\n }\n }\n\n this.request = new Request(input, requestInit);\n this.bodySourceValue = normalizedBody ?? null;\n }\n\n /**\n * Narrow an unknown value to `TangoRequest`.\n */\n static isTangoRequest(value: unknown): value is TangoRequest {\n return (\n typeof value === 'object' &&\n value !== null &&\n (value as { __tangoBrand?: unknown }).__tangoBrand === TangoRequest.BRAND\n );\n }\n\n /**\n * Expose the request cache mode from the underlying fetch request.\n */\n get cache(): RequestCache {\n return this.request.cache;\n }\n\n /**\n * Expose the request credentials mode from the underlying fetch request.\n */\n get credentials(): RequestCredentials {\n return this.request.credentials;\n }\n\n /**\n * Expose the request destination from the underlying fetch request.\n */\n get destination(): RequestDestination {\n return this.request.destination;\n }\n\n /**\n * Expose the request headers from the underlying fetch request.\n */\n get headers(): Headers {\n return this.request.headers;\n }\n\n /**\n * Expose the request integrity value from the underlying fetch request.\n */\n get integrity(): string {\n return this.request.integrity;\n }\n\n /**\n * Expose the request keepalive flag from the underlying fetch request.\n */\n get keepalive(): boolean {\n return this.request.keepalive;\n }\n\n /**\n * Expose the normalized HTTP method.\n */\n get method(): string {\n return this.request.method;\n }\n\n /**\n * Expose the request mode from the underlying fetch request.\n */\n get mode(): RequestMode {\n return this.request.mode;\n }\n\n /**\n * Expose the redirect policy from the underlying fetch request.\n */\n get redirect(): RequestRedirect {\n return this.request.redirect;\n }\n\n /**\n * Expose the referrer from the underlying fetch request.\n */\n get referrer(): string {\n return this.request.referrer;\n }\n\n /**\n * Expose the referrer policy from the underlying fetch request.\n */\n get referrerPolicy(): ReferrerPolicy {\n return this.request.referrerPolicy;\n }\n\n /**\n * Expose the abort signal from the underlying fetch request.\n */\n get signal(): AbortSignal {\n return this.request.signal;\n }\n\n /**\n * Expose the absolute request URL.\n */\n get url(): string {\n return this.request.url;\n }\n\n /**\n * Expose the readable request body stream when one exists.\n */\n get body(): Request['body'] {\n return this.request.body;\n }\n\n /**\n * Report whether the body has been consumed.\n */\n get bodyUsed(): boolean {\n return this.request.bodyUsed;\n }\n\n /**\n * Expose the pre-normalized body value used to build the request.\n */\n get bodySource(): BodyInit | JsonValue | null {\n return this.bodySourceValue;\n }\n\n /**\n * Expose normalized query parameters derived from the request URL.\n */\n get queryParams(): TangoQueryParams {\n this.queryParamsValue ??= TangoQueryParams.fromURL(this.request.url);\n return this.queryParamsValue;\n }\n\n /**\n * Read the request body as an array buffer.\n */\n async arrayBuffer(): Promise<ArrayBuffer> {\n return this.request.arrayBuffer();\n }\n\n /**\n * Read the request body as a blob.\n */\n async blob(): Promise<Blob> {\n return this.request.blob();\n }\n\n /**\n * Read the request body as bytes, including runtimes without `Request.bytes()`.\n */\n async bytes(): Promise<Uint8Array<ArrayBuffer>> {\n const requestWithBytes = this.request as Request & { bytes?: () => Promise<Uint8Array<ArrayBuffer>> };\n if (typeof requestWithBytes.bytes === 'function') {\n return requestWithBytes.bytes();\n }\n const buffer = await this.request.arrayBuffer();\n return new Uint8Array(buffer);\n }\n\n /**\n * Read the request body as form data.\n */\n async formData(): Promise<FormData> {\n return this.request.formData();\n }\n\n /**\n * Parse the request body as JSON.\n */\n async json<T = unknown>(): Promise<T> {\n return this.request.json() as Promise<T>;\n }\n\n /**\n * Read the request body as text.\n */\n async text(): Promise<string> {\n return this.request.text();\n }\n\n /**\n * Clone the request so downstream code can consume it independently.\n */\n clone(): TangoRequest {\n return new TangoRequest(this.request.clone());\n }\n\n private normalizeBody(\n body: BodyInit | JsonValue | null | undefined,\n headers: Headers,\n method: string\n ): BodyInit | undefined {\n if (method === 'GET' || method === 'HEAD') {\n return undefined;\n }\n if (isNil(body)) {\n return undefined;\n }\n if (typeof body === 'string') {\n return body;\n }\n if (isArrayBuffer(body) || isUint8Array(body) || isBlob(body)) {\n return body;\n }\n if (isURLSearchParams(body) || isFormData(body) || isReadableStream(body)) {\n return body as BodyInit;\n }\n\n const serialized = JSON.stringify(body);\n if (!headers.has('content-type')) {\n headers.set('content-type', 'application/json; charset=utf-8');\n }\n return serialized;\n }\n}\n","import { TangoError, type ErrorEnvelope, type ErrorDetails, type ProblemDetails } from '../errors/TangoError';\nimport {\n isArrayBuffer,\n isBlob,\n isFormData,\n isNil,\n isReadableStream,\n isUint8Array,\n isURLSearchParams,\n} from '../runtime/index';\nimport { TangoHeaders } from '../http/TangoHeaders';\nimport { TangoBody, type JsonValue } from './TangoBody';\n\ntype TangoResponseInit = {\n body?: BodyInit | JsonValue | null;\n headers?: HeadersInit;\n ok?: boolean;\n redirected?: boolean;\n status?: number;\n statusText?: string;\n type?: ResponseType;\n url?: string;\n};\n\n/**\n * Framework response wrapper with fetch-compatible surface plus ergonomic helpers.\n */\nexport class TangoResponse implements Response {\n static readonly BRAND = 'tango.http.response' as const;\n readonly __tangoBrand: typeof TangoResponse.BRAND = TangoResponse.BRAND;\n readonly headers: TangoHeaders;\n readonly redirected: boolean;\n readonly status: number;\n readonly statusText: string;\n readonly type: ResponseType;\n readonly url: string;\n readonly body: Response['body'];\n private tangoBody: TangoBody;\n private okValue: boolean | undefined;\n\n constructor(init: TangoResponseInit = {}) {\n this.headers = new TangoHeaders(init.headers);\n this.redirected = Boolean(init.redirected);\n this.status = typeof init.status === 'number' ? init.status : 200;\n this.statusText = init.statusText || '';\n this.type = init.type || 'default';\n this.url = init.url || '';\n this.okValue = typeof init.ok === 'boolean' ? init.ok : undefined;\n\n this.tangoBody = new TangoBody(init.body ?? null, this.headers);\n this.body = isReadableStream(this.tangoBody.bodySource) ? this.tangoBody.bodySource : null;\n }\n\n /**\n * Narrow an unknown value to `TangoResponse`.\n */\n static isTangoResponse(value: unknown): value is TangoResponse {\n return (\n typeof value === 'object' &&\n value !== null &&\n (value as { __tangoBrand?: unknown }).__tangoBrand === TangoResponse.BRAND\n );\n }\n\n /**\n * Create a JSON response with sensible content headers.\n */\n static json(\n data: JsonValue,\n init?: Omit<TangoResponseInit, 'body' | 'headers'> & { headers?: HeadersInit }\n ): TangoResponse {\n const headers = new TangoHeaders(init?.headers);\n if (!headers.has('Content-Type')) {\n headers.set('Content-Type', 'application/json; charset=utf-8');\n }\n const body = JSON.stringify(data);\n if (!headers.has('Content-Length')) {\n headers.set('Content-Length', new TextEncoder().encode(body).length.toString());\n }\n return new TangoResponse({\n ...init,\n body,\n headers,\n });\n }\n\n /**\n * Create a plain-text response with sensible content headers.\n */\n static text(\n text: string,\n init?: Omit<TangoResponseInit, 'body' | 'headers'> & { headers?: HeadersInit }\n ): TangoResponse {\n const headers = new TangoHeaders(init?.headers);\n if (!headers.has('Content-Type')) {\n headers.set('Content-Type', 'text/plain; charset=utf-8');\n }\n if (!headers.has('Content-Length')) {\n headers.set('Content-Length', new TextEncoder().encode(text).length.toString());\n }\n return new TangoResponse({\n ...init,\n body: text,\n headers,\n });\n }\n\n /**\n * Create an HTML response with sensible content headers.\n */\n static html(\n html: string,\n init?: Omit<TangoResponseInit, 'body' | 'headers'> & { headers?: HeadersInit }\n ): TangoResponse {\n const headers = new TangoHeaders(init?.headers);\n if (!headers.has('Content-Type')) {\n headers.set('Content-Type', 'text/html; charset=utf-8');\n }\n if (!headers.has('Content-Length')) {\n headers.set('Content-Length', new TextEncoder().encode(html).length.toString());\n }\n return new TangoResponse({\n ...init,\n body: html,\n headers,\n });\n }\n\n /**\n * Create a streaming response without buffering the payload in memory.\n */\n static stream(\n stream: ReadableStream<Uint8Array>,\n init?: Omit<TangoResponseInit, 'body' | 'headers'> & { headers?: HeadersInit }\n ): TangoResponse {\n return new TangoResponse({\n ...init,\n body: stream,\n headers: new TangoHeaders(init?.headers),\n });\n }\n\n /**\n * Create a redirect response and set the `Location` header.\n */\n static redirect(\n url: string,\n status: number = 302,\n init?: Omit<TangoResponseInit, 'body' | 'headers' | 'status'> & {\n headers?: HeadersInit;\n }\n ): TangoResponse {\n const headers = new TangoHeaders(init?.headers);\n headers.set('Location', url);\n return new TangoResponse({\n ...init,\n body: undefined,\n status,\n headers,\n redirected: true,\n url,\n });\n }\n\n /**\n * Create an empty `204 No Content` response.\n */\n static noContent(\n init?: Omit<TangoResponseInit, 'body' | 'status' | 'headers'> & {\n headers?: HeadersInit;\n }\n ): TangoResponse {\n const headers = new TangoHeaders(init?.headers);\n return new TangoResponse({\n ...init,\n body: undefined,\n status: 204,\n headers,\n });\n }\n\n /**\n * Create a `201 Created` response and optionally attach a location or body.\n */\n static created(\n location?: string,\n body?: JsonValue,\n init?: Omit<TangoResponseInit, 'body' | 'status' | 'headers'> & {\n headers?: HeadersInit;\n }\n ): TangoResponse {\n const headers = new TangoHeaders(init?.headers);\n if (location) {\n headers.set('Location', location);\n }\n let respBody: BodyInit | undefined;\n if (body !== undefined) {\n respBody = JSON.stringify(body);\n if (!headers.has('Content-Type')) {\n headers.set('Content-Type', 'application/json; charset=utf-8');\n }\n }\n if (typeof respBody === 'string' && !headers.has('Content-Length')) {\n headers.set('Content-Length', new TextEncoder().encode(respBody).length.toString());\n }\n return new TangoResponse({\n ...init,\n body: respBody,\n status: 201,\n headers,\n });\n }\n\n /**\n * Create a `405 Method Not Allowed` response and optionally populate `Allow`.\n */\n static methodNotAllowed(\n allow?: readonly string[],\n detail: string = 'Method not allowed.',\n init?: Omit<TangoResponseInit, 'body' | 'status' | 'headers'> & {\n headers?: HeadersInit;\n }\n ): TangoResponse {\n const headers = new TangoHeaders(init?.headers);\n if (allow && allow.length > 0) {\n headers.set('Allow', allow.join(', '));\n }\n return TangoResponse.json(\n {\n error: detail,\n },\n {\n ...init,\n status: 405,\n headers,\n }\n );\n }\n\n /**\n * Normalize a Tango error or problem-details object into an error response.\n */\n static error<TDetails extends ErrorDetails = null>(\n error: TangoError | ProblemDetails<TDetails>,\n init?: Omit<TangoResponseInit, 'body' | 'headers'> & { headers?: HeadersInit }\n ): TangoResponse {\n let code: string;\n let message: string;\n let details: ErrorDetails;\n let fields: Record<string, string[]> | undefined;\n let status = init?.status ?? 500;\n\n if (TangoError.isTangoError(error)) {\n const envelope = error.toErrorEnvelope();\n code = envelope.error.code;\n message = envelope.error.message;\n details = envelope.error.details;\n fields = envelope.error.fields;\n status = error.status;\n } else {\n code = error.code;\n message = error.message;\n details = error.details;\n fields = error.fields;\n }\n\n return TangoResponse.problem(\n {\n code,\n message,\n details,\n fields,\n },\n {\n ...init,\n status,\n }\n );\n }\n\n /**\n * Create a `400 Bad Request` response from a string or structured error.\n */\n static badRequest<TDetails extends ErrorDetails = null>(\n detail?: string | TangoError | ProblemDetails<TDetails>,\n init?: Omit<TangoResponseInit, 'body' | 'status' | 'headers'> & {\n headers?: HeadersInit;\n }\n ): TangoResponse {\n if (TangoError.isTangoError(detail) || TangoError.isProblemDetails(detail)) {\n return TangoResponse.error(detail, { ...init, status: 400 });\n }\n\n if (typeof detail === 'string') {\n return TangoResponse.error(\n {\n code: 'bad_request',\n message: detail,\n },\n { ...init, status: 400 }\n );\n }\n\n return TangoResponse.error(\n {\n code: 'bad_request',\n message: 'Bad Request',\n },\n { ...init, status: 400 }\n );\n }\n\n /**\n * Create a `401 Unauthorized` response from a string or structured error.\n */\n static unauthorized<TDetails extends ErrorDetails = null>(\n detail?: string | TangoError | ProblemDetails<TDetails>,\n init?: Omit<TangoResponseInit, 'body' | 'status' | 'headers'> & {\n headers?: HeadersInit;\n }\n ): TangoResponse {\n if (TangoError.isTangoError(detail) || TangoError.isProblemDetails(detail)) {\n return TangoResponse.error(detail, { ...init, status: 401 });\n }\n if (typeof detail === 'string') {\n return TangoResponse.error(\n {\n code: 'unauthorized',\n message: detail,\n },\n { ...init, status: 401 }\n );\n }\n\n return TangoResponse.error(\n {\n code: 'unauthorized',\n message: 'Unauthorized',\n },\n { ...init, status: 401 }\n );\n }\n\n /**\n * Create a `403 Forbidden` response from a string or structured error.\n */\n static forbidden<TDetails extends ErrorDetails = null>(\n detail?: string | TangoError | ProblemDetails<TDetails>,\n init?: Omit<TangoResponseInit, 'body' | 'status' | 'headers'> & {\n headers?: HeadersInit;\n }\n ): TangoResponse {\n if (TangoError.isTangoError(detail) || TangoError.isProblemDetails(detail)) {\n return TangoResponse.error(detail, { ...init, status: 403 });\n }\n\n if (typeof detail === 'string') {\n return TangoResponse.error(\n {\n code: 'forbidden',\n message: detail,\n },\n { ...init, status: 403 }\n );\n }\n\n return TangoResponse.error(\n {\n code: 'forbidden',\n message: 'Forbidden',\n },\n { ...init, status: 403 }\n );\n }\n\n /**\n * Create a `404 Not Found` response from a string or structured error.\n */\n static notFound<TDetails extends ErrorDetails = null>(\n detail?: string | TangoError | ProblemDetails<TDetails>,\n init?: Omit<TangoResponseInit, 'body' | 'status' | 'headers'> & {\n headers?: HeadersInit;\n }\n ): TangoResponse {\n if (TangoError.isTangoError(detail) || TangoError.isProblemDetails(detail)) {\n return TangoResponse.error(detail, { ...init, status: 404 });\n }\n\n if (typeof detail === 'string') {\n return TangoResponse.error(\n {\n code: 'not_found',\n message: detail,\n },\n { ...init, status: 404 }\n );\n }\n\n return TangoResponse.error(\n {\n code: 'not_found',\n message: 'Not Found',\n },\n { ...init, status: 404 }\n );\n }\n\n /**\n * Create a `409 Conflict` response from a string or structured error.\n */\n static conflict<TDetails extends ErrorDetails = null>(\n detail?: string | TangoError | ProblemDetails<TDetails>,\n init?: Omit<TangoResponseInit, 'body' | 'status' | 'headers'> & {\n headers?: HeadersInit;\n }\n ): TangoResponse {\n if (TangoError.isTangoError(detail) || TangoError.isProblemDetails(detail)) {\n return TangoResponse.error(detail, { ...init, status: 409 });\n }\n\n if (typeof detail === 'string') {\n return TangoResponse.error(\n {\n code: 'conflict',\n message: detail,\n },\n { ...init, status: 409 }\n );\n }\n\n return TangoResponse.error(\n {\n code: 'conflict',\n message: 'Conflict',\n },\n { ...init, status: 409 }\n );\n }\n\n /**\n * Create a `422 Unprocessable Entity` response from a string or structured error.\n */\n static unprocessableEntity<TDetails extends ErrorDetails = null>(\n detail?: string | TangoError | ProblemDetails<TDetails>,\n init?: Omit<TangoResponseInit, 'body' | 'status' | 'headers'> & {\n headers?: HeadersInit;\n }\n ): TangoResponse {\n if (TangoError.isTangoError(detail) || TangoError.isProblemDetails(detail)) {\n return TangoResponse.error(detail, { ...init, status: 422 });\n }\n\n if (typeof detail === 'string') {\n return TangoResponse.error(\n {\n code: 'unprocessable_entity',\n message: detail,\n },\n { ...init, status: 422 }\n );\n }\n\n return TangoResponse.error(\n {\n code: 'unprocessable_entity',\n message: 'Unprocessable Entity',\n },\n { ...init, status: 422 }\n );\n }\n\n /**\n * Create a `429 Too Many Requests` response from a string or structured error.\n */\n static tooManyRequests<TDetails extends ErrorDetails = null>(\n detail?: string | TangoError | ProblemDetails<TDetails>,\n init?: Omit<TangoResponseInit, 'body' | 'status' | 'headers'> & {\n headers?: HeadersInit;\n }\n ): TangoResponse {\n if (TangoError.isTangoError(detail) || TangoError.isProblemDetails(detail)) {\n return TangoResponse.error(detail, { ...init, status: 429 });\n }\n\n if (typeof detail === 'string') {\n return TangoResponse.error(\n {\n code: 'too_many_requests',\n message: detail,\n },\n { ...init, status: 429 }\n );\n }\n\n return TangoResponse.error(\n {\n code: 'too_many_requests',\n message: 'Too Many Requests',\n },\n { ...init, status: 429 }\n );\n }\n\n /**\n * Create a problem-details style error response with Tango's envelope shape.\n */\n static problem<TDetails extends ErrorDetails = null>(\n problem?: string | TangoError | ProblemDetails<TDetails> | unknown,\n init?: Omit<TangoResponseInit, 'body' | 'headers'> & {\n headers?: HeadersInit;\n status?: number;\n }\n ): TangoResponse {\n let status = init?.status ?? 500;\n const headers = new TangoHeaders(init?.headers);\n if (!headers.has('Content-Type')) {\n headers.set('Content-Type', 'application/problem+json; charset=utf-8');\n }\n\n let code = 'error';\n let message = 'An error occurred';\n let details: ErrorDetails = undefined;\n let fields: Record<string, string[]> | undefined;\n\n if (TangoError.isTangoError(problem)) {\n const envelope = problem.toErrorEnvelope();\n status = problem.status;\n code = envelope.error.code;\n message = envelope.error.message;\n details = envelope.error.details;\n fields = envelope.error.fields;\n } else if (TangoError.isProblemDetails(problem)) {\n code = problem.code;\n message = problem.message;\n details = problem.details;\n fields = problem.fields;\n } else if (typeof problem === 'string') {\n message = problem;\n } else if (problem && typeof problem === 'object') {\n const extracted = problem as {\n details?: ErrorDetails;\n fields?: Record<string, string[]>;\n };\n details = extracted.details;\n fields = extracted.fields;\n }\n\n const envelope: ErrorEnvelope<ErrorDetails> = {\n error: {\n code,\n message,\n ...(details === undefined ? {} : { details }),\n ...(fields ? { fields } : {}),\n },\n };\n\n const body = JSON.stringify(envelope);\n if (!headers.has('Content-Length')) {\n headers.set('Content-Length', new TextEncoder().encode(body).length.toString());\n }\n return new TangoResponse({\n ...init,\n headers,\n status,\n body,\n });\n }\n\n /**\n * Returns a response for serving a file.\n */\n static file(\n file: Blob | Uint8Array | ArrayBuffer | ReadableStream<Uint8Array> | string,\n opts?: {\n filename?: string;\n contentType?: string;\n init?: Omit<TangoResponseInit, 'body' | 'headers'> & { headers?: HeadersInit };\n }\n ): TangoResponse {\n const headers = new TangoHeaders(opts?.init?.headers ?? {});\n if (opts?.filename) {\n // Serve as an attachment by default, but not 'download'\n headers.setContentDispositionInline(opts.filename);\n }\n if (opts?.contentType && !headers.has('Content-Type')) {\n headers.set('Content-Type', opts.contentType);\n } else if (!headers.has('Content-Type')) {\n headers.setContentTypeByFile(file, opts?.filename);\n }\n if (!headers.has('Content-Length')) {\n headers.setContentLengthFromBody(file);\n }\n return new TangoResponse({\n ...opts?.init,\n body: file as BodyInit,\n headers,\n });\n }\n\n /**\n * Returns a response that prompts the user to download the file.\n */\n static download(\n file: Blob | Uint8Array | ArrayBuffer | ReadableStream<Uint8Array> | string,\n opts?: {\n filename?: string;\n contentType?: string;\n init?: Omit<TangoResponseInit, 'body' | 'headers'> & { headers?: HeadersInit };\n }\n ): TangoResponse {\n const headers = new TangoHeaders(opts?.init?.headers ?? {});\n if (opts?.filename) {\n headers.setContentDispositionAttachment(opts.filename);\n } else {\n headers.set('Content-Disposition', 'attachment');\n }\n if (opts?.contentType && !headers.has('Content-Type')) {\n headers.set('Content-Type', opts.contentType);\n } else if (!headers.has('Content-Type')) {\n headers.setContentTypeByFile(file, opts?.filename);\n }\n if (!headers.has('Content-Length')) {\n headers.setContentLengthFromBody(file);\n }\n return new TangoResponse({\n ...opts?.init,\n body: file as BodyInit,\n headers,\n });\n }\n\n private static normalizeWebBody(body: BodyInit | JsonValue | null): BodyInit | null {\n if (\n isNil(body) ||\n typeof body === 'string' ||\n isBlob(body) ||\n isFormData(body) ||\n isArrayBuffer(body) ||\n isUint8Array(body) ||\n isURLSearchParams(body) ||\n isReadableStream(body)\n ) {\n return body;\n }\n\n return JSON.stringify(body);\n }\n\n /**\n * Expose the original body source for cloning and adapter integration.\n */\n get bodySource(): BodyInit | JsonValue | null {\n return this.tangoBody.bodySource;\n }\n\n /**\n * Report whether the status code falls inside the 2xx range.\n */\n get ok(): boolean {\n if (typeof this.okValue === 'boolean') return this.okValue;\n return this.status >= 200 && this.status < 300;\n }\n\n /**\n * Report whether the body has been consumed.\n */\n get bodyUsed(): boolean {\n return this.tangoBody.bodyUsed;\n }\n\n /**\n * Replace a header value on the response.\n */\n setHeader(name: string, value: string): void {\n this.headers.set(name, value);\n }\n /**\n * Append another value for a repeated response header.\n */\n appendHeader(name: string, value: string): void {\n this.headers.append(name, value);\n }\n /**\n * Read a response header value.\n */\n getHeader(name: string): string | null {\n return this.headers.get(name);\n }\n /**\n * Check whether a response header is present.\n */\n hasHeader(name: string): boolean {\n return this.headers.has(name);\n }\n /**\n * Remove a response header.\n */\n deleteHeader(name: string): void {\n this.headers.delete(name);\n }\n /**\n * Merge one or more values into the `Vary` header.\n */\n vary(...fields: string[]): void {\n this.headers.vary(...fields);\n }\n\n /**\n * Add a `Set-Cookie` header that replaces prior application intent.\n */\n setCookie(name: string, value: string, options?: Parameters<TangoHeaders['setCookie']>[2]): void {\n this.headers.setCookie(name, value, options);\n }\n /**\n * Append another `Set-Cookie` header.\n */\n appendCookie(name: string, value: string, options?: Parameters<TangoHeaders['appendCookie']>[2]): void {\n this.headers.appendCookie(name, value, options);\n }\n /**\n * Expire a cookie by issuing a matching deletion cookie header.\n */\n deleteCookie(name: string, options?: Parameters<TangoHeaders['deleteCookie']>[1]): void {\n this.headers.deleteCookie(name, options);\n }\n\n /**\n * Set the `Cache-Control` header through Tango's higher-level helper.\n */\n cacheControl(control: Parameters<TangoHeaders['cacheControl']>[0]): void {\n this.headers.cacheControl(control);\n }\n\n /**\n * Set the `Location` header on the response.\n */\n location(url: string): void {\n this.headers.location(url);\n }\n\n /**\n * Set the response content type.\n */\n contentType(mime: string): void {\n this.headers.contentType(mime);\n }\n\n // ---- Trace & Correlation helper methods ----\n\n /**\n * Set the X-Request-Id header (request correlation).\n * Returns this for fluent chaining.\n */\n withRequestId(requestId: string | undefined | null): this {\n if (!isNil(requestId) && typeof requestId === 'string' && requestId !== '') {\n this.headers.set('X-Request-Id', requestId);\n }\n return this;\n }\n\n /**\n * Set the traceparent header (W3C Trace Context propagation).\n * Returns this for fluent chaining.\n */\n withTraceparent(traceparent: string | undefined | null): this {\n if (!isNil(traceparent) && typeof traceparent === 'string' && traceparent !== '') {\n this.headers.set('traceparent', traceparent);\n }\n return this;\n }\n\n /**\n * Set the Server-Timing header.\n * Accepts a string or array of timing metrics.\n * Returns this for fluent chaining.\n */\n withServerTiming(timing: string | string[]): this {\n if (Array.isArray(timing)) {\n this.headers.set('Server-Timing', timing.join(', '));\n } else if (typeof timing === 'string') {\n this.headers.set('Server-Timing', timing);\n }\n return this;\n }\n\n /**\n * Set the X-Response-Time header (in ms).\n * Numeric or formatted string (e.g. \"76ms\").\n * Returns this for fluent chaining.\n */\n withResponseTime(time: number | string): this {\n if (typeof time === 'number') {\n this.headers.set('X-Response-Time', `${time}ms`);\n } else if (typeof time === 'string') {\n this.headers.set('X-Response-Time', time);\n }\n return this;\n }\n\n /**\n * Propagate common tracing/correlation headers from provided Headers, TangoHeaders, or plain object.\n * Known headers: x-request-id, traceparent, server-timing\n * Returns this for fluent chaining.\n */\n propagateTraceHeaders(input: HeadersInit): this {\n const incoming = new TangoHeaders(input);\n const traceHeaderNames = [\n 'x-request-id',\n 'traceparent',\n 'server-timing',\n // If you want to propagate response time, add 'x-response-time',\n ];\n for (const name of traceHeaderNames) {\n const value = incoming.get(name);\n if (!isNil(value)) this.headers.set(name, value);\n }\n return this;\n }\n\n /**\n * Clone the response so its body can be consumed independently.\n */\n clone(): TangoResponse {\n if (this.bodyUsed) {\n throw new TypeError('Body has already been used');\n }\n const clonedBody = this.tangoBody.clone();\n return new TangoResponse({\n body: clonedBody.bodySource,\n headers: this.headers.clone(),\n ok: this.okValue,\n redirected: this.redirected,\n status: this.status,\n statusText: this.statusText,\n type: this.type,\n url: this.url,\n });\n }\n\n /**\n * Convert this Tango-owned response into a native web `Response`.\n *\n * Adapters use this at the host-framework boundary so Tango can standardize\n * on `TangoResponse` internally while Next.js and other hosts still receive\n * a platform-native response object.\n */\n toWebResponse(): Response {\n const responseForTransfer = !this.bodyUsed && isReadableStream(this.bodySource) ? this.clone() : this;\n const body = TangoResponse.normalizeWebBody(responseForTransfer.bodySource);\n\n return new Response(body, {\n headers: new Headers(responseForTransfer.headers),\n status: responseForTransfer.status,\n statusText: responseForTransfer.statusText,\n });\n }\n\n //---- Spec Response interface fields and methods ----\n\n /**\n * Read the response body as an array buffer.\n */\n async arrayBuffer(): Promise<ArrayBuffer> {\n return this.tangoBody.arrayBuffer();\n }\n /**\n * Read the response body as a blob.\n */\n async blob(): Promise<Blob> {\n return this.tangoBody.blob();\n }\n /**\n * Read the response body as bytes.\n */\n async bytes(): Promise<Uint8Array<ArrayBuffer>> {\n return this.tangoBody.bytes();\n }\n /**\n * Read the response body as form data.\n */\n async formData(): Promise<FormData> {\n return this.tangoBody.formData();\n }\n /**\n * Parse the response body as JSON.\n */\n async json<T = unknown>(): Promise<T> {\n return this.tangoBody.json<T>();\n }\n /**\n * Read the response body as text.\n */\n async text(): Promise<string> {\n return this.tangoBody.text();\n }\n\n /**\n * Returns a plain object debug representation of this response: { status, headers: { ... }, bodyType: ... }.\n * Intended for testing and debug tooling.\n */\n toJSON(): { status: number; headers: Record<string, string>; bodyType: string } {\n return {\n status: this.status,\n headers: Object.fromEntries(this.headers.entries()),\n bodyType: this.tangoBody.bodyType,\n };\n }\n\n /**\n * Returns the original body for test/debug purposes *without* consuming the stream.\n *\n * @throws {Error} if called in a production environment. Provided only for test or debug.\n * @remarks\n * This method gives direct access to the original body as provided to the constructor,\n * before consumption. It is primarily intended for use in test code, introspection, or\n * advanced debug tools. **Do not rely on this in production.**\n * In production (`process.env.NODE_ENV === 'production'`), using this method will throw.\n *\n * This method is _not_ part of the web Response interface, and is intentionally private/internal.\n */\n\n public __peekBodyForTestOnly(): BodyInit | JsonValue | null {\n const nodeEnv = typeof process !== 'undefined' ? (process.env?.NODE_ENV as string | undefined) : undefined;\n\n // Strong guard against accidental shipping in production\n if (nodeEnv === 'production' || nodeEnv === 'prod') {\n throw new Error('peekBody() is not available in production builds. For test/debug use only.');\n }\n return this.tangoBody.bodySource;\n }\n}\n","/**\n * Domain boundary barrel: centralizes this subdomain's public contract.\n */\n\nimport { TangoBody, type JsonValue } from './TangoBody';\nimport { TangoHeaders } from './TangoHeaders';\nimport { TangoQueryParams } from './TangoQueryParams';\nimport { TangoRequest } from './TangoRequest';\nimport { TangoResponse } from './TangoResponse';\n\nexport { TangoBody, TangoHeaders, TangoQueryParams, TangoRequest, TangoResponse };\nexport type { JsonValue };\n"],"mappings":";;;;;;;AA2BA,IAAa,YAAb,MAAa,UAAU;CACnB,OAAgB,QAAQ;CACxB,eAAgD,UAAU;CAC1D;CACA;CACA;CAEA,YAAY,YAA6B,SAAuB;EAC5D,KAAK,qBAAqB;EAC1B,KAAK,mBAAmB;EACxB,KAAK,UAAU;CACnB;;;;CAKA,OAAO,YAAY,OAAoC;EACnD,OACI,OAAO,UAAU,YACjB,UAAU,QACT,MAAqC,iBAAiB,UAAU;CAEzE;;;;CAKA,IAAW,aAA8B;EACrC,OAAO,KAAK;CAChB;;;;CAKA,IAAI,WAAoB;EACpB,OAAO,KAAK;CAChB;;;;CAKA,IAAI,WAAmB;EACnB,MAAM,OAAO,KAAK;EAClB,IAAI,MAAM,IAAI,GAAG,OAAO;EACxB,IAAI,OAAO,SAAS,UAAU,OAAO;EACrC,IAAI,cAAc,IAAI,GAAG,OAAO;EAChC,IAAI,aAAa,IAAI,GAAG,OAAO;EAC/B,IAAI,OAAO,IAAI,GAAG,OAAO;EACzB,IAAI,WAAW,IAAI,GAAG,OAAO;EAC7B,IAAI,kBAAkB,IAAI,GAAG,OAAO;EACpC,IAAI,iBAAiB,IAAI,GAAG,OAAO;EACnC,IAAI,UAAU,YAAY,IAAI,GAAG,OAAO;EACxC,OAAO,OAAO;CAClB;;;;CAKA,OAAc,YAAY,GAA4B;EAClD,IAAI,MAAM,QAAQ,OAAO,MAAM,YAAY,OAAO,MAAM,YAAY,OAAO,MAAM,WAC7E,OAAO;EAEX,IAAI,MAAM,QAAQ,CAAC,GACf,OAAO,EAAE,MAAM,UAAU,WAAW;EAExC,IAAI,OAAO,MAAM,YAAY,MAAM,QAAQ,OAAO,UAAU,SAAS,KAAK,CAAC,MAAM,mBAC7E,OAAO,OAAO,OAAO,CAAC,EAAE,MAAM,UAAU,WAAW;EAEvD,OAAO;CACX;;;;;CAMA,OAAO,cAAc,MAAwC;EACzD,IAAI,MAAM,IAAI,GACV,OAAO;EAEX,IAAI,OAAO,SAAS,UAChB,OAAO;EAEX,IAAI,cAAc,IAAI,GAClB,OAAO,KAAK,MAAM,CAAC;EAEvB,IAAI,aAAa,IAAI,GACjB,OAAO,IAAI,WAAW,IAAI;EAE9B,IAAI,OAAO,IAAI,GACX,OAAO,KAAK,MAAM,GAAG,KAAK,MAAM,KAAK,IAAI;EAE7C,IAAI,WAAW,IAAI,GAAG;GAGlB,MAAM,SAAS,IAAI,SAAS;GAC5B,KAAK,MAAM,CAAC,GAAG,MAAM,MAEjB,IAAI,OAAO,CAAC,GAAG;IAEX,MAAM,OAAO,IAAI,KAAK,CAAC,CAAC,GAAG,EAAE,MAAM;KAAE,MAAM,EAAE;KAAM,cAAc,EAAE;IAAa,CAAC;IACjF,OAAO,OAAO,GAAG,IAAI;GACzB,OACI,OAAO,OAAO,GAAG,CAAW;GAGpC,OAAO;EACX;EACA,IAAI,iBAAiB,IAAI,GACrB,MAAM,IAAI,UAAU,oEAAoE;EAE5F,IAAI,UAAU,YAAY,IAAI,GAC1B,OAAO,KAAK,MAAM,KAAK,UAAU,IAAI,CAAC;EAE1C,OAAO;CACX;;;;CAKA,aAAa,wBAAwB,QAA0D;EAC3F,MAAM,SAAuB,CAAC;EAC9B,MAAM,SAAS,OAAO,UAAU;EAChC,IAAI,QAAQ;EACZ,OAAO,MAAM;GACT,MAAM,EAAE,MAAM,UAAU,MAAM,OAAO,KAAK;GAC1C,IAAI,MAAM;GACV,OAAO,KAAK,KAAK;GACjB,SAAS,MAAM;EACnB;EACA,MAAM,SAAS,IAAI,WAAW,KAAK;EACnC,IAAI,MAAM;EACV,KAAK,MAAM,SAAS,QAAQ;GACxB,OAAO,IAAI,OAAO,GAAG;GACrB,OAAO,MAAM;EACjB;EACA,OAAO,OAAO,OAAO,MAAM,GAAG,OAAO,UAAU;CACnD;;;;CAKA,aAAa,uBAAuB,QAAsE;EACtG,MAAM,MAAM,MAAM,UAAU,wBAAwB,MAAM;EAC1D,OAAO,IAAI,WAAW,GAAG;CAC7B;;;;CAKA,aAAa,iBAAiB,QAAqD;EAC/E,MAAM,MAAM,MAAM,UAAU,uBAAuB,MAAM;EACzD,OAAO,IAAI,YAAY,EAAE,OAAO,GAAG;CACvC;;;;;CAMA,OAAO,kBAAkB,MAAuB,cAA2C;EACvF,IAAI,cAAc,OAAO;EACzB,IAAI,MAAM,IAAI,GAAG,OAAO,KAAA;EACxB,IAAI,OAAO,SAAS,UAAU,OAAO;EACrC,IAAI,cAAc,IAAI,KAAK,aAAa,IAAI,GAAG,OAAO;EACtD,IAAI,OAAO,IAAI,GAAG;GACd,IAAI,KAAK,MAAM,OAAO,KAAK;GAC3B,OAAO;EACX;EACA,IAAI,WAAW,IAAI,GAAG,OAAO,KAAA;EAC7B,IAAI,OAAO,SAAS,YAAY,UAAU,YAAY,IAAI,GAAG,OAAO;EACpE,IAAI,iBAAiB,IAAI,GAAG,OAAO,KAAA;CAEvC;;;;;CAMA,aAAa,iBAAiB,MAAoD;EAC9E,IAAI,MAAM,IAAI,GAAG,OAAO;EACxB,IAAI,OAAO,SAAS,UAAU,OAAO,IAAI,YAAY,EAAE,OAAO,IAAI,EAAE;EACpE,IAAI,aAAa,IAAI,GAAG,OAAO,KAAK;EACpC,IAAI,cAAc,IAAI,GAAG,OAAO,KAAK;EACrC,IAAI,OAAO,IAAI,GAAG,OAAO,KAAK;EAC9B,IAAI,UAAU,YAAY,IAAI,GAAG,OAAO,IAAI,YAAY,EAAE,OAAO,KAAK,UAAU,IAAI,CAAC,EAAE;CAE3F;;;;CAKA,MAAM,cAAoC;EACtC,OAAO,KAAK,YAAY,OAAO,UAAU;GACrC,IAAI,cAAc,KAAK,GAAG,OAAO;GACjC,IAAI,aAAa,KAAK,GAAG;IACrB,MAAM,OAAO,IAAI,WAAW,MAAM,UAAU;IAC5C,KAAK,IAAI,KAAK;IACd,OAAO,KAAK;GAChB;GACA,IAAI,OAAO,UAAU,UAAU,OAAO,IAAI,YAAY,EAAE,OAAO,KAAK,EAAE;GACtE,IAAI,OAAO,KAAK,GAAG,OAAO,MAAM,YAAY;GAC5C,IAAI,iBAAiB,KAAK,GACtB,OAAO,UAAU,wBAAwB,KAAK;GAElD,IAAI,UAAU,YAAY,KAAK,GAE3B,OAAO,IAAI,YAAY,EAAE,OAAO,KAAK,UAAU,KAAK,CAAC,EAAE;GAE3D,MAAM,IAAI,UAAU,+EAA+E;EACvG,CAAC;CACL;;;;CAKA,MAAM,OAAsB;EACxB,OAAO,KAAK,YAAY,OAAO,UAAU;GACrC,IAAI,OAAO,KAAK,GAAG,OAAO;GAC1B,IAAI,OAAO,UAAU,UAAU,OAAO,IAAI,KAAK,CAAC,KAAK,CAAC;GACtD,IAAI,cAAc,KAAK,GAAG,OAAO,IAAI,KAAK,CAAC,KAAK,CAAC;GACjD,IAAI,aAAa,KAAK,GAAG,OAAO,IAAI,KAAK,CAAC,IAAI,WAAW,KAAK,CAAC,CAAC;GAChE,IAAI,iBAAiB,KAAK,GAAG;IACzB,MAAM,MAAM,MAAM,UAAU,wBAAwB,KAAK;IACzD,OAAO,IAAI,KAAK,CAAC,GAAG,CAAC;GACzB;GACA,IAAI,UAAU,YAAY,KAAK,GAC3B,OAAO,IAAI,KAAK,CAAC,KAAK,UAAU,KAAK,CAAC,GAAG,EAAE,MAAM,mBAAmB,CAAC;GAEzE,MAAM,IAAI,UACN,0FACJ;EACJ,CAAC;CACL;;;;CAKA,MAAM,QAA0C;EAC5C,OAAO,KAAK,YAAY,OAAO,UAAU;GACrC,IAAI,aAAa,KAAK,GAAG,OAAO,IAAI,WAAW,KAAK;GACpD,IAAI,cAAc,KAAK,GAAG,OAAO,IAAI,WAAW,KAAK;GACrD,IAAI,OAAO,UAAU,UAAU,OAAO,IAAI,YAAY,EAAE,OAAO,KAAK;GACpE,IAAI,OAAO,KAAK,GAAG,OAAO,IAAI,WAAW,MAAM,MAAM,YAAY,CAAC;GAClE,IAAI,iBAAiB,KAAK,GACtB,OAAO,UAAU,uBAAuB,KAAK;GAEjD,IAAI,UAAU,YAAY,KAAK,GAC3B,OAAO,IAAI,YAAY,EAAE,OAAO,KAAK,UAAU,KAAK,CAAC;GAEzD,MAAM,IAAI,UAAU,mFAAmF;EAC3G,CAAC;CACL;;;;;CAMA,MAAM,WAA8B;EAChC,OAAO,KAAK,YAAY,OAAO,UAAU;GACrC,IAAI,WAAW,KAAK,GAAG,OAAO;GAE9B,IAAI,cAAkC,KAAA;GACtC,IAAI,KAAK,WAAW,OAAO,KAAK,QAAQ,QAAQ,YAAY;IACxD,MAAM,MAAM,KAAK,QAAQ,IAAI,cAAc;IAC3C,IAAI,OAAO,QAAQ,UAAU,cAAc,IAAI,YAAY;GAC/D;GAEA,IAAI;GACJ,IAAI,OAAO,UAAU,UACjB,MAAM;QACH,IAAI,cAAc,KAAK,GAC1B,MAAM,IAAI,YAAY,EAAE,OAAO,KAAK;QACjC,IAAI,aAAa,KAAK,GACzB,MAAM,IAAI,YAAY,EAAE,OAAO,KAAK;QAEpC,MAAM,IAAI,UAAU,gCAAgC;GAIxD,IAAI,eAAe,YAAY,SAAS,mCAAmC,GAAG;IAC1E,MAAM,OAAO,IAAI,SAAS;IAE1B,IADmB,gBAAgB,GAC9B,EAAE,SAAS,OAAO,QAAQ,KAAK,OAAO,KAAK,KAAK,CAAC;IACtD,OAAO;GACX;GAEA,IAAI,eAAe,YAAY,WAAW,qBAAqB,GAAG;IAC9D,MAAM,gBAAgB,sBAAsB,KAAK,WAAW;IAC5D,IAAI,CAAC,eAAe,MAAM,IAAI,UAAU,yCAAyC;IACjF,MAAM,WAAW,cAAc;IAG/B,MAAM,QAAQ,IAAI,MAAM,KAAK,UAAU;IACvC,MAAM,OAAO,IAAI,SAAS;IAC1B,KAAK,MAAM,QAAQ,OAAO;KACtB,MAAM,UAAU,KAAK,KAAK;KAC1B,IAAI,CAAC,WAAW,YAAY,QAAQ,YAAY,IAAI;KAEpD,MAAM,CAAC,aAAa,IAAI,GAAG,gBAAgB,QAAQ,MAAM,YAAY;KACrE,MAAM,OAAO,aAAa,KAAK,MAAM,EAAE,QAAQ,UAAU,EAAE;KAC3D,MAAM,mBAAmB,sDAAsD,KAAK,UAAU;KAC9F,IAAI,CAAC,kBAAkB;KACvB,MAAM,OAAO,iBAAiB;KAC9B,KAAK,OAAO,MAAM,IAAI;IAC1B;IACA,OAAO;GACX;GACA,MAAM,IAAI,UAAU,qDAAqD;EAC7E,CAAC;CACL;;;;CAKA,MAAM,OAAgC;EAClC,OAAO,KAAK,YAAY,OAAO,UAAU;GACrC,IAAI,OAAO,UAAU,UAAU,OAAO,KAAK,MAAM,KAAK;GACtD,IAAI,UAAU,YAAY,KAAK,GAAG,OAAO;GACzC,IAAI,cAAc,KAAK,KAAK,aAAa,KAAK,GAAG;IAC7C,MAAM,OAAO,IAAI,YAAY,EAAE,OAAO,aAAa,KAAK,IAAI,QAAQ,IAAI,WAAW,KAAK,CAAC;IACzF,OAAO,KAAK,MAAM,IAAI;GAC1B;GACA,IAAI,iBAAiB,KAAK,GAAG;IACzB,MAAM,OAAO,MAAM,UAAU,iBAAiB,KAAK;IACnD,OAAO,KAAK,MAAM,IAAI;GAC1B;GACA,MAAM,IAAI,UAAU,wBAAwB;EAChD,CAAC;CACL;;;;CAKA,MAAM,OAAwB;EAC1B,OAAO,KAAK,YAAY,OAAO,UAAU;GACrC,IAAI,OAAO,UAAU,UAAU,OAAO;GACtC,IAAI,cAAc,KAAK,GAAG,OAAO,IAAI,YAAY,EAAE,OAAO,KAAK;GAC/D,IAAI,aAAa,KAAK,GAAG,OAAO,IAAI,YAAY,EAAE,OAAO,KAAK;GAC9D,IAAI,OAAO,KAAK,GAAG,OAAO,MAAM,MAAM,KAAK;GAC3C,IAAI,iBAAiB,KAAK,GAAG,OAAO,MAAM,UAAU,iBAAiB,KAAK;GAC1E,IAAI,UAAU,YAAY,KAAK,GAAG,OAAO,KAAK,UAAU,KAAK;GAC7D,MAAM,IAAI,UAAU,sFAAsF;EAC9G,CAAC;CACL;;;;CAKA,iBAAkC;EAC9B,OAAO,KAAK;CAChB;;;;;CAMA,QAAmB;EACf,IAAI,KAAK,kBAAkB,MAAM,IAAI,UAAU,6BAA6B;EAC5E,IAAI,iBAAiB,KAAK,kBAAkB,GAAG;GAC3C,IAAI,OAAO,KAAK,mBAAmB,QAAQ,YACvC,MAAM,IAAI,UAAU,mEAAmE;GAE3F,MAAM,CAAC,mBAAmB,kBAAkB,KAAK,mBAAmB,IAAI;GACxE,KAAK,qBAAqB;GAC1B,OAAO,IAAI,UAAU,gBAAgB,KAAK,OAAO;EACrD;EAEA,OAAO,IAAI,UADS,UAAU,cAAc,KAAK,kBAClB,GAAG,KAAK,OAAO;CAClD;;;;CAKA,MAAc,YAAe,QAA4D;EACrF,IAAI,KAAK,kBACL,MAAM,IAAI,UAAU,iCAAiC;EAEzD,KAAK,mBAAmB;EACxB,OAAO,OAAO,KAAK,kBAAkB;CACzC;AACJ;;;;;;;;;;;;;;;;;ACtYA,IAAa,eAAb,MAAa,qBAAqB,QAAQ;CACtC,OAAgB,QAAQ;CACxB,eAAmD,aAAa;;;;CAKhE,OAAO,eAAe,OAAuC;EACzD,OACI,OAAO,UAAU,YACjB,UAAU,QACT,MAAqC,iBAAiB,aAAa;CAE5E;;;;CAKA,OAAe,gBACX,MACA,OACA,UAUI,CAAC,GACC;EACN,IAAI,SAAS,mBAAmB,IAAI,IAAI,MAAM,mBAAmB,SAAS,EAAE;EAC5E,IAAI,QAAQ,QAAQ,UAAU,YAAY,QAAQ;EAClD,IAAI,QAAQ,MAAM,UAAU,UAAU,QAAQ;OACzC,UAAU;EACf,IAAI,QAAQ,SAAS,UAAU,aAAa,QAAQ,QAAQ,YAAY;EACxE,IAAI,OAAO,QAAQ,WAAW,UAAU,UAAU,aAAa,QAAQ;EACvE,IAAI,QAAQ,QAAQ,UAAU;EAC9B,IAAI,QAAQ,UAAU,UAAU;EAChC,IAAI,QAAQ,UAAU,UAAU,cAAc,QAAQ;EACtD,IAAI,QAAQ,UAAU,UAAU,cAAc,QAAQ;EACtD,IAAI,QAAQ,aAAa,UAAU;EACnC,OAAO;CACX;CAEA,OAAe,cAAc,OAA2C;EACpE,OAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,OAAQ,MAA6B,SAAS;CACxG;CAEA,OAAe,gBAAgB,OAA6C;EACxE,OACI,OAAO,UAAU,YAAY,UAAU,QAAQ,OAAQ,MAA+B,WAAW;CAEzG;CAEA,OAAe,aAAa,OAA6C;EACrE,MAAM,cAAc;EACpB,OACI,OAAO,WAAW,eAAe,OAAO,YAAY,aAAa,cAAc,YAAY,SAAS,KAAK;CAEjH;;;;;;;;CASA,4BAA4B,UAAwB;EAChD,MAAM,UAAU,mBAAmB,QAAQ;EAC3C,KAAK,IAAI,uBAAuB,qBAAqB,QAAQ,sBAAsB,SAAS;CAChG;;;;;;;CAQA,gCAAgC,UAAwB;EACpD,MAAM,UAAU,mBAAmB,QAAQ;EAC3C,KAAK,IAAI,uBAAuB,yBAAyB,QAAQ,sBAAsB,SAAS;CACpG;;;;CAKA,QAAsB;EAClB,MAAM,OAAO,IAAI,aAAa;EAC9B,KAAK,MAAM,CAAC,MAAM,UAAU,KAAK,QAAQ,GACrC,KAAK,OAAO,MAAM,KAAK;EAE3B,OAAO;CACX;;;;CAKA,UAAU,MAAc,OAAqB;EACzC,KAAK,IAAI,MAAM,KAAK;CACxB;;;;CAKA,aAAa,MAAc,OAAqB;EAC5C,KAAK,OAAO,MAAM,KAAK;CAC3B;;;;CAKA,UAAU,MAA6B;EACnC,OAAO,KAAK,IAAI,IAAI;CACxB;;;;CAKA,UAAU,MAAuB;EAC7B,OAAO,KAAK,IAAI,IAAI;CACxB;;;;CAKA,aAAa,MAAoB;EAC7B,KAAK,OAAO,IAAI;CACpB;;;;CAKA,aAAa,MAAc,OAAqB;EAC5C,KAAK,OAAO,IAAI;EAChB,KAAK,IAAI,MAAM,KAAK;CACxB;;;;CAKA,KAAK,GAAG,QAAwB;EAC5B,IAAI,OAAO,WAAW,GAAG;EACzB,MAAM,MAAM;EACZ,MAAM,OAAO,KAAK,IAAI,GAAG;EACzB,MAAM,0BAAU,IAAI,IAAY;EAChC,IAAI;QACK,MAAM,KAAK,KAAK,MAAM,GAAG,GAC1B,IAAI,EAAE,KAAK,GAAG,QAAQ,IAAI,EAAE,KAAK,CAAC;EAAA;EAG1C,KAAK,MAAM,KAAK,QACZ,IAAI,EAAE,KAAK,GAAG,QAAQ,IAAI,EAAE,KAAK,CAAC;EAEtC,KAAK,IAAI,KAAK,MAAM,KAAK,OAAO,EAAE,KAAK,IAAI,CAAC;CAChD;;;;;;;CAQA,UACI,MACA,OACA,SAWI;EACJ,KAAK,OAAO,cAAc,aAAa,gBAAgB,MAAM,OAAO,OAAO,CAAC;CAChF;;;;CAKA,aACI,MACA,OACA,SAWI;EACJ,KAAK,OAAO,cAAc,aAAa,gBAAgB,MAAM,OAAO,OAAO,CAAC;CAChF;;;;CAKA,aACI,MACA,SAQI;EACJ,KAAK,UAAU,MAAM,IAAI;GACrB,GAAG;GACH,yBAAS,IAAI,KAAK,CAAC;GACnB,QAAQ;EACZ,CAAC;CACL;;;;CAKA,aAAa,SAA+E;EACxF,IAAI,OAAO,YAAY,UAAU;GAC7B,KAAK,IAAI,iBAAiB,OAAO;GACjC;EACJ;EAEA,MAAM,QAAkB,CAAC;EACzB,KAAK,MAAM,CAAC,GAAG,MAAM,OAAO,QAAQ,OAAO,GACvC,IAAI,OAAO,MAAM;OACT,GAAG,MAAM,KAAK,EAAE,QAAQ,WAAW,MAAM,MAAM,EAAE,YAAY,CAAC,CAAC;EAAA,OAChE,IAAI,OAAO,MAAM,YAAa,OAAO,MAAM,YAAY,EAAE,SAAS,GACrE,MAAM,KAAK,GAAG,EAAE,QAAQ,WAAW,MAAM,MAAM,EAAE,YAAY,CAAC,EAAE,GAAG,GAAG;EAG9E,IAAI,MAAM,QACN,KAAK,IAAI,iBAAiB,MAAM,KAAK,IAAI,CAAC;CAElD;;;;CAKA,SAAS,KAAmB;EACxB,KAAK,IAAI,YAAY,GAAG;CAC5B;;;;CAKA,YAAY,MAAoB;EAC5B,KAAK,IAAI,gBAAgB,IAAI;CACjC;;;;;;;CAQA,qBAAqB,MAAe,UAAyB;EAEzD,IAAI,KAAK,IAAI,cAAc,GAAG;EAG9B,IAAI,OAAO,SAAS,YAAY,UAAU;GAEtC,MAAM,WAAW,SAAS,YAAY,GAAG;GAmBzC,MAAM,OAAO;IAhBT,KAAK;IACL,MAAM;IACN,MAAM;IACN,KAAK;IACL,IAAI;IACJ,MAAM;IACN,KAAK;IACL,MAAM;IACN,KAAK;IACL,KAAK;IACL,MAAM;IACN,KAAK;IACL,KAAK;IACL,KAAK;IACL,IAAI;GAEO,EAlBH,YAAY,IAAI,SAAS,MAAM,WAAW,CAAC,EAAE,YAAY,IAAI;GAmBzE,IAAI,MACA,KAAK,IAAI,gBAAgB,IAAI;QAE7B,KAAK,IAAI,gBAAgB,0BAA0B;GAEvD;EACJ;EAGA,IAAI,OAAO,IAAI,GAAG;GACd,IAAI,KAAK,QAAQ,KAAK,SAAS,IAC3B,KAAK,IAAI,gBAAgB,KAAK,IAAI;QAElC,KAAK,IAAI,gBAAgB,0BAA0B;GAEvD;EACJ;EAGA,KAAK,IAAI,gBAAgB,0BAA0B;CACvD;;;;;;;CAQA,yBAAyB,MAAqB;EAC1C,IAAI,KAAK,IAAI,gBAAgB,KAAK,SAAS,QAAQ,SAAS,KAAA,GACxD;EAGJ,IAAI;EAEJ,IAAI,OAAO,SAAS,UAChB,MAAM,IAAI,YAAY,EAAE,OAAO,IAAI,EAAE;OAClC,IAAI,cAAc,IAAI,GACzB,MAAM,KAAK;OAGV,IAAI,aAAa,aAAa,IAAI,GACnC,MAAO,KAA4B;OAChC,IAAI,aAAa,IAAI,GACxB,MAAM,KAAK;OACR,IAAI,OAAO,IAAI,GAClB,MAAM,KAAK;OAGV,IAAI,aAAa,cAAc,IAAI,GACpC,MAAO,KAA0B;OAGhC,IACD,aAAa,gBAAgB,IAAI,KACjC,OAAO,SAAS,YAChB,CAAC,cAAc,IAAI,KACnB,CAAC,aAAa,IAAI,GAElB,MAAO,KAA4B;EAGvC,IAAI,OAAO,QAAQ,UACf,KAAK,IAAI,kBAAkB,IAAI,SAAS,CAAC;CAEjD;;;;;CAMA,cAAc,IAAkB;EAC5B,KAAK,IAAI,gBAAgB,EAAE;EAC3B,OAAO;CACX;;;;;CAMA,gBAAgB,OAAqB;EACjC,KAAK,IAAI,eAAe,KAAK;EAC7B,OAAO;CACX;;;;;;;;;;CAWA,iBAAiB,MAAc,KAAc,MAAqB;EAE9D,IAAI,SAAS;EACb,IAAI,OAAO,QAAQ,UACf,UAAU,QAAQ;EAEtB,IAAI,MACA,UAAU,UAAU,KAAK,QAAQ,MAAM,MAAK,EAAE;EAIlD,MAAM,OAAO,KAAK,IAAI,eAAe;EACrC,IAAI,QAAQ,KAAK,SAAS,GACtB,KAAK,IAAI,iBAAiB,OAAO,OAAO,MAAM;OAE9C,KAAK,IAAI,iBAAiB,MAAM;EAEpC,OAAO;CACX;;;;;;CAOA,sBAAsB,OAAqB;EACvC,MAAM,OAAO,KAAK,IAAI,eAAe;EACrC,IAAI,QAAQ,KAAK,SAAS,GACtB,KAAK,IAAI,iBAAiB,OAAO,OAAO,KAAK;OAE7C,KAAK,IAAI,iBAAiB,KAAK;EAEnC,OAAO;CACX;;;;;CAMA,iBAAiB,IAA2B;EACxC,KAAK,IAAI,mBAAmB,OAAO,OAAO,WAAW,GAAG,GAAG,MAAM,EAAE;EACnE,OAAO;CACX;;;;CAKA,eAA8B;EAC1B,OAAO,KAAK,IAAI,cAAc;CAClC;;;;CAKA,iBAAgC;EAC5B,OAAO,KAAK,IAAI,aAAa;CACjC;;;;CAKA,kBAAiC;EAC7B,OAAO,KAAK,IAAI,eAAe;CACnC;;;;CAKA,kBAAiC;EAC7B,OAAO,KAAK,IAAI,iBAAiB;CACrC;AACJ;;;;;;;ACldA,IAAa,mBAAb,MAAa,iBAAiB;CAC1B,OAAgB,QAAQ;CACxB,eAAuD,iBAAiB;CACxE;CAEA,YAAoB,QAAwC;EACxD,KAAK,SAAS;CAClB;;;;CAKA,OAAO,mBAAmB,OAA2C;EACjE,OACI,OAAO,UAAU,YACjB,UAAU,QACT,MAAqC,iBAAiB,iBAAiB;CAEhF;;;;CAKA,OAAO,oBAAoB,QAA2C;EAClE,MAAM,yBAAS,IAAI,IAAsB;EAEzC,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,GAAG;GACzC,MAAM,UAAU,OAAO,IAAI,GAAG;GAC9B,IAAI,SAAS;IACT,QAAQ,KAAK,KAAK;IAClB;GACJ;GACA,OAAO,IAAI,KAAK,CAAC,KAAK,CAAC;EAC3B;EAEA,OAAO,IAAI,iBAAiB,MAAM;CACtC;;;;CAKA,OAAO,WAAW,QAA4C;EAC1D,MAAM,yBAAS,IAAI,IAAsB;EAEzC,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,MAAM,GAAG;GAC/C,IAAI,MAAM,QAAQ,KAAK,GAAG;IACtB,MAAM,aAAa,MAAM,QAAQ,UAAU,OAAO,UAAU,QAAQ;IACpE,IAAI,WAAW,SAAS,GACpB,OAAO,IAAI,KAAK,UAAU;IAE9B;GACJ;GAEA,IAAI,OAAO,UAAU,UACjB,OAAO,IAAI,KAAK,CAAC,KAAK,CAAC;EAE/B;EAEA,OAAO,IAAI,iBAAiB,MAAM;CACtC;;;;CAKA,OAAO,QAAQ,OAAuC;EAClD,MAAM,MAAM,OAAO,UAAU,WAAW,IAAI,IAAI,KAAK,IAAI;EACzD,OAAO,iBAAiB,oBAAoB,IAAI,YAAY;CAChE;;;;CAKA,OAAO,YAAY,SAAmD;EAClE,OAAO,iBAAiB,QAAQ,QAAQ,GAAG;CAC/C;;;;CAKA,IAAI,MAAkC;EAClC,OAAO,KAAK,OAAO,IAAI,IAAI,IAAI;CACnC;;;;CAKA,OAAO,MAAwB;EAC3B,OAAO,CAAC,GAAI,KAAK,OAAO,IAAI,IAAI,KAAK,CAAC,CAAE;CAC5C;;;;CAKA,IAAI,MAAuB;EACvB,QAAQ,KAAK,OAAO,IAAI,IAAI,GAAG,UAAU,KAAK;CAClD;;;;CAKA,CAAC,UAAgD;EAC7C,KAAK,MAAM,CAAC,KAAK,WAAW,KAAK,OAAO,QAAQ,GAC5C,MAAM,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC;CAE/B;;;;CAKA,CAAC,OAAiC;EAC9B,OAAO,KAAK,OAAO,KAAK;CAC5B;;;;CAKA,oBAAqC;EACjC,MAAM,SAAS,IAAI,gBAAgB;EAEnC,KAAK,MAAM,CAAC,KAAK,WAAW,KAAK,OAAO,QAAQ,GAC5C,KAAK,MAAM,SAAS,QAChB,OAAO,OAAO,KAAK,KAAK;EAIhC,OAAO;CACX;;;;;;CAOA,WAAW,SAAqD;EAC5D,MAAM,uBAAO,IAAI,IAAsB;EAEvC,KAAK,MAAM,CAAC,KAAK,WAAW,KAAK,OAAO,QAAQ,GAC5C,KAAK,IAAI,KAAK,CAAC,GAAG,MAAM,CAAC;EAG7B,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,OAAO,GAAG;GAChD,IAAI,UAAU,KAAA,KAAa,UAAU,MAAM;IACvC,KAAK,OAAO,GAAG;IACf;GACJ;GAEA,MAAM,aAAa,MAAM,QAAQ,KAAK,IAAI,MAAM,KAAK,UAAU,OAAO,KAAK,CAAC,IAAI,CAAC,OAAO,KAAK,CAAC;GAC9F,IAAI,WAAW,WAAW,GAAG;IACzB,KAAK,OAAO,GAAG;IACf;GACJ;GAEA,KAAK,IAAI,KAAK,UAAU;EAC5B;EAEA,OAAO,IAAI,iBAAiB,IAAI;CACpC;;;;CAKA,gBAAwB;EACpB,MAAM,QAAQ,KAAK,kBAAkB,EAAE,SAAS;EAChD,OAAO,MAAM,SAAS,IAAI,IAAI,UAAU;CAC5C;;;;CAKA,WAAW,MAAkC;EACzC,MAAM,QAAQ,KAAK,IAAI,IAAI,GAAG,KAAK;EACnC,OAAO,QAAQ,QAAQ,KAAA;CAC3B;;;;CAKA,UAAU,MAAc,UAA8B;EAClD,OAAO,KAAK,WAAW,GAAG;CAC9B;;;;CAKA,YAAY,MAAc,YAAsB;EAC5C,MAAM,QAAQ,KAAK,IAAI,GAAG;EAC1B,IAAI,CAAC,OACD,OAAO,CAAC;EAGZ,OAAO,MACF,MAAM,GAAG,EACT,KAAK,UAAU,MAAM,KAAK,CAAC,EAC3B,QAAQ,UAAU,MAAM,SAAS,CAAC;CAC3C;AACJ;;;;;;;AC9KA,IAAa,eAAb,MAAa,aAAgC;CACzC,OAAgB,QAAQ;CACxB,eAAmD,aAAa;CAChE;CACA;CACA;CAEA,YAAY,OAAyB,OAAyB,CAAC,GAAG;EAC9D,MAAM,gBAAgB,OAAO,UAAU,WAAW,KAAA,IAAY;EAC9D,MAAM,UAAU,KAAK,UAAU,eAAe,UAAU,OAAO,YAAY;EAC3E,MAAM,UAAU,IAAI,QAAQ,KAAK,WAAW,eAAe,OAAO;EAClE,MAAM,iBAAiB,KAAK,cAAc,KAAK,MAAM,SAAS,MAAM;EAEpE,MAAM,cAAiD;GACnD;GACA;GACA,UAAU,KAAK,YAAY,eAAe;GAC1C,OAAO,KAAK,SAAS,eAAe;GACpC,aAAa,KAAK,eAAe,eAAe;GAChD,WAAW,KAAK,aAAa,eAAe;GAC5C,WAAW,KAAK,aAAa,eAAe;GAC5C,MAAM,KAAK,QAAQ,eAAe;GAClC,UAAU,KAAK,YAAY,eAAe;GAC1C,gBAAgB,KAAK,kBAAkB,eAAe;GACtD,QAAQ,KAAK,UAAU,eAAe;EAC1C;EAEA,IAAI,mBAAmB,KAAA,GAAW;GAC9B,YAAY,OAAO;GACnB,IAAI,iBAAiB,cAAc,GAC/B,YAAY,SAAS;EAE7B;EAEA,KAAK,UAAU,IAAI,QAAQ,OAAO,WAAW;EAC7C,KAAK,kBAAkB,kBAAkB;CAC7C;;;;CAKA,OAAO,eAAe,OAAuC;EACzD,OACI,OAAO,UAAU,YACjB,UAAU,QACT,MAAqC,iBAAiB,aAAa;CAE5E;;;;CAKA,IAAI,QAAsB;EACtB,OAAO,KAAK,QAAQ;CACxB;;;;CAKA,IAAI,cAAkC;EAClC,OAAO,KAAK,QAAQ;CACxB;;;;CAKA,IAAI,cAAkC;EAClC,OAAO,KAAK,QAAQ;CACxB;;;;CAKA,IAAI,UAAmB;EACnB,OAAO,KAAK,QAAQ;CACxB;;;;CAKA,IAAI,YAAoB;EACpB,OAAO,KAAK,QAAQ;CACxB;;;;CAKA,IAAI,YAAqB;EACrB,OAAO,KAAK,QAAQ;CACxB;;;;CAKA,IAAI,SAAiB;EACjB,OAAO,KAAK,QAAQ;CACxB;;;;CAKA,IAAI,OAAoB;EACpB,OAAO,KAAK,QAAQ;CACxB;;;;CAKA,IAAI,WAA4B;EAC5B,OAAO,KAAK,QAAQ;CACxB;;;;CAKA,IAAI,WAAmB;EACnB,OAAO,KAAK,QAAQ;CACxB;;;;CAKA,IAAI,iBAAiC;EACjC,OAAO,KAAK,QAAQ;CACxB;;;;CAKA,IAAI,SAAsB;EACtB,OAAO,KAAK,QAAQ;CACxB;;;;CAKA,IAAI,MAAc;EACd,OAAO,KAAK,QAAQ;CACxB;;;;CAKA,IAAI,OAAwB;EACxB,OAAO,KAAK,QAAQ;CACxB;;;;CAKA,IAAI,WAAoB;EACpB,OAAO,KAAK,QAAQ;CACxB;;;;CAKA,IAAI,aAA0C;EAC1C,OAAO,KAAK;CAChB;;;;CAKA,IAAI,cAAgC;EAChC,KAAK,qBAAqB,iBAAiB,QAAQ,KAAK,QAAQ,GAAG;EACnE,OAAO,KAAK;CAChB;;;;CAKA,MAAM,cAAoC;EACtC,OAAO,KAAK,QAAQ,YAAY;CACpC;;;;CAKA,MAAM,OAAsB;EACxB,OAAO,KAAK,QAAQ,KAAK;CAC7B;;;;CAKA,MAAM,QAA0C;EAC5C,MAAM,mBAAmB,KAAK;EAC9B,IAAI,OAAO,iBAAiB,UAAU,YAClC,OAAO,iBAAiB,MAAM;EAElC,MAAM,SAAS,MAAM,KAAK,QAAQ,YAAY;EAC9C,OAAO,IAAI,WAAW,MAAM;CAChC;;;;CAKA,MAAM,WAA8B;EAChC,OAAO,KAAK,QAAQ,SAAS;CACjC;;;;CAKA,MAAM,OAAgC;EAClC,OAAO,KAAK,QAAQ,KAAK;CAC7B;;;;CAKA,MAAM,OAAwB;EAC1B,OAAO,KAAK,QAAQ,KAAK;CAC7B;;;;CAKA,QAAsB;EAClB,OAAO,IAAI,aAAa,KAAK,QAAQ,MAAM,CAAC;CAChD;CAEA,cACI,MACA,SACA,QACoB;EACpB,IAAI,WAAW,SAAS,WAAW,QAC/B;EAEJ,IAAI,MAAM,IAAI,GACV;EAEJ,IAAI,OAAO,SAAS,UAChB,OAAO;EAEX,IAAI,cAAc,IAAI,KAAK,aAAa,IAAI,KAAK,OAAO,IAAI,GACxD,OAAO;EAEX,IAAI,kBAAkB,IAAI,KAAK,WAAW,IAAI,KAAK,iBAAiB,IAAI,GACpE,OAAO;EAGX,MAAM,aAAa,KAAK,UAAU,IAAI;EACtC,IAAI,CAAC,QAAQ,IAAI,cAAc,GAC3B,QAAQ,IAAI,gBAAgB,iCAAiC;EAEjE,OAAO;CACX;AACJ;;;;;;AC9PA,IAAa,gBAAb,MAAa,cAAkC;CAC3C,OAAgB,QAAQ;CACxB,eAAoD,cAAc;CAClE;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CAEA,YAAY,OAA0B,CAAC,GAAG;EACtC,KAAK,UAAU,IAAI,aAAa,KAAK,OAAO;EAC5C,KAAK,aAAa,QAAQ,KAAK,UAAU;EACzC,KAAK,SAAS,OAAO,KAAK,WAAW,WAAW,KAAK,SAAS;EAC9D,KAAK,aAAa,KAAK,cAAc;EACrC,KAAK,OAAO,KAAK,QAAQ;EACzB,KAAK,MAAM,KAAK,OAAO;EACvB,KAAK,UAAU,OAAO,KAAK,OAAO,YAAY,KAAK,KAAK,KAAA;EAExD,KAAK,YAAY,IAAI,UAAU,KAAK,QAAQ,MAAM,KAAK,OAAO;EAC9D,KAAK,OAAO,iBAAiB,KAAK,UAAU,UAAU,IAAI,KAAK,UAAU,aAAa;CAC1F;;;;CAKA,OAAO,gBAAgB,OAAwC;EAC3D,OACI,OAAO,UAAU,YACjB,UAAU,QACT,MAAqC,iBAAiB,cAAc;CAE7E;;;;CAKA,OAAO,KACH,MACA,MACa;EACb,MAAM,UAAU,IAAI,aAAa,MAAM,OAAO;EAC9C,IAAI,CAAC,QAAQ,IAAI,cAAc,GAC3B,QAAQ,IAAI,gBAAgB,iCAAiC;EAEjE,MAAM,OAAO,KAAK,UAAU,IAAI;EAChC,IAAI,CAAC,QAAQ,IAAI,gBAAgB,GAC7B,QAAQ,IAAI,kBAAkB,IAAI,YAAY,EAAE,OAAO,IAAI,EAAE,OAAO,SAAS,CAAC;EAElF,OAAO,IAAI,cAAc;GACrB,GAAG;GACH;GACA;EACJ,CAAC;CACL;;;;CAKA,OAAO,KACH,MACA,MACa;EACb,MAAM,UAAU,IAAI,aAAa,MAAM,OAAO;EAC9C,IAAI,CAAC,QAAQ,IAAI,cAAc,GAC3B,QAAQ,IAAI,gBAAgB,2BAA2B;EAE3D,IAAI,CAAC,QAAQ,IAAI,gBAAgB,GAC7B,QAAQ,IAAI,kBAAkB,IAAI,YAAY,EAAE,OAAO,IAAI,EAAE,OAAO,SAAS,CAAC;EAElF,OAAO,IAAI,cAAc;GACrB,GAAG;GACH,MAAM;GACN;EACJ,CAAC;CACL;;;;CAKA,OAAO,KACH,MACA,MACa;EACb,MAAM,UAAU,IAAI,aAAa,MAAM,OAAO;EAC9C,IAAI,CAAC,QAAQ,IAAI,cAAc,GAC3B,QAAQ,IAAI,gBAAgB,0BAA0B;EAE1D,IAAI,CAAC,QAAQ,IAAI,gBAAgB,GAC7B,QAAQ,IAAI,kBAAkB,IAAI,YAAY,EAAE,OAAO,IAAI,EAAE,OAAO,SAAS,CAAC;EAElF,OAAO,IAAI,cAAc;GACrB,GAAG;GACH,MAAM;GACN;EACJ,CAAC;CACL;;;;CAKA,OAAO,OACH,QACA,MACa;EACb,OAAO,IAAI,cAAc;GACrB,GAAG;GACH,MAAM;GACN,SAAS,IAAI,aAAa,MAAM,OAAO;EAC3C,CAAC;CACL;;;;CAKA,OAAO,SACH,KACA,SAAiB,KACjB,MAGa;EACb,MAAM,UAAU,IAAI,aAAa,MAAM,OAAO;EAC9C,QAAQ,IAAI,YAAY,GAAG;EAC3B,OAAO,IAAI,cAAc;GACrB,GAAG;GACH,MAAM,KAAA;GACN;GACA;GACA,YAAY;GACZ;EACJ,CAAC;CACL;;;;CAKA,OAAO,UACH,MAGa;EACb,MAAM,UAAU,IAAI,aAAa,MAAM,OAAO;EAC9C,OAAO,IAAI,cAAc;GACrB,GAAG;GACH,MAAM,KAAA;GACN,QAAQ;GACR;EACJ,CAAC;CACL;;;;CAKA,OAAO,QACH,UACA,MACA,MAGa;EACb,MAAM,UAAU,IAAI,aAAa,MAAM,OAAO;EAC9C,IAAI,UACA,QAAQ,IAAI,YAAY,QAAQ;EAEpC,IAAI;EACJ,IAAI,SAAS,KAAA,GAAW;GACpB,WAAW,KAAK,UAAU,IAAI;GAC9B,IAAI,CAAC,QAAQ,IAAI,cAAc,GAC3B,QAAQ,IAAI,gBAAgB,iCAAiC;EAErE;EACA,IAAI,OAAO,aAAa,YAAY,CAAC,QAAQ,IAAI,gBAAgB,GAC7D,QAAQ,IAAI,kBAAkB,IAAI,YAAY,EAAE,OAAO,QAAQ,EAAE,OAAO,SAAS,CAAC;EAEtF,OAAO,IAAI,cAAc;GACrB,GAAG;GACH,MAAM;GACN,QAAQ;GACR;EACJ,CAAC;CACL;;;;CAKA,OAAO,iBACH,OACA,SAAiB,uBACjB,MAGa;EACb,MAAM,UAAU,IAAI,aAAa,MAAM,OAAO;EAC9C,IAAI,SAAS,MAAM,SAAS,GACxB,QAAQ,IAAI,SAAS,MAAM,KAAK,IAAI,CAAC;EAEzC,OAAO,cAAc,KACjB,EACI,OAAO,OACX,GACA;GACI,GAAG;GACH,QAAQ;GACR;EACJ,CACJ;CACJ;;;;CAKA,OAAO,MACH,OACA,MACa;EACb,IAAI;EACJ,IAAI;EACJ,IAAI;EACJ,IAAI;EACJ,IAAI,SAAS,MAAM,UAAU;EAE7B,IAAI,WAAW,aAAa,KAAK,GAAG;GAChC,MAAM,WAAW,MAAM,gBAAgB;GACvC,OAAO,SAAS,MAAM;GACtB,UAAU,SAAS,MAAM;GACzB,UAAU,SAAS,MAAM;GACzB,SAAS,SAAS,MAAM;GACxB,SAAS,MAAM;EACnB,OAAO;GACH,OAAO,MAAM;GACb,UAAU,MAAM;GAChB,UAAU,MAAM;GAChB,SAAS,MAAM;EACnB;EAEA,OAAO,cAAc,QACjB;GACI;GACA;GACA;GACA;EACJ,GACA;GACI,GAAG;GACH;EACJ,CACJ;CACJ;;;;CAKA,OAAO,WACH,QACA,MAGa;EACb,IAAI,WAAW,aAAa,MAAM,KAAK,WAAW,iBAAiB,MAAM,GACrE,OAAO,cAAc,MAAM,QAAQ;GAAE,GAAG;GAAM,QAAQ;EAAI,CAAC;EAG/D,IAAI,OAAO,WAAW,UAClB,OAAO,cAAc,MACjB;GACI,MAAM;GACN,SAAS;EACb,GACA;GAAE,GAAG;GAAM,QAAQ;EAAI,CAC3B;EAGJ,OAAO,cAAc,MACjB;GACI,MAAM;GACN,SAAS;EACb,GACA;GAAE,GAAG;GAAM,QAAQ;EAAI,CAC3B;CACJ;;;;CAKA,OAAO,aACH,QACA,MAGa;EACb,IAAI,WAAW,aAAa,MAAM,KAAK,WAAW,iBAAiB,MAAM,GACrE,OAAO,cAAc,MAAM,QAAQ;GAAE,GAAG;GAAM,QAAQ;EAAI,CAAC;EAE/D,IAAI,OAAO,WAAW,UAClB,OAAO,cAAc,MACjB;GACI,MAAM;GACN,SAAS;EACb,GACA;GAAE,GAAG;GAAM,QAAQ;EAAI,CAC3B;EAGJ,OAAO,cAAc,MACjB;GACI,MAAM;GACN,SAAS;EACb,GACA;GAAE,GAAG;GAAM,QAAQ;EAAI,CAC3B;CACJ;;;;CAKA,OAAO,UACH,QACA,MAGa;EACb,IAAI,WAAW,aAAa,MAAM,KAAK,WAAW,iBAAiB,MAAM,GACrE,OAAO,cAAc,MAAM,QAAQ;GAAE,GAAG;GAAM,QAAQ;EAAI,CAAC;EAG/D,IAAI,OAAO,WAAW,UAClB,OAAO,cAAc,MACjB;GACI,MAAM;GACN,SAAS;EACb,GACA;GAAE,GAAG;GAAM,QAAQ;EAAI,CAC3B;EAGJ,OAAO,cAAc,MACjB;GACI,MAAM;GACN,SAAS;EACb,GACA;GAAE,GAAG;GAAM,QAAQ;EAAI,CAC3B;CACJ;;;;CAKA,OAAO,SACH,QACA,MAGa;EACb,IAAI,WAAW,aAAa,MAAM,KAAK,WAAW,iBAAiB,MAAM,GACrE,OAAO,cAAc,MAAM,QAAQ;GAAE,GAAG;GAAM,QAAQ;EAAI,CAAC;EAG/D,IAAI,OAAO,WAAW,UAClB,OAAO,cAAc,MACjB;GACI,MAAM;GACN,SAAS;EACb,GACA;GAAE,GAAG;GAAM,QAAQ;EAAI,CAC3B;EAGJ,OAAO,cAAc,MACjB;GACI,MAAM;GACN,SAAS;EACb,GACA;GAAE,GAAG;GAAM,QAAQ;EAAI,CAC3B;CACJ;;;;CAKA,OAAO,SACH,QACA,MAGa;EACb,IAAI,WAAW,aAAa,MAAM,KAAK,WAAW,iBAAiB,MAAM,GACrE,OAAO,cAAc,MAAM,QAAQ;GAAE,GAAG;GAAM,QAAQ;EAAI,CAAC;EAG/D,IAAI,OAAO,WAAW,UAClB,OAAO,cAAc,MACjB;GACI,MAAM;GACN,SAAS;EACb,GACA;GAAE,GAAG;GAAM,QAAQ;EAAI,CAC3B;EAGJ,OAAO,cAAc,MACjB;GACI,MAAM;GACN,SAAS;EACb,GACA;GAAE,GAAG;GAAM,QAAQ;EAAI,CAC3B;CACJ;;;;CAKA,OAAO,oBACH,QACA,MAGa;EACb,IAAI,WAAW,aAAa,MAAM,KAAK,WAAW,iBAAiB,MAAM,GACrE,OAAO,cAAc,MAAM,QAAQ;GAAE,GAAG;GAAM,QAAQ;EAAI,CAAC;EAG/D,IAAI,OAAO,WAAW,UAClB,OAAO,cAAc,MACjB;GACI,MAAM;GACN,SAAS;EACb,GACA;GAAE,GAAG;GAAM,QAAQ;EAAI,CAC3B;EAGJ,OAAO,cAAc,MACjB;GACI,MAAM;GACN,SAAS;EACb,GACA;GAAE,GAAG;GAAM,QAAQ;EAAI,CAC3B;CACJ;;;;CAKA,OAAO,gBACH,QACA,MAGa;EACb,IAAI,WAAW,aAAa,MAAM,KAAK,WAAW,iBAAiB,MAAM,GACrE,OAAO,cAAc,MAAM,QAAQ;GAAE,GAAG;GAAM,QAAQ;EAAI,CAAC;EAG/D,IAAI,OAAO,WAAW,UAClB,OAAO,cAAc,MACjB;GACI,MAAM;GACN,SAAS;EACb,GACA;GAAE,GAAG;GAAM,QAAQ;EAAI,CAC3B;EAGJ,OAAO,cAAc,MACjB;GACI,MAAM;GACN,SAAS;EACb,GACA;GAAE,GAAG;GAAM,QAAQ;EAAI,CAC3B;CACJ;;;;CAKA,OAAO,QACH,SACA,MAIa;EACb,IAAI,SAAS,MAAM,UAAU;EAC7B,MAAM,UAAU,IAAI,aAAa,MAAM,OAAO;EAC9C,IAAI,CAAC,QAAQ,IAAI,cAAc,GAC3B,QAAQ,IAAI,gBAAgB,yCAAyC;EAGzE,IAAI,OAAO;EACX,IAAI,UAAU;EACd,IAAI,UAAwB,KAAA;EAC5B,IAAI;EAEJ,IAAI,WAAW,aAAa,OAAO,GAAG;GAClC,MAAM,WAAW,QAAQ,gBAAgB;GACzC,SAAS,QAAQ;GACjB,OAAO,SAAS,MAAM;GACtB,UAAU,SAAS,MAAM;GACzB,UAAU,SAAS,MAAM;GACzB,SAAS,SAAS,MAAM;EAC5B,OAAO,IAAI,WAAW,iBAAiB,OAAO,GAAG;GAC7C,OAAO,QAAQ;GACf,UAAU,QAAQ;GAClB,UAAU,QAAQ;GAClB,SAAS,QAAQ;EACrB,OAAO,IAAI,OAAO,YAAY,UAC1B,UAAU;OACP,IAAI,WAAW,OAAO,YAAY,UAAU;GAC/C,MAAM,YAAY;GAIlB,UAAU,UAAU;GACpB,SAAS,UAAU;EACvB;EAEA,MAAM,WAAwC,EAC1C,OAAO;GACH;GACA;GACA,GAAI,YAAY,KAAA,IAAY,CAAC,IAAI,EAAE,QAAQ;GAC3C,GAAI,SAAS,EAAE,OAAO,IAAI,CAAC;EAC/B,EACJ;EAEA,MAAM,OAAO,KAAK,UAAU,QAAQ;EACpC,IAAI,CAAC,QAAQ,IAAI,gBAAgB,GAC7B,QAAQ,IAAI,kBAAkB,IAAI,YAAY,EAAE,OAAO,IAAI,EAAE,OAAO,SAAS,CAAC;EAElF,OAAO,IAAI,cAAc;GACrB,GAAG;GACH;GACA;GACA;EACJ,CAAC;CACL;;;;CAKA,OAAO,KACH,MACA,MAKa;EACb,MAAM,UAAU,IAAI,aAAa,MAAM,MAAM,WAAW,CAAC,CAAC;EAC1D,IAAI,MAAM,UAEN,QAAQ,4BAA4B,KAAK,QAAQ;EAErD,IAAI,MAAM,eAAe,CAAC,QAAQ,IAAI,cAAc,GAChD,QAAQ,IAAI,gBAAgB,KAAK,WAAW;OACzC,IAAI,CAAC,QAAQ,IAAI,cAAc,GAClC,QAAQ,qBAAqB,MAAM,MAAM,QAAQ;EAErD,IAAI,CAAC,QAAQ,IAAI,gBAAgB,GAC7B,QAAQ,yBAAyB,IAAI;EAEzC,OAAO,IAAI,cAAc;GACrB,GAAG,MAAM;GACT,MAAM;GACN;EACJ,CAAC;CACL;;;;CAKA,OAAO,SACH,MACA,MAKa;EACb,MAAM,UAAU,IAAI,aAAa,MAAM,MAAM,WAAW,CAAC,CAAC;EAC1D,IAAI,MAAM,UACN,QAAQ,gCAAgC,KAAK,QAAQ;OAErD,QAAQ,IAAI,uBAAuB,YAAY;EAEnD,IAAI,MAAM,eAAe,CAAC,QAAQ,IAAI,cAAc,GAChD,QAAQ,IAAI,gBAAgB,KAAK,WAAW;OACzC,IAAI,CAAC,QAAQ,IAAI,cAAc,GAClC,QAAQ,qBAAqB,MAAM,MAAM,QAAQ;EAErD,IAAI,CAAC,QAAQ,IAAI,gBAAgB,GAC7B,QAAQ,yBAAyB,IAAI;EAEzC,OAAO,IAAI,cAAc;GACrB,GAAG,MAAM;GACT,MAAM;GACN;EACJ,CAAC;CACL;CAEA,OAAe,iBAAiB,MAAoD;EAChF,IACI,MAAM,IAAI,KACV,OAAO,SAAS,YAChB,OAAO,IAAI,KACX,WAAW,IAAI,KACf,cAAc,IAAI,KAClB,aAAa,IAAI,KACjB,kBAAkB,IAAI,KACtB,iBAAiB,IAAI,GAErB,OAAO;EAGX,OAAO,KAAK,UAAU,IAAI;CAC9B;;;;CAKA,IAAI,aAA0C;EAC1C,OAAO,KAAK,UAAU;CAC1B;;;;CAKA,IAAI,KAAc;EACd,IAAI,OAAO,KAAK,YAAY,WAAW,OAAO,KAAK;EACnD,OAAO,KAAK,UAAU,OAAO,KAAK,SAAS;CAC/C;;;;CAKA,IAAI,WAAoB;EACpB,OAAO,KAAK,UAAU;CAC1B;;;;CAKA,UAAU,MAAc,OAAqB;EACzC,KAAK,QAAQ,IAAI,MAAM,KAAK;CAChC;;;;CAIA,aAAa,MAAc,OAAqB;EAC5C,KAAK,QAAQ,OAAO,MAAM,KAAK;CACnC;;;;CAIA,UAAU,MAA6B;EACnC,OAAO,KAAK,QAAQ,IAAI,IAAI;CAChC;;;;CAIA,UAAU,MAAuB;EAC7B,OAAO,KAAK,QAAQ,IAAI,IAAI;CAChC;;;;CAIA,aAAa,MAAoB;EAC7B,KAAK,QAAQ,OAAO,IAAI;CAC5B;;;;CAIA,KAAK,GAAG,QAAwB;EAC5B,KAAK,QAAQ,KAAK,GAAG,MAAM;CAC/B;;;;CAKA,UAAU,MAAc,OAAe,SAA0D;EAC7F,KAAK,QAAQ,UAAU,MAAM,OAAO,OAAO;CAC/C;;;;CAIA,aAAa,MAAc,OAAe,SAA6D;EACnG,KAAK,QAAQ,aAAa,MAAM,OAAO,OAAO;CAClD;;;;CAIA,aAAa,MAAc,SAA6D;EACpF,KAAK,QAAQ,aAAa,MAAM,OAAO;CAC3C;;;;CAKA,aAAa,SAA4D;EACrE,KAAK,QAAQ,aAAa,OAAO;CACrC;;;;CAKA,SAAS,KAAmB;EACxB,KAAK,QAAQ,SAAS,GAAG;CAC7B;;;;CAKA,YAAY,MAAoB;EAC5B,KAAK,QAAQ,YAAY,IAAI;CACjC;;;;;CAQA,cAAc,WAA4C;EACtD,IAAI,CAAC,MAAM,SAAS,KAAK,OAAO,cAAc,YAAY,cAAc,IACpE,KAAK,QAAQ,IAAI,gBAAgB,SAAS;EAE9C,OAAO;CACX;;;;;CAMA,gBAAgB,aAA8C;EAC1D,IAAI,CAAC,MAAM,WAAW,KAAK,OAAO,gBAAgB,YAAY,gBAAgB,IAC1E,KAAK,QAAQ,IAAI,eAAe,WAAW;EAE/C,OAAO;CACX;;;;;;CAOA,iBAAiB,QAAiC;EAC9C,IAAI,MAAM,QAAQ,MAAM,GACpB,KAAK,QAAQ,IAAI,iBAAiB,OAAO,KAAK,IAAI,CAAC;OAChD,IAAI,OAAO,WAAW,UACzB,KAAK,QAAQ,IAAI,iBAAiB,MAAM;EAE5C,OAAO;CACX;;;;;;CAOA,iBAAiB,MAA6B;EAC1C,IAAI,OAAO,SAAS,UAChB,KAAK,QAAQ,IAAI,mBAAmB,GAAG,KAAK,GAAG;OAC5C,IAAI,OAAO,SAAS,UACvB,KAAK,QAAQ,IAAI,mBAAmB,IAAI;EAE5C,OAAO;CACX;;;;;;CAOA,sBAAsB,OAA0B;EAC5C,MAAM,WAAW,IAAI,aAAa,KAAK;EAOvC,KAAK,MAAM,QAAQ;GALf;GACA;GACA;EAG8B,GAAG;GACjC,MAAM,QAAQ,SAAS,IAAI,IAAI;GAC/B,IAAI,CAAC,MAAM,KAAK,GAAG,KAAK,QAAQ,IAAI,MAAM,KAAK;EACnD;EACA,OAAO;CACX;;;;CAKA,QAAuB;EACnB,IAAI,KAAK,UACL,MAAM,IAAI,UAAU,4BAA4B;EAGpD,OAAO,IAAI,cAAc;GACrB,MAFe,KAAK,UAAU,MAEf,EAAE;GACjB,SAAS,KAAK,QAAQ,MAAM;GAC5B,IAAI,KAAK;GACT,YAAY,KAAK;GACjB,QAAQ,KAAK;GACb,YAAY,KAAK;GACjB,MAAM,KAAK;GACX,KAAK,KAAK;EACd,CAAC;CACL;;;;;;;;CASA,gBAA0B;EACtB,MAAM,sBAAsB,CAAC,KAAK,YAAY,iBAAiB,KAAK,UAAU,IAAI,KAAK,MAAM,IAAI;EACjG,MAAM,OAAO,cAAc,iBAAiB,oBAAoB,UAAU;EAE1E,OAAO,IAAI,SAAS,MAAM;GACtB,SAAS,IAAI,QAAQ,oBAAoB,OAAO;GAChD,QAAQ,oBAAoB;GAC5B,YAAY,oBAAoB;EACpC,CAAC;CACL;;;;CAOA,MAAM,cAAoC;EACtC,OAAO,KAAK,UAAU,YAAY;CACtC;;;;CAIA,MAAM,OAAsB;EACxB,OAAO,KAAK,UAAU,KAAK;CAC/B;;;;CAIA,MAAM,QAA0C;EAC5C,OAAO,KAAK,UAAU,MAAM;CAChC;;;;CAIA,MAAM,WAA8B;EAChC,OAAO,KAAK,UAAU,SAAS;CACnC;;;;CAIA,MAAM,OAAgC;EAClC,OAAO,KAAK,UAAU,KAAQ;CAClC;;;;CAIA,MAAM,OAAwB;EAC1B,OAAO,KAAK,UAAU,KAAK;CAC/B;;;;;CAMA,SAAgF;EAC5E,OAAO;GACH,QAAQ,KAAK;GACb,SAAS,OAAO,YAAY,KAAK,QAAQ,QAAQ,CAAC;GAClD,UAAU,KAAK,UAAU;EAC7B;CACJ;;;;;;;;;;;;;CAeA,wBAA4D;EACxD,MAAM,UAAU,OAAO,YAAY,cAAe,QAAQ,KAAK,WAAkC,KAAA;EAGjG,IAAI,YAAY,gBAAgB,YAAY,QACxC,MAAM,IAAI,MAAM,4EAA4E;EAEhG,OAAO,KAAK,UAAU;CAC1B;AACJ"}
1
+ {"version":3,"file":"http-BJPRtBGV.js","names":[],"sources":["../src/http/TangoBody.ts","../src/http/TangoHeaders.ts","../src/http/TangoQueryParams.ts","../src/http/TangoRequest.ts","../src/http/TangoResponse.ts","../src/http/index.ts"],"sourcesContent":["import {\n isArrayBuffer,\n isBlob,\n isFile,\n isFormData,\n isNil,\n isReadableStream,\n isUint8Array,\n isURLSearchParams,\n} from '../runtime/index';\n\n/**\n * The full type of body that TangoResponse/TangoBody supports.\n * Unlike the fetch spec BodyInit, this can be directly:\n * - a string, ArrayBuffer, Uint8Array, Blob, FormData, ReadableStream, or JSON-like object, or null/undefined.\n */\n\ntype HeadersLike = { get?: (arg: string) => string | null };\n\ntype TangoBodySource = BodyInit | JsonValue | null;\n\n/** Recursive JSON value contract used by Tango HTTP helpers. */\nexport type JsonValue = string | number | boolean | null | JsonValue[] | { [key: string]: JsonValue };\n\n/**\n * Unified body reader/clone utility for Tango request/response wrappers.\n */\nexport class TangoBody {\n static readonly BRAND = 'tango.http.body' as const;\n readonly __tangoBrand: typeof TangoBody.BRAND = TangoBody.BRAND;\n private bodySourceInternal: TangoBodySource;\n private bodyUsedInternal: boolean;\n private headers?: HeadersLike;\n\n constructor(bodySource: TangoBodySource, headers?: HeadersLike) {\n this.bodySourceInternal = bodySource;\n this.bodyUsedInternal = false;\n this.headers = headers;\n }\n\n /**\n * Narrow an unknown value to `TangoBody`.\n */\n static isTangoBody(value: unknown): value is TangoBody {\n return (\n typeof value === 'object' &&\n value !== null &&\n (value as { __tangoBrand?: unknown }).__tangoBrand === TangoBody.BRAND\n );\n }\n\n /**\n * Expose the original body source for cloning and adapter integration.\n */\n public get bodySource(): TangoBodySource {\n return this.bodySourceInternal;\n }\n\n /**\n * Report whether a reader method has already consumed this body.\n */\n get bodyUsed(): boolean {\n return this.bodyUsedInternal;\n }\n\n /**\n * Describe the current body shape in a way that is useful for diagnostics.\n */\n get bodyType(): string {\n const body = this.bodySourceInternal;\n if (isNil(body)) return 'null';\n if (typeof body === 'string') return 'string';\n if (isArrayBuffer(body)) return 'ArrayBuffer';\n if (isUint8Array(body)) return 'Uint8Array';\n if (isBlob(body)) return 'Blob';\n if (isFormData(body)) return 'FormData';\n if (isURLSearchParams(body)) return 'URLSearchParams';\n if (isReadableStream(body)) return 'ReadableStream';\n if (TangoBody.isJsonValue(body)) return 'JsonValue';\n return typeof body;\n }\n\n /**\n * Returns true if value is a valid JSON value (recursively).\n */\n public static isJsonValue(v: unknown): v is JsonValue {\n if (v === null || typeof v === 'string' || typeof v === 'number' || typeof v === 'boolean') {\n return true;\n }\n if (Array.isArray(v)) {\n return v.every(TangoBody.isJsonValue);\n }\n if (typeof v === 'object' && v !== null && Object.prototype.toString.call(v) === '[object Object]') {\n return Object.values(v).every(TangoBody.isJsonValue);\n }\n return false;\n }\n\n /**\n * Deep clone utility for body values. Preserves types and values as in the legacy implementation.\n * If the source is a stream, the stream will be cloned if readable, otherwise throws.\n */\n static deepCloneBody(body: TangoBodySource): TangoBodySource {\n if (isNil(body)) {\n return null;\n }\n if (typeof body === 'string') {\n return body;\n }\n if (isArrayBuffer(body)) {\n return body.slice(0);\n }\n if (isUint8Array(body)) {\n return new Uint8Array(body);\n }\n if (isBlob(body)) {\n return body.slice(0, body.size, body.type);\n }\n if (isFormData(body)) {\n // Deep clone FormData: only text fields (files not handled)\n // This is the best we can do in cross-platform without File support.\n const cloned = new FormData();\n for (const [k, v] of body) {\n // If value is File, attempt to clone (not fully implemented)\n if (isFile(v)) {\n // Note: Cloning File loses prototype, but rarely needed\n const file = new File([v], v.name, { type: v.type, lastModified: v.lastModified });\n cloned.append(k, file);\n } else {\n cloned.append(k, v as string);\n }\n }\n return cloned;\n }\n if (isReadableStream(body)) {\n throw new TypeError('Cannot deep clone a ReadableStream directly; use TangoBody.clone()');\n }\n if (TangoBody.isJsonValue(body)) {\n return JSON.parse(JSON.stringify(body));\n }\n return null;\n }\n\n /**\n * Read a `ReadableStream` into an `ArrayBuffer`.\n */\n static async readStreamToArrayBuffer(stream: ReadableStream<Uint8Array>): Promise<ArrayBuffer> {\n const chunks: Uint8Array[] = [];\n const reader = stream.getReader();\n let total = 0;\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n chunks.push(value);\n total += value.length;\n }\n const joined = new Uint8Array(total);\n let off = 0;\n for (const chunk of chunks) {\n joined.set(chunk, off);\n off += chunk.length;\n }\n return joined.buffer.slice(0, joined.byteLength) as ArrayBuffer;\n }\n\n /**\n * Read a `ReadableStream` into a `Uint8Array`.\n */\n static async readStreamToUint8Array(stream: ReadableStream<Uint8Array>): Promise<Uint8Array<ArrayBuffer>> {\n const buf = await TangoBody.readStreamToArrayBuffer(stream);\n return new Uint8Array(buf) as Uint8Array<ArrayBuffer>;\n }\n\n /**\n * Read a `ReadableStream` into UTF-8 text.\n */\n static async readStreamToText(stream: ReadableStream<Uint8Array>): Promise<string> {\n const arr = await TangoBody.readStreamToUint8Array(stream);\n return new TextDecoder().decode(arr);\n }\n\n /**\n * Determine the content type for this body, if possible.\n * Respects an explicitly passed header, otherwise infers from value type.\n */\n static detectContentType(body: TangoBodySource, providedType?: string): string | undefined {\n if (providedType) return providedType;\n if (isNil(body)) return undefined;\n if (typeof body === 'string') return 'text/plain; charset=utf-8';\n if (isArrayBuffer(body) || isUint8Array(body)) return 'application/octet-stream';\n if (isBlob(body)) {\n if (body.type) return body.type;\n return 'application/octet-stream';\n }\n if (isFormData(body)) return undefined;\n if (typeof body === 'object' && TangoBody.isJsonValue(body)) return 'application/json; charset=utf-8';\n if (isReadableStream(body)) return undefined;\n return undefined;\n }\n\n /**\n * Attempt to determine the content length, in bytes, for this body.\n * Only available for certain body types, otherwise returns undefined.\n */\n static async getContentLength(body: TangoBodySource): Promise<number | undefined> {\n if (isNil(body)) return 0;\n if (typeof body === 'string') return new TextEncoder().encode(body).length;\n if (isUint8Array(body)) return body.byteLength;\n if (isArrayBuffer(body)) return body.byteLength;\n if (isBlob(body)) return body.size;\n if (TangoBody.isJsonValue(body)) return new TextEncoder().encode(JSON.stringify(body)).length;\n return undefined;\n }\n\n /**\n * Reads the body as an ArrayBuffer.\n */\n async arrayBuffer(): Promise<ArrayBuffer> {\n return this.consumeBody(async (input) => {\n if (isArrayBuffer(input)) return input;\n if (isUint8Array(input)) {\n const copy = new Uint8Array(input.byteLength);\n copy.set(input);\n return copy.buffer;\n }\n if (typeof input === 'string') return new TextEncoder().encode(input).buffer as ArrayBuffer;\n if (isBlob(input)) return input.arrayBuffer();\n if (isReadableStream(input)) {\n return TangoBody.readStreamToArrayBuffer(input);\n }\n if (TangoBody.isJsonValue(input)) {\n // If body is object/array, encode as JSON and return buffer\n return new TextEncoder().encode(JSON.stringify(input)).buffer as ArrayBuffer;\n }\n throw new TypeError('Body is not an ArrayBuffer, Blob, string, stream, or JSON serializable object');\n });\n }\n\n /**\n * Reads the body as a Blob (browser only).\n */\n async blob(): Promise<Blob> {\n return this.consumeBody(async (input) => {\n if (isBlob(input)) return input;\n if (typeof input === 'string') return new Blob([input]);\n if (isArrayBuffer(input)) return new Blob([input]);\n if (isUint8Array(input)) return new Blob([new Uint8Array(input)]);\n if (isReadableStream(input)) {\n const buf = await TangoBody.readStreamToArrayBuffer(input);\n return new Blob([buf]);\n }\n if (TangoBody.isJsonValue(input)) {\n return new Blob([JSON.stringify(input)], { type: 'application/json' });\n }\n throw new TypeError(\n 'Body is not a Blob, string, ArrayBuffer, Uint8Array, stream, or JSON serializable object'\n );\n });\n }\n\n /**\n * Reads the body as a Uint8Array.\n */\n async bytes(): Promise<Uint8Array<ArrayBuffer>> {\n return this.consumeBody(async (input) => {\n if (isUint8Array(input)) return new Uint8Array(input);\n if (isArrayBuffer(input)) return new Uint8Array(input);\n if (typeof input === 'string') return new TextEncoder().encode(input);\n if (isBlob(input)) return new Uint8Array(await input.arrayBuffer());\n if (isReadableStream(input)) {\n return TangoBody.readStreamToUint8Array(input);\n }\n if (TangoBody.isJsonValue(input)) {\n return new TextEncoder().encode(JSON.stringify(input));\n }\n throw new TypeError('Body is not bytes, ArrayBuffer, Blob, string, stream, or JSON serializable object');\n });\n }\n\n /**\n * Reads the body as FormData.\n * Accepts FormData, or if type is urlencoded or multipart parses a string/bytes.\n */\n async formData(): Promise<FormData> {\n return this.consumeBody(async (input) => {\n if (isFormData(input)) return input;\n\n let contentType: string | undefined = undefined;\n if (this.headers && typeof this.headers.get === 'function') {\n const raw = this.headers.get('Content-Type');\n if (typeof raw === 'string') contentType = raw.toLowerCase();\n }\n\n let raw: string;\n if (typeof input === 'string') {\n raw = input;\n } else if (isArrayBuffer(input)) {\n raw = new TextDecoder().decode(input);\n } else if (isUint8Array(input)) {\n raw = new TextDecoder().decode(input);\n } else {\n throw new TypeError('Body is not valid for FormData');\n }\n\n // application/x-www-form-urlencoded\n if (contentType && contentType.includes('application/x-www-form-urlencoded')) {\n const form = new FormData();\n const params = new URLSearchParams(raw);\n params.forEach((value, key) => form.append(key, value));\n return form;\n }\n // multipart/form-data\n if (contentType && contentType.startsWith('multipart/form-data')) {\n const boundaryMatch = /boundary=([^\\s;]+)/i.exec(contentType);\n if (!boundaryMatch) throw new TypeError('Missing boundary in multipart/form-data');\n const boundary = boundaryMatch[1];\n\n // Warning: minimal multipart parsing, no file support\n const parts = raw.split(`--${boundary}`);\n const form = new FormData();\n for (const part of parts) {\n const trimmed = part.trim();\n if (!trimmed || trimmed === '--' || trimmed === '') continue;\n\n const [rawHeaders = '', ...rawBodyParts] = trimmed.split(/\\r?\\n\\r?\\n/);\n const body = rawBodyParts.join('\\n\\n').replace(/\\r?\\n$/, '');\n const dispositionMatch = /Content-Disposition:\\s*form-data;\\s*name=\"([^\"]+)\"/i.exec(rawHeaders);\n if (!dispositionMatch) continue;\n const name = dispositionMatch[1]!;\n form.append(name, body);\n }\n return form;\n }\n throw new TypeError('Body is not FormData, nor a supported form encoding');\n });\n }\n\n /**\n * Reads and parses the body as JSON (if possible).\n */\n async json<T = unknown>(): Promise<T> {\n return this.consumeBody(async (input) => {\n if (typeof input === 'string') return JSON.parse(input) as T;\n if (TangoBody.isJsonValue(input)) return input as T;\n if (isArrayBuffer(input) || isUint8Array(input)) {\n const text = new TextDecoder().decode(isUint8Array(input) ? input : new Uint8Array(input));\n return JSON.parse(text) as T;\n }\n if (isReadableStream(input)) {\n const text = await TangoBody.readStreamToText(input);\n return JSON.parse(text) as T;\n }\n throw new TypeError('Body is not valid JSON');\n });\n }\n\n /**\n * Reads the body as UTF-8 string.\n */\n async text(): Promise<string> {\n return this.consumeBody(async (input) => {\n if (typeof input === 'string') return input;\n if (isArrayBuffer(input)) return new TextDecoder().decode(input);\n if (isUint8Array(input)) return new TextDecoder().decode(input);\n if (isBlob(input)) return await input.text();\n if (isReadableStream(input)) return await TangoBody.readStreamToText(input);\n if (TangoBody.isJsonValue(input)) return JSON.stringify(input);\n throw new TypeError('Body is not text, ArrayBuffer, Uint8Array, Blob, stream, or JSON serializable object');\n });\n }\n\n /**\n * Returns the original body value (may be used for streaming or clone).\n */\n getRawBodyInit(): TangoBodySource {\n return this.bodySourceInternal;\n }\n\n /**\n * Clone the body instance and stream if possible.\n * If the source is a stream, the stream will be cloned if readable, otherwise throws.\n */\n clone(): TangoBody {\n if (this.bodyUsedInternal) throw new TypeError('Body has already been used.');\n if (isReadableStream(this.bodySourceInternal)) {\n if (typeof this.bodySourceInternal.tee !== 'function') {\n throw new TypeError('Cannot clone: body is a ReadableStream and tee() is not available');\n }\n const [streamForOriginal, streamForClone] = this.bodySourceInternal.tee();\n this.bodySourceInternal = streamForOriginal;\n return new TangoBody(streamForClone, this.headers);\n }\n const cloneSource = TangoBody.deepCloneBody(this.bodySourceInternal);\n return new TangoBody(cloneSource, this.headers);\n }\n\n /**\n * Helper for all readers. Only allows reading once.\n */\n private async consumeBody<T>(parser: (input: TangoBodySource) => Promise<T>): Promise<T> {\n if (this.bodyUsedInternal) {\n throw new TypeError('Body has already been consumed.');\n }\n this.bodyUsedInternal = true;\n return parser(this.bodySourceInternal);\n }\n}\n","import { isArrayBuffer, isBlob, isUint8Array } from '../runtime/index';\n\n/**\n * TangoHeaders extends the Web Headers class, adding ergonomic helpers\n * for common HTTP header patterns, convenience features, and a consistent API for\n * setting, appending, and deleting headers and cookies. This is designed to be\n * used by TangoResponse and other Tango HTTP utilities.\n * Additionally, provides helpers for safely setting Content-Length based on a known body,\n * and setting Content-Disposition for inline or attachment filenames.\n *\n * Includes helpers for request tracing and correlation headers:\n * - X-Request-Id\n * - traceparent (W3C Trace Context)\n * - Server-Timing\n * - X-Response-Time\n */\nexport class TangoHeaders extends Headers {\n static readonly BRAND = 'tango.http.headers' as const;\n readonly __tangoBrand: typeof TangoHeaders.BRAND = TangoHeaders.BRAND;\n\n /**\n * Narrow an unknown value to `TangoHeaders`.\n */\n static isTangoHeaders(value: unknown): value is TangoHeaders {\n return (\n typeof value === 'object' &&\n value !== null &&\n (value as { __tangoBrand?: unknown }).__tangoBrand === TangoHeaders.BRAND\n );\n }\n\n /**\n * Serialize a cookie for the Set-Cookie header line.\n */\n private static serializeCookie(\n name: string,\n value: string,\n options: {\n domain?: string;\n expires?: Date;\n httpOnly?: boolean;\n maxAge?: number;\n path?: string;\n sameSite?: 'Strict' | 'Lax' | 'None';\n secure?: boolean;\n priority?: 'Low' | 'Medium' | 'High';\n partitioned?: boolean;\n } = {}\n ): string {\n let cookie = encodeURIComponent(name) + '=' + encodeURIComponent(value ?? '');\n if (options.domain) cookie += `; Domain=${options.domain}`;\n if (options.path) cookie += `; Path=${options.path}`;\n else cookie += '; Path=/';\n if (options.expires) cookie += `; Expires=${options.expires.toUTCString()}`;\n if (typeof options.maxAge === 'number') cookie += `; Max-Age=${options.maxAge}`;\n if (options.secure) cookie += '; Secure';\n if (options.httpOnly) cookie += '; HttpOnly';\n if (options.sameSite) cookie += `; SameSite=${options.sameSite}`;\n if (options.priority) cookie += `; Priority=${options.priority}`;\n if (options.partitioned) cookie += '; Partitioned';\n return cookie;\n }\n\n private static hasNumberSize(value: unknown): value is { size: number } {\n return typeof value === 'object' && value !== null && typeof (value as { size?: unknown }).size === 'number';\n }\n\n private static hasNumberLength(value: unknown): value is { length: number } {\n return (\n typeof value === 'object' && value !== null && typeof (value as { length?: unknown }).length === 'number'\n );\n }\n\n private static isNodeBuffer(value: unknown): value is { length: number } {\n const maybeBuffer = Buffer as unknown as { isBuffer?: (input: unknown) => boolean };\n return (\n typeof Buffer !== 'undefined' && typeof maybeBuffer.isBuffer === 'function' && maybeBuffer.isBuffer(value)\n );\n }\n\n /**\n * Sets the Content-Disposition header with type \"inline\" and the specified filename.\n * This is useful to indicate that the content should be displayed inline in the browser,\n * but with a suggested filename for saving.\n *\n * @param filename The filename to include in the Content-Disposition header.\n */\n setContentDispositionInline(filename: string): void {\n const encoded = encodeURIComponent(filename);\n this.set('Content-Disposition', `inline; filename=\"${encoded}\"; filename*=UTF-8''${encoded}`);\n }\n\n /**\n * Sets the Content-Disposition header with type \"attachment\" and the specified filename.\n * This is useful to indicate that the response should be downloaded as a file.\n *\n * @param filename The filename to include in the Content-Disposition header.\n */\n setContentDispositionAttachment(filename: string): void {\n const encoded = encodeURIComponent(filename);\n this.set('Content-Disposition', `attachment; filename=\"${encoded}\"; filename*=UTF-8''${encoded}`);\n }\n\n /**\n * Create a copy that preserves all header names and values.\n */\n clone(): TangoHeaders {\n const copy = new TangoHeaders();\n for (const [name, value] of this.entries()) {\n copy.append(name, value);\n }\n return copy;\n }\n\n /**\n * Set a header, replacing the existing value.\n */\n setHeader(name: string, value: string): void {\n this.set(name, value);\n }\n\n /**\n * Append a header, adding to existing value(s) for the name.\n */\n appendHeader(name: string, value: string): void {\n this.append(name, value);\n }\n\n /**\n * Get a header value (first value if header is repeated).\n */\n getHeader(name: string): string | null {\n return this.get(name);\n }\n\n /**\n * Check if a header exists.\n */\n hasHeader(name: string): boolean {\n return this.has(name);\n }\n\n /**\n * Delete a header.\n */\n deleteHeader(name: string): void {\n this.delete(name);\n }\n\n /**\n * Ensure a header is present only once and fully replaces the old value.\n */\n ensureUnique(name: string, value: string): void {\n this.delete(name);\n this.set(name, value);\n }\n\n /**\n * Add a field (or fields) to the Vary header, merging with existing values.\n */\n vary(...fields: string[]): void {\n if (fields.length === 0) return;\n const key = 'Vary';\n const prev = this.get(key);\n const nextSet = new Set<string>();\n if (prev) {\n for (const v of prev.split(',')) {\n if (v.trim()) nextSet.add(v.trim());\n }\n }\n for (const f of fields) {\n if (f.trim()) nextSet.add(f.trim());\n }\n this.set(key, Array.from(nextSet).join(', '));\n }\n\n /**\n * Set a cookie header (for Set-Cookie).\n * @param name\n * @param value\n * @param options\n */\n setCookie(\n name: string,\n value: string,\n options?: {\n domain?: string;\n expires?: Date;\n httpOnly?: boolean;\n maxAge?: number;\n path?: string;\n sameSite?: 'Strict' | 'Lax' | 'None';\n secure?: boolean;\n priority?: 'Low' | 'Medium' | 'High';\n partitioned?: boolean;\n }\n ): void {\n this.append('Set-Cookie', TangoHeaders.serializeCookie(name, value, options));\n }\n\n /**\n * Append (additionally) a new cookie.\n */\n appendCookie(\n name: string,\n value: string,\n options?: {\n domain?: string;\n expires?: Date;\n httpOnly?: boolean;\n maxAge?: number;\n path?: string;\n sameSite?: 'Strict' | 'Lax' | 'None';\n secure?: boolean;\n priority?: 'Low' | 'Medium' | 'High';\n partitioned?: boolean;\n }\n ): void {\n this.append('Set-Cookie', TangoHeaders.serializeCookie(name, value, options));\n }\n\n /**\n * Delete a cookie (\"unset\" it via expired date).\n */\n deleteCookie(\n name: string,\n options?: {\n domain?: string;\n path?: string;\n sameSite?: 'Strict' | 'Lax' | 'None';\n secure?: boolean;\n priority?: 'Low' | 'Medium' | 'High';\n partitioned?: boolean;\n }\n ): void {\n this.setCookie(name, '', {\n ...options,\n expires: new Date(0),\n maxAge: 0,\n });\n }\n\n /**\n * Add or override Cache-Control header with helpers for common policies.\n */\n cacheControl(control: string | Record<string, string | number | boolean | undefined>): void {\n if (typeof control === 'string') {\n this.set('Cache-Control', control);\n return;\n }\n // Compose Cache-Control from object\n const parts: string[] = [];\n for (const [k, v] of Object.entries(control)) {\n if (typeof v === 'boolean') {\n if (v) parts.push(k.replace(/[A-Z]/g, (c) => '-' + c.toLowerCase()));\n } else if (typeof v === 'number' || (typeof v === 'string' && v.length > 0)) {\n parts.push(`${k.replace(/[A-Z]/g, (c) => '-' + c.toLowerCase())}=${v}`);\n }\n }\n if (parts.length) {\n this.set('Cache-Control', parts.join(', '));\n }\n }\n\n /**\n * Set the Location header.\n */\n location(url: string): void {\n this.set('Location', url);\n }\n\n /**\n * Set the Content-Type header.\n */\n contentType(mime: string): void {\n this.set('Content-Type', mime);\n }\n\n /**\n * Attempt to guess and set the Content-Type header from a file (string or Blob) and optional filename.\n *\n * @param file File-like input (string or Blob)\n * @param filename Optional filename to help guess mime type by extension\n */\n setContentTypeByFile(file: unknown, filename?: string): void {\n // do not overwrite explicit content-type\n if (this.has('Content-Type')) return;\n\n // If file is a string and a filename is provided or can be guessed from file path\n if (typeof file === 'string' && filename) {\n // Guess type by extension\n const dotIndex = filename.lastIndexOf('.');\n const ext = dotIndex >= 0 ? filename.slice(dotIndex + 1).toLowerCase() : '';\n const map: Record<string, string> = {\n txt: 'text/plain',\n text: 'text/plain',\n html: 'text/html',\n css: 'text/css',\n js: 'application/javascript',\n json: 'application/json',\n jpg: 'image/jpeg',\n jpeg: 'image/jpeg',\n png: 'image/png',\n gif: 'image/gif',\n webp: 'image/webp',\n pdf: 'application/pdf',\n svg: 'image/svg+xml',\n ico: 'image/x-icon',\n md: 'text/markdown',\n };\n const mime = map[ext];\n if (mime) {\n this.set('Content-Type', mime);\n } else {\n this.set('Content-Type', 'application/octet-stream');\n }\n return;\n }\n\n // If it's a Blob, use its type, or fallback\n if (isBlob(file)) {\n if (file.type && file.type !== '') {\n this.set('Content-Type', file.type);\n } else {\n this.set('Content-Type', 'application/octet-stream');\n }\n return;\n }\n\n // Fallback\n this.set('Content-Type', 'application/octet-stream');\n }\n\n /**\n * Sets the Content-Length header, inferring it from the body if not explicitly provided.\n * If the body is a string, ArrayBuffer, Uint8Array, Blob/Buffer (or has a .size or .length property),\n * the length is computed. For unsupported types, does nothing.\n * Mirrors logic from TangoResponse.ts, but generalized for use anywhere.\n */\n setContentLengthFromBody(body: unknown): void {\n if (this.has('Content-Length') || body === null || body === undefined) {\n return;\n }\n\n let len: number | undefined;\n\n if (typeof body === 'string') {\n len = new TextEncoder().encode(body).length;\n } else if (isArrayBuffer(body)) {\n len = body.byteLength;\n }\n // Node.js Buffer support (Buffer.isBuffer and .length)\n else if (TangoHeaders.isNodeBuffer(body)) {\n len = (body as { length: number }).length;\n } else if (isUint8Array(body)) {\n len = body.byteLength;\n } else if (isBlob(body)) {\n len = body.size;\n }\n // Generic \"size\" (number) property\n else if (TangoHeaders.hasNumberSize(body)) {\n len = (body as { size: number }).size;\n }\n // Generic \"length\" (number) property but not string/ArrayBuffer/Uint8Array/etc\n else if (\n TangoHeaders.hasNumberLength(body) &&\n typeof body !== 'string' &&\n !isArrayBuffer(body) &&\n !isUint8Array(body)\n ) {\n len = (body as { length: number }).length;\n }\n\n if (typeof len === 'number') {\n this.set('Content-Length', len.toString());\n }\n }\n\n /**\n * Set or update the X-Request-Id header. Used for associating a request/response with a unique id.\n * @param id The request id value to set.\n */\n withRequestId(id: string): this {\n this.set('X-Request-Id', id);\n return this;\n }\n\n /**\n * Set or update the traceparent header. Used for distributed trace context propagation (W3C Trace Context).\n * @param value The traceparent value (should be a valid traceparent header value).\n */\n withTraceParent(value: string): this {\n this.set('traceparent', value);\n return this;\n }\n\n /**\n * Set or append a value to the Server-Timing header.\n * For a single metric, supply name, and optionally dur and desc.\n * For advanced usage (many metrics), set the value directly or use appendServerTimingRaw.\n *\n * @param name Name of the server-timing metric (e.g., 'total', 'db').\n * @param dur Optional duration in ms.\n * @param desc Optional string description.\n */\n withServerTiming(name: string, dur?: number, desc?: string): this {\n // Build the metric string per spec: <metric>=<value>;dur=<duration>;desc=\"<description>\"\n let metric = name;\n if (typeof dur === 'number') {\n metric += `;dur=${dur}`;\n }\n if (desc) {\n metric += `;desc=\"${desc.replace(/\"/g, '\\\\\"')}\"`;\n }\n\n // Set or append. If header exists, append, separated by comma.\n const prev = this.get('Server-Timing');\n if (prev && prev.length > 0) {\n this.set('Server-Timing', prev + ', ' + metric);\n } else {\n this.set('Server-Timing', metric);\n }\n return this;\n }\n\n /**\n * Directly append a raw Server-Timing metric value.\n * This is useful for advanced cases where you have multiple metrics assembled.\n * @param value The server-timing value chunk to append.\n */\n appendServerTimingRaw(value: string): this {\n const prev = this.get('Server-Timing');\n if (prev && prev.length > 0) {\n this.set('Server-Timing', prev + ', ' + value);\n } else {\n this.set('Server-Timing', value);\n }\n return this;\n }\n\n /**\n * Set or update X-Response-Time header.\n * @param ms Elapsed time in milliseconds (number or string for flexibility).\n */\n withResponseTime(ms: number | string): this {\n this.set('X-Response-Time', typeof ms === 'number' ? `${ms}ms` : ms);\n return this;\n }\n\n /**\n * Return the current value of X-Request-Id.\n */\n getRequestId(): string | null {\n return this.get('X-Request-Id');\n }\n\n /**\n * Return the current value of traceparent header.\n */\n getTraceParent(): string | null {\n return this.get('traceparent');\n }\n\n /**\n * Return the current Server-Timing string, if set.\n */\n getServerTiming(): string | null {\n return this.get('Server-Timing');\n }\n\n /**\n * Return the current X-Response-Time string, if set.\n */\n getResponseTime(): string | null {\n return this.get('X-Response-Time');\n }\n}\n","import type { TangoRequest } from './TangoRequest';\n\ntype QueryParamRecord = Record<string, string | string[] | undefined>;\ntype QueryParamMutationValue = string | number | readonly (string | number)[] | null | undefined;\ntype QueryParamMutationRecord = Record<string, QueryParamMutationValue>;\n\n/**\n * Immutable query parameter helper that normalizes framework-specific shapes\n * into one Tango-owned API.\n */\nexport class TangoQueryParams {\n static readonly BRAND = 'tango.http.query_params' as const;\n readonly __tangoBrand: typeof TangoQueryParams.BRAND = TangoQueryParams.BRAND;\n private readonly values: Map<string, readonly string[]>;\n\n private constructor(values: Map<string, readonly string[]>) {\n this.values = values;\n }\n\n /**\n * Narrow an unknown value to `TangoQueryParams`.\n */\n static isTangoQueryParams(value: unknown): value is TangoQueryParams {\n return (\n typeof value === 'object' &&\n value !== null &&\n (value as { __tangoBrand?: unknown }).__tangoBrand === TangoQueryParams.BRAND\n );\n }\n\n /**\n * Build query params from a `URLSearchParams` instance.\n */\n static fromURLSearchParams(params: URLSearchParams): TangoQueryParams {\n const values = new Map<string, string[]>();\n\n for (const [key, value] of params.entries()) {\n const current = values.get(key);\n if (current) {\n current.push(value);\n continue;\n }\n values.set(key, [value]);\n }\n\n return new TangoQueryParams(values);\n }\n\n /**\n * Build query params from framework record-style search params.\n */\n static fromRecord(params: QueryParamRecord): TangoQueryParams {\n const values = new Map<string, string[]>();\n\n for (const [key, value] of Object.entries(params)) {\n if (Array.isArray(value)) {\n const normalized = value.filter((entry) => typeof entry === 'string');\n if (normalized.length > 0) {\n values.set(key, normalized);\n }\n continue;\n }\n\n if (typeof value === 'string') {\n values.set(key, [value]);\n }\n }\n\n return new TangoQueryParams(values);\n }\n\n /**\n * Build query params from a full URL string or URL object.\n */\n static fromURL(input: string | URL): TangoQueryParams {\n const url = typeof input === 'string' ? new URL(input) : input;\n return TangoQueryParams.fromURLSearchParams(url.searchParams);\n }\n\n /**\n * Build query params from a request-like object with a URL.\n */\n static fromRequest(request: Request | TangoRequest): TangoQueryParams {\n return TangoQueryParams.fromURL(request.url);\n }\n\n /**\n * Get the first value for a query param.\n */\n get(name: string): string | undefined {\n return this.values.get(name)?.[0];\n }\n\n /**\n * Get all values for a query param.\n */\n getAll(name: string): string[] {\n return [...(this.values.get(name) ?? [])];\n }\n\n /**\n * Check whether a query param exists.\n */\n has(name: string): boolean {\n return (this.values.get(name)?.length ?? 0) > 0;\n }\n\n /**\n * Iterate key -> values entries.\n */\n *entries(): IterableIterator<[string, string[]]> {\n for (const [key, values] of this.values.entries()) {\n yield [key, [...values]];\n }\n }\n\n /**\n * Iterate keys present in the query params.\n */\n *keys(): IterableIterator<string> {\n yield* this.values.keys();\n }\n\n /**\n * Convert back to a native `URLSearchParams` object.\n */\n toURLSearchParams(): URLSearchParams {\n const params = new URLSearchParams();\n\n for (const [key, values] of this.values.entries()) {\n for (const value of values) {\n params.append(key, value);\n }\n }\n\n return params;\n }\n\n /**\n * Return a new query param set with selected keys replaced or removed.\n *\n * `undefined`, `null`, and empty arrays remove the key entirely.\n */\n withValues(updates: QueryParamMutationRecord): TangoQueryParams {\n const next = new Map<string, string[]>();\n\n for (const [key, values] of this.values.entries()) {\n next.set(key, [...values]);\n }\n\n for (const [key, value] of Object.entries(updates)) {\n if (value === undefined || value === null) {\n next.delete(key);\n continue;\n }\n\n const normalized = Array.isArray(value) ? value.map((entry) => String(entry)) : [String(value)];\n if (normalized.length === 0) {\n next.delete(key);\n continue;\n }\n\n next.set(key, normalized);\n }\n\n return new TangoQueryParams(next);\n }\n\n /**\n * Convert to a relative query string suitable for links.\n */\n toRelativeURL(): string {\n const query = this.toURLSearchParams().toString();\n return query.length > 0 ? `?${query}` : '';\n }\n\n /**\n * Get a trimmed value, omitting blank strings.\n */\n getTrimmed(name: string): string | undefined {\n const value = this.get(name)?.trim();\n return value ? value : undefined;\n }\n\n /**\n * Get the free-text search param using Tango's default key.\n */\n getSearch(key: string = 'search'): string | undefined {\n return this.getTrimmed(key);\n }\n\n /**\n * Get the ordering param as trimmed field tokens.\n */\n getOrdering(key: string = 'ordering'): string[] {\n const value = this.get(key);\n if (!value) {\n return [];\n }\n\n return value\n .split(',')\n .map((token) => token.trim())\n .filter((token) => token.length > 0);\n }\n}\n","import type { JsonValue } from './TangoBody';\nimport { TangoQueryParams } from './TangoQueryParams';\nimport {\n isArrayBuffer,\n isBlob,\n isFormData,\n isNil,\n isReadableStream,\n isUint8Array,\n isURLSearchParams,\n} from '../runtime/index';\n\ntype TangoRequestInit = {\n method?: string;\n headers?: HeadersInit;\n body?: BodyInit | JsonValue | null;\n redirect?: RequestRedirect;\n cache?: RequestCache;\n credentials?: RequestCredentials;\n integrity?: string;\n keepalive?: boolean;\n mode?: RequestMode;\n referrer?: string;\n referrerPolicy?: ReferrerPolicy;\n signal?: AbortSignal;\n};\n\n/**\n * Framework request wrapper that normalizes JSON-like bodies and preserves\n * fetch `Request` compatibility for downstream handlers.\n */\nexport class TangoRequest implements Request {\n static readonly BRAND = 'tango.http.request' as const;\n readonly __tangoBrand: typeof TangoRequest.BRAND = TangoRequest.BRAND;\n private request: Request;\n private bodySourceValue: BodyInit | JsonValue | null;\n private queryParamsValue?: TangoQueryParams;\n\n constructor(input: string | Request, init: TangoRequestInit = {}) {\n const sourceRequest = typeof input === 'string' ? undefined : input;\n const method = (init.method ?? sourceRequest?.method ?? 'GET').toUpperCase();\n const headers = new Headers(init.headers ?? sourceRequest?.headers);\n const normalizedBody = this.normalizeBody(init.body, headers, method);\n\n const requestInit: RequestInit & { duplex?: 'half' } = {\n method,\n headers,\n redirect: init.redirect ?? sourceRequest?.redirect,\n cache: init.cache ?? sourceRequest?.cache,\n credentials: init.credentials ?? sourceRequest?.credentials,\n integrity: init.integrity ?? sourceRequest?.integrity,\n keepalive: init.keepalive ?? sourceRequest?.keepalive,\n mode: init.mode ?? sourceRequest?.mode,\n referrer: init.referrer ?? sourceRequest?.referrer,\n referrerPolicy: init.referrerPolicy ?? sourceRequest?.referrerPolicy,\n signal: init.signal ?? sourceRequest?.signal,\n };\n\n if (normalizedBody !== undefined) {\n requestInit.body = normalizedBody;\n if (isReadableStream(normalizedBody)) {\n requestInit.duplex = 'half';\n }\n }\n\n this.request = new Request(input, requestInit);\n this.bodySourceValue = normalizedBody ?? null;\n }\n\n /**\n * Narrow an unknown value to `TangoRequest`.\n */\n static isTangoRequest(value: unknown): value is TangoRequest {\n return (\n typeof value === 'object' &&\n value !== null &&\n (value as { __tangoBrand?: unknown }).__tangoBrand === TangoRequest.BRAND\n );\n }\n\n /**\n * Expose the request cache mode from the underlying fetch request.\n */\n get cache(): RequestCache {\n return this.request.cache;\n }\n\n /**\n * Expose the request credentials mode from the underlying fetch request.\n */\n get credentials(): RequestCredentials {\n return this.request.credentials;\n }\n\n /**\n * Expose the request destination from the underlying fetch request.\n */\n get destination(): RequestDestination {\n return this.request.destination;\n }\n\n /**\n * Expose the request headers from the underlying fetch request.\n */\n get headers(): Headers {\n return this.request.headers;\n }\n\n /**\n * Expose the request integrity value from the underlying fetch request.\n */\n get integrity(): string {\n return this.request.integrity;\n }\n\n /**\n * Expose the request keepalive flag from the underlying fetch request.\n */\n get keepalive(): boolean {\n return this.request.keepalive;\n }\n\n /**\n * Expose the normalized HTTP method.\n */\n get method(): string {\n return this.request.method;\n }\n\n /**\n * Expose the request mode from the underlying fetch request.\n */\n get mode(): RequestMode {\n return this.request.mode;\n }\n\n /**\n * Expose the redirect policy from the underlying fetch request.\n */\n get redirect(): RequestRedirect {\n return this.request.redirect;\n }\n\n /**\n * Expose the referrer from the underlying fetch request.\n */\n get referrer(): string {\n return this.request.referrer;\n }\n\n /**\n * Expose the referrer policy from the underlying fetch request.\n */\n get referrerPolicy(): ReferrerPolicy {\n return this.request.referrerPolicy;\n }\n\n /**\n * Expose the abort signal from the underlying fetch request.\n */\n get signal(): AbortSignal {\n return this.request.signal;\n }\n\n /**\n * Expose the absolute request URL.\n */\n get url(): string {\n return this.request.url;\n }\n\n /**\n * Expose the readable request body stream when one exists.\n */\n get body(): Request['body'] {\n return this.request.body;\n }\n\n /**\n * Report whether the body has been consumed.\n */\n get bodyUsed(): boolean {\n return this.request.bodyUsed;\n }\n\n /**\n * Expose the pre-normalized body value used to build the request.\n */\n get bodySource(): BodyInit | JsonValue | null {\n return this.bodySourceValue;\n }\n\n /**\n * Expose normalized query parameters derived from the request URL.\n */\n get queryParams(): TangoQueryParams {\n this.queryParamsValue ??= TangoQueryParams.fromURL(this.request.url);\n return this.queryParamsValue;\n }\n\n /**\n * Read the request body as an array buffer.\n */\n async arrayBuffer(): Promise<ArrayBuffer> {\n return this.request.arrayBuffer();\n }\n\n /**\n * Read the request body as a blob.\n */\n async blob(): Promise<Blob> {\n return this.request.blob();\n }\n\n /**\n * Read the request body as bytes, including runtimes without `Request.bytes()`.\n */\n async bytes(): Promise<Uint8Array<ArrayBuffer>> {\n const requestWithBytes = this.request as Request & { bytes?: () => Promise<Uint8Array<ArrayBuffer>> };\n if (typeof requestWithBytes.bytes === 'function') {\n return requestWithBytes.bytes();\n }\n const buffer = await this.request.arrayBuffer();\n return new Uint8Array(buffer);\n }\n\n /**\n * Read the request body as form data.\n */\n async formData(): Promise<FormData> {\n return this.request.formData();\n }\n\n /**\n * Parse the request body as JSON.\n */\n async json<T = unknown>(): Promise<T> {\n return this.request.json() as Promise<T>;\n }\n\n /**\n * Read the request body as text.\n */\n async text(): Promise<string> {\n return this.request.text();\n }\n\n /**\n * Clone the request so downstream code can consume it independently.\n */\n clone(): TangoRequest {\n return new TangoRequest(this.request.clone());\n }\n\n private normalizeBody(\n body: BodyInit | JsonValue | null | undefined,\n headers: Headers,\n method: string\n ): BodyInit | undefined {\n if (method === 'GET' || method === 'HEAD') {\n return undefined;\n }\n if (isNil(body)) {\n return undefined;\n }\n if (typeof body === 'string') {\n return body;\n }\n if (isArrayBuffer(body) || isUint8Array(body) || isBlob(body)) {\n return body;\n }\n if (isURLSearchParams(body) || isFormData(body) || isReadableStream(body)) {\n return body as BodyInit;\n }\n\n const serialized = JSON.stringify(body);\n if (!headers.has('content-type')) {\n headers.set('content-type', 'application/json; charset=utf-8');\n }\n return serialized;\n }\n}\n","import { TangoError, type ErrorEnvelope, type ErrorDetails, type ProblemDetails } from '../errors/TangoError';\nimport {\n isArrayBuffer,\n isBlob,\n isFormData,\n isNil,\n isReadableStream,\n isUint8Array,\n isURLSearchParams,\n} from '../runtime/index';\nimport { TangoHeaders } from '../http/TangoHeaders';\nimport { TangoBody, type JsonValue } from './TangoBody';\n\ntype TangoResponseInit = {\n body?: BodyInit | JsonValue | null;\n headers?: HeadersInit;\n ok?: boolean;\n redirected?: boolean;\n status?: number;\n statusText?: string;\n type?: ResponseType;\n url?: string;\n};\n\n/**\n * Framework response wrapper with fetch-compatible surface plus ergonomic helpers.\n */\nexport class TangoResponse implements Response {\n static readonly BRAND = 'tango.http.response' as const;\n readonly __tangoBrand: typeof TangoResponse.BRAND = TangoResponse.BRAND;\n readonly headers: TangoHeaders;\n readonly redirected: boolean;\n readonly status: number;\n readonly statusText: string;\n readonly type: ResponseType;\n readonly url: string;\n readonly body: Response['body'];\n private tangoBody: TangoBody;\n private okValue: boolean | undefined;\n\n constructor(init: TangoResponseInit = {}) {\n this.headers = new TangoHeaders(init.headers);\n this.redirected = Boolean(init.redirected);\n this.status = typeof init.status === 'number' ? init.status : 200;\n this.statusText = init.statusText || '';\n this.type = init.type || 'default';\n this.url = init.url || '';\n this.okValue = typeof init.ok === 'boolean' ? init.ok : undefined;\n\n this.tangoBody = new TangoBody(init.body ?? null, this.headers);\n this.body = isReadableStream(this.tangoBody.bodySource) ? this.tangoBody.bodySource : null;\n }\n\n /**\n * Narrow an unknown value to `TangoResponse`.\n */\n static isTangoResponse(value: unknown): value is TangoResponse {\n return (\n typeof value === 'object' &&\n value !== null &&\n (value as { __tangoBrand?: unknown }).__tangoBrand === TangoResponse.BRAND\n );\n }\n\n /**\n * Create a JSON response with sensible content headers.\n */\n static json(\n data: JsonValue,\n init?: Omit<TangoResponseInit, 'body' | 'headers'> & { headers?: HeadersInit }\n ): TangoResponse {\n const headers = new TangoHeaders(init?.headers);\n if (!headers.has('Content-Type')) {\n headers.set('Content-Type', 'application/json; charset=utf-8');\n }\n const body = JSON.stringify(data);\n if (!headers.has('Content-Length')) {\n headers.set('Content-Length', new TextEncoder().encode(body).length.toString());\n }\n return new TangoResponse({\n ...init,\n body,\n headers,\n });\n }\n\n /**\n * Create a plain-text response with sensible content headers.\n */\n static text(\n text: string,\n init?: Omit<TangoResponseInit, 'body' | 'headers'> & { headers?: HeadersInit }\n ): TangoResponse {\n const headers = new TangoHeaders(init?.headers);\n if (!headers.has('Content-Type')) {\n headers.set('Content-Type', 'text/plain; charset=utf-8');\n }\n if (!headers.has('Content-Length')) {\n headers.set('Content-Length', new TextEncoder().encode(text).length.toString());\n }\n return new TangoResponse({\n ...init,\n body: text,\n headers,\n });\n }\n\n /**\n * Create an HTML response with sensible content headers.\n */\n static html(\n html: string,\n init?: Omit<TangoResponseInit, 'body' | 'headers'> & { headers?: HeadersInit }\n ): TangoResponse {\n const headers = new TangoHeaders(init?.headers);\n if (!headers.has('Content-Type')) {\n headers.set('Content-Type', 'text/html; charset=utf-8');\n }\n if (!headers.has('Content-Length')) {\n headers.set('Content-Length', new TextEncoder().encode(html).length.toString());\n }\n return new TangoResponse({\n ...init,\n body: html,\n headers,\n });\n }\n\n /**\n * Create a streaming response without buffering the payload in memory.\n */\n static stream(\n stream: ReadableStream<Uint8Array>,\n init?: Omit<TangoResponseInit, 'body' | 'headers'> & { headers?: HeadersInit }\n ): TangoResponse {\n return new TangoResponse({\n ...init,\n body: stream,\n headers: new TangoHeaders(init?.headers),\n });\n }\n\n /**\n * Create a redirect response and set the `Location` header.\n */\n static redirect(\n url: string,\n status: number = 302,\n init?: Omit<TangoResponseInit, 'body' | 'headers' | 'status'> & {\n headers?: HeadersInit;\n }\n ): TangoResponse {\n const headers = new TangoHeaders(init?.headers);\n headers.set('Location', url);\n return new TangoResponse({\n ...init,\n body: undefined,\n status,\n headers,\n redirected: true,\n url,\n });\n }\n\n /**\n * Create an empty `204 No Content` response.\n */\n static noContent(\n init?: Omit<TangoResponseInit, 'body' | 'status' | 'headers'> & {\n headers?: HeadersInit;\n }\n ): TangoResponse {\n const headers = new TangoHeaders(init?.headers);\n return new TangoResponse({\n ...init,\n body: undefined,\n status: 204,\n headers,\n });\n }\n\n /**\n * Create a `201 Created` response and optionally attach a location or body.\n */\n static created(\n location?: string,\n body?: JsonValue,\n init?: Omit<TangoResponseInit, 'body' | 'status' | 'headers'> & {\n headers?: HeadersInit;\n }\n ): TangoResponse {\n const headers = new TangoHeaders(init?.headers);\n if (location) {\n headers.set('Location', location);\n }\n let respBody: BodyInit | undefined;\n if (body !== undefined) {\n respBody = JSON.stringify(body);\n if (!headers.has('Content-Type')) {\n headers.set('Content-Type', 'application/json; charset=utf-8');\n }\n }\n if (typeof respBody === 'string' && !headers.has('Content-Length')) {\n headers.set('Content-Length', new TextEncoder().encode(respBody).length.toString());\n }\n return new TangoResponse({\n ...init,\n body: respBody,\n status: 201,\n headers,\n });\n }\n\n /**\n * Create a `405 Method Not Allowed` response and optionally populate `Allow`.\n */\n static methodNotAllowed<TDetails extends ErrorDetails = null>(\n allow?: readonly string[],\n detail?: string | TangoError | ProblemDetails<TDetails>,\n init?: Omit<TangoResponseInit, 'body' | 'status' | 'headers'> & {\n headers?: HeadersInit;\n }\n ): TangoResponse {\n const headers = new TangoHeaders(init?.headers);\n if (allow && allow.length > 0) {\n headers.set('Allow', allow.join(', '));\n }\n\n if (TangoError.isTangoError(detail) || TangoError.isProblemDetails(detail)) {\n return TangoResponse.error(detail, { ...init, status: 405, headers });\n }\n\n if (typeof detail === 'string') {\n return TangoResponse.error(\n {\n code: 'method_not_allowed',\n message: detail,\n },\n { ...init, status: 405, headers }\n );\n }\n\n return TangoResponse.error(\n {\n code: 'method_not_allowed',\n message: 'Method not allowed.',\n },\n { ...init, status: 405, headers }\n );\n }\n\n /**\n * Normalize a Tango error or problem-details object into an error response.\n */\n static error<TDetails extends ErrorDetails = null>(\n error: TangoError | ProblemDetails<TDetails>,\n init?: Omit<TangoResponseInit, 'body' | 'headers'> & { headers?: HeadersInit }\n ): TangoResponse {\n let code: string;\n let message: string;\n let details: ErrorDetails;\n let fields: Record<string, string[]> | undefined;\n let status = init?.status ?? 500;\n\n if (TangoError.isTangoError(error)) {\n const envelope = error.toErrorEnvelope();\n code = envelope.error.code;\n message = envelope.error.message;\n details = envelope.error.details;\n fields = envelope.error.fields;\n status = error.status;\n } else {\n code = error.code;\n message = error.message;\n details = error.details;\n fields = error.fields;\n }\n\n return TangoResponse.problem(\n {\n code,\n message,\n details,\n fields,\n },\n {\n ...init,\n status,\n }\n );\n }\n\n /**\n * Create a `400 Bad Request` response from a string or structured error.\n */\n static badRequest<TDetails extends ErrorDetails = null>(\n detail?: string | TangoError | ProblemDetails<TDetails>,\n init?: Omit<TangoResponseInit, 'body' | 'status' | 'headers'> & {\n headers?: HeadersInit;\n }\n ): TangoResponse {\n if (TangoError.isTangoError(detail) || TangoError.isProblemDetails(detail)) {\n return TangoResponse.error(detail, { ...init, status: 400 });\n }\n\n if (typeof detail === 'string') {\n return TangoResponse.error(\n {\n code: 'bad_request',\n message: detail,\n },\n { ...init, status: 400 }\n );\n }\n\n return TangoResponse.error(\n {\n code: 'bad_request',\n message: 'Bad Request',\n },\n { ...init, status: 400 }\n );\n }\n\n /**\n * Create a `401 Unauthorized` response from a string or structured error.\n */\n static unauthorized<TDetails extends ErrorDetails = null>(\n detail?: string | TangoError | ProblemDetails<TDetails>,\n init?: Omit<TangoResponseInit, 'body' | 'status' | 'headers'> & {\n headers?: HeadersInit;\n }\n ): TangoResponse {\n if (TangoError.isTangoError(detail) || TangoError.isProblemDetails(detail)) {\n return TangoResponse.error(detail, { ...init, status: 401 });\n }\n if (typeof detail === 'string') {\n return TangoResponse.error(\n {\n code: 'unauthorized',\n message: detail,\n },\n { ...init, status: 401 }\n );\n }\n\n return TangoResponse.error(\n {\n code: 'unauthorized',\n message: 'Unauthorized',\n },\n { ...init, status: 401 }\n );\n }\n\n /**\n * Create a `403 Forbidden` response from a string or structured error.\n */\n static forbidden<TDetails extends ErrorDetails = null>(\n detail?: string | TangoError | ProblemDetails<TDetails>,\n init?: Omit<TangoResponseInit, 'body' | 'status' | 'headers'> & {\n headers?: HeadersInit;\n }\n ): TangoResponse {\n if (TangoError.isTangoError(detail) || TangoError.isProblemDetails(detail)) {\n return TangoResponse.error(detail, { ...init, status: 403 });\n }\n\n if (typeof detail === 'string') {\n return TangoResponse.error(\n {\n code: 'forbidden',\n message: detail,\n },\n { ...init, status: 403 }\n );\n }\n\n return TangoResponse.error(\n {\n code: 'forbidden',\n message: 'Forbidden',\n },\n { ...init, status: 403 }\n );\n }\n\n /**\n * Create a `404 Not Found` response from a string or structured error.\n */\n static notFound<TDetails extends ErrorDetails = null>(\n detail?: string | TangoError | ProblemDetails<TDetails>,\n init?: Omit<TangoResponseInit, 'body' | 'status' | 'headers'> & {\n headers?: HeadersInit;\n }\n ): TangoResponse {\n if (TangoError.isTangoError(detail) || TangoError.isProblemDetails(detail)) {\n return TangoResponse.error(detail, { ...init, status: 404 });\n }\n\n if (typeof detail === 'string') {\n return TangoResponse.error(\n {\n code: 'not_found',\n message: detail,\n },\n { ...init, status: 404 }\n );\n }\n\n return TangoResponse.error(\n {\n code: 'not_found',\n message: 'Not Found',\n },\n { ...init, status: 404 }\n );\n }\n\n /**\n * Create a `409 Conflict` response from a string or structured error.\n */\n static conflict<TDetails extends ErrorDetails = null>(\n detail?: string | TangoError | ProblemDetails<TDetails>,\n init?: Omit<TangoResponseInit, 'body' | 'status' | 'headers'> & {\n headers?: HeadersInit;\n }\n ): TangoResponse {\n if (TangoError.isTangoError(detail) || TangoError.isProblemDetails(detail)) {\n return TangoResponse.error(detail, { ...init, status: 409 });\n }\n\n if (typeof detail === 'string') {\n return TangoResponse.error(\n {\n code: 'conflict',\n message: detail,\n },\n { ...init, status: 409 }\n );\n }\n\n return TangoResponse.error(\n {\n code: 'conflict',\n message: 'Conflict',\n },\n { ...init, status: 409 }\n );\n }\n\n /**\n * Create a `422 Unprocessable Entity` response from a string or structured error.\n */\n static unprocessableEntity<TDetails extends ErrorDetails = null>(\n detail?: string | TangoError | ProblemDetails<TDetails>,\n init?: Omit<TangoResponseInit, 'body' | 'status' | 'headers'> & {\n headers?: HeadersInit;\n }\n ): TangoResponse {\n if (TangoError.isTangoError(detail) || TangoError.isProblemDetails(detail)) {\n return TangoResponse.error(detail, { ...init, status: 422 });\n }\n\n if (typeof detail === 'string') {\n return TangoResponse.error(\n {\n code: 'unprocessable_entity',\n message: detail,\n },\n { ...init, status: 422 }\n );\n }\n\n return TangoResponse.error(\n {\n code: 'unprocessable_entity',\n message: 'Unprocessable Entity',\n },\n { ...init, status: 422 }\n );\n }\n\n /**\n * Create a `429 Too Many Requests` response from a string or structured error.\n */\n static tooManyRequests<TDetails extends ErrorDetails = null>(\n detail?: string | TangoError | ProblemDetails<TDetails>,\n init?: Omit<TangoResponseInit, 'body' | 'status' | 'headers'> & {\n headers?: HeadersInit;\n }\n ): TangoResponse {\n if (TangoError.isTangoError(detail) || TangoError.isProblemDetails(detail)) {\n return TangoResponse.error(detail, { ...init, status: 429 });\n }\n\n if (typeof detail === 'string') {\n return TangoResponse.error(\n {\n code: 'too_many_requests',\n message: detail,\n },\n { ...init, status: 429 }\n );\n }\n\n return TangoResponse.error(\n {\n code: 'too_many_requests',\n message: 'Too Many Requests',\n },\n { ...init, status: 429 }\n );\n }\n\n /**\n * Create a problem-details style error response with Tango's envelope shape.\n */\n static problem<TDetails extends ErrorDetails = null>(\n problem?: string | TangoError | ProblemDetails<TDetails> | unknown,\n init?: Omit<TangoResponseInit, 'body' | 'headers'> & {\n headers?: HeadersInit;\n status?: number;\n }\n ): TangoResponse {\n let status = init?.status ?? 500;\n const headers = new TangoHeaders(init?.headers);\n if (!headers.has('Content-Type')) {\n headers.set('Content-Type', 'application/problem+json; charset=utf-8');\n }\n\n let code = 'error';\n let message = 'An error occurred';\n let details: ErrorDetails = undefined;\n let fields: Record<string, string[]> | undefined;\n\n if (TangoError.isTangoError(problem)) {\n const envelope = problem.toErrorEnvelope();\n status = problem.status;\n code = envelope.error.code;\n message = envelope.error.message;\n details = envelope.error.details;\n fields = envelope.error.fields;\n } else if (TangoError.isProblemDetails(problem)) {\n code = problem.code;\n message = problem.message;\n details = problem.details;\n fields = problem.fields;\n } else if (typeof problem === 'string') {\n message = problem;\n } else if (problem && typeof problem === 'object') {\n const extracted = problem as {\n details?: ErrorDetails;\n fields?: Record<string, string[]>;\n };\n details = extracted.details;\n fields = extracted.fields;\n }\n\n const envelope: ErrorEnvelope<ErrorDetails> = {\n error: {\n code,\n message,\n ...(details === undefined ? {} : { details }),\n ...(fields ? { fields } : {}),\n },\n };\n\n const body = JSON.stringify(envelope);\n if (!headers.has('Content-Length')) {\n headers.set('Content-Length', new TextEncoder().encode(body).length.toString());\n }\n return new TangoResponse({\n ...init,\n headers,\n status,\n body,\n });\n }\n\n /**\n * Returns a response for serving a file.\n */\n static file(\n file: Blob | Uint8Array | ArrayBuffer | ReadableStream<Uint8Array> | string,\n opts?: {\n filename?: string;\n contentType?: string;\n init?: Omit<TangoResponseInit, 'body' | 'headers'> & { headers?: HeadersInit };\n }\n ): TangoResponse {\n const headers = new TangoHeaders(opts?.init?.headers ?? {});\n if (opts?.filename) {\n // Serve as an attachment by default, but not 'download'\n headers.setContentDispositionInline(opts.filename);\n }\n if (opts?.contentType && !headers.has('Content-Type')) {\n headers.set('Content-Type', opts.contentType);\n } else if (!headers.has('Content-Type')) {\n headers.setContentTypeByFile(file, opts?.filename);\n }\n if (!headers.has('Content-Length')) {\n headers.setContentLengthFromBody(file);\n }\n return new TangoResponse({\n ...opts?.init,\n body: file as BodyInit,\n headers,\n });\n }\n\n /**\n * Returns a response that prompts the user to download the file.\n */\n static download(\n file: Blob | Uint8Array | ArrayBuffer | ReadableStream<Uint8Array> | string,\n opts?: {\n filename?: string;\n contentType?: string;\n init?: Omit<TangoResponseInit, 'body' | 'headers'> & { headers?: HeadersInit };\n }\n ): TangoResponse {\n const headers = new TangoHeaders(opts?.init?.headers ?? {});\n if (opts?.filename) {\n headers.setContentDispositionAttachment(opts.filename);\n } else {\n headers.set('Content-Disposition', 'attachment');\n }\n if (opts?.contentType && !headers.has('Content-Type')) {\n headers.set('Content-Type', opts.contentType);\n } else if (!headers.has('Content-Type')) {\n headers.setContentTypeByFile(file, opts?.filename);\n }\n if (!headers.has('Content-Length')) {\n headers.setContentLengthFromBody(file);\n }\n return new TangoResponse({\n ...opts?.init,\n body: file as BodyInit,\n headers,\n });\n }\n\n private static normalizeWebBody(body: BodyInit | JsonValue | null): BodyInit | null {\n if (\n isNil(body) ||\n typeof body === 'string' ||\n isBlob(body) ||\n isFormData(body) ||\n isArrayBuffer(body) ||\n isUint8Array(body) ||\n isURLSearchParams(body) ||\n isReadableStream(body)\n ) {\n return body;\n }\n\n return JSON.stringify(body);\n }\n\n /**\n * Expose the original body source for cloning and adapter integration.\n */\n get bodySource(): BodyInit | JsonValue | null {\n return this.tangoBody.bodySource;\n }\n\n /**\n * Report whether the status code falls inside the 2xx range.\n */\n get ok(): boolean {\n if (typeof this.okValue === 'boolean') return this.okValue;\n return this.status >= 200 && this.status < 300;\n }\n\n /**\n * Report whether the body has been consumed.\n */\n get bodyUsed(): boolean {\n return this.tangoBody.bodyUsed;\n }\n\n /**\n * Replace a header value on the response.\n */\n setHeader(name: string, value: string): void {\n this.headers.set(name, value);\n }\n /**\n * Append another value for a repeated response header.\n */\n appendHeader(name: string, value: string): void {\n this.headers.append(name, value);\n }\n /**\n * Read a response header value.\n */\n getHeader(name: string): string | null {\n return this.headers.get(name);\n }\n /**\n * Check whether a response header is present.\n */\n hasHeader(name: string): boolean {\n return this.headers.has(name);\n }\n /**\n * Remove a response header.\n */\n deleteHeader(name: string): void {\n this.headers.delete(name);\n }\n /**\n * Merge one or more values into the `Vary` header.\n */\n vary(...fields: string[]): void {\n this.headers.vary(...fields);\n }\n\n /**\n * Add a `Set-Cookie` header that replaces prior application intent.\n */\n setCookie(name: string, value: string, options?: Parameters<TangoHeaders['setCookie']>[2]): void {\n this.headers.setCookie(name, value, options);\n }\n /**\n * Append another `Set-Cookie` header.\n */\n appendCookie(name: string, value: string, options?: Parameters<TangoHeaders['appendCookie']>[2]): void {\n this.headers.appendCookie(name, value, options);\n }\n /**\n * Expire a cookie by issuing a matching deletion cookie header.\n */\n deleteCookie(name: string, options?: Parameters<TangoHeaders['deleteCookie']>[1]): void {\n this.headers.deleteCookie(name, options);\n }\n\n /**\n * Set the `Cache-Control` header through Tango's higher-level helper.\n */\n cacheControl(control: Parameters<TangoHeaders['cacheControl']>[0]): void {\n this.headers.cacheControl(control);\n }\n\n /**\n * Set the `Location` header on the response.\n */\n location(url: string): void {\n this.headers.location(url);\n }\n\n /**\n * Set the response content type.\n */\n contentType(mime: string): void {\n this.headers.contentType(mime);\n }\n\n // ---- Trace & Correlation helper methods ----\n\n /**\n * Set the X-Request-Id header (request correlation).\n * Returns this for fluent chaining.\n */\n withRequestId(requestId: string | undefined | null): this {\n if (!isNil(requestId) && typeof requestId === 'string' && requestId !== '') {\n this.headers.set('X-Request-Id', requestId);\n }\n return this;\n }\n\n /**\n * Set the traceparent header (W3C Trace Context propagation).\n * Returns this for fluent chaining.\n */\n withTraceparent(traceparent: string | undefined | null): this {\n if (!isNil(traceparent) && typeof traceparent === 'string' && traceparent !== '') {\n this.headers.set('traceparent', traceparent);\n }\n return this;\n }\n\n /**\n * Set the Server-Timing header.\n * Accepts a string or array of timing metrics.\n * Returns this for fluent chaining.\n */\n withServerTiming(timing: string | string[]): this {\n if (Array.isArray(timing)) {\n this.headers.set('Server-Timing', timing.join(', '));\n } else if (typeof timing === 'string') {\n this.headers.set('Server-Timing', timing);\n }\n return this;\n }\n\n /**\n * Set the X-Response-Time header (in ms).\n * Numeric or formatted string (e.g. \"76ms\").\n * Returns this for fluent chaining.\n */\n withResponseTime(time: number | string): this {\n if (typeof time === 'number') {\n this.headers.set('X-Response-Time', `${time}ms`);\n } else if (typeof time === 'string') {\n this.headers.set('X-Response-Time', time);\n }\n return this;\n }\n\n /**\n * Propagate common tracing/correlation headers from provided Headers, TangoHeaders, or plain object.\n * Known headers: x-request-id, traceparent, server-timing\n * Returns this for fluent chaining.\n */\n propagateTraceHeaders(input: HeadersInit): this {\n const incoming = new TangoHeaders(input);\n const traceHeaderNames = [\n 'x-request-id',\n 'traceparent',\n 'server-timing',\n // If you want to propagate response time, add 'x-response-time',\n ];\n for (const name of traceHeaderNames) {\n const value = incoming.get(name);\n if (!isNil(value)) this.headers.set(name, value);\n }\n return this;\n }\n\n /**\n * Clone the response so its body can be consumed independently.\n */\n clone(): TangoResponse {\n if (this.bodyUsed) {\n throw new TypeError('Body has already been used');\n }\n const clonedBody = this.tangoBody.clone();\n return new TangoResponse({\n body: clonedBody.bodySource,\n headers: this.headers.clone(),\n ok: this.okValue,\n redirected: this.redirected,\n status: this.status,\n statusText: this.statusText,\n type: this.type,\n url: this.url,\n });\n }\n\n /**\n * Convert this Tango-owned response into a native web `Response`.\n *\n * Adapters use this at the host-framework boundary so Tango can standardize\n * on `TangoResponse` internally while Next.js and other hosts still receive\n * a platform-native response object.\n */\n toWebResponse(): Response {\n const responseForTransfer = !this.bodyUsed && isReadableStream(this.bodySource) ? this.clone() : this;\n const body = TangoResponse.normalizeWebBody(responseForTransfer.bodySource);\n\n return new Response(body, {\n headers: new Headers(responseForTransfer.headers),\n status: responseForTransfer.status,\n statusText: responseForTransfer.statusText,\n });\n }\n\n //---- Spec Response interface fields and methods ----\n\n /**\n * Read the response body as an array buffer.\n */\n async arrayBuffer(): Promise<ArrayBuffer> {\n return this.tangoBody.arrayBuffer();\n }\n /**\n * Read the response body as a blob.\n */\n async blob(): Promise<Blob> {\n return this.tangoBody.blob();\n }\n /**\n * Read the response body as bytes.\n */\n async bytes(): Promise<Uint8Array<ArrayBuffer>> {\n return this.tangoBody.bytes();\n }\n /**\n * Read the response body as form data.\n */\n async formData(): Promise<FormData> {\n return this.tangoBody.formData();\n }\n /**\n * Parse the response body as JSON.\n */\n async json<T = unknown>(): Promise<T> {\n return this.tangoBody.json<T>();\n }\n /**\n * Read the response body as text.\n */\n async text(): Promise<string> {\n return this.tangoBody.text();\n }\n\n /**\n * Returns a plain object debug representation of this response: { status, headers: { ... }, bodyType: ... }.\n * Intended for testing and debug tooling.\n */\n toJSON(): { status: number; headers: Record<string, string>; bodyType: string } {\n return {\n status: this.status,\n headers: Object.fromEntries(this.headers.entries()),\n bodyType: this.tangoBody.bodyType,\n };\n }\n\n /**\n * Returns the original body for test/debug purposes *without* consuming the stream.\n *\n * @throws {Error} if called in a production environment. Provided only for test or debug.\n * @remarks\n * This method gives direct access to the original body as provided to the constructor,\n * before consumption. It is primarily intended for use in test code, introspection, or\n * advanced debug tools. **Do not rely on this in production.**\n * In production (`process.env.NODE_ENV === 'production'`), using this method will throw.\n *\n * This method is _not_ part of the web Response interface, and is intentionally private/internal.\n */\n\n public __peekBodyForTestOnly(): BodyInit | JsonValue | null {\n const nodeEnv = typeof process !== 'undefined' ? (process.env?.NODE_ENV as string | undefined) : undefined;\n\n // Strong guard against accidental shipping in production\n if (nodeEnv === 'production' || nodeEnv === 'prod') {\n throw new Error('peekBody() is not available in production builds. For test/debug use only.');\n }\n return this.tangoBody.bodySource;\n }\n}\n","/**\n * Domain boundary barrel: centralizes this subdomain's public contract.\n */\n\nimport { TangoBody, type JsonValue } from './TangoBody';\nimport { TangoHeaders } from './TangoHeaders';\nimport { TangoQueryParams } from './TangoQueryParams';\nimport { TangoRequest } from './TangoRequest';\nimport { TangoResponse } from './TangoResponse';\n\nexport { TangoBody, TangoHeaders, TangoQueryParams, TangoRequest, TangoResponse };\nexport type { JsonValue };\n"],"mappings":"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"}
@@ -590,7 +590,7 @@ declare class TangoResponse implements Response {
590
590
  /**
591
591
  * Create a `405 Method Not Allowed` response and optionally populate `Allow`.
592
592
  */
593
- static methodNotAllowed(allow?: readonly string[], detail?: string, init?: Omit<TangoResponseInit, 'body' | 'status' | 'headers'> & {
593
+ static methodNotAllowed<TDetails extends ErrorDetails = null>(allow?: readonly string[], detail?: string | TangoError | ProblemDetails<TDetails>, init?: Omit<TangoResponseInit, 'body' | 'status' | 'headers'> & {
594
594
  headers?: HeadersInit;
595
595
  }): TangoResponse;
596
596
  /**
@@ -821,4 +821,4 @@ declare namespace index_d_exports {
821
821
  }
822
822
  //#endregion
823
823
  export { TangoHeaders as a, TangoRequest as i, TangoResponse as n, JsonValue as o, TangoQueryParams as r, TangoBody as s, index_d_exports as t };
824
- //# sourceMappingURL=index-D8o4DOOG.d.ts.map
824
+ //# sourceMappingURL=index-Ds43ITu5.d.ts.map
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { a as HttpError, i as TangoError, n as ErrorEnvelope, r as ProblemDetails, t as ErrorDetails } from "./TangoError-ptR2iApz.js";
2
2
  import { a as MultipleObjectsReturned, i as NotFoundError, l as HttpErrorFactory, n as AuthenticationError, o as ValidationError, r as PermissionDenied, s as ConflictError, t as index_d_exports, u as HttpErrorFactoryConfig } from "./index-DFWodYLS.js";
3
- import { a as TangoHeaders, i as TangoRequest, n as TangoResponse, o as JsonValue, r as TangoQueryParams, s as TangoBody, t as index_d_exports$1 } from "./index-D8o4DOOG.js";
3
+ import { a as TangoHeaders, i as TangoRequest, n as TangoResponse, o as JsonValue, r as TangoQueryParams, s as TangoBody, t as index_d_exports$1 } from "./index-Ds43ITu5.js";
4
4
  import { a as ConsoleLogger, i as setLoggerFactory, n as getLogger, o as Logger, r as resetLoggerFactory, t as index_d_exports$2 } from "./index-MZzjIxgD.js";
5
5
  import { _ as isArrayBuffer, a as isError, c as isObject, d as isReadableStream, f as isURLSearchParams, g as isUint8Array, h as isBlob, p as isFormData, r as isDate, t as index_d_exports$3, u as isFile } from "./index-B5PoK4LH.js";
6
6
  import { a as trustedSql, c as SqlRawFragmentRequest, d as ValidatedSqlLookupToken, f as ValidatedSqlSafetyResult, g as SqlDialect, h as SqlIdentifierRole, i as isTrustedSqlFragment, l as SqlSafetyEngine, m as TrustedSqlFragment, n as quoteSqlIdentifier, o as SqlIdentifierRequest, p as ValidatedSqlIdentifier, r as validateSqlIdentifier, s as SqlLookupTokenRequest, t as index_d_exports$4, u as SqlSafetyRequest } from "./index-DPABSINz.js";
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { t as TangoError } from "./TangoError-Cvgnm026.js";
2
2
  import { a as isError, d as isURLSearchParams, f as isFormData, g as isArrayBuffer, h as isUint8Array, l as isFile, m as isBlob, r as isDate, s as isObject, t as runtime_exports, u as isReadableStream } from "./runtime-BAG_EKuM.js";
3
3
  import { a as MultipleObjectsReturned, i as NotFoundError, l as HttpErrorFactory, n as AuthenticationError, o as ValidationError, r as PermissionDenied, s as ConflictError, t as errors_exports } from "./errors-DpI5Dxmr.js";
4
- import { a as TangoHeaders, i as TangoQueryParams, n as TangoResponse, o as TangoBody, r as TangoRequest, t as http_exports } from "./http-6e0y_vd6.js";
4
+ import { a as TangoHeaders, i as TangoQueryParams, n as TangoResponse, o as TangoBody, r as TangoRequest, t as http_exports } from "./http-BJPRtBGV.js";
5
5
  import { a as ConsoleLogger, i as setLoggerFactory, n as getLogger, r as resetLoggerFactory, t as logging_exports } from "./logging-UC5uXHET.js";
6
6
  import { a as validateSqlIdentifier, i as SqlSafetyEngine, n as quoteSqlIdentifier, o as isTrustedSqlFragment, r as trustedSql, t as sql_exports } from "./sql-CIPnuTYO.js";
7
7
  //#region src/index.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@danceroutine/tango-core",
3
- "version": "1.11.13",
3
+ "version": "1.11.15",
4
4
  "description": "Core types, errors, and result utilities for Tango",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -56,7 +56,7 @@
56
56
  "@types/node": "^25.9.1",
57
57
  "tsdown": "^0.22.1",
58
58
  "typescript": "^6.0.3",
59
- "vitest": "^4.1.7",
59
+ "vitest": "^4.1.8",
60
60
  "zod": "^4.0.0"
61
61
  },
62
62
  "scripts": {