@twin.org/web 0.9.2-next.9 → 0.9.2

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 +1 @@
1
- {"version":3,"file":"fetchHelper.js","sourceRoot":"","sources":["../../../src/utils/fetchHelper.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport { AsyncCache, BaseError, Guards, Is, ObjectHelper, type IError } from \"@twin.org/core\";\nimport { nameof, nameofCamelCase } from \"@twin.org/nameof\";\nimport { FetchError } from \"../errors/fetchError.js\";\nimport { HeaderTypes } from \"../models/headerTypes.js\";\nimport { HttpMethod } from \"../models/httpMethod.js\";\nimport { HttpStatusCode } from \"../models/httpStatusCode.js\";\nimport type { IFetchOptions } from \"../models/IFetchOptions.js\";\nimport type { IHttpHeaders } from \"../models/IHttpHeaders.js\";\nimport { MimeTypes } from \"../models/mimeTypes.js\";\n\n/**\n * Class to helper with fetch operations.\n */\nexport class FetchHelper {\n\t/**\n\t * Runtime name for the class.\n\t */\n\tpublic static readonly CLASS_NAME: string = nameof<FetchHelper>();\n\n\t/**\n\t * Prefix to use for cache entries.\n\t * @internal\n\t */\n\tprivate static readonly _CACHE_PREFIX: string = \"fetch_\";\n\n\t/**\n\t * Perform a fetch request.\n\t * @param source The source for the request.\n\t * @param url The url for the request.\n\t * @param method The http method.\n\t * @param body Request to send to the endpoint.\n\t * @param options Options for sending the requests.\n\t * @returns The response.\n\t */\n\tpublic static async fetch(\n\t\tsource: string,\n\t\turl: string,\n\t\tmethod: HttpMethod,\n\t\tbody?: string | Uint8Array,\n\t\toptions?: Omit<IFetchOptions, \"cacheTtlSeconds\">\n\t): Promise<Response> {\n\t\tGuards.string(FetchHelper.CLASS_NAME, nameof(source), source);\n\t\tGuards.string(FetchHelper.CLASS_NAME, nameof(url), url);\n\t\tGuards.arrayOneOf<HttpMethod>(\n\t\t\tFetchHelper.CLASS_NAME,\n\t\t\tnameof(method),\n\t\t\tmethod,\n\t\t\tObject.values(HttpMethod)\n\t\t);\n\t\tif (!Is.undefined(body) && !Is.uint8Array(body)) {\n\t\t\tGuards.string(FetchHelper.CLASS_NAME, nameof(body), body);\n\t\t}\n\t\tif (!Is.undefined(options)) {\n\t\t\tGuards.object<IFetchOptions>(FetchHelper.CLASS_NAME, nameof(options), options);\n\t\t\tif (!Is.undefined(options.headers)) {\n\t\t\t\tGuards.object<IHttpHeaders>(\n\t\t\t\t\tFetchHelper.CLASS_NAME,\n\t\t\t\t\tnameof(options.headers),\n\t\t\t\t\toptions.headers\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (!Is.undefined(options.timeoutMs)) {\n\t\t\t\tGuards.integer(FetchHelper.CLASS_NAME, nameof(options.timeoutMs), options.timeoutMs);\n\t\t\t}\n\t\t\tif (!Is.undefined(options.includeCredentials)) {\n\t\t\t\tGuards.boolean(\n\t\t\t\t\tFetchHelper.CLASS_NAME,\n\t\t\t\t\tnameof(options.includeCredentials),\n\t\t\t\t\toptions.includeCredentials\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (!Is.undefined(options.retryCount)) {\n\t\t\t\tGuards.integer(FetchHelper.CLASS_NAME, nameof(options.retryCount), options.retryCount);\n\t\t\t}\n\t\t\tif (!Is.undefined(options.retryDelayMs)) {\n\t\t\t\tGuards.integer(FetchHelper.CLASS_NAME, nameof(options.retryDelayMs), options.retryDelayMs);\n\t\t\t}\n\t\t}\n\n\t\tlet controller: AbortController | undefined;\n\t\tlet timerId: number | NodeJS.Timeout | undefined;\n\t\tconst retryCount = options?.retryCount ?? 1;\n\t\tconst baseDelayMilliseconds = options?.retryDelayMs ?? 3000;\n\n\t\tlet lastError: IError | undefined;\n\t\tlet attempt;\n\t\tfor (attempt = 0; attempt < retryCount; attempt++) {\n\t\t\tif (attempt > 0) {\n\t\t\t\tconst exponentialBackoffDelay = baseDelayMilliseconds * Math.pow(2, attempt - 1);\n\t\t\t\tawait new Promise(resolve => globalThis.setTimeout(resolve, exponentialBackoffDelay));\n\t\t\t}\n\n\t\t\tif (options?.timeoutMs !== undefined) {\n\t\t\t\tcontroller = new AbortController();\n\t\t\t\ttimerId = globalThis.setTimeout(() => {\n\t\t\t\t\tif (controller) {\n\t\t\t\t\t\tcontroller.abort();\n\t\t\t\t\t}\n\t\t\t\t}, options?.timeoutMs);\n\t\t\t}\n\n\t\t\tlet finalBody;\n\t\t\tif (method === HttpMethod.POST || method === HttpMethod.PUT || method === HttpMethod.PATCH) {\n\t\t\t\tif (Is.string(body)) {\n\t\t\t\t\tfinalBody = body;\n\t\t\t\t} else if (Is.uint8Array(body)) {\n\t\t\t\t\tfinalBody = new Uint8Array(body);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tconst requestOptions: RequestInit = {\n\t\t\t\t\tmethod,\n\t\t\t\t\theaders: options?.headers as HeadersInit,\n\t\t\t\t\tbody: finalBody,\n\t\t\t\t\tsignal: controller ? controller.signal : undefined\n\t\t\t\t};\n\t\t\t\tif (Is.boolean(options?.includeCredentials)) {\n\t\t\t\t\trequestOptions.credentials = \"include\";\n\t\t\t\t}\n\n\t\t\t\tconst response = await fetch(url, requestOptions);\n\n\t\t\t\tif (!response.ok && retryCount > 1) {\n\t\t\t\t\tlastError = new FetchError(\n\t\t\t\t\t\tsource,\n\t\t\t\t\t\t`${nameofCamelCase<FetchHelper>()}.general`,\n\t\t\t\t\t\t(response.status as HttpStatusCode) ?? HttpStatusCode.internalServerError,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\turl,\n\t\t\t\t\t\t\tstatusText: response.statusText\n\t\t\t\t\t\t}\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\treturn response;\n\t\t\t\t}\n\t\t\t} catch (err) {\n\t\t\t\tconst isErr = Is.object<IError>(err);\n\t\t\t\tif (isErr && Is.stringValue(err.message) && err.message.includes(\"Failed to fetch\")) {\n\t\t\t\t\tlastError = new FetchError(\n\t\t\t\t\t\tsource,\n\t\t\t\t\t\t`${nameofCamelCase<FetchHelper>()}.connectivity`,\n\t\t\t\t\t\tHttpStatusCode.serviceUnavailable,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\turl\n\t\t\t\t\t\t},\n\t\t\t\t\t\terr\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tconst isAbort = isErr && err.name === \"AbortError\";\n\t\t\t\t\tconst props: { [id: string]: unknown } = { url };\n\t\t\t\t\tlet httpStatus: HttpStatusCode = HttpStatusCode.internalServerError;\n\t\t\t\t\tif (isAbort) {\n\t\t\t\t\t\thttpStatus = HttpStatusCode.requestTimeout;\n\t\t\t\t\t} else if (isErr && \"httpStatus\" in err) {\n\t\t\t\t\t\thttpStatus = err.httpStatus as HttpStatusCode;\n\t\t\t\t\t}\n\t\t\t\t\tif (isErr && \"statusText\" in err) {\n\t\t\t\t\t\tprops.statusText = err.statusText;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (isAbort) {\n\t\t\t\t\t\tlastError = new FetchError(\n\t\t\t\t\t\t\tsource,\n\t\t\t\t\t\t\t`${nameofCamelCase<FetchHelper>()}.timeout`,\n\t\t\t\t\t\t\thttpStatus,\n\t\t\t\t\t\t\tprops,\n\t\t\t\t\t\t\terr\n\t\t\t\t\t\t);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tlastError = new FetchError(\n\t\t\t\t\t\t\tsource,\n\t\t\t\t\t\t\t`${nameofCamelCase<FetchHelper>()}.general`,\n\t\t\t\t\t\t\thttpStatus,\n\t\t\t\t\t\t\tprops,\n\t\t\t\t\t\t\terr\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} finally {\n\t\t\t\tif (timerId) {\n\t\t\t\t\tglobalThis.clearTimeout(timerId);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (retryCount > 1 && attempt === retryCount) {\n\t\t\tthrow new FetchError(\n\t\t\t\tsource,\n\t\t\t\t`${nameofCamelCase<FetchHelper>()}.retryLimitExceeded`,\n\t\t\t\tHttpStatusCode.internalServerError,\n\t\t\t\t{ url },\n\t\t\t\tlastError\n\t\t\t);\n\t\t}\n\n\t\tthrow lastError as Error;\n\t}\n\n\t/**\n\t * Perform a request in json format.\n\t * @param source The source for the request.\n\t * @param url The url for the request.\n\t * @param method The http method.\n\t * @param requestData Request to send to the endpoint.\n\t * @param options Options for sending the requests.\n\t * @returns The response.\n\t */\n\tpublic static async fetchJson<T, U>(\n\t\tsource: string,\n\t\turl: string,\n\t\tmethod: HttpMethod,\n\t\trequestData?: T,\n\t\toptions?: IFetchOptions\n\t): Promise<U> {\n\t\tif (Is.integer(options?.cacheTtlMs) && options.cacheTtlMs >= 0) {\n\t\t\t// The cache option is set, so call the same method again but without\n\t\t\t// the cache option to get the result and cache it.\n\t\t\tconst cacheResponse = AsyncCache.exec(\n\t\t\t\t`${FetchHelper._CACHE_PREFIX}${url}`,\n\t\t\t\toptions.cacheTtlMs,\n\t\t\t\tasync () =>\n\t\t\t\t\tFetchHelper.fetchJson<T, U>(\n\t\t\t\t\t\tsource,\n\t\t\t\t\t\turl,\n\t\t\t\t\t\tmethod,\n\t\t\t\t\t\trequestData,\n\t\t\t\t\t\tObjectHelper.omit(options, [\"cacheTtlMs\"])\n\t\t\t\t\t)\n\t\t\t);\n\n\t\t\t// If the return value is a promise return it, otherwise continue\n\t\t\t// with the regular processing.\n\t\t\tif (Is.promise(cacheResponse)) {\n\t\t\t\treturn cacheResponse;\n\t\t\t}\n\t\t}\n\n\t\toptions ??= {};\n\t\toptions.headers ??= {};\n\n\t\tif (\n\t\t\tIs.undefined(options.headers[HeaderTypes.ContentType]) &&\n\t\t\t(method === HttpMethod.POST || method === HttpMethod.PUT || method === HttpMethod.PATCH)\n\t\t) {\n\t\t\toptions.headers[HeaderTypes.ContentType] = MimeTypes.Json;\n\t\t}\n\n\t\tconst response = await FetchHelper.fetch(\n\t\t\tsource,\n\t\t\turl,\n\t\t\tmethod,\n\t\t\trequestData ? JSON.stringify(requestData) : undefined,\n\t\t\toptions\n\t\t);\n\n\t\tif (response.ok) {\n\t\t\tif (response.status === HttpStatusCode.noContent) {\n\t\t\t\treturn {} as U;\n\t\t\t}\n\t\t\ttry {\n\t\t\t\treturn (await response.json()) as U;\n\t\t\t} catch (err) {\n\t\t\t\tthrow new FetchError(\n\t\t\t\t\tsource,\n\t\t\t\t\t`${nameofCamelCase<FetchHelper>()}.decodingJSON`,\n\t\t\t\t\tHttpStatusCode.badRequest,\n\t\t\t\t\t{ url },\n\t\t\t\t\terr\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tconst errorResponseData = await response.json();\n\t\tconst errorResponse = BaseError.fromError(errorResponseData);\n\t\tconst isErrorEmpty = BaseError.isEmpty(errorResponse);\n\n\t\tthrow new FetchError(\n\t\t\tsource,\n\t\t\t`${nameofCamelCase<FetchHelper>()}.failureStatusText`,\n\t\t\tresponse.status as HttpStatusCode,\n\t\t\t{\n\t\t\t\tstatusText: response.statusText,\n\t\t\t\turl,\n\t\t\t\tdata: isErrorEmpty ? errorResponseData : undefined\n\t\t\t},\n\t\t\tisErrorEmpty ? undefined : errorResponse\n\t\t);\n\t}\n\n\t/**\n\t * Perform a request for binary data.\n\t * @param source The source for the request.\n\t * @param url The url for the request.\n\t * @param method The http method.\n\t * @param requestData Request to send to the endpoint.\n\t * @param options Options for sending the requests.\n\t * @returns The response.\n\t */\n\tpublic static async fetchBinary<T>(\n\t\tsource: string,\n\t\turl: string,\n\t\tmethod: Extract<HttpMethod, \"GET\" | \"POST\">,\n\t\trequestData?: Uint8Array,\n\t\toptions?: IFetchOptions\n\t): Promise<Uint8Array | T> {\n\t\tif (Is.integer(options?.cacheTtlMs) && options.cacheTtlMs >= 0) {\n\t\t\t// The cache option is set, so call the same method again but without\n\t\t\t// the cache option to get the result and cache it.\n\t\t\tconst cacheResponse = AsyncCache.exec(\n\t\t\t\t`${FetchHelper._CACHE_PREFIX}${url}`,\n\t\t\t\toptions.cacheTtlMs,\n\t\t\t\tasync () =>\n\t\t\t\t\tFetchHelper.fetchBinary<T>(\n\t\t\t\t\t\tsource,\n\t\t\t\t\t\turl,\n\t\t\t\t\t\tmethod,\n\t\t\t\t\t\trequestData,\n\t\t\t\t\t\tObjectHelper.omit(options, [\"cacheTtlMs\"])\n\t\t\t\t\t)\n\t\t\t);\n\n\t\t\t// If the return value is a promise return it, otherwise continue\n\t\t\t// with the regular processing.\n\t\t\tif (Is.promise(cacheResponse)) {\n\t\t\t\treturn cacheResponse;\n\t\t\t}\n\t\t}\n\n\t\toptions ??= {};\n\t\toptions.headers ??= {};\n\n\t\tif (Is.undefined(options.headers[HeaderTypes.ContentType])) {\n\t\t\toptions.headers[HeaderTypes.ContentType] = MimeTypes.OctetStream;\n\t\t}\n\n\t\tconst response = await FetchHelper.fetch(source, url, method, requestData, options);\n\n\t\tif (response.ok) {\n\t\t\tif (method === HttpMethod.GET) {\n\t\t\t\tif (response.status === HttpStatusCode.noContent) {\n\t\t\t\t\treturn new Uint8Array();\n\t\t\t\t}\n\t\t\t\treturn new Uint8Array(await response.arrayBuffer());\n\t\t\t}\n\t\t\ttry {\n\t\t\t\treturn (await response.json()) as T;\n\t\t\t} catch (err) {\n\t\t\t\tthrow new FetchError(\n\t\t\t\t\tsource,\n\t\t\t\t\t`${nameofCamelCase<FetchHelper>()}.decodingJSON`,\n\t\t\t\t\tHttpStatusCode.badRequest,\n\t\t\t\t\t{ url },\n\t\t\t\t\terr\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tconst errorResponseData = await response.json();\n\t\tconst errorResponse = BaseError.fromError(errorResponseData);\n\t\tconst isErrorEmpty = BaseError.isEmpty(errorResponse);\n\n\t\tthrow new FetchError(\n\t\t\tsource,\n\t\t\t`${nameofCamelCase<FetchHelper>()}.failureStatusText`,\n\t\t\tresponse.status as HttpStatusCode,\n\t\t\t{\n\t\t\t\tstatusText: response.statusText,\n\t\t\t\turl,\n\t\t\t\tdata: isErrorEmpty ? errorResponseData : undefined\n\t\t\t},\n\t\t\tisErrorEmpty ? undefined : errorResponse\n\t\t);\n\t}\n\n\t/**\n\t * Clears the cache.\n\t */\n\tpublic static clearCache(): void {\n\t\tAsyncCache.clearCache(FetchHelper._CACHE_PREFIX);\n\t}\n\n\t/**\n\t * Get a cache entry.\n\t * @param url The url for the request.\n\t * @returns The cache entry if it exists.\n\t */\n\tpublic static async getCacheEntry<T>(url: string): Promise<T | undefined> {\n\t\treturn AsyncCache.get<T>(`${FetchHelper._CACHE_PREFIX}${url}`);\n\t}\n\n\t/**\n\t * Set a cache entry.\n\t * @param url The url for the request.\n\t * @param value The value to cache.\n\t * @returns The cache entry if it exists.\n\t */\n\tpublic static async setCacheEntry<T>(url: string, value: T): Promise<void> {\n\t\tawait AsyncCache.set<T>(`${FetchHelper._CACHE_PREFIX}${url}`, value);\n\t}\n\n\t/**\n\t * Remove a cache entry.\n\t * @param url The url for the request.\n\t */\n\tpublic static removeCacheEntry(url: string): void {\n\t\tAsyncCache.remove(`${FetchHelper._CACHE_PREFIX}${url}`);\n\t}\n}\n"]}
1
+ {"version":3,"file":"fetchHelper.js","sourceRoot":"","sources":["../../../src/utils/fetchHelper.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport { AsyncCache, BaseError, Guards, Is, ObjectHelper, type IError } from \"@twin.org/core\";\nimport { nameof, nameofCamelCase } from \"@twin.org/nameof\";\nimport { FetchError } from \"../errors/fetchError.js\";\nimport { HeaderTypes } from \"../models/headerTypes.js\";\nimport { HttpMethod } from \"../models/httpMethod.js\";\nimport { HttpStatusCode } from \"../models/httpStatusCode.js\";\nimport type { IFetchOptions } from \"../models/IFetchOptions.js\";\nimport type { IHttpHeaders } from \"../models/IHttpHeaders.js\";\nimport { MimeTypes } from \"../models/mimeTypes.js\";\n\n/**\n * Class to helper with fetch operations.\n */\nexport class FetchHelper {\n\t/**\n\t * Runtime name for the class.\n\t */\n\tpublic static readonly CLASS_NAME: string = nameof<FetchHelper>();\n\n\t/**\n\t * Prefix to use for cache entries.\n\t * @internal\n\t */\n\tprivate static readonly _CACHE_PREFIX: string = \"fetch_\";\n\n\t/**\n\t * Perform a fetch request.\n\t * @param source The source for the request.\n\t * @param url The url for the request.\n\t * @param method The http method.\n\t * @param body Request to send to the endpoint.\n\t * @param options Options for sending the requests.\n\t * @returns The response.\n\t */\n\tpublic static async fetch(\n\t\tsource: string,\n\t\turl: string,\n\t\tmethod: HttpMethod,\n\t\tbody?: string | Uint8Array,\n\t\toptions?: Omit<IFetchOptions, \"cacheTtlSeconds\">\n\t): Promise<Response> {\n\t\tGuards.string(FetchHelper.CLASS_NAME, nameof(source), source);\n\t\tGuards.string(FetchHelper.CLASS_NAME, nameof(url), url);\n\t\tGuards.arrayOneOf<HttpMethod>(\n\t\t\tFetchHelper.CLASS_NAME,\n\t\t\tnameof(method),\n\t\t\tmethod,\n\t\t\tObject.values(HttpMethod)\n\t\t);\n\t\tif (!Is.undefined(body) && !Is.uint8Array(body)) {\n\t\t\tGuards.string(FetchHelper.CLASS_NAME, nameof(body), body);\n\t\t}\n\t\tif (!Is.undefined(options)) {\n\t\t\tGuards.object<IFetchOptions>(FetchHelper.CLASS_NAME, nameof(options), options);\n\t\t\tif (!Is.undefined(options.headers)) {\n\t\t\t\tGuards.object<IHttpHeaders>(\n\t\t\t\t\tFetchHelper.CLASS_NAME,\n\t\t\t\t\tnameof(options.headers),\n\t\t\t\t\toptions.headers\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (!Is.undefined(options.timeoutMs)) {\n\t\t\t\tGuards.integer(FetchHelper.CLASS_NAME, nameof(options.timeoutMs), options.timeoutMs);\n\t\t\t}\n\t\t\tif (!Is.undefined(options.includeCredentials)) {\n\t\t\t\tGuards.boolean(\n\t\t\t\t\tFetchHelper.CLASS_NAME,\n\t\t\t\t\tnameof(options.includeCredentials),\n\t\t\t\t\toptions.includeCredentials\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (!Is.undefined(options.retryCount)) {\n\t\t\t\tGuards.integer(FetchHelper.CLASS_NAME, nameof(options.retryCount), options.retryCount);\n\t\t\t}\n\t\t\tif (!Is.undefined(options.retryDelayMs)) {\n\t\t\t\tGuards.integer(FetchHelper.CLASS_NAME, nameof(options.retryDelayMs), options.retryDelayMs);\n\t\t\t}\n\t\t}\n\n\t\tlet controller: AbortController | undefined;\n\t\tlet timerId: number | ReturnType<typeof setTimeout> | undefined;\n\t\tconst retryCount = options?.retryCount ?? 1;\n\t\tconst baseDelayMilliseconds = options?.retryDelayMs ?? 3000;\n\n\t\tlet lastError: IError | undefined;\n\t\tlet attempt;\n\t\tfor (attempt = 0; attempt < retryCount; attempt++) {\n\t\t\tif (attempt > 0) {\n\t\t\t\tconst exponentialBackoffDelay = baseDelayMilliseconds * Math.pow(2, attempt - 1);\n\t\t\t\tawait new Promise(resolve => globalThis.setTimeout(resolve, exponentialBackoffDelay));\n\t\t\t}\n\n\t\t\tif (options?.timeoutMs !== undefined) {\n\t\t\t\tcontroller = new AbortController();\n\t\t\t\ttimerId = globalThis.setTimeout(() => {\n\t\t\t\t\tif (controller) {\n\t\t\t\t\t\tcontroller.abort();\n\t\t\t\t\t}\n\t\t\t\t}, options?.timeoutMs);\n\t\t\t}\n\n\t\t\tlet finalBody;\n\t\t\tif (method === HttpMethod.POST || method === HttpMethod.PUT || method === HttpMethod.PATCH) {\n\t\t\t\tif (Is.string(body)) {\n\t\t\t\t\tfinalBody = body;\n\t\t\t\t} else if (Is.uint8Array(body)) {\n\t\t\t\t\tfinalBody = new Uint8Array(body);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tconst requestOptions: RequestInit = {\n\t\t\t\t\tmethod,\n\t\t\t\t\theaders: options?.headers as HeadersInit,\n\t\t\t\t\tbody: finalBody,\n\t\t\t\t\tsignal: controller ? controller.signal : undefined\n\t\t\t\t};\n\t\t\t\tif (Is.boolean(options?.includeCredentials)) {\n\t\t\t\t\trequestOptions.credentials = \"include\";\n\t\t\t\t}\n\n\t\t\t\tconst response = await fetch(url, requestOptions);\n\n\t\t\t\tif (!response.ok && retryCount > 1) {\n\t\t\t\t\tlastError = new FetchError(\n\t\t\t\t\t\tsource,\n\t\t\t\t\t\t`${nameofCamelCase<FetchHelper>()}.general`,\n\t\t\t\t\t\t(response.status as HttpStatusCode) ?? HttpStatusCode.internalServerError,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\turl,\n\t\t\t\t\t\t\tstatusText: response.statusText\n\t\t\t\t\t\t}\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\treturn response;\n\t\t\t\t}\n\t\t\t} catch (err) {\n\t\t\t\tconst isErr = Is.object<IError>(err);\n\t\t\t\tif (isErr && Is.stringValue(err.message) && err.message.includes(\"Failed to fetch\")) {\n\t\t\t\t\tlastError = new FetchError(\n\t\t\t\t\t\tsource,\n\t\t\t\t\t\t`${nameofCamelCase<FetchHelper>()}.connectivity`,\n\t\t\t\t\t\tHttpStatusCode.serviceUnavailable,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\turl\n\t\t\t\t\t\t},\n\t\t\t\t\t\terr\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tconst isAbort = isErr && err.name === \"AbortError\";\n\t\t\t\t\tconst props: { [id: string]: unknown } = { url };\n\t\t\t\t\tlet httpStatus: HttpStatusCode = HttpStatusCode.internalServerError;\n\t\t\t\t\tif (isAbort) {\n\t\t\t\t\t\thttpStatus = HttpStatusCode.requestTimeout;\n\t\t\t\t\t} else if (isErr && \"httpStatus\" in err) {\n\t\t\t\t\t\thttpStatus = err.httpStatus as HttpStatusCode;\n\t\t\t\t\t}\n\t\t\t\t\tif (isErr && \"statusText\" in err) {\n\t\t\t\t\t\tprops.statusText = err.statusText;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (isAbort) {\n\t\t\t\t\t\tlastError = new FetchError(\n\t\t\t\t\t\t\tsource,\n\t\t\t\t\t\t\t`${nameofCamelCase<FetchHelper>()}.timeout`,\n\t\t\t\t\t\t\thttpStatus,\n\t\t\t\t\t\t\tprops,\n\t\t\t\t\t\t\terr\n\t\t\t\t\t\t);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tlastError = new FetchError(\n\t\t\t\t\t\t\tsource,\n\t\t\t\t\t\t\t`${nameofCamelCase<FetchHelper>()}.general`,\n\t\t\t\t\t\t\thttpStatus,\n\t\t\t\t\t\t\tprops,\n\t\t\t\t\t\t\terr\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} finally {\n\t\t\t\tif (timerId) {\n\t\t\t\t\tglobalThis.clearTimeout(timerId);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (retryCount > 1 && attempt === retryCount) {\n\t\t\tthrow new FetchError(\n\t\t\t\tsource,\n\t\t\t\t`${nameofCamelCase<FetchHelper>()}.retryLimitExceeded`,\n\t\t\t\tHttpStatusCode.internalServerError,\n\t\t\t\t{ url },\n\t\t\t\tlastError\n\t\t\t);\n\t\t}\n\n\t\tthrow lastError as Error;\n\t}\n\n\t/**\n\t * Perform a request in json format.\n\t * @param source The source for the request.\n\t * @param url The url for the request.\n\t * @param method The http method.\n\t * @param requestData Request to send to the endpoint.\n\t * @param options Options for sending the requests.\n\t * @returns The response.\n\t */\n\tpublic static async fetchJson<T, U>(\n\t\tsource: string,\n\t\turl: string,\n\t\tmethod: HttpMethod,\n\t\trequestData?: T,\n\t\toptions?: IFetchOptions\n\t): Promise<U> {\n\t\tif (Is.integer(options?.cacheTtlMs) && options.cacheTtlMs >= 0) {\n\t\t\t// The cache option is set, so call the same method again but without\n\t\t\t// the cache option to get the result and cache it.\n\t\t\tconst cacheResponse = AsyncCache.exec(\n\t\t\t\t`${FetchHelper._CACHE_PREFIX}${url}`,\n\t\t\t\toptions.cacheTtlMs,\n\t\t\t\tasync () =>\n\t\t\t\t\tFetchHelper.fetchJson<T, U>(\n\t\t\t\t\t\tsource,\n\t\t\t\t\t\turl,\n\t\t\t\t\t\tmethod,\n\t\t\t\t\t\trequestData,\n\t\t\t\t\t\tObjectHelper.omit(options, [\"cacheTtlMs\"])\n\t\t\t\t\t)\n\t\t\t);\n\n\t\t\t// If the return value is a promise return it, otherwise continue\n\t\t\t// with the regular processing.\n\t\t\tif (Is.promise(cacheResponse)) {\n\t\t\t\treturn cacheResponse;\n\t\t\t}\n\t\t}\n\n\t\toptions ??= {};\n\t\toptions.headers ??= {};\n\n\t\tif (\n\t\t\tIs.undefined(options.headers[HeaderTypes.ContentType]) &&\n\t\t\t(method === HttpMethod.POST || method === HttpMethod.PUT || method === HttpMethod.PATCH)\n\t\t) {\n\t\t\toptions.headers[HeaderTypes.ContentType] = MimeTypes.Json;\n\t\t}\n\n\t\tconst response = await FetchHelper.fetch(\n\t\t\tsource,\n\t\t\turl,\n\t\t\tmethod,\n\t\t\trequestData ? JSON.stringify(requestData) : undefined,\n\t\t\toptions\n\t\t);\n\n\t\tif (response.ok) {\n\t\t\tif (response.status === HttpStatusCode.noContent) {\n\t\t\t\treturn {} as U;\n\t\t\t}\n\t\t\ttry {\n\t\t\t\treturn (await response.json()) as U;\n\t\t\t} catch (err) {\n\t\t\t\tthrow new FetchError(\n\t\t\t\t\tsource,\n\t\t\t\t\t`${nameofCamelCase<FetchHelper>()}.decodingJSON`,\n\t\t\t\t\tHttpStatusCode.badRequest,\n\t\t\t\t\t{ url },\n\t\t\t\t\terr\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tconst errorResponseData = await response.json();\n\t\tconst errorResponse = BaseError.fromError(errorResponseData);\n\t\tconst isErrorEmpty = BaseError.isEmpty(errorResponse);\n\n\t\tthrow new FetchError(\n\t\t\tsource,\n\t\t\t`${nameofCamelCase<FetchHelper>()}.failureStatusText`,\n\t\t\tresponse.status as HttpStatusCode,\n\t\t\t{\n\t\t\t\tstatusText: response.statusText,\n\t\t\t\turl,\n\t\t\t\tdata: isErrorEmpty ? errorResponseData : undefined\n\t\t\t},\n\t\t\tisErrorEmpty ? undefined : errorResponse\n\t\t);\n\t}\n\n\t/**\n\t * Perform a request for binary data.\n\t * @param source The source for the request.\n\t * @param url The url for the request.\n\t * @param method The http method.\n\t * @param requestData Request to send to the endpoint.\n\t * @param options Options for sending the requests.\n\t * @returns The response.\n\t */\n\tpublic static async fetchBinary<T>(\n\t\tsource: string,\n\t\turl: string,\n\t\tmethod: Extract<HttpMethod, \"GET\" | \"POST\">,\n\t\trequestData?: Uint8Array,\n\t\toptions?: IFetchOptions\n\t): Promise<Uint8Array | T> {\n\t\tif (Is.integer(options?.cacheTtlMs) && options.cacheTtlMs >= 0) {\n\t\t\t// The cache option is set, so call the same method again but without\n\t\t\t// the cache option to get the result and cache it.\n\t\t\tconst cacheResponse = AsyncCache.exec(\n\t\t\t\t`${FetchHelper._CACHE_PREFIX}${url}`,\n\t\t\t\toptions.cacheTtlMs,\n\t\t\t\tasync () =>\n\t\t\t\t\tFetchHelper.fetchBinary<T>(\n\t\t\t\t\t\tsource,\n\t\t\t\t\t\turl,\n\t\t\t\t\t\tmethod,\n\t\t\t\t\t\trequestData,\n\t\t\t\t\t\tObjectHelper.omit(options, [\"cacheTtlMs\"])\n\t\t\t\t\t)\n\t\t\t);\n\n\t\t\t// If the return value is a promise return it, otherwise continue\n\t\t\t// with the regular processing.\n\t\t\tif (Is.promise(cacheResponse)) {\n\t\t\t\treturn cacheResponse;\n\t\t\t}\n\t\t}\n\n\t\toptions ??= {};\n\t\toptions.headers ??= {};\n\n\t\tif (Is.undefined(options.headers[HeaderTypes.ContentType])) {\n\t\t\toptions.headers[HeaderTypes.ContentType] = MimeTypes.OctetStream;\n\t\t}\n\n\t\tconst response = await FetchHelper.fetch(source, url, method, requestData, options);\n\n\t\tif (response.ok) {\n\t\t\tif (method === HttpMethod.GET) {\n\t\t\t\tif (response.status === HttpStatusCode.noContent) {\n\t\t\t\t\treturn new Uint8Array();\n\t\t\t\t}\n\t\t\t\treturn new Uint8Array(await response.arrayBuffer());\n\t\t\t}\n\t\t\ttry {\n\t\t\t\treturn (await response.json()) as T;\n\t\t\t} catch (err) {\n\t\t\t\tthrow new FetchError(\n\t\t\t\t\tsource,\n\t\t\t\t\t`${nameofCamelCase<FetchHelper>()}.decodingJSON`,\n\t\t\t\t\tHttpStatusCode.badRequest,\n\t\t\t\t\t{ url },\n\t\t\t\t\terr\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tconst errorResponseData = await response.json();\n\t\tconst errorResponse = BaseError.fromError(errorResponseData);\n\t\tconst isErrorEmpty = BaseError.isEmpty(errorResponse);\n\n\t\tthrow new FetchError(\n\t\t\tsource,\n\t\t\t`${nameofCamelCase<FetchHelper>()}.failureStatusText`,\n\t\t\tresponse.status as HttpStatusCode,\n\t\t\t{\n\t\t\t\tstatusText: response.statusText,\n\t\t\t\turl,\n\t\t\t\tdata: isErrorEmpty ? errorResponseData : undefined\n\t\t\t},\n\t\t\tisErrorEmpty ? undefined : errorResponse\n\t\t);\n\t}\n\n\t/**\n\t * Clears the cache.\n\t */\n\tpublic static clearCache(): void {\n\t\tAsyncCache.clearCache(FetchHelper._CACHE_PREFIX);\n\t}\n\n\t/**\n\t * Get a cache entry.\n\t * @param url The url for the request.\n\t * @returns The cache entry if it exists.\n\t */\n\tpublic static async getCacheEntry<T>(url: string): Promise<T | undefined> {\n\t\treturn AsyncCache.get<T>(`${FetchHelper._CACHE_PREFIX}${url}`);\n\t}\n\n\t/**\n\t * Set a cache entry.\n\t * @param url The url for the request.\n\t * @param value The value to cache.\n\t * @returns The cache entry if it exists.\n\t */\n\tpublic static async setCacheEntry<T>(url: string, value: T): Promise<void> {\n\t\tawait AsyncCache.set<T>(`${FetchHelper._CACHE_PREFIX}${url}`, value);\n\t}\n\n\t/**\n\t * Remove a cache entry.\n\t * @param url The url for the request.\n\t */\n\tpublic static removeCacheEntry(url: string): void {\n\t\tAsyncCache.remove(`${FetchHelper._CACHE_PREFIX}${url}`);\n\t}\n}\n"]}
@@ -110,7 +110,7 @@ export class HeaderHelper {
110
110
  return parsed?.map(({ value, quality, params }) => ({
111
111
  mimeType: value,
112
112
  quality,
113
- ...(Object.keys(params).length > 0 ? { params } : {})
113
+ params: Object.keys(params).length > 0 ? params : undefined
114
114
  }));
115
115
  }
