@openid4vc/utils 0.3.0-alpha-20251120112059 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -290,10 +290,11 @@ function objectToQueryParams(object) {
290
290
 
291
291
  //#endregion
292
292
  //#region src/validation.ts
293
- const zHttpsUrl = zod.default.string().url().refine((url) => {
293
+ const zHttpsUrl = zod.default.url().refine((url) => {
294
294
  const { allowInsecureUrls } = getGlobalConfig();
295
295
  return allowInsecureUrls ? url.startsWith("http://") || url.startsWith("https://") : url.startsWith("https://");
296
296
  }, { message: "url must be an https:// url" });
297
+ const zDataUrl = zod.default.string().regex(/data:[\w/\-.]+;\w+,.*/, "url must be a data URL");
297
298
  const zInteger = zod.default.number().int();
298
299
  const zHttpMethod = zod.default.enum([
299
300
  "GET",
@@ -420,6 +421,7 @@ exports.parseWithErrorHandling = parseWithErrorHandling;
420
421
  exports.parseWwwAuthenticateHeader = parseWwwAuthenticateHeader;
421
422
  exports.setGlobalConfig = setGlobalConfig;
422
423
  exports.stringToJsonWithErrorHandling = stringToJsonWithErrorHandling;
424
+ exports.zDataUrl = zDataUrl;
423
425
  exports.zHttpMethod = zHttpMethod;
424
426
  exports.zHttpsUrl = zHttpsUrl;
425
427
  exports.zInteger = zInteger;
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["GLOBAL_CONFIG: Oid4vcTsConfig","Buffer","textResponse: string","z","URLSearchParams","URLSearchParams","URL","params: Record<string, string>","z","payload: Record<string, string | string[] | null>","challenges: WwwAuthenticateHeaderChallenge[]","endsWithScheme: string | undefined","entries: string[]","z"],"sources":["../src/array.ts","../src/config.ts","../src/content-type.ts","../src/date.ts","../src/encoding.ts","../src/error/InvalidFetchResponseError.ts","../src/error/JsonParseError.ts","../src/error/ValidationError.ts","../src/error/FetchError.ts","../src/globals.ts","../src/fetcher.ts","../src/object.ts","../src/parse.ts","../src/path.ts","../src/url.ts","../src/validation.ts","../src/www-authenticate.ts","../src/zod-error.ts"],"sourcesContent":["/**\n * Only primitive types allowed\n * Must have not duplicate entries (will always return false in this case)\n */\nexport function arrayEqualsIgnoreOrder<Item extends string | number | boolean>(\n a: Array<Item>,\n b: Array<Item>\n): boolean {\n if (new Set(a).size !== new Set(b).size) return false\n if (a.length !== b.length) return false\n\n return a.every((k) => b.includes(k))\n}\n","export interface Oid4vcTsConfig {\n /**\n * Whether to allow insecure http urls.\n *\n * @default false\n */\n allowInsecureUrls: boolean\n}\n\nlet GLOBAL_CONFIG: Oid4vcTsConfig = {\n allowInsecureUrls: false,\n}\n\nexport function setGlobalConfig(config: Oid4vcTsConfig) {\n GLOBAL_CONFIG = config\n}\n\nexport function getGlobalConfig(): Oid4vcTsConfig {\n return GLOBAL_CONFIG\n}\n","import type { FetchResponse } from './globals'\n\nexport enum ContentType {\n XWwwFormUrlencoded = 'application/x-www-form-urlencoded',\n Json = 'application/json',\n JwkSet = 'application/jwk-set+json',\n OAuthAuthorizationRequestJwt = 'application/oauth-authz-req+jwt',\n Jwt = 'application/jwt',\n Html = 'text/html',\n}\n\nexport function isContentType(contentType: ContentType, value: string) {\n return value.toLowerCase().includes(contentType)\n}\n\nexport function isResponseContentType(contentType: ContentType | ContentType[], response: FetchResponse) {\n const contentTypeArray = Array.isArray(contentType) ? contentType : [contentType]\n\n const header = response.headers.get('Content-Type')\n if (!header) return false\n return contentTypeArray.some((contentTypeEntry) => isContentType(contentTypeEntry, header))\n}\n","/**\n * Get the time in seconds since epoch for a date.\n * If date is not provided the current time will be used.\n */\nexport function dateToSeconds(date?: Date) {\n const milliseconds = date?.getTime() ?? Date.now()\n\n return Math.floor(milliseconds / 1000)\n}\n\nexport function addSecondsToDate(date: Date, seconds: number) {\n return new Date(date.getTime() + seconds * 1000)\n}\n","import { Buffer } from 'buffer'\n\nexport function decodeUtf8String(string: string): Uint8Array {\n return new Uint8Array(Buffer.from(string, 'utf-8'))\n}\n\nexport function encodeToUtf8String(data: Uint8Array) {\n return Buffer.from(data).toString('utf-8')\n}\n\n/**\n * Also supports base64 url\n */\nexport function decodeBase64(base64: string): Uint8Array {\n return new Uint8Array(Buffer.from(base64, 'base64'))\n}\n\nexport function encodeToBase64(data: Uint8Array | string) {\n // To make ts happy. Somehow Uint8Array or string is no bueno\n if (typeof data === 'string') {\n return Buffer.from(data).toString('base64')\n }\n\n return Buffer.from(data).toString('base64')\n}\n\nexport function encodeToBase64Url(data: Uint8Array | string) {\n return base64ToBase64Url(encodeToBase64(data))\n}\n\n/**\n * The 'buffer' npm library does not support base64url.\n */\nfunction base64ToBase64Url(base64: string) {\n return base64.replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, '')\n}\n","import { ContentType, isResponseContentType } from '../content-type'\nimport type { FetchResponse } from '../globals'\n\nexport class InvalidFetchResponseError extends Error {\n public readonly response: FetchResponse\n\n public constructor(\n message: string,\n public readonly textResponse: string,\n response: FetchResponse\n ) {\n // We don't want to put html content in pages. For other content we take the first 1000 characters\n // to prevent ridiculously long errors.\n const textResponseMessage = isResponseContentType(ContentType.Html, response)\n ? undefined\n : textResponse.substring(0, 1000)\n\n super(textResponseMessage ? `${message}\\n${textResponseMessage}` : message)\n\n this.response = response.clone()\n }\n}\n","export class JsonParseError extends Error {\n public constructor(message: string, jsonString: string) {\n super(`${message}\\n${jsonString}`)\n }\n}\n","import z, { type ZodError } from 'zod'\n\nexport class ValidationError extends Error {\n public zodError: ZodError | undefined\n\n constructor(message: string, zodError?: ZodError) {\n super(message)\n\n const formattedError = zodError ? z.prettifyError(zodError) : ''\n this.message = `${message}\\n${formattedError}`\n\n Object.defineProperty(this, 'zodError', {\n value: zodError,\n writable: false,\n enumerable: false,\n })\n }\n}\n","export class FetchError extends Error {\n public readonly cause?: Error\n\n public constructor(message: string, { cause }: { cause?: Error } = {}) {\n super(`${message}\\nCause: ${cause?.message}`)\n this.cause = cause\n }\n}\n","// Theses types are provided by the platform (so @types/node, @types/react-native, DOM)\n\n// biome-ignore lint/style/noRestrictedGlobals: no explanation\nconst _URL = URL\n\n// biome-ignore lint/style/noRestrictedGlobals: no explanation\nconst _URLSearchParams = URLSearchParams\n\n// biome-ignore lint/style/noRestrictedGlobals: no explanation\nexport type Fetch = typeof fetch\n// biome-ignore lint/style/noRestrictedGlobals: no explanation\nexport type FetchResponse = Response\n// biome-ignore lint/style/noRestrictedGlobals: no explanation\nconst _Headers = Headers as typeof globalThis.Headers\nexport type FetchHeaders = globalThis.Headers\nexport type FetchRequestInit = RequestInit\n\nexport { _URLSearchParams as URLSearchParams, _URL as URL, _Headers as Headers }\n","import type z from 'zod'\nimport { ContentType, isResponseContentType } from './content-type'\nimport { FetchError } from './error/FetchError'\nimport { InvalidFetchResponseError } from './error/InvalidFetchResponseError'\nimport { type Fetch, URLSearchParams } from './globals'\n\n/**\n * A type utility which represents the function returned\n * from createZodFetcher\n */\nexport type ZodFetcher = <Schema extends z.ZodTypeAny>(\n schema: Schema,\n expectedContentType: ContentType | ContentType[],\n ...args: Parameters<Fetch>\n) => Promise<{ response: Awaited<ReturnType<Fetch>>; result?: z.ZodSafeParseResult<z.infer<Schema>> }>\n\n/**\n * The default fetcher used by createZodFetcher when no\n * fetcher is provided.\n */\n// biome-ignore lint/style/noRestrictedGlobals: this is the only place where we use the global\nconst defaultFetcher = fetch\n\nexport function createFetcher(fetcher = defaultFetcher): Fetch {\n return (input, init, ...args) => {\n return fetcher(\n input,\n init\n ? {\n ...init,\n // React Native does not seem to handle the toString(). This is hard to catch when running\n // tests in Node.JS where this does work correctly. so we handle it here.\n body: init.body instanceof URLSearchParams ? init.body.toString() : init.body,\n }\n : undefined,\n ...args\n ).catch((error) => {\n throw new FetchError(`Unknown error occurred during fetch to '${input}'`, { cause: error })\n })\n }\n}\n\n/**\n * Creates a `fetchWithZod` function that takes in a schema of\n * the expected response, and the arguments to the fetcher\n * you provided.\n *\n * @example\n *\n * const fetchWithZod = createZodFetcher((url) => {\n * return fetch(url).then((res) => res.json());\n * });\n *\n * const response = await fetchWithZod(\n * z.object({\n * hello: z.string(),\n * }),\n * \"https://example.com\",\n * );\n */\nexport function createZodFetcher(fetcher?: Fetch): ZodFetcher {\n return async (schema, expectedContentType, ...args) => {\n const response = await createFetcher(fetcher)(...args)\n\n const expectedContentTypeArray = Array.isArray(expectedContentType) ? expectedContentType : [expectedContentType]\n\n if (response.ok && !isResponseContentType(expectedContentTypeArray, response)) {\n throw new InvalidFetchResponseError(\n `Expected response to match content type ${expectedContentTypeArray.join(' | ')}, but received '${response.headers.get('Content-Type')}'`,\n await response.clone().text(),\n response\n )\n }\n\n if (isResponseContentType([ContentType.OAuthAuthorizationRequestJwt, ContentType.Jwt], response)) {\n return {\n response,\n result: response.ok ? schema.safeParse(await response.text()) : undefined,\n }\n }\n\n return {\n response,\n result: response.ok ? schema.safeParse(await response.json()) : undefined,\n }\n }\n}\n","export function isObject(item: unknown): item is Record<string, unknown> {\n return item != null && typeof item === 'object' && !Array.isArray(item)\n}\n\n/**\n * Deep merge two objects.\n * @param target\n * @param ...sources\n */\nexport function mergeDeep(target: unknown, ...sources: Array<unknown>): unknown {\n if (!sources.length) return target\n const source = sources.shift()\n\n if (isObject(target) && isObject(source)) {\n for (const key in source) {\n if (isObject(source[key])) {\n if (!target[key]) Object.assign(target, { [key]: {} })\n mergeDeep(target[key], source[key])\n } else {\n Object.assign(target, { [key]: source[key] })\n }\n }\n }\n\n return mergeDeep(target, ...sources)\n}\n","import type z from 'zod'\nimport { JsonParseError } from './error/JsonParseError'\nimport { ValidationError } from './error/ValidationError'\n\nexport type BaseSchema = z.ZodTypeAny\n// biome-ignore lint/suspicious/noExplicitAny: no explanation\nexport type InferOutputUnion<T extends readonly any[]> = {\n [K in keyof T]: z.infer<T[K]>\n}[number]\n\nexport function stringToJsonWithErrorHandling(string: string, errorMessage?: string) {\n try {\n return JSON.parse(string)\n } catch (_error) {\n throw new JsonParseError(errorMessage ?? 'Unable to parse string to JSON.', string)\n }\n}\n\nexport function parseIfJson<T>(data: T): T | Record<string, unknown> {\n if (typeof data !== 'string') {\n return data\n }\n\n try {\n // Try to parse the string as JSON\n return JSON.parse(data)\n } catch (_error) {}\n\n return data\n}\n\nexport function parseWithErrorHandling<Schema extends BaseSchema>(\n schema: Schema,\n data: unknown,\n customErrorMessage?: string\n): z.infer<Schema> {\n const parseResult = schema.safeParse(data)\n\n if (!parseResult.success) {\n throw new ValidationError(\n customErrorMessage ?? `Error validating schema with data ${JSON.stringify(data)}`,\n parseResult.error\n )\n }\n\n return parseResult.data\n}\n","/**\n * Combine multiple uri parts into a single uri taking into account slashes.\n *\n * @param parts the parts to combine\n * @returns the combined url\n */\nexport function joinUriParts(base: string, parts: string[]) {\n if (parts.length === 0) return base\n\n // take base without trailing /\n let combined = base.trim()\n combined = base.endsWith('/') ? base.slice(0, base.length - 1) : base\n\n for (const part of parts) {\n // Remove leading and trailing /\n let strippedPart = part.trim()\n strippedPart = strippedPart.startsWith('/') ? strippedPart.slice(1) : strippedPart\n strippedPart = strippedPart.endsWith('/') ? strippedPart.slice(0, strippedPart.length - 1) : strippedPart\n\n // Don't want to add if empty\n if (strippedPart === '') continue\n\n combined += `/${strippedPart}`\n }\n\n return combined\n}\n","import { URL, URLSearchParams } from './globals'\n\nexport function getQueryParams(url: string) {\n const parsedUrl = new URL(url)\n const searchParams = new URLSearchParams(parsedUrl.search)\n const params: Record<string, string> = {}\n\n searchParams.forEach((value, key) => {\n params[key] = value\n })\n\n return params\n}\n\nexport function objectToQueryParams(object: Record<string, unknown>): InstanceType<typeof URLSearchParams> {\n const params = new URLSearchParams()\n\n for (const [key, value] of Object.entries(object)) {\n if (value != null) {\n params.append(key, typeof value === 'object' ? JSON.stringify(value) : String(value))\n }\n }\n\n return params\n}\n","import z from 'zod'\nimport { getGlobalConfig } from './config'\n\nexport const zHttpsUrl = z\n .string()\n .url()\n .refine(\n (url) => {\n const { allowInsecureUrls } = getGlobalConfig()\n return allowInsecureUrls ? url.startsWith('http://') || url.startsWith('https://') : url.startsWith('https://')\n },\n { message: 'url must be an https:// url' }\n )\n\nexport const zInteger = z.number().int()\n\nexport const zHttpMethod = z.enum(['GET', 'POST', 'PUT', 'DELETE', 'HEAD', 'OPTIONS', 'TRACE', 'CONNECT', 'PATCH'])\nexport type HttpMethod = z.infer<typeof zHttpMethod>\n\nexport const zStringToJson = z.string().transform((string, ctx) => {\n try {\n return JSON.parse(string)\n } catch (_error) {\n ctx.addIssue({\n code: 'custom',\n message: 'Expected a JSON string, but could not parse the string to JSON',\n })\n return z.NEVER\n }\n})\n\nexport const zIs = <Schema extends z.ZodSchema>(schema: Schema, data: unknown): data is z.infer<typeof schema> =>\n schema.safeParse(data).success\n","const unquote = (value: string) => value.substring(1, value.length - 1).replace(/\\\\\"/g, '\"')\n// Fixup quoted strings and tokens with spaces around them\nconst sanitize = (value: string) => (value.charAt(0) === '\"' ? unquote(value) : value.trim())\n\n// lol dis\nconst body =\n // biome-ignore lint/suspicious/noControlCharactersInRegex: no explanation\n /((?:[a-zA-Z0-9._~+/-]+=*(?:\\s+|$))|[^\\u0000-\\u001F\\u007F()<>@,;:\\\\\"/?={}[\\]\\u0020\\u0009]+)(?:=([^\\\\\"=\\s,]+|\"(?:[^\"\\\\]|\\\\.)*\"))?/g\n\nexport interface WwwAuthenticateHeaderChallenge {\n scheme: string\n\n /**\n * Record where the keys are the names, and the value can be 0 (null), 1 (string) or multiple (string[])\n * entries\n */\n payload: Record<string, string | string[] | null>\n}\n\nconst parsePayload = (scheme: string, string: string): WwwAuthenticateHeaderChallenge => {\n const payload: Record<string, string | string[] | null> = {}\n\n while (true) {\n const res = body.exec(string)\n if (!res) break\n\n const [, key, newValue] = res\n\n const payloadValue = payload[key]\n if (newValue) {\n const sanitizedValue = sanitize(newValue)\n payload[key] = payloadValue\n ? Array.isArray(payloadValue)\n ? [...payloadValue, sanitizedValue]\n : [payloadValue, sanitizedValue]\n : sanitizedValue\n } else if (!payloadValue) {\n payload[key] = null\n }\n }\n\n return { scheme, payload }\n}\n\nexport function parseWwwAuthenticateHeader(str: string): WwwAuthenticateHeaderChallenge[] {\n const start = str.indexOf(' ')\n let scheme = str.substring(0, start)\n let value = str.substring(start)\n\n const challenges: WwwAuthenticateHeaderChallenge[] = []\n\n // Some well-known schemes to support-multi parsing\n const endsWithSchemeRegex = /, ?(Bearer|DPoP|Basic)$/\n const endsWithSchemeTest = endsWithSchemeRegex.exec(value)\n let endsWithScheme: string | undefined\n if (endsWithSchemeTest) {\n value = value.substring(0, value.length - endsWithSchemeTest[0].length)\n endsWithScheme = endsWithSchemeTest[1]\n }\n\n const additionalSchemesRegex = /(.*?)(, ?)(Bearer|DPoP|Basic)[, ]/\n let match = additionalSchemesRegex.exec(value)\n while (match) {\n challenges.push(parsePayload(scheme, match[1]))\n value = value.substring(match[0].length - 1)\n scheme = match[3]\n\n match = additionalSchemesRegex.exec(value)\n }\n challenges.push(parsePayload(scheme, value))\n if (endsWithScheme) {\n challenges.push({ scheme: endsWithScheme, payload: {} })\n }\n return challenges\n}\n\nexport function encodeWwwAuthenticateHeader(challenges: WwwAuthenticateHeaderChallenge[]) {\n const entries: string[] = []\n\n for (const challenge of challenges) {\n // Encode each parameter according to RFC 7235\n const encodedParams = Object.entries(challenge.payload).flatMap(([key, value]) => {\n const encode = (s: string) => s.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"')\n // Convert value to string and escape special characters\n if (Array.isArray(value)) {\n return value.map((v) => `${key}=\"${encode(v)}\"`)\n }\n\n return value ? `${key}=\"${encode(value)}\"` : key\n })\n\n entries.push(encodedParams.length === 0 ? challenge.scheme : `${challenge.scheme} ${encodedParams.join(', ')}`)\n }\n\n return entries.join(', ')\n}\n","import z from 'zod'\n\nexport function formatZodError(error?: z.ZodError): string {\n if (!error) return ''\n\n return z.prettifyError(error)\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","names":["GLOBAL_CONFIG: Oid4vcTsConfig","Buffer","textResponse: string","z","URLSearchParams","URLSearchParams","URL","params: Record<string, string>","z","payload: Record<string, string | string[] | null>","challenges: WwwAuthenticateHeaderChallenge[]","endsWithScheme: string | undefined","entries: string[]","z"],"sources":["../src/array.ts","../src/config.ts","../src/content-type.ts","../src/date.ts","../src/encoding.ts","../src/error/InvalidFetchResponseError.ts","../src/error/JsonParseError.ts","../src/error/ValidationError.ts","../src/error/FetchError.ts","../src/globals.ts","../src/fetcher.ts","../src/object.ts","../src/parse.ts","../src/path.ts","../src/url.ts","../src/validation.ts","../src/www-authenticate.ts","../src/zod-error.ts"],"sourcesContent":["/**\n * Only primitive types allowed\n * Must have not duplicate entries (will always return false in this case)\n */\nexport function arrayEqualsIgnoreOrder<Item extends string | number | boolean>(\n a: Array<Item>,\n b: Array<Item>\n): boolean {\n if (new Set(a).size !== new Set(b).size) return false\n if (a.length !== b.length) return false\n\n return a.every((k) => b.includes(k))\n}\n","export interface Oid4vcTsConfig {\n /**\n * Whether to allow insecure http urls.\n *\n * @default false\n */\n allowInsecureUrls: boolean\n}\n\nlet GLOBAL_CONFIG: Oid4vcTsConfig = {\n allowInsecureUrls: false,\n}\n\nexport function setGlobalConfig(config: Oid4vcTsConfig) {\n GLOBAL_CONFIG = config\n}\n\nexport function getGlobalConfig(): Oid4vcTsConfig {\n return GLOBAL_CONFIG\n}\n","import type { FetchResponse } from './globals'\n\nexport enum ContentType {\n XWwwFormUrlencoded = 'application/x-www-form-urlencoded',\n Json = 'application/json',\n JwkSet = 'application/jwk-set+json',\n OAuthAuthorizationRequestJwt = 'application/oauth-authz-req+jwt',\n Jwt = 'application/jwt',\n Html = 'text/html',\n}\n\nexport function isContentType(contentType: ContentType, value: string) {\n return value.toLowerCase().includes(contentType)\n}\n\nexport function isResponseContentType(contentType: ContentType | ContentType[], response: FetchResponse) {\n const contentTypeArray = Array.isArray(contentType) ? contentType : [contentType]\n\n const header = response.headers.get('Content-Type')\n if (!header) return false\n return contentTypeArray.some((contentTypeEntry) => isContentType(contentTypeEntry, header))\n}\n","/**\n * Get the time in seconds since epoch for a date.\n * If date is not provided the current time will be used.\n */\nexport function dateToSeconds(date?: Date) {\n const milliseconds = date?.getTime() ?? Date.now()\n\n return Math.floor(milliseconds / 1000)\n}\n\nexport function addSecondsToDate(date: Date, seconds: number) {\n return new Date(date.getTime() + seconds * 1000)\n}\n","import { Buffer } from 'buffer'\n\nexport function decodeUtf8String(string: string): Uint8Array {\n return new Uint8Array(Buffer.from(string, 'utf-8'))\n}\n\nexport function encodeToUtf8String(data: Uint8Array) {\n return Buffer.from(data).toString('utf-8')\n}\n\n/**\n * Also supports base64 url\n */\nexport function decodeBase64(base64: string): Uint8Array {\n return new Uint8Array(Buffer.from(base64, 'base64'))\n}\n\nexport function encodeToBase64(data: Uint8Array | string) {\n // To make ts happy. Somehow Uint8Array or string is no bueno\n if (typeof data === 'string') {\n return Buffer.from(data).toString('base64')\n }\n\n return Buffer.from(data).toString('base64')\n}\n\nexport function encodeToBase64Url(data: Uint8Array | string) {\n return base64ToBase64Url(encodeToBase64(data))\n}\n\n/**\n * The 'buffer' npm library does not support base64url.\n */\nfunction base64ToBase64Url(base64: string) {\n return base64.replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, '')\n}\n","import { ContentType, isResponseContentType } from '../content-type'\nimport type { FetchResponse } from '../globals'\n\nexport class InvalidFetchResponseError extends Error {\n public readonly response: FetchResponse\n\n public constructor(\n message: string,\n public readonly textResponse: string,\n response: FetchResponse\n ) {\n // We don't want to put html content in pages. For other content we take the first 1000 characters\n // to prevent ridiculously long errors.\n const textResponseMessage = isResponseContentType(ContentType.Html, response)\n ? undefined\n : textResponse.substring(0, 1000)\n\n super(textResponseMessage ? `${message}\\n${textResponseMessage}` : message)\n\n this.response = response.clone()\n }\n}\n","export class JsonParseError extends Error {\n public constructor(message: string, jsonString: string) {\n super(`${message}\\n${jsonString}`)\n }\n}\n","import z, { type ZodError } from 'zod'\n\nexport class ValidationError extends Error {\n public zodError: ZodError | undefined\n\n constructor(message: string, zodError?: ZodError) {\n super(message)\n\n const formattedError = zodError ? z.prettifyError(zodError) : ''\n this.message = `${message}\\n${formattedError}`\n\n Object.defineProperty(this, 'zodError', {\n value: zodError,\n writable: false,\n enumerable: false,\n })\n }\n}\n","export class FetchError extends Error {\n public readonly cause?: Error\n\n public constructor(message: string, { cause }: { cause?: Error } = {}) {\n super(`${message}\\nCause: ${cause?.message}`)\n this.cause = cause\n }\n}\n","// Theses types are provided by the platform (so @types/node, @types/react-native, DOM)\n\n// biome-ignore lint/style/noRestrictedGlobals: no explanation\nconst _URL = URL\n\n// biome-ignore lint/style/noRestrictedGlobals: no explanation\nconst _URLSearchParams = URLSearchParams\n\n// biome-ignore lint/style/noRestrictedGlobals: no explanation\nexport type Fetch = typeof fetch\n// biome-ignore lint/style/noRestrictedGlobals: no explanation\nexport type FetchResponse = Response\n// biome-ignore lint/style/noRestrictedGlobals: no explanation\nconst _Headers = Headers as typeof globalThis.Headers\nexport type FetchHeaders = globalThis.Headers\nexport type FetchRequestInit = RequestInit\n\nexport { _URLSearchParams as URLSearchParams, _URL as URL, _Headers as Headers }\n","import type z from 'zod'\nimport { ContentType, isResponseContentType } from './content-type'\nimport { FetchError } from './error/FetchError'\nimport { InvalidFetchResponseError } from './error/InvalidFetchResponseError'\nimport { type Fetch, URLSearchParams } from './globals'\n\n/**\n * A type utility which represents the function returned\n * from createZodFetcher\n */\nexport type ZodFetcher = <Schema extends z.ZodTypeAny>(\n schema: Schema,\n expectedContentType: ContentType | ContentType[],\n ...args: Parameters<Fetch>\n) => Promise<{ response: Awaited<ReturnType<Fetch>>; result?: z.ZodSafeParseResult<z.infer<Schema>> }>\n\n/**\n * The default fetcher used by createZodFetcher when no\n * fetcher is provided.\n */\n// biome-ignore lint/style/noRestrictedGlobals: this is the only place where we use the global\nconst defaultFetcher = fetch\n\nexport function createFetcher(fetcher = defaultFetcher): Fetch {\n return (input, init, ...args) => {\n return fetcher(\n input,\n init\n ? {\n ...init,\n // React Native does not seem to handle the toString(). This is hard to catch when running\n // tests in Node.JS where this does work correctly. so we handle it here.\n body: init.body instanceof URLSearchParams ? init.body.toString() : init.body,\n }\n : undefined,\n ...args\n ).catch((error) => {\n throw new FetchError(`Unknown error occurred during fetch to '${input}'`, { cause: error })\n })\n }\n}\n\n/**\n * Creates a `fetchWithZod` function that takes in a schema of\n * the expected response, and the arguments to the fetcher\n * you provided.\n *\n * @example\n *\n * const fetchWithZod = createZodFetcher((url) => {\n * return fetch(url).then((res) => res.json());\n * });\n *\n * const response = await fetchWithZod(\n * z.object({\n * hello: z.string(),\n * }),\n * \"https://example.com\",\n * );\n */\nexport function createZodFetcher(fetcher?: Fetch): ZodFetcher {\n return async (schema, expectedContentType, ...args) => {\n const response = await createFetcher(fetcher)(...args)\n\n const expectedContentTypeArray = Array.isArray(expectedContentType) ? expectedContentType : [expectedContentType]\n\n if (response.ok && !isResponseContentType(expectedContentTypeArray, response)) {\n throw new InvalidFetchResponseError(\n `Expected response to match content type ${expectedContentTypeArray.join(' | ')}, but received '${response.headers.get('Content-Type')}'`,\n await response.clone().text(),\n response\n )\n }\n\n if (isResponseContentType([ContentType.OAuthAuthorizationRequestJwt, ContentType.Jwt], response)) {\n return {\n response,\n result: response.ok ? schema.safeParse(await response.text()) : undefined,\n }\n }\n\n return {\n response,\n result: response.ok ? schema.safeParse(await response.json()) : undefined,\n }\n }\n}\n","export function isObject(item: unknown): item is Record<string, unknown> {\n return item != null && typeof item === 'object' && !Array.isArray(item)\n}\n\n/**\n * Deep merge two objects.\n * @param target\n * @param ...sources\n */\nexport function mergeDeep(target: unknown, ...sources: Array<unknown>): unknown {\n if (!sources.length) return target\n const source = sources.shift()\n\n if (isObject(target) && isObject(source)) {\n for (const key in source) {\n if (isObject(source[key])) {\n if (!target[key]) Object.assign(target, { [key]: {} })\n mergeDeep(target[key], source[key])\n } else {\n Object.assign(target, { [key]: source[key] })\n }\n }\n }\n\n return mergeDeep(target, ...sources)\n}\n","import type z from 'zod'\nimport { JsonParseError } from './error/JsonParseError'\nimport { ValidationError } from './error/ValidationError'\n\nexport type BaseSchema = z.ZodTypeAny\n// biome-ignore lint/suspicious/noExplicitAny: no explanation\nexport type InferOutputUnion<T extends readonly any[]> = {\n [K in keyof T]: z.infer<T[K]>\n}[number]\n\nexport function stringToJsonWithErrorHandling(string: string, errorMessage?: string) {\n try {\n return JSON.parse(string)\n } catch (_error) {\n throw new JsonParseError(errorMessage ?? 'Unable to parse string to JSON.', string)\n }\n}\n\nexport function parseIfJson<T>(data: T): T | Record<string, unknown> {\n if (typeof data !== 'string') {\n return data\n }\n\n try {\n // Try to parse the string as JSON\n return JSON.parse(data)\n } catch (_error) {}\n\n return data\n}\n\nexport function parseWithErrorHandling<Schema extends BaseSchema>(\n schema: Schema,\n data: unknown,\n customErrorMessage?: string\n): z.infer<Schema> {\n const parseResult = schema.safeParse(data)\n\n if (!parseResult.success) {\n throw new ValidationError(\n customErrorMessage ?? `Error validating schema with data ${JSON.stringify(data)}`,\n parseResult.error\n )\n }\n\n return parseResult.data\n}\n","/**\n * Combine multiple uri parts into a single uri taking into account slashes.\n *\n * @param parts the parts to combine\n * @returns the combined url\n */\nexport function joinUriParts(base: string, parts: string[]) {\n if (parts.length === 0) return base\n\n // take base without trailing /\n let combined = base.trim()\n combined = base.endsWith('/') ? base.slice(0, base.length - 1) : base\n\n for (const part of parts) {\n // Remove leading and trailing /\n let strippedPart = part.trim()\n strippedPart = strippedPart.startsWith('/') ? strippedPart.slice(1) : strippedPart\n strippedPart = strippedPart.endsWith('/') ? strippedPart.slice(0, strippedPart.length - 1) : strippedPart\n\n // Don't want to add if empty\n if (strippedPart === '') continue\n\n combined += `/${strippedPart}`\n }\n\n return combined\n}\n","import { URL, URLSearchParams } from './globals'\n\nexport function getQueryParams(url: string) {\n const parsedUrl = new URL(url)\n const searchParams = new URLSearchParams(parsedUrl.search)\n const params: Record<string, string> = {}\n\n searchParams.forEach((value, key) => {\n params[key] = value\n })\n\n return params\n}\n\nexport function objectToQueryParams(object: Record<string, unknown>): InstanceType<typeof URLSearchParams> {\n const params = new URLSearchParams()\n\n for (const [key, value] of Object.entries(object)) {\n if (value != null) {\n params.append(key, typeof value === 'object' ? JSON.stringify(value) : String(value))\n }\n }\n\n return params\n}\n","import z from 'zod'\nimport { getGlobalConfig } from './config'\n\nexport const zHttpsUrl = z.url().refine(\n (url) => {\n const { allowInsecureUrls } = getGlobalConfig()\n return allowInsecureUrls ? url.startsWith('http://') || url.startsWith('https://') : url.startsWith('https://')\n },\n { message: 'url must be an https:// url' }\n)\n\nexport const zDataUrl = z.string().regex(/data:[\\w/\\-.]+;\\w+,.*/, 'url must be a data URL')\n\nexport const zInteger = z.number().int()\n\nexport const zHttpMethod = z.enum(['GET', 'POST', 'PUT', 'DELETE', 'HEAD', 'OPTIONS', 'TRACE', 'CONNECT', 'PATCH'])\nexport type HttpMethod = z.infer<typeof zHttpMethod>\n\nexport const zStringToJson = z.string().transform((string, ctx) => {\n try {\n return JSON.parse(string)\n } catch (_error) {\n ctx.addIssue({\n code: 'custom',\n message: 'Expected a JSON string, but could not parse the string to JSON',\n })\n return z.NEVER\n }\n})\n\nexport const zIs = <Schema extends z.ZodSchema>(schema: Schema, data: unknown): data is z.infer<typeof schema> =>\n schema.safeParse(data).success\n","const unquote = (value: string) => value.substring(1, value.length - 1).replace(/\\\\\"/g, '\"')\n// Fixup quoted strings and tokens with spaces around them\nconst sanitize = (value: string) => (value.charAt(0) === '\"' ? unquote(value) : value.trim())\n\n// lol dis\nconst body =\n // biome-ignore lint/suspicious/noControlCharactersInRegex: no explanation\n /((?:[a-zA-Z0-9._~+/-]+=*(?:\\s+|$))|[^\\u0000-\\u001F\\u007F()<>@,;:\\\\\"/?={}[\\]\\u0020\\u0009]+)(?:=([^\\\\\"=\\s,]+|\"(?:[^\"\\\\]|\\\\.)*\"))?/g\n\nexport interface WwwAuthenticateHeaderChallenge {\n scheme: string\n\n /**\n * Record where the keys are the names, and the value can be 0 (null), 1 (string) or multiple (string[])\n * entries\n */\n payload: Record<string, string | string[] | null>\n}\n\nconst parsePayload = (scheme: string, string: string): WwwAuthenticateHeaderChallenge => {\n const payload: Record<string, string | string[] | null> = {}\n\n while (true) {\n const res = body.exec(string)\n if (!res) break\n\n const [, key, newValue] = res\n\n const payloadValue = payload[key]\n if (newValue) {\n const sanitizedValue = sanitize(newValue)\n payload[key] = payloadValue\n ? Array.isArray(payloadValue)\n ? [...payloadValue, sanitizedValue]\n : [payloadValue, sanitizedValue]\n : sanitizedValue\n } else if (!payloadValue) {\n payload[key] = null\n }\n }\n\n return { scheme, payload }\n}\n\nexport function parseWwwAuthenticateHeader(str: string): WwwAuthenticateHeaderChallenge[] {\n const start = str.indexOf(' ')\n let scheme = str.substring(0, start)\n let value = str.substring(start)\n\n const challenges: WwwAuthenticateHeaderChallenge[] = []\n\n // Some well-known schemes to support-multi parsing\n const endsWithSchemeRegex = /, ?(Bearer|DPoP|Basic)$/\n const endsWithSchemeTest = endsWithSchemeRegex.exec(value)\n let endsWithScheme: string | undefined\n if (endsWithSchemeTest) {\n value = value.substring(0, value.length - endsWithSchemeTest[0].length)\n endsWithScheme = endsWithSchemeTest[1]\n }\n\n const additionalSchemesRegex = /(.*?)(, ?)(Bearer|DPoP|Basic)[, ]/\n let match = additionalSchemesRegex.exec(value)\n while (match) {\n challenges.push(parsePayload(scheme, match[1]))\n value = value.substring(match[0].length - 1)\n scheme = match[3]\n\n match = additionalSchemesRegex.exec(value)\n }\n challenges.push(parsePayload(scheme, value))\n if (endsWithScheme) {\n challenges.push({ scheme: endsWithScheme, payload: {} })\n }\n return challenges\n}\n\nexport function encodeWwwAuthenticateHeader(challenges: WwwAuthenticateHeaderChallenge[]) {\n const entries: string[] = []\n\n for (const challenge of challenges) {\n // Encode each parameter according to RFC 7235\n const encodedParams = Object.entries(challenge.payload).flatMap(([key, value]) => {\n const encode = (s: string) => s.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"')\n // Convert value to string and escape special characters\n if (Array.isArray(value)) {\n return value.map((v) => `${key}=\"${encode(v)}\"`)\n }\n\n return value ? `${key}=\"${encode(value)}\"` : key\n })\n\n entries.push(encodedParams.length === 0 ? challenge.scheme : `${challenge.scheme} ${encodedParams.join(', ')}`)\n }\n\n return entries.join(', ')\n}\n","import z from 'zod'\n\nexport function formatZodError(error?: z.ZodError): string {\n if (!error) return ''\n\n return z.prettifyError(error)\n}\n"],"mappings":"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"}
package/dist/index.d.cts CHANGED
@@ -154,7 +154,8 @@ declare function getQueryParams(url: string): Record<string, string>;
154
154
  declare function objectToQueryParams(object: Record<string, unknown>): InstanceType<typeof _URLSearchParams>;
155
155
  //#endregion
156
156
  //#region src/validation.d.ts
157
- declare const zHttpsUrl: z.ZodString;
157
+ declare const zHttpsUrl: z.ZodURL;
158
+ declare const zDataUrl: z.ZodString;
158
159
  declare const zInteger: z.ZodNumber;
159
160
  declare const zHttpMethod: z.ZodEnum<{
160
161
  GET: "GET";
@@ -186,5 +187,5 @@ declare function encodeWwwAuthenticateHeader(challenges: WwwAuthenticateHeaderCh
186
187
  //#region src/zod-error.d.ts
187
188
  declare function formatZodError(error?: z.ZodError): string;
188
189
  //#endregion
189
- export { type BaseSchema, ContentType, type Fetch, type FetchHeaders, type FetchRequestInit, type FetchResponse, _Headers as Headers, type HttpMethod, type InferOutputUnion, InvalidFetchResponseError, JsonParseError, type NonEmptyArray, type Oid4vcTsConfig, type Optional, type OrPromise, type Simplify, type StringWithAutoCompletion, _URL as URL, _URLSearchParams as URLSearchParams, ValidationError, type WwwAuthenticateHeaderChallenge, type ZodFetcher, addSecondsToDate, arrayEqualsIgnoreOrder, createFetcher, createZodFetcher, dateToSeconds, decodeBase64, decodeUtf8String, encodeToBase64, encodeToBase64Url, encodeToUtf8String, encodeWwwAuthenticateHeader, formatZodError, getGlobalConfig, getQueryParams, isContentType, isObject, isResponseContentType, joinUriParts, mergeDeep, objectToQueryParams, parseIfJson, parseWithErrorHandling, parseWwwAuthenticateHeader, setGlobalConfig, stringToJsonWithErrorHandling, zHttpMethod, zHttpsUrl, zInteger, zIs, zStringToJson };
190
+ export { type BaseSchema, ContentType, type Fetch, type FetchHeaders, type FetchRequestInit, type FetchResponse, _Headers as Headers, type HttpMethod, type InferOutputUnion, InvalidFetchResponseError, JsonParseError, type NonEmptyArray, type Oid4vcTsConfig, type Optional, type OrPromise, type Simplify, type StringWithAutoCompletion, _URL as URL, _URLSearchParams as URLSearchParams, ValidationError, type WwwAuthenticateHeaderChallenge, type ZodFetcher, addSecondsToDate, arrayEqualsIgnoreOrder, createFetcher, createZodFetcher, dateToSeconds, decodeBase64, decodeUtf8String, encodeToBase64, encodeToBase64Url, encodeToUtf8String, encodeWwwAuthenticateHeader, formatZodError, getGlobalConfig, getQueryParams, isContentType, isObject, isResponseContentType, joinUriParts, mergeDeep, objectToQueryParams, parseIfJson, parseWithErrorHandling, parseWwwAuthenticateHeader, setGlobalConfig, stringToJsonWithErrorHandling, zDataUrl, zHttpMethod, zHttpsUrl, zInteger, zIs, zStringToJson };
190
191
  //# sourceMappingURL=index.d.cts.map
package/dist/index.d.mts CHANGED
@@ -154,7 +154,8 @@ declare function getQueryParams(url: string): Record<string, string>;
154
154
  declare function objectToQueryParams(object: Record<string, unknown>): InstanceType<typeof _URLSearchParams>;
155
155
  //#endregion
156
156
  //#region src/validation.d.ts
157
- declare const zHttpsUrl: z.ZodString;
157
+ declare const zHttpsUrl: z.ZodURL;
158
+ declare const zDataUrl: z.ZodString;
158
159
  declare const zInteger: z.ZodNumber;
159
160
  declare const zHttpMethod: z.ZodEnum<{
160
161
  GET: "GET";
@@ -186,5 +187,5 @@ declare function encodeWwwAuthenticateHeader(challenges: WwwAuthenticateHeaderCh
186
187
  //#region src/zod-error.d.ts
187
188
  declare function formatZodError(error?: z.ZodError): string;
188
189
  //#endregion
189
- export { type BaseSchema, ContentType, type Fetch, type FetchHeaders, type FetchRequestInit, type FetchResponse, _Headers as Headers, type HttpMethod, type InferOutputUnion, InvalidFetchResponseError, JsonParseError, type NonEmptyArray, type Oid4vcTsConfig, type Optional, type OrPromise, type Simplify, type StringWithAutoCompletion, _URL as URL, _URLSearchParams as URLSearchParams, ValidationError, type WwwAuthenticateHeaderChallenge, type ZodFetcher, addSecondsToDate, arrayEqualsIgnoreOrder, createFetcher, createZodFetcher, dateToSeconds, decodeBase64, decodeUtf8String, encodeToBase64, encodeToBase64Url, encodeToUtf8String, encodeWwwAuthenticateHeader, formatZodError, getGlobalConfig, getQueryParams, isContentType, isObject, isResponseContentType, joinUriParts, mergeDeep, objectToQueryParams, parseIfJson, parseWithErrorHandling, parseWwwAuthenticateHeader, setGlobalConfig, stringToJsonWithErrorHandling, zHttpMethod, zHttpsUrl, zInteger, zIs, zStringToJson };
190
+ export { type BaseSchema, ContentType, type Fetch, type FetchHeaders, type FetchRequestInit, type FetchResponse, _Headers as Headers, type HttpMethod, type InferOutputUnion, InvalidFetchResponseError, JsonParseError, type NonEmptyArray, type Oid4vcTsConfig, type Optional, type OrPromise, type Simplify, type StringWithAutoCompletion, _URL as URL, _URLSearchParams as URLSearchParams, ValidationError, type WwwAuthenticateHeaderChallenge, type ZodFetcher, addSecondsToDate, arrayEqualsIgnoreOrder, createFetcher, createZodFetcher, dateToSeconds, decodeBase64, decodeUtf8String, encodeToBase64, encodeToBase64Url, encodeToUtf8String, encodeWwwAuthenticateHeader, formatZodError, getGlobalConfig, getQueryParams, isContentType, isObject, isResponseContentType, joinUriParts, mergeDeep, objectToQueryParams, parseIfJson, parseWithErrorHandling, parseWwwAuthenticateHeader, setGlobalConfig, stringToJsonWithErrorHandling, zDataUrl, zHttpMethod, zHttpsUrl, zInteger, zIs, zStringToJson };
190
191
  //# sourceMappingURL=index.d.mts.map
package/dist/index.mjs CHANGED
@@ -266,10 +266,11 @@ function objectToQueryParams(object) {
266
266
 
267
267
  //#endregion
268
268
  //#region src/validation.ts
269
- const zHttpsUrl = z.string().url().refine((url) => {
269
+ const zHttpsUrl = z.url().refine((url) => {
270
270
  const { allowInsecureUrls } = getGlobalConfig();
271
271
  return allowInsecureUrls ? url.startsWith("http://") || url.startsWith("https://") : url.startsWith("https://");
272
272
  }, { message: "url must be an https:// url" });
273
+ const zDataUrl = z.string().regex(/data:[\w/\-.]+;\w+,.*/, "url must be a data URL");
273
274
  const zInteger = z.number().int();
274
275
  const zHttpMethod = z.enum([
275
276
  "GET",
@@ -364,5 +365,5 @@ function formatZodError(error) {
364
365
  }
365
366
 
366
367
  //#endregion
367
- export { ContentType, _Headers as Headers, InvalidFetchResponseError, JsonParseError, _URL as URL, _URLSearchParams as URLSearchParams, ValidationError, addSecondsToDate, arrayEqualsIgnoreOrder, createFetcher, createZodFetcher, dateToSeconds, decodeBase64, decodeUtf8String, encodeToBase64, encodeToBase64Url, encodeToUtf8String, encodeWwwAuthenticateHeader, formatZodError, getGlobalConfig, getQueryParams, isContentType, isObject, isResponseContentType, joinUriParts, mergeDeep, objectToQueryParams, parseIfJson, parseWithErrorHandling, parseWwwAuthenticateHeader, setGlobalConfig, stringToJsonWithErrorHandling, zHttpMethod, zHttpsUrl, zInteger, zIs, zStringToJson };
368
+ export { ContentType, _Headers as Headers, InvalidFetchResponseError, JsonParseError, _URL as URL, _URLSearchParams as URLSearchParams, ValidationError, addSecondsToDate, arrayEqualsIgnoreOrder, createFetcher, createZodFetcher, dateToSeconds, decodeBase64, decodeUtf8String, encodeToBase64, encodeToBase64Url, encodeToUtf8String, encodeWwwAuthenticateHeader, formatZodError, getGlobalConfig, getQueryParams, isContentType, isObject, isResponseContentType, joinUriParts, mergeDeep, objectToQueryParams, parseIfJson, parseWithErrorHandling, parseWwwAuthenticateHeader, setGlobalConfig, stringToJsonWithErrorHandling, zDataUrl, zHttpMethod, zHttpsUrl, zInteger, zIs, zStringToJson };
368
369
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["GLOBAL_CONFIG: Oid4vcTsConfig","textResponse: string","URLSearchParams","URLSearchParams","URL","params: Record<string, string>","payload: Record<string, string | string[] | null>","challenges: WwwAuthenticateHeaderChallenge[]","endsWithScheme: string | undefined","entries: string[]"],"sources":["../src/array.ts","../src/config.ts","../src/content-type.ts","../src/date.ts","../src/encoding.ts","../src/error/InvalidFetchResponseError.ts","../src/error/JsonParseError.ts","../src/error/ValidationError.ts","../src/error/FetchError.ts","../src/globals.ts","../src/fetcher.ts","../src/object.ts","../src/parse.ts","../src/path.ts","../src/url.ts","../src/validation.ts","../src/www-authenticate.ts","../src/zod-error.ts"],"sourcesContent":["/**\n * Only primitive types allowed\n * Must have not duplicate entries (will always return false in this case)\n */\nexport function arrayEqualsIgnoreOrder<Item extends string | number | boolean>(\n a: Array<Item>,\n b: Array<Item>\n): boolean {\n if (new Set(a).size !== new Set(b).size) return false\n if (a.length !== b.length) return false\n\n return a.every((k) => b.includes(k))\n}\n","export interface Oid4vcTsConfig {\n /**\n * Whether to allow insecure http urls.\n *\n * @default false\n */\n allowInsecureUrls: boolean\n}\n\nlet GLOBAL_CONFIG: Oid4vcTsConfig = {\n allowInsecureUrls: false,\n}\n\nexport function setGlobalConfig(config: Oid4vcTsConfig) {\n GLOBAL_CONFIG = config\n}\n\nexport function getGlobalConfig(): Oid4vcTsConfig {\n return GLOBAL_CONFIG\n}\n","import type { FetchResponse } from './globals'\n\nexport enum ContentType {\n XWwwFormUrlencoded = 'application/x-www-form-urlencoded',\n Json = 'application/json',\n JwkSet = 'application/jwk-set+json',\n OAuthAuthorizationRequestJwt = 'application/oauth-authz-req+jwt',\n Jwt = 'application/jwt',\n Html = 'text/html',\n}\n\nexport function isContentType(contentType: ContentType, value: string) {\n return value.toLowerCase().includes(contentType)\n}\n\nexport function isResponseContentType(contentType: ContentType | ContentType[], response: FetchResponse) {\n const contentTypeArray = Array.isArray(contentType) ? contentType : [contentType]\n\n const header = response.headers.get('Content-Type')\n if (!header) return false\n return contentTypeArray.some((contentTypeEntry) => isContentType(contentTypeEntry, header))\n}\n","/**\n * Get the time in seconds since epoch for a date.\n * If date is not provided the current time will be used.\n */\nexport function dateToSeconds(date?: Date) {\n const milliseconds = date?.getTime() ?? Date.now()\n\n return Math.floor(milliseconds / 1000)\n}\n\nexport function addSecondsToDate(date: Date, seconds: number) {\n return new Date(date.getTime() + seconds * 1000)\n}\n","import { Buffer } from 'buffer'\n\nexport function decodeUtf8String(string: string): Uint8Array {\n return new Uint8Array(Buffer.from(string, 'utf-8'))\n}\n\nexport function encodeToUtf8String(data: Uint8Array) {\n return Buffer.from(data).toString('utf-8')\n}\n\n/**\n * Also supports base64 url\n */\nexport function decodeBase64(base64: string): Uint8Array {\n return new Uint8Array(Buffer.from(base64, 'base64'))\n}\n\nexport function encodeToBase64(data: Uint8Array | string) {\n // To make ts happy. Somehow Uint8Array or string is no bueno\n if (typeof data === 'string') {\n return Buffer.from(data).toString('base64')\n }\n\n return Buffer.from(data).toString('base64')\n}\n\nexport function encodeToBase64Url(data: Uint8Array | string) {\n return base64ToBase64Url(encodeToBase64(data))\n}\n\n/**\n * The 'buffer' npm library does not support base64url.\n */\nfunction base64ToBase64Url(base64: string) {\n return base64.replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, '')\n}\n","import { ContentType, isResponseContentType } from '../content-type'\nimport type { FetchResponse } from '../globals'\n\nexport class InvalidFetchResponseError extends Error {\n public readonly response: FetchResponse\n\n public constructor(\n message: string,\n public readonly textResponse: string,\n response: FetchResponse\n ) {\n // We don't want to put html content in pages. For other content we take the first 1000 characters\n // to prevent ridiculously long errors.\n const textResponseMessage = isResponseContentType(ContentType.Html, response)\n ? undefined\n : textResponse.substring(0, 1000)\n\n super(textResponseMessage ? `${message}\\n${textResponseMessage}` : message)\n\n this.response = response.clone()\n }\n}\n","export class JsonParseError extends Error {\n public constructor(message: string, jsonString: string) {\n super(`${message}\\n${jsonString}`)\n }\n}\n","import z, { type ZodError } from 'zod'\n\nexport class ValidationError extends Error {\n public zodError: ZodError | undefined\n\n constructor(message: string, zodError?: ZodError) {\n super(message)\n\n const formattedError = zodError ? z.prettifyError(zodError) : ''\n this.message = `${message}\\n${formattedError}`\n\n Object.defineProperty(this, 'zodError', {\n value: zodError,\n writable: false,\n enumerable: false,\n })\n }\n}\n","export class FetchError extends Error {\n public readonly cause?: Error\n\n public constructor(message: string, { cause }: { cause?: Error } = {}) {\n super(`${message}\\nCause: ${cause?.message}`)\n this.cause = cause\n }\n}\n","// Theses types are provided by the platform (so @types/node, @types/react-native, DOM)\n\n// biome-ignore lint/style/noRestrictedGlobals: no explanation\nconst _URL = URL\n\n// biome-ignore lint/style/noRestrictedGlobals: no explanation\nconst _URLSearchParams = URLSearchParams\n\n// biome-ignore lint/style/noRestrictedGlobals: no explanation\nexport type Fetch = typeof fetch\n// biome-ignore lint/style/noRestrictedGlobals: no explanation\nexport type FetchResponse = Response\n// biome-ignore lint/style/noRestrictedGlobals: no explanation\nconst _Headers = Headers as typeof globalThis.Headers\nexport type FetchHeaders = globalThis.Headers\nexport type FetchRequestInit = RequestInit\n\nexport { _URLSearchParams as URLSearchParams, _URL as URL, _Headers as Headers }\n","import type z from 'zod'\nimport { ContentType, isResponseContentType } from './content-type'\nimport { FetchError } from './error/FetchError'\nimport { InvalidFetchResponseError } from './error/InvalidFetchResponseError'\nimport { type Fetch, URLSearchParams } from './globals'\n\n/**\n * A type utility which represents the function returned\n * from createZodFetcher\n */\nexport type ZodFetcher = <Schema extends z.ZodTypeAny>(\n schema: Schema,\n expectedContentType: ContentType | ContentType[],\n ...args: Parameters<Fetch>\n) => Promise<{ response: Awaited<ReturnType<Fetch>>; result?: z.ZodSafeParseResult<z.infer<Schema>> }>\n\n/**\n * The default fetcher used by createZodFetcher when no\n * fetcher is provided.\n */\n// biome-ignore lint/style/noRestrictedGlobals: this is the only place where we use the global\nconst defaultFetcher = fetch\n\nexport function createFetcher(fetcher = defaultFetcher): Fetch {\n return (input, init, ...args) => {\n return fetcher(\n input,\n init\n ? {\n ...init,\n // React Native does not seem to handle the toString(). This is hard to catch when running\n // tests in Node.JS where this does work correctly. so we handle it here.\n body: init.body instanceof URLSearchParams ? init.body.toString() : init.body,\n }\n : undefined,\n ...args\n ).catch((error) => {\n throw new FetchError(`Unknown error occurred during fetch to '${input}'`, { cause: error })\n })\n }\n}\n\n/**\n * Creates a `fetchWithZod` function that takes in a schema of\n * the expected response, and the arguments to the fetcher\n * you provided.\n *\n * @example\n *\n * const fetchWithZod = createZodFetcher((url) => {\n * return fetch(url).then((res) => res.json());\n * });\n *\n * const response = await fetchWithZod(\n * z.object({\n * hello: z.string(),\n * }),\n * \"https://example.com\",\n * );\n */\nexport function createZodFetcher(fetcher?: Fetch): ZodFetcher {\n return async (schema, expectedContentType, ...args) => {\n const response = await createFetcher(fetcher)(...args)\n\n const expectedContentTypeArray = Array.isArray(expectedContentType) ? expectedContentType : [expectedContentType]\n\n if (response.ok && !isResponseContentType(expectedContentTypeArray, response)) {\n throw new InvalidFetchResponseError(\n `Expected response to match content type ${expectedContentTypeArray.join(' | ')}, but received '${response.headers.get('Content-Type')}'`,\n await response.clone().text(),\n response\n )\n }\n\n if (isResponseContentType([ContentType.OAuthAuthorizationRequestJwt, ContentType.Jwt], response)) {\n return {\n response,\n result: response.ok ? schema.safeParse(await response.text()) : undefined,\n }\n }\n\n return {\n response,\n result: response.ok ? schema.safeParse(await response.json()) : undefined,\n }\n }\n}\n","export function isObject(item: unknown): item is Record<string, unknown> {\n return item != null && typeof item === 'object' && !Array.isArray(item)\n}\n\n/**\n * Deep merge two objects.\n * @param target\n * @param ...sources\n */\nexport function mergeDeep(target: unknown, ...sources: Array<unknown>): unknown {\n if (!sources.length) return target\n const source = sources.shift()\n\n if (isObject(target) && isObject(source)) {\n for (const key in source) {\n if (isObject(source[key])) {\n if (!target[key]) Object.assign(target, { [key]: {} })\n mergeDeep(target[key], source[key])\n } else {\n Object.assign(target, { [key]: source[key] })\n }\n }\n }\n\n return mergeDeep(target, ...sources)\n}\n","import type z from 'zod'\nimport { JsonParseError } from './error/JsonParseError'\nimport { ValidationError } from './error/ValidationError'\n\nexport type BaseSchema = z.ZodTypeAny\n// biome-ignore lint/suspicious/noExplicitAny: no explanation\nexport type InferOutputUnion<T extends readonly any[]> = {\n [K in keyof T]: z.infer<T[K]>\n}[number]\n\nexport function stringToJsonWithErrorHandling(string: string, errorMessage?: string) {\n try {\n return JSON.parse(string)\n } catch (_error) {\n throw new JsonParseError(errorMessage ?? 'Unable to parse string to JSON.', string)\n }\n}\n\nexport function parseIfJson<T>(data: T): T | Record<string, unknown> {\n if (typeof data !== 'string') {\n return data\n }\n\n try {\n // Try to parse the string as JSON\n return JSON.parse(data)\n } catch (_error) {}\n\n return data\n}\n\nexport function parseWithErrorHandling<Schema extends BaseSchema>(\n schema: Schema,\n data: unknown,\n customErrorMessage?: string\n): z.infer<Schema> {\n const parseResult = schema.safeParse(data)\n\n if (!parseResult.success) {\n throw new ValidationError(\n customErrorMessage ?? `Error validating schema with data ${JSON.stringify(data)}`,\n parseResult.error\n )\n }\n\n return parseResult.data\n}\n","/**\n * Combine multiple uri parts into a single uri taking into account slashes.\n *\n * @param parts the parts to combine\n * @returns the combined url\n */\nexport function joinUriParts(base: string, parts: string[]) {\n if (parts.length === 0) return base\n\n // take base without trailing /\n let combined = base.trim()\n combined = base.endsWith('/') ? base.slice(0, base.length - 1) : base\n\n for (const part of parts) {\n // Remove leading and trailing /\n let strippedPart = part.trim()\n strippedPart = strippedPart.startsWith('/') ? strippedPart.slice(1) : strippedPart\n strippedPart = strippedPart.endsWith('/') ? strippedPart.slice(0, strippedPart.length - 1) : strippedPart\n\n // Don't want to add if empty\n if (strippedPart === '') continue\n\n combined += `/${strippedPart}`\n }\n\n return combined\n}\n","import { URL, URLSearchParams } from './globals'\n\nexport function getQueryParams(url: string) {\n const parsedUrl = new URL(url)\n const searchParams = new URLSearchParams(parsedUrl.search)\n const params: Record<string, string> = {}\n\n searchParams.forEach((value, key) => {\n params[key] = value\n })\n\n return params\n}\n\nexport function objectToQueryParams(object: Record<string, unknown>): InstanceType<typeof URLSearchParams> {\n const params = new URLSearchParams()\n\n for (const [key, value] of Object.entries(object)) {\n if (value != null) {\n params.append(key, typeof value === 'object' ? JSON.stringify(value) : String(value))\n }\n }\n\n return params\n}\n","import z from 'zod'\nimport { getGlobalConfig } from './config'\n\nexport const zHttpsUrl = z\n .string()\n .url()\n .refine(\n (url) => {\n const { allowInsecureUrls } = getGlobalConfig()\n return allowInsecureUrls ? url.startsWith('http://') || url.startsWith('https://') : url.startsWith('https://')\n },\n { message: 'url must be an https:// url' }\n )\n\nexport const zInteger = z.number().int()\n\nexport const zHttpMethod = z.enum(['GET', 'POST', 'PUT', 'DELETE', 'HEAD', 'OPTIONS', 'TRACE', 'CONNECT', 'PATCH'])\nexport type HttpMethod = z.infer<typeof zHttpMethod>\n\nexport const zStringToJson = z.string().transform((string, ctx) => {\n try {\n return JSON.parse(string)\n } catch (_error) {\n ctx.addIssue({\n code: 'custom',\n message: 'Expected a JSON string, but could not parse the string to JSON',\n })\n return z.NEVER\n }\n})\n\nexport const zIs = <Schema extends z.ZodSchema>(schema: Schema, data: unknown): data is z.infer<typeof schema> =>\n schema.safeParse(data).success\n","const unquote = (value: string) => value.substring(1, value.length - 1).replace(/\\\\\"/g, '\"')\n// Fixup quoted strings and tokens with spaces around them\nconst sanitize = (value: string) => (value.charAt(0) === '\"' ? unquote(value) : value.trim())\n\n// lol dis\nconst body =\n // biome-ignore lint/suspicious/noControlCharactersInRegex: no explanation\n /((?:[a-zA-Z0-9._~+/-]+=*(?:\\s+|$))|[^\\u0000-\\u001F\\u007F()<>@,;:\\\\\"/?={}[\\]\\u0020\\u0009]+)(?:=([^\\\\\"=\\s,]+|\"(?:[^\"\\\\]|\\\\.)*\"))?/g\n\nexport interface WwwAuthenticateHeaderChallenge {\n scheme: string\n\n /**\n * Record where the keys are the names, and the value can be 0 (null), 1 (string) or multiple (string[])\n * entries\n */\n payload: Record<string, string | string[] | null>\n}\n\nconst parsePayload = (scheme: string, string: string): WwwAuthenticateHeaderChallenge => {\n const payload: Record<string, string | string[] | null> = {}\n\n while (true) {\n const res = body.exec(string)\n if (!res) break\n\n const [, key, newValue] = res\n\n const payloadValue = payload[key]\n if (newValue) {\n const sanitizedValue = sanitize(newValue)\n payload[key] = payloadValue\n ? Array.isArray(payloadValue)\n ? [...payloadValue, sanitizedValue]\n : [payloadValue, sanitizedValue]\n : sanitizedValue\n } else if (!payloadValue) {\n payload[key] = null\n }\n }\n\n return { scheme, payload }\n}\n\nexport function parseWwwAuthenticateHeader(str: string): WwwAuthenticateHeaderChallenge[] {\n const start = str.indexOf(' ')\n let scheme = str.substring(0, start)\n let value = str.substring(start)\n\n const challenges: WwwAuthenticateHeaderChallenge[] = []\n\n // Some well-known schemes to support-multi parsing\n const endsWithSchemeRegex = /, ?(Bearer|DPoP|Basic)$/\n const endsWithSchemeTest = endsWithSchemeRegex.exec(value)\n let endsWithScheme: string | undefined\n if (endsWithSchemeTest) {\n value = value.substring(0, value.length - endsWithSchemeTest[0].length)\n endsWithScheme = endsWithSchemeTest[1]\n }\n\n const additionalSchemesRegex = /(.*?)(, ?)(Bearer|DPoP|Basic)[, ]/\n let match = additionalSchemesRegex.exec(value)\n while (match) {\n challenges.push(parsePayload(scheme, match[1]))\n value = value.substring(match[0].length - 1)\n scheme = match[3]\n\n match = additionalSchemesRegex.exec(value)\n }\n challenges.push(parsePayload(scheme, value))\n if (endsWithScheme) {\n challenges.push({ scheme: endsWithScheme, payload: {} })\n }\n return challenges\n}\n\nexport function encodeWwwAuthenticateHeader(challenges: WwwAuthenticateHeaderChallenge[]) {\n const entries: string[] = []\n\n for (const challenge of challenges) {\n // Encode each parameter according to RFC 7235\n const encodedParams = Object.entries(challenge.payload).flatMap(([key, value]) => {\n const encode = (s: string) => s.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"')\n // Convert value to string and escape special characters\n if (Array.isArray(value)) {\n return value.map((v) => `${key}=\"${encode(v)}\"`)\n }\n\n return value ? `${key}=\"${encode(value)}\"` : key\n })\n\n entries.push(encodedParams.length === 0 ? challenge.scheme : `${challenge.scheme} ${encodedParams.join(', ')}`)\n }\n\n return entries.join(', ')\n}\n","import z from 'zod'\n\nexport function formatZodError(error?: z.ZodError): string {\n if (!error) return ''\n\n return z.prettifyError(error)\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":["GLOBAL_CONFIG: Oid4vcTsConfig","textResponse: string","URLSearchParams","URLSearchParams","URL","params: Record<string, string>","payload: Record<string, string | string[] | null>","challenges: WwwAuthenticateHeaderChallenge[]","endsWithScheme: string | undefined","entries: string[]"],"sources":["../src/array.ts","../src/config.ts","../src/content-type.ts","../src/date.ts","../src/encoding.ts","../src/error/InvalidFetchResponseError.ts","../src/error/JsonParseError.ts","../src/error/ValidationError.ts","../src/error/FetchError.ts","../src/globals.ts","../src/fetcher.ts","../src/object.ts","../src/parse.ts","../src/path.ts","../src/url.ts","../src/validation.ts","../src/www-authenticate.ts","../src/zod-error.ts"],"sourcesContent":["/**\n * Only primitive types allowed\n * Must have not duplicate entries (will always return false in this case)\n */\nexport function arrayEqualsIgnoreOrder<Item extends string | number | boolean>(\n a: Array<Item>,\n b: Array<Item>\n): boolean {\n if (new Set(a).size !== new Set(b).size) return false\n if (a.length !== b.length) return false\n\n return a.every((k) => b.includes(k))\n}\n","export interface Oid4vcTsConfig {\n /**\n * Whether to allow insecure http urls.\n *\n * @default false\n */\n allowInsecureUrls: boolean\n}\n\nlet GLOBAL_CONFIG: Oid4vcTsConfig = {\n allowInsecureUrls: false,\n}\n\nexport function setGlobalConfig(config: Oid4vcTsConfig) {\n GLOBAL_CONFIG = config\n}\n\nexport function getGlobalConfig(): Oid4vcTsConfig {\n return GLOBAL_CONFIG\n}\n","import type { FetchResponse } from './globals'\n\nexport enum ContentType {\n XWwwFormUrlencoded = 'application/x-www-form-urlencoded',\n Json = 'application/json',\n JwkSet = 'application/jwk-set+json',\n OAuthAuthorizationRequestJwt = 'application/oauth-authz-req+jwt',\n Jwt = 'application/jwt',\n Html = 'text/html',\n}\n\nexport function isContentType(contentType: ContentType, value: string) {\n return value.toLowerCase().includes(contentType)\n}\n\nexport function isResponseContentType(contentType: ContentType | ContentType[], response: FetchResponse) {\n const contentTypeArray = Array.isArray(contentType) ? contentType : [contentType]\n\n const header = response.headers.get('Content-Type')\n if (!header) return false\n return contentTypeArray.some((contentTypeEntry) => isContentType(contentTypeEntry, header))\n}\n","/**\n * Get the time in seconds since epoch for a date.\n * If date is not provided the current time will be used.\n */\nexport function dateToSeconds(date?: Date) {\n const milliseconds = date?.getTime() ?? Date.now()\n\n return Math.floor(milliseconds / 1000)\n}\n\nexport function addSecondsToDate(date: Date, seconds: number) {\n return new Date(date.getTime() + seconds * 1000)\n}\n","import { Buffer } from 'buffer'\n\nexport function decodeUtf8String(string: string): Uint8Array {\n return new Uint8Array(Buffer.from(string, 'utf-8'))\n}\n\nexport function encodeToUtf8String(data: Uint8Array) {\n return Buffer.from(data).toString('utf-8')\n}\n\n/**\n * Also supports base64 url\n */\nexport function decodeBase64(base64: string): Uint8Array {\n return new Uint8Array(Buffer.from(base64, 'base64'))\n}\n\nexport function encodeToBase64(data: Uint8Array | string) {\n // To make ts happy. Somehow Uint8Array or string is no bueno\n if (typeof data === 'string') {\n return Buffer.from(data).toString('base64')\n }\n\n return Buffer.from(data).toString('base64')\n}\n\nexport function encodeToBase64Url(data: Uint8Array | string) {\n return base64ToBase64Url(encodeToBase64(data))\n}\n\n/**\n * The 'buffer' npm library does not support base64url.\n */\nfunction base64ToBase64Url(base64: string) {\n return base64.replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, '')\n}\n","import { ContentType, isResponseContentType } from '../content-type'\nimport type { FetchResponse } from '../globals'\n\nexport class InvalidFetchResponseError extends Error {\n public readonly response: FetchResponse\n\n public constructor(\n message: string,\n public readonly textResponse: string,\n response: FetchResponse\n ) {\n // We don't want to put html content in pages. For other content we take the first 1000 characters\n // to prevent ridiculously long errors.\n const textResponseMessage = isResponseContentType(ContentType.Html, response)\n ? undefined\n : textResponse.substring(0, 1000)\n\n super(textResponseMessage ? `${message}\\n${textResponseMessage}` : message)\n\n this.response = response.clone()\n }\n}\n","export class JsonParseError extends Error {\n public constructor(message: string, jsonString: string) {\n super(`${message}\\n${jsonString}`)\n }\n}\n","import z, { type ZodError } from 'zod'\n\nexport class ValidationError extends Error {\n public zodError: ZodError | undefined\n\n constructor(message: string, zodError?: ZodError) {\n super(message)\n\n const formattedError = zodError ? z.prettifyError(zodError) : ''\n this.message = `${message}\\n${formattedError}`\n\n Object.defineProperty(this, 'zodError', {\n value: zodError,\n writable: false,\n enumerable: false,\n })\n }\n}\n","export class FetchError extends Error {\n public readonly cause?: Error\n\n public constructor(message: string, { cause }: { cause?: Error } = {}) {\n super(`${message}\\nCause: ${cause?.message}`)\n this.cause = cause\n }\n}\n","// Theses types are provided by the platform (so @types/node, @types/react-native, DOM)\n\n// biome-ignore lint/style/noRestrictedGlobals: no explanation\nconst _URL = URL\n\n// biome-ignore lint/style/noRestrictedGlobals: no explanation\nconst _URLSearchParams = URLSearchParams\n\n// biome-ignore lint/style/noRestrictedGlobals: no explanation\nexport type Fetch = typeof fetch\n// biome-ignore lint/style/noRestrictedGlobals: no explanation\nexport type FetchResponse = Response\n// biome-ignore lint/style/noRestrictedGlobals: no explanation\nconst _Headers = Headers as typeof globalThis.Headers\nexport type FetchHeaders = globalThis.Headers\nexport type FetchRequestInit = RequestInit\n\nexport { _URLSearchParams as URLSearchParams, _URL as URL, _Headers as Headers }\n","import type z from 'zod'\nimport { ContentType, isResponseContentType } from './content-type'\nimport { FetchError } from './error/FetchError'\nimport { InvalidFetchResponseError } from './error/InvalidFetchResponseError'\nimport { type Fetch, URLSearchParams } from './globals'\n\n/**\n * A type utility which represents the function returned\n * from createZodFetcher\n */\nexport type ZodFetcher = <Schema extends z.ZodTypeAny>(\n schema: Schema,\n expectedContentType: ContentType | ContentType[],\n ...args: Parameters<Fetch>\n) => Promise<{ response: Awaited<ReturnType<Fetch>>; result?: z.ZodSafeParseResult<z.infer<Schema>> }>\n\n/**\n * The default fetcher used by createZodFetcher when no\n * fetcher is provided.\n */\n// biome-ignore lint/style/noRestrictedGlobals: this is the only place where we use the global\nconst defaultFetcher = fetch\n\nexport function createFetcher(fetcher = defaultFetcher): Fetch {\n return (input, init, ...args) => {\n return fetcher(\n input,\n init\n ? {\n ...init,\n // React Native does not seem to handle the toString(). This is hard to catch when running\n // tests in Node.JS where this does work correctly. so we handle it here.\n body: init.body instanceof URLSearchParams ? init.body.toString() : init.body,\n }\n : undefined,\n ...args\n ).catch((error) => {\n throw new FetchError(`Unknown error occurred during fetch to '${input}'`, { cause: error })\n })\n }\n}\n\n/**\n * Creates a `fetchWithZod` function that takes in a schema of\n * the expected response, and the arguments to the fetcher\n * you provided.\n *\n * @example\n *\n * const fetchWithZod = createZodFetcher((url) => {\n * return fetch(url).then((res) => res.json());\n * });\n *\n * const response = await fetchWithZod(\n * z.object({\n * hello: z.string(),\n * }),\n * \"https://example.com\",\n * );\n */\nexport function createZodFetcher(fetcher?: Fetch): ZodFetcher {\n return async (schema, expectedContentType, ...args) => {\n const response = await createFetcher(fetcher)(...args)\n\n const expectedContentTypeArray = Array.isArray(expectedContentType) ? expectedContentType : [expectedContentType]\n\n if (response.ok && !isResponseContentType(expectedContentTypeArray, response)) {\n throw new InvalidFetchResponseError(\n `Expected response to match content type ${expectedContentTypeArray.join(' | ')}, but received '${response.headers.get('Content-Type')}'`,\n await response.clone().text(),\n response\n )\n }\n\n if (isResponseContentType([ContentType.OAuthAuthorizationRequestJwt, ContentType.Jwt], response)) {\n return {\n response,\n result: response.ok ? schema.safeParse(await response.text()) : undefined,\n }\n }\n\n return {\n response,\n result: response.ok ? schema.safeParse(await response.json()) : undefined,\n }\n }\n}\n","export function isObject(item: unknown): item is Record<string, unknown> {\n return item != null && typeof item === 'object' && !Array.isArray(item)\n}\n\n/**\n * Deep merge two objects.\n * @param target\n * @param ...sources\n */\nexport function mergeDeep(target: unknown, ...sources: Array<unknown>): unknown {\n if (!sources.length) return target\n const source = sources.shift()\n\n if (isObject(target) && isObject(source)) {\n for (const key in source) {\n if (isObject(source[key])) {\n if (!target[key]) Object.assign(target, { [key]: {} })\n mergeDeep(target[key], source[key])\n } else {\n Object.assign(target, { [key]: source[key] })\n }\n }\n }\n\n return mergeDeep(target, ...sources)\n}\n","import type z from 'zod'\nimport { JsonParseError } from './error/JsonParseError'\nimport { ValidationError } from './error/ValidationError'\n\nexport type BaseSchema = z.ZodTypeAny\n// biome-ignore lint/suspicious/noExplicitAny: no explanation\nexport type InferOutputUnion<T extends readonly any[]> = {\n [K in keyof T]: z.infer<T[K]>\n}[number]\n\nexport function stringToJsonWithErrorHandling(string: string, errorMessage?: string) {\n try {\n return JSON.parse(string)\n } catch (_error) {\n throw new JsonParseError(errorMessage ?? 'Unable to parse string to JSON.', string)\n }\n}\n\nexport function parseIfJson<T>(data: T): T | Record<string, unknown> {\n if (typeof data !== 'string') {\n return data\n }\n\n try {\n // Try to parse the string as JSON\n return JSON.parse(data)\n } catch (_error) {}\n\n return data\n}\n\nexport function parseWithErrorHandling<Schema extends BaseSchema>(\n schema: Schema,\n data: unknown,\n customErrorMessage?: string\n): z.infer<Schema> {\n const parseResult = schema.safeParse(data)\n\n if (!parseResult.success) {\n throw new ValidationError(\n customErrorMessage ?? `Error validating schema with data ${JSON.stringify(data)}`,\n parseResult.error\n )\n }\n\n return parseResult.data\n}\n","/**\n * Combine multiple uri parts into a single uri taking into account slashes.\n *\n * @param parts the parts to combine\n * @returns the combined url\n */\nexport function joinUriParts(base: string, parts: string[]) {\n if (parts.length === 0) return base\n\n // take base without trailing /\n let combined = base.trim()\n combined = base.endsWith('/') ? base.slice(0, base.length - 1) : base\n\n for (const part of parts) {\n // Remove leading and trailing /\n let strippedPart = part.trim()\n strippedPart = strippedPart.startsWith('/') ? strippedPart.slice(1) : strippedPart\n strippedPart = strippedPart.endsWith('/') ? strippedPart.slice(0, strippedPart.length - 1) : strippedPart\n\n // Don't want to add if empty\n if (strippedPart === '') continue\n\n combined += `/${strippedPart}`\n }\n\n return combined\n}\n","import { URL, URLSearchParams } from './globals'\n\nexport function getQueryParams(url: string) {\n const parsedUrl = new URL(url)\n const searchParams = new URLSearchParams(parsedUrl.search)\n const params: Record<string, string> = {}\n\n searchParams.forEach((value, key) => {\n params[key] = value\n })\n\n return params\n}\n\nexport function objectToQueryParams(object: Record<string, unknown>): InstanceType<typeof URLSearchParams> {\n const params = new URLSearchParams()\n\n for (const [key, value] of Object.entries(object)) {\n if (value != null) {\n params.append(key, typeof value === 'object' ? JSON.stringify(value) : String(value))\n }\n }\n\n return params\n}\n","import z from 'zod'\nimport { getGlobalConfig } from './config'\n\nexport const zHttpsUrl = z.url().refine(\n (url) => {\n const { allowInsecureUrls } = getGlobalConfig()\n return allowInsecureUrls ? url.startsWith('http://') || url.startsWith('https://') : url.startsWith('https://')\n },\n { message: 'url must be an https:// url' }\n)\n\nexport const zDataUrl = z.string().regex(/data:[\\w/\\-.]+;\\w+,.*/, 'url must be a data URL')\n\nexport const zInteger = z.number().int()\n\nexport const zHttpMethod = z.enum(['GET', 'POST', 'PUT', 'DELETE', 'HEAD', 'OPTIONS', 'TRACE', 'CONNECT', 'PATCH'])\nexport type HttpMethod = z.infer<typeof zHttpMethod>\n\nexport const zStringToJson = z.string().transform((string, ctx) => {\n try {\n return JSON.parse(string)\n } catch (_error) {\n ctx.addIssue({\n code: 'custom',\n message: 'Expected a JSON string, but could not parse the string to JSON',\n })\n return z.NEVER\n }\n})\n\nexport const zIs = <Schema extends z.ZodSchema>(schema: Schema, data: unknown): data is z.infer<typeof schema> =>\n schema.safeParse(data).success\n","const unquote = (value: string) => value.substring(1, value.length - 1).replace(/\\\\\"/g, '\"')\n// Fixup quoted strings and tokens with spaces around them\nconst sanitize = (value: string) => (value.charAt(0) === '\"' ? unquote(value) : value.trim())\n\n// lol dis\nconst body =\n // biome-ignore lint/suspicious/noControlCharactersInRegex: no explanation\n /((?:[a-zA-Z0-9._~+/-]+=*(?:\\s+|$))|[^\\u0000-\\u001F\\u007F()<>@,;:\\\\\"/?={}[\\]\\u0020\\u0009]+)(?:=([^\\\\\"=\\s,]+|\"(?:[^\"\\\\]|\\\\.)*\"))?/g\n\nexport interface WwwAuthenticateHeaderChallenge {\n scheme: string\n\n /**\n * Record where the keys are the names, and the value can be 0 (null), 1 (string) or multiple (string[])\n * entries\n */\n payload: Record<string, string | string[] | null>\n}\n\nconst parsePayload = (scheme: string, string: string): WwwAuthenticateHeaderChallenge => {\n const payload: Record<string, string | string[] | null> = {}\n\n while (true) {\n const res = body.exec(string)\n if (!res) break\n\n const [, key, newValue] = res\n\n const payloadValue = payload[key]\n if (newValue) {\n const sanitizedValue = sanitize(newValue)\n payload[key] = payloadValue\n ? Array.isArray(payloadValue)\n ? [...payloadValue, sanitizedValue]\n : [payloadValue, sanitizedValue]\n : sanitizedValue\n } else if (!payloadValue) {\n payload[key] = null\n }\n }\n\n return { scheme, payload }\n}\n\nexport function parseWwwAuthenticateHeader(str: string): WwwAuthenticateHeaderChallenge[] {\n const start = str.indexOf(' ')\n let scheme = str.substring(0, start)\n let value = str.substring(start)\n\n const challenges: WwwAuthenticateHeaderChallenge[] = []\n\n // Some well-known schemes to support-multi parsing\n const endsWithSchemeRegex = /, ?(Bearer|DPoP|Basic)$/\n const endsWithSchemeTest = endsWithSchemeRegex.exec(value)\n let endsWithScheme: string | undefined\n if (endsWithSchemeTest) {\n value = value.substring(0, value.length - endsWithSchemeTest[0].length)\n endsWithScheme = endsWithSchemeTest[1]\n }\n\n const additionalSchemesRegex = /(.*?)(, ?)(Bearer|DPoP|Basic)[, ]/\n let match = additionalSchemesRegex.exec(value)\n while (match) {\n challenges.push(parsePayload(scheme, match[1]))\n value = value.substring(match[0].length - 1)\n scheme = match[3]\n\n match = additionalSchemesRegex.exec(value)\n }\n challenges.push(parsePayload(scheme, value))\n if (endsWithScheme) {\n challenges.push({ scheme: endsWithScheme, payload: {} })\n }\n return challenges\n}\n\nexport function encodeWwwAuthenticateHeader(challenges: WwwAuthenticateHeaderChallenge[]) {\n const entries: string[] = []\n\n for (const challenge of challenges) {\n // Encode each parameter according to RFC 7235\n const encodedParams = Object.entries(challenge.payload).flatMap(([key, value]) => {\n const encode = (s: string) => s.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"')\n // Convert value to string and escape special characters\n if (Array.isArray(value)) {\n return value.map((v) => `${key}=\"${encode(v)}\"`)\n }\n\n return value ? `${key}=\"${encode(value)}\"` : key\n })\n\n entries.push(encodedParams.length === 0 ? challenge.scheme : `${challenge.scheme} ${encodedParams.join(', ')}`)\n }\n\n return entries.join(', ')\n}\n","import z from 'zod'\n\nexport function formatZodError(error?: z.ZodError): string {\n if (!error) return ''\n\n return z.prettifyError(error)\n}\n"],"mappings":";;;;;;;;AAIA,SAAgB,uBACd,GACA,GACS;AACT,KAAI,IAAI,IAAI,EAAE,CAAC,SAAS,IAAI,IAAI,EAAE,CAAC,KAAM,QAAO;AAChD,KAAI,EAAE,WAAW,EAAE,OAAQ,QAAO;AAElC,QAAO,EAAE,OAAO,MAAM,EAAE,SAAS,EAAE,CAAC;;;;;ACFtC,IAAIA,gBAAgC,EAClC,mBAAmB,OACpB;AAED,SAAgB,gBAAgB,QAAwB;AACtD,iBAAgB;;AAGlB,SAAgB,kBAAkC;AAChD,QAAO;;;;;AChBT,IAAY,sDAAL;AACL;AACA;AACA;AACA;AACA;AACA;;;AAGF,SAAgB,cAAc,aAA0B,OAAe;AACrE,QAAO,MAAM,aAAa,CAAC,SAAS,YAAY;;AAGlD,SAAgB,sBAAsB,aAA0C,UAAyB;CACvG,MAAM,mBAAmB,MAAM,QAAQ,YAAY,GAAG,cAAc,CAAC,YAAY;CAEjF,MAAM,SAAS,SAAS,QAAQ,IAAI,eAAe;AACnD,KAAI,CAAC,OAAQ,QAAO;AACpB,QAAO,iBAAiB,MAAM,qBAAqB,cAAc,kBAAkB,OAAO,CAAC;;;;;;;;;AChB7F,SAAgB,cAAc,MAAa;CACzC,MAAM,eAAe,MAAM,SAAS,IAAI,KAAK,KAAK;AAElD,QAAO,KAAK,MAAM,eAAe,IAAK;;AAGxC,SAAgB,iBAAiB,MAAY,SAAiB;AAC5D,QAAO,IAAI,KAAK,KAAK,SAAS,GAAG,UAAU,IAAK;;;;;ACTlD,SAAgB,iBAAiB,QAA4B;AAC3D,QAAO,IAAI,WAAW,OAAO,KAAK,QAAQ,QAAQ,CAAC;;AAGrD,SAAgB,mBAAmB,MAAkB;AACnD,QAAO,OAAO,KAAK,KAAK,CAAC,SAAS,QAAQ;;;;;AAM5C,SAAgB,aAAa,QAA4B;AACvD,QAAO,IAAI,WAAW,OAAO,KAAK,QAAQ,SAAS,CAAC;;AAGtD,SAAgB,eAAe,MAA2B;AAExD,KAAI,OAAO,SAAS,SAClB,QAAO,OAAO,KAAK,KAAK,CAAC,SAAS,SAAS;AAG7C,QAAO,OAAO,KAAK,KAAK,CAAC,SAAS,SAAS;;AAG7C,SAAgB,kBAAkB,MAA2B;AAC3D,QAAO,kBAAkB,eAAe,KAAK,CAAC;;;;;AAMhD,SAAS,kBAAkB,QAAgB;AACzC,QAAO,OAAO,QAAQ,OAAO,IAAI,CAAC,QAAQ,OAAO,IAAI,CAAC,QAAQ,MAAM,GAAG;;;;;AC/BzE,IAAa,4BAAb,cAA+C,MAAM;CAGnD,AAAO,YACL,SACA,AAAgBC,cAChB,UACA;EAGA,MAAM,sBAAsB,sBAAsB,YAAY,MAAM,SAAS,GACzE,SACA,aAAa,UAAU,GAAG,IAAK;AAEnC,QAAM,sBAAsB,GAAG,QAAQ,IAAI,wBAAwB,QAAQ;EAT3D;AAWhB,OAAK,WAAW,SAAS,OAAO;;;;;;ACnBpC,IAAa,iBAAb,cAAoC,MAAM;CACxC,AAAO,YAAY,SAAiB,YAAoB;AACtD,QAAM,GAAG,QAAQ,IAAI,aAAa;;;;;;ACAtC,IAAa,kBAAb,cAAqC,MAAM;CAGzC,YAAY,SAAiB,UAAqB;AAChD,QAAM,QAAQ;AAGd,OAAK,UAAU,GAAG,QAAQ,IADH,WAAW,EAAE,cAAc,SAAS,GAAG;AAG9D,SAAO,eAAe,MAAM,YAAY;GACtC,OAAO;GACP,UAAU;GACV,YAAY;GACb,CAAC;;;;;;ACfN,IAAa,aAAb,cAAgC,MAAM;CAGpC,AAAO,YAAY,SAAiB,EAAE,UAA6B,EAAE,EAAE;AACrE,QAAM,GAAG,QAAQ,WAAW,OAAO,UAAU;AAC7C,OAAK,QAAQ;;;;;;ACFjB,MAAM,OAAO;AAGb,MAAM,mBAAmB;AAOzB,MAAM,WAAW;;;;;;;;ACQjB,MAAM,iBAAiB;AAEvB,SAAgB,cAAc,UAAU,gBAAuB;AAC7D,SAAQ,OAAO,MAAM,GAAG,SAAS;AAC/B,SAAO,QACL,OACA,OACI;GACE,GAAG;GAGH,MAAM,KAAK,gBAAgBC,mBAAkB,KAAK,KAAK,UAAU,GAAG,KAAK;GAC1E,GACD,QACJ,GAAG,KACJ,CAAC,OAAO,UAAU;AACjB,SAAM,IAAI,WAAW,2CAA2C,MAAM,IAAI,EAAE,OAAO,OAAO,CAAC;IAC3F;;;;;;;;;;;;;;;;;;;;;AAsBN,SAAgB,iBAAiB,SAA6B;AAC5D,QAAO,OAAO,QAAQ,qBAAqB,GAAG,SAAS;EACrD,MAAM,WAAW,MAAM,cAAc,QAAQ,CAAC,GAAG,KAAK;EAEtD,MAAM,2BAA2B,MAAM,QAAQ,oBAAoB,GAAG,sBAAsB,CAAC,oBAAoB;AAEjH,MAAI,SAAS,MAAM,CAAC,sBAAsB,0BAA0B,SAAS,CAC3E,OAAM,IAAI,0BACR,2CAA2C,yBAAyB,KAAK,MAAM,CAAC,kBAAkB,SAAS,QAAQ,IAAI,eAAe,CAAC,IACvI,MAAM,SAAS,OAAO,CAAC,MAAM,EAC7B,SACD;AAGH,MAAI,sBAAsB,CAAC,YAAY,8BAA8B,YAAY,IAAI,EAAE,SAAS,CAC9F,QAAO;GACL;GACA,QAAQ,SAAS,KAAK,OAAO,UAAU,MAAM,SAAS,MAAM,CAAC,GAAG;GACjE;AAGH,SAAO;GACL;GACA,QAAQ,SAAS,KAAK,OAAO,UAAU,MAAM,SAAS,MAAM,CAAC,GAAG;GACjE;;;;;;ACpFL,SAAgB,SAAS,MAAgD;AACvE,QAAO,QAAQ,QAAQ,OAAO,SAAS,YAAY,CAAC,MAAM,QAAQ,KAAK;;;;;;;AAQzE,SAAgB,UAAU,QAAiB,GAAG,SAAkC;AAC9E,KAAI,CAAC,QAAQ,OAAQ,QAAO;CAC5B,MAAM,SAAS,QAAQ,OAAO;AAE9B,KAAI,SAAS,OAAO,IAAI,SAAS,OAAO,CACtC,MAAK,MAAM,OAAO,OAChB,KAAI,SAAS,OAAO,KAAK,EAAE;AACzB,MAAI,CAAC,OAAO,KAAM,QAAO,OAAO,QAAQ,GAAG,MAAM,EAAE,EAAE,CAAC;AACtD,YAAU,OAAO,MAAM,OAAO,KAAK;OAEnC,QAAO,OAAO,QAAQ,GAAG,MAAM,OAAO,MAAM,CAAC;AAKnD,QAAO,UAAU,QAAQ,GAAG,QAAQ;;;;;ACdtC,SAAgB,8BAA8B,QAAgB,cAAuB;AACnF,KAAI;AACF,SAAO,KAAK,MAAM,OAAO;UAClB,QAAQ;AACf,QAAM,IAAI,eAAe,gBAAgB,mCAAmC,OAAO;;;AAIvF,SAAgB,YAAe,MAAsC;AACnE,KAAI,OAAO,SAAS,SAClB,QAAO;AAGT,KAAI;AAEF,SAAO,KAAK,MAAM,KAAK;UAChB,QAAQ;AAEjB,QAAO;;AAGT,SAAgB,uBACd,QACA,MACA,oBACiB;CACjB,MAAM,cAAc,OAAO,UAAU,KAAK;AAE1C,KAAI,CAAC,YAAY,QACf,OAAM,IAAI,gBACR,sBAAsB,qCAAqC,KAAK,UAAU,KAAK,IAC/E,YAAY,MACb;AAGH,QAAO,YAAY;;;;;;;;;;;ACvCrB,SAAgB,aAAa,MAAc,OAAiB;AAC1D,KAAI,MAAM,WAAW,EAAG,QAAO;CAG/B,IAAI,WAAW,KAAK,MAAM;AAC1B,YAAW,KAAK,SAAS,IAAI,GAAG,KAAK,MAAM,GAAG,KAAK,SAAS,EAAE,GAAG;AAEjE,MAAK,MAAM,QAAQ,OAAO;EAExB,IAAI,eAAe,KAAK,MAAM;AAC9B,iBAAe,aAAa,WAAW,IAAI,GAAG,aAAa,MAAM,EAAE,GAAG;AACtE,iBAAe,aAAa,SAAS,IAAI,GAAG,aAAa,MAAM,GAAG,aAAa,SAAS,EAAE,GAAG;AAG7F,MAAI,iBAAiB,GAAI;AAEzB,cAAY,IAAI;;AAGlB,QAAO;;;;;ACvBT,SAAgB,eAAe,KAAa;CAE1C,MAAM,eAAe,IAAIC,iBADP,IAAIC,KAAI,IAAI,CACqB,OAAO;CAC1D,MAAMC,SAAiC,EAAE;AAEzC,cAAa,SAAS,OAAO,QAAQ;AACnC,SAAO,OAAO;GACd;AAEF,QAAO;;AAGT,SAAgB,oBAAoB,QAAuE;CACzG,MAAM,SAAS,IAAIF,kBAAiB;AAEpC,MAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,OAAO,CAC/C,KAAI,SAAS,KACX,QAAO,OAAO,KAAK,OAAO,UAAU,WAAW,KAAK,UAAU,MAAM,GAAG,OAAO,MAAM,CAAC;AAIzF,QAAO;;;;;ACpBT,MAAa,YAAY,EAAE,KAAK,CAAC,QAC9B,QAAQ;CACP,MAAM,EAAE,sBAAsB,iBAAiB;AAC/C,QAAO,oBAAoB,IAAI,WAAW,UAAU,IAAI,IAAI,WAAW,WAAW,GAAG,IAAI,WAAW,WAAW;GAEjH,EAAE,SAAS,+BAA+B,CAC3C;AAED,MAAa,WAAW,EAAE,QAAQ,CAAC,MAAM,yBAAyB,yBAAyB;AAE3F,MAAa,WAAW,EAAE,QAAQ,CAAC,KAAK;AAExC,MAAa,cAAc,EAAE,KAAK;CAAC;CAAO;CAAQ;CAAO;CAAU;CAAQ;CAAW;CAAS;CAAW;CAAQ,CAAC;AAGnH,MAAa,gBAAgB,EAAE,QAAQ,CAAC,WAAW,QAAQ,QAAQ;AACjE,KAAI;AACF,SAAO,KAAK,MAAM,OAAO;UAClB,QAAQ;AACf,MAAI,SAAS;GACX,MAAM;GACN,SAAS;GACV,CAAC;AACF,SAAO,EAAE;;EAEX;AAEF,MAAa,OAAmC,QAAgB,SAC9D,OAAO,UAAU,KAAK,CAAC;;;;AC/BzB,MAAM,WAAW,UAAkB,MAAM,UAAU,GAAG,MAAM,SAAS,EAAE,CAAC,QAAQ,QAAQ,KAAI;AAE5F,MAAM,YAAY,UAAmB,MAAM,OAAO,EAAE,KAAK,OAAM,QAAQ,MAAM,GAAG,MAAM,MAAM;AAG5F,MAAM,OAEJ;AAYF,MAAM,gBAAgB,QAAgB,WAAmD;CACvF,MAAMG,UAAoD,EAAE;AAE5D,QAAO,MAAM;EACX,MAAM,MAAM,KAAK,KAAK,OAAO;AAC7B,MAAI,CAAC,IAAK;EAEV,MAAM,GAAG,KAAK,YAAY;EAE1B,MAAM,eAAe,QAAQ;AAC7B,MAAI,UAAU;GACZ,MAAM,iBAAiB,SAAS,SAAS;AACzC,WAAQ,OAAO,eACX,MAAM,QAAQ,aAAa,GACzB,CAAC,GAAG,cAAc,eAAe,GACjC,CAAC,cAAc,eAAe,GAChC;aACK,CAAC,aACV,SAAQ,OAAO;;AAInB,QAAO;EAAE;EAAQ;EAAS;;AAG5B,SAAgB,2BAA2B,KAA+C;CACxF,MAAM,QAAQ,IAAI,QAAQ,IAAI;CAC9B,IAAI,SAAS,IAAI,UAAU,GAAG,MAAM;CACpC,IAAI,QAAQ,IAAI,UAAU,MAAM;CAEhC,MAAMC,aAA+C,EAAE;CAIvD,MAAM,qBADsB,0BACmB,KAAK,MAAM;CAC1D,IAAIC;AACJ,KAAI,oBAAoB;AACtB,UAAQ,MAAM,UAAU,GAAG,MAAM,SAAS,mBAAmB,GAAG,OAAO;AACvE,mBAAiB,mBAAmB;;CAGtC,MAAM,yBAAyB;CAC/B,IAAI,QAAQ,uBAAuB,KAAK,MAAM;AAC9C,QAAO,OAAO;AACZ,aAAW,KAAK,aAAa,QAAQ,MAAM,GAAG,CAAC;AAC/C,UAAQ,MAAM,UAAU,MAAM,GAAG,SAAS,EAAE;AAC5C,WAAS,MAAM;AAEf,UAAQ,uBAAuB,KAAK,MAAM;;AAE5C,YAAW,KAAK,aAAa,QAAQ,MAAM,CAAC;AAC5C,KAAI,eACF,YAAW,KAAK;EAAE,QAAQ;EAAgB,SAAS,EAAE;EAAE,CAAC;AAE1D,QAAO;;AAGT,SAAgB,4BAA4B,YAA8C;CACxF,MAAMC,UAAoB,EAAE;AAE5B,MAAK,MAAM,aAAa,YAAY;EAElC,MAAM,gBAAgB,OAAO,QAAQ,UAAU,QAAQ,CAAC,SAAS,CAAC,KAAK,WAAW;GAChF,MAAM,UAAU,MAAc,EAAE,QAAQ,OAAO,OAAO,CAAC,QAAQ,MAAM,OAAM;AAE3E,OAAI,MAAM,QAAQ,MAAM,CACtB,QAAO,MAAM,KAAK,MAAM,GAAG,IAAI,IAAI,OAAO,EAAE,CAAC,GAAG;AAGlD,UAAO,QAAQ,GAAG,IAAI,IAAI,OAAO,MAAM,CAAC,KAAK;IAC7C;AAEF,UAAQ,KAAK,cAAc,WAAW,IAAI,UAAU,SAAS,GAAG,UAAU,OAAO,GAAG,cAAc,KAAK,KAAK,GAAG;;AAGjH,QAAO,QAAQ,KAAK,KAAK;;;;;AC5F3B,SAAgB,eAAe,OAA4B;AACzD,KAAI,CAAC,MAAO,QAAO;AAEnB,QAAO,EAAE,cAAc,MAAM"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openid4vc/utils",
3
- "version": "0.3.0-alpha-20251120112059",
3
+ "version": "0.3.0",
4
4
  "files": [
5
5
  "dist"
6
6
  ],