t1y-sdk-js 5.0.1 → 5.0.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.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/constants.ts","../src/utils/errors.ts","../src/utils/validators.ts","../src/utils/convert.ts","../src/crypto/sha256.ts","../src/crypto/hmac.ts","../src/crypto/aes-pure.ts","../src/crypto/aes.ts","../src/crypto/sign.ts","../src/utils/url.ts","../src/utils/time.ts","../src/http/response.ts","../src/platform/detect.ts","../src/platform/request/fetch.ts","../src/platform/request/wx.ts","../src/platform/request/my.ts","../src/platform/request/hap.ts","../src/platform/dispatcher.ts","../src/http/request.ts","../src/client/T1Collection.ts","../src/client/T1YOS.ts","../src/special-types/object-id.ts","../src/special-types/date-types.ts","../src/special-types/numeric-types.ts","../src/special-types/structured-types.ts","../src/special-types/null-types.ts","../src/special-types/time-helpers.ts"],"sourcesContent":["/**\n * t1yOS Serverless Platform JavaScript/TypeScript SDK\n *\n * @packageDocumentation\n *\n * @example\n * ```ts\n * import { T1YOS, ObjectID, timeNow } from 't1y-sdk-js'\n *\n * const client = new T1YOS({\n * appId: 1001,\n * apiKey: 'your-api-key-32-characters-here!',\n * secretKey: 'your-secret-key-32-characters!',\n * })\n *\n * await client.init()\n *\n * // Database operations\n * await client.db.collection('users').insertOne({\n * name: 'Alice',\n * age: 25,\n * createdAt: timeNow.Now(),\n * })\n *\n * const { data } = await client.db.collection('users').findOne({ name: 'Alice' })\n * console.log(data.result)\n * ```\n */\n\n// Main client classes\nexport { T1YOS } from './client/T1YOS'\nexport { T1Collection } from './client/T1Collection'\n\n// Special type helpers\nexport {\n ObjectID,\n Date,\n DateTime,\n Timestamp,\n Boolean,\n Integer,\n Bigint,\n Float,\n Double,\n Array,\n Map,\n MapArray,\n Null,\n None,\n Nil,\n Empty,\n UNDEFINED,\n Undefined,\n TimeNow,\n TimeNowUnix,\n TimeNowUnixNano,\n TimeNowWeekday,\n TimeNowWeekdayChinese,\n timeNow,\n} from './special-types'\n\n// Cryptographic utilities (for advanced use)\nexport {\n sha256Hex,\n sha256HexAsync,\n hmacSHA256Hex,\n hmacSHA256HexAsync,\n verifyHmacSHA256,\n encryptAESGCM,\n decryptAESGCM,\n isAESGCMAvailable,\n isWebCryptoAvailable,\n createSignature,\n getSafeTimestamp,\n} from './crypto'\n\n// Utility functions\nexport {\n formatTimestampsToLocal,\n convertDateTypes,\n validateInitConfig,\n validateAppId,\n validateApiKey,\n validateSecretKey,\n validateBaseUrl,\n assertObjectID,\n isNonEmptyObject,\n isPlainObject,\n isNonEmptyArrayWithNonEmptyObjects,\n} from './utils'\n\n// Custom error classes\nexport { T1YError, ValidationError } from './utils/errors'\n\n// Core types\nexport type {\n T1YOSConfig,\n T1YOSInternalConfig,\n HttpMethod,\n ApiResponse,\n InsertResult,\n InsertManyResult,\n DeleteResult,\n DeleteManyResult,\n UpdateResult,\n UpdateManyResult,\n FindResult,\n Pagination,\n PaginationResult,\n AggregateResult,\n InitResult,\n} from './types'\n\nexport type { AESGCMPayload, SignatureInput } from './crypto'\n\n// Special type marker types\nexport type {\n ObjectIDMarker,\n DateMarker,\n DateTimeMarker,\n TimestampMarker,\n BooleanMarker,\n IntegerMarker,\n BigintMarker,\n FloatMarker,\n DoubleMarker,\n ArrayMarker,\n MapMarker,\n MapArrayMarker,\n NullMarker,\n UndefinedMarker,\n TimeNowMarker,\n TimeNowUnixMarker,\n TimeNowUnixNanoMarker,\n TimeNowWeekdayMarker,\n TimeNowWeekdayChineseMarker,\n SpecialTypeMarker,\n} from './types/special-types'\n\n// Platform detection and adapters (for cross-platform usage)\nexport {\n getPlatformType,\n getMiniProgramSubType,\n getMiniProgramAPI,\n resetPlatformDetection,\n} from './platform'\n\nexport type { PlatformType, MiniProgramSubType } from './platform'\n\n// Default export\nexport { default } from './client/T1YOS'\n","/** Default base URL for the t1yOS platform */\nexport const DEFAULT_BASE_URL = 'https://myapp.t1y.net'\n\n/** Minimum valid application ID */\nexport const MIN_APP_ID = 1001\n\n/** Required length for API Key */\nexport const API_KEY_LENGTH = 32\n\n/** Required length for Secret Key */\nexport const SECRET_KEY_LENGTH = 32\n\n/** Default application version */\nexport const DEFAULT_VERSION = 0\n\n/** Default time format for createdAt/updatedAt fields */\nexport const DEFAULT_TIME_FORMAT = 'YYYY-MM-DD HH:mm:ss'\n\n/** Default time offset in seconds */\nexport const DEFAULT_OFFSET = 0\n\n/** Default safe mode setting */\nexport const DEFAULT_SAFE_MODE = false\n\n/** Maximum time difference allowed for request timestamp (seconds) */\nexport const MAX_TIME_DIFF = 10\n\n/** Request timeout in milliseconds (5 minutes) */\nexport const REQUEST_TIMEOUT_MS = 5 * 60 * 1000\n\n/** Maximum page size for find queries */\nexport const MAX_PAGE_SIZE = 100\n\n/** Default page size */\nexport const DEFAULT_PAGE_SIZE = 10\n\n/** ObjectID hex string length */\nexport const OBJECT_ID_LENGTH = 24\n\n/** ObjectID hex pattern */\nexport const OBJECT_ID_PATTERN = /^[0-9a-fA-F]{24}$/\n\n/** API version prefix */\nexport const API_VERSION = 'v5'\n","/**\n * Custom error class for t1yOS SDK errors.\n * Wraps API error responses with code, message, and data.\n */\nexport class T1YError extends Error {\n /** HTTP status or error code */\n code: number\n /** Response data from server (if any) */\n data: unknown\n\n constructor(code: number, message: string, data?: unknown) {\n super(message)\n this.name = 'T1YError'\n this.code = code\n this.data = data\n }\n\n toJSON(): Record<string, unknown> {\n return {\n name: this.name,\n code: this.code,\n message: this.message,\n data: this.data,\n }\n }\n}\n\n/**\n * Validation error thrown when configuration parameters are invalid.\n */\nexport class ValidationError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'ValidationError'\n }\n}\n","import { MIN_APP_ID, API_KEY_LENGTH, SECRET_KEY_LENGTH, OBJECT_ID_PATTERN } from '../constants'\nimport { ValidationError } from './errors'\nimport type { T1YOSConfig } from '../types'\n\n/**\n * Validate that the application ID is a valid integer >= MIN_APP_ID.\n */\nexport function validateAppId(appId: number): void {\n if (!Number.isInteger(appId)) {\n throw new ValidationError('appId must be an integer')\n }\n if (appId < MIN_APP_ID) {\n throw new ValidationError(`appId must be >= ${MIN_APP_ID}`)\n }\n}\n\n/**\n * Validate that the API Key is exactly the required length.\n */\nexport function validateApiKey(apiKey: string): void {\n if (typeof apiKey !== 'string') {\n throw new ValidationError('apiKey must be a string')\n }\n if (apiKey.length !== API_KEY_LENGTH) {\n throw new ValidationError(\n `apiKey must be exactly ${API_KEY_LENGTH} characters (got ${apiKey.length})`\n )\n }\n}\n\n/**\n * Validate that the Secret Key is exactly the required length.\n */\nexport function validateSecretKey(secretKey: string): void {\n if (typeof secretKey !== 'string') {\n throw new ValidationError('secretKey must be a string')\n }\n if (secretKey.length !== SECRET_KEY_LENGTH) {\n throw new ValidationError(\n `secretKey must be exactly ${SECRET_KEY_LENGTH} characters (got ${secretKey.length})`\n )\n }\n}\n\n/**\n * Validate the base URL format.\n */\nexport function validateBaseUrl(baseUrl: string): void {\n if (!/^https?:\\/\\//.test(baseUrl)) {\n throw new ValidationError('baseUrl must start with \"http://\" or \"https://\"')\n }\n}\n\n/**\n * Validate all configuration parameters at once.\n */\nexport function validateInitConfig(config: T1YOSConfig): void {\n if (config.baseUrl !== undefined) {\n validateBaseUrl(config.baseUrl)\n }\n validateAppId(config.appId)\n validateApiKey(config.apiKey)\n validateSecretKey(config.secretKey)\n\n if (config.version !== undefined && (!Number.isInteger(config.version) || config.version < 0)) {\n throw new ValidationError('version must be a non-negative integer')\n }\n}\n\n/**\n * Validate an ObjectID hex string.\n * Returns true if valid, throws otherwise.\n */\nexport function assertObjectID(idStr: string, name = 'ObjectID'): boolean {\n if (typeof idStr !== 'string') {\n throw new ValidationError(`${name} must be a string`)\n }\n if (!OBJECT_ID_PATTERN.test(idStr)) {\n throw new ValidationError(`Invalid ${name} string: \"${idStr}\"`)\n }\n return true\n}\n","/**\n * Recursively convert JavaScript Date objects and timestamp numbers\n * into the marker string format that the server's GetDataTypes() recognizes.\n *\n * - Date objects → `Date('ISO-8601')`\n * - Numbers >= 10 digits → `Timestamp('unix')`\n * - Already-marker strings (starting with recognized prefixes) are passed through\n */\nexport function convertDateTypes(value: unknown): unknown {\n if (value instanceof Date) {\n return `Date('${value.toISOString()}')`\n }\n\n if (typeof value === 'number') {\n const str = String(value)\n // 10+ digit integer → Timestamp\n if (/^\\d{10,}$/.test(str)) {\n return `Timestamp('${str}')`\n }\n return value\n }\n\n if (Array.isArray(value)) {\n return value.map((v) => convertDateTypes(v))\n }\n\n if (value && typeof value === 'object') {\n const obj: Record<string, unknown> = {}\n for (const key in value as Record<string, unknown>) {\n if (Object.prototype.hasOwnProperty.call(value, key)) {\n obj[key] = convertDateTypes((value as Record<string, unknown>)[key])\n }\n }\n return obj\n }\n\n return value\n}\n\n/**\n * Check if a value is a non-null, non-array object with at least one key.\n */\nexport function isNonEmptyObject(value: unknown): boolean {\n return (\n typeof value === 'object' &&\n value !== null &&\n !Array.isArray(value) &&\n Object.keys(value).length > 0\n )\n}\n\n/**\n * Check if a value is a plain object (non-null, non-array).\n */\nexport function isPlainObject(value: unknown): boolean {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\n/**\n * Check if a value is a non-empty array where every element is a non-empty object.\n */\nexport function isNonEmptyArrayWithNonEmptyObjects(value: unknown): boolean {\n if (!Array.isArray(value) || value.length === 0) {\n return false\n }\n return value.every(\n (item) =>\n typeof item === 'object' &&\n item !== null &&\n !Array.isArray(item) &&\n Object.keys(item).length > 0\n )\n}\n","/**\n * SHA-256 hashing — works in both Node.js and browser environments.\n *\n * Node.js (CJS): Uses node:crypto (synchronous via require)\n * Node.js (ESM): Falls back to pure-JS (works correctly for all byte values)\n * Browser: Uses pure-JS implementation\n */\n\n// Detect if require is available (CJS context)\nfunction getNodeRequire(): ((m: string) => unknown) | null {\n try {\n // In CJS, `require` is a local variable\n if (typeof require !== 'undefined') {\n return require\n }\n } catch {\n // require is not defined (ESM or browser)\n }\n return null\n}\n\n/**\n * Compute the SHA-256 hash of a string and return the hex digest.\n *\n * For the signing path: the input is always a UTF-8 string\n * (method, URL, body JSON, etc.), so this works correctly.\n *\n * For raw binary data (from HMAC inner hash), use sha256RawBytesHex instead.\n *\n * @param data - Input string to hash (UTF-8)\n * @returns Hex-encoded SHA-256 hash (64 hex characters)\n */\nexport function sha256Hex(data: string): string {\n const nodeReq = getNodeRequire()\n if (nodeReq) {\n try {\n const nodeCrypto = nodeReq('node:crypto') as {\n createHash: (alg: string) => { update: (d: string) => { digest: (enc: string) => string } }\n }\n return nodeCrypto.createHash('sha256').update(data).digest('hex')\n } catch {\n // fall through to pure-JS\n }\n }\n\n // Pure-JS path: encode string as UTF-8 bytes and hash\n const bytes = utf8ToBytes(data)\n return sha256RawBytesHex(bytes)\n}\n\n/**\n * Compute SHA-256 of raw bytes and return hex digest.\n * Used internally by HMAC for hashing binary key data.\n */\nexport function sha256RawBytesHex(bytes: Uint8Array): string {\n return sha256Raw(bytes)\n}\n\n/**\n * Compute SHA-256 hash asynchronously using Web Crypto API.\n */\nexport async function sha256HexAsync(data: string): Promise<string> {\n const nodeReq = getNodeRequire()\n if (nodeReq) {\n try {\n const nodeCrypto = nodeReq('node:crypto') as {\n createHash: (alg: string) => { update: (d: string) => { digest: (enc: string) => string } }\n }\n return nodeCrypto.createHash('sha256').update(data).digest('hex')\n } catch {\n // fall through\n }\n }\n\n const encoder = new TextEncoder()\n const hashBuffer = await crypto.subtle.digest(\n 'SHA-256',\n encoder.encode(data) as Uint8Array<ArrayBuffer>\n )\n return Array.from(new Uint8Array(hashBuffer))\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('')\n}\n\n// ==================== Pure-JS SHA-256 ====================\n\n/**\n * UTF-8 encode a JavaScript string to Uint8Array.\n * Uses TextEncoder when available, falls back to manual encoding.\n */\nfunction utf8ToBytes(str: string): Uint8Array {\n if (typeof TextEncoder !== 'undefined') {\n return new TextEncoder().encode(str) as Uint8Array<ArrayBuffer>\n }\n // Fallback: manual UTF-8 encoding\n const bytes: number[] = []\n for (let i = 0; i < str.length; i++) {\n let c = str.charCodeAt(i)\n if (c < 0x80) {\n bytes.push(c)\n } else if (c < 0x800) {\n bytes.push(0xc0 | (c >> 6), 0x80 | (c & 0x3f))\n } else if (c < 0xd800 || c >= 0xe000) {\n bytes.push(0xe0 | (c >> 12), 0x80 | ((c >> 6) & 0x3f), 0x80 | (c & 0x3f))\n } else {\n // surrogate pair\n i++\n const c2 = str.charCodeAt(i)\n const cp = 0x10000 + ((c & 0x3ff) << 10) + (c2 & 0x3ff)\n bytes.push(\n 0xf0 | (cp >> 18),\n 0x80 | ((cp >> 12) & 0x3f),\n 0x80 | ((cp >> 6) & 0x3f),\n 0x80 | (cp & 0x3f)\n )\n }\n }\n return new Uint8Array(bytes) as Uint8Array<ArrayBuffer>\n}\n\n/** SHA-256 implementation that operates on raw bytes */\nfunction sha256Raw(bytes: Uint8Array): string {\n const K = [\n 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,\n 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,\n 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,\n 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,\n 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,\n 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,\n 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,\n 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,\n ]\n\n // Build message schedule\n const msgByteLen = bytes.length\n const msgBitLen = msgByteLen * 8\n\n // Allocate padded message: original bytes + 0x80 + zeros + 8-byte length\n const padLen = (64 - ((msgByteLen + 9) % 64)) % 64\n const totalLen = msgByteLen + 1 + padLen + 8\n const padded = new Uint8Array(totalLen)\n padded.set(bytes)\n padded[msgByteLen] = 0x80\n // Write length as 64-bit big-endian\n for (let i = 0; i < 8; i++) {\n padded[totalLen - 8 + i] = Number((BigInt(msgBitLen) >> BigInt((7 - i) * 8)) & BigInt(0xff))\n }\n\n const H = [\n 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19,\n ]\n\n // Process each 512-bit chunk\n for (let offset = 0; offset < totalLen; offset += 64) {\n const W = new Array<number>(64)\n\n for (let t = 0; t < 16; t++) {\n W[t] =\n (padded[offset + t * 4]! << 24) |\n (padded[offset + t * 4 + 1]! << 16) |\n (padded[offset + t * 4 + 2]! << 8) |\n padded[offset + t * 4 + 3]!\n }\n\n for (let t = 16; t < 64; t++) {\n const s0 = (rotr(W[t - 15]!, 7) ^ rotr(W[t - 15]!, 18) ^ (W[t - 15]! >>> 3)) >>> 0\n const s1 = (rotr(W[t - 2]!, 17) ^ rotr(W[t - 2]!, 19) ^ (W[t - 2]! >>> 10)) >>> 0\n W[t] = (W[t - 16]! + s0 + W[t - 7]! + s1) >>> 0\n }\n\n let [a, b, c, d, e, f, g, h] = H\n\n for (let t = 0; t < 64; t++) {\n const S1 = (rotr(e!, 6) ^ rotr(e!, 11) ^ rotr(e!, 25)) >>> 0\n const ch = ((e! & f!) ^ (~e! & g!)) >>> 0\n const temp1 = (h! + S1 + ch + K[t]! + W[t]!) >>> 0\n const S0 = (rotr(a!, 2) ^ rotr(a!, 13) ^ rotr(a!, 22)) >>> 0\n const maj = ((a! & b!) ^ (a! & c!) ^ (b! & c!)) >>> 0\n const temp2 = (S0 + maj) >>> 0\n\n h = g\n g = f\n f = e\n e = (d! + temp1) >>> 0\n d = c\n c = b\n b = a\n a = (temp1 + temp2) >>> 0\n }\n\n H[0] = (H[0]! + a!) >>> 0\n H[1] = (H[1]! + b!) >>> 0\n H[2] = (H[2]! + c!) >>> 0\n H[3] = (H[3]! + d!) >>> 0\n H[4] = (H[4]! + e!) >>> 0\n H[5] = (H[5]! + f!) >>> 0\n H[6] = (H[6]! + g!) >>> 0\n H[7] = (H[7]! + h!) >>> 0\n }\n\n return H.map((v) => v.toString(16).padStart(8, '0')).join('')\n}\n\nfunction rotr(x: number, n: number): number {\n return (x >>> n) | (x << (32 - n))\n}\n","/**\n * HMAC-SHA256 implementation — works in both Node.js and browser environments.\n *\n * Node.js (CJS): Uses node:crypto (synchronous via require)\n * Browser / ESM: Uses pure-JS implementation operating on Uint8Array\n */\n\nimport { sha256RawBytesHex } from './sha256'\n\n// Detect if require is available (CJS context)\nfunction getNodeRequire(): ((m: string) => unknown) | null {\n try {\n if (typeof require !== 'undefined') {\n return require\n }\n } catch {\n // require is not defined (ESM or browser)\n }\n return null\n}\n\n/**\n * Compute HMAC-SHA256 and return hex digest.\n *\n * This is intentionally synchronous because it's called in the request\n * signing path, which must be fast and cannot defer to async.\n *\n * @param secret - The secret key (raw string, used as-is as bytes)\n * @param message - The message to sign\n * @returns Hex-encoded HMAC-SHA256 signature (64 hex characters)\n */\nexport function hmacSHA256Hex(secret: string, message: string): string {\n const nodeReq = getNodeRequire()\n if (nodeReq) {\n try {\n const nodeCrypto = nodeReq('node:crypto') as {\n createHmac: (\n alg: string,\n key: string\n ) => { update: (d: string) => { digest: (enc: string) => string } }\n }\n return nodeCrypto.createHmac('sha256', secret).update(message).digest('hex')\n } catch {\n // fall through to pure-JS\n }\n }\n\n // Pure-JS HMAC-SHA256 implementation\n return hmacSHA256Pure(secret, message)\n}\n\n/**\n * Compute HMAC-SHA256 asynchronously using Web Crypto API.\n */\nexport async function hmacSHA256HexAsync(secret: string, message: string): Promise<string> {\n const nodeReq = getNodeRequire()\n if (nodeReq) {\n try {\n const nodeCrypto = nodeReq('node:crypto') as {\n createHmac: (\n alg: string,\n key: string\n ) => { update: (d: string) => { digest: (enc: string) => string } }\n }\n return nodeCrypto.createHmac('sha256', secret).update(message).digest('hex')\n } catch {\n // fall through\n }\n }\n\n const encoder = new TextEncoder()\n const key = await crypto.subtle.importKey(\n 'raw',\n encoder.encode(secret) as Uint8Array<ArrayBuffer>,\n { name: 'HMAC', hash: 'SHA-256' },\n false,\n ['sign']\n )\n const signature = await crypto.subtle.sign(\n 'HMAC',\n key,\n encoder.encode(message) as Uint8Array<ArrayBuffer>\n )\n return Array.from(new Uint8Array(signature))\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('')\n}\n\n/**\n * Verify an HMAC-SHA256 signature using constant-time comparison.\n */\nexport function verifyHmacSHA256(secret: string, message: string, signature: string): boolean {\n if (typeof signature !== 'string') return false\n const expected = hmacSHA256Hex(secret, message)\n return timingSafeEqual(expected, signature.toLowerCase())\n}\n\n/** Constant-time string comparison */\nfunction timingSafeEqual(a: string, b: string): boolean {\n if (a.length !== b.length) return false\n let result = 0\n for (let i = 0; i < a.length; i++) {\n result |= a.charCodeAt(i) ^ b.charCodeAt(i)\n }\n return result === 0\n}\n\n// ==================== Pure-JS HMAC-SHA256 ====================\n\n/**\n * HMAC-SHA256 using only pure-JS SHA-256 (byte-oriented).\n *\n * Implements: HMAC(K, m) = H((K' XOR opad) || H((K' XOR ipad) || m))\n * where H is SHA-256, K' is the processed key, ipad=0x36, opad=0x5c\n *\n * This implementation uses Uint8Array for ALL binary data,\n * avoiding the corruption issue with raw-byte-in-JS-strings.\n */\nfunction hmacSHA256Pure(secret: string, message: string): string {\n const BLOCK_SIZE = 64\n\n // Convert secret and message to UTF-8 bytes\n let keyBytes = utf8ToBytes(secret)\n const msgBytes = utf8ToBytes(message)\n\n // If key is longer than block size, hash it first\n if (keyBytes.length > BLOCK_SIZE) {\n keyBytes = hexToBytes(sha256RawBytesHex(keyBytes))\n }\n\n // Pad key to block size (or truncate — should not happen for SHA-256)\n const paddedKey = new Uint8Array(BLOCK_SIZE)\n paddedKey.set(keyBytes.subarray(0, Math.min(keyBytes.length, BLOCK_SIZE)))\n // rest is already zero-initialized\n\n // Compute inner: H((key XOR ipad) || message)\n const ipad = new Uint8Array(BLOCK_SIZE)\n ipad.fill(0x36)\n const innerKey = xorBytes(paddedKey, ipad)\n const innerData = new Uint8Array(BLOCK_SIZE + msgBytes.length)\n innerData.set(innerKey)\n innerData.set(msgBytes, BLOCK_SIZE)\n const innerHash = hexToBytes(sha256RawBytesHex(innerData))\n\n // Compute outer: H((key XOR opad) || innerHash)\n const opad = new Uint8Array(BLOCK_SIZE)\n opad.fill(0x5c)\n const outerKey = xorBytes(paddedKey, opad)\n const outerData = new Uint8Array(BLOCK_SIZE + innerHash.length)\n outerData.set(outerKey)\n outerData.set(innerHash, BLOCK_SIZE)\n\n return sha256RawBytesHex(outerData)\n}\n\n/** XOR two Uint8Arrays (must be same length) */\nfunction xorBytes(a: Uint8Array, b: Uint8Array): Uint8Array {\n const result = new Uint8Array(a.length)\n for (let i = 0; i < a.length; i++) {\n result[i] = a[i]! ^ b[i]!\n }\n return result as Uint8Array<ArrayBuffer>\n}\n\n/** UTF-8 encode a string to Uint8Array */\nfunction utf8ToBytes(str: string): Uint8Array {\n if (typeof TextEncoder !== 'undefined') {\n return new TextEncoder().encode(str) as Uint8Array<ArrayBuffer>\n }\n // Fallback for ancient browsers\n const bytes: number[] = []\n for (let i = 0; i < str.length; i++) {\n let c = str.charCodeAt(i)\n if (c < 0x80) {\n bytes.push(c)\n } else if (c < 0x800) {\n bytes.push(0xc0 | (c >> 6), 0x80 | (c & 0x3f))\n } else if (c < 0xd800 || c >= 0xe000) {\n bytes.push(0xe0 | (c >> 12), 0x80 | ((c >> 6) & 0x3f), 0x80 | (c & 0x3f))\n } else {\n i++\n const c2 = str.charCodeAt(i)\n const cp = 0x10000 + ((c & 0x3ff) << 10) + (c2 & 0x3ff)\n bytes.push(\n 0xf0 | (cp >> 18),\n 0x80 | ((cp >> 12) & 0x3f),\n 0x80 | ((cp >> 6) & 0x3f),\n 0x80 | (cp & 0x3f)\n )\n }\n }\n return new Uint8Array(bytes) as Uint8Array<ArrayBuffer>\n}\n\n/** Convert hex string to Uint8Array */\nfunction hexToBytes(hex: string): Uint8Array {\n const bytes = new Uint8Array(hex.length / 2)\n for (let i = 0; i < hex.length; i += 2) {\n bytes[i / 2] = parseInt(hex.substring(i, i + 2), 16)\n }\n return bytes as Uint8Array<ArrayBuffer>\n}\n","/**\n * Pure JavaScript AES-256-GCM implementation.\n *\n * This is a fallback for environments that do not have the Web Crypto API\n * (e.g., WeChat Mini Program, Alipay Mini Program, Quick App).\n *\n * Implements:\n * - AES-256 block cipher (14 rounds, 256-bit key)\n * - GCM mode: CTR encryption + GHASH authentication\n *\n * References:\n * - FIPS 197: Advanced Encryption Standard (AES)\n * - NIST SP 800-38D: Galois/Counter Mode (GCM)\n *\n * IMPORTANT: This implementation is NOT constant-time and should only be\n * used as a fallback. In Web browsers and Node.js, the native Web Crypto API\n * implementation in aes.ts is preferred.\n */\n\n// ==================== AES S-Box and Inverse S-Box ====================\n\nconst SBOX: number[] = [\n 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,\n 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,\n 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,\n 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,\n 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,\n 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,\n 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,\n 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,\n 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,\n 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,\n 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,\n 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,\n 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,\n 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,\n 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,\n 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16,\n]\n\n// Round constants\nconst RCON: number[] = [0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36]\n\n// ==================== AES Key Expansion (256-bit key) ====================\n\n/**\n * Expand a 256-bit (32-byte) key into 15 round keys (60 words of 4 bytes each).\n * AES-256 uses 14 rounds, needing 15 round keys (including the initial key).\n */\nfunction keyExpansion256(key: Uint8Array): Uint8Array[] {\n if (key.length !== 32) {\n throw new Error('AES-256 requires a 32-byte key')\n }\n\n const Nk = 8 // 256-bit key = 8 words\n const Nr = 14 // 14 rounds for AES-256\n const Nb = 4 // 4 words per block\n\n // Total words = Nb * (Nr + 1) = 4 * 15 = 60\n const totalWords = Nb * (Nr + 1)\n const words: number[] = new Array(totalWords)\n\n // Copy key into first Nk words\n for (let i = 0; i < Nk; i++) {\n words[i] =\n (key[4 * i]! << 24) | (key[4 * i + 1]! << 16) | (key[4 * i + 2]! << 8) | key[4 * i + 3]!\n }\n\n // Expand\n for (let i = Nk; i < totalWords; i++) {\n let temp = words[i - 1]!\n\n if (i % Nk === 0) {\n // RotWord + SubWord + Rcon\n temp = subWord(rotWord(temp)) ^ (RCON[Math.floor(i / Nk) - 1]! << 24)\n } else if (Nk > 6 && i % Nk === 4) {\n // Extra SubWord for AES-256 every 4th iteration after the first Nk\n temp = subWord(temp)\n }\n\n words[i] = words[i - Nk]! ^ temp\n }\n\n // Convert to round keys (Uint8Array per round)\n const roundKeys: Uint8Array[] = []\n for (let r = 0; r <= Nr; r++) {\n const rk = new Uint8Array(16)\n for (let j = 0; j < 4; j++) {\n const w = words[r * 4 + j]!\n rk[4 * j] = (w >>> 24) & 0xff\n rk[4 * j + 1] = (w >>> 16) & 0xff\n rk[4 * j + 2] = (w >>> 8) & 0xff\n rk[4 * j + 3] = w & 0xff\n }\n roundKeys.push(rk)\n }\n\n return roundKeys\n}\n\nfunction rotWord(w: number): number {\n return ((w << 8) | (w >>> 24)) >>> 0\n}\n\nfunction subWord(w: number): number {\n return (\n ((SBOX[(w >>> 24) & 0xff]! << 24) |\n (SBOX[(w >>> 16) & 0xff]! << 16) |\n (SBOX[(w >>> 8) & 0xff]! << 8) |\n (SBOX[w & 0xff]! << 0)) >>>\n 0\n )\n}\n\n// ==================== AES Block Encrypt ====================\n\n/**\n * Encrypt a single 16-byte block using AES-256.\n */\nfunction aesEncryptBlock(block: Uint8Array, roundKeys: Uint8Array[]): Uint8Array {\n if (block.length !== 16) {\n throw new Error('AES block must be exactly 16 bytes')\n }\n\n const state: number[][] = [[], [], [], []]\n\n // Load block into state (column-major order)\n for (let i = 0; i < 4; i++) {\n for (let j = 0; j < 4; j++) {\n state[j]![i] = block[i * 4 + j]!\n }\n }\n\n const Nr = 14 // AES-256\n\n // Initial AddRoundKey\n addRoundKey(state, roundKeys[0]!)\n\n // Rounds 1 through Nr-1 (13 rounds)\n for (let round = 1; round < Nr; round++) {\n subBytes(state)\n shiftRows(state)\n mixColumns(state)\n addRoundKey(state, roundKeys[round]!)\n }\n\n // Final round (no MixColumns)\n subBytes(state)\n shiftRows(state)\n addRoundKey(state, roundKeys[Nr]!)\n\n // Extract state into output block\n const out = new Uint8Array(16)\n for (let i = 0; i < 4; i++) {\n for (let j = 0; j < 4; j++) {\n out[i * 4 + j] = state[j]![i]!\n }\n }\n\n return out\n}\n\nfunction subBytes(state: number[][]): void {\n for (let i = 0; i < 4; i++) {\n for (let j = 0; j < 4; j++) {\n state[i]![j] = SBOX[state[i]![j]!]!\n }\n }\n}\n\nfunction shiftRows(state: number[][]): void {\n for (let i = 1; i < 4; i++) {\n const row = state[i]!\n state[i] = [row[i % 4]!, row[(i + 1) % 4]!, row[(i + 2) % 4]!, row[(i + 3) % 4]!]\n }\n}\n\nfunction mixColumns(state: number[][]): void {\n for (let i = 0; i < 4; i++) {\n const a: number[] = []\n for (let j = 0; j < 4; j++) {\n a[j] = state[j]![i]!\n }\n\n state[0]![i] = gmul(2, a[0]!) ^ gmul(3, a[1]!) ^ a[2]! ^ a[3]!\n state[1]![i] = a[0]! ^ gmul(2, a[1]!) ^ gmul(3, a[2]!) ^ a[3]!\n state[2]![i] = a[0]! ^ a[1]! ^ gmul(2, a[2]!) ^ gmul(3, a[3]!)\n state[3]![i] = gmul(3, a[0]!) ^ a[1]! ^ a[2]! ^ gmul(2, a[3]!)\n }\n}\n\nfunction addRoundKey(state: number[][], roundKey: Uint8Array): void {\n for (let i = 0; i < 4; i++) {\n for (let j = 0; j < 4; j++) {\n state[j]![i] = state[j]![i]! ^ roundKey[i * 4 + j]!\n }\n }\n}\n\n/** Galois field multiplication in GF(2^8) */\nfunction gmul(a: number, b: number): number {\n let p = 0\n let aa = a\n let bb = b\n for (let i = 0; i < 8; i++) {\n if (bb & 1) p ^= aa\n const hiBit = aa & 0x80\n aa = (aa << 1) & 0xff\n if (hiBit) aa ^= 0x1b\n bb >>= 1\n }\n return p\n}\n\n// ==================== AES-CTR Mode ====================\n\n/**\n * AES-256-CTR encryption/decryption (they are the same operation in CTR mode).\n */\nfunction aesCtr(key: Uint8Array, counter: Uint8Array, data: Uint8Array): Uint8Array {\n const roundKeys = keyExpansion256(key)\n const blockCount = Math.ceil(data.length / 16)\n const output = new Uint8Array(data.length)\n\n const ctr = new Uint8Array(counter) // Copy counter so we can increment it\n\n for (let i = 0; i < blockCount; i++) {\n // Encrypt the counter block\n const keystream = aesEncryptBlock(ctr, roundKeys)\n\n // XOR with plaintext/ciphertext\n const blockLen = Math.min(16, data.length - i * 16)\n for (let j = 0; j < blockLen; j++) {\n output[i * 16 + j] = data[i * 16 + j]! ^ keystream[j]!\n }\n\n // Increment counter (big-endian, 32-bit last 4 bytes)\n incrementCounter(ctr)\n }\n\n return output\n}\n\nfunction incrementCounter(ctr: Uint8Array): void {\n // Increment the last 4 bytes as a 32-bit big-endian integer\n for (let i = 15; i >= 12; i--) {\n const val = ctr[i]! + 1\n ctr[i] = val & 0xff\n if (val <= 0xff) break\n }\n}\n\n// ==================== 64-bit Big-Endian Helpers ====================\n\n/**\n * Write a 64-bit unsigned integer in big-endian format.\n * Uses Number (not BigInt) for compatibility with ES2017 and older targets.\n * The value must be within Number.MAX_SAFE_INTEGER (2^53 - 1).\n */\nfunction writeUint64BE(buf: Uint8Array, offset: number, value: number): void {\n // High 32 bits\n const hi = Math.floor(value / 0x100000000)\n // Low 32 bits\n const lo = value % 0x100000000\n buf[offset] = (hi >>> 24) & 0xff\n buf[offset + 1] = (hi >>> 16) & 0xff\n buf[offset + 2] = (hi >>> 8) & 0xff\n buf[offset + 3] = hi & 0xff\n buf[offset + 4] = (lo >>> 24) & 0xff\n buf[offset + 5] = (lo >>> 16) & 0xff\n buf[offset + 6] = (lo >>> 8) & 0xff\n buf[offset + 7] = lo & 0xff\n}\n\n// ==================== GHASH (GCM Authentication) ====================\n\n/**\n * GHASH: Galois field multiplication-based hash used in GCM.\n *\n * Computes the authentication tag over the AAD (additional authenticated data)\n * and ciphertext using the hash subkey H.\n */\nfunction ghash(h: Uint8Array, aad: Uint8Array, ciphertext: Uint8Array): Uint8Array {\n const blockSize = 16\n\n // Number of blocks needed\n const aadBlocks = Math.ceil(aad.length / blockSize)\n const ctBlocks = Math.ceil(ciphertext.length / blockSize)\n const totalBlocks = aadBlocks + ctBlocks + 1 // +1 for the length block\n\n // Initialize Y to zero\n const y = new Uint8Array(blockSize)\n\n // Process AAD\n for (let i = 0; i < aadBlocks; i++) {\n const block = new Uint8Array(blockSize)\n const offset = i * blockSize\n const len = Math.min(blockSize, aad.length - offset)\n for (let j = 0; j < len; j++) {\n block[j] = aad[offset + j]!\n }\n // XOR with Y, then multiply by H\n for (let j = 0; j < blockSize; j++) {\n block[j] ^= y[j]!\n }\n const mulResult = gfMul(block, h)\n y.set(mulResult)\n }\n\n // Process ciphertext\n for (let i = 0; i < ctBlocks; i++) {\n const block = new Uint8Array(blockSize)\n const offset = i * blockSize\n const len = Math.min(blockSize, ciphertext.length - offset)\n for (let j = 0; j < len; j++) {\n block[j] = ciphertext[offset + j]!\n }\n // XOR with Y, then multiply by H\n for (let j = 0; j < blockSize; j++) {\n block[j] ^= y[j]!\n }\n const mulResult = gfMul(block, h)\n y.set(mulResult)\n }\n\n // Process length block: [len(AAD) in bits (64-bit BE)] || [len(C) in bits (64-bit BE)]\n // Using Number instead of BigInt for compatibility with older ES targets.\n // GCM max data size is ~64GB (2^36 bits), well within Number.MAX_SAFE_INTEGER (2^53).\n const lenBlock = new Uint8Array(blockSize)\n const aadBitLen = aad.length * 8\n const ctBitLen = ciphertext.length * 8\n writeUint64BE(lenBlock, 0, aadBitLen)\n writeUint64BE(lenBlock, 8, ctBitLen)\n for (let j = 0; j < blockSize; j++) {\n lenBlock[j] ^= y[j]!\n }\n const tag = gfMul(lenBlock, h)\n\n return tag\n}\n\n/**\n * Galois field multiplication in GF(2^128).\n *\n * Used by GHASH to compute the authentication tag.\n * Operates on 16-byte blocks interpreted as elements of GF(2^128).\n */\nfunction gfMul(x: Uint8Array, y: Uint8Array): Uint8Array {\n const result = new Uint8Array(16)\n const v = new Uint8Array(y) // Copy y so we can shift it\n\n // R = 0xE1 << 120 (reduction polynomial for GCM)\n // Process each bit of x from LSB to MSB\n for (let byteIdx = 0; byteIdx < 16; byteIdx++) {\n for (let bit = 0; bit < 8; bit++) {\n if ((x[15 - byteIdx]! >> (7 - bit)) & 1) {\n // result ^= v\n for (let k = 0; k < 16; k++) {\n result[k] ^= v[k]!\n }\n }\n\n // v >>= 1 (shift right, LSB first in GCM convention)\n const lsb = v[15]! & 1\n for (let k = 15; k > 0; k--) {\n v[k] = (v[k]! >> 1) | ((v[k - 1]! & 1) << 7)\n }\n v[0] = v[0]! >> 1\n\n if (lsb) {\n v[0] ^= 0xe1 // Reduction polynomial applied at the MSB\n }\n }\n }\n\n return result\n}\n\n// ==================== GCM Encrypt / Decrypt ====================\n\n/**\n * AES-256-GCM encryption.\n *\n * @param plaintext - Data to encrypt (Uint8Array)\n * @param key - 32-byte AES-256 key\n * @param nonce - 12-byte nonce/IV\n * @param aad - Additional authenticated data (Uint8Array, can be empty)\n * @returns { ciphertext, tag } where tag is 16 bytes\n */\nexport function aesGcmEncryptPure(\n plaintext: Uint8Array,\n key: Uint8Array,\n nonce: Uint8Array,\n aad: Uint8Array = new Uint8Array(0)\n): { ciphertext: Uint8Array; tag: Uint8Array } {\n if (key.length !== 32) {\n throw new Error('key length must be 32 bytes for AES-256-GCM')\n }\n if (nonce.length !== 12) {\n throw new Error('nonce length must be 12 bytes for AES-256-GCM')\n }\n\n // Build initial counter block: nonce (12 bytes) || counter (4 bytes, starting at 1)\n // Using 32-bit counter (last 4 bytes of 16-byte block)\n const j0 = new Uint8Array(16)\n j0.set(nonce)\n j0[15] = 1 // Counter starts at 1 (J0 is used for GHASH, counter from 1 for encryption)\n\n // Encrypt plaintext with AES-CTR starting at J0\n // Actually, GCM uses the initial counter block for the tag, and J0+1 for encryption\n // Let me re-read the spec...\n\n // GCM uses:\n // - J0 (nonce || counter=1) for the final GHASH XOR\n // - Counter blocks starting from inc32(J0) for encryption\n // Wait, actually the standard says:\n // If len(IV) == 96 bits (12 bytes): J0 = IV || 0^31 || 1\n // Then encryption uses inc32(J0), inc32(inc32(J0)), etc.\n // And the tag is GHASH(...) XOR GCTR(J0, ...)\n\n // Actually, let me follow the NIST spec more carefully:\n // J0 = IV || 0^31 || 1 (for 96-bit IV)\n // Let inc32(X) increment the last 32 bits of X\n // The ciphertext is GCTR(inc32(J0), P)\n // The tag is GHASH(H, A, C) XOR GCTR(J0, GHASH(H, A, C))\n\n const roundKeys = keyExpansion256(key)\n\n // Compute H = AES(K, 0^128)\n const zeroBlock = new Uint8Array(16)\n const h = aesEncryptBlock(zeroBlock, roundKeys)\n\n // Build J0\n const j0Block = new Uint8Array(16)\n j0Block.set(nonce)\n j0Block[15] = 1 // Counter = 1 for J0\n\n // Build first encryption counter = inc32(J0)\n const ctrBlock = new Uint8Array(j0Block)\n incrementCounter(ctrBlock)\n\n // Encrypt plaintext with AES-CTR\n const ciphertext = aesCtr(key, ctrBlock, plaintext)\n\n // Compute GHASH over AAD and ciphertext\n const s = ghash(h, aad, ciphertext)\n\n // Compute tag = S XOR GCTR(J0, S)\n const encryptedS = aesCtr(key, j0Block, s) // Using J0 as the initial counter\n const tag = new Uint8Array(16)\n for (let i = 0; i < 16; i++) {\n tag[i] = s[i]! ^ encryptedS[i]!\n }\n\n return { ciphertext, tag }\n}\n\n/**\n * AES-256-GCM decryption.\n *\n * @param ciphertext - Data to decrypt (Uint8Array)\n * @param tag - 16-byte authentication tag\n * @param key - 32-byte AES-256 key\n * @param nonce - 12-byte nonce/IV\n * @param aad - Additional authenticated data (Uint8Array, can be empty)\n * @returns Decrypted plaintext (Uint8Array)\n * @throws {Error} If authentication fails (tag mismatch)\n */\nexport function aesGcmDecryptPure(\n ciphertext: Uint8Array,\n tag: Uint8Array,\n key: Uint8Array,\n nonce: Uint8Array,\n aad: Uint8Array = new Uint8Array(0)\n): Uint8Array {\n if (key.length !== 32) {\n throw new Error('key length must be 32 bytes for AES-256-GCM')\n }\n if (nonce.length !== 12) {\n throw new Error('nonce length must be 12 bytes for AES-256-GCM')\n }\n if (tag.length !== 16) {\n throw new Error('tag length must be 16 bytes for AES-256-GCM')\n }\n\n const roundKeys = keyExpansion256(key)\n\n // Compute H = AES(K, 0^128)\n const zeroBlock = new Uint8Array(16)\n const h = aesEncryptBlock(zeroBlock, roundKeys)\n\n // Build J0\n const j0Block = new Uint8Array(16)\n j0Block.set(nonce)\n j0Block[15] = 1\n\n // Verify authentication tag FIRST\n const s = ghash(h, aad, ciphertext)\n const encryptedS = aesCtr(key, j0Block, s)\n const expectedTag = new Uint8Array(16)\n for (let i = 0; i < 16; i++) {\n expectedTag[i] = s[i]! ^ encryptedS[i]!\n }\n\n // Constant-time tag comparison\n let mismatch = 0\n for (let i = 0; i < 16; i++) {\n mismatch |= tag[i]! ^ expectedTag[i]!\n }\n if (mismatch !== 0) {\n throw new Error('AES-256-GCM authentication failed: tag mismatch')\n }\n\n // Build encryption counter = inc32(J0)\n const ctrBlock = new Uint8Array(j0Block)\n incrementCounter(ctrBlock)\n\n // Decrypt (CTR mode: decryption is same as encryption)\n return aesCtr(key, ctrBlock, ciphertext)\n}\n","/**\n * AES-256-GCM encryption and decryption.\n *\n * Compatible with the t1yOS Go server's AES-256-GCM implementation.\n * Payload format: { \"n\": \"<nonce base64>\", \"j\": \"<ciphertext base64>\", \"t\": \"<tag base64>\" }\n *\n * Uses Web Crypto API when available (Web browsers, Node.js), with automatic\n * fallback to pure-JS implementation for environments without Web Crypto\n * (WeChat/QQ/Alipay Mini Programs, Quick App, etc.).\n */\n\nimport { aesGcmEncryptPure, aesGcmDecryptPure } from './aes-pure'\n\n// Detect Web Crypto API (browser globalThis.crypto.subtle or Node require('node:crypto').webcrypto)\nfunction getWebCrypto(): {\n subtle: SubtleCrypto\n getRandomValues: (arr: Uint8Array) => Uint8Array\n} | null {\n try {\n if (typeof globalThis !== 'undefined') {\n // Browser\n if (typeof globalThis.crypto !== 'undefined' && globalThis.crypto.subtle) {\n return globalThis.crypto as ReturnType<typeof getWebCrypto>\n }\n // Node.js — try node:crypto.webcrypto\n try {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const nodeReq = typeof require !== 'undefined' ? require : null\n if (nodeReq) {\n const nodeCryptoModule = nodeReq('node:crypto') as {\n webcrypto: { subtle: SubtleCrypto; getRandomValues: (arr: Uint8Array) => Uint8Array }\n }\n if (nodeCryptoModule?.webcrypto) {\n return nodeCryptoModule.webcrypto\n }\n }\n } catch {\n // fall through\n }\n }\n } catch {\n // globalThis not available\n }\n return null\n}\n\n/**\n * Check whether AES-256-GCM encryption/decryption is available in the current environment.\n *\n * Web Crypto API is available in modern browsers and Node.js.\n * In mini programs (WeChat/QQ/Alipay) and Quick App, the pure-JS fallback is used.\n *\n * @returns `true` if AES-256-GCM is available (always true since we have pure-JS fallback)\n */\nexport function isAESGCMAvailable(): boolean {\n // With pure-JS fallback, AES-GCM is always available\n return true\n}\n\n/**\n * Check whether the native Web Crypto API is available (faster than pure-JS fallback).\n */\nexport function isWebCryptoAvailable(): boolean {\n return getWebCrypto() !== null\n}\n\n// ==================== GCM constants ====================\n\n/** GCM authentication tag length in bytes */\nconst AES_GCM_TAG_LENGTH = 16\n\n/** AES-GCM nonce/IV length in bytes */\nconst AES_GCM_NONCE_LENGTH = 12\n\n// ==================== Base64 helpers ====================\n\n/** Get random bytes using the best available source */\nfunction getRandomBytes(length: number): Uint8Array {\n const wc = getWebCrypto()\n if (wc) {\n const bytes = new Uint8Array(length)\n wc.getRandomValues(bytes)\n return bytes\n }\n\n // Fallback: Math.random-based (NOT cryptographically secure, but works everywhere)\n // For mini programs, they may have their own random API (e.g., wx.getRandomValues)\n try {\n if (\n typeof wx !== 'undefined' &&\n typeof (wx as Record<string, unknown>).getRandomValues === 'function'\n ) {\n const bytes = new Uint8Array(length)\n ;(wx as unknown as { getRandomValues: (arr: Uint8Array) => Uint8Array }).getRandomValues(\n bytes\n )\n return bytes\n }\n } catch {\n // fall through\n }\n\n // Last resort: Math.random (NOT cryptographically secure)\n const bytes = new Uint8Array(length)\n for (let i = 0; i < length; i++) {\n bytes[i] = Math.floor(Math.random() * 256)\n }\n return bytes\n}\n\nfunction encodeBase64(uint8array: Uint8Array): string {\n let binary = ''\n const len = uint8array.byteLength\n for (let i = 0; i < len; i++) {\n binary += String.fromCharCode(uint8array[i]!)\n }\n return btoa(binary)\n}\n\nfunction decodeBase64(b64: string): Uint8Array {\n const binary = atob(b64)\n const len = binary.length\n const bytes = new Uint8Array(len)\n for (let i = 0; i < len; i++) {\n bytes[i] = binary.charCodeAt(i)\n }\n return bytes\n}\n\n// ==================== Public API types ====================\n\n/**\n * AES-256-GCM encrypted payload structure.\n * Matches the Go server's AESGCMEncryptedPayload struct.\n */\nexport interface AESGCMPayload {\n /** Base64-encoded nonce */\n n: string\n /** Base64-encoded ciphertext */\n j: string\n /** Base64-encoded authentication tag */\n t: string\n}\n\n// ==================== Web Crypto implementation ====================\n\nasync function encryptAESGCMWebCrypto(data: string, keyBytes: Uint8Array): Promise<string> {\n const cryptoApi = getWebCrypto()!\n if (!cryptoApi) {\n throw new Error('Web Crypto API is not available')\n }\n\n const key = await cryptoApi.subtle.importKey(\n 'raw',\n keyBytes as Uint8Array<ArrayBuffer>,\n 'AES-GCM',\n false,\n ['encrypt']\n )\n\n const nonce = new Uint8Array(AES_GCM_NONCE_LENGTH)\n cryptoApi.getRandomValues(nonce)\n\n const encodedData = new TextEncoder().encode(data) as Uint8Array<ArrayBuffer>\n\n const encrypted = new Uint8Array(\n await cryptoApi.subtle.encrypt(\n { name: 'AES-GCM', iv: nonce as Uint8Array<ArrayBuffer>, tagLength: 128 },\n key,\n encodedData\n )\n )\n\n const ciphertext = encrypted.slice(0, encrypted.length - AES_GCM_TAG_LENGTH)\n const tag = encrypted.slice(encrypted.length - AES_GCM_TAG_LENGTH)\n\n const payload: AESGCMPayload = {\n n: encodeBase64(nonce),\n j: encodeBase64(ciphertext),\n t: encodeBase64(tag),\n }\n\n return JSON.stringify(payload)\n}\n\nasync function decryptAESGCMWebCrypto(jsonPayload: string, keyBytes: Uint8Array): Promise<string> {\n const cryptoApi = getWebCrypto()!\n if (!cryptoApi) {\n throw new Error('Web Crypto API is not available')\n }\n\n const { n, j, t } = JSON.parse(jsonPayload) as AESGCMPayload\n\n const nonce = decodeBase64(n)\n const ciphertext = decodeBase64(j)\n const tag = decodeBase64(t)\n\n const sealed = new Uint8Array(ciphertext.length + tag.length)\n sealed.set(ciphertext)\n sealed.set(tag, ciphertext.length)\n\n const key = await cryptoApi.subtle.importKey(\n 'raw',\n keyBytes as Uint8Array<ArrayBuffer>,\n 'AES-GCM',\n false,\n ['decrypt']\n )\n\n const decrypted = await cryptoApi.subtle.decrypt(\n { name: 'AES-GCM', iv: nonce as Uint8Array<ArrayBuffer>, tagLength: 128 },\n key,\n sealed as Uint8Array<ArrayBuffer>\n )\n\n return new TextDecoder().decode(decrypted)\n}\n\n// ==================== Pure-JS fallback implementation ====================\n\nfunction encryptAESGCMPure(data: string, keyBytes: Uint8Array): string {\n const nonce = getRandomBytes(AES_GCM_NONCE_LENGTH)\n const plaintext = new TextEncoder().encode(data)\n\n const { ciphertext, tag } = aesGcmEncryptPure(plaintext, keyBytes, nonce)\n\n const payload: AESGCMPayload = {\n n: encodeBase64(nonce),\n j: encodeBase64(ciphertext),\n t: encodeBase64(tag),\n }\n\n return JSON.stringify(payload)\n}\n\nfunction decryptAESGCMPure(jsonPayload: string, keyBytes: Uint8Array): string {\n const { n, j, t } = JSON.parse(jsonPayload) as AESGCMPayload\n\n const nonce = decodeBase64(n)\n const ciphertext = decodeBase64(j)\n const tag = decodeBase64(t)\n\n const decrypted = aesGcmDecryptPure(ciphertext, tag, keyBytes, nonce)\n\n return new TextDecoder().decode(decrypted)\n}\n\n// ==================== Unified public API ====================\n\n/**\n * Encrypt data using AES-256-GCM.\n *\n * Uses Web Crypto API when available (faster), falls back to pure-JS\n * implementation in environments without Web Crypto (mini programs, Quick App).\n *\n * @param data - The plaintext data to encrypt (string)\n * @param keyBytes - 32-byte encryption key (Uint8Array)\n * @returns JSON string of { n, j, t } payload\n */\nexport async function encryptAESGCM(data: string, keyBytes: Uint8Array): Promise<string> {\n if (!(keyBytes instanceof Uint8Array)) {\n throw new Error('key must be Uint8Array')\n }\n if (keyBytes.length !== 32) {\n throw new Error('key length must be 32 bytes for AES-256-GCM')\n }\n\n if (getWebCrypto()) {\n return await encryptAESGCMWebCrypto(data, keyBytes)\n }\n\n // Pure-JS fallback (synchronous, but wrapped in async for consistent API)\n return encryptAESGCMPure(data, keyBytes)\n}\n\n/**\n * Decrypt data using AES-256-GCM.\n *\n * Uses Web Crypto API when available (faster), falls back to pure-JS\n * implementation in environments without Web Crypto (mini programs, Quick App).\n *\n * @param jsonPayload - JSON string of { n, j, t } payload\n * @param keyBytes - 32-byte decryption key (Uint8Array)\n * @returns Decrypted plaintext string\n */\nexport async function decryptAESGCM(jsonPayload: string, keyBytes: Uint8Array): Promise<string> {\n if (!(keyBytes instanceof Uint8Array)) {\n throw new Error('key must be Uint8Array')\n }\n if (keyBytes.length !== 32) {\n throw new Error('key length must be 32 bytes for AES-256-GCM')\n }\n\n if (getWebCrypto()) {\n return await decryptAESGCMWebCrypto(jsonPayload, keyBytes)\n }\n\n // Pure-JS fallback\n return decryptAESGCMPure(jsonPayload, keyBytes)\n}\n","/**\n * Request signing algorithm for T1Y v5 RESTful API authentication.\n *\n * Implements the same signing logic as the Go server's middleware/v5_auth.go:\n *\n * message = METHOD + \"\\n\" + URL_PATH_AND_QUERY + \"\\n\" + SHA256(body) + \"\\n\" + appId + \"\\n\" + timestamp\n * signature = HMAC-SHA256(secretKey, message)\n */\n\nimport { sha256Hex } from './sha256'\nimport { hmacSHA256Hex } from './hmac'\n\n/**\n * Parameters for creating a request signature.\n */\nexport interface SignatureInput {\n /** HTTP method in uppercase (GET, POST, PUT, DELETE) */\n method: string\n /** URL path including query string, e.g. /v5/classes/users?field=name */\n pathAndQuery: string\n /** Request body as a raw string (empty string for GET requests) */\n body: string\n /** Application ID */\n appId: number\n /** 10-digit Unix timestamp (UTC + offset) */\n timestamp: number\n /** 32-character Secret Key */\n secretKey: string\n}\n\n/**\n * Create an HMAC-SHA256 signature for a T1Y API request.\n *\n * The message format is (each line separated by \\n):\n * 1. HTTP method (uppercase)\n * 2. URL path + query string\n * 3. SHA-256 hex digest of the request body\n * 4. Application ID (as string)\n * 5. Unix timestamp (as string)\n *\n * @param input - Signature parameters\n * @returns 64-character hex-encoded HMAC-SHA256 signature\n *\n * @example\n * ```ts\n * const sign = createSignature({\n * method: 'POST',\n * pathAndQuery: '/v5/classes/users',\n * body: '{\"name\":\"Alice\"}',\n * appId: 1001,\n * timestamp: 1705312200,\n * secretKey: '17b784e359c946ffa65eebbf9ce29752',\n * })\n * // Set as X-T1Y-Safe-Sign header\n * ```\n */\nexport function createSignature(input: SignatureInput): string {\n const { method, pathAndQuery, body, appId, timestamp, secretKey } = input\n\n const bodyHash = sha256Hex(body)\n\n const message = [\n method.toUpperCase(),\n pathAndQuery,\n bodyHash,\n String(appId),\n String(timestamp),\n ].join('\\n')\n\n return hmacSHA256Hex(secretKey, message)\n}\n\n/**\n * Get the current UTC Unix timestamp adjusted by the given offset.\n *\n * @param offset - Time offset in seconds (from server init)\n * @returns 10-digit Unix timestamp string\n */\nexport function getSafeTimestamp(offset: number): string {\n return String(Math.floor(Date.now() / 1000) + offset)\n}\n","/**\n * Strip trailing slashes from a base URL.\n */\nexport function normalizeBaseUrl(baseUrl: string): string {\n return baseUrl.replace(/\\/+$/, '')\n}\n\n/**\n * Append query parameters from a params object to a URL.\n * Skips undefined and null values.\n * String values are added directly; others are JSON-stringified.\n */\nexport function appendQueryParams(url: URL, params: Record<string, unknown>): void {\n for (const key of Object.keys(params)) {\n const value = params[key]\n if (value === undefined || value === null) continue\n url.searchParams.set(key, typeof value === 'string' ? value : JSON.stringify(value))\n }\n}\n","import { DEFAULT_TIME_FORMAT } from '../constants'\n\n/**\n * Format a UTC date string to local time using the given format template.\n *\n * Format tokens:\n * YYYY - 4-digit year\n * MM - 2-digit month (01-12)\n * DD - 2-digit day (01-31)\n * HH - 2-digit hour (00-23)\n * mm - 2-digit minute (00-59)\n * ss - 2-digit second (00-59)\n */\nfunction formatLocalTime(utcString: string, format: string): string {\n const date = new Date(utcString)\n if (isNaN(date.getTime())) return utcString\n\n const pad = (n: number) => String(n).padStart(2, '0')\n\n return format\n .replace('YYYY', String(date.getFullYear()))\n .replace('MM', pad(date.getMonth() + 1))\n .replace('DD', pad(date.getDate()))\n .replace('HH', pad(date.getHours()))\n .replace('mm', pad(date.getMinutes()))\n .replace('ss', pad(date.getSeconds()))\n}\n\n/**\n * Recursively convert all `createdAt` and `updatedAt` fields in a data structure\n * from UTC strings to local time formatted strings.\n *\n * Returns a new object/array; does not mutate the original.\n */\nexport function formatTimestampsToLocal(\n data: unknown,\n format: string = DEFAULT_TIME_FORMAT\n): unknown {\n function traverse(value: unknown): unknown {\n if (Array.isArray(value)) {\n return value.map(traverse)\n }\n if (value && typeof value === 'object') {\n const result: Record<string, unknown> = {}\n for (const key in value as Record<string, unknown>) {\n if (!Object.prototype.hasOwnProperty.call(value, key)) continue\n\n if (key === 'createdAt' || key === 'updatedAt') {\n result[key] = formatLocalTime((value as Record<string, unknown>)[key] as string, format)\n } else {\n result[key] = traverse((value as Record<string, unknown>)[key])\n }\n }\n return result\n }\n return value\n }\n\n return traverse(data)\n}\n","/**\n * Response handling — decryption, timestamp formatting, and error wrapping.\n *\n * Works with platform-agnostic `PlatformResponse` objects instead of the\n * browser-native `Response` type, enabling cross-platform support.\n */\n\nimport { decryptAESGCM } from '../crypto/aes'\nimport { formatTimestampsToLocal } from '../utils/time'\nimport { T1YError } from '../utils/errors'\nimport type { ApiResponse } from '../types/api'\nimport type { PlatformResponse } from '../platform/types'\n\n/**\n * Process a platform response into the SDK's standard ApiResponse format.\n *\n * Handles:\n * 1. JSON parsing or string fallback\n * 2. Safe mode AES-GCM decryption (response data has `j` field)\n * 3. Timestamp formatting (createdAt/updatedAt → local time)\n * 4. Error wrapping for non-2xx status codes\n *\n * @param response - Platform-agnostic response object\n * @param isSafeMode - Whether safe mode encryption is active\n * @param secretKey - Secret key for decryption (as raw string)\n * @param timeFormat - Time format for createdAt/updatedAt fields\n * @returns Processed ApiResponse\n */\nexport async function handleResponse<T = unknown>(\n response: PlatformResponse,\n isSafeMode: boolean,\n secretKey: string,\n timeFormat: string\n): Promise<ApiResponse<T>> {\n // Determine content type from response headers\n const contentType = response.headers['content-type'] || ''\n\n // Try to parse response body\n let rawData: unknown\n const responseText = response.body\n\n if (contentType.includes('application/json')) {\n try {\n rawData = JSON.parse(responseText)\n } catch {\n rawData = responseText\n }\n } else {\n rawData = responseText\n }\n\n // If safe mode is on and the response data looks encrypted (has `j` field),\n // decrypt it first\n if (\n isSafeMode &&\n rawData &&\n typeof rawData === 'object' &&\n 'j' in (rawData as Record<string, unknown>)\n ) {\n try {\n const decrypted = await decryptAESGCM(\n JSON.stringify(rawData),\n new TextEncoder().encode(secretKey)\n )\n\n // Try to parse decrypted result as JSON\n try {\n rawData = JSON.parse(decrypted)\n } catch {\n rawData = decrypted\n }\n } catch (err) {\n throw new T1YError(\n 400,\n 'AES-256-GCM decryption failed',\n err instanceof Error ? err.message : null\n )\n }\n }\n\n const isOk = response.status >= 200 && response.status < 300\n\n // If the response is a standard ApiResponse wrapper, format timestamps\n if (rawData && typeof rawData === 'object' && 'data' in (rawData as Record<string, unknown>)) {\n const apiResp = rawData as ApiResponse<T>\n apiResp.data = formatTimestampsToLocal(apiResp.data, timeFormat) as T\n\n // If the status code is not 2xx, throw a T1YError\n if (!isOk) {\n throw new T1YError(\n apiResp.code || response.status,\n apiResp.message || response.statusText,\n apiResp.data\n )\n }\n\n return apiResp\n }\n\n // Handle non-standard responses\n if (!isOk) {\n throw new T1YError(response.status, response.statusText, rawData)\n }\n\n // Raw success response — wrap in ApiResponse shape\n return {\n code: 0,\n message: 'ok',\n data: formatTimestampsToLocal(rawData, timeFormat) as T,\n }\n}\n\n/**\n * Handle request errors (network errors, timeouts, etc.) from any platform.\n */\nexport function handleFetchError(error: unknown): never {\n // Re-throw as T1YError if it's not already\n if (error instanceof T1YError) {\n throw error\n }\n\n if (error instanceof Error) {\n // Network error / timeout\n const message = error.message || 'Unknown error'\n if (\n message.includes('timeout') ||\n message.includes('超时') ||\n error.name === 'AbortError' ||\n message.includes('abort')\n ) {\n throw new T1YError(408, 'Request timeout', null)\n }\n throw new T1YError(0, message, null)\n }\n\n throw new T1YError(0, 'Unknown error', error)\n}\n","/**\n * Platform detection module.\n *\n * Detects the current runtime environment and returns a platform type identifier.\n * This enables the SDK to use the correct network request API for each platform:\n *\n * | Platform | Type | Request API | Global Object |\n * |-----------------------|----------|--------------------|---------------|\n * | WeChat Mini Program | `wx` | `wx.request` | `wx` |\n * | QQ Mini Program | `wx` | `qq.request` | `qq` |\n * | Toutiao/Douyin Mini | `wx` | `tt.request` | `tt` |\n * | Alipay Mini Program | `my` | `my.request` | `my` |\n * | Quick App | `hap` | `@system.fetch` | — |\n * | Web / Vue / React | `h5` | `fetch` | `window` |\n * | Node.js | `nodejs` | `fetch` (18+) | `process` |\n */\n\n/** Platform type identifiers */\nexport type PlatformType = 'wx' | 'my' | 'hap' | 'h5' | 'nodejs' | 'unknown'\n\n/** Mini program sub-type within the `wx` platform family */\nexport type MiniProgramSubType = 'wechat' | 'qq' | 'toutiao' | 'unknown'\n\n/** Cached platform detection result */\nlet _platformType: PlatformType | null = null\nlet _miniProgramSubType: MiniProgramSubType | null = null\n\n/**\n * Detect the current platform type.\n *\n * Detection order (from most specific to least):\n * 1. WeChat/QQ/Toutiao/Douyin Mini Programs — global `wx`/`qq`/`tt` object\n * 2. Alipay Mini Program — global `my` object\n * 3. Quick App — no `window`, no `wx`, but has device info via special flag\n * 4. Web / H5 — global `window` and `document`\n * 5. Node.js — global `process` without `window`\n *\n * @returns The detected platform type\n */\nexport function getPlatformType(): PlatformType {\n if (_platformType !== null) {\n return _platformType\n }\n\n // Use `typeof` checks to avoid ReferenceError in strict environments\n\n // Check for Mini Programs (WeChat, QQ, Toutiao, Douyin)\n // All of these expose a global `wx`-like API object\n if (typeof wx !== 'undefined' && typeof (wx as Record<string, unknown>).request === 'function') {\n _platformType = 'wx'\n return _platformType\n }\n\n // Check for Alipay Mini Program\n if (typeof my !== 'undefined' && typeof (my as Record<string, unknown>).request === 'function') {\n _platformType = 'my'\n return _platformType\n }\n\n // Check for Quick App\n // Quick App has no `window` or `document` but also no `wx`\n // Detection: check if it's not a browser and has `global` (Quick App's global scope)\n if (\n typeof window === 'undefined' &&\n typeof document === 'undefined' &&\n typeof global !== 'undefined' &&\n typeof (global as Record<string, unknown>).require === 'function'\n ) {\n // Further distinguish: Quick App has @system packages available via require\n try {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n if (typeof require !== 'undefined' && typeof require('@system.fetch') !== 'undefined') {\n _platformType = 'hap'\n return _platformType\n }\n } catch {\n // @system.fetch not available — not Quick App\n }\n }\n\n // Check for Web / H5 (browser environment)\n if (typeof window !== 'undefined' && typeof document !== 'undefined') {\n _platformType = 'h5'\n return _platformType\n }\n\n // Check for Node.js\n if (\n typeof process !== 'undefined' &&\n typeof (process as unknown as Record<string, unknown>).versions !== 'undefined' &&\n typeof ((process as unknown as Record<string, unknown>).versions as Record<string, unknown>)\n ?.node !== 'undefined'\n ) {\n _platformType = 'nodejs'\n return _platformType\n }\n\n _platformType = 'unknown'\n return _platformType\n}\n\n/**\n * Detect the mini program sub-type (only meaningful when platform is `wx`).\n *\n * | Sub-type | Global Object | Notes |\n * |------------|---------------|----------------------------------------|\n * | `toutiao` | `tt` | Toutiao/Douyin Mini Program |\n * | `qq` | `qq` | QQ Mini Program |\n * | `wechat` | `wx` | WeChat Mini Program (default for `wx`) |\n *\n * @returns The detected mini program sub-type\n */\nexport function getMiniProgramSubType(): MiniProgramSubType {\n if (_miniProgramSubType !== null) {\n return _miniProgramSubType\n }\n\n // Only relevant for `wx` platform\n if (getPlatformType() !== 'wx') {\n _miniProgramSubType = 'unknown'\n return _miniProgramSubType\n }\n\n // Toutiao/Douyin exposes `tt` alongside `wx`\n if (typeof tt !== 'undefined' && typeof (tt as Record<string, unknown>).request === 'function') {\n _miniProgramSubType = 'toutiao'\n return _miniProgramSubType\n }\n\n // QQ Mini Program exposes `qq` alongside `wx`\n if (typeof qq !== 'undefined' && typeof (qq as Record<string, unknown>).request === 'function') {\n _miniProgramSubType = 'qq'\n return _miniProgramSubType\n }\n\n // Default to WeChat\n _miniProgramSubType = 'wechat'\n return _miniProgramSubType\n}\n\n/**\n * Get the global API object for mini programs.\n *\n * Returns the appropriate global object based on the detected platform:\n * - WeChat: `wx`\n * - QQ: `qq`\n * - Toutiao/Douyin: `tt`\n *\n * @returns The mini program global API object, or `null` if not in a mini program\n */\nexport function getMiniProgramAPI(): Record<string, unknown> | null {\n const platform = getPlatformType()\n\n if (platform === 'my') {\n return my as unknown as Record<string, unknown>\n }\n\n if (platform !== 'wx') {\n return null\n }\n\n const subType = getMiniProgramSubType()\n\n switch (subType) {\n case 'toutiao':\n return tt as unknown as Record<string, unknown>\n case 'qq':\n return qq as unknown as Record<string, unknown>\n case 'wechat':\n default:\n return wx as unknown as Record<string, unknown>\n }\n}\n\n/**\n * Reset cached platform detection (useful for testing).\n */\nexport function resetPlatformDetection(): void {\n _platformType = null\n _miniProgramSubType = null\n}\n","/**\n * Fetch-based request adapter for Web (H5) and Node.js environments.\n *\n * Uses the standard `fetch` API (native in Node.js 18+, all modern browsers).\n */\n\nimport type { PlatformRequestOptions, PlatformResponse, PlatformRequestFn } from '../types'\n\n/**\n * Execute an HTTP request using the standard `fetch` API.\n *\n * @param options - Standardized request options\n * @returns Standardized response object\n */\nexport const fetchRequest: PlatformRequestFn = async (\n options: PlatformRequestOptions\n): Promise<PlatformResponse> => {\n const { url, method, headers, body, signal } = options\n\n const fetchOptions: RequestInit = {\n method,\n headers,\n signal,\n }\n\n if (body !== undefined && method !== 'GET') {\n fetchOptions.body = body\n }\n\n const response = await fetch(url, fetchOptions)\n\n // Extract response headers into a plain object\n const responseHeaders: Record<string, string> = {}\n response.headers.forEach((value: string, key: string) => {\n responseHeaders[key.toLowerCase()] = value\n })\n\n const responseBody = await response.text()\n\n return {\n status: response.status,\n statusText: response.statusText,\n headers: responseHeaders,\n body: responseBody,\n }\n}\n","/**\n * WeChat / QQ / Toutiao / Douyin Mini Program request adapter.\n *\n * All of these platforms expose a `wx.request`-compatible API:\n * - WeChat: `wx.request`\n * - QQ: `qq.request`\n * - Toutiao: `tt.request`\n * - Douyin: `tt.request`\n *\n * The actual API object is resolved at call time via `getMiniProgramAPI()`.\n */\n\nimport { getMiniProgramAPI } from '../detect'\nimport type { PlatformRequestOptions, PlatformResponse, PlatformRequestFn } from '../types'\n\n/**\n * Execute an HTTP request using the mini program's `request` API.\n *\n * The mini program API uses callback-based `wx.request({ success, fail, complete })`.\n * This adapter wraps it in a Promise for consistent async/await usage.\n *\n * @param options - Standardized request options\n * @returns Standardized response object\n */\nexport const wxRequest: PlatformRequestFn = async (\n options: PlatformRequestOptions\n): Promise<PlatformResponse> => {\n const mpApi = getMiniProgramAPI()\n\n if (!mpApi || typeof (mpApi as Record<string, unknown>).request !== 'function') {\n throw new Error('Mini program request API is not available')\n }\n\n const requestFn = (mpApi as Record<string, unknown>).request as (\n opts: Record<string, unknown>\n ) => { abort: () => void }\n\n const { url, method, headers, body, timeout } = options\n\n return new Promise<PlatformResponse>((resolve, reject) => {\n const requestTask = requestFn({\n url,\n method: method as\n | 'GET'\n | 'POST'\n | 'PUT'\n | 'DELETE'\n | 'OPTIONS'\n | 'HEAD'\n | 'TRACE'\n | 'CONNECT',\n header: headers,\n data: body,\n timeout: timeout ?? 300000, // 5 minutes default\n dataType: 'text', // Get raw text, we parse JSON ourselves\n responseType: 'text',\n success: (res: {\n statusCode: number\n errMsg?: string\n header?: Record<string, string>\n data?: string | object\n }) => {\n // Normalize response headers\n const responseHeaders: Record<string, string> = {}\n if (res.header) {\n for (const key of Object.keys(res.header)) {\n responseHeaders[key.toLowerCase()] = res.header[key]!\n }\n }\n\n // Handle response body — it might already be parsed as JSON\n let bodyStr: string\n if (typeof res.data === 'string') {\n bodyStr = res.data\n } else if (res.data !== undefined && res.data !== null) {\n bodyStr = JSON.stringify(res.data)\n } else {\n bodyStr = ''\n }\n\n resolve({\n status: res.statusCode,\n statusText: res.errMsg ?? '',\n headers: responseHeaders,\n body: bodyStr,\n })\n },\n fail: (err: { errMsg?: string; errno?: number }) => {\n // Handle timeout specially\n const errMsg = err.errMsg ?? 'Mini program request failed'\n if (errMsg.includes('timeout') || errMsg.includes('超时')) {\n reject(new Error('Request timeout'))\n } else {\n reject(new Error(errMsg))\n }\n },\n })\n\n // Handle AbortSignal if provided\n if (options.signal) {\n const onAbort = () => {\n if (typeof requestTask.abort === 'function') {\n requestTask.abort()\n }\n }\n options.signal.addEventListener('abort', onAbort, { once: true })\n }\n })\n}\n","/**\n * Alipay Mini Program request adapter.\n *\n * Alipay Mini Program uses `my.request` which has a slightly different API\n * from WeChat's `wx.request`. Key differences:\n * - Uses `headers` instead of `header`\n * - Response `data` is always parsed JSON (not raw text)\n * - Different error object structure\n *\n * API reference: https://opendocs.alipay.com/mini/api/owycmh\n */\n\nimport type { PlatformRequestOptions, PlatformResponse, PlatformRequestFn } from '../types'\n\n/**\n * Execute an HTTP request using Alipay's `my.request` API.\n *\n * @param options - Standardized request options\n * @returns Standardized response object\n */\nexport const myRequest: PlatformRequestFn = async (\n options: PlatformRequestOptions\n): Promise<PlatformResponse> => {\n // Access the Alipay global API\n const mpApi = my as unknown as Record<string, unknown>\n\n if (!mpApi || typeof mpApi.request !== 'function') {\n throw new Error('Alipay mini program request API (my.request) is not available')\n }\n\n const requestFn = mpApi.request as (opts: Record<string, unknown>) => { abort: () => void }\n\n const { url, method, headers, body, timeout } = options\n\n return new Promise<PlatformResponse>((resolve, reject) => {\n const requestTask = requestFn({\n url,\n method: method.toUpperCase(),\n headers, // Alipay uses `headers` (not `header` like WeChat)\n data: body !== undefined ? body : undefined,\n timeout: timeout ?? 300000,\n // Request JSON but we handle parsing ourselves\n dataType: 'text',\n success: (res: {\n status?: number\n statusCode?: number\n headers?: Record<string, string>\n data?: unknown\n }) => {\n // Normalize response\n const status = res.status ?? res.statusCode ?? 200\n\n const responseHeaders: Record<string, string> = {}\n if (res.headers) {\n for (const key of Object.keys(res.headers)) {\n responseHeaders[key.toLowerCase()] = res.headers[key]!\n }\n }\n\n let bodyStr: string\n if (typeof res.data === 'string') {\n bodyStr = res.data\n } else if (res.data !== undefined && res.data !== null) {\n bodyStr = JSON.stringify(res.data)\n } else {\n bodyStr = ''\n }\n\n resolve({\n status,\n statusText: '',\n headers: responseHeaders,\n body: bodyStr,\n })\n },\n fail: (err: { error?: number | string; errorMessage?: string; errMsg?: string }) => {\n const errMsg =\n err.errorMessage ?? err.errMsg ?? `Alipay request failed (error: ${err.error})`\n reject(new Error(errMsg))\n },\n complete: () => {\n // No-op — handled in success/fail\n },\n })\n\n // Handle AbortSignal if provided\n if (options.signal) {\n const onAbort = () => {\n if (requestTask && typeof requestTask.abort === 'function') {\n requestTask.abort()\n }\n }\n options.signal.addEventListener('abort', onAbort, { once: true })\n }\n })\n}\n","/**\n * Quick App (快应用) request adapter.\n *\n * Quick App uses the `@system.fetch` module for HTTP requests.\n * Unlike mini programs, Quick App's fetch API is more similar to the standard\n * `fetch` API but requires importing the system module.\n *\n * IMPORTANT: The `@system.fetch` module is only available inside Quick App.\n * In other environments, the require call is wrapped in a try-catch and will\n * safely return null, falling back to other adapters.\n *\n * API reference: https://doc.quickapp.cn/features/system/fetch.html\n */\n\nimport type { PlatformRequestOptions, PlatformResponse, PlatformRequestFn } from '../types'\n\n/**\n * Safely access Quick App's @system.fetch module.\n *\n * Uses a dynamic require call wrapped in try-catch so that:\n * - In Quick App: returns the @system.fetch module ✓\n * - In other bundlers (webpack/esbuild): the require is preserved as-is\n * - In browsers: throws ReferenceError (require not defined) → caught → returns null\n */\nfunction getSystemFetch(): {\n fetch: (opts: {\n url: string\n method?: string\n header?: Record<string, string>\n data?: string\n responseType?: string\n success?: (res: { code: number; data: string; headers: Record<string, string> }) => void\n fail?: (err: { code: number; data: string }) => void\n complete?: () => void\n }) => void\n} | null {\n try {\n // In Quick App, @system.fetch is a built-in module accessible via require.\n // Quick App's hap-toolkit will resolve this at build time.\n // In other environments, this will throw and be caught.\n //\n // NOTE: For UMD/IIFE builds, esbuild is configured with --external:@system.fetch\n // so this require call is preserved as-is in the output.\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const sysFetch = require('@system.fetch')\n return sysFetch as ReturnType<typeof getSystemFetch>\n } catch (_e) {\n return null\n }\n}\n\n/**\n * Execute an HTTP request using Quick App's `@system.fetch` API.\n *\n * Key differences from standard fetch:\n * - Callback-based (success/fail/complete), not Promise-based\n * - Response status is in `res.code`\n * - Headers are in `res.headers`\n *\n * @param options - Standardized request options\n * @returns Standardized response object\n */\nexport const hapRequest: PlatformRequestFn = async (\n options: PlatformRequestOptions\n): Promise<PlatformResponse> => {\n const sysFetch = getSystemFetch()\n\n if (!sysFetch) {\n throw new Error(\n 'Quick App fetch module (@system.fetch) is not available. ' +\n 'Ensure you are running inside a Quick App environment.'\n )\n }\n\n const { url, method, headers, body } = options\n\n return new Promise<PlatformResponse>((resolve, reject) => {\n sysFetch.fetch({\n url,\n method: method.toUpperCase(),\n header: headers,\n data: body,\n responseType: 'text',\n success: (res: { code: number; data: string; headers: Record<string, string> }) => {\n const responseHeaders: Record<string, string> = {}\n if (res.headers) {\n for (const key of Object.keys(res.headers)) {\n responseHeaders[key.toLowerCase()] = res.headers[key]!\n }\n }\n\n resolve({\n status: res.code,\n statusText: '',\n headers: responseHeaders,\n body: typeof res.data === 'string' ? res.data : JSON.stringify(res.data),\n })\n },\n fail: (err: { code: number; data: string }) => {\n reject(new Error(`Quick App request failed (code: ${err.code}, data: ${err.data})`))\n },\n complete: () => {\n // No-op\n },\n })\n })\n}\n","/**\n * Platform request dispatcher.\n *\n * Detects the runtime platform and returns the appropriate request function\n * and platform metadata. This is the single entry point used by the HTTP\n * module to execute requests in any environment.\n */\n\nimport { getPlatformType, getMiniProgramSubType } from './detect'\nimport { fetchRequest } from './request/fetch'\nimport { wxRequest } from './request/wx'\nimport { myRequest } from './request/my'\nimport { hapRequest } from './request/hap'\nimport type { PlatformRequestFn, PlatformInfo } from './types'\n\n/** Cached platform request function */\nlet _cachedRequest: PlatformRequestFn | null = null\nlet _cachedInfo: PlatformInfo | null = null\n\n/**\n * Get the platform-appropriate request function.\n *\n * On first call, detects the platform and caches the result.\n * Subsequent calls return the cached adapter.\n *\n * @returns The request function for the current platform\n * @throws {Error} If the platform cannot be determined or no adapter is available\n */\nexport function getPlatformRequest(): PlatformRequestFn {\n if (_cachedRequest !== null) {\n return _cachedRequest\n }\n\n const platform = getPlatformType()\n\n switch (platform) {\n case 'h5':\n case 'nodejs':\n _cachedRequest = fetchRequest\n break\n case 'wx':\n _cachedRequest = wxRequest\n break\n case 'my':\n _cachedRequest = myRequest\n break\n case 'hap':\n _cachedRequest = hapRequest\n break\n default:\n // Fallback: try fetch first (works in modern environments)\n if (typeof fetch === 'function') {\n _cachedRequest = fetchRequest\n } else {\n throw new Error(\n 'Unable to determine platform request adapter. ' +\n 'The current environment does not have `fetch`, `wx.request`, `my.request`, ' +\n 'or `@system.fetch` available. Please ensure you are running in a supported environment: ' +\n 'Web browser, Node.js 18+, WeChat/QQ/Alipay/Toutiao/Douyin Mini Program, or Quick App.'\n )\n }\n break\n }\n\n return _cachedRequest!\n}\n\n/**\n * Get platform metadata including the SDK type string for request headers.\n *\n * The `sdkType` value is sent in the `X-T1Y-SDK-Type` header to help the\n * server identify which platform the request is coming from.\n *\n * @returns Platform metadata\n */\nexport function getPlatformInfo(): PlatformInfo {\n if (_cachedInfo !== null) {\n return _cachedInfo\n }\n\n const platform = getPlatformType()\n let sdkType = 'javascript'\n\n switch (platform) {\n case 'wx': {\n const subType = getMiniProgramSubType()\n switch (subType) {\n case 'toutiao':\n sdkType = 'toutiao'\n break\n case 'qq':\n sdkType = 'qqApp'\n break\n case 'wechat':\n default:\n sdkType = 'wechatApp'\n break\n }\n break\n }\n case 'my':\n sdkType = 'alipay'\n break\n case 'hap':\n sdkType = 'quickApp'\n break\n case 'h5':\n sdkType = 'web'\n break\n case 'nodejs':\n sdkType = 'nodejs'\n break\n default:\n sdkType = 'javascript'\n break\n }\n\n _cachedInfo = {\n type: platform,\n sdkType,\n request: getPlatformRequest(),\n }\n\n return _cachedInfo\n}\n\n/**\n * Reset cached dispatcher state (useful for testing).\n */\nexport function resetDispatcher(): void {\n _cachedRequest = null\n _cachedInfo = null\n}\n","/**\n * Core HTTP request execution for the t1yOS SDK.\n *\n * Handles:\n * - URL construction (baseUrl + path + query params for GET)\n * - Date type conversion in params\n * - AES-256-GCM encryption (safe mode)\n * - Request signing (HMAC-SHA256)\n * - Auth header injection\n * - Platform-agnostic request execution (via platform adapters)\n * - Response processing (decryption, timestamp formatting)\n */\n\nimport { encryptAESGCM } from '../crypto/aes'\nimport { createSignature, getSafeTimestamp } from '../crypto/sign'\nimport { convertDateTypes } from '../utils/convert'\nimport { appendQueryParams, normalizeBaseUrl } from '../utils/url'\nimport { REQUEST_TIMEOUT_MS } from '../constants'\nimport { handleResponse, handleFetchError } from './response'\nimport { getPlatformRequest } from '../platform/dispatcher'\nimport type { T1YOSInternalConfig, HttpMethod, ApiResponse } from '../types'\n\n/**\n * Options for a single HTTP request.\n */\nexport interface RequestOptions {\n /** HTTP method */\n method: HttpMethod\n /** API path (e.g., /v5/classes/users) */\n path: string\n /** Request parameters/body */\n params?: unknown\n /** Override encryption for this request (defaults to client.isSafeMode) */\n encryption?: boolean\n /** Request timeout in milliseconds (default: 5 minutes) */\n timeout?: number\n}\n\n/**\n * Execute an HTTP request to the t1yOS API with full auth and encryption handling.\n *\n * This function is platform-agnostic. It builds the request (URL, headers, body,\n * encryption, signing) and then delegates the actual HTTP call to a platform-specific\n * adapter that works in Web, Node.js, WeChat/QQ/Alipay/Toutiao/Douyin Mini Programs,\n * and Quick App.\n *\n * @param client - Internal client configuration\n * @param options - Request options\n * @returns The processed API response\n */\nexport async function executeRequest<T = unknown>(\n client: T1YOSInternalConfig,\n options: RequestOptions\n): Promise<ApiResponse<T>> {\n const { method, path, params, encryption, timeout } = options\n\n // Normalize base URL\n const baseUrl = normalizeBaseUrl(client.baseUrl)\n const isSafeMode = encryption ?? client.isSafeMode\n\n // Build URL\n const fullUrl = new URL(baseUrl + path)\n\n // Convert Date types in params\n const convertedParams = convertDateTypes(params)\n\n // Handle request body\n let bodyForRequest: string | undefined\n let rawBodyString = ''\n\n if (method !== 'GET') {\n // For non-GET requests, the body is the params\n if (isSafeMode && convertedParams !== undefined) {\n // Safe mode: encrypt the JSON body\n const encryptedBody = await encryptAESGCM(\n JSON.stringify(convertedParams),\n new TextEncoder().encode(client.secretKey)\n )\n bodyForRequest = encryptedBody\n rawBodyString = encryptedBody\n } else if (convertedParams !== undefined) {\n const jsonBody = JSON.stringify(convertedParams)\n bodyForRequest = jsonBody\n rawBodyString = jsonBody\n } else {\n rawBodyString = ''\n }\n } else if (\n convertedParams &&\n typeof convertedParams === 'object' &&\n Object.keys(convertedParams as object).length > 0\n ) {\n // For GET requests, append params as query string\n appendQueryParams(fullUrl, convertedParams as Record<string, unknown>)\n }\n\n // Compute timestamp with offset\n const timestamp = Number(getSafeTimestamp(client.offset))\n\n // Get the path + query for signing\n const originalURL = fullUrl.pathname + fullUrl.search\n\n // Create the HMAC-SHA256 signature\n const sign = createSignature({\n method,\n pathAndQuery: originalURL,\n body: rawBodyString,\n appId: client.appId,\n timestamp,\n secretKey: client.secretKey,\n })\n\n // Use the platform-specific request adapter\n const platformRequest = getPlatformRequest()\n const timeoutMs = timeout ?? REQUEST_TIMEOUT_MS\n\n try {\n const response = await platformRequest({\n url: fullUrl.toString(),\n method,\n headers: {\n 'X-T1Y-Application-ID': String(client.appId),\n 'X-T1Y-API-Key': client.apiKey,\n 'X-T1Y-Safe-Timestamp': String(timestamp),\n 'X-T1Y-Safe-Sign': sign,\n 'Content-Type': 'application/json',\n },\n body: method !== 'GET' ? bodyForRequest : undefined,\n timeout: timeoutMs,\n })\n\n return await handleResponse<T>(response, isSafeMode, client.secretKey, client.timeFormat)\n } catch (error) {\n return handleFetchError(error)\n }\n}\n","/**\n * T1Collection — Database collection class providing chainable CRUD and schema operations.\n *\n * Created via `client.db.collection('name')` — never instantiated directly.\n */\n\nimport { assertObjectID } from '../utils/validators'\nimport {\n isNonEmptyObject,\n isPlainObject,\n isNonEmptyArrayWithNonEmptyObjects,\n} from '../utils/convert'\nimport { MAX_PAGE_SIZE } from '../constants'\nimport type { T1YOS } from './T1YOS'\nimport type {\n ApiResponse,\n InsertResult,\n InsertManyResult,\n DeleteResult,\n DeleteManyResult,\n UpdateResult,\n UpdateManyResult,\n FindResult,\n PaginationResult,\n AggregateResult,\n} from '../types'\n\nexport class T1Collection {\n /** The parent T1YOS client */\n private client: T1YOS\n /** The collection (table) name */\n private name: string\n\n /**\n * @internal — Use `client.db.collection(name)` instead.\n */\n constructor(client: T1YOS, name: string) {\n this.client = client\n this.name = name\n }\n\n // ==================== Single Document Operations ====================\n\n /**\n * Insert one document into the collection.\n *\n * @param data - Document data (must be a non-empty plain object)\n * @returns Response with the inserted document's ObjectID\n *\n * @example\n * ```ts\n * const { data } = await client.db.collection('users').insertOne({\n * name: 'Alice',\n * age: 25,\n * })\n * console.log(data.objectId) // '507f1f77bcf86cd799439011'\n * ```\n */\n async insertOne(data: Record<string, unknown>): Promise<ApiResponse<InsertResult>> {\n if (!isNonEmptyObject(data)) {\n throw new TypeError('insertOne data must be a non-empty plain object')\n }\n return await this.client.request<InsertResult>('POST', `/v5/classes/${this.name}`, data)\n }\n\n /**\n * Delete one document by ObjectID.\n *\n * @param objectId - 24-character hex ObjectID string\n * @returns Response with deleted count\n *\n * @example\n * ```ts\n * await client.db.collection('users').deleteById('507f1f77bcf86cd799439011')\n * ```\n */\n async deleteById(objectId: string): Promise<ApiResponse<DeleteResult>> {\n assertObjectID(objectId)\n return await this.client.request<DeleteResult>('DELETE', `/v5/classes/${this.name}/${objectId}`)\n }\n\n /**\n * Update one document by ObjectID.\n *\n * @param objectId - 24-character hex ObjectID string\n * @param data - Update data (must be a non-empty plain object)\n * @returns Response with modified count\n *\n * @example\n * ```ts\n * await client.db.collection('users').updateById('507f1f77bcf86cd799439011', { name: 'Bob' })\n * ```\n */\n async updateById(\n objectId: string,\n data: Record<string, unknown>\n ): Promise<ApiResponse<UpdateResult>> {\n assertObjectID(objectId)\n if (!isNonEmptyObject(data)) {\n throw new TypeError('update data must be a non-empty plain object')\n }\n return await this.client.request<UpdateResult>(\n 'PUT',\n `/v5/classes/${this.name}/${objectId}`,\n data\n )\n }\n\n /**\n * Find one document by ObjectID.\n *\n * @param objectId - 24-character hex ObjectID string\n * @returns Response with the found document\n *\n * @example\n * ```ts\n * const { data } = await client.db.collection('users').findById('507f1f77bcf86cd799439011')\n * console.log(data.result) // { _id: '507f1f77...', name: 'Alice', ... }\n * ```\n */\n async findById(objectId: string): Promise<ApiResponse<FindResult>> {\n assertObjectID(objectId)\n return await this.client.request<FindResult>('GET', `/v5/classes/${this.name}/${objectId}`)\n }\n\n // ==================== Filter-based Single Operations ====================\n\n /**\n * Delete one document matching the filter.\n *\n * @param filter - Query filter (must be a non-empty plain object)\n * @returns Response with deleted count\n *\n * @example\n * ```ts\n * await client.db.collection('users').deleteOne({ name: 'Alice' })\n * ```\n */\n async deleteOne(filter: Record<string, unknown>): Promise<ApiResponse<DeleteResult>> {\n if (!isNonEmptyObject(filter)) {\n throw new TypeError('deleteOne filter must be a non-empty plain object')\n }\n return await this.client.request<DeleteResult>('DELETE', `/v5/classes/${this.name}/one`, filter)\n }\n\n /**\n * Update one document matching the filter.\n *\n * @param filter - Query filter to find the document\n * @param body - Update data (MongoDB update operators like $set, $inc, etc.)\n * @returns Response with modified count\n *\n * @example\n * ```ts\n * await client.db.collection('users').updateOne(\n * { name: 'Alice' },\n * { $set: { age: 26 } }\n * )\n * ```\n */\n async updateOne(\n filter: Record<string, unknown>,\n body: Record<string, unknown>\n ): Promise<ApiResponse<UpdateResult>> {\n if (!isNonEmptyObject(filter)) {\n throw new TypeError('updateOne filter must be a non-empty plain object')\n }\n if (!isNonEmptyObject(body)) {\n throw new TypeError('updateOne body must be a non-empty plain object')\n }\n return await this.client.request<UpdateResult>('PUT', `/v5/classes/${this.name}/one`, {\n filter,\n body,\n })\n }\n\n /**\n * Find one document matching the filter.\n *\n * @param filter - Query filter\n * @returns Response with the found document (or null if not found)\n *\n * @example\n * ```ts\n * const { data } = await client.db.collection('users').findOne({ name: 'Alice' })\n * ```\n */\n async findOne(filter: Record<string, unknown>): Promise<ApiResponse<FindResult>> {\n if (!isNonEmptyObject(filter)) {\n throw new TypeError('findOne filter must be a non-empty plain object')\n }\n return await this.client.request<FindResult>('POST', `/v5/classes/${this.name}/one`, filter)\n }\n\n // ==================== Bulk Operations ====================\n\n /**\n * Insert multiple documents into the collection.\n *\n * @param dataList - Array of document data (each must be a non-empty plain object)\n * @returns Response with inserted ObjectIDs and count\n *\n * @example\n * ```ts\n * const { data } = await client.db.collection('users').insertMany([\n * { name: 'Alice', age: 25 },\n * { name: 'Bob', age: 30 },\n * ])\n * console.log(data.insertedCount) // 2\n * ```\n */\n async insertMany(dataList: Record<string, unknown>[]): Promise<ApiResponse<InsertManyResult>> {\n if (!isNonEmptyArrayWithNonEmptyObjects(dataList)) {\n throw new TypeError(\n 'insertMany dataList must be a non-empty array of non-empty plain objects'\n )\n }\n return await this.client.request<InsertManyResult>(\n 'POST',\n `/v5/classes/${this.name}/many`,\n dataList\n )\n }\n\n /**\n * Delete multiple documents matching the filter.\n *\n * @param filter - Query filter (can be an empty object to match all)\n * @returns Response with deleted count\n *\n * @example\n * ```ts\n * const { data } = await client.db.collection('users').deleteMany({ age: { $lt: 18 } })\n * console.log(data.deletedCount) // 5\n * ```\n */\n async deleteMany(filter: Record<string, unknown>): Promise<ApiResponse<DeleteManyResult>> {\n if (!isPlainObject(filter)) {\n throw new TypeError('deleteMany filter must be a plain object')\n }\n return await this.client.request<DeleteManyResult>(\n 'DELETE',\n `/v5/classes/${this.name}/many`,\n filter\n )\n }\n\n /**\n * Update multiple documents matching the filter.\n *\n * @param filter - Query filter to match documents\n * @param body - Update data (MongoDB update operators)\n * @returns Response with modified count\n *\n * @example\n * ```ts\n * await client.db.collection('users').updateMany(\n * { status: 'inactive' },\n * { $set: { status: 'archived' } }\n * )\n * ```\n */\n async updateMany(\n filter: Record<string, unknown>,\n body: Record<string, unknown>\n ): Promise<ApiResponse<UpdateManyResult>> {\n if (!isPlainObject(filter)) {\n throw new TypeError('updateMany filter must be a plain object')\n }\n if (!isNonEmptyObject(body)) {\n throw new TypeError('updateMany body must be a non-empty plain object')\n }\n return await this.client.request<UpdateManyResult>('PUT', `/v5/classes/${this.name}/many`, {\n filter,\n body,\n })\n }\n\n // ==================== Advanced Queries ====================\n\n /**\n * Paginated find query with sorting and filtering.\n *\n * @param page - Page number (1-based, default: 1)\n * @param size - Page size (1-100, default: 10)\n * @param sort - Sort specification, e.g. `{ createdAt: -1 }` for newest first\n * @param filter - Query filter\n * @returns Response with paginated results and pagination metadata\n *\n * @example\n * ```ts\n * const { data } = await client.db.collection('users').find(\n * 1, // page\n * 20, // size\n * { createdAt: -1 }, // sort (newest first)\n * { age: { $gte: 18 } } // filter\n * )\n * console.log(data.results) // Array of documents\n * console.log(data.pagination) // { totalItems: 100, totalPages: 5 }\n * ```\n */\n async find(\n page: number = 1,\n size: number = 10,\n sort: Record<string, number> = { createdAt: -1 },\n filter: Record<string, unknown> = {}\n ): Promise<ApiResponse<PaginationResult>> {\n if (!Number.isInteger(page) || page < 1) {\n throw new TypeError('find page must be a positive integer')\n }\n if (!Number.isInteger(size) || size < 1) {\n throw new TypeError('find size must be a positive integer')\n }\n if (size > MAX_PAGE_SIZE) {\n size = MAX_PAGE_SIZE\n }\n if (!isNonEmptyObject(sort)) {\n throw new TypeError('find sort must be a non-empty plain object')\n }\n if (!isPlainObject(filter)) {\n throw new TypeError('find filter must be a plain object')\n }\n\n return await this.client.request<PaginationResult>('POST', `/v5/classes/${this.name}/find`, {\n page,\n size,\n sort,\n filter,\n })\n }\n\n /**\n * Execute a MongoDB aggregation pipeline.\n *\n * @param pipeline - Array of aggregation stages\n * @returns Response with aggregation results\n *\n * @example\n * ```ts\n * const { data } = await client.db.collection('orders').aggregate([\n * { $match: { status: 'completed' } },\n * { $group: { _id: '$category', total: { $sum: '$amount' } } },\n * { $sort: { total: -1 } },\n * ])\n * ```\n */\n async aggregate(pipeline: Record<string, unknown>[]): Promise<ApiResponse<AggregateResult>> {\n if (!Array.isArray(pipeline)) {\n throw new TypeError('aggregate pipeline must be an array')\n }\n return await this.client.request<AggregateResult>(\n 'POST',\n `/v5/classes/${this.name}/aggregate`,\n pipeline\n )\n }\n\n /**\n * Count documents matching a filter.\n *\n * Uses `POST /v5/classes/:name/count` with the filter as the request body.\n *\n * @param filter - Query filter (can be an empty object for total count)\n * @returns Response with `data.count`\n *\n * @example\n * ```ts\n * const { data } = await client.db.collection('users').count({ status: 'active' })\n * console.log(data.count) // 42\n * ```\n */\n async count(filter: Record<string, unknown> = {}): Promise<ApiResponse<{ count: number }>> {\n if (!isPlainObject(filter)) {\n throw new TypeError('count filter must be a plain object')\n }\n return await this.client.request<{ count: number }>(\n 'POST',\n `/v5/classes/${this.name}/count`,\n filter\n )\n }\n\n /**\n * Get distinct values for a field, optionally filtered.\n *\n * Uses `POST /v5/classes/:name/distinct/:field` with the filter as the request body.\n *\n * @param fieldName - The field to get distinct values for\n * @param filter - Optional filter to narrow the documents\n * @returns Response with `data.results` containing distinct values\n *\n * @example\n * ```ts\n * const { data } = await client.db.collection('users').distinct('city')\n * console.log(data.results) // ['Beijing', 'Shanghai', ...]\n * ```\n */\n async distinct(\n fieldName: string,\n filter: Record<string, unknown> = {}\n ): Promise<ApiResponse<{ results: unknown[] }>> {\n if (typeof fieldName !== 'string' || fieldName.length === 0) {\n throw new TypeError('distinct fieldName must be a non-empty string')\n }\n if (!isPlainObject(filter)) {\n throw new TypeError('distinct filter must be a plain object')\n }\n return await this.client.request<{ results: unknown[] }>(\n 'POST',\n `/v5/classes/${this.name}/distinct/${encodeURIComponent(fieldName)}`,\n filter\n )\n }\n\n // ==================== Schema Management ====================\n\n /**\n * Create this collection (table) in the application's database.\n *\n * @example\n * ```ts\n * await client.db.collection('posts').create()\n * ```\n */\n async create(): Promise<ApiResponse> {\n return await this.client.request('POST', `/v5/schemas/${encodeURIComponent(this.name)}`)\n }\n\n /**\n * Clear all documents from this collection without dropping it.\n *\n * @returns Response with `data.deletedCount`\n *\n * @example\n * ```ts\n * const { data } = await client.db.collection('temp').clear()\n * console.log(data.deletedCount) // 150\n * ```\n */\n async clear(): Promise<ApiResponse<{ deletedCount: number }>> {\n return await this.client.request<{ deletedCount: number }>(\n 'PUT',\n `/v5/schemas/${encodeURIComponent(this.name)}`\n )\n }\n\n /**\n * Drop (delete) this collection entirely.\n *\n * @example\n * ```ts\n * await client.db.collection('old_collection').drop()\n * ```\n */\n async drop(): Promise<ApiResponse> {\n return await this.client.request('DELETE', `/v5/schemas/${encodeURIComponent(this.name)}`)\n }\n}\n\nexport default T1Collection\n","/**\n * T1YOS — Main client class for the t1yOS Serverless Platform SDK.\n *\n * Provides:\n * - Initialization with server time sync\n * - Chainable database operations via `db.collection(name)`\n * - Cloud function invocation\n * - Metadata retrieval\n * - Cryptographic utilities\n */\n\nimport {\n DEFAULT_BASE_URL,\n DEFAULT_VERSION,\n DEFAULT_SAFE_MODE,\n DEFAULT_TIME_FORMAT,\n DEFAULT_OFFSET,\n} from '../constants'\nimport { validateInitConfig, assertObjectID } from '../utils/validators'\nimport {\n isNonEmptyObject,\n isPlainObject,\n isNonEmptyArrayWithNonEmptyObjects,\n} from '../utils/convert'\nimport { hmacSHA256Hex, verifyHmacSHA256 } from '../crypto'\nimport { executeRequest } from '../http'\nimport { T1Collection } from './T1Collection'\nimport type {\n T1YOSConfig,\n T1YOSInternalConfig,\n HttpMethod,\n ApiResponse,\n InitResult,\n} from '../types'\n\n/**\n * Main T1Y client class.\n *\n * @example\n * ```ts\n * import { T1YOS } from 't1y-sdk-js'\n *\n * const client = new T1YOS({\n * appId: 1001,\n * apiKey: '4fd7448cdc684431a62d8a0111dc6973',\n * secretKey: '17b784e359c946ffa65eebbf9ce29752',\n * })\n *\n * await client.init()\n *\n * // Database operations\n * const { data } = await client.db.collection('users').insertOne({ name: 'Alice' })\n * ```\n */\nexport class T1YOS {\n private config: T1YOSInternalConfig\n\n /**\n * Database accessor providing chainable collection operations.\n *\n * @example\n * ```ts\n * await client.db.collection('users').insertOne({ name: 'Alice' })\n * await client.db.collection('users').findOne({ name: 'Alice' })\n * ```\n */\n readonly db: {\n collection: (name: string) => T1Collection\n toObjectID: (id: string) => string\n getCollections: () => Promise<ApiResponse<{ results: string[] }>>\n }\n\n /**\n * Create a new T1YOS client instance.\n *\n * @param config - Client configuration (appId, apiKey, secretKey are required)\n *\n * @throws {ValidationError} If required parameters are invalid\n */\n constructor(config: T1YOSConfig) {\n // Validate required parameters\n validateInitConfig(config)\n\n this.config = {\n baseUrl: config.baseUrl ?? DEFAULT_BASE_URL,\n appId: config.appId,\n apiKey: config.apiKey,\n secretKey: config.secretKey,\n version: config.version ?? DEFAULT_VERSION,\n isSafeMode: config.isSafeMode ?? DEFAULT_SAFE_MODE,\n timeFormat: config.timeFormat ?? DEFAULT_TIME_FORMAT,\n offset: config.offset ?? DEFAULT_OFFSET,\n }\n\n // Set up the chainable db accessor\n this.db = {\n collection: (name: string) => this.#collection(name),\n toObjectID: (id: string) => this.#toObjectID(id),\n getCollections: () => this.#getCollections(),\n }\n }\n\n /**\n * Initialize the SDK by syncing with the server.\n *\n * Calls `GET /init/:appId` to:\n * 1. Get the server's current UTC Unix timestamp\n * 2. Get the server's isSafeMode setting\n *\n * The time offset is computed as: `server.unix - client.unix`\n * This offset is used for all subsequent request signing to prevent clock skew issues.\n *\n * @throws {T1YError} If the server returns an error (e.g., app not found, app disabled)\n */\n async init(): Promise<void> {\n try {\n const res = await this.request<InitResult>(\n 'GET',\n `/init/${this.config.appId}`,\n undefined,\n false\n )\n const data = res.data\n this.config.isSafeMode = data.is_safe_mode\n this.config.offset = data.unix - Math.floor(Date.now() / 1000)\n } catch (err) {\n console.warn('Failed to get time offset from server, defaulting to 0. Error:', err)\n this.config.isSafeMode = false\n this.config.offset = 0\n }\n }\n\n // ==================== Public API ====================\n\n /**\n * Get application metadata.\n *\n * @param field - Optional field name to retrieve a specific metadata field\n * @returns Metadata as key-value pairs, or a single field value if `field` is specified\n *\n * @example\n * ```ts\n * // Get all metadata\n * const { data } = await client.getMeta()\n * // data.results = { version: 1, collections: [...] }\n *\n * // Get a specific field\n * const { data } = await client.getMeta('version')\n * // data.result = 1\n * ```\n */\n async getMeta(field?: string): Promise<ApiResponse> {\n if (field !== undefined && field !== '' && typeof field !== 'string') {\n throw new TypeError('Meta field must be a string')\n }\n const queryPath = field ? `?field=${encodeURIComponent(field)}` : ''\n return await this.request('GET', `/v5/meta${queryPath}`)\n }\n\n /**\n * Check if there's a newer version of the application available.\n *\n * Compares the server's `version` metadata field against the configured `version`.\n *\n * @returns `true` if the server version is greater than the client version\n */\n async checkUpdate(): Promise<boolean> {\n try {\n const res = await this.request<{ result: number }>('GET', '/v5/meta?field=version')\n return res.data.result > this.config.version\n } catch {\n return false\n }\n }\n\n /**\n * Call a cloud function (`.jsc` file).\n *\n * If `name` doesn't end with `.jsc`, it's auto-appended.\n * If `name` ends with `/`, `index.jsc` is appended.\n * If `name` ends with `.js`, it's replaced with `.jsc`.\n *\n * @param name - Function name or path (e.g., 'hello' or 'hello.jsc')\n * @param params - Parameters to pass to the function\n * @param enableSafeMode - Override safe mode for this call (defaults to client setting)\n *\n * @example\n * ```ts\n * const { data } = await client.callFunc('hello', { name: 'World' })\n * ```\n */\n async callFunc(\n name: string,\n params: unknown = null,\n enableSafeMode?: boolean\n ): Promise<ApiResponse> {\n if (typeof name !== 'string') {\n throw new TypeError('Function name must be a string')\n }\n return await this.request(\n 'POST',\n `/${this.config.appId}/${this.#ensureJscExtension(name)}`,\n params,\n enableSafeMode\n )\n }\n\n /**\n * Core HTTP request method with full authentication and encryption.\n *\n * @param method - HTTP method (GET, POST, PUT, DELETE)\n * @param path - API path (e.g., /v5/classes/users)\n * @param params - Request parameters/body\n * @param encryption - Override encryption (defaults to client.isSafeMode)\n * @returns Typed API response\n *\n * @throws {T1YError} On API errors (non-2xx responses)\n * @throws {Error} On network errors or timeouts\n */\n async request<T = unknown>(\n method: HttpMethod,\n path: string,\n params?: unknown,\n encryption?: boolean\n ): Promise<ApiResponse<T>> {\n if (typeof path !== 'string') {\n throw new TypeError('request path must be a string')\n }\n\n return await executeRequest<T>(this.config, {\n method,\n path,\n params,\n encryption: encryption ?? this.config.isSafeMode,\n })\n }\n\n // ==================== Utilities ====================\n\n /**\n * Validate an ObjectID hex string.\n *\n * @param idStr - 24-character hex string to validate\n * @param name - Optional name for error messages (default: 'ObjectID')\n * @returns `true` if valid\n * @throws {ValidationError} If the string is not a valid ObjectID\n */\n assertObjectID(idStr: string, name = 'ObjectID'): boolean {\n return assertObjectID(idStr, name)\n }\n\n /** Check if a value is a non-null, non-array object with at least one key */\n isNonEmptyObject(value: unknown): boolean {\n return isNonEmptyObject(value)\n }\n\n /** Check if a value is a plain object (non-null, non-array) */\n isPlainObject(value: unknown): boolean {\n return isPlainObject(value)\n }\n\n /** Check if a value is a non-empty array where every element is a non-empty object */\n isNonEmptyArrayWithNonEmptyObjects(value: unknown): boolean {\n return isNonEmptyArrayWithNonEmptyObjects(value)\n }\n\n // ==================== Crypto ====================\n\n /**\n * Compute HMAC-SHA256 hash and return hex digest.\n *\n * @param message - The message to sign\n * @param secret - The secret key\n * @returns 64-character hex-encoded HMAC-SHA256\n */\n hmacSHA256(secret: string, message: string): string {\n return hmacSHA256Hex(secret, message)\n }\n\n /**\n * Verify an HMAC-SHA256 signature using constant-time comparison.\n *\n * @param secret - The secret key\n * @param message - The message that was signed\n * @param signature - The expected signature (hex string)\n * @returns `true` if the signature matches\n */\n verifyHmacSHA256(secret: string, message: string, signature: string): boolean {\n return verifyHmacSHA256(secret, message, signature)\n }\n\n // ==================== Private Helpers ====================\n\n /** Create a T1Collection for the given collection name */\n #collection(name: string): T1Collection {\n if (typeof name !== 'string') {\n throw new TypeError('Collection name must be a string')\n }\n return new T1Collection(this, name)\n }\n\n /** Get all collections in the application's database */\n async #getCollections(): Promise<ApiResponse<{ results: string[] }>> {\n return await this.request<{ results: string[] }>('GET', '/v5/schemas')\n }\n\n /** Convert a 24-char hex string to an ObjectID marker */\n #toObjectID(idStr: string): string {\n assertObjectID(idStr)\n return `ObjectID('${idStr}')`\n }\n\n /** Ensure a function name has the .jsc extension */\n #ensureJscExtension(input: string): string {\n let path = input.startsWith('/') ? input.slice(1) : input\n\n // Separate hash fragment\n const hashIndex = path.indexOf('#')\n const hash = hashIndex !== -1 ? path.slice(hashIndex) : ''\n const withoutHash = hashIndex !== -1 ? path.slice(0, hashIndex) : path\n\n // Separate query string\n const qIndex = withoutHash.indexOf('?')\n const query = qIndex !== -1 ? withoutHash.slice(qIndex) : ''\n let mainPath = qIndex !== -1 ? withoutHash.slice(0, qIndex) : withoutHash\n\n // Apply extension rules\n if (mainPath.endsWith('/')) {\n mainPath = mainPath + 'index.jsc'\n } else if (mainPath.endsWith('.jsc')) {\n // Already has .jsc\n } else if (mainPath.endsWith('.js')) {\n mainPath = mainPath.replace(/\\.js$/, '.jsc')\n } else {\n mainPath = mainPath + '.jsc'\n }\n\n return mainPath + query + hash\n }\n}\n\nexport default T1YOS\n","import { OBJECT_ID_PATTERN } from '../constants'\n\n/**\n * Create an ObjectID marker string that the server will convert to a MongoDB ObjectID.\n *\n * @param id - 24-character hexadecimal string\n * @returns ObjectID marker string, e.g. `ObjectID('507f1f77bcf86cd799439011')`\n *\n * @example\n * ```ts\n * import { ObjectID } from 't1y-sdk-js'\n *\n * await db.collection('users').find(ObjectID('507f1f77bcf86cd799439011'))\n * ```\n */\nexport function ObjectID(id: string): `ObjectID('${string}')` {\n if (!OBJECT_ID_PATTERN.test(id)) {\n throw new Error(`Invalid ObjectID: \"${id}\" (must be 24 hex characters)`)\n }\n return `ObjectID('${id}')`\n}\n","/**\n * Create a Date marker string. The server converts this to a Go time.Time.\n *\n * @param dateStr - ISO 8601 / RFC 3339 date string\n * @returns Date marker, e.g. `Date('2024-01-15T10:30:00Z')`\n */\nexport function Date_(dateStr: string): `Date('${string}')` {\n return `Date('${dateStr}')`\n}\n\n/**\n * Create a DateTime marker string. Same as Date on the server side.\n *\n * @param dateStr - ISO 8601 / RFC 3339 date string\n * @returns DateTime marker, e.g. `DateTime('2024-01-15T10:30:00Z')`\n */\nexport function DateTime(dateStr: string): `DateTime('${string}')` {\n return `DateTime('${dateStr}')`\n}\n\n/**\n * Create a Timestamp marker string. The server converts this to a Unix timestamp.\n *\n * @param unix - Unix timestamp (seconds) as number or string\n * @returns Timestamp marker, e.g. `Timestamp('1705312200')`\n */\nexport function Timestamp(unix: number | string): `Timestamp('${string}')` {\n return `Timestamp('${String(unix)}')`\n}\n","/**\n * Create a Boolean marker. The server converts this to a Go bool.\n */\nexport function Boolean_(val: boolean): `Boolean(${string})` {\n return `Boolean(${val})`\n}\n\n/**\n * Create an Integer marker. The server converts this to int32.\n */\nexport function Integer(n: number): `Integer(${number})` {\n return `Integer(${n})`\n}\n\n/**\n * Create a Bigint marker. The server converts this to int64.\n */\nexport function Bigint(n: number | bigint): `Bigint(${number})` {\n return `Bigint(${Number(n)})`\n}\n\n/**\n * Create a Float marker. The server converts this to float32.\n */\nexport function Float(n: number): `Float(${number})` {\n return `Float(${n})`\n}\n\n/**\n * Create a Double marker. The server converts this to float64.\n */\nexport function Double(n: number): `Double(${number})` {\n return `Double(${n})`\n}\n","/**\n * Create an Array marker. The server converts this to a Go slice.\n *\n * @param arr - Array to serialize as JSON\n */\nexport function Array_(arr: unknown[]): `Array(${string})` {\n return `Array(${JSON.stringify(arr)})`\n}\n\n/**\n * Create a Map marker. The server converts this to a map[string]interface{}.\n *\n * @param obj - Object to serialize as JSON\n */\nexport function Map_(obj: Record<string, unknown>): `Map(${string})` {\n return `Map(${JSON.stringify(obj)})`\n}\n\n/**\n * Create a Map[] marker. The server converts this to []map[string]interface{}.\n *\n * @param arr - Array of objects to serialize as JSON\n */\nexport function MapArray(arr: Record<string, unknown>[]): `Map[](${string})` {\n return `Map[](${JSON.stringify(arr)})`\n}\n","/**\n * Null / null-equivalent markers that the server converts to Go nil.\n *\n * The server recognizes all these variants as null:\n * 'Null', 'null', 'NULL', 'None', 'none', 'NONE', 'Nil', 'nil', 'NIL', '<nil>', ''\n */\n\n/** Null marker — server converts to nil */\nexport const Null = 'Null' as const\n\n/** None marker — server converts to nil */\nexport const None = 'None' as const\n\n/** Nil marker — server converts to nil */\nexport const Nil = 'Nil' as const\n\n/** empty string — server converts to nil (use '' directly) */\nexport const Empty = '' as const\n\n/**\n * Undefined markers that the server converts to bson.Undefined{}.\n */\nexport const UNDEFINED = 'UNDEFINED' as const\nexport const Undefined = 'Undefined' as const\n","/**\n * Time helper markers that the server evaluates at request time.\n *\n * These are string values that, when sent to the server, are replaced\n * with the actual current time on the server side via Go's time.Now().\n */\n\n/** Server fills in time.Now() (current UTC time) */\nexport const TimeNow = 'time.Now()' as const\n\n/** Server fills in time.Now().Unix() (current Unix timestamp) */\nexport const TimeNowUnix = 'time.Now().Unix()' as const\n\n/** Server fills in time.Now().UnixNano() */\nexport const TimeNowUnixNano = 'time.Now().UnixNano()' as const\n\n/** Server fills in time.Now().Weekday() (e.g., time.Monday) */\nexport const TimeNowWeekday = 'time.Now().Weekday()' as const\n\n/** Server fills in time.Now().Weekday().Chinese() (Chinese weekday name) */\nexport const TimeNowWeekdayChinese = 'time.Now().Weekday().Chinese()' as const\n\n/**\n * Convenience object grouping all time-now helpers.\n *\n * @example\n * ```ts\n * import { timeNow } from 't1y-sdk-js'\n *\n * await db.collection('posts').insertOne({\n * title: 'Hello',\n * createdAt: timeNow.Now(),\n * })\n * ```\n */\nexport const timeNow = {\n Now: () => TimeNow,\n NowUnix: () => TimeNowUnix,\n NowUnixNano: () => TimeNowUnixNano,\n NowWeekday: () => TimeNowWeekday,\n NowWeekdayChinese: () => TimeNowWeekdayChinese,\n}\n"],"mappings":"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","names":["src_exports","__export","Array_","Bigint","Boolean_","Date_","DateTime","Double","Empty","Float","Integer","Map_","MapArray","Nil","None","Null","ObjectID","T1Collection","T1YError","T1YOS","TimeNow","TimeNowUnix","TimeNowUnixNano","TimeNowWeekday","TimeNowWeekdayChinese","Timestamp","UNDEFINED","Undefined","ValidationError","assertObjectID","convertDateTypes","createSignature","decryptAESGCM","T1YOS_default","encryptAESGCM","formatTimestampsToLocal","getMiniProgramAPI","getMiniProgramSubType","getPlatformType","getSafeTimestamp","hmacSHA256Hex","hmacSHA256HexAsync","isAESGCMAvailable","isNonEmptyArrayWithNonEmptyObjects","isNonEmptyObject","isPlainObject","isWebCryptoAvailable","resetPlatformDetection","sha256Hex","sha256HexAsync","timeNow","validateApiKey","validateAppId","validateBaseUrl","validateInitConfig","validateSecretKey","verifyHmacSHA256","__toCommonJS","DEFAULT_BASE_URL","DEFAULT_TIME_FORMAT","OBJECT_ID_PATTERN","T1YError","code","message","data","ValidationError","validateAppId","appId","ValidationError","validateApiKey","apiKey","validateSecretKey","secretKey","validateBaseUrl","baseUrl","validateInitConfig","config","assertObjectID","idStr","name","OBJECT_ID_PATTERN","convertDateTypes","value","str","v","obj","key","isNonEmptyObject","isPlainObject","isNonEmptyArrayWithNonEmptyObjects","item","getNodeRequire","sha256Hex","data","nodeReq","bytes","utf8ToBytes","sha256RawBytesHex","sha256Raw","sha256HexAsync","encoder","hashBuffer","b","str","i","c","c2","cp","K","msgByteLen","msgBitLen","padLen","totalLen","padded","H","offset","W","t","s0","rotr","s1","a","d","e","f","g","h","S1","ch","temp1","S0","maj","temp2","v","x","n","getNodeRequire","hmacSHA256Hex","secret","message","nodeReq","hmacSHA256Pure","hmacSHA256HexAsync","encoder","key","signature","b","verifyHmacSHA256","expected","timingSafeEqual","a","result","i","keyBytes","utf8ToBytes","msgBytes","hexToBytes","sha256RawBytesHex","paddedKey","ipad","innerKey","xorBytes","innerData","innerHash","opad","outerKey","outerData","str","bytes","c","c2","cp","hex","SBOX","RCON","keyExpansion256","key","Nk","Nr","totalWords","words","temp","subWord","rotWord","roundKeys","r","rk","j","w","aesEncryptBlock","block","state","i","addRoundKey","round","subBytes","shiftRows","mixColumns","out","row","a","gmul","roundKey","b","p","aa","bb","hiBit","aesCtr","counter","data","blockCount","output","ctr","keystream","blockLen","incrementCounter","val","writeUint64BE","buf","offset","value","hi","lo","ghash","h","aad","ciphertext","aadBlocks","ctBlocks","totalBlocks","y","len","mulResult","gfMul","lenBlock","aadBitLen","ctBitLen","x","result","v","byteIdx","bit","k","lsb","aesGcmEncryptPure","plaintext","nonce","j0","zeroBlock","j0Block","ctrBlock","s","encryptedS","tag","aesGcmDecryptPure","expectedTag","mismatch","getWebCrypto","nodeReq","nodeCryptoModule","isAESGCMAvailable","isWebCryptoAvailable","AES_GCM_TAG_LENGTH","AES_GCM_NONCE_LENGTH","getRandomBytes","length","wc","bytes","i","encodeBase64","uint8array","binary","len","decodeBase64","b64","encryptAESGCMWebCrypto","data","keyBytes","cryptoApi","key","nonce","encodedData","encrypted","ciphertext","tag","payload","decryptAESGCMWebCrypto","jsonPayload","n","j","t","sealed","decrypted","encryptAESGCMPure","plaintext","aesGcmEncryptPure","decryptAESGCMPure","aesGcmDecryptPure","encryptAESGCM","decryptAESGCM","createSignature","input","method","pathAndQuery","body","appId","timestamp","secretKey","bodyHash","sha256Hex","message","hmacSHA256Hex","getSafeTimestamp","offset","normalizeBaseUrl","baseUrl","appendQueryParams","url","params","key","value","formatLocalTime","utcString","format","date","pad","n","formatTimestampsToLocal","data","DEFAULT_TIME_FORMAT","traverse","value","result","key","handleResponse","response","isSafeMode","secretKey","timeFormat","contentType","rawData","responseText","decrypted","decryptAESGCM","err","T1YError","isOk","apiResp","formatTimestampsToLocal","handleFetchError","error","message","_platformType","_miniProgramSubType","getPlatformType","getMiniProgramSubType","getMiniProgramAPI","platform","resetPlatformDetection","fetchRequest","options","url","method","headers","body","signal","fetchOptions","response","responseHeaders","value","key","responseBody","wxRequest","options","mpApi","getMiniProgramAPI","requestFn","url","method","headers","body","timeout","resolve","reject","requestTask","res","responseHeaders","key","bodyStr","err","errMsg","onAbort","myRequest","options","mpApi","requestFn","url","method","headers","body","timeout","resolve","reject","requestTask","res","status","responseHeaders","key","bodyStr","err","errMsg","onAbort","getSystemFetch","hapRequest","options","sysFetch","url","method","headers","body","resolve","reject","res","responseHeaders","key","err","_cachedRequest","getPlatformRequest","_cachedRequest","getPlatformType","fetchRequest","wxRequest","myRequest","hapRequest","executeRequest","client","options","method","path","params","encryption","timeout","baseUrl","normalizeBaseUrl","isSafeMode","fullUrl","convertedParams","convertDateTypes","bodyForRequest","rawBodyString","encryptedBody","encryptAESGCM","jsonBody","appendQueryParams","timestamp","getSafeTimestamp","originalURL","sign","createSignature","platformRequest","getPlatformRequest","timeoutMs","response","handleResponse","error","handleFetchError","T1Collection","client","name","data","isNonEmptyObject","objectId","assertObjectID","filter","body","dataList","isNonEmptyArrayWithNonEmptyObjects","isPlainObject","page","size","sort","pipeline","fieldName","_T1YOS_instances","collection_fn","getCollections_fn","toObjectID_fn","ensureJscExtension_fn","T1YOS","config","__privateAdd","validateInitConfig","DEFAULT_BASE_URL","DEFAULT_TIME_FORMAT","name","__privateMethod","id","data","err","field","queryPath","params","enableSafeMode","method","path","encryption","executeRequest","idStr","assertObjectID","value","isNonEmptyObject","isPlainObject","isNonEmptyArrayWithNonEmptyObjects","secret","message","hmacSHA256Hex","signature","verifyHmacSHA256","T1Collection","input","hashIndex","hash","withoutHash","qIndex","query","mainPath","T1YOS_default","ObjectID","id","OBJECT_ID_PATTERN","Date_","dateStr","DateTime","Timestamp","unix","Boolean_","val","Integer","n","Bigint","Float","Double","Array_","arr","Map_","obj","MapArray","Null","None","Nil","Empty","UNDEFINED","Undefined","TimeNow","TimeNowUnix","TimeNowUnixNano","TimeNowWeekday","TimeNowWeekdayChinese","timeNow"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/constants.ts","../src/utils/errors.ts","../src/utils/validators.ts","../src/utils/convert.ts","../src/crypto/sha256.ts","../src/crypto/hmac.ts","../src/crypto/aes-pure.ts","../src/crypto/aes.ts","../src/crypto/sign.ts","../src/utils/url.ts","../src/utils/time.ts","../src/http/response.ts","../src/platform/detect.ts","../src/platform/request/fetch.ts","../src/platform/request/wx.ts","../src/platform/request/my.ts","../src/platform/request/hap.ts","../src/platform/dispatcher.ts","../src/http/request.ts","../src/client/T1Collection.ts","../src/client/T1YOS.ts","../src/special-types/object-id.ts","../src/special-types/date-types.ts","../src/special-types/numeric-types.ts","../src/special-types/structured-types.ts","../src/special-types/null-types.ts","../src/special-types/time-helpers.ts"],"sourcesContent":["/**\n * t1yOS Serverless Platform JavaScript/TypeScript SDK\n *\n * @packageDocumentation\n *\n * @example\n * ```ts\n * import { T1YOS, ObjectID, timeNow } from 't1y-sdk-js'\n *\n * const client = new T1YOS({\n * appId: 1001,\n * apiKey: 'your-api-key-32-characters-here!',\n * secretKey: 'your-secret-key-32-characters!',\n * })\n *\n * await client.init()\n *\n * // Database operations\n * await client.db.collection('users').insertOne({\n * name: 'Alice',\n * age: 25,\n * createdAt: timeNow.Now(),\n * })\n *\n * const { data } = await client.db.collection('users').findOne({ name: 'Alice' })\n * console.log(data.result)\n * ```\n */\n\n// Main client classes\nexport { T1YOS } from './client/T1YOS'\nexport { T1Collection } from './client/T1Collection'\n\n// Special type helpers\nexport {\n ObjectID,\n Date,\n DateTime,\n Timestamp,\n Boolean,\n Integer,\n Bigint,\n Float,\n Double,\n Array,\n Map,\n MapArray,\n Null,\n None,\n Nil,\n Empty,\n UNDEFINED,\n Undefined,\n TimeNow,\n TimeNowUnix,\n TimeNowUnixNano,\n TimeNowWeekday,\n TimeNowWeekdayChinese,\n timeNow,\n} from './special-types'\n\n// Cryptographic utilities (for advanced use)\nexport {\n sha256Hex,\n sha256HexAsync,\n hmacSHA256Hex,\n hmacSHA256HexAsync,\n verifyHmacSHA256,\n encryptAESGCM,\n decryptAESGCM,\n isAESGCMAvailable,\n isWebCryptoAvailable,\n createSignature,\n getSafeTimestamp,\n} from './crypto'\n\n// Utility functions\nexport {\n formatTimestampsToLocal,\n convertDateTypes,\n validateInitConfig,\n validateAppId,\n validateApiKey,\n validateSecretKey,\n validateBaseUrl,\n assertObjectID,\n isNonEmptyObject,\n isPlainObject,\n isNonEmptyArrayWithNonEmptyObjects,\n} from './utils'\n\n// Custom error classes\nexport { T1YError, ValidationError } from './utils/errors'\n\n// Core types\nexport type {\n T1YOSConfig,\n T1YOSInternalConfig,\n HttpMethod,\n ApiResponse,\n InsertResult,\n InsertManyResult,\n DeleteResult,\n DeleteManyResult,\n UpdateResult,\n UpdateManyResult,\n FindResult,\n Pagination,\n PaginationResult,\n AggregateResult,\n InitResult,\n} from './types'\n\nexport type { AESGCMPayload, SignatureInput } from './crypto'\n\n// Special type marker types\nexport type {\n ObjectIDMarker,\n DateMarker,\n DateTimeMarker,\n TimestampMarker,\n BooleanMarker,\n IntegerMarker,\n BigintMarker,\n FloatMarker,\n DoubleMarker,\n ArrayMarker,\n MapMarker,\n MapArrayMarker,\n NullMarker,\n UndefinedMarker,\n TimeNowMarker,\n TimeNowUnixMarker,\n TimeNowUnixNanoMarker,\n TimeNowWeekdayMarker,\n TimeNowWeekdayChineseMarker,\n SpecialTypeMarker,\n} from './types/special-types'\n\n// Platform detection and adapters (for cross-platform usage)\nexport {\n getPlatformType,\n getMiniProgramSubType,\n getMiniProgramAPI,\n resetPlatformDetection,\n} from './platform'\n\nexport type { PlatformType, MiniProgramSubType } from './platform'\n\n// Default export\nexport { default } from './client/T1YOS'\n","/** Default base URL for the t1yOS platform */\nexport const DEFAULT_BASE_URL = 'https://myapp.t1y.net'\n\n/** Minimum valid application ID */\nexport const MIN_APP_ID = 1001\n\n/** Required length for API Key */\nexport const API_KEY_LENGTH = 32\n\n/** Required length for Secret Key */\nexport const SECRET_KEY_LENGTH = 32\n\n/** Default application version */\nexport const DEFAULT_VERSION = 0\n\n/** Default time format for createdAt/updatedAt fields */\nexport const DEFAULT_TIME_FORMAT = 'YYYY-MM-DD HH:mm:ss'\n\n/** Default time offset in seconds */\nexport const DEFAULT_OFFSET = 0\n\n/** Default safe mode setting */\nexport const DEFAULT_SAFE_MODE = false\n\n/** Maximum time difference allowed for request timestamp (seconds) */\nexport const MAX_TIME_DIFF = 10\n\n/** Request timeout in milliseconds (5 minutes) */\nexport const REQUEST_TIMEOUT_MS = 5 * 60 * 1000\n\n/** Maximum page size for find queries */\nexport const MAX_PAGE_SIZE = 100\n\n/** Default page size */\nexport const DEFAULT_PAGE_SIZE = 10\n\n/** ObjectID hex string length */\nexport const OBJECT_ID_LENGTH = 24\n\n/** ObjectID hex pattern */\nexport const OBJECT_ID_PATTERN = /^[0-9a-fA-F]{24}$/\n\n/** API version prefix */\nexport const API_VERSION = 'v5'\n","/**\n * Custom error class for t1yOS SDK errors.\n * Wraps API error responses with code, message, and data.\n */\nexport class T1YError extends Error {\n /** HTTP status or error code */\n code: number\n /** Response data from server (if any) */\n data: unknown\n\n constructor(code: number, message: string, data?: unknown) {\n super(message)\n this.name = 'T1YError'\n this.code = code\n this.data = data\n }\n\n toJSON(): Record<string, unknown> {\n return {\n name: this.name,\n code: this.code,\n message: this.message,\n data: this.data,\n }\n }\n}\n\n/**\n * Validation error thrown when configuration parameters are invalid.\n */\nexport class ValidationError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'ValidationError'\n }\n}\n","import { MIN_APP_ID, API_KEY_LENGTH, SECRET_KEY_LENGTH, OBJECT_ID_PATTERN } from '../constants'\nimport { ValidationError } from './errors'\nimport type { T1YOSConfig } from '../types'\n\n/**\n * Validate that the application ID is a valid integer >= MIN_APP_ID.\n */\nexport function validateAppId(appId: number): void {\n if (!Number.isInteger(appId)) {\n throw new ValidationError('appId must be an integer')\n }\n if (appId < MIN_APP_ID) {\n throw new ValidationError(`appId must be >= ${MIN_APP_ID}`)\n }\n}\n\n/**\n * Validate that the API Key is exactly the required length.\n */\nexport function validateApiKey(apiKey: string): void {\n if (typeof apiKey !== 'string') {\n throw new ValidationError('apiKey must be a string')\n }\n if (apiKey.length !== API_KEY_LENGTH) {\n throw new ValidationError(\n `apiKey must be exactly ${API_KEY_LENGTH} characters (got ${apiKey.length})`\n )\n }\n}\n\n/**\n * Validate that the Secret Key is exactly the required length.\n */\nexport function validateSecretKey(secretKey: string): void {\n if (typeof secretKey !== 'string') {\n throw new ValidationError('secretKey must be a string')\n }\n if (secretKey.length !== SECRET_KEY_LENGTH) {\n throw new ValidationError(\n `secretKey must be exactly ${SECRET_KEY_LENGTH} characters (got ${secretKey.length})`\n )\n }\n}\n\n/**\n * Validate the base URL format.\n */\nexport function validateBaseUrl(baseUrl: string): void {\n if (!/^https?:\\/\\//.test(baseUrl)) {\n throw new ValidationError('baseUrl must start with \"http://\" or \"https://\"')\n }\n}\n\n/**\n * Validate all configuration parameters at once.\n */\nexport function validateInitConfig(config: T1YOSConfig): void {\n if (config.baseUrl !== undefined) {\n validateBaseUrl(config.baseUrl)\n }\n validateAppId(config.appId)\n validateApiKey(config.apiKey)\n validateSecretKey(config.secretKey)\n\n if (config.version !== undefined && (!Number.isInteger(config.version) || config.version < 0)) {\n throw new ValidationError('version must be a non-negative integer')\n }\n}\n\n/**\n * Validate an ObjectID hex string.\n * Returns true if valid, throws otherwise.\n */\nexport function assertObjectID(idStr: string, name = 'ObjectID'): boolean {\n if (typeof idStr !== 'string') {\n throw new ValidationError(`${name} must be a string`)\n }\n if (!OBJECT_ID_PATTERN.test(idStr)) {\n throw new ValidationError(`Invalid ${name} string: \"${idStr}\"`)\n }\n return true\n}\n","/**\n * Recursively convert JavaScript Date objects and timestamp numbers\n * into the marker string format that the server's GetDataTypes() recognizes.\n *\n * - Date objects → `Date('ISO-8601')`\n * - Numbers >= 10 digits → `Timestamp('unix')`\n * - Already-marker strings (starting with recognized prefixes) are passed through\n */\nexport function convertDateTypes(value: unknown): unknown {\n if (value instanceof Date) {\n return `Date('${value.toISOString()}')`\n }\n\n if (typeof value === 'number') {\n const str = String(value)\n // 10+ digit integer → Timestamp\n if (/^\\d{10,}$/.test(str)) {\n return `Timestamp('${str}')`\n }\n return value\n }\n\n if (Array.isArray(value)) {\n return value.map((v) => convertDateTypes(v))\n }\n\n if (value && typeof value === 'object') {\n const obj: Record<string, unknown> = {}\n for (const key in value as Record<string, unknown>) {\n if (Object.prototype.hasOwnProperty.call(value, key)) {\n obj[key] = convertDateTypes((value as Record<string, unknown>)[key])\n }\n }\n return obj\n }\n\n return value\n}\n\n/**\n * Check if a value is a non-null, non-array object with at least one key.\n */\nexport function isNonEmptyObject(value: unknown): boolean {\n return (\n typeof value === 'object' &&\n value !== null &&\n !Array.isArray(value) &&\n Object.keys(value).length > 0\n )\n}\n\n/**\n * Check if a value is a plain object (non-null, non-array).\n */\nexport function isPlainObject(value: unknown): boolean {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\n/**\n * Check if a value is a non-empty array where every element is a non-empty object.\n */\nexport function isNonEmptyArrayWithNonEmptyObjects(value: unknown): boolean {\n if (!Array.isArray(value) || value.length === 0) {\n return false\n }\n return value.every(\n (item) =>\n typeof item === 'object' &&\n item !== null &&\n !Array.isArray(item) &&\n Object.keys(item).length > 0\n )\n}\n","/**\n * SHA-256 hashing — works in both Node.js and browser environments.\n *\n * Node.js (CJS): Uses node:crypto (synchronous via require)\n * Node.js (ESM): Falls back to pure-JS (works correctly for all byte values)\n * Browser: Uses pure-JS implementation\n */\n\n// Detect if require is available (CJS context)\nfunction getNodeRequire(): ((m: string) => unknown) | null {\n try {\n // In CJS, `require` is a local variable\n if (typeof require !== 'undefined') {\n return require\n }\n } catch {\n // require is not defined (ESM or browser)\n }\n return null\n}\n\n/**\n * Compute the SHA-256 hash of a string and return the hex digest.\n *\n * For the signing path: the input is always a UTF-8 string\n * (method, URL, body JSON, etc.), so this works correctly.\n *\n * For raw binary data (from HMAC inner hash), use sha256RawBytesHex instead.\n *\n * @param data - Input string to hash (UTF-8)\n * @returns Hex-encoded SHA-256 hash (64 hex characters)\n */\nexport function sha256Hex(data: string): string {\n const nodeReq = getNodeRequire()\n if (nodeReq) {\n try {\n const nodeCrypto = nodeReq('node:crypto') as {\n createHash: (alg: string) => { update: (d: string) => { digest: (enc: string) => string } }\n }\n return nodeCrypto.createHash('sha256').update(data).digest('hex')\n } catch {\n // fall through to pure-JS\n }\n }\n\n // Pure-JS path: encode string as UTF-8 bytes and hash\n const bytes = utf8ToBytes(data)\n return sha256RawBytesHex(bytes)\n}\n\n/**\n * Compute SHA-256 of raw bytes and return hex digest.\n * Used internally by HMAC for hashing binary key data.\n */\nexport function sha256RawBytesHex(bytes: Uint8Array): string {\n return sha256Raw(bytes)\n}\n\n/**\n * Compute SHA-256 hash asynchronously using Web Crypto API.\n */\nexport async function sha256HexAsync(data: string): Promise<string> {\n const nodeReq = getNodeRequire()\n if (nodeReq) {\n try {\n const nodeCrypto = nodeReq('node:crypto') as {\n createHash: (alg: string) => { update: (d: string) => { digest: (enc: string) => string } }\n }\n return nodeCrypto.createHash('sha256').update(data).digest('hex')\n } catch {\n // fall through\n }\n }\n\n const encoder = new TextEncoder()\n const hashBuffer = await crypto.subtle.digest(\n 'SHA-256',\n encoder.encode(data) as Uint8Array<ArrayBuffer>\n )\n return Array.from(new Uint8Array(hashBuffer))\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('')\n}\n\n// ==================== Pure-JS SHA-256 ====================\n\n/**\n * UTF-8 encode a JavaScript string to Uint8Array.\n * Uses TextEncoder when available, falls back to manual encoding.\n */\nfunction utf8ToBytes(str: string): Uint8Array {\n if (typeof TextEncoder !== 'undefined') {\n return new TextEncoder().encode(str) as Uint8Array<ArrayBuffer>\n }\n // Fallback: manual UTF-8 encoding\n const bytes: number[] = []\n for (let i = 0; i < str.length; i++) {\n let c = str.charCodeAt(i)\n if (c < 0x80) {\n bytes.push(c)\n } else if (c < 0x800) {\n bytes.push(0xc0 | (c >> 6), 0x80 | (c & 0x3f))\n } else if (c < 0xd800 || c >= 0xe000) {\n bytes.push(0xe0 | (c >> 12), 0x80 | ((c >> 6) & 0x3f), 0x80 | (c & 0x3f))\n } else {\n // surrogate pair\n i++\n const c2 = str.charCodeAt(i)\n const cp = 0x10000 + ((c & 0x3ff) << 10) + (c2 & 0x3ff)\n bytes.push(\n 0xf0 | (cp >> 18),\n 0x80 | ((cp >> 12) & 0x3f),\n 0x80 | ((cp >> 6) & 0x3f),\n 0x80 | (cp & 0x3f)\n )\n }\n }\n return new Uint8Array(bytes) as Uint8Array<ArrayBuffer>\n}\n\n/**\n * Write a 64-bit unsigned integer in big-endian format.\n * Uses Number (not BigInt) for ES2017 compatibility.\n * The value must be within Number.MAX_SAFE_INTEGER (2^53 - 1).\n */\nfunction writeUint64BE(buf: Uint8Array, offset: number, value: number): void {\n const hi = Math.floor(value / 0x100000000)\n const lo = value % 0x100000000\n buf[offset] = (hi >>> 24) & 0xff\n buf[offset + 1] = (hi >>> 16) & 0xff\n buf[offset + 2] = (hi >>> 8) & 0xff\n buf[offset + 3] = hi & 0xff\n buf[offset + 4] = (lo >>> 24) & 0xff\n buf[offset + 5] = (lo >>> 16) & 0xff\n buf[offset + 6] = (lo >>> 8) & 0xff\n buf[offset + 7] = lo & 0xff\n}\n\n/** SHA-256 implementation that operates on raw bytes */\nfunction sha256Raw(bytes: Uint8Array): string {\n const K = [\n 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,\n 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,\n 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,\n 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,\n 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,\n 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,\n 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,\n 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,\n ]\n\n // Build message schedule\n const msgByteLen = bytes.length\n const msgBitLen = msgByteLen * 8\n\n // Allocate padded message: original bytes + 0x80 + zeros + 8-byte length\n const padLen = (64 - ((msgByteLen + 9) % 64)) % 64\n const totalLen = msgByteLen + 1 + padLen + 8\n const padded = new Uint8Array(totalLen)\n padded.set(bytes)\n padded[msgByteLen] = 0x80\n // Write length as 64-bit big-endian (using Number, no BigInt for ES2017 compat)\n // msgBitLen fits in Number (max ~2^35 bits for 2^32 * 8 bytes)\n writeUint64BE(padded, totalLen - 8, msgBitLen)\n\n const H = [\n 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19,\n ]\n\n // Process each 512-bit chunk\n for (let offset = 0; offset < totalLen; offset += 64) {\n const W = new Array<number>(64)\n\n for (let t = 0; t < 16; t++) {\n W[t] =\n (padded[offset + t * 4]! << 24) |\n (padded[offset + t * 4 + 1]! << 16) |\n (padded[offset + t * 4 + 2]! << 8) |\n padded[offset + t * 4 + 3]!\n }\n\n for (let t = 16; t < 64; t++) {\n const s0 = (rotr(W[t - 15]!, 7) ^ rotr(W[t - 15]!, 18) ^ (W[t - 15]! >>> 3)) >>> 0\n const s1 = (rotr(W[t - 2]!, 17) ^ rotr(W[t - 2]!, 19) ^ (W[t - 2]! >>> 10)) >>> 0\n W[t] = (W[t - 16]! + s0 + W[t - 7]! + s1) >>> 0\n }\n\n let [a, b, c, d, e, f, g, h] = H\n\n for (let t = 0; t < 64; t++) {\n const S1 = (rotr(e!, 6) ^ rotr(e!, 11) ^ rotr(e!, 25)) >>> 0\n const ch = ((e! & f!) ^ (~e! & g!)) >>> 0\n const temp1 = (h! + S1 + ch + K[t]! + W[t]!) >>> 0\n const S0 = (rotr(a!, 2) ^ rotr(a!, 13) ^ rotr(a!, 22)) >>> 0\n const maj = ((a! & b!) ^ (a! & c!) ^ (b! & c!)) >>> 0\n const temp2 = (S0 + maj) >>> 0\n\n h = g\n g = f\n f = e\n e = (d! + temp1) >>> 0\n d = c\n c = b\n b = a\n a = (temp1 + temp2) >>> 0\n }\n\n H[0] = (H[0]! + a!) >>> 0\n H[1] = (H[1]! + b!) >>> 0\n H[2] = (H[2]! + c!) >>> 0\n H[3] = (H[3]! + d!) >>> 0\n H[4] = (H[4]! + e!) >>> 0\n H[5] = (H[5]! + f!) >>> 0\n H[6] = (H[6]! + g!) >>> 0\n H[7] = (H[7]! + h!) >>> 0\n }\n\n return H.map((v) => v.toString(16).padStart(8, '0')).join('')\n}\n\nfunction rotr(x: number, n: number): number {\n return (x >>> n) | (x << (32 - n))\n}\n","/**\n * HMAC-SHA256 implementation — works in both Node.js and browser environments.\n *\n * Node.js (CJS): Uses node:crypto (synchronous via require)\n * Browser / ESM: Uses pure-JS implementation operating on Uint8Array\n */\n\nimport { sha256RawBytesHex } from './sha256'\n\n// Detect if require is available (CJS context)\nfunction getNodeRequire(): ((m: string) => unknown) | null {\n try {\n if (typeof require !== 'undefined') {\n return require\n }\n } catch {\n // require is not defined (ESM or browser)\n }\n return null\n}\n\n/**\n * Compute HMAC-SHA256 and return hex digest.\n *\n * This is intentionally synchronous because it's called in the request\n * signing path, which must be fast and cannot defer to async.\n *\n * @param secret - The secret key (raw string, used as-is as bytes)\n * @param message - The message to sign\n * @returns Hex-encoded HMAC-SHA256 signature (64 hex characters)\n */\nexport function hmacSHA256Hex(secret: string, message: string): string {\n const nodeReq = getNodeRequire()\n if (nodeReq) {\n try {\n const nodeCrypto = nodeReq('node:crypto') as {\n createHmac: (\n alg: string,\n key: string\n ) => { update: (d: string) => { digest: (enc: string) => string } }\n }\n return nodeCrypto.createHmac('sha256', secret).update(message).digest('hex')\n } catch {\n // fall through to pure-JS\n }\n }\n\n // Pure-JS HMAC-SHA256 implementation\n return hmacSHA256Pure(secret, message)\n}\n\n/**\n * Compute HMAC-SHA256 asynchronously using Web Crypto API.\n */\nexport async function hmacSHA256HexAsync(secret: string, message: string): Promise<string> {\n const nodeReq = getNodeRequire()\n if (nodeReq) {\n try {\n const nodeCrypto = nodeReq('node:crypto') as {\n createHmac: (\n alg: string,\n key: string\n ) => { update: (d: string) => { digest: (enc: string) => string } }\n }\n return nodeCrypto.createHmac('sha256', secret).update(message).digest('hex')\n } catch {\n // fall through\n }\n }\n\n const encoder = new TextEncoder()\n const key = await crypto.subtle.importKey(\n 'raw',\n encoder.encode(secret) as Uint8Array<ArrayBuffer>,\n { name: 'HMAC', hash: 'SHA-256' },\n false,\n ['sign']\n )\n const signature = await crypto.subtle.sign(\n 'HMAC',\n key,\n encoder.encode(message) as Uint8Array<ArrayBuffer>\n )\n return Array.from(new Uint8Array(signature))\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('')\n}\n\n/**\n * Verify an HMAC-SHA256 signature using constant-time comparison.\n */\nexport function verifyHmacSHA256(secret: string, message: string, signature: string): boolean {\n if (typeof signature !== 'string') return false\n const expected = hmacSHA256Hex(secret, message)\n return timingSafeEqual(expected, signature.toLowerCase())\n}\n\n/** Constant-time string comparison */\nfunction timingSafeEqual(a: string, b: string): boolean {\n if (a.length !== b.length) return false\n let result = 0\n for (let i = 0; i < a.length; i++) {\n result |= a.charCodeAt(i) ^ b.charCodeAt(i)\n }\n return result === 0\n}\n\n// ==================== Pure-JS HMAC-SHA256 ====================\n\n/**\n * HMAC-SHA256 using only pure-JS SHA-256 (byte-oriented).\n *\n * Implements: HMAC(K, m) = H((K' XOR opad) || H((K' XOR ipad) || m))\n * where H is SHA-256, K' is the processed key, ipad=0x36, opad=0x5c\n *\n * This implementation uses Uint8Array for ALL binary data,\n * avoiding the corruption issue with raw-byte-in-JS-strings.\n */\nfunction hmacSHA256Pure(secret: string, message: string): string {\n const BLOCK_SIZE = 64\n\n // Convert secret and message to UTF-8 bytes\n let keyBytes = utf8ToBytes(secret)\n const msgBytes = utf8ToBytes(message)\n\n // If key is longer than block size, hash it first\n if (keyBytes.length > BLOCK_SIZE) {\n keyBytes = hexToBytes(sha256RawBytesHex(keyBytes))\n }\n\n // Pad key to block size (or truncate — should not happen for SHA-256)\n const paddedKey = new Uint8Array(BLOCK_SIZE)\n paddedKey.set(keyBytes.subarray(0, Math.min(keyBytes.length, BLOCK_SIZE)))\n // rest is already zero-initialized\n\n // Compute inner: H((key XOR ipad) || message)\n const ipad = new Uint8Array(BLOCK_SIZE)\n ipad.fill(0x36)\n const innerKey = xorBytes(paddedKey, ipad)\n const innerData = new Uint8Array(BLOCK_SIZE + msgBytes.length)\n innerData.set(innerKey)\n innerData.set(msgBytes, BLOCK_SIZE)\n const innerHash = hexToBytes(sha256RawBytesHex(innerData))\n\n // Compute outer: H((key XOR opad) || innerHash)\n const opad = new Uint8Array(BLOCK_SIZE)\n opad.fill(0x5c)\n const outerKey = xorBytes(paddedKey, opad)\n const outerData = new Uint8Array(BLOCK_SIZE + innerHash.length)\n outerData.set(outerKey)\n outerData.set(innerHash, BLOCK_SIZE)\n\n return sha256RawBytesHex(outerData)\n}\n\n/** XOR two Uint8Arrays (must be same length) */\nfunction xorBytes(a: Uint8Array, b: Uint8Array): Uint8Array {\n const result = new Uint8Array(a.length)\n for (let i = 0; i < a.length; i++) {\n result[i] = a[i]! ^ b[i]!\n }\n return result as Uint8Array<ArrayBuffer>\n}\n\n/** UTF-8 encode a string to Uint8Array */\nfunction utf8ToBytes(str: string): Uint8Array {\n if (typeof TextEncoder !== 'undefined') {\n return new TextEncoder().encode(str) as Uint8Array<ArrayBuffer>\n }\n // Fallback for ancient browsers\n const bytes: number[] = []\n for (let i = 0; i < str.length; i++) {\n let c = str.charCodeAt(i)\n if (c < 0x80) {\n bytes.push(c)\n } else if (c < 0x800) {\n bytes.push(0xc0 | (c >> 6), 0x80 | (c & 0x3f))\n } else if (c < 0xd800 || c >= 0xe000) {\n bytes.push(0xe0 | (c >> 12), 0x80 | ((c >> 6) & 0x3f), 0x80 | (c & 0x3f))\n } else {\n i++\n const c2 = str.charCodeAt(i)\n const cp = 0x10000 + ((c & 0x3ff) << 10) + (c2 & 0x3ff)\n bytes.push(\n 0xf0 | (cp >> 18),\n 0x80 | ((cp >> 12) & 0x3f),\n 0x80 | ((cp >> 6) & 0x3f),\n 0x80 | (cp & 0x3f)\n )\n }\n }\n return new Uint8Array(bytes) as Uint8Array<ArrayBuffer>\n}\n\n/** Convert hex string to Uint8Array */\nfunction hexToBytes(hex: string): Uint8Array {\n const bytes = new Uint8Array(hex.length / 2)\n for (let i = 0; i < hex.length; i += 2) {\n bytes[i / 2] = parseInt(hex.substring(i, i + 2), 16)\n }\n return bytes as Uint8Array<ArrayBuffer>\n}\n","/**\n * Pure JavaScript AES-256-GCM implementation.\n *\n * This is a fallback for environments that do not have the Web Crypto API\n * (e.g., WeChat Mini Program, Alipay Mini Program, Quick App).\n *\n * Implements:\n * - AES-256 block cipher (14 rounds, 256-bit key)\n * - GCM mode: CTR encryption + GHASH authentication\n *\n * References:\n * - FIPS 197: Advanced Encryption Standard (AES)\n * - NIST SP 800-38D: Galois/Counter Mode (GCM)\n *\n * IMPORTANT: This implementation is NOT constant-time and should only be\n * used as a fallback. In Web browsers and Node.js, the native Web Crypto API\n * implementation in aes.ts is preferred.\n */\n\n// ==================== AES S-Box and Inverse S-Box ====================\n\nconst SBOX: number[] = [\n 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,\n 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,\n 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,\n 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,\n 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,\n 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,\n 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,\n 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,\n 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,\n 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,\n 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,\n 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,\n 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,\n 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,\n 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,\n 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16,\n]\n\n// Round constants\nconst RCON: number[] = [0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36]\n\n// ==================== AES Key Expansion (256-bit key) ====================\n\n/**\n * Expand a 256-bit (32-byte) key into 15 round keys (60 words of 4 bytes each).\n * AES-256 uses 14 rounds, needing 15 round keys (including the initial key).\n */\nfunction keyExpansion256(key: Uint8Array): Uint8Array[] {\n if (key.length !== 32) {\n throw new Error('AES-256 requires a 32-byte key')\n }\n\n const Nk = 8 // 256-bit key = 8 words\n const Nr = 14 // 14 rounds for AES-256\n const Nb = 4 // 4 words per block\n\n // Total words = Nb * (Nr + 1) = 4 * 15 = 60\n const totalWords = Nb * (Nr + 1)\n const words: number[] = new Array(totalWords)\n\n // Copy key into first Nk words\n for (let i = 0; i < Nk; i++) {\n words[i] =\n (key[4 * i]! << 24) | (key[4 * i + 1]! << 16) | (key[4 * i + 2]! << 8) | key[4 * i + 3]!\n }\n\n // Expand\n for (let i = Nk; i < totalWords; i++) {\n let temp = words[i - 1]!\n\n if (i % Nk === 0) {\n // RotWord + SubWord + Rcon\n temp = subWord(rotWord(temp)) ^ (RCON[Math.floor(i / Nk) - 1]! << 24)\n } else if (Nk > 6 && i % Nk === 4) {\n // Extra SubWord for AES-256 every 4th iteration after the first Nk\n temp = subWord(temp)\n }\n\n words[i] = words[i - Nk]! ^ temp\n }\n\n // Convert to round keys (Uint8Array per round)\n const roundKeys: Uint8Array[] = []\n for (let r = 0; r <= Nr; r++) {\n const rk = new Uint8Array(16)\n for (let j = 0; j < 4; j++) {\n const w = words[r * 4 + j]!\n rk[4 * j] = (w >>> 24) & 0xff\n rk[4 * j + 1] = (w >>> 16) & 0xff\n rk[4 * j + 2] = (w >>> 8) & 0xff\n rk[4 * j + 3] = w & 0xff\n }\n roundKeys.push(rk)\n }\n\n return roundKeys\n}\n\nfunction rotWord(w: number): number {\n return ((w << 8) | (w >>> 24)) >>> 0\n}\n\nfunction subWord(w: number): number {\n return (\n ((SBOX[(w >>> 24) & 0xff]! << 24) |\n (SBOX[(w >>> 16) & 0xff]! << 16) |\n (SBOX[(w >>> 8) & 0xff]! << 8) |\n (SBOX[w & 0xff]! << 0)) >>>\n 0\n )\n}\n\n// ==================== AES Block Encrypt ====================\n\n/**\n * Encrypt a single 16-byte block using AES-256.\n */\nfunction aesEncryptBlock(block: Uint8Array, roundKeys: Uint8Array[]): Uint8Array {\n if (block.length !== 16) {\n throw new Error('AES block must be exactly 16 bytes')\n }\n\n const state: number[][] = [[], [], [], []]\n\n // Load block into state (column-major order)\n for (let i = 0; i < 4; i++) {\n for (let j = 0; j < 4; j++) {\n state[j]![i] = block[i * 4 + j]!\n }\n }\n\n const Nr = 14 // AES-256\n\n // Initial AddRoundKey\n addRoundKey(state, roundKeys[0]!)\n\n // Rounds 1 through Nr-1 (13 rounds)\n for (let round = 1; round < Nr; round++) {\n subBytes(state)\n shiftRows(state)\n mixColumns(state)\n addRoundKey(state, roundKeys[round]!)\n }\n\n // Final round (no MixColumns)\n subBytes(state)\n shiftRows(state)\n addRoundKey(state, roundKeys[Nr]!)\n\n // Extract state into output block\n const out = new Uint8Array(16)\n for (let i = 0; i < 4; i++) {\n for (let j = 0; j < 4; j++) {\n out[i * 4 + j] = state[j]![i]!\n }\n }\n\n return out\n}\n\nfunction subBytes(state: number[][]): void {\n for (let i = 0; i < 4; i++) {\n for (let j = 0; j < 4; j++) {\n state[i]![j] = SBOX[state[i]![j]!]!\n }\n }\n}\n\nfunction shiftRows(state: number[][]): void {\n for (let i = 1; i < 4; i++) {\n const row = state[i]!\n state[i] = [row[i % 4]!, row[(i + 1) % 4]!, row[(i + 2) % 4]!, row[(i + 3) % 4]!]\n }\n}\n\nfunction mixColumns(state: number[][]): void {\n for (let i = 0; i < 4; i++) {\n const a: number[] = []\n for (let j = 0; j < 4; j++) {\n a[j] = state[j]![i]!\n }\n\n state[0]![i] = gmul(2, a[0]!) ^ gmul(3, a[1]!) ^ a[2]! ^ a[3]!\n state[1]![i] = a[0]! ^ gmul(2, a[1]!) ^ gmul(3, a[2]!) ^ a[3]!\n state[2]![i] = a[0]! ^ a[1]! ^ gmul(2, a[2]!) ^ gmul(3, a[3]!)\n state[3]![i] = gmul(3, a[0]!) ^ a[1]! ^ a[2]! ^ gmul(2, a[3]!)\n }\n}\n\nfunction addRoundKey(state: number[][], roundKey: Uint8Array): void {\n for (let i = 0; i < 4; i++) {\n for (let j = 0; j < 4; j++) {\n state[j]![i] = state[j]![i]! ^ roundKey[i * 4 + j]!\n }\n }\n}\n\n/** Galois field multiplication in GF(2^8) */\nfunction gmul(a: number, b: number): number {\n let p = 0\n let aa = a\n let bb = b\n for (let i = 0; i < 8; i++) {\n if (bb & 1) p ^= aa\n const hiBit = aa & 0x80\n aa = (aa << 1) & 0xff\n if (hiBit) aa ^= 0x1b\n bb >>= 1\n }\n return p\n}\n\n// ==================== AES-CTR Mode ====================\n\n/**\n * AES-256-CTR encryption/decryption (they are the same operation in CTR mode).\n */\nfunction aesCtr(key: Uint8Array, counter: Uint8Array, data: Uint8Array): Uint8Array {\n const roundKeys = keyExpansion256(key)\n const blockCount = Math.ceil(data.length / 16)\n const output = new Uint8Array(data.length)\n\n const ctr = new Uint8Array(counter) // Copy counter so we can increment it\n\n for (let i = 0; i < blockCount; i++) {\n // Encrypt the counter block\n const keystream = aesEncryptBlock(ctr, roundKeys)\n\n // XOR with plaintext/ciphertext\n const blockLen = Math.min(16, data.length - i * 16)\n for (let j = 0; j < blockLen; j++) {\n output[i * 16 + j] = data[i * 16 + j]! ^ keystream[j]!\n }\n\n // Increment counter (big-endian, 32-bit last 4 bytes)\n incrementCounter(ctr)\n }\n\n return output\n}\n\nfunction incrementCounter(ctr: Uint8Array): void {\n // Increment the last 4 bytes as a 32-bit big-endian integer\n for (let i = 15; i >= 12; i--) {\n const val = ctr[i]! + 1\n ctr[i] = val & 0xff\n if (val <= 0xff) break\n }\n}\n\n// ==================== 64-bit Big-Endian Helpers ====================\n\n/**\n * Write a 64-bit unsigned integer in big-endian format.\n * Uses Number (not BigInt) for compatibility with ES2017 and older targets.\n * The value must be within Number.MAX_SAFE_INTEGER (2^53 - 1).\n */\nfunction writeUint64BE(buf: Uint8Array, offset: number, value: number): void {\n // High 32 bits\n const hi = Math.floor(value / 0x100000000)\n // Low 32 bits\n const lo = value % 0x100000000\n buf[offset] = (hi >>> 24) & 0xff\n buf[offset + 1] = (hi >>> 16) & 0xff\n buf[offset + 2] = (hi >>> 8) & 0xff\n buf[offset + 3] = hi & 0xff\n buf[offset + 4] = (lo >>> 24) & 0xff\n buf[offset + 5] = (lo >>> 16) & 0xff\n buf[offset + 6] = (lo >>> 8) & 0xff\n buf[offset + 7] = lo & 0xff\n}\n\n// ==================== GHASH (GCM Authentication) ====================\n\n/**\n * GHASH: Galois field multiplication-based hash used in GCM.\n *\n * Computes the authentication tag over the AAD (additional authenticated data)\n * and ciphertext using the hash subkey H.\n */\nfunction ghash(h: Uint8Array, aad: Uint8Array, ciphertext: Uint8Array): Uint8Array {\n const blockSize = 16\n\n // Number of blocks needed\n const aadBlocks = Math.ceil(aad.length / blockSize)\n const ctBlocks = Math.ceil(ciphertext.length / blockSize)\n const totalBlocks = aadBlocks + ctBlocks + 1 // +1 for the length block\n\n // Initialize Y to zero\n const y = new Uint8Array(blockSize)\n\n // Process AAD\n for (let i = 0; i < aadBlocks; i++) {\n const block = new Uint8Array(blockSize)\n const offset = i * blockSize\n const len = Math.min(blockSize, aad.length - offset)\n for (let j = 0; j < len; j++) {\n block[j] = aad[offset + j]!\n }\n // XOR with Y, then multiply by H\n for (let j = 0; j < blockSize; j++) {\n block[j] ^= y[j]!\n }\n const mulResult = gfMul(block, h)\n y.set(mulResult)\n }\n\n // Process ciphertext\n for (let i = 0; i < ctBlocks; i++) {\n const block = new Uint8Array(blockSize)\n const offset = i * blockSize\n const len = Math.min(blockSize, ciphertext.length - offset)\n for (let j = 0; j < len; j++) {\n block[j] = ciphertext[offset + j]!\n }\n // XOR with Y, then multiply by H\n for (let j = 0; j < blockSize; j++) {\n block[j] ^= y[j]!\n }\n const mulResult = gfMul(block, h)\n y.set(mulResult)\n }\n\n // Process length block: [len(AAD) in bits (64-bit BE)] || [len(C) in bits (64-bit BE)]\n // Using Number instead of BigInt for compatibility with older ES targets.\n // GCM max data size is ~64GB (2^36 bits), well within Number.MAX_SAFE_INTEGER (2^53).\n const lenBlock = new Uint8Array(blockSize)\n const aadBitLen = aad.length * 8\n const ctBitLen = ciphertext.length * 8\n writeUint64BE(lenBlock, 0, aadBitLen)\n writeUint64BE(lenBlock, 8, ctBitLen)\n for (let j = 0; j < blockSize; j++) {\n lenBlock[j] ^= y[j]!\n }\n const tag = gfMul(lenBlock, h)\n\n return tag\n}\n\n/**\n * Galois field multiplication in GF(2^128).\n *\n * Used by GHASH to compute the authentication tag.\n * Operates on 16-byte blocks interpreted as elements of GF(2^128).\n */\nfunction gfMul(x: Uint8Array, y: Uint8Array): Uint8Array {\n const result = new Uint8Array(16)\n const v = new Uint8Array(y) // Copy y so we can shift it\n\n // R = 0xE1 << 120 (reduction polynomial for GCM)\n // Process each bit of x from LSB to MSB\n for (let byteIdx = 0; byteIdx < 16; byteIdx++) {\n for (let bit = 0; bit < 8; bit++) {\n if ((x[15 - byteIdx]! >> (7 - bit)) & 1) {\n // result ^= v\n for (let k = 0; k < 16; k++) {\n result[k] ^= v[k]!\n }\n }\n\n // v >>= 1 (shift right, LSB first in GCM convention)\n const lsb = v[15]! & 1\n for (let k = 15; k > 0; k--) {\n v[k] = (v[k]! >> 1) | ((v[k - 1]! & 1) << 7)\n }\n v[0] = v[0]! >> 1\n\n if (lsb) {\n v[0] ^= 0xe1 // Reduction polynomial applied at the MSB\n }\n }\n }\n\n return result\n}\n\n// ==================== GCM Encrypt / Decrypt ====================\n\n/**\n * AES-256-GCM encryption.\n *\n * @param plaintext - Data to encrypt (Uint8Array)\n * @param key - 32-byte AES-256 key\n * @param nonce - 12-byte nonce/IV\n * @param aad - Additional authenticated data (Uint8Array, can be empty)\n * @returns { ciphertext, tag } where tag is 16 bytes\n */\nexport function aesGcmEncryptPure(\n plaintext: Uint8Array,\n key: Uint8Array,\n nonce: Uint8Array,\n aad: Uint8Array = new Uint8Array(0)\n): { ciphertext: Uint8Array; tag: Uint8Array } {\n if (key.length !== 32) {\n throw new Error('key length must be 32 bytes for AES-256-GCM')\n }\n if (nonce.length !== 12) {\n throw new Error('nonce length must be 12 bytes for AES-256-GCM')\n }\n\n // Build initial counter block: nonce (12 bytes) || counter (4 bytes, starting at 1)\n // Using 32-bit counter (last 4 bytes of 16-byte block)\n const j0 = new Uint8Array(16)\n j0.set(nonce)\n j0[15] = 1 // Counter starts at 1 (J0 is used for GHASH, counter from 1 for encryption)\n\n // Encrypt plaintext with AES-CTR starting at J0\n // Actually, GCM uses the initial counter block for the tag, and J0+1 for encryption\n // Let me re-read the spec...\n\n // GCM uses:\n // - J0 (nonce || counter=1) for the final GHASH XOR\n // - Counter blocks starting from inc32(J0) for encryption\n // Wait, actually the standard says:\n // If len(IV) == 96 bits (12 bytes): J0 = IV || 0^31 || 1\n // Then encryption uses inc32(J0), inc32(inc32(J0)), etc.\n // And the tag is GHASH(...) XOR GCTR(J0, ...)\n\n // Actually, let me follow the NIST spec more carefully:\n // J0 = IV || 0^31 || 1 (for 96-bit IV)\n // Let inc32(X) increment the last 32 bits of X\n // The ciphertext is GCTR(inc32(J0), P)\n // The tag is GHASH(H, A, C) XOR GCTR(J0, GHASH(H, A, C))\n\n const roundKeys = keyExpansion256(key)\n\n // Compute H = AES(K, 0^128)\n const zeroBlock = new Uint8Array(16)\n const h = aesEncryptBlock(zeroBlock, roundKeys)\n\n // Build J0\n const j0Block = new Uint8Array(16)\n j0Block.set(nonce)\n j0Block[15] = 1 // Counter = 1 for J0\n\n // Build first encryption counter = inc32(J0)\n const ctrBlock = new Uint8Array(j0Block)\n incrementCounter(ctrBlock)\n\n // Encrypt plaintext with AES-CTR\n const ciphertext = aesCtr(key, ctrBlock, plaintext)\n\n // Compute GHASH over AAD and ciphertext\n const s = ghash(h, aad, ciphertext)\n\n // Compute tag = S XOR GCTR(J0, S)\n const encryptedS = aesCtr(key, j0Block, s) // Using J0 as the initial counter\n const tag = new Uint8Array(16)\n for (let i = 0; i < 16; i++) {\n tag[i] = s[i]! ^ encryptedS[i]!\n }\n\n return { ciphertext, tag }\n}\n\n/**\n * AES-256-GCM decryption.\n *\n * @param ciphertext - Data to decrypt (Uint8Array)\n * @param tag - 16-byte authentication tag\n * @param key - 32-byte AES-256 key\n * @param nonce - 12-byte nonce/IV\n * @param aad - Additional authenticated data (Uint8Array, can be empty)\n * @returns Decrypted plaintext (Uint8Array)\n * @throws {Error} If authentication fails (tag mismatch)\n */\nexport function aesGcmDecryptPure(\n ciphertext: Uint8Array,\n tag: Uint8Array,\n key: Uint8Array,\n nonce: Uint8Array,\n aad: Uint8Array = new Uint8Array(0)\n): Uint8Array {\n if (key.length !== 32) {\n throw new Error('key length must be 32 bytes for AES-256-GCM')\n }\n if (nonce.length !== 12) {\n throw new Error('nonce length must be 12 bytes for AES-256-GCM')\n }\n if (tag.length !== 16) {\n throw new Error('tag length must be 16 bytes for AES-256-GCM')\n }\n\n const roundKeys = keyExpansion256(key)\n\n // Compute H = AES(K, 0^128)\n const zeroBlock = new Uint8Array(16)\n const h = aesEncryptBlock(zeroBlock, roundKeys)\n\n // Build J0\n const j0Block = new Uint8Array(16)\n j0Block.set(nonce)\n j0Block[15] = 1\n\n // Verify authentication tag FIRST\n const s = ghash(h, aad, ciphertext)\n const encryptedS = aesCtr(key, j0Block, s)\n const expectedTag = new Uint8Array(16)\n for (let i = 0; i < 16; i++) {\n expectedTag[i] = s[i]! ^ encryptedS[i]!\n }\n\n // Constant-time tag comparison\n let mismatch = 0\n for (let i = 0; i < 16; i++) {\n mismatch |= tag[i]! ^ expectedTag[i]!\n }\n if (mismatch !== 0) {\n throw new Error('AES-256-GCM authentication failed: tag mismatch')\n }\n\n // Build encryption counter = inc32(J0)\n const ctrBlock = new Uint8Array(j0Block)\n incrementCounter(ctrBlock)\n\n // Decrypt (CTR mode: decryption is same as encryption)\n return aesCtr(key, ctrBlock, ciphertext)\n}\n","/**\n * AES-256-GCM encryption and decryption.\n *\n * Compatible with the t1yOS Go server's AES-256-GCM implementation.\n * Payload format: { \"n\": \"<nonce base64>\", \"j\": \"<ciphertext base64>\", \"t\": \"<tag base64>\" }\n *\n * Uses Web Crypto API when available (Web browsers, Node.js), with automatic\n * fallback to pure-JS implementation for environments without Web Crypto\n * (WeChat/QQ/Alipay Mini Programs, Quick App, etc.).\n */\n\nimport { aesGcmEncryptPure, aesGcmDecryptPure } from './aes-pure'\n\n// Detect Web Crypto API (browser globalThis.crypto.subtle or Node require('node:crypto').webcrypto)\nfunction getWebCrypto(): {\n subtle: SubtleCrypto\n getRandomValues: (arr: Uint8Array) => Uint8Array\n} | null {\n try {\n if (typeof globalThis !== 'undefined') {\n // Browser\n if (typeof globalThis.crypto !== 'undefined' && globalThis.crypto.subtle) {\n return globalThis.crypto as ReturnType<typeof getWebCrypto>\n }\n // Node.js — try node:crypto.webcrypto\n try {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const nodeReq = typeof require !== 'undefined' ? require : null\n if (nodeReq) {\n const nodeCryptoModule = nodeReq('node:crypto') as {\n webcrypto: { subtle: SubtleCrypto; getRandomValues: (arr: Uint8Array) => Uint8Array }\n }\n if (nodeCryptoModule?.webcrypto) {\n return nodeCryptoModule.webcrypto\n }\n }\n } catch {\n // fall through\n }\n }\n } catch {\n // globalThis not available\n }\n return null\n}\n\n/**\n * Check whether AES-256-GCM encryption/decryption is available in the current environment.\n *\n * Web Crypto API is available in modern browsers and Node.js.\n * In mini programs (WeChat/QQ/Alipay) and Quick App, the pure-JS fallback is used.\n *\n * @returns `true` if AES-256-GCM is available (always true since we have pure-JS fallback)\n */\nexport function isAESGCMAvailable(): boolean {\n // With pure-JS fallback, AES-GCM is always available\n return true\n}\n\n/**\n * Check whether the native Web Crypto API is available (faster than pure-JS fallback).\n */\nexport function isWebCryptoAvailable(): boolean {\n return getWebCrypto() !== null\n}\n\n// ==================== GCM constants ====================\n\n/** GCM authentication tag length in bytes */\nconst AES_GCM_TAG_LENGTH = 16\n\n/** AES-GCM nonce/IV length in bytes */\nconst AES_GCM_NONCE_LENGTH = 12\n\n// ==================== Base64 helpers ====================\n\n/** Get random bytes using the best available source */\nfunction getRandomBytes(length: number): Uint8Array {\n const wc = getWebCrypto()\n if (wc) {\n const bytes = new Uint8Array(length)\n wc.getRandomValues(bytes)\n return bytes\n }\n\n // Fallback: Math.random-based (NOT cryptographically secure, but works everywhere)\n // For mini programs, they may have their own random API (e.g., wx.getRandomValues)\n try {\n if (\n typeof wx !== 'undefined' &&\n typeof (wx as Record<string, unknown>).getRandomValues === 'function'\n ) {\n const bytes = new Uint8Array(length)\n ;(wx as unknown as { getRandomValues: (arr: Uint8Array) => Uint8Array }).getRandomValues(\n bytes\n )\n return bytes\n }\n } catch {\n // fall through\n }\n\n // Last resort: Math.random (NOT cryptographically secure)\n const bytes = new Uint8Array(length)\n for (let i = 0; i < length; i++) {\n bytes[i] = Math.floor(Math.random() * 256)\n }\n return bytes\n}\n\nfunction encodeBase64(uint8array: Uint8Array): string {\n let binary = ''\n const len = uint8array.byteLength\n for (let i = 0; i < len; i++) {\n binary += String.fromCharCode(uint8array[i]!)\n }\n return btoa(binary)\n}\n\nfunction decodeBase64(b64: string): Uint8Array {\n const binary = atob(b64)\n const len = binary.length\n const bytes = new Uint8Array(len)\n for (let i = 0; i < len; i++) {\n bytes[i] = binary.charCodeAt(i)\n }\n return bytes\n}\n\n// ==================== Public API types ====================\n\n/**\n * AES-256-GCM encrypted payload structure.\n * Matches the Go server's AESGCMEncryptedPayload struct.\n */\nexport interface AESGCMPayload {\n /** Base64-encoded nonce */\n n: string\n /** Base64-encoded ciphertext */\n j: string\n /** Base64-encoded authentication tag */\n t: string\n}\n\n// ==================== Web Crypto implementation ====================\n\nasync function encryptAESGCMWebCrypto(data: string, keyBytes: Uint8Array): Promise<string> {\n const cryptoApi = getWebCrypto()!\n if (!cryptoApi) {\n throw new Error('Web Crypto API is not available')\n }\n\n const key = await cryptoApi.subtle.importKey(\n 'raw',\n keyBytes as Uint8Array<ArrayBuffer>,\n 'AES-GCM',\n false,\n ['encrypt']\n )\n\n const nonce = new Uint8Array(AES_GCM_NONCE_LENGTH)\n cryptoApi.getRandomValues(nonce)\n\n const encodedData = new TextEncoder().encode(data) as Uint8Array<ArrayBuffer>\n\n const encrypted = new Uint8Array(\n await cryptoApi.subtle.encrypt(\n { name: 'AES-GCM', iv: nonce as Uint8Array<ArrayBuffer>, tagLength: 128 },\n key,\n encodedData\n )\n )\n\n const ciphertext = encrypted.slice(0, encrypted.length - AES_GCM_TAG_LENGTH)\n const tag = encrypted.slice(encrypted.length - AES_GCM_TAG_LENGTH)\n\n const payload: AESGCMPayload = {\n n: encodeBase64(nonce),\n j: encodeBase64(ciphertext),\n t: encodeBase64(tag),\n }\n\n return JSON.stringify(payload)\n}\n\nasync function decryptAESGCMWebCrypto(jsonPayload: string, keyBytes: Uint8Array): Promise<string> {\n const cryptoApi = getWebCrypto()!\n if (!cryptoApi) {\n throw new Error('Web Crypto API is not available')\n }\n\n const { n, j, t } = JSON.parse(jsonPayload) as AESGCMPayload\n\n const nonce = decodeBase64(n)\n const ciphertext = decodeBase64(j)\n const tag = decodeBase64(t)\n\n const sealed = new Uint8Array(ciphertext.length + tag.length)\n sealed.set(ciphertext)\n sealed.set(tag, ciphertext.length)\n\n const key = await cryptoApi.subtle.importKey(\n 'raw',\n keyBytes as Uint8Array<ArrayBuffer>,\n 'AES-GCM',\n false,\n ['decrypt']\n )\n\n const decrypted = await cryptoApi.subtle.decrypt(\n { name: 'AES-GCM', iv: nonce as Uint8Array<ArrayBuffer>, tagLength: 128 },\n key,\n sealed as Uint8Array<ArrayBuffer>\n )\n\n return new TextDecoder().decode(decrypted)\n}\n\n// ==================== Pure-JS fallback implementation ====================\n\nfunction encryptAESGCMPure(data: string, keyBytes: Uint8Array): string {\n const nonce = getRandomBytes(AES_GCM_NONCE_LENGTH)\n const plaintext = new TextEncoder().encode(data)\n\n const { ciphertext, tag } = aesGcmEncryptPure(plaintext, keyBytes, nonce)\n\n const payload: AESGCMPayload = {\n n: encodeBase64(nonce),\n j: encodeBase64(ciphertext),\n t: encodeBase64(tag),\n }\n\n return JSON.stringify(payload)\n}\n\nfunction decryptAESGCMPure(jsonPayload: string, keyBytes: Uint8Array): string {\n const { n, j, t } = JSON.parse(jsonPayload) as AESGCMPayload\n\n const nonce = decodeBase64(n)\n const ciphertext = decodeBase64(j)\n const tag = decodeBase64(t)\n\n const decrypted = aesGcmDecryptPure(ciphertext, tag, keyBytes, nonce)\n\n return new TextDecoder().decode(decrypted)\n}\n\n// ==================== Unified public API ====================\n\n/**\n * Encrypt data using AES-256-GCM.\n *\n * Uses Web Crypto API when available (faster), falls back to pure-JS\n * implementation in environments without Web Crypto (mini programs, Quick App).\n *\n * @param data - The plaintext data to encrypt (string)\n * @param keyBytes - 32-byte encryption key (Uint8Array)\n * @returns JSON string of { n, j, t } payload\n */\nexport async function encryptAESGCM(data: string, keyBytes: Uint8Array): Promise<string> {\n if (!(keyBytes instanceof Uint8Array)) {\n throw new Error('key must be Uint8Array')\n }\n if (keyBytes.length !== 32) {\n throw new Error('key length must be 32 bytes for AES-256-GCM')\n }\n\n if (getWebCrypto()) {\n return await encryptAESGCMWebCrypto(data, keyBytes)\n }\n\n // Pure-JS fallback (synchronous, but wrapped in async for consistent API)\n return encryptAESGCMPure(data, keyBytes)\n}\n\n/**\n * Decrypt data using AES-256-GCM.\n *\n * Uses Web Crypto API when available (faster), falls back to pure-JS\n * implementation in environments without Web Crypto (mini programs, Quick App).\n *\n * @param jsonPayload - JSON string of { n, j, t } payload\n * @param keyBytes - 32-byte decryption key (Uint8Array)\n * @returns Decrypted plaintext string\n */\nexport async function decryptAESGCM(jsonPayload: string, keyBytes: Uint8Array): Promise<string> {\n if (!(keyBytes instanceof Uint8Array)) {\n throw new Error('key must be Uint8Array')\n }\n if (keyBytes.length !== 32) {\n throw new Error('key length must be 32 bytes for AES-256-GCM')\n }\n\n if (getWebCrypto()) {\n return await decryptAESGCMWebCrypto(jsonPayload, keyBytes)\n }\n\n // Pure-JS fallback\n return decryptAESGCMPure(jsonPayload, keyBytes)\n}\n","/**\n * Request signing algorithm for T1Y v5 RESTful API authentication.\n *\n * Implements the same signing logic as the Go server's middleware/v5_auth.go:\n *\n * message = METHOD + \"\\n\" + URL_PATH_AND_QUERY + \"\\n\" + SHA256(body) + \"\\n\" + appId + \"\\n\" + timestamp\n * signature = HMAC-SHA256(secretKey, message)\n */\n\nimport { sha256Hex } from './sha256'\nimport { hmacSHA256Hex } from './hmac'\n\n/**\n * Parameters for creating a request signature.\n */\nexport interface SignatureInput {\n /** HTTP method in uppercase (GET, POST, PUT, DELETE) */\n method: string\n /** URL path including query string, e.g. /v5/classes/users?field=name */\n pathAndQuery: string\n /** Request body as a raw string (empty string for GET requests) */\n body: string\n /** Application ID */\n appId: number\n /** 10-digit Unix timestamp (UTC + offset) */\n timestamp: number\n /** 32-character Secret Key */\n secretKey: string\n}\n\n/**\n * Create an HMAC-SHA256 signature for a T1Y API request.\n *\n * The message format is (each line separated by \\n):\n * 1. HTTP method (uppercase)\n * 2. URL path + query string\n * 3. SHA-256 hex digest of the request body\n * 4. Application ID (as string)\n * 5. Unix timestamp (as string)\n *\n * @param input - Signature parameters\n * @returns 64-character hex-encoded HMAC-SHA256 signature\n *\n * @example\n * ```ts\n * const sign = createSignature({\n * method: 'POST',\n * pathAndQuery: '/v5/classes/users',\n * body: '{\"name\":\"Alice\"}',\n * appId: 1001,\n * timestamp: 1705312200,\n * secretKey: '17b784e359c946ffa65eebbf9ce29752',\n * })\n * // Set as X-T1Y-Safe-Sign header\n * ```\n */\nexport function createSignature(input: SignatureInput): string {\n const { method, pathAndQuery, body, appId, timestamp, secretKey } = input\n\n const bodyHash = sha256Hex(body)\n\n const message = [\n method.toUpperCase(),\n pathAndQuery,\n bodyHash,\n String(appId),\n String(timestamp),\n ].join('\\n')\n\n return hmacSHA256Hex(secretKey, message)\n}\n\n/**\n * Get the current UTC Unix timestamp adjusted by the given offset.\n *\n * @param offset - Time offset in seconds (from server init)\n * @returns 10-digit Unix timestamp string\n */\nexport function getSafeTimestamp(offset: number): string {\n return String(Math.floor(Date.now() / 1000) + offset)\n}\n","/**\n * Strip trailing slashes from a base URL.\n */\nexport function normalizeBaseUrl(baseUrl: string): string {\n return baseUrl.replace(/\\/+$/, '')\n}\n\n/**\n * Append query parameters from a params object to a URL.\n * Skips undefined and null values.\n * String values are added directly; others are JSON-stringified.\n */\nexport function appendQueryParams(url: URL, params: Record<string, unknown>): void {\n for (const key of Object.keys(params)) {\n const value = params[key]\n if (value === undefined || value === null) continue\n url.searchParams.set(key, typeof value === 'string' ? value : JSON.stringify(value))\n }\n}\n","import { DEFAULT_TIME_FORMAT } from '../constants'\n\n/**\n * Format a UTC date string to local time using the given format template.\n *\n * Format tokens:\n * YYYY - 4-digit year\n * MM - 2-digit month (01-12)\n * DD - 2-digit day (01-31)\n * HH - 2-digit hour (00-23)\n * mm - 2-digit minute (00-59)\n * ss - 2-digit second (00-59)\n */\nfunction formatLocalTime(utcString: string, format: string): string {\n const date = new Date(utcString)\n if (isNaN(date.getTime())) return utcString\n\n const pad = (n: number) => String(n).padStart(2, '0')\n\n return format\n .replace('YYYY', String(date.getFullYear()))\n .replace('MM', pad(date.getMonth() + 1))\n .replace('DD', pad(date.getDate()))\n .replace('HH', pad(date.getHours()))\n .replace('mm', pad(date.getMinutes()))\n .replace('ss', pad(date.getSeconds()))\n}\n\n/**\n * Recursively convert all `createdAt` and `updatedAt` fields in a data structure\n * from UTC strings to local time formatted strings.\n *\n * Returns a new object/array; does not mutate the original.\n */\nexport function formatTimestampsToLocal(\n data: unknown,\n format: string = DEFAULT_TIME_FORMAT\n): unknown {\n function traverse(value: unknown): unknown {\n if (Array.isArray(value)) {\n return value.map(traverse)\n }\n if (value && typeof value === 'object') {\n const result: Record<string, unknown> = {}\n for (const key in value as Record<string, unknown>) {\n if (!Object.prototype.hasOwnProperty.call(value, key)) continue\n\n if (key === 'createdAt' || key === 'updatedAt') {\n result[key] = formatLocalTime((value as Record<string, unknown>)[key] as string, format)\n } else {\n result[key] = traverse((value as Record<string, unknown>)[key])\n }\n }\n return result\n }\n return value\n }\n\n return traverse(data)\n}\n","/**\n * Response handling — decryption, timestamp formatting, and error wrapping.\n *\n * Works with platform-agnostic `PlatformResponse` objects instead of the\n * browser-native `Response` type, enabling cross-platform support.\n */\n\nimport { decryptAESGCM } from '../crypto/aes'\nimport { formatTimestampsToLocal } from '../utils/time'\nimport { T1YError } from '../utils/errors'\nimport type { ApiResponse } from '../types/api'\nimport type { PlatformResponse } from '../platform/types'\n\n/**\n * Process a platform response into the SDK's standard ApiResponse format.\n *\n * Handles:\n * 1. JSON parsing or string fallback\n * 2. Safe mode AES-GCM decryption (response data has `j` field)\n * 3. Timestamp formatting (createdAt/updatedAt → local time)\n * 4. Error wrapping for non-2xx status codes\n *\n * @param response - Platform-agnostic response object\n * @param isSafeMode - Whether safe mode encryption is active\n * @param secretKey - Secret key for decryption (as raw string)\n * @param timeFormat - Time format for createdAt/updatedAt fields\n * @returns Processed ApiResponse\n */\nexport async function handleResponse<T = unknown>(\n response: PlatformResponse,\n isSafeMode: boolean,\n secretKey: string,\n timeFormat: string\n): Promise<ApiResponse<T>> {\n // Determine content type from response headers\n const contentType = response.headers['content-type'] || ''\n\n // Try to parse response body\n let rawData: unknown\n const responseText = response.body\n\n if (contentType.includes('application/json')) {\n try {\n rawData = JSON.parse(responseText)\n } catch {\n rawData = responseText\n }\n } else {\n rawData = responseText\n }\n\n // If safe mode is on and the response data looks encrypted (has `j` field),\n // decrypt it first\n if (\n isSafeMode &&\n rawData &&\n typeof rawData === 'object' &&\n 'j' in (rawData as Record<string, unknown>)\n ) {\n try {\n const decrypted = await decryptAESGCM(\n JSON.stringify(rawData),\n new TextEncoder().encode(secretKey)\n )\n\n // Try to parse decrypted result as JSON\n try {\n rawData = JSON.parse(decrypted)\n } catch {\n rawData = decrypted\n }\n } catch (err) {\n throw new T1YError(\n 400,\n 'AES-256-GCM decryption failed',\n err instanceof Error ? err.message : null\n )\n }\n }\n\n const isOk = response.status >= 200 && response.status < 300\n\n // If the response is a standard ApiResponse wrapper, format timestamps\n if (rawData && typeof rawData === 'object' && 'data' in (rawData as Record<string, unknown>)) {\n const apiResp = rawData as ApiResponse<T>\n apiResp.data = formatTimestampsToLocal(apiResp.data, timeFormat) as T\n\n // If the status code is not 2xx, throw a T1YError\n if (!isOk) {\n throw new T1YError(\n apiResp.code || response.status,\n apiResp.message || response.statusText,\n apiResp.data\n )\n }\n\n return apiResp\n }\n\n // Handle non-standard responses\n if (!isOk) {\n throw new T1YError(response.status, response.statusText, rawData)\n }\n\n // Raw success response — wrap in ApiResponse shape\n return {\n code: 0,\n message: 'ok',\n data: formatTimestampsToLocal(rawData, timeFormat) as T,\n }\n}\n\n/**\n * Handle request errors (network errors, timeouts, etc.) from any platform.\n */\nexport function handleFetchError(error: unknown): never {\n // Re-throw as T1YError if it's not already\n if (error instanceof T1YError) {\n throw error\n }\n\n if (error instanceof Error) {\n // Network error / timeout\n const message = error.message || 'Unknown error'\n if (\n message.includes('timeout') ||\n message.includes('超时') ||\n error.name === 'AbortError' ||\n message.includes('abort')\n ) {\n throw new T1YError(408, 'Request timeout', null)\n }\n throw new T1YError(0, message, null)\n }\n\n throw new T1YError(0, 'Unknown error', error)\n}\n","/**\n * Platform detection module.\n *\n * Detects the current runtime environment and returns a platform type identifier.\n * This enables the SDK to use the correct network request API for each platform:\n *\n * | Platform | Type | Request API | Global Object |\n * |-----------------------|----------|--------------------|---------------|\n * | WeChat Mini Program | `wx` | `wx.request` | `wx` |\n * | QQ Mini Program | `wx` | `qq.request` | `qq` |\n * | Toutiao/Douyin Mini | `wx` | `tt.request` | `tt` |\n * | Alipay Mini Program | `my` | `my.request` | `my` |\n * | Quick App | `hap` | `@system.fetch` | — |\n * | Web / Vue / React | `h5` | `fetch` | `window` |\n * | Node.js | `nodejs` | `fetch` (18+) | `process` |\n */\n\n/** Platform type identifiers */\nexport type PlatformType = 'wx' | 'my' | 'hap' | 'h5' | 'nodejs' | 'unknown'\n\n/** Mini program sub-type within the `wx` platform family */\nexport type MiniProgramSubType = 'wechat' | 'qq' | 'toutiao' | 'unknown'\n\n/** Cached platform detection result */\nlet _platformType: PlatformType | null = null\nlet _miniProgramSubType: MiniProgramSubType | null = null\n\n/**\n * Detect the current platform type.\n *\n * Detection order (from most specific to least):\n * 1. WeChat/QQ/Toutiao/Douyin Mini Programs — global `wx`/`qq`/`tt` object\n * 2. Alipay Mini Program — global `my` object\n * 3. Quick App — no `window`, no `wx`, but has device info via special flag\n * 4. Web / H5 — global `window` and `document`\n * 5. Node.js — global `process` without `window`\n *\n * @returns The detected platform type\n */\nexport function getPlatformType(): PlatformType {\n if (_platformType !== null) {\n return _platformType\n }\n\n // Use `typeof` checks to avoid ReferenceError in strict environments\n\n // Check for Mini Programs (WeChat, QQ, Toutiao, Douyin)\n // All of these expose a global `wx`-like API object\n if (typeof wx !== 'undefined' && typeof (wx as Record<string, unknown>).request === 'function') {\n _platformType = 'wx'\n return _platformType\n }\n\n // Check for Alipay Mini Program\n if (typeof my !== 'undefined' && typeof (my as Record<string, unknown>).request === 'function') {\n _platformType = 'my'\n return _platformType\n }\n\n // Check for Quick App\n // Quick App has no `window` or `document` but also no `wx`\n // Detection: check if it's not a browser and has `global` (Quick App's global scope)\n if (\n typeof window === 'undefined' &&\n typeof document === 'undefined' &&\n typeof global !== 'undefined' &&\n typeof (global as Record<string, unknown>).require === 'function'\n ) {\n // Further distinguish: Quick App has @system packages available via require\n try {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n if (typeof require !== 'undefined' && typeof require('@system.fetch') !== 'undefined') {\n _platformType = 'hap'\n return _platformType\n }\n } catch {\n // @system.fetch not available — not Quick App\n }\n }\n\n // Check for Web / H5 (browser environment)\n if (typeof window !== 'undefined' && typeof document !== 'undefined') {\n _platformType = 'h5'\n return _platformType\n }\n\n // Check for Node.js\n if (\n typeof process !== 'undefined' &&\n typeof (process as unknown as Record<string, unknown>).versions !== 'undefined' &&\n typeof ((process as unknown as Record<string, unknown>).versions as Record<string, unknown>)\n ?.node !== 'undefined'\n ) {\n _platformType = 'nodejs'\n return _platformType\n }\n\n _platformType = 'unknown'\n return _platformType\n}\n\n/**\n * Detect the mini program sub-type (only meaningful when platform is `wx`).\n *\n * | Sub-type | Global Object | Notes |\n * |------------|---------------|----------------------------------------|\n * | `toutiao` | `tt` | Toutiao/Douyin Mini Program |\n * | `qq` | `qq` | QQ Mini Program |\n * | `wechat` | `wx` | WeChat Mini Program (default for `wx`) |\n *\n * @returns The detected mini program sub-type\n */\nexport function getMiniProgramSubType(): MiniProgramSubType {\n if (_miniProgramSubType !== null) {\n return _miniProgramSubType\n }\n\n // Only relevant for `wx` platform\n if (getPlatformType() !== 'wx') {\n _miniProgramSubType = 'unknown'\n return _miniProgramSubType\n }\n\n // Toutiao/Douyin exposes `tt` alongside `wx`\n if (typeof tt !== 'undefined' && typeof (tt as Record<string, unknown>).request === 'function') {\n _miniProgramSubType = 'toutiao'\n return _miniProgramSubType\n }\n\n // QQ Mini Program exposes `qq` alongside `wx`\n if (typeof qq !== 'undefined' && typeof (qq as Record<string, unknown>).request === 'function') {\n _miniProgramSubType = 'qq'\n return _miniProgramSubType\n }\n\n // Default to WeChat\n _miniProgramSubType = 'wechat'\n return _miniProgramSubType\n}\n\n/**\n * Get the global API object for mini programs.\n *\n * Returns the appropriate global object based on the detected platform:\n * - WeChat: `wx`\n * - QQ: `qq`\n * - Toutiao/Douyin: `tt`\n *\n * @returns The mini program global API object, or `null` if not in a mini program\n */\nexport function getMiniProgramAPI(): Record<string, unknown> | null {\n const platform = getPlatformType()\n\n if (platform === 'my') {\n return my as unknown as Record<string, unknown>\n }\n\n if (platform !== 'wx') {\n return null\n }\n\n const subType = getMiniProgramSubType()\n\n switch (subType) {\n case 'toutiao':\n return tt as unknown as Record<string, unknown>\n case 'qq':\n return qq as unknown as Record<string, unknown>\n case 'wechat':\n default:\n return wx as unknown as Record<string, unknown>\n }\n}\n\n/**\n * Reset cached platform detection (useful for testing).\n */\nexport function resetPlatformDetection(): void {\n _platformType = null\n _miniProgramSubType = null\n}\n","/**\n * Fetch-based request adapter for Web (H5) and Node.js environments.\n *\n * Uses the standard `fetch` API (native in Node.js 18+, all modern browsers).\n */\n\nimport type { PlatformRequestOptions, PlatformResponse, PlatformRequestFn } from '../types'\n\n/**\n * Execute an HTTP request using the standard `fetch` API.\n *\n * @param options - Standardized request options\n * @returns Standardized response object\n */\nexport const fetchRequest: PlatformRequestFn = async (\n options: PlatformRequestOptions\n): Promise<PlatformResponse> => {\n const { url, method, headers, body, signal } = options\n\n const fetchOptions: RequestInit = {\n method,\n headers,\n signal,\n }\n\n if (body !== undefined && method !== 'GET') {\n fetchOptions.body = body\n }\n\n const response = await fetch(url, fetchOptions)\n\n // Extract response headers into a plain object\n const responseHeaders: Record<string, string> = {}\n response.headers.forEach((value: string, key: string) => {\n responseHeaders[key.toLowerCase()] = value\n })\n\n const responseBody = await response.text()\n\n return {\n status: response.status,\n statusText: response.statusText,\n headers: responseHeaders,\n body: responseBody,\n }\n}\n","/**\n * WeChat / QQ / Toutiao / Douyin Mini Program request adapter.\n *\n * All of these platforms expose a `wx.request`-compatible API:\n * - WeChat: `wx.request`\n * - QQ: `qq.request`\n * - Toutiao: `tt.request`\n * - Douyin: `tt.request`\n *\n * The actual API object is resolved at call time via `getMiniProgramAPI()`.\n */\n\nimport { getMiniProgramAPI } from '../detect'\nimport type { PlatformRequestOptions, PlatformResponse, PlatformRequestFn } from '../types'\n\n/**\n * Execute an HTTP request using the mini program's `request` API.\n *\n * The mini program API uses callback-based `wx.request({ success, fail, complete })`.\n * This adapter wraps it in a Promise for consistent async/await usage.\n *\n * @param options - Standardized request options\n * @returns Standardized response object\n */\nexport const wxRequest: PlatformRequestFn = async (\n options: PlatformRequestOptions\n): Promise<PlatformResponse> => {\n const mpApi = getMiniProgramAPI()\n\n if (!mpApi || typeof (mpApi as Record<string, unknown>).request !== 'function') {\n throw new Error('Mini program request API is not available')\n }\n\n const requestFn = (mpApi as Record<string, unknown>).request as (\n opts: Record<string, unknown>\n ) => { abort: () => void }\n\n const { url, method, headers, body, timeout } = options\n\n return new Promise<PlatformResponse>((resolve, reject) => {\n const requestTask = requestFn({\n url,\n method: method as\n | 'GET'\n | 'POST'\n | 'PUT'\n | 'DELETE'\n | 'OPTIONS'\n | 'HEAD'\n | 'TRACE'\n | 'CONNECT',\n header: headers,\n data: body,\n timeout: timeout ?? 300000, // 5 minutes default\n dataType: 'text', // Get raw text, we parse JSON ourselves\n responseType: 'text',\n success: (res: {\n statusCode: number\n errMsg?: string\n header?: Record<string, string>\n data?: string | object\n }) => {\n // Normalize response headers\n const responseHeaders: Record<string, string> = {}\n if (res.header) {\n for (const key of Object.keys(res.header)) {\n responseHeaders[key.toLowerCase()] = res.header[key]!\n }\n }\n\n // Handle response body — it might already be parsed as JSON\n let bodyStr: string\n if (typeof res.data === 'string') {\n bodyStr = res.data\n } else if (res.data !== undefined && res.data !== null) {\n bodyStr = JSON.stringify(res.data)\n } else {\n bodyStr = ''\n }\n\n resolve({\n status: res.statusCode,\n statusText: res.errMsg ?? '',\n headers: responseHeaders,\n body: bodyStr,\n })\n },\n fail: (err: { errMsg?: string; errno?: number }) => {\n // Handle timeout specially\n const errMsg = err.errMsg ?? 'Mini program request failed'\n if (errMsg.includes('timeout') || errMsg.includes('超时')) {\n reject(new Error('Request timeout'))\n } else {\n reject(new Error(errMsg))\n }\n },\n })\n\n // Handle AbortSignal if provided\n if (options.signal) {\n const onAbort = () => {\n if (typeof requestTask.abort === 'function') {\n requestTask.abort()\n }\n }\n options.signal.addEventListener('abort', onAbort, { once: true })\n }\n })\n}\n","/**\n * Alipay Mini Program request adapter.\n *\n * Alipay Mini Program uses `my.request` which has a slightly different API\n * from WeChat's `wx.request`. Key differences:\n * - Uses `headers` instead of `header`\n * - Response `data` is always parsed JSON (not raw text)\n * - Different error object structure\n *\n * API reference: https://opendocs.alipay.com/mini/api/owycmh\n */\n\nimport type { PlatformRequestOptions, PlatformResponse, PlatformRequestFn } from '../types'\n\n/**\n * Execute an HTTP request using Alipay's `my.request` API.\n *\n * @param options - Standardized request options\n * @returns Standardized response object\n */\nexport const myRequest: PlatformRequestFn = async (\n options: PlatformRequestOptions\n): Promise<PlatformResponse> => {\n // Access the Alipay global API\n const mpApi = my as unknown as Record<string, unknown>\n\n if (!mpApi || typeof mpApi.request !== 'function') {\n throw new Error('Alipay mini program request API (my.request) is not available')\n }\n\n const requestFn = mpApi.request as (opts: Record<string, unknown>) => { abort: () => void }\n\n const { url, method, headers, body, timeout } = options\n\n return new Promise<PlatformResponse>((resolve, reject) => {\n const requestTask = requestFn({\n url,\n method: method.toUpperCase(),\n headers, // Alipay uses `headers` (not `header` like WeChat)\n data: body !== undefined ? body : undefined,\n timeout: timeout ?? 300000,\n // Request JSON but we handle parsing ourselves\n dataType: 'text',\n success: (res: {\n status?: number\n statusCode?: number\n headers?: Record<string, string>\n data?: unknown\n }) => {\n // Normalize response\n const status = res.status ?? res.statusCode ?? 200\n\n const responseHeaders: Record<string, string> = {}\n if (res.headers) {\n for (const key of Object.keys(res.headers)) {\n responseHeaders[key.toLowerCase()] = res.headers[key]!\n }\n }\n\n let bodyStr: string\n if (typeof res.data === 'string') {\n bodyStr = res.data\n } else if (res.data !== undefined && res.data !== null) {\n bodyStr = JSON.stringify(res.data)\n } else {\n bodyStr = ''\n }\n\n resolve({\n status,\n statusText: '',\n headers: responseHeaders,\n body: bodyStr,\n })\n },\n fail: (err: { error?: number | string; errorMessage?: string; errMsg?: string }) => {\n const errMsg =\n err.errorMessage ?? err.errMsg ?? `Alipay request failed (error: ${err.error})`\n reject(new Error(errMsg))\n },\n complete: () => {\n // No-op — handled in success/fail\n },\n })\n\n // Handle AbortSignal if provided\n if (options.signal) {\n const onAbort = () => {\n if (requestTask && typeof requestTask.abort === 'function') {\n requestTask.abort()\n }\n }\n options.signal.addEventListener('abort', onAbort, { once: true })\n }\n })\n}\n","/**\n * Quick App (快应用) request adapter.\n *\n * Quick App uses the `@system.fetch` module for HTTP requests.\n * Unlike mini programs, Quick App's fetch API is more similar to the standard\n * `fetch` API but requires importing the system module.\n *\n * IMPORTANT: The `@system.fetch` module is only available inside Quick App.\n * In other environments, the require call is wrapped in a try-catch and will\n * safely return null, falling back to other adapters.\n *\n * API reference: https://doc.quickapp.cn/features/system/fetch.html\n */\n\nimport type { PlatformRequestOptions, PlatformResponse, PlatformRequestFn } from '../types'\n\n/**\n * Safely access Quick App's @system.fetch module.\n *\n * Uses a dynamic require call wrapped in try-catch so that:\n * - In Quick App: returns the @system.fetch module ✓\n * - In other bundlers (webpack/esbuild): the require is preserved as-is\n * - In browsers: throws ReferenceError (require not defined) → caught → returns null\n */\nfunction getSystemFetch(): {\n fetch: (opts: {\n url: string\n method?: string\n header?: Record<string, string>\n data?: string\n responseType?: string\n success?: (res: { code: number; data: string; headers: Record<string, string> }) => void\n fail?: (err: { code: number; data: string }) => void\n complete?: () => void\n }) => void\n} | null {\n try {\n // In Quick App, @system.fetch is a built-in module accessible via require.\n // Quick App's hap-toolkit will resolve this at build time.\n // In other environments, this will throw and be caught.\n //\n // NOTE: For UMD/IIFE builds, esbuild is configured with --external:@system.fetch\n // so this require call is preserved as-is in the output.\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const sysFetch = require('@system.fetch')\n return sysFetch as ReturnType<typeof getSystemFetch>\n } catch (_e) {\n return null\n }\n}\n\n/**\n * Execute an HTTP request using Quick App's `@system.fetch` API.\n *\n * Key differences from standard fetch:\n * - Callback-based (success/fail/complete), not Promise-based\n * - Response status is in `res.code`\n * - Headers are in `res.headers`\n *\n * @param options - Standardized request options\n * @returns Standardized response object\n */\nexport const hapRequest: PlatformRequestFn = async (\n options: PlatformRequestOptions\n): Promise<PlatformResponse> => {\n const sysFetch = getSystemFetch()\n\n if (!sysFetch) {\n throw new Error(\n 'Quick App fetch module (@system.fetch) is not available. ' +\n 'Ensure you are running inside a Quick App environment.'\n )\n }\n\n const { url, method, headers, body } = options\n\n return new Promise<PlatformResponse>((resolve, reject) => {\n sysFetch.fetch({\n url,\n method: method.toUpperCase(),\n header: headers,\n data: body,\n responseType: 'text',\n success: (res: { code: number; data: string; headers: Record<string, string> }) => {\n const responseHeaders: Record<string, string> = {}\n if (res.headers) {\n for (const key of Object.keys(res.headers)) {\n responseHeaders[key.toLowerCase()] = res.headers[key]!\n }\n }\n\n resolve({\n status: res.code,\n statusText: '',\n headers: responseHeaders,\n body: typeof res.data === 'string' ? res.data : JSON.stringify(res.data),\n })\n },\n fail: (err: { code: number; data: string }) => {\n reject(new Error(`Quick App request failed (code: ${err.code}, data: ${err.data})`))\n },\n complete: () => {\n // No-op\n },\n })\n })\n}\n","/**\n * Platform request dispatcher.\n *\n * Detects the runtime platform and returns the appropriate request function\n * and platform metadata. This is the single entry point used by the HTTP\n * module to execute requests in any environment.\n */\n\nimport { getPlatformType, getMiniProgramSubType } from './detect'\nimport { fetchRequest } from './request/fetch'\nimport { wxRequest } from './request/wx'\nimport { myRequest } from './request/my'\nimport { hapRequest } from './request/hap'\nimport type { PlatformRequestFn, PlatformInfo } from './types'\n\n/** Cached platform request function */\nlet _cachedRequest: PlatformRequestFn | null = null\nlet _cachedInfo: PlatformInfo | null = null\n\n/**\n * Get the platform-appropriate request function.\n *\n * On first call, detects the platform and caches the result.\n * Subsequent calls return the cached adapter.\n *\n * @returns The request function for the current platform\n * @throws {Error} If the platform cannot be determined or no adapter is available\n */\nexport function getPlatformRequest(): PlatformRequestFn {\n if (_cachedRequest !== null) {\n return _cachedRequest\n }\n\n const platform = getPlatformType()\n\n switch (platform) {\n case 'h5':\n case 'nodejs':\n _cachedRequest = fetchRequest\n break\n case 'wx':\n _cachedRequest = wxRequest\n break\n case 'my':\n _cachedRequest = myRequest\n break\n case 'hap':\n _cachedRequest = hapRequest\n break\n default:\n // Fallback: try fetch first (works in modern environments)\n if (typeof fetch === 'function') {\n _cachedRequest = fetchRequest\n } else {\n throw new Error(\n 'Unable to determine platform request adapter. ' +\n 'The current environment does not have `fetch`, `wx.request`, `my.request`, ' +\n 'or `@system.fetch` available. Please ensure you are running in a supported environment: ' +\n 'Web browser, Node.js 18+, WeChat/QQ/Alipay/Toutiao/Douyin Mini Program, or Quick App.'\n )\n }\n break\n }\n\n return _cachedRequest!\n}\n\n/**\n * Get platform metadata including the SDK type string for request headers.\n *\n * The `sdkType` value is sent in the `X-T1Y-SDK-Type` header to help the\n * server identify which platform the request is coming from.\n *\n * @returns Platform metadata\n */\nexport function getPlatformInfo(): PlatformInfo {\n if (_cachedInfo !== null) {\n return _cachedInfo\n }\n\n const platform = getPlatformType()\n let sdkType = 'javascript'\n\n switch (platform) {\n case 'wx': {\n const subType = getMiniProgramSubType()\n switch (subType) {\n case 'toutiao':\n sdkType = 'toutiao'\n break\n case 'qq':\n sdkType = 'qqApp'\n break\n case 'wechat':\n default:\n sdkType = 'wechatApp'\n break\n }\n break\n }\n case 'my':\n sdkType = 'alipay'\n break\n case 'hap':\n sdkType = 'quickApp'\n break\n case 'h5':\n sdkType = 'web'\n break\n case 'nodejs':\n sdkType = 'nodejs'\n break\n default:\n sdkType = 'javascript'\n break\n }\n\n _cachedInfo = {\n type: platform,\n sdkType,\n request: getPlatformRequest(),\n }\n\n return _cachedInfo\n}\n\n/**\n * Reset cached dispatcher state (useful for testing).\n */\nexport function resetDispatcher(): void {\n _cachedRequest = null\n _cachedInfo = null\n}\n","/**\n * Core HTTP request execution for the t1yOS SDK.\n *\n * Handles:\n * - URL construction (baseUrl + path + query params for GET)\n * - Date type conversion in params\n * - AES-256-GCM encryption (safe mode)\n * - Request signing (HMAC-SHA256)\n * - Auth header injection\n * - Platform-agnostic request execution (via platform adapters)\n * - Response processing (decryption, timestamp formatting)\n */\n\nimport { encryptAESGCM } from '../crypto/aes'\nimport { createSignature, getSafeTimestamp } from '../crypto/sign'\nimport { convertDateTypes } from '../utils/convert'\nimport { appendQueryParams, normalizeBaseUrl } from '../utils/url'\nimport { REQUEST_TIMEOUT_MS } from '../constants'\nimport { handleResponse, handleFetchError } from './response'\nimport { getPlatformRequest } from '../platform/dispatcher'\nimport type { T1YOSInternalConfig, HttpMethod, ApiResponse } from '../types'\n\n/**\n * Options for a single HTTP request.\n */\nexport interface RequestOptions {\n /** HTTP method */\n method: HttpMethod\n /** API path (e.g., /v5/classes/users) */\n path: string\n /** Request parameters/body */\n params?: unknown\n /** Override encryption for this request (defaults to client.isSafeMode) */\n encryption?: boolean\n /** Request timeout in milliseconds (default: 5 minutes) */\n timeout?: number\n}\n\n/**\n * Execute an HTTP request to the t1yOS API with full auth and encryption handling.\n *\n * This function is platform-agnostic. It builds the request (URL, headers, body,\n * encryption, signing) and then delegates the actual HTTP call to a platform-specific\n * adapter that works in Web, Node.js, WeChat/QQ/Alipay/Toutiao/Douyin Mini Programs,\n * and Quick App.\n *\n * @param client - Internal client configuration\n * @param options - Request options\n * @returns The processed API response\n */\nexport async function executeRequest<T = unknown>(\n client: T1YOSInternalConfig,\n options: RequestOptions\n): Promise<ApiResponse<T>> {\n const { method, path, params, encryption, timeout } = options\n\n // Normalize base URL\n const baseUrl = normalizeBaseUrl(client.baseUrl)\n const isSafeMode = encryption ?? client.isSafeMode\n\n // Build URL\n const fullUrl = new URL(baseUrl + path)\n\n // Convert Date types in params\n const convertedParams = convertDateTypes(params)\n\n // Handle request body\n let bodyForRequest: string | undefined\n let rawBodyString = ''\n\n if (method !== 'GET') {\n // For non-GET requests, the body is the params\n if (isSafeMode && convertedParams !== undefined) {\n // Safe mode: encrypt the JSON body\n const encryptedBody = await encryptAESGCM(\n JSON.stringify(convertedParams),\n new TextEncoder().encode(client.secretKey)\n )\n bodyForRequest = encryptedBody\n rawBodyString = encryptedBody\n } else if (convertedParams !== undefined) {\n const jsonBody = JSON.stringify(convertedParams)\n bodyForRequest = jsonBody\n rawBodyString = jsonBody\n } else {\n rawBodyString = ''\n }\n } else if (\n convertedParams &&\n typeof convertedParams === 'object' &&\n Object.keys(convertedParams as object).length > 0\n ) {\n // For GET requests, append params as query string\n appendQueryParams(fullUrl, convertedParams as Record<string, unknown>)\n }\n\n // Compute timestamp with offset\n const timestamp = Number(getSafeTimestamp(client.offset))\n\n // Get the path + query for signing\n const originalURL = fullUrl.pathname + fullUrl.search\n\n // Create the HMAC-SHA256 signature\n const sign = createSignature({\n method,\n pathAndQuery: originalURL,\n body: rawBodyString,\n appId: client.appId,\n timestamp,\n secretKey: client.secretKey,\n })\n\n // Use the platform-specific request adapter\n const platformRequest = getPlatformRequest()\n const timeoutMs = timeout ?? REQUEST_TIMEOUT_MS\n\n try {\n const response = await platformRequest({\n url: fullUrl.toString(),\n method,\n headers: {\n 'X-T1Y-Application-ID': String(client.appId),\n 'X-T1Y-API-Key': client.apiKey,\n 'X-T1Y-Safe-Timestamp': String(timestamp),\n 'X-T1Y-Safe-Sign': sign,\n 'Content-Type': 'application/json',\n },\n body: method !== 'GET' ? bodyForRequest : undefined,\n timeout: timeoutMs,\n })\n\n return await handleResponse<T>(response, isSafeMode, client.secretKey, client.timeFormat)\n } catch (error) {\n return handleFetchError(error)\n }\n}\n","/**\n * T1Collection — Database collection class providing chainable CRUD and schema operations.\n *\n * Created via `client.db.collection('name')` — never instantiated directly.\n */\n\nimport { assertObjectID } from '../utils/validators'\nimport {\n isNonEmptyObject,\n isPlainObject,\n isNonEmptyArrayWithNonEmptyObjects,\n} from '../utils/convert'\nimport { MAX_PAGE_SIZE } from '../constants'\nimport type { T1YOS } from './T1YOS'\nimport type {\n ApiResponse,\n InsertResult,\n InsertManyResult,\n DeleteResult,\n DeleteManyResult,\n UpdateResult,\n UpdateManyResult,\n FindResult,\n PaginationResult,\n AggregateResult,\n} from '../types'\n\nexport class T1Collection {\n /** The parent T1YOS client */\n private client: T1YOS\n /** The collection (table) name */\n private name: string\n\n /**\n * @internal — Use `client.db.collection(name)` instead.\n */\n constructor(client: T1YOS, name: string) {\n this.client = client\n this.name = name\n }\n\n // ==================== Single Document Operations ====================\n\n /**\n * Insert one document into the collection.\n *\n * @param data - Document data (must be a non-empty plain object)\n * @returns Response with the inserted document's ObjectID\n *\n * @example\n * ```ts\n * const { data } = await client.db.collection('users').insertOne({\n * name: 'Alice',\n * age: 25,\n * })\n * console.log(data.objectId) // '507f1f77bcf86cd799439011'\n * ```\n */\n async insertOne(data: Record<string, unknown>): Promise<ApiResponse<InsertResult>> {\n if (!isNonEmptyObject(data)) {\n throw new TypeError('insertOne data must be a non-empty plain object')\n }\n return await this.client.request<InsertResult>('POST', `/v5/classes/${this.name}`, data)\n }\n\n /**\n * Delete one document by ObjectID.\n *\n * @param objectId - 24-character hex ObjectID string\n * @returns Response with deleted count\n *\n * @example\n * ```ts\n * await client.db.collection('users').deleteById('507f1f77bcf86cd799439011')\n * ```\n */\n async deleteById(objectId: string): Promise<ApiResponse<DeleteResult>> {\n assertObjectID(objectId)\n return await this.client.request<DeleteResult>('DELETE', `/v5/classes/${this.name}/${objectId}`)\n }\n\n /**\n * Update one document by ObjectID.\n *\n * @param objectId - 24-character hex ObjectID string\n * @param data - Update data (must be a non-empty plain object)\n * @returns Response with modified count\n *\n * @example\n * ```ts\n * await client.db.collection('users').updateById('507f1f77bcf86cd799439011', { name: 'Bob' })\n * ```\n */\n async updateById(\n objectId: string,\n data: Record<string, unknown>\n ): Promise<ApiResponse<UpdateResult>> {\n assertObjectID(objectId)\n if (!isNonEmptyObject(data)) {\n throw new TypeError('update data must be a non-empty plain object')\n }\n return await this.client.request<UpdateResult>(\n 'PUT',\n `/v5/classes/${this.name}/${objectId}`,\n data\n )\n }\n\n /**\n * Find one document by ObjectID.\n *\n * @param objectId - 24-character hex ObjectID string\n * @returns Response with the found document\n *\n * @example\n * ```ts\n * const { data } = await client.db.collection('users').findById('507f1f77bcf86cd799439011')\n * console.log(data.result) // { _id: '507f1f77...', name: 'Alice', ... }\n * ```\n */\n async findById(objectId: string): Promise<ApiResponse<FindResult>> {\n assertObjectID(objectId)\n return await this.client.request<FindResult>('GET', `/v5/classes/${this.name}/${objectId}`)\n }\n\n // ==================== Filter-based Single Operations ====================\n\n /**\n * Delete one document matching the filter.\n *\n * @param filter - Query filter (must be a non-empty plain object)\n * @returns Response with deleted count\n *\n * @example\n * ```ts\n * await client.db.collection('users').deleteOne({ name: 'Alice' })\n * ```\n */\n async deleteOne(filter: Record<string, unknown>): Promise<ApiResponse<DeleteResult>> {\n if (!isNonEmptyObject(filter)) {\n throw new TypeError('deleteOne filter must be a non-empty plain object')\n }\n return await this.client.request<DeleteResult>('DELETE', `/v5/classes/${this.name}/one`, filter)\n }\n\n /**\n * Update one document matching the filter.\n *\n * @param filter - Query filter to find the document\n * @param body - Update data (MongoDB update operators like $set, $inc, etc.)\n * @returns Response with modified count\n *\n * @example\n * ```ts\n * await client.db.collection('users').updateOne(\n * { name: 'Alice' },\n * { $set: { age: 26 } }\n * )\n * ```\n */\n async updateOne(\n filter: Record<string, unknown>,\n body: Record<string, unknown>\n ): Promise<ApiResponse<UpdateResult>> {\n if (!isNonEmptyObject(filter)) {\n throw new TypeError('updateOne filter must be a non-empty plain object')\n }\n if (!isNonEmptyObject(body)) {\n throw new TypeError('updateOne body must be a non-empty plain object')\n }\n return await this.client.request<UpdateResult>('PUT', `/v5/classes/${this.name}/one`, {\n filter,\n body,\n })\n }\n\n /**\n * Find one document matching the filter.\n *\n * @param filter - Query filter\n * @returns Response with the found document (or null if not found)\n *\n * @example\n * ```ts\n * const { data } = await client.db.collection('users').findOne({ name: 'Alice' })\n * ```\n */\n async findOne(filter: Record<string, unknown>): Promise<ApiResponse<FindResult>> {\n if (!isNonEmptyObject(filter)) {\n throw new TypeError('findOne filter must be a non-empty plain object')\n }\n return await this.client.request<FindResult>('POST', `/v5/classes/${this.name}/one`, filter)\n }\n\n // ==================== Bulk Operations ====================\n\n /**\n * Insert multiple documents into the collection.\n *\n * @param dataList - Array of document data (each must be a non-empty plain object)\n * @returns Response with inserted ObjectIDs and count\n *\n * @example\n * ```ts\n * const { data } = await client.db.collection('users').insertMany([\n * { name: 'Alice', age: 25 },\n * { name: 'Bob', age: 30 },\n * ])\n * console.log(data.insertedCount) // 2\n * ```\n */\n async insertMany(dataList: Record<string, unknown>[]): Promise<ApiResponse<InsertManyResult>> {\n if (!isNonEmptyArrayWithNonEmptyObjects(dataList)) {\n throw new TypeError(\n 'insertMany dataList must be a non-empty array of non-empty plain objects'\n )\n }\n return await this.client.request<InsertManyResult>(\n 'POST',\n `/v5/classes/${this.name}/many`,\n dataList\n )\n }\n\n /**\n * Delete multiple documents matching the filter.\n *\n * @param filter - Query filter (can be an empty object to match all)\n * @returns Response with deleted count\n *\n * @example\n * ```ts\n * const { data } = await client.db.collection('users').deleteMany({ age: { $lt: 18 } })\n * console.log(data.deletedCount) // 5\n * ```\n */\n async deleteMany(filter: Record<string, unknown>): Promise<ApiResponse<DeleteManyResult>> {\n if (!isPlainObject(filter)) {\n throw new TypeError('deleteMany filter must be a plain object')\n }\n return await this.client.request<DeleteManyResult>(\n 'DELETE',\n `/v5/classes/${this.name}/many`,\n filter\n )\n }\n\n /**\n * Update multiple documents matching the filter.\n *\n * @param filter - Query filter to match documents\n * @param body - Update data (MongoDB update operators)\n * @returns Response with modified count\n *\n * @example\n * ```ts\n * await client.db.collection('users').updateMany(\n * { status: 'inactive' },\n * { $set: { status: 'archived' } }\n * )\n * ```\n */\n async updateMany(\n filter: Record<string, unknown>,\n body: Record<string, unknown>\n ): Promise<ApiResponse<UpdateManyResult>> {\n if (!isPlainObject(filter)) {\n throw new TypeError('updateMany filter must be a plain object')\n }\n if (!isNonEmptyObject(body)) {\n throw new TypeError('updateMany body must be a non-empty plain object')\n }\n return await this.client.request<UpdateManyResult>('PUT', `/v5/classes/${this.name}/many`, {\n filter,\n body,\n })\n }\n\n // ==================== Advanced Queries ====================\n\n /**\n * Paginated find query with sorting and filtering.\n *\n * @param page - Page number (1-based, default: 1)\n * @param size - Page size (1-100, default: 10)\n * @param sort - Sort specification, e.g. `{ createdAt: -1 }` for newest first\n * @param filter - Query filter\n * @returns Response with paginated results and pagination metadata\n *\n * @example\n * ```ts\n * const { data } = await client.db.collection('users').find(\n * 1, // page\n * 20, // size\n * { createdAt: -1 }, // sort (newest first)\n * { age: { $gte: 18 } } // filter\n * )\n * console.log(data.results) // Array of documents\n * console.log(data.pagination) // { totalItems: 100, totalPages: 5 }\n * ```\n */\n async find(\n page: number = 1,\n size: number = 10,\n sort: Record<string, number> = { createdAt: -1 },\n filter: Record<string, unknown> = {}\n ): Promise<ApiResponse<PaginationResult>> {\n if (!Number.isInteger(page) || page < 1) {\n throw new TypeError('find page must be a positive integer')\n }\n if (!Number.isInteger(size) || size < 1) {\n throw new TypeError('find size must be a positive integer')\n }\n if (size > MAX_PAGE_SIZE) {\n size = MAX_PAGE_SIZE\n }\n if (!isNonEmptyObject(sort)) {\n throw new TypeError('find sort must be a non-empty plain object')\n }\n if (!isPlainObject(filter)) {\n throw new TypeError('find filter must be a plain object')\n }\n\n return await this.client.request<PaginationResult>('POST', `/v5/classes/${this.name}/find`, {\n page,\n size,\n sort,\n filter,\n })\n }\n\n /**\n * Execute a MongoDB aggregation pipeline.\n *\n * @param pipeline - Array of aggregation stages\n * @returns Response with aggregation results\n *\n * @example\n * ```ts\n * const { data } = await client.db.collection('orders').aggregate([\n * { $match: { status: 'completed' } },\n * { $group: { _id: '$category', total: { $sum: '$amount' } } },\n * { $sort: { total: -1 } },\n * ])\n * ```\n */\n async aggregate(pipeline: Record<string, unknown>[]): Promise<ApiResponse<AggregateResult>> {\n if (!Array.isArray(pipeline)) {\n throw new TypeError('aggregate pipeline must be an array')\n }\n return await this.client.request<AggregateResult>(\n 'POST',\n `/v5/classes/${this.name}/aggregate`,\n pipeline\n )\n }\n\n /**\n * Count documents matching a filter.\n *\n * Uses `POST /v5/classes/:name/count` with the filter as the request body.\n *\n * @param filter - Query filter (can be an empty object for total count)\n * @returns Response with `data.count`\n *\n * @example\n * ```ts\n * const { data } = await client.db.collection('users').count({ status: 'active' })\n * console.log(data.count) // 42\n * ```\n */\n async count(filter: Record<string, unknown> = {}): Promise<ApiResponse<{ count: number }>> {\n if (!isPlainObject(filter)) {\n throw new TypeError('count filter must be a plain object')\n }\n return await this.client.request<{ count: number }>(\n 'POST',\n `/v5/classes/${this.name}/count`,\n filter\n )\n }\n\n /**\n * Get distinct values for a field, optionally filtered.\n *\n * Uses `POST /v5/classes/:name/distinct/:field` with the filter as the request body.\n *\n * @param fieldName - The field to get distinct values for\n * @param filter - Optional filter to narrow the documents\n * @returns Response with `data.results` containing distinct values\n *\n * @example\n * ```ts\n * const { data } = await client.db.collection('users').distinct('city')\n * console.log(data.results) // ['Beijing', 'Shanghai', ...]\n * ```\n */\n async distinct(\n fieldName: string,\n filter: Record<string, unknown> = {}\n ): Promise<ApiResponse<{ results: unknown[] }>> {\n if (typeof fieldName !== 'string' || fieldName.length === 0) {\n throw new TypeError('distinct fieldName must be a non-empty string')\n }\n if (!isPlainObject(filter)) {\n throw new TypeError('distinct filter must be a plain object')\n }\n return await this.client.request<{ results: unknown[] }>(\n 'POST',\n `/v5/classes/${this.name}/distinct/${encodeURIComponent(fieldName)}`,\n filter\n )\n }\n\n // ==================== Schema Management ====================\n\n /**\n * Create this collection (table) in the application's database.\n *\n * @example\n * ```ts\n * await client.db.collection('posts').create()\n * ```\n */\n async create(): Promise<ApiResponse> {\n return await this.client.request('POST', `/v5/schemas/${encodeURIComponent(this.name)}`)\n }\n\n /**\n * Clear all documents from this collection without dropping it.\n *\n * @returns Response with `data.deletedCount`\n *\n * @example\n * ```ts\n * const { data } = await client.db.collection('temp').clear()\n * console.log(data.deletedCount) // 150\n * ```\n */\n async clear(): Promise<ApiResponse<{ deletedCount: number }>> {\n return await this.client.request<{ deletedCount: number }>(\n 'PUT',\n `/v5/schemas/${encodeURIComponent(this.name)}`\n )\n }\n\n /**\n * Drop (delete) this collection entirely.\n *\n * @example\n * ```ts\n * await client.db.collection('old_collection').drop()\n * ```\n */\n async drop(): Promise<ApiResponse> {\n return await this.client.request('DELETE', `/v5/schemas/${encodeURIComponent(this.name)}`)\n }\n}\n\nexport default T1Collection\n","/**\n * T1YOS — Main client class for the t1yOS Serverless Platform SDK.\n *\n * Provides:\n * - Initialization with server time sync\n * - Chainable database operations via `db.collection(name)`\n * - Cloud function invocation\n * - Metadata retrieval\n * - Cryptographic utilities\n */\n\nimport {\n DEFAULT_BASE_URL,\n DEFAULT_VERSION,\n DEFAULT_SAFE_MODE,\n DEFAULT_TIME_FORMAT,\n DEFAULT_OFFSET,\n} from '../constants'\nimport { validateInitConfig, assertObjectID } from '../utils/validators'\nimport {\n isNonEmptyObject,\n isPlainObject,\n isNonEmptyArrayWithNonEmptyObjects,\n} from '../utils/convert'\nimport { hmacSHA256Hex, verifyHmacSHA256 } from '../crypto'\nimport { executeRequest } from '../http'\nimport { T1Collection } from './T1Collection'\nimport type {\n T1YOSConfig,\n T1YOSInternalConfig,\n HttpMethod,\n ApiResponse,\n InitResult,\n} from '../types'\n\n/**\n * Main T1Y client class.\n *\n * @example\n * ```ts\n * import { T1YOS } from 't1y-sdk-js'\n *\n * const client = new T1YOS({\n * appId: 1001,\n * apiKey: '4fd7448cdc684431a62d8a0111dc6973',\n * secretKey: '17b784e359c946ffa65eebbf9ce29752',\n * })\n *\n * await client.init()\n *\n * // Database operations\n * const { data } = await client.db.collection('users').insertOne({ name: 'Alice' })\n * ```\n */\nexport class T1YOS {\n private config: T1YOSInternalConfig\n\n /**\n * Database accessor providing chainable collection operations.\n *\n * @example\n * ```ts\n * await client.db.collection('users').insertOne({ name: 'Alice' })\n * await client.db.collection('users').findOne({ name: 'Alice' })\n * ```\n */\n readonly db: {\n collection: (name: string) => T1Collection\n toObjectID: (id: string) => string\n getCollections: () => Promise<ApiResponse<{ results: string[] }>>\n }\n\n /**\n * Create a new T1YOS client instance.\n *\n * @param config - Client configuration (appId, apiKey, secretKey are required)\n *\n * @throws {ValidationError} If required parameters are invalid\n */\n constructor(config: T1YOSConfig) {\n // Validate required parameters\n validateInitConfig(config)\n\n this.config = {\n baseUrl: config.baseUrl ?? DEFAULT_BASE_URL,\n appId: config.appId,\n apiKey: config.apiKey,\n secretKey: config.secretKey,\n version: config.version ?? DEFAULT_VERSION,\n isSafeMode: config.isSafeMode ?? DEFAULT_SAFE_MODE,\n timeFormat: config.timeFormat ?? DEFAULT_TIME_FORMAT,\n offset: config.offset ?? DEFAULT_OFFSET,\n }\n\n // Set up the chainable db accessor\n this.db = {\n collection: (name: string) => this.#collection(name),\n toObjectID: (id: string) => this.#toObjectID(id),\n getCollections: () => this.#getCollections(),\n }\n }\n\n /**\n * Initialize the SDK by syncing with the server.\n *\n * Calls `GET /init/:appId` to:\n * 1. Get the server's current UTC Unix timestamp\n * 2. Get the server's isSafeMode setting\n *\n * The time offset is computed as: `server.unix - client.unix`\n * This offset is used for all subsequent request signing to prevent clock skew issues.\n *\n * @throws {T1YError} If the server returns an error (e.g., app not found, app disabled)\n */\n async init(): Promise<void> {\n try {\n const res = await this.request<InitResult>(\n 'GET',\n `/init/${this.config.appId}`,\n undefined,\n false\n )\n const data = res.data\n this.config.isSafeMode = data.is_safe_mode\n this.config.offset = data.unix - Math.floor(Date.now() / 1000)\n } catch (err) {\n console.warn('Failed to get time offset from server, defaulting to 0. Error:', err)\n this.config.isSafeMode = false\n this.config.offset = 0\n }\n }\n\n // ==================== Public API ====================\n\n /**\n * Get application metadata.\n *\n * @param field - Optional field name to retrieve a specific metadata field\n * @returns Metadata as key-value pairs, or a single field value if `field` is specified\n *\n * @example\n * ```ts\n * // Get all metadata\n * const { data } = await client.getMeta()\n * // data.results = { version: 1, collections: [...] }\n *\n * // Get a specific field\n * const { data } = await client.getMeta('version')\n * // data.result = 1\n * ```\n */\n async getMeta(field?: string): Promise<ApiResponse> {\n if (field !== undefined && field !== '' && typeof field !== 'string') {\n throw new TypeError('Meta field must be a string')\n }\n const queryPath = field ? `?field=${encodeURIComponent(field)}` : ''\n return await this.request('GET', `/v5/meta${queryPath}`)\n }\n\n /**\n * Check if there's a newer version of the application available.\n *\n * Compares the server's `version` metadata field against the configured `version`.\n *\n * @returns `true` if the server version is greater than the client version\n */\n async checkUpdate(): Promise<boolean> {\n try {\n const res = await this.request<{ result: number }>('GET', '/v5/meta?field=version')\n return res.data.result > this.config.version\n } catch {\n return false\n }\n }\n\n /**\n * Call a cloud function (`.jsc` file).\n *\n * If `name` doesn't end with `.jsc`, it's auto-appended.\n * If `name` ends with `/`, `index.jsc` is appended.\n * If `name` ends with `.js`, it's replaced with `.jsc`.\n *\n * @param name - Function name or path (e.g., 'hello' or 'hello.jsc')\n * @param params - Parameters to pass to the function\n * @param enableSafeMode - Override safe mode for this call (defaults to client setting)\n *\n * @example\n * ```ts\n * const { data } = await client.callFunc('hello', { name: 'World' })\n * ```\n */\n async callFunc(\n name: string,\n params: unknown = null,\n enableSafeMode?: boolean\n ): Promise<ApiResponse> {\n if (typeof name !== 'string') {\n throw new TypeError('Function name must be a string')\n }\n return await this.request(\n 'POST',\n `/${this.config.appId}/${this.#ensureJscExtension(name)}`,\n params,\n enableSafeMode\n )\n }\n\n /**\n * Core HTTP request method with full authentication and encryption.\n *\n * @param method - HTTP method (GET, POST, PUT, DELETE)\n * @param path - API path (e.g., /v5/classes/users)\n * @param params - Request parameters/body\n * @param encryption - Override encryption (defaults to client.isSafeMode)\n * @returns Typed API response\n *\n * @throws {T1YError} On API errors (non-2xx responses)\n * @throws {Error} On network errors or timeouts\n */\n async request<T = unknown>(\n method: HttpMethod,\n path: string,\n params?: unknown,\n encryption?: boolean\n ): Promise<ApiResponse<T>> {\n if (typeof path !== 'string') {\n throw new TypeError('request path must be a string')\n }\n\n return await executeRequest<T>(this.config, {\n method,\n path,\n params,\n encryption: encryption ?? this.config.isSafeMode,\n })\n }\n\n // ==================== Utilities ====================\n\n /**\n * Validate an ObjectID hex string.\n *\n * @param idStr - 24-character hex string to validate\n * @param name - Optional name for error messages (default: 'ObjectID')\n * @returns `true` if valid\n * @throws {ValidationError} If the string is not a valid ObjectID\n */\n assertObjectID(idStr: string, name = 'ObjectID'): boolean {\n return assertObjectID(idStr, name)\n }\n\n /** Check if a value is a non-null, non-array object with at least one key */\n isNonEmptyObject(value: unknown): boolean {\n return isNonEmptyObject(value)\n }\n\n /** Check if a value is a plain object (non-null, non-array) */\n isPlainObject(value: unknown): boolean {\n return isPlainObject(value)\n }\n\n /** Check if a value is a non-empty array where every element is a non-empty object */\n isNonEmptyArrayWithNonEmptyObjects(value: unknown): boolean {\n return isNonEmptyArrayWithNonEmptyObjects(value)\n }\n\n // ==================== Crypto ====================\n\n /**\n * Compute HMAC-SHA256 hash and return hex digest.\n *\n * @param message - The message to sign\n * @param secret - The secret key\n * @returns 64-character hex-encoded HMAC-SHA256\n */\n hmacSHA256(secret: string, message: string): string {\n return hmacSHA256Hex(secret, message)\n }\n\n /**\n * Verify an HMAC-SHA256 signature using constant-time comparison.\n *\n * @param secret - The secret key\n * @param message - The message that was signed\n * @param signature - The expected signature (hex string)\n * @returns `true` if the signature matches\n */\n verifyHmacSHA256(secret: string, message: string, signature: string): boolean {\n return verifyHmacSHA256(secret, message, signature)\n }\n\n // ==================== Private Helpers ====================\n\n /** Create a T1Collection for the given collection name */\n #collection(name: string): T1Collection {\n if (typeof name !== 'string') {\n throw new TypeError('Collection name must be a string')\n }\n return new T1Collection(this, name)\n }\n\n /** Get all collections in the application's database */\n async #getCollections(): Promise<ApiResponse<{ results: string[] }>> {\n return await this.request<{ results: string[] }>('GET', '/v5/schemas')\n }\n\n /** Convert a 24-char hex string to an ObjectID marker */\n #toObjectID(idStr: string): string {\n assertObjectID(idStr)\n return `ObjectID('${idStr}')`\n }\n\n /** Ensure a function name has the .jsc extension */\n #ensureJscExtension(input: string): string {\n let path = input.startsWith('/') ? input.slice(1) : input\n\n // Separate hash fragment\n const hashIndex = path.indexOf('#')\n const hash = hashIndex !== -1 ? path.slice(hashIndex) : ''\n const withoutHash = hashIndex !== -1 ? path.slice(0, hashIndex) : path\n\n // Separate query string\n const qIndex = withoutHash.indexOf('?')\n const query = qIndex !== -1 ? withoutHash.slice(qIndex) : ''\n let mainPath = qIndex !== -1 ? withoutHash.slice(0, qIndex) : withoutHash\n\n // Apply extension rules\n if (mainPath.endsWith('/')) {\n mainPath = mainPath + 'index.jsc'\n } else if (mainPath.endsWith('.jsc')) {\n // Already has .jsc\n } else if (mainPath.endsWith('.js')) {\n mainPath = mainPath.replace(/\\.js$/, '.jsc')\n } else {\n mainPath = mainPath + '.jsc'\n }\n\n return mainPath + query + hash\n }\n}\n\nexport default T1YOS\n","import { OBJECT_ID_PATTERN } from '../constants'\n\n/**\n * Create an ObjectID marker string that the server will convert to a MongoDB ObjectID.\n *\n * @param id - 24-character hexadecimal string\n * @returns ObjectID marker string, e.g. `ObjectID('507f1f77bcf86cd799439011')`\n *\n * @example\n * ```ts\n * import { ObjectID } from 't1y-sdk-js'\n *\n * await db.collection('users').find(ObjectID('507f1f77bcf86cd799439011'))\n * ```\n */\nexport function ObjectID(id: string): `ObjectID('${string}')` {\n if (!OBJECT_ID_PATTERN.test(id)) {\n throw new Error(`Invalid ObjectID: \"${id}\" (must be 24 hex characters)`)\n }\n return `ObjectID('${id}')`\n}\n","/**\n * Create a Date marker string. The server converts this to a Go time.Time.\n *\n * @param dateStr - ISO 8601 / RFC 3339 date string\n * @returns Date marker, e.g. `Date('2024-01-15T10:30:00Z')`\n */\nexport function Date_(dateStr: string): `Date('${string}')` {\n return `Date('${dateStr}')`\n}\n\n/**\n * Create a DateTime marker string. Same as Date on the server side.\n *\n * @param dateStr - ISO 8601 / RFC 3339 date string\n * @returns DateTime marker, e.g. `DateTime('2024-01-15T10:30:00Z')`\n */\nexport function DateTime(dateStr: string): `DateTime('${string}')` {\n return `DateTime('${dateStr}')`\n}\n\n/**\n * Create a Timestamp marker string. The server converts this to a Unix timestamp.\n *\n * @param unix - Unix timestamp (seconds) as number or string\n * @returns Timestamp marker, e.g. `Timestamp('1705312200')`\n */\nexport function Timestamp(unix: number | string): `Timestamp('${string}')` {\n return `Timestamp('${String(unix)}')`\n}\n","/**\n * Create a Boolean marker. The server converts this to a Go bool.\n */\nexport function Boolean_(val: boolean): `Boolean(${string})` {\n return `Boolean(${val})`\n}\n\n/**\n * Create an Integer marker. The server converts this to int32.\n */\nexport function Integer(n: number): `Integer(${number})` {\n return `Integer(${n})`\n}\n\n/**\n * Create a Bigint marker. The server converts this to int64.\n */\nexport function Bigint(n: number | bigint): `Bigint(${number})` {\n return `Bigint(${Number(n)})`\n}\n\n/**\n * Create a Float marker. The server converts this to float32.\n */\nexport function Float(n: number): `Float(${number})` {\n return `Float(${n})`\n}\n\n/**\n * Create a Double marker. The server converts this to float64.\n */\nexport function Double(n: number): `Double(${number})` {\n return `Double(${n})`\n}\n","/**\n * Create an Array marker. The server converts this to a Go slice.\n *\n * @param arr - Array to serialize as JSON\n */\nexport function Array_(arr: unknown[]): `Array(${string})` {\n return `Array(${JSON.stringify(arr)})`\n}\n\n/**\n * Create a Map marker. The server converts this to a map[string]interface{}.\n *\n * @param obj - Object to serialize as JSON\n */\nexport function Map_(obj: Record<string, unknown>): `Map(${string})` {\n return `Map(${JSON.stringify(obj)})`\n}\n\n/**\n * Create a Map[] marker. The server converts this to []map[string]interface{}.\n *\n * @param arr - Array of objects to serialize as JSON\n */\nexport function MapArray(arr: Record<string, unknown>[]): `Map[](${string})` {\n return `Map[](${JSON.stringify(arr)})`\n}\n","/**\n * Null / null-equivalent markers that the server converts to Go nil.\n *\n * The server recognizes all these variants as null:\n * 'Null', 'null', 'NULL', 'None', 'none', 'NONE', 'Nil', 'nil', 'NIL', '<nil>', ''\n */\n\n/** Null marker — server converts to nil */\nexport const Null = 'Null' as const\n\n/** None marker — server converts to nil */\nexport const None = 'None' as const\n\n/** Nil marker — server converts to nil */\nexport const Nil = 'Nil' as const\n\n/** empty string — server converts to nil (use '' directly) */\nexport const Empty = '' as const\n\n/**\n * Undefined markers that the server converts to bson.Undefined{}.\n */\nexport const UNDEFINED = 'UNDEFINED' as const\nexport const Undefined = 'Undefined' as const\n","/**\n * Time helper markers that the server evaluates at request time.\n *\n * These are string values that, when sent to the server, are replaced\n * with the actual current time on the server side via Go's time.Now().\n */\n\n/** Server fills in time.Now() (current UTC time) */\nexport const TimeNow = 'time.Now()' as const\n\n/** Server fills in time.Now().Unix() (current Unix timestamp) */\nexport const TimeNowUnix = 'time.Now().Unix()' as const\n\n/** Server fills in time.Now().UnixNano() */\nexport const TimeNowUnixNano = 'time.Now().UnixNano()' as const\n\n/** Server fills in time.Now().Weekday() (e.g., time.Monday) */\nexport const TimeNowWeekday = 'time.Now().Weekday()' as const\n\n/** Server fills in time.Now().Weekday().Chinese() (Chinese weekday name) */\nexport const TimeNowWeekdayChinese = 'time.Now().Weekday().Chinese()' as const\n\n/**\n * Convenience object grouping all time-now helpers.\n *\n * @example\n * ```ts\n * import { timeNow } from 't1y-sdk-js'\n *\n * await db.collection('posts').insertOne({\n * title: 'Hello',\n * createdAt: timeNow.Now(),\n * })\n * ```\n */\nexport const timeNow = {\n Now: () => TimeNow,\n NowUnix: () => TimeNowUnix,\n NowUnixNano: () => TimeNowUnixNano,\n NowWeekday: () => TimeNowWeekday,\n NowWeekdayChinese: () => TimeNowWeekdayChinese,\n}\n"],"mappings":"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","names":["src_exports","__export","Array_","Bigint","Boolean_","Date_","DateTime","Double","Empty","Float","Integer","Map_","MapArray","Nil","None","Null","ObjectID","T1Collection","T1YError","T1YOS","TimeNow","TimeNowUnix","TimeNowUnixNano","TimeNowWeekday","TimeNowWeekdayChinese","Timestamp","UNDEFINED","Undefined","ValidationError","assertObjectID","convertDateTypes","createSignature","decryptAESGCM","T1YOS_default","encryptAESGCM","formatTimestampsToLocal","getMiniProgramAPI","getMiniProgramSubType","getPlatformType","getSafeTimestamp","hmacSHA256Hex","hmacSHA256HexAsync","isAESGCMAvailable","isNonEmptyArrayWithNonEmptyObjects","isNonEmptyObject","isPlainObject","isWebCryptoAvailable","resetPlatformDetection","sha256Hex","sha256HexAsync","timeNow","validateApiKey","validateAppId","validateBaseUrl","validateInitConfig","validateSecretKey","verifyHmacSHA256","__toCommonJS","DEFAULT_BASE_URL","DEFAULT_TIME_FORMAT","OBJECT_ID_PATTERN","T1YError","code","message","data","ValidationError","validateAppId","appId","ValidationError","validateApiKey","apiKey","validateSecretKey","secretKey","validateBaseUrl","baseUrl","validateInitConfig","config","assertObjectID","idStr","name","OBJECT_ID_PATTERN","convertDateTypes","value","str","v","obj","key","isNonEmptyObject","isPlainObject","isNonEmptyArrayWithNonEmptyObjects","item","getNodeRequire","e","sha256Hex","data","nodeReq","bytes","utf8ToBytes","sha256RawBytesHex","sha256Raw","sha256HexAsync","encoder","hashBuffer","b","str","i","c","c2","cp","writeUint64BE","buf","offset","value","hi","lo","K","msgByteLen","msgBitLen","padLen","totalLen","padded","H","W","t","s0","rotr","s1","a","f","g","h","S1","ch","temp1","S0","maj","temp2","v","x","n","getNodeRequire","e","hmacSHA256Hex","secret","message","nodeReq","hmacSHA256Pure","hmacSHA256HexAsync","encoder","key","signature","b","verifyHmacSHA256","expected","timingSafeEqual","a","result","i","keyBytes","utf8ToBytes","msgBytes","hexToBytes","sha256RawBytesHex","paddedKey","ipad","innerKey","xorBytes","innerData","innerHash","opad","outerKey","outerData","str","bytes","c","c2","cp","hex","SBOX","RCON","keyExpansion256","key","Nk","Nr","totalWords","words","i","temp","subWord","rotWord","roundKeys","r","rk","j","w","aesEncryptBlock","block","state","addRoundKey","round","subBytes","shiftRows","mixColumns","out","row","a","gmul","roundKey","b","p","aa","bb","hiBit","aesCtr","counter","data","blockCount","output","ctr","keystream","blockLen","incrementCounter","val","writeUint64BE","buf","offset","value","hi","lo","ghash","h","aad","ciphertext","aadBlocks","ctBlocks","totalBlocks","y","len","mulResult","gfMul","lenBlock","aadBitLen","ctBitLen","x","result","v","byteIdx","bit","k","lsb","aesGcmEncryptPure","plaintext","nonce","j0","zeroBlock","j0Block","ctrBlock","s","encryptedS","tag","aesGcmDecryptPure","expectedTag","mismatch","getWebCrypto","nodeReq","nodeCryptoModule","e","isAESGCMAvailable","isWebCryptoAvailable","AES_GCM_TAG_LENGTH","AES_GCM_NONCE_LENGTH","getRandomBytes","length","wc","bytes","i","encodeBase64","uint8array","binary","len","decodeBase64","b64","encryptAESGCMWebCrypto","data","keyBytes","cryptoApi","key","nonce","encodedData","encrypted","ciphertext","tag","payload","decryptAESGCMWebCrypto","jsonPayload","n","j","t","sealed","decrypted","encryptAESGCMPure","plaintext","aesGcmEncryptPure","decryptAESGCMPure","aesGcmDecryptPure","encryptAESGCM","decryptAESGCM","createSignature","input","method","pathAndQuery","body","appId","timestamp","secretKey","bodyHash","sha256Hex","message","hmacSHA256Hex","getSafeTimestamp","offset","normalizeBaseUrl","baseUrl","appendQueryParams","url","params","key","value","formatLocalTime","utcString","format","date","pad","n","formatTimestampsToLocal","data","DEFAULT_TIME_FORMAT","traverse","value","result","key","handleResponse","response","isSafeMode","secretKey","timeFormat","contentType","rawData","responseText","e","decrypted","decryptAESGCM","err","T1YError","isOk","apiResp","formatTimestampsToLocal","handleFetchError","error","message","_platformType","_miniProgramSubType","getPlatformType","_a","getMiniProgramSubType","getMiniProgramAPI","platform","resetPlatformDetection","fetchRequest","options","url","method","headers","body","signal","fetchOptions","response","responseHeaders","value","key","responseBody","wxRequest","options","mpApi","getMiniProgramAPI","requestFn","url","method","headers","body","timeout","resolve","reject","requestTask","res","_a","responseHeaders","key","bodyStr","err","errMsg","onAbort","myRequest","options","mpApi","requestFn","url","method","headers","body","timeout","resolve","reject","requestTask","res","_a","_b","status","responseHeaders","key","bodyStr","err","errMsg","onAbort","getSystemFetch","_e","hapRequest","options","sysFetch","url","method","headers","body","resolve","reject","res","responseHeaders","key","err","_cachedRequest","getPlatformRequest","_cachedRequest","getPlatformType","fetchRequest","wxRequest","myRequest","hapRequest","executeRequest","client","options","method","path","params","encryption","timeout","baseUrl","normalizeBaseUrl","isSafeMode","fullUrl","convertedParams","convertDateTypes","bodyForRequest","rawBodyString","encryptedBody","encryptAESGCM","jsonBody","appendQueryParams","timestamp","getSafeTimestamp","originalURL","sign","createSignature","platformRequest","getPlatformRequest","timeoutMs","response","handleResponse","error","handleFetchError","T1Collection","client","name","data","isNonEmptyObject","objectId","assertObjectID","filter","body","dataList","isNonEmptyArrayWithNonEmptyObjects","isPlainObject","page","size","sort","pipeline","fieldName","_T1YOS_instances","collection_fn","getCollections_fn","toObjectID_fn","ensureJscExtension_fn","T1YOS","config","__privateAdd","_a","_b","_c","_d","_e","validateInitConfig","DEFAULT_BASE_URL","DEFAULT_TIME_FORMAT","name","__privateMethod","id","data","err","field","queryPath","params","enableSafeMode","method","path","encryption","executeRequest","idStr","assertObjectID","value","isNonEmptyObject","isPlainObject","isNonEmptyArrayWithNonEmptyObjects","secret","message","hmacSHA256Hex","signature","verifyHmacSHA256","T1Collection","input","hashIndex","hash","withoutHash","qIndex","query","mainPath","T1YOS_default","ObjectID","id","OBJECT_ID_PATTERN","Date_","dateStr","DateTime","Timestamp","unix","Boolean_","val","Integer","n","Bigint","Float","Double","Array_","arr","Map_","obj","MapArray","Null","None","Nil","Empty","UNDEFINED","Undefined","TimeNow","TimeNowUnix","TimeNowUnixNano","TimeNowWeekday","TimeNowWeekdayChinese","timeNow"]}