116
116
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"headerHelper.js","sourceRoot":"","sources":["../../../src/utils/headerHelper.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport { ArrayHelper, GeneralError, Guards, Is } from \"@twin.org/core\";\nimport { nameof } from \"@twin.org/nameof\";\nimport { HeaderTypes } from \"../models/headerTypes.js\";\nimport type { HttpLinkRelType } from \"../models/httpLinkRelType.js\";\nimport type { IHttpHeaders } from \"../models/IHttpHeaders.js\";\nimport type { IHttpLinkHeader } from \"../models/IHttpLinkHeader.js\";\n\n/**\n * Class to helper with header operations.\n */\nexport class HeaderHelper {\n\t/**\n\t * Runtime name for the class.\n\t */\n\tpublic static readonly CLASS_NAME: string = nameof<HeaderHelper>();\n\n\t/**\n\t * Regex for valid correlation ID (alphanumeric, dash, underscore).\n\t * Examples: `request_123`, `trace-id-456`, `ABC_789`.\n\t * @internal\n\t */\n\tprivate static readonly _CORRELATION_ID_REGEX = /^[\\w-]+$/;\n\n\t/**\n\t * Regex for valid Accept-Language tags and wildcard values.\n\t * Supports wildcard entries and common BCP 47 style tags.\n\t * Examples: `*`, `en`, `en-GB`, `es-419`, `zh-Hant`, `zh-Hant-TW`.\n\t * @internal\n\t */\n\tprivate static readonly _ACCEPT_LANGUAGE_TAG_REGEX = /^(\\*|[A-Za-z]{1,8}(?:-[\\dA-Za-z]{1,8})*)$/;\n\n\t/**\n\t * Regex for valid quality parameters in negotiation headers.\n\t * Supports quality values from `0` to `1` with up to three decimal places.\n\t * Examples: `q=1`, `q=0.9`, `q=0.875`, `q=0`, `q=1.0`.\n\t * @internal\n\t */\n\tprivate static readonly _QUALITY_REGEX = /^q=(0(?:\\.\\d{1,3})?|1(?:\\.0{1,3})?)$/i;\n\n\t/**\n\t * Regex for valid media type values in Accept headers.\n\t * Supports wildcards, standard types, and vendor extensions.\n\t * Examples: `text/html`, `application/json`, `image/*`, `application/vnd.api+json`.\n\t * @internal\n\t */\n\tprivate static readonly _ACCEPT_MEDIA_TYPE_REGEX =\n\t\t/^(\\*|[A-Za-z0-9][\\w.+-]*)\\/(\\*|[A-Za-z0-9][\\w.+-]*)$/;\n\n\t/**\n\t * Regex for valid IPv4 addresses.\n\t * Examples: `127.0.0.1`, `192.168.1.10`, `255.255.255.255`.\n\t * @internal\n\t */\n\tprivate static readonly _IP_V4_REGEX =\n\t\t/^(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(?:\\.(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}$/;\n\n\t/**\n\t * Regex for valid IPv6 addresses.\n\t * Examples: `2001:0db8:85a3:0000:0000:8a2e:0370:7334`, `2001:db8::`, `::1`.\n\t * @internal\n\t */\n\tprivate static readonly _IP_V6_REGEX =\n\t\t/^((?:[\\dA-Fa-f]{1,4}:){7}[\\dA-Fa-f]{1,4}|(?:[\\dA-Fa-f]{1,4}:){1,7}:|:(?::[\\dA-Fa-f]{1,4}){1,7})$/;\n\n\t/**\n\t * Create a bearer token header.\n\t * @param token The token to create the header for.\n\t * @returns The bearer token header.\n\t */\n\tpublic static createBearer(token: unknown): string {\n\t\tif (Is.stringValue(token)) {\n\t\t\tif (token.startsWith(\"Bearer \")) {\n\t\t\t\treturn token;\n\t\t\t}\n\t\t\treturn `Bearer ${token.trim()}`;\n\t\t}\n\t\treturn \"\";\n\t}\n\n\t/**\n\t * Extract the bearer token from a header.\n\t * @param header The header value to extract the token from.\n\t * @returns The extracted token if it exists.\n\t */\n\tpublic static extractBearer(header: unknown): string {\n\t\tif (Is.stringValue(header) && header.startsWith(\"Bearer \")) {\n\t\t\treturn header.slice(7, header.length).trim();\n\t\t}\n\t\treturn \"\";\n\t}\n\n\t/**\n\t * Extract parsed language preferences from the Accept-Language header.\n\t * @param headers The HTTP request headers.\n\t * @returns The parsed language preferences ordered by highest quality first, or undefined if missing or invalid.\n\t */\n\tpublic static extractAcceptLanguage(\n\t\theaders?: IHttpHeaders\n\t): { language: string; quality: number }[] | undefined {\n\t\treturn HeaderHelper.parseAcceptLanguage(headers?.[HeaderTypes.AcceptLanguage]);\n\t}\n\n\t/**\n\t * Parse one or more Accept-Language header values into language preferences.\n\t * @param acceptLanguage The Accept-Language header value or values.\n\t * @returns The parsed language preferences ordered by highest quality first, or undefined if missing or if any entry is invalid.\n\t */\n\tpublic static parseAcceptLanguage(\n\t\tacceptLanguage: string | string[] | undefined\n\t): { language: string; quality: number }[] | undefined {\n\t\tconst parsed = HeaderHelper.parseWeightedHeader(\n\t\t\tacceptLanguage,\n\t\t\tHeaderHelper._ACCEPT_LANGUAGE_TAG_REGEX\n\t\t);\n\t\treturn parsed?.map(({ value, quality }) => ({ language: value, quality }));\n\t}\n\n\t/**\n\t * Extract parsed media type preferences from the Accept header.\n\t * @param headers The HTTP request headers.\n\t * @returns The parsed media type preferences ordered by highest quality first, or undefined if missing or invalid.\n\t */\n\tpublic static extractAccept(\n\t\theaders?: IHttpHeaders\n\t): { mimeType: string; quality: number; params?: { [key: string]: string } }[] | undefined {\n\t\treturn HeaderHelper.parseAccept(headers?.[HeaderTypes.Accept]);\n\t}\n\n\t/**\n\t * Parse one or more Accept header values into media type preferences.\n\t * @param accept The Accept header value or values.\n\t * @returns The parsed media type preferences ordered by highest quality first, or undefined if missing or if any entry is invalid.\n\t * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Accept\n\t */\n\tpublic static parseAccept(\n\t\taccept: string | string[] | undefined\n\t): { mimeType: string; quality: number; params?: { [key: string]: string } }[] | undefined {\n\t\tconst parsed = HeaderHelper.parseWeightedHeader(accept, HeaderHelper._ACCEPT_MEDIA_TYPE_REGEX);\n\t\treturn parsed?.map(({ value, quality, params }) => ({\n\t\t\tmimeType: value,\n\t\t\tquality,\n\t\t\t...(Object.keys(params).length > 0 ? { params } : {})\n\t\t}));\n\t}\n\n\t/**\n\t * Extract client IP addresses from HTTP request headers.\n\t * Checks all `X-Forwarded-For` and `X-Real-IP` header values for proxied requests.\n\t * @param headers The HTTP request headers.\n\t * @returns The extracted client IP addresses in header order.\n\t */\n\tpublic static extractClientIps(headers?: IHttpHeaders): string[] {\n\t\tconst ips: string[] = [];\n\n\t\tconst forwardedForValues = HeaderHelper.getHeaderValues(headers?.[\"x-forwarded-for\"]);\n\t\tfor (const forwardedFor of forwardedForValues) {\n\t\t\tconst forwardedIps = forwardedFor\n\t\t\t\t.split(\",\")\n\t\t\t\t.map(ip => ip.trim())\n\t\t\t\t.filter(ip => HeaderHelper.isIpAddress(ip));\n\n\t\t\tips.push(...forwardedIps);\n\t\t}\n\n\t\tconst realIpValues = HeaderHelper.getHeaderValues(headers?.[\"x-real-ip\"]);\n\t\tfor (const realIp of realIpValues) {\n\t\t\tif (HeaderHelper.isIpAddress(realIp)) {\n\t\t\t\tips.push(realIp);\n\t\t\t}\n\t\t}\n\n\t\treturn ips;\n\t}\n\n\t/**\n\t * Extract the User-Agent header from the HTTP request context.\n\t * @param headers The HTTP request headers.\n\t * @param maxLength Optional maximum length for the User-Agent string to prevent excessively long values.\n\t * @returns The user agent string or undefined if not available.\n\t */\n\tpublic static extractUserAgent(headers?: IHttpHeaders, maxLength?: number): string | undefined {\n\t\tconst headerValues = HeaderHelper.getHeaderValues(headers?.[HeaderTypes.UserAgent]);\n\t\tfor (const headerValue of headerValues) {\n\t\t\treturn Is.integer(maxLength) ? headerValue.slice(0, maxLength) : headerValue;\n\t\t}\n\t}\n\n\t/**\n\t * Extract a correlation ID for request tracing from the X-Correlation-ID header.\n\t * @param headers The HTTP request headers.\n\t * @param maxLength Optional maximum length for the extracted correlation ID.\n\t * @returns The correlation ID, or undefined if the header is missing or invalid.\n\t */\n\tpublic static extractCorrelationId(\n\t\theaders?: IHttpHeaders,\n\t\tmaxLength?: number\n\t): string | undefined {\n\t\tconst headerValues = HeaderHelper.getHeaderValues(headers?.[\"x-correlation-id\"]);\n\t\tfor (const headerValue of headerValues) {\n\t\t\tif (HeaderHelper._CORRELATION_ID_REGEX.test(headerValue)) {\n\t\t\t\treturn Is.integer(maxLength) ? headerValue.slice(0, maxLength) : headerValue;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Validate if a string is a valid IP address (IPv4 or IPv6).\n\t * @param ip The IP address to validate.\n\t * @returns True if valid, false otherwise.\n\t */\n\tpublic static isIpAddress(ip: string): boolean {\n\t\tif (!Is.stringValue(ip)) {\n\t\t\treturn false;\n\t\t}\n\t\treturn HeaderHelper.isIpAddressV4(ip) || HeaderHelper.isIpAddressV6(ip);\n\t}\n\n\t/**\n\t * Validate if a string is a valid IP address IPv4.\n\t * @param ip The IP address to validate.\n\t * @returns True if valid, false otherwise.\n\t */\n\tpublic static isIpAddressV4(ip: string): boolean {\n\t\tif (!Is.stringValue(ip)) {\n\t\t\treturn false;\n\t\t}\n\t\treturn HeaderHelper._IP_V4_REGEX.test(ip);\n\t}\n\n\t/**\n\t * Validate if a string is a valid IP address IPv6.\n\t * @param ip The IP address to validate.\n\t * @returns True if valid, false otherwise.\n\t */\n\tpublic static isIpAddressV6(ip: string): boolean {\n\t\tif (!Is.stringValue(ip)) {\n\t\t\treturn false;\n\t\t}\n\t\treturn HeaderHelper._IP_V6_REGEX.test(ip);\n\t}\n\n\t/**\n\t * Extract the first occurrence of properties from a Link header for a specific relation type.\n\t * @param linkHeader The Link header value in format `<url>; rel=\"...\"; param1=\"\"; param2=\"\"`.\n\t * @param relation The relation type to extract.\n\t * @returns The extracted URL, rel and optional params or undefined if invalid/missing.\n\t * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Link\n\t */\n\tpublic static extractLinkHeaderRelation(\n\t\tlinkHeader: string | string[] | undefined,\n\t\trelation: HttpLinkRelType | string | RegExp\n\t): IHttpLinkHeader | undefined {\n\t\tconst headers = HeaderHelper.extractLinkHeaders(linkHeader);\n\t\tif (Is.arrayValue(headers)) {\n\t\t\treturn headers.find(h => HeaderHelper.matchesLinkHeaderRelation(h.rel, relation));\n\t\t}\n\t}\n\n\t/**\n\t * Extract multiple properties from a Link header for a specific relation type.\n\t * @param linkHeader The Link header value in format `<url>; rel=\"...\"; param1=\"\"; param2=\"\"`.\n\t * @param relation The relation type to extract.\n\t * @returns The extracted URL, rel and optional params or undefined if invalid/missing.\n\t * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Link\n\t */\n\tpublic static extractLinkHeaderRelations(\n\t\tlinkHeader: string | string[] | undefined,\n\t\trelation: HttpLinkRelType | string | RegExp\n\t): IHttpLinkHeader[] | undefined {\n\t\tconst headers = HeaderHelper.extractLinkHeaders(linkHeader);\n\t\tif (Is.arrayValue(headers)) {\n\t\t\treturn headers.filter(h => HeaderHelper.matchesLinkHeaderRelation(h.rel, relation));\n\t\t}\n\t}\n\n\t/**\n\t * Extract the link headers.\n\t * @param linkHeader The Link header value in format `<url>; rel=\"...\"; param1=\"\"; param2=\"\"`.\n\t * @returns The extracted possible array of URL, rel and optional params or undefined if invalid/missing.\n\t * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Link\n\t */\n\tpublic static extractLinkHeaders(\n\t\tlinkHeader: string | string[] | undefined\n\t): IHttpLinkHeader[] | undefined {\n\t\tconst linkHeaderArray = ArrayHelper.fromObjectOrArray<string>(linkHeader);\n\t\tif (Is.arrayValue<string>(linkHeaderArray)) {\n\t\t\tconst results = [];\n\t\t\tfor (const singleLinkHeader of linkHeaderArray) {\n\t\t\t\tconst segments = HeaderHelper.extractLinkHeaderSegments(singleLinkHeader);\n\t\t\t\tresults.push(\n\t\t\t\t\t...segments.map(l => HeaderHelper.extractLinkHeader(l)).filter(h => !Is.empty(h))\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn results;\n\t\t}\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * Split a combined Link header value into individual link-value segments, comma separated.\n\t * @param linkHeader Raw Link header string.\n\t * @returns Array of individual link-value segments.\n\t * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Link\n\t */\n\tpublic static extractLinkHeaderSegments(linkHeader: string): string[] {\n\t\tif (!Is.stringValue(linkHeader)) {\n\t\t\treturn [];\n\t\t}\n\t\tconst trimmed = linkHeader.trim();\n\t\tif (Is.empty(trimmed)) {\n\t\t\treturn [];\n\t\t}\n\t\treturn trimmed\n\t\t\t.split(/,(?=\\s*<)/)\n\t\t\t.map(s => s.trim())\n\t\t\t.filter(s => !Is.empty(s));\n\t}\n\n\t/**\n\t * Extract the properties from a Link header.\n\t * @param linkHeader The Link header value in format `<url>; rel=\"...\"; param1=\"\"; param2=\"\"`.\n\t * @returns The extracted URL, rel and optional params or undefined if invalid/missing.\n\t * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Link\n\t */\n\tpublic static extractLinkHeader(linkHeader: string): IHttpLinkHeader | undefined {\n\t\tif (!Is.stringValue(linkHeader)) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst parts = linkHeader.split(\";\");\n\n\t\tif (parts.length >= 2) {\n\t\t\tlet url;\n\t\t\tlet urlQueryParams: { [id: string]: string } | undefined;\n\n\t\t\tconst urlMatch = /<([^>]+)>/.exec(parts[0]);\n\t\t\tif (Is.stringValue(urlMatch?.[1])) {\n\t\t\t\turl = urlMatch[1];\n\n\t\t\t\tconst queryIndex = url.indexOf(\"?\");\n\t\t\t\tif (queryIndex !== -1) {\n\t\t\t\t\tconst urlParamsString = url.slice(queryIndex + 1);\n\t\t\t\t\tconst queryParts = urlParamsString.split(\"&\");\n\n\t\t\t\t\tfor (const queryPart of queryParts) {\n\t\t\t\t\t\tconst [key, value] = queryPart.split(\"=\");\n\t\t\t\t\t\tif (Is.stringValue(key) && Is.stringValue(value)) {\n\t\t\t\t\t\t\turlQueryParams ??= {};\n\t\t\t\t\t\t\turlQueryParams[key] = decodeURIComponent(value);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tlet rel: string[] | undefined;\n\t\t\tconst params: { [id: string]: string } = {};\n\n\t\t\tfor (let i = 1; i < parts.length; i++) {\n\t\t\t\tconst relMatch = /rel=\"([^\"]+)\"/.exec(parts[i].trim());\n\t\t\t\tif (relMatch?.[1]) {\n\t\t\t\t\trel = HeaderHelper.normalizeLinkHeaderRelations(relMatch[1]);\n\t\t\t\t} else {\n\t\t\t\t\tconst paramMatch = /([^=]+)=\"([^\"]+)\"/.exec(parts[i].trim());\n\t\t\t\t\tif (paramMatch?.[1] && paramMatch?.[2]) {\n\t\t\t\t\t\tparams[paramMatch[1]] = paramMatch[2];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (Is.stringValue(url) && Is.arrayValue(rel)) {\n\t\t\t\treturn {\n\t\t\t\t\turl,\n\t\t\t\t\turlQueryParams,\n\t\t\t\t\trel,\n\t\t\t\t\tparams: Object.keys(params).length > 0 ? params : undefined\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * Create a compliant Link header.\n\t * @param url The URL to include in the Link header.\n\t * @param urlQueryParams Optional query parameters to include in the URL.\n\t * @param rel The relation type (e.g., \"next\", \"prev\", \"self\").\n\t * @returns The formatted Link header string.\n\t * @throws GeneralError if the URL or rel are invalid.\n\t * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Link\n\t */\n\tpublic static createLinkHeader(\n\t\turl: string,\n\t\turlQueryParams: { [id: string]: string } | undefined,\n\t\trel: HttpLinkRelType | HttpLinkRelType[] | string | string[],\n\t\tparams?: { [id: string]: string }\n\t): string {\n\t\tGuards.stringValue(HeaderHelper.CLASS_NAME, nameof(url), url);\n\n\t\tconst relationValues = Is.string(rel)\n\t\t\t? HeaderHelper.normalizeLinkHeaderRelations(rel)\n\t\t\t: ArrayHelper.fromObjectOrArray(rel);\n\n\t\tGuards.arrayValue(HeaderHelper.CLASS_NAME, nameof(rel), relationValues);\n\n\t\tif (url.includes(\">\")) {\n\t\t\tthrow new GeneralError(HeaderHelper.CLASS_NAME, \"invalidLinkHeaderURL\");\n\t\t}\n\n\t\tfor (let i = 0; i < relationValues.length; i++) {\n\t\t\tGuards.stringValue(\n\t\t\t\tHeaderHelper.CLASS_NAME,\n\t\t\t\t`${nameof(rel)}.${i.toString()}`,\n\t\t\t\trelationValues[i]\n\t\t\t);\n\t\t\tif (relationValues[i].includes('\"') || relationValues[i].includes(\" \")) {\n\t\t\t\tthrow new GeneralError(HeaderHelper.CLASS_NAME, \"invalidLinkHeaderRel\");\n\t\t\t}\n\t\t}\n\n\t\tif (Is.objectValue(urlQueryParams)) {\n\t\t\tconst queryParamsString = Object.entries(urlQueryParams)\n\t\t\t\t.map(([key, value]) => `${key}=${encodeURIComponent(value)}`)\n\t\t\t\t.join(\"&\");\n\t\t\tconst queryIndex = url.indexOf(\"?\");\n\t\t\tif (queryIndex === -1) {\n\t\t\t\turl += `?${queryParamsString}`;\n\t\t\t} else if (queryIndex === url.length - 1) {\n\t\t\t\turl += queryParamsString;\n\t\t\t} else {\n\t\t\t\turl += `&${queryParamsString}`;\n\t\t\t}\n\t\t}\n\n\t\treturn `<${url}>; rel=\"${relationValues.join(\" \")}\"${\n\t\t\tparams\n\t\t\t\t? Object.entries(params)\n\t\t\t\t\t\t.map(([key, value]) => `; ${key}=\"${value}\"`)\n\t\t\t\t\t\t.join(\"\")\n\t\t\t\t: \"\"\n\t\t}`;\n\t}\n\n\t/**\n\t * Parse a quality-weighted comma-separated header into entries.\n\t * @param header The header value or values.\n\t * @param valueValidator Regex to validate the value portion of each entry.\n\t * @returns Entries ordered by quality descending, or undefined if any entry is invalid.\n\t */\n\tpublic static parseWeightedHeader(\n\t\theader: string | string[] | undefined,\n\t\tvalueValidator: RegExp\n\t): { value: string; quality: number; params: { [key: string]: string } }[] | undefined {\n\t\tlet headerValues: string[] = [];\n\n\t\tif (Is.array(header)) {\n\t\t\theaderValues = header.map(v => v.trim()).filter(v => v.length > 0);\n\t\t} else if (Is.stringValue(header)) {\n\t\t\theaderValues = [header.trim()];\n\t\t}\n\n\t\tif (headerValues.length > 0) {\n\t\t\tconst entries = headerValues\n\t\t\t\t.flatMap(v => v.split(\",\"))\n\t\t\t\t.map(s => s.trim())\n\t\t\t\t.filter(s => s.length > 0);\n\n\t\t\tconst parsed: { value: string; quality: number; params: { [key: string]: string } }[] = [];\n\n\t\t\tfor (const entry of entries) {\n\t\t\t\tconst [valuePart, ...paramParts] = entry.split(\";\").map(p => p.trim());\n\n\t\t\t\tif (!valueValidator.test(valuePart)) {\n\t\t\t\t\treturn undefined;\n\t\t\t\t}\n\n\t\t\t\tlet quality = 1;\n\t\t\t\tconst params: { [key: string]: string } = {};\n\n\t\t\t\tfor (const paramPart of paramParts) {\n\t\t\t\t\tif (paramPart.length > 0) {\n\t\t\t\t\t\tif (paramPart.startsWith(\"q=\") || paramPart.startsWith(\"Q=\")) {\n\t\t\t\t\t\t\tconst qualityMatch = HeaderHelper._QUALITY_REGEX.exec(paramPart);\n\t\t\t\t\t\t\tif (!qualityMatch?.[1]) {\n\t\t\t\t\t\t\t\treturn undefined;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tquality = Number(qualityMatch[1]);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tconst eqIndex = paramPart.indexOf(\"=\");\n\t\t\t\t\t\t\tif (eqIndex > 0) {\n\t\t\t\t\t\t\t\tconst key = paramPart.slice(0, eqIndex).trim().toLowerCase();\n\t\t\t\t\t\t\t\tconst val = paramPart.slice(eqIndex + 1).trim();\n\t\t\t\t\t\t\t\tif (key.length > 0) {\n\t\t\t\t\t\t\t\t\tparams[key] = val;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tparsed.push({ value: valuePart, quality, params });\n\t\t\t}\n\n\t\t\tif (parsed.length > 0) {\n\t\t\t\treturn parsed.sort((a, b) => b.quality - a.quality);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Does the relation selector match any of the link header relations.\n\t * @param relations The relations from the header.\n\t * @param relation The relation selector to test.\n\t * @returns True if the selector matches any relation.\n\t * @internal\n\t */\n\tprivate static matchesLinkHeaderRelation(\n\t\trelations: (HttpLinkRelType | string)[],\n\t\trelation: HttpLinkRelType | string | RegExp\n\t): boolean {\n\t\tif (Is.string(relation)) {\n\t\t\treturn relations.includes(relation);\n\t\t}\n\n\t\treturn relations.some(relValue => relation.test(relValue));\n\t}\n\n\t/**\n\t * Normalize a relation string into tokens.\n\t * @param relation The relation string.\n\t * @returns The relation tokens.\n\t * @internal\n\t */\n\tprivate static normalizeLinkHeaderRelations(relation: string): HttpLinkRelType[] {\n\t\treturn relation\n\t\t\t.split(/\\s+/)\n\t\t\t.map(relValue => relValue.trim())\n\t\t\t.filter(relValue => !Is.empty(relValue)) as HttpLinkRelType[];\n\t}\n\n\t/**\n\t * Get all non-empty values from a header that may be a string or string array.\n\t * @param header The header value (string, string array, or undefined).\n\t * @returns The trimmed non-empty string values.\n\t * @internal\n\t */\n\tprivate static getHeaderValues(header: string | string[] | undefined): string[] {\n\t\tlet headerValues: string[] = [];\n\n\t\tif (Is.array(header)) {\n\t\t\theaderValues = header;\n\t\t} else if (Is.stringValue(header)) {\n\t\t\theaderValues = [header];\n\t\t}\n\n\t\treturn headerValues\n\t\t\t.map(headerValue => headerValue.trim())\n\t\t\t.filter(headerValue => headerValue.length > 0);\n\t}\n}\n"]}
1
+ {"version":3,"file":"headerHelper.js","sourceRoot":"","sources":["../../../src/utils/headerHelper.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport { ArrayHelper, GeneralError, Guards, Is } from \"@twin.org/core\";\nimport { nameof } from \"@twin.org/nameof\";\nimport { HeaderTypes } from \"../models/headerTypes.js\";\nimport type { HttpLinkRelType } from \"../models/httpLinkRelType.js\";\nimport type { IHttpHeaders } from \"../models/IHttpHeaders.js\";\nimport type { IHttpLinkHeader } from \"../models/IHttpLinkHeader.js\";\n\n/**\n * Class to helper with header operations.\n */\nexport class HeaderHelper {\n\t/**\n\t * Runtime name for the class.\n\t */\n\tpublic static readonly CLASS_NAME: string = nameof<HeaderHelper>();\n\n\t/**\n\t * Regex for valid correlation ID (alphanumeric, dash, underscore).\n\t * Examples: `request_123`, `trace-id-456`, `ABC_789`.\n\t * @internal\n\t */\n\tprivate static readonly _CORRELATION_ID_REGEX = /^[\\w-]+$/;\n\n\t/**\n\t * Regex for valid Accept-Language tags and wildcard values.\n\t * Supports wildcard entries and common BCP 47 style tags.\n\t * Examples: `*`, `en`, `en-GB`, `es-419`, `zh-Hant`, `zh-Hant-TW`.\n\t * @internal\n\t */\n\tprivate static readonly _ACCEPT_LANGUAGE_TAG_REGEX = /^(\\*|[A-Za-z]{1,8}(?:-[\\dA-Za-z]{1,8})*)$/;\n\n\t/**\n\t * Regex for valid quality parameters in negotiation headers.\n\t * Supports quality values from `0` to `1` with up to three decimal places.\n\t * Examples: `q=1`, `q=0.9`, `q=0.875`, `q=0`, `q=1.0`.\n\t * @internal\n\t */\n\tprivate static readonly _QUALITY_REGEX = /^q=(0(?:\\.\\d{1,3})?|1(?:\\.0{1,3})?)$/i;\n\n\t/**\n\t * Regex for valid media type values in Accept headers.\n\t * Supports wildcards, standard types, and vendor extensions.\n\t * Examples: `text/html`, `application/json`, `image/*`, `application/vnd.api+json`.\n\t * @internal\n\t */\n\tprivate static readonly _ACCEPT_MEDIA_TYPE_REGEX =\n\t\t/^(\\*|[A-Za-z0-9][\\w.+-]*)\\/(\\*|[A-Za-z0-9][\\w.+-]*)$/;\n\n\t/**\n\t * Regex for valid IPv4 addresses.\n\t * Examples: `127.0.0.1`, `192.168.1.10`, `255.255.255.255`.\n\t * @internal\n\t */\n\tprivate static readonly _IP_V4_REGEX =\n\t\t/^(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(?:\\.(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}$/;\n\n\t/**\n\t * Regex for valid IPv6 addresses.\n\t * Examples: `2001:0db8:85a3:0000:0000:8a2e:0370:7334`, `2001:db8::`, `::1`.\n\t * @internal\n\t */\n\tprivate static readonly _IP_V6_REGEX =\n\t\t/^((?:[\\dA-Fa-f]{1,4}:){7}[\\dA-Fa-f]{1,4}|(?:[\\dA-Fa-f]{1,4}:){1,7}:|:(?::[\\dA-Fa-f]{1,4}){1,7})$/;\n\n\t/**\n\t * Create a bearer token header.\n\t * @param token The token to create the header for.\n\t * @returns The bearer token header.\n\t */\n\tpublic static createBearer(token: unknown): string {\n\t\tif (Is.stringValue(token)) {\n\t\t\tif (token.startsWith(\"Bearer \")) {\n\t\t\t\treturn token;\n\t\t\t}\n\t\t\treturn `Bearer ${token.trim()}`;\n\t\t}\n\t\treturn \"\";\n\t}\n\n\t/**\n\t * Extract the bearer token from a header.\n\t * @param header The header value to extract the token from.\n\t * @returns The extracted token if it exists.\n\t */\n\tpublic static extractBearer(header: unknown): string {\n\t\tif (Is.stringValue(header) && header.startsWith(\"Bearer \")) {\n\t\t\treturn header.slice(7, header.length).trim();\n\t\t}\n\t\treturn \"\";\n\t}\n\n\t/**\n\t * Extract parsed language preferences from the Accept-Language header.\n\t * @param headers The HTTP request headers.\n\t * @returns The parsed language preferences ordered by highest quality first, or undefined if missing or invalid.\n\t */\n\tpublic static extractAcceptLanguage(\n\t\theaders?: IHttpHeaders\n\t): { language: string; quality: number }[] | undefined {\n\t\treturn HeaderHelper.parseAcceptLanguage(headers?.[HeaderTypes.AcceptLanguage]);\n\t}\n\n\t/**\n\t * Parse one or more Accept-Language header values into language preferences.\n\t * @param acceptLanguage The Accept-Language header value or values.\n\t * @returns The parsed language preferences ordered by highest quality first, or undefined if missing or if any entry is invalid.\n\t */\n\tpublic static parseAcceptLanguage(\n\t\tacceptLanguage: string | string[] | undefined\n\t): { language: string; quality: number }[] | undefined {\n\t\tconst parsed = HeaderHelper.parseWeightedHeader(\n\t\t\tacceptLanguage,\n\t\t\tHeaderHelper._ACCEPT_LANGUAGE_TAG_REGEX\n\t\t);\n\t\treturn parsed?.map(({ value, quality }) => ({ language: value, quality }));\n\t}\n\n\t/**\n\t * Extract parsed media type preferences from the Accept header.\n\t * @param headers The HTTP request headers.\n\t * @returns The parsed media type preferences ordered by highest quality first, or undefined if missing or invalid.\n\t */\n\tpublic static extractAccept(\n\t\theaders?: IHttpHeaders\n\t): { mimeType: string; quality: number; params?: { [key: string]: string } }[] | undefined {\n\t\treturn HeaderHelper.parseAccept(headers?.[HeaderTypes.Accept]);\n\t}\n\n\t/**\n\t * Parse one or more Accept header values into media type preferences.\n\t * @param accept The Accept header value or values.\n\t * @returns The parsed media type preferences ordered by highest quality first, or undefined if missing or if any entry is invalid.\n\t * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Accept\n\t */\n\tpublic static parseAccept(\n\t\taccept: string | string[] | undefined\n\t): { mimeType: string; quality: number; params?: { [key: string]: string } }[] | undefined {\n\t\tconst parsed = HeaderHelper.parseWeightedHeader(accept, HeaderHelper._ACCEPT_MEDIA_TYPE_REGEX);\n\t\treturn parsed?.map(({ value, quality, params }) => ({\n\t\t\tmimeType: value,\n\t\t\tquality,\n\t\t\tparams: Object.keys(params).length > 0 ? params : undefined\n\t\t}));\n\t}\n\n\t/**\n\t * Extract client IP addresses from HTTP request headers.\n\t * Checks all `X-Forwarded-For` and `X-Real-IP` header values for proxied requests.\n\t * @param headers The HTTP request headers.\n\t * @returns The extracted client IP addresses in header order.\n\t */\n\tpublic static extractClientIps(headers?: IHttpHeaders): string[] {\n\t\tconst ips: string[] = [];\n\n\t\tconst forwardedForValues = HeaderHelper.getHeaderValues(headers?.[\"x-forwarded-for\"]);\n\t\tfor (const forwardedFor of forwardedForValues) {\n\t\t\tconst forwardedIps = forwardedFor\n\t\t\t\t.split(\",\")\n\t\t\t\t.map(ip => ip.trim())\n\t\t\t\t.filter(ip => HeaderHelper.isIpAddress(ip));\n\n\t\t\tips.push(...forwardedIps);\n\t\t}\n\n\t\tconst realIpValues = HeaderHelper.getHeaderValues(headers?.[\"x-real-ip\"]);\n\t\tfor (const realIp of realIpValues) {\n\t\t\tif (HeaderHelper.isIpAddress(realIp)) {\n\t\t\t\tips.push(realIp);\n\t\t\t}\n\t\t}\n\n\t\treturn ips;\n\t}\n\n\t/**\n\t * Extract the User-Agent header from the HTTP request context.\n\t * @param headers The HTTP request headers.\n\t * @param maxLength Optional maximum length for the User-Agent string to prevent excessively long values.\n\t * @returns The user agent string or undefined if not available.\n\t */\n\tpublic static extractUserAgent(headers?: IHttpHeaders, maxLength?: number): string | undefined {\n\t\tconst headerValues = HeaderHelper.getHeaderValues(headers?.[HeaderTypes.UserAgent]);\n\t\tfor (const headerValue of headerValues) {\n\t\t\treturn Is.integer(maxLength) ? headerValue.slice(0, maxLength) : headerValue;\n\t\t}\n\t}\n\n\t/**\n\t * Extract a correlation ID for request tracing from the X-Correlation-ID header.\n\t * @param headers The HTTP request headers.\n\t * @param maxLength Optional maximum length for the extracted correlation ID.\n\t * @returns The correlation ID, or undefined if the header is missing or invalid.\n\t */\n\tpublic static extractCorrelationId(\n\t\theaders?: IHttpHeaders,\n\t\tmaxLength?: number\n\t): string | undefined {\n\t\tconst headerValues = HeaderHelper.getHeaderValues(headers?.[\"x-correlation-id\"]);\n\t\tfor (const headerValue of headerValues) {\n\t\t\tif (HeaderHelper._CORRELATION_ID_REGEX.test(headerValue)) {\n\t\t\t\treturn Is.integer(maxLength) ? headerValue.slice(0, maxLength) : headerValue;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Validate if a string is a valid IP address (IPv4 or IPv6).\n\t * @param ip The IP address to validate.\n\t * @returns True if valid, false otherwise.\n\t */\n\tpublic static isIpAddress(ip: string): boolean {\n\t\tif (!Is.stringValue(ip)) {\n\t\t\treturn false;\n\t\t}\n\t\treturn HeaderHelper.isIpAddressV4(ip) || HeaderHelper.isIpAddressV6(ip);\n\t}\n\n\t/**\n\t * Validate if a string is a valid IP address IPv4.\n\t * @param ip The IP address to validate.\n\t * @returns True if valid, false otherwise.\n\t */\n\tpublic static isIpAddressV4(ip: string): boolean {\n\t\tif (!Is.stringValue(ip)) {\n\t\t\treturn false;\n\t\t}\n\t\treturn HeaderHelper._IP_V4_REGEX.test(ip);\n\t}\n\n\t/**\n\t * Validate if a string is a valid IP address IPv6.\n\t * @param ip The IP address to validate.\n\t * @returns True if valid, false otherwise.\n\t */\n\tpublic static isIpAddressV6(ip: string): boolean {\n\t\tif (!Is.stringValue(ip)) {\n\t\t\treturn false;\n\t\t}\n\t\treturn HeaderHelper._IP_V6_REGEX.test(ip);\n\t}\n\n\t/**\n\t * Extract the first occurrence of properties from a Link header for a specific relation type.\n\t * @param linkHeader The Link header value in format `<url>; rel=\"...\"; param1=\"\"; param2=\"\"`.\n\t * @param relation The relation type to extract.\n\t * @returns The extracted URL, rel and optional params or undefined if invalid/missing.\n\t * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Link\n\t */\n\tpublic static extractLinkHeaderRelation(\n\t\tlinkHeader: string | string[] | undefined,\n\t\trelation: HttpLinkRelType | string | RegExp\n\t): IHttpLinkHeader | undefined {\n\t\tconst headers = HeaderHelper.extractLinkHeaders(linkHeader);\n\t\tif (Is.arrayValue(headers)) {\n\t\t\treturn headers.find(h => HeaderHelper.matchesLinkHeaderRelation(h.rel, relation));\n\t\t}\n\t}\n\n\t/**\n\t * Extract multiple properties from a Link header for a specific relation type.\n\t * @param linkHeader The Link header value in format `<url>; rel=\"...\"; param1=\"\"; param2=\"\"`.\n\t * @param relation The relation type to extract.\n\t * @returns The extracted URL, rel and optional params or undefined if invalid/missing.\n\t * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Link\n\t */\n\tpublic static extractLinkHeaderRelations(\n\t\tlinkHeader: string | string[] | undefined,\n\t\trelation: HttpLinkRelType | string | RegExp\n\t): IHttpLinkHeader[] | undefined {\n\t\tconst headers = HeaderHelper.extractLinkHeaders(linkHeader);\n\t\tif (Is.arrayValue(headers)) {\n\t\t\treturn headers.filter(h => HeaderHelper.matchesLinkHeaderRelation(h.rel, relation));\n\t\t}\n\t}\n\n\t/**\n\t * Extract the link headers.\n\t * @param linkHeader The Link header value in format `<url>; rel=\"...\"; param1=\"\"; param2=\"\"`.\n\t * @returns The extracted possible array of URL, rel and optional params or undefined if invalid/missing.\n\t * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Link\n\t */\n\tpublic static extractLinkHeaders(\n\t\tlinkHeader: string | string[] | undefined\n\t): IHttpLinkHeader[] | undefined {\n\t\tconst linkHeaderArray = ArrayHelper.fromObjectOrArray<string>(linkHeader);\n\t\tif (Is.arrayValue<string>(linkHeaderArray)) {\n\t\t\tconst results = [];\n\t\t\tfor (const singleLinkHeader of linkHeaderArray) {\n\t\t\t\tconst segments = HeaderHelper.extractLinkHeaderSegments(singleLinkHeader);\n\t\t\t\tresults.push(\n\t\t\t\t\t...segments.map(l => HeaderHelper.extractLinkHeader(l)).filter(h => !Is.empty(h))\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn results;\n\t\t}\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * Split a combined Link header value into individual link-value segments, comma separated.\n\t * @param linkHeader Raw Link header string.\n\t * @returns Array of individual link-value segments.\n\t * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Link\n\t */\n\tpublic static extractLinkHeaderSegments(linkHeader: string): string[] {\n\t\tif (!Is.stringValue(linkHeader)) {\n\t\t\treturn [];\n\t\t}\n\t\tconst trimmed = linkHeader.trim();\n\t\tif (Is.empty(trimmed)) {\n\t\t\treturn [];\n\t\t}\n\t\treturn trimmed\n\t\t\t.split(/,(?=\\s*<)/)\n\t\t\t.map(s => s.trim())\n\t\t\t.filter(s => !Is.empty(s));\n\t}\n\n\t/**\n\t * Extract the properties from a Link header.\n\t * @param linkHeader The Link header value in format `<url>; rel=\"...\"; param1=\"\"; param2=\"\"`.\n\t * @returns The extracted URL, rel and optional params or undefined if invalid/missing.\n\t * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Link\n\t */\n\tpublic static extractLinkHeader(linkHeader: string): IHttpLinkHeader | undefined {\n\t\tif (!Is.stringValue(linkHeader)) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst parts = linkHeader.split(\";\");\n\n\t\tif (parts.length >= 2) {\n\t\t\tlet url;\n\t\t\tlet urlQueryParams: { [id: string]: string } | undefined;\n\n\t\t\tconst urlMatch = /<([^>]+)>/.exec(parts[0]);\n\t\t\tif (Is.stringValue(urlMatch?.[1])) {\n\t\t\t\turl = urlMatch[1];\n\n\t\t\t\tconst queryIndex = url.indexOf(\"?\");\n\t\t\t\tif (queryIndex !== -1) {\n\t\t\t\t\tconst urlParamsString = url.slice(queryIndex + 1);\n\t\t\t\t\tconst queryParts = urlParamsString.split(\"&\");\n\n\t\t\t\t\tfor (const queryPart of queryParts) {\n\t\t\t\t\t\tconst [key, value] = queryPart.split(\"=\");\n\t\t\t\t\t\tif (Is.stringValue(key) && Is.stringValue(value)) {\n\t\t\t\t\t\t\turlQueryParams ??= {};\n\t\t\t\t\t\t\turlQueryParams[key] = decodeURIComponent(value);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tlet rel: string[] | undefined;\n\t\t\tconst params: { [id: string]: string } = {};\n\n\t\t\tfor (let i = 1; i < parts.length; i++) {\n\t\t\t\tconst relMatch = /rel=\"([^\"]+)\"/.exec(parts[i].trim());\n\t\t\t\tif (relMatch?.[1]) {\n\t\t\t\t\trel = HeaderHelper.normalizeLinkHeaderRelations(relMatch[1]);\n\t\t\t\t} else {\n\t\t\t\t\tconst paramMatch = /([^=]+)=\"([^\"]+)\"/.exec(parts[i].trim());\n\t\t\t\t\tif (paramMatch?.[1] && paramMatch?.[2]) {\n\t\t\t\t\t\tparams[paramMatch[1]] = paramMatch[2];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (Is.stringValue(url) && Is.arrayValue(rel)) {\n\t\t\t\treturn {\n\t\t\t\t\turl,\n\t\t\t\t\turlQueryParams,\n\t\t\t\t\trel,\n\t\t\t\t\tparams: Object.keys(params).length > 0 ? params : undefined\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * Create a compliant Link header.\n\t * @param url The URL to include in the Link header.\n\t * @param urlQueryParams Optional query parameters to include in the URL.\n\t * @param rel The relation type (e.g., \"next\", \"prev\", \"self\").\n\t * @returns The formatted Link header string.\n\t * @throws GeneralError if the URL or rel are invalid.\n\t * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Link\n\t */\n\tpublic static createLinkHeader(\n\t\turl: string,\n\t\turlQueryParams: { [id: string]: string } | undefined,\n\t\trel: HttpLinkRelType | HttpLinkRelType[] | string | string[],\n\t\tparams?: { [id: string]: string }\n\t): string {\n\t\tGuards.stringValue(HeaderHelper.CLASS_NAME, nameof(url), url);\n\n\t\tconst relationValues = Is.string(rel)\n\t\t\t? HeaderHelper.normalizeLinkHeaderRelations(rel)\n\t\t\t: ArrayHelper.fromObjectOrArray(rel);\n\n\t\tGuards.arrayValue(HeaderHelper.CLASS_NAME, nameof(rel), relationValues);\n\n\t\tif (url.includes(\">\")) {\n\t\t\tthrow new GeneralError(HeaderHelper.CLASS_NAME, \"invalidLinkHeaderURL\");\n\t\t}\n\n\t\tfor (let i = 0; i < relationValues.length; i++) {\n\t\t\tGuards.stringValue(\n\t\t\t\tHeaderHelper.CLASS_NAME,\n\t\t\t\t`${nameof(rel)}.${i.toString()}`,\n\t\t\t\trelationValues[i]\n\t\t\t);\n\t\t\tif (relationValues[i].includes('\"') || relationValues[i].includes(\" \")) {\n\t\t\t\tthrow new GeneralError(HeaderHelper.CLASS_NAME, \"invalidLinkHeaderRel\");\n\t\t\t}\n\t\t}\n\n\t\tif (Is.objectValue(urlQueryParams)) {\n\t\t\tconst queryParamsString = Object.entries(urlQueryParams)\n\t\t\t\t.map(([key, value]) => `${key}=${encodeURIComponent(value)}`)\n\t\t\t\t.join(\"&\");\n\t\t\tconst queryIndex = url.indexOf(\"?\");\n\t\t\tif (queryIndex === -1) {\n\t\t\t\turl += `?${queryParamsString}`;\n\t\t\t} else if (queryIndex === url.length - 1) {\n\t\t\t\turl += queryParamsString;\n\t\t\t} else {\n\t\t\t\turl += `&${queryParamsString}`;\n\t\t\t}\n\t\t}\n\n\t\treturn `<${url}>; rel=\"${relationValues.join(\" \")}\"${\n\t\t\tparams\n\t\t\t\t? Object.entries(params)\n\t\t\t\t\t\t.map(([key, value]) => `; ${key}=\"${value}\"`)\n\t\t\t\t\t\t.join(\"\")\n\t\t\t\t: \"\"\n\t\t}`;\n\t}\n\n\t/**\n\t * Parse a quality-weighted comma-separated header into entries.\n\t * @param header The header value or values.\n\t * @param valueValidator Regex to validate the value portion of each entry.\n\t * @returns Entries ordered by quality descending, or undefined if any entry is invalid.\n\t */\n\tpublic static parseWeightedHeader(\n\t\theader: string | string[] | undefined,\n\t\tvalueValidator: RegExp\n\t): { value: string; quality: number; params: { [key: string]: string } }[] | undefined {\n\t\tlet headerValues: string[] = [];\n\n\t\tif (Is.array(header)) {\n\t\t\theaderValues = header.map(v => v.trim()).filter(v => v.length > 0);\n\t\t} else if (Is.stringValue(header)) {\n\t\t\theaderValues = [header.trim()];\n\t\t}\n\n\t\tif (headerValues.length > 0) {\n\t\t\tconst entries = headerValues\n\t\t\t\t.flatMap(v => v.split(\",\"))\n\t\t\t\t.map(s => s.trim())\n\t\t\t\t.filter(s => s.length > 0);\n\n\t\t\tconst parsed: { value: string; quality: number; params: { [key: string]: string } }[] = [];\n\n\t\t\tfor (const entry of entries) {\n\t\t\t\tconst [valuePart, ...paramParts] = entry.split(\";\").map(p => p.trim());\n\n\t\t\t\tif (!valueValidator.test(valuePart)) {\n\t\t\t\t\treturn undefined;\n\t\t\t\t}\n\n\t\t\t\tlet quality = 1;\n\t\t\t\tconst params: { [key: string]: string } = {};\n\n\t\t\t\tfor (const paramPart of paramParts) {\n\t\t\t\t\tif (paramPart.length > 0) {\n\t\t\t\t\t\tif (paramPart.startsWith(\"q=\") || paramPart.startsWith(\"Q=\")) {\n\t\t\t\t\t\t\tconst qualityMatch = HeaderHelper._QUALITY_REGEX.exec(paramPart);\n\t\t\t\t\t\t\tif (!qualityMatch?.[1]) {\n\t\t\t\t\t\t\t\treturn undefined;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tquality = Number(qualityMatch[1]);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tconst eqIndex = paramPart.indexOf(\"=\");\n\t\t\t\t\t\t\tif (eqIndex > 0) {\n\t\t\t\t\t\t\t\tconst key = paramPart.slice(0, eqIndex).trim().toLowerCase();\n\t\t\t\t\t\t\t\tconst val = paramPart.slice(eqIndex + 1).trim();\n\t\t\t\t\t\t\t\tif (key.length > 0) {\n\t\t\t\t\t\t\t\t\tparams[key] = val;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tparsed.push({ value: valuePart, quality, params });\n\t\t\t}\n\n\t\t\tif (parsed.length > 0) {\n\t\t\t\treturn parsed.sort((a, b) => b.quality - a.quality);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Does the relation selector match any of the link header relations.\n\t * @param relations The relations from the header.\n\t * @param relation The relation selector to test.\n\t * @returns True if the selector matches any relation.\n\t * @internal\n\t */\n\tprivate static matchesLinkHeaderRelation(\n\t\trelations: (HttpLinkRelType | string)[],\n\t\trelation: HttpLinkRelType | string | RegExp\n\t): boolean {\n\t\tif (Is.string(relation)) {\n\t\t\treturn relations.includes(relation);\n\t\t}\n\n\t\treturn relations.some(relValue => relation.test(relValue));\n\t}\n\n\t/**\n\t * Normalize a relation string into tokens.\n\t * @param relation The relation string.\n\t * @returns The relation tokens.\n\t * @internal\n\t */\n\tprivate static normalizeLinkHeaderRelations(relation: string): HttpLinkRelType[] {\n\t\treturn relation\n\t\t\t.split(/\\s+/)\n\t\t\t.map(relValue => relValue.trim())\n\t\t\t.filter(relValue => !Is.empty(relValue)) as HttpLinkRelType[];\n\t}\n\n\t/**\n\t * Get all non-empty values from a header that may be a string or string array.\n\t * @param header The header value (string, string array, or undefined).\n\t * @returns The trimmed non-empty string values.\n\t * @internal\n\t */\n\tprivate static getHeaderValues(header: string | string[] | undefined): string[] {\n\t\tlet headerValues: string[] = [];\n\n\t\tif (Is.array(header)) {\n\t\t\theaderValues = header;\n\t\t} else if (Is.stringValue(header)) {\n\t\t\theaderValues = [header];\n\t\t}\n\n\t\treturn headerValues\n\t\t\t.map(headerValue => headerValue.trim())\n\t\t\t.filter(headerValue => headerValue.length > 0);\n\t}\n}\n"]}
package/docs/changelog.md CHANGED
@@ -1,5 +1,67 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.9.2](https://github.com/iotaledger/twin-framework/compare/web-v0.9.2...web-v0.9.2) (2026-08-24)
4
+
5
+
6
+ ### Features
7
+
8
+ * release to production ([b24cba1](https://github.com/iotaledger/twin-framework/commit/b24cba1b6a969278d638e632590602ec881e49fb))
9
+ * release to production ([787287d](https://github.com/iotaledger/twin-framework/commit/787287d06ea8319657401589d61fff369310c422))
10
+ * release to production ([53f4843](https://github.com/iotaledger/twin-framework/commit/53f484326b2851d7a506d2620db24c4a65cee7b3))
11
+ * release to production ([56cda4d](https://github.com/iotaledger/twin-framework/commit/56cda4da93e978c5be19ec7cfd421ae2a7fe4147))
12
+ * release to production ([f7c6586](https://github.com/iotaledger/twin-framework/commit/f7c6586f6976b903b647b4c5ac5ad9421e0c9051))
13
+ * release to production ([829d53d](https://github.com/iotaledger/twin-framework/commit/829d53d3953b1e1b40b0243c04cfdfd3842aac7b))
14
+ * release to production ([5cf3a76](https://github.com/iotaledger/twin-framework/commit/5cf3a76a09eff2e6414d0cba846c7c37400a11d6))
15
+ * release to production ([#330](https://github.com/iotaledger/twin-framework/issues/330)) ([d73f565](https://github.com/iotaledger/twin-framework/commit/d73f565588d156d23ef49b2a5718973756f7a696))
16
+ * release to production ([#382](https://github.com/iotaledger/twin-framework/issues/382)) ([bbed01a](https://github.com/iotaledger/twin-framework/commit/bbed01a605ee9724bda77a0f7feab249118c2d90))
17
+ * release to production ([#417](https://github.com/iotaledger/twin-framework/issues/417)) ([59727e7](https://github.com/iotaledger/twin-framework/commit/59727e73903a137310ca48fe469189cf29879cb9))
18
+ * release to production ([#459](https://github.com/iotaledger/twin-framework/issues/459)) ([e26e2d9](https://github.com/iotaledger/twin-framework/commit/e26e2d9a88767364c32494c45232033447b26e22))
19
+
20
+
21
+ ### Miscellaneous Chores
22
+
23
+ * release to production ([63cae24](https://github.com/iotaledger/twin-framework/commit/63cae2401f6c11f93b2a01260b665064e8bd28e0))
24
+
25
+ ## [0.9.2-next.11](https://github.com/iotaledger/twin-framework/compare/web-v0.9.2-next.10...web-v0.9.2-next.11) (2026-08-20)
26
+
27
+
28
+ ### Miscellaneous Chores
29
+
30
+ * **web:** Synchronize repo versions
31
+
32
+
33
+ ### Dependencies
34
+
35
+ * The following workspace dependencies were updated
36
+ * dependencies
37
+ * @twin.org/core bumped from 0.9.2-next.10 to 0.9.2-next.11
38
+ * @twin.org/crypto bumped from 0.9.2-next.10 to 0.9.2-next.11
39
+ * @twin.org/nameof bumped from 0.9.2-next.10 to 0.9.2-next.11
40
+ * devDependencies
41
+ * @twin.org/nameof-transformer bumped from 0.9.2-next.10 to 0.9.2-next.11
42
+ * @twin.org/nameof-vitest-plugin bumped from 0.9.2-next.10 to 0.9.2-next.11
43
+ * @twin.org/validate-locales bumped from 0.9.2-next.10 to 0.9.2-next.11
44
+
45
+ ## [0.9.2-next.10](https://github.com/iotaledger/twin-framework/compare/web-v0.9.2-next.9...web-v0.9.2-next.10) (2026-08-11)
46
+
47
+
48
+ ### Features
49
+
50
+ * timeout return type ([4b40b23](https://github.com/iotaledger/twin-framework/commit/4b40b23a7e6b073c7e96cbccc1d41ba7caed2556))
51
+
52
+
53
+ ### Dependencies
54
+
55
+ * The following workspace dependencies were updated
56
+ * dependencies
57
+ * @twin.org/core bumped from 0.9.2-next.9 to 0.9.2-next.10
58
+ * @twin.org/crypto bumped from 0.9.2-next.9 to 0.9.2-next.10
59
+ * @twin.org/nameof bumped from 0.9.2-next.9 to 0.9.2-next.10
60
+ * devDependencies
61
+ * @twin.org/nameof-transformer bumped from 0.9.2-next.9 to 0.9.2-next.10
62
+ * @twin.org/nameof-vitest-plugin bumped from 0.9.2-next.9 to 0.9.2-next.10
63
+ * @twin.org/validate-locales bumped from 0.9.2-next.9 to 0.9.2-next.10
64
+
3
65
  ## [0.9.2-next.9](https://github.com/iotaledger/twin-framework/compare/web-v0.9.2-next.8...web-v0.9.2-next.9) (2026-08-10)
4
66
 
5
67
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@twin.org/web",
3
- "version": "0.9.2-next.9",
3
+ "version": "0.9.2",
4
4
  "description": "Classes for use with web operations",
5
5
  "repository": {
6
6
  "type": "git",
@@ -14,9 +14,9 @@
14
14
  "node": ">=24.0.0"
15
15
  },
16
16
  "dependencies": {
17
- "@twin.org/core": "0.9.2-next.9",
18
- "@twin.org/crypto": "0.9.2-next.9",
19
- "@twin.org/nameof": "0.9.2-next.9",
17
+ "@twin.org/core": "^0.9.2",
18
+ "@twin.org/crypto": "^0.9.2",
19
+ "@twin.org/nameof": "^0.9.2",
20
20
  "jose": "6.2.8"
21
21
  },
22
22
  "main": "./dist/es/index.js",