{"version":3,"file":"utils.mjs","names":[],"sources":["../../../src/libs/kv/utils.ts"],"sourcesContent":["import { sha256 } from \"@noble/hashes/sha2.js\";\nimport { utf8ToBytes } from \"@noble/hashes/utils.js\";\nimport type {\n\tKVAdapterInstance,\n\tKVIncrementCapability,\n\tKVNamespace,\n} from \"./types.js\";\n\nexport const HASH_PREFIX = \"h:\" as const;\n\ntype ResolveKeyOptions = {\n\tmaxKeyBytes?: number;\n\tnamespace?: KVNamespace;\n};\n\ntype ParsedResolveKeyOptions = ResolveKeyOptions & {\n\tnamespacePrefix: string;\n};\n\n/**\n * Converts a namespace option into the literal prefix stored in the backing KV.\n */\nexport const getNamespacePrefix = (namespace?: KVNamespace): string => {\n\tif (namespace === undefined || namespace === false) return \"\";\n\n\tif (namespace.length === 0) {\n\t\tthrow new Error(\n\t\t\t\"KV namespace cannot be an empty string. Use false to disable namespacing.\",\n\t\t);\n\t}\n\n\treturn `${namespace}:`;\n};\n\nconst toBase64Url = (bytes: Uint8Array): string => {\n\tlet binary = \"\";\n\tconst chunkSize = 0x8000;\n\n\tfor (let i = 0; i < bytes.length; i += chunkSize) {\n\t\tconst chunk = bytes.subarray(i, i + chunkSize);\n\t\tbinary += String.fromCharCode(...chunk);\n\t}\n\n\tconst base64 =\n\t\ttypeof btoa === \"function\"\n\t\t\t? btoa(binary)\n\t\t\t: Buffer.from(bytes).toString(\"base64\");\n\n\treturn base64.replace(/\\+/g, \"-\").replace(/\\//g, \"_\").replace(/=+$/g, \"\");\n};\n\n/**\n * Deterministically hash a key\n */\nexport const hashKey = (key: string): string =>\n\t`${HASH_PREFIX}${toBase64Url(sha256(utf8ToBytes(key)))}`;\n\nconst utf8ByteLength = (value: string): number => {\n\tif (typeof Buffer !== \"undefined\") return Buffer.byteLength(value, \"utf8\");\n\treturn new globalThis.TextEncoder().encode(value).byteLength;\n};\n\nconst parseResolveKeyOptions = (\n\toptions?: number | ResolveKeyOptions,\n): ParsedResolveKeyOptions => {\n\tconst resolved =\n\t\ttypeof options === \"number\" ? { maxKeyBytes: options } : (options ?? {});\n\n\treturn {\n\t\t...resolved,\n\t\tnamespacePrefix: getNamespacePrefix(resolved.namespace),\n\t};\n};\n\n/**\n * Resolve the KV key\n */\nexport const resolveKey = (\n\tkey: string,\n\toptions?: {\n\t\thash?: boolean;\n\t},\n\tresolveOptions?: number | ResolveKeyOptions,\n): string => {\n\tconst { maxKeyBytes, namespacePrefix } =\n\t\tparseResolveKeyOptions(resolveOptions);\n\tconst namespacedKey = `${namespacePrefix}${key}`;\n\n\tconst shouldHash =\n\t\toptions?.hash ||\n\t\t(typeof maxKeyBytes === \"number\" &&\n\t\t\tmaxKeyBytes > 0 &&\n\t\t\tutf8ByteLength(namespacedKey) > maxKeyBytes);\n\n\tconst resolvedKey = shouldHash\n\t\t? `${namespacePrefix}${hashKey(key)}`\n\t\t: namespacedKey;\n\n\tif (\n\t\ttypeof maxKeyBytes === \"number\" &&\n\t\tmaxKeyBytes > 0 &&\n\t\tutf8ByteLength(resolvedKey) > maxKeyBytes\n\t) {\n\t\tthrow new Error(\n\t\t\t`Resolved KV key exceeds the maximum size of ${maxKeyBytes} bytes. Use a shorter KV namespace.`,\n\t\t);\n\t}\n\n\treturn resolvedKey;\n};\n\n/**\n * Type guard for adapters that provide provider-backed atomic increments.\n */\nexport const supportsKVIncrement = (\n\tadapter: KVAdapterInstance,\n): adapter is KVAdapterInstance & KVIncrementCapability =>\n\ttypeof adapter.increment === \"function\";\n"],"mappings":"oGAQA,MAAa,EAAc,KAcd,EAAsB,GAAoC,CACtE,GAAI,IAAc,IAAA,IAAa,IAAc,GAAO,MAAO,GAE3D,GAAI,EAAU,SAAW,EACxB,MAAU,MACT,2EACD,EAGD,MAAO,GAAG,EAAU,EACrB,EAEM,EAAe,GAA8B,CAClD,IAAI,EAAS,GACP,EAAY,MAElB,IAAK,IAAI,EAAI,EAAG,EAAI,EAAM,OAAQ,GAAK,EAAW,CACjD,IAAM,EAAQ,EAAM,SAAS,EAAG,EAAI,CAAS,EAC7C,GAAU,OAAO,aAAa,GAAG,CAAK,CACvC,CAOA,OAJC,OAAO,MAAS,WACb,KAAK,CAAM,EACX,OAAO,KAAK,CAAK,CAAC,CAAC,SAAS,QAAQ,EAAA,CAE1B,QAAQ,MAAO,GAAG,CAAC,CAAC,QAAQ,MAAO,GAAG,CAAC,CAAC,QAAQ,OAAQ,EAAE,CACzE,EAKa,EAAW,GACvB,KAAiB,EAAY,EAAO,EAAY,CAAG,CAAC,CAAC,IAEhD,EAAkB,GACnB,OAAO,OAAW,IAAoB,OAAO,WAAW,EAAO,MAAM,EAClE,IAAI,WAAW,YAAY,CAAC,CAAC,OAAO,CAAK,CAAC,CAAC,WAG7C,EACL,GAC6B,CAC7B,IAAM,EACL,OAAO,GAAY,SAAW,CAAE,YAAa,CAAQ,EAAK,GAAW,CAAC,EAEvE,MAAO,CACN,GAAG,EACH,gBAAiB,EAAmB,EAAS,SAAS,CACvD,CACD,EAKa,GACZ,EACA,EAGA,IACY,CACZ,GAAM,CAAE,cAAa,mBACpB,EAAuB,CAAc,EAChC,EAAgB,GAAG,IAAkB,IAQrC,EALL,GAAS,MACR,OAAO,GAAgB,UACvB,EAAc,GACd,EAAe,CAAa,EAAI,EAG/B,GAAG,IAAkB,EAAQ,CAAG,IAChC,EAEH,GACC,OAAO,GAAgB,UACvB,EAAc,GACd,EAAe,CAAW,EAAI,EAE9B,MAAU,MACT,+CAA+C,EAAY,oCAC5D,EAGD,OAAO,CACR,EAKa,EACZ,GAEA,OAAO,EAAQ,WAAc"}