@cipherstash/stack 0.18.0 → 0.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. package/CHANGELOG.md +173 -0
  2. package/README.md +2 -2
  3. package/dist/{chunk-ZYOZHZMJ.js → chunk-36AA7IBJ.js} +151 -160
  4. package/dist/chunk-36AA7IBJ.js.map +1 -0
  5. package/dist/{chunk-VPOTNP4K.js → chunk-4AVL4VZD.js} +1 -1
  6. package/dist/chunk-4AVL4VZD.js.map +1 -0
  7. package/dist/{chunk-XWPGAHBZ.js → chunk-BNO32ZMV.js} +1 -1
  8. package/dist/chunk-BNO32ZMV.js.map +1 -0
  9. package/dist/{chunk-LLCCNKDL.js → chunk-HQANMV7R.js} +3 -3
  10. package/dist/{chunk-LLCCNKDL.js.map → chunk-HQANMV7R.js.map} +1 -1
  11. package/dist/chunk-IADZCZEA.js +23 -0
  12. package/dist/chunk-IADZCZEA.js.map +1 -0
  13. package/dist/chunk-IBSK6P33.js +209 -0
  14. package/dist/chunk-IBSK6P33.js.map +1 -0
  15. package/dist/chunk-JSG2AMDI.js +17 -0
  16. package/dist/chunk-JSG2AMDI.js.map +1 -0
  17. package/dist/chunk-MP3SSDNN.js +4439 -0
  18. package/dist/chunk-MP3SSDNN.js.map +1 -0
  19. package/dist/chunk-OFQ555AX.js +191 -0
  20. package/dist/chunk-OFQ555AX.js.map +1 -0
  21. package/dist/chunk-PZ5AY32C.js +10 -0
  22. package/dist/chunk-PZ5AY32C.js.map +1 -0
  23. package/dist/chunk-U66S7VIF.js +435 -0
  24. package/dist/chunk-U66S7VIF.js.map +1 -0
  25. package/dist/{client-Dt98Rugc.d.cts → client-DSGHBN-g.d.cts} +200 -58
  26. package/dist/{client-CIsfZ2zg.d.ts → client-DfCrlHXh.d.ts} +200 -58
  27. package/dist/client.cjs +4101 -43
  28. package/dist/client.cjs.map +1 -1
  29. package/dist/client.d.cts +5 -5
  30. package/dist/client.d.ts +5 -5
  31. package/dist/client.js +3 -1
  32. package/dist/drizzle/index.cjs +4133 -74
  33. package/dist/drizzle/index.cjs.map +1 -1
  34. package/dist/drizzle/index.d.cts +33 -33
  35. package/dist/drizzle/index.d.ts +33 -33
  36. package/dist/drizzle/index.js +35 -30
  37. package/dist/drizzle/index.js.map +1 -1
  38. package/dist/dynamodb/index.cjs +19 -12
  39. package/dist/dynamodb/index.cjs.map +1 -1
  40. package/dist/dynamodb/index.d.cts +2 -2
  41. package/dist/dynamodb/index.d.ts +2 -2
  42. package/dist/dynamodb/index.js +8 -10
  43. package/dist/dynamodb/index.js.map +1 -1
  44. package/dist/encryption/index.cjs +4448 -212
  45. package/dist/encryption/index.cjs.map +1 -1
  46. package/dist/encryption/index.d.cts +3 -3
  47. package/dist/encryption/index.d.ts +3 -3
  48. package/dist/encryption/index.js +15 -7
  49. package/dist/encryption/v3.cjs +7791 -0
  50. package/dist/encryption/v3.cjs.map +1 -0
  51. package/dist/encryption/v3.d.cts +100 -0
  52. package/dist/encryption/v3.d.ts +100 -0
  53. package/dist/encryption/v3.js +161 -0
  54. package/dist/encryption/v3.js.map +1 -0
  55. package/dist/eql/v3/index.cjs +612 -0
  56. package/dist/eql/v3/index.cjs.map +1 -0
  57. package/dist/eql/v3/index.d.cts +71 -0
  58. package/dist/eql/v3/index.d.ts +71 -0
  59. package/dist/eql/v3/index.js +89 -0
  60. package/dist/eql/v3/index.js.map +1 -0
  61. package/dist/errors/index.js +1 -0
  62. package/dist/identity/index.cjs +55 -35
  63. package/dist/identity/index.cjs.map +1 -1
  64. package/dist/identity/index.d.cts +54 -30
  65. package/dist/identity/index.d.ts +54 -30
  66. package/dist/identity/index.js +9 -177
  67. package/dist/identity/index.js.map +1 -1
  68. package/dist/index.cjs +4480 -228
  69. package/dist/index.cjs.map +1 -1
  70. package/dist/index.d.cts +18 -7
  71. package/dist/index.d.ts +18 -7
  72. package/dist/index.js +20 -5
  73. package/dist/index.js.map +1 -1
  74. package/dist/schema/index.cjs +4105 -43
  75. package/dist/schema/index.cjs.map +1 -1
  76. package/dist/schema/index.d.cts +1 -1
  77. package/dist/schema/index.d.ts +1 -1
  78. package/dist/schema/index.js +3 -1
  79. package/dist/supabase/index.cjs +4500 -75
  80. package/dist/supabase/index.cjs.map +1 -1
  81. package/dist/supabase/index.d.cts +113 -34
  82. package/dist/supabase/index.d.ts +113 -34
  83. package/dist/supabase/index.js +350 -32
  84. package/dist/supabase/index.js.map +1 -1
  85. package/dist/table-CIH7jZ2h.d.ts +603 -0
  86. package/dist/table-DihEAlxG.d.cts +603 -0
  87. package/dist/{types-public-BTxqjmtv.d.ts → types-public-CpS5KjwX.d.cts} +250 -92
  88. package/dist/{types-public-BTxqjmtv.d.cts → types-public-CpS5KjwX.d.ts} +250 -92
  89. package/dist/types-public.cjs.map +1 -1
  90. package/dist/types-public.d.cts +2 -2
  91. package/dist/types-public.d.ts +2 -2
  92. package/dist/types-public.js +2 -1
  93. package/dist/wasm-inline.d.ts +1269 -0
  94. package/dist/wasm-inline.js +4594 -0
  95. package/dist/wasm-inline.js.map +1 -0
  96. package/package.json +54 -4
  97. package/dist/chunk-VPOTNP4K.js.map +0 -1
  98. package/dist/chunk-XWPGAHBZ.js.map +0 -1
  99. package/dist/chunk-YWQXTZ5M.js +0 -383
  100. package/dist/chunk-YWQXTZ5M.js.map +0 -1
  101. package/dist/chunk-ZYOZHZMJ.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../node_modules/.pnpm/evlog@1.11.0_next@15.5.10_react-dom@19.2.3_react@19.2.3__react@19.2.3__react@19.2.3/node_modules/evlog/src/utils.ts","../../../node_modules/.pnpm/evlog@1.11.0_next@15.5.10_react-dom@19.2.3_react@19.2.3__react@19.2.3__react@19.2.3/node_modules/evlog/src/logger.ts","../src/utils/logger/index.ts"],"sourcesContent":["import type { EnvironmentContext, LogLevel } from './types'\n\nexport function formatDuration(ms: number): string {\n if (ms < 1000) {\n return `${Math.round(ms)}ms`\n }\n return `${(ms / 1000).toFixed(2)}s`\n}\n\nexport function isServer(): boolean {\n return typeof window === 'undefined'\n}\n\nexport function isClient(): boolean {\n return typeof window !== 'undefined'\n}\n\nexport function isDev(): boolean {\n if (typeof process !== 'undefined') {\n return process.env.NODE_ENV !== 'production'\n }\n if (typeof window !== 'undefined') {\n return true\n }\n return false\n}\n\nexport function detectEnvironment(): Partial<EnvironmentContext> {\n const env = typeof process !== 'undefined' ? process.env : {}\n const defaultEnvironment = isDev() ? 'development' : 'production'\n\n return {\n environment: env.NODE_ENV || defaultEnvironment,\n service: env.SERVICE_NAME || 'app',\n version: env.APP_VERSION,\n commitHash: env.COMMIT_SHA\n || env.GITHUB_SHA\n || env.VERCEL_GIT_COMMIT_SHA\n || env.CF_PAGES_COMMIT_SHA,\n region: env.VERCEL_REGION\n || env.AWS_REGION\n || env.FLY_REGION\n || env.CF_REGION,\n }\n}\n\nexport function getConsoleMethod(level: LogLevel): LogLevel {\n return level\n}\n\nexport const colors = {\n reset: '\\x1B[0m',\n bold: '\\x1B[1m',\n dim: '\\x1B[2m',\n red: '\\x1B[31m',\n green: '\\x1B[32m',\n yellow: '\\x1B[33m',\n blue: '\\x1B[34m',\n magenta: '\\x1B[35m',\n cyan: '\\x1B[36m',\n white: '\\x1B[37m',\n gray: '\\x1B[90m',\n} as const\n\nexport function getLevelColor(level: string): string {\n switch (level) {\n case 'error':\n return colors.red\n case 'warn':\n return colors.yellow\n case 'info':\n return colors.cyan\n case 'debug':\n return colors.gray\n default:\n return colors.white\n }\n}\n\n/** Headers that should never be passed to hooks for security */\nexport const SENSITIVE_HEADERS = [\n 'authorization',\n 'cookie',\n 'set-cookie',\n 'x-api-key',\n 'x-auth-token',\n 'proxy-authorization',\n]\n\nexport function filterSafeHeaders(headers: Record<string, string>): Record<string, string> {\n const safeHeaders: Record<string, string> = {}\n\n for (const [key, value] of Object.entries(headers)) {\n if (!SENSITIVE_HEADERS.includes(key.toLowerCase())) {\n safeHeaders[key] = value\n }\n }\n\n return safeHeaders\n}\n\n/**\n * Match a path against a glob pattern.\n * Supports * (any chars except /) and ** (any chars including /).\n */\nexport function matchesPattern(path: string, pattern: string): boolean {\n const regexPattern = pattern\n .replace(/[.+^${}()|[\\]\\\\]/g, '\\\\$&') // Escape special regex chars except * and ?\n .replace(/\\*\\*/g, '{{GLOBSTAR}}') // Temp placeholder for **\n .replace(/\\*/g, '[^/]*') // * matches anything except /\n .replace(/{{GLOBSTAR}}/g, '.*') // ** matches anything including /\n .replace(/\\?/g, '[^/]') // ? matches single char except /\n\n const regex = new RegExp(`^${regexPattern}$`)\n return regex.test(path)\n}\n","import type { DrainContext, EnvironmentContext, FieldContext, Log, LogLevel, LoggerConfig, RequestLogger, RequestLoggerOptions, SamplingConfig, TailSamplingContext, WideEvent } from './types'\nimport { colors, detectEnvironment, formatDuration, getConsoleMethod, getLevelColor, isDev, matchesPattern } from './utils'\n\nfunction isPlainObject(val: unknown): val is Record<string, unknown> {\n return val !== null && typeof val === 'object' && !Array.isArray(val)\n}\n\nfunction deepDefaults(base: Record<string, unknown>, defaults: Record<string, unknown>): Record<string, unknown> {\n const result = { ...base }\n for (const key in defaults) {\n const baseVal = result[key]\n const defaultVal = defaults[key]\n if (baseVal === undefined || baseVal === null) {\n result[key] = defaultVal\n } else if (isPlainObject(baseVal) && isPlainObject(defaultVal)) {\n result[key] = deepDefaults(baseVal, defaultVal)\n }\n }\n return result\n}\n\nlet globalEnv: EnvironmentContext = {\n service: 'app',\n environment: 'development',\n}\n\nlet globalPretty = isDev()\nlet globalSampling: SamplingConfig = {}\nlet globalStringify = true\nlet globalDrain: ((ctx: DrainContext) => void | Promise<void>) | undefined\nlet globalEnabled = true\n\n/**\n * Initialize the logger with configuration.\n * Call this once at application startup.\n */\nexport function initLogger(config: LoggerConfig = {}): void {\n globalEnabled = config.enabled ?? true\n const detected = detectEnvironment()\n\n globalEnv = {\n service: config.env?.service ?? detected.service ?? 'app',\n environment: config.env?.environment ?? detected.environment ?? 'development',\n version: config.env?.version ?? detected.version,\n commitHash: config.env?.commitHash ?? detected.commitHash,\n region: config.env?.region ?? detected.region,\n }\n\n globalPretty = config.pretty ?? isDev()\n globalSampling = config.sampling ?? {}\n globalStringify = config.stringify ?? true\n globalDrain = config.drain\n}\n\n/**\n * Check if logging is globally enabled.\n */\nexport function isEnabled(): boolean {\n return globalEnabled\n}\n\n/**\n * Determine if a log at the given level should be emitted based on sampling config.\n * Error level defaults to 100% (always logged) unless explicitly configured otherwise.\n */\nfunction shouldSample(level: LogLevel): boolean {\n const { rates } = globalSampling\n if (!rates) {\n return true // No sampling configured, log everything\n }\n\n // Error defaults to 100% unless explicitly set\n const percentage = level === 'error' && rates.error === undefined\n ? 100\n : rates[level] ?? 100\n\n // 0% = never log, 100% = always log\n if (percentage <= 0) return false\n if (percentage >= 100) return true\n\n return Math.random() * 100 < percentage\n}\n\n/**\n * Evaluate tail sampling conditions to determine if a log should be force-kept.\n * Returns true if ANY condition matches (OR logic).\n */\nexport function shouldKeep(ctx: TailSamplingContext): boolean {\n const { keep } = globalSampling\n if (!keep?.length) return false\n\n return keep.some((condition) => {\n if (condition.status !== undefined && ctx.status !== undefined && ctx.status >= condition.status) {\n return true\n }\n if (condition.duration !== undefined && ctx.duration !== undefined && ctx.duration >= condition.duration) {\n return true\n }\n if (condition.path && ctx.path && matchesPattern(ctx.path, condition.path)) {\n return true\n }\n return false\n })\n}\n\nfunction emitWideEvent(level: LogLevel, event: Record<string, unknown>, skipSamplingCheck = false): WideEvent | null {\n if (!globalEnabled) return null\n\n if (!skipSamplingCheck && !shouldSample(level)) {\n return null\n }\n\n const formatted: WideEvent = {\n timestamp: new Date().toISOString(),\n level,\n ...globalEnv,\n ...event,\n }\n\n if (globalPretty) {\n prettyPrintWideEvent(formatted)\n } else if (globalStringify) {\n console[getConsoleMethod(level)](JSON.stringify(formatted))\n } else {\n console[getConsoleMethod(level)](formatted)\n }\n\n if (globalDrain) {\n Promise.resolve(globalDrain({ event: formatted })).catch((err) => {\n console.error('[evlog] drain failed:', err)\n })\n }\n\n return formatted\n}\n\nfunction emitTaggedLog(level: LogLevel, tag: string, message: string): void {\n if (!globalEnabled) return\n\n if (globalPretty) {\n if (!shouldSample(level)) {\n return\n }\n const color = getLevelColor(level)\n const timestamp = new Date().toISOString().slice(11, 23)\n console.log(`${colors.dim}${timestamp}${colors.reset} ${color}[${tag}]${colors.reset} ${message}`)\n return\n }\n emitWideEvent(level, { tag, message })\n}\n\nfunction formatValue(value: unknown): string {\n if (value === null || value === undefined) {\n return String(value)\n }\n if (typeof value === 'object') {\n // Flatten object to key=value pairs\n const pairs: string[] = []\n for (const [k, v] of Object.entries(value as Record<string, unknown>)) {\n if (v !== undefined && v !== null) {\n if (typeof v === 'object') {\n // For nested objects, show as JSON\n pairs.push(`${k}=${JSON.stringify(v)}`)\n } else {\n pairs.push(`${k}=${v}`)\n }\n }\n }\n return pairs.join(' ')\n }\n return String(value)\n}\n\nfunction prettyPrintWideEvent(event: Record<string, unknown>): void {\n const { timestamp, level, service, environment, version, ...rest } = event\n const levelColor = getLevelColor(level as string)\n const ts = (timestamp as string).slice(11, 23)\n\n let header = `${colors.dim}${ts}${colors.reset} ${levelColor}${(level as string).toUpperCase()}${colors.reset}`\n header += ` ${colors.cyan}[${service}]${colors.reset}`\n\n if (rest.method && rest.path) {\n header += ` ${rest.method} ${rest.path}`\n delete rest.method\n delete rest.path\n }\n\n if (rest.status) {\n const statusColor = (rest.status as number) >= 400 ? colors.red : colors.green\n header += ` ${statusColor}${rest.status}${colors.reset}`\n delete rest.status\n }\n\n if (rest.duration) {\n header += ` ${colors.dim}in ${rest.duration}${colors.reset}`\n delete rest.duration\n }\n\n console.log(header)\n\n const entries = Object.entries(rest).filter(([_, v]) => v !== undefined)\n const lastIndex = entries.length - 1\n\n entries.forEach(([key, value], index) => {\n const isLast = index === lastIndex\n const prefix = isLast ? '└─' : '├─'\n const formatted = formatValue(value)\n console.log(` ${colors.dim}${prefix}${colors.reset} ${colors.cyan}${key}:${colors.reset} ${formatted}`)\n })\n}\n\nfunction createLogMethod(level: LogLevel) {\n return function logMethod(tagOrEvent: string | Record<string, unknown>, message?: string): void {\n if (typeof tagOrEvent === 'string' && message !== undefined) {\n emitTaggedLog(level, tagOrEvent, message)\n } else if (typeof tagOrEvent === 'object') {\n emitWideEvent(level, tagOrEvent)\n } else {\n emitTaggedLog(level, 'log', String(tagOrEvent))\n }\n }\n}\n\n/**\n * Simple logging API - as easy as console.log\n *\n * @example\n * ```ts\n * log.info('auth', 'User logged in')\n * log.error({ action: 'payment', error: 'failed' })\n * ```\n */\nconst _log: Log = {\n info: createLogMethod('info'),\n error: createLogMethod('error'),\n warn: createLogMethod('warn'),\n debug: createLogMethod('debug'),\n}\n\nexport { _log as log }\n\nconst noopLogger: RequestLogger = {\n set() {},\n error() {},\n info() {},\n warn() {},\n emit() {\n return null\n },\n getContext() {\n return {}\n },\n}\n\n/**\n * Create a request-scoped logger for building wide events.\n *\n * @example\n * ```ts\n * const log = createRequestLogger({ method: 'POST', path: '/checkout' })\n * log.set({ user: { id: '123' } })\n * log.set({ cart: { items: 3 } })\n * log.emit()\n * ```\n */\nexport function createRequestLogger<T extends object = Record<string, unknown>>(options: RequestLoggerOptions = {}): RequestLogger<T> {\n if (!globalEnabled) return noopLogger as RequestLogger<T>\n\n const startTime = Date.now()\n let context: Record<string, unknown> = {\n method: options.method,\n path: options.path,\n requestId: options.requestId,\n }\n let hasError = false\n let hasWarn = false\n\n function addRequestLog(level: 'info' | 'warn', message: string): void {\n const entry = {\n level,\n message,\n timestamp: new Date().toISOString(),\n }\n\n const requestLogs = Array.isArray(context.requestLogs)\n ? [...context.requestLogs, entry]\n : [entry]\n\n context = {\n ...context,\n requestLogs,\n }\n }\n\n return {\n set(data: FieldContext<T>): void {\n context = deepDefaults(data as Record<string, unknown>, context) as Record<string, unknown>\n },\n\n error(error: Error | string, errorContext?: FieldContext<T>): void {\n hasError = true\n const err = typeof error === 'string' ? new Error(error) : error\n\n const errorData = {\n ...(errorContext as Record<string, unknown>),\n error: {\n name: err.name,\n message: err.message,\n stack: err.stack,\n ...('status' in err && { status: (err as Record<string, unknown>).status }),\n ...('statusText' in err && { statusText: (err as Record<string, unknown>).statusText }),\n ...('statusCode' in err && { statusCode: (err as Record<string, unknown>).statusCode }),\n ...('statusMessage' in err && { statusMessage: (err as Record<string, unknown>).statusMessage }),\n ...('data' in err && { data: (err as Record<string, unknown>).data }),\n ...('cause' in err && { cause: (err as unknown as Record<string, unknown>).cause }),\n },\n }\n context = deepDefaults(errorData, context) as Record<string, unknown>\n },\n\n info(message: string, infoContext?: FieldContext<T>): void {\n addRequestLog('info', message)\n if (infoContext) {\n const { requestLogs: _, ...rest } = infoContext as Record<string, unknown>\n context = deepDefaults(rest, context) as Record<string, unknown>\n }\n },\n\n warn(message: string, warnContext?: FieldContext<T>): void {\n hasWarn = true\n addRequestLog('warn', message)\n if (warnContext) {\n const { requestLogs: _, ...rest } = warnContext as Record<string, unknown>\n context = deepDefaults(rest, context) as Record<string, unknown>\n }\n },\n\n emit(overrides?: FieldContext<T> & { _forceKeep?: boolean }): WideEvent | null {\n const durationMs = Date.now() - startTime\n const duration = formatDuration(durationMs)\n const level: LogLevel = hasError ? 'error' : hasWarn ? 'warn' : 'info'\n\n // Extract _forceKeep from overrides (set by evlog:emit:keep hook)\n const { _forceKeep, ...restOverrides } = (overrides ?? {}) as Record<string, unknown> & { _forceKeep?: boolean }\n\n // Build tail sampling context\n const tailCtx: TailSamplingContext = {\n status: (context.status ?? restOverrides.status) as number | undefined,\n duration: durationMs,\n path: context.path as string | undefined,\n method: context.method as string | undefined,\n context: { ...context, ...restOverrides },\n }\n\n // Tail sampling: force keep if hook or built-in conditions match\n const forceKeep = _forceKeep || shouldKeep(tailCtx)\n\n // Apply head sampling only if not force-kept\n if (!forceKeep && !shouldSample(level)) {\n return null\n }\n\n return emitWideEvent(level, {\n ...context,\n ...restOverrides,\n duration,\n }, true)\n },\n\n getContext(): FieldContext<T> & Record<string, unknown> {\n return { ...context }\n },\n }\n}\n\n/**\n * Get the current environment context.\n */\nexport function getEnvironment(): EnvironmentContext {\n return { ...globalEnv }\n}\n","import { createRequestLogger, initLogger } from 'evlog'\n\n/**\n * Log level for the Stack logger.\n *\n * Configured via the `STASH_STACK_LOG` environment variable.\n *\n * - `'error'` — Only errors (default when `STASH_STACK_LOG` is not set).\n * - `'info'` — Info and errors.\n * - `'debug'` — Debug, info, and errors.\n */\nexport type LogLevel = 'debug' | 'info' | 'error'\n\nconst validLevels: readonly LogLevel[] = ['debug', 'info', 'error'] as const\n\nfunction levelFromEnv(): LogLevel {\n const env = process.env.STASH_STACK_LOG\n if (env && validLevels.includes(env as LogLevel)) return env as LogLevel\n return 'error'\n}\n\nfunction samplingRatesForLevel(level: LogLevel): Record<string, number> {\n // evlog uses sampling rates: 100 = always emit, 0 = never emit\n switch (level) {\n case 'debug':\n return { debug: 100, info: 100, warn: 100, error: 100 }\n case 'info':\n return { debug: 0, info: 100, warn: 100, error: 100 }\n case 'error':\n default:\n return { debug: 0, info: 0, warn: 0, error: 100 }\n }\n}\n\nlet initialized = false\n\n/**\n * Initialize the Stack logger.\n *\n * The log level is read from the `STASH_STACK_LOG` environment variable.\n * When the variable is not set, the default is `'error'` (errors only).\n *\n * @internal\n */\nexport function initStackLogger(): void {\n if (initialized) return\n initialized = true\n\n const level = levelFromEnv()\n const rates = samplingRatesForLevel(level)\n\n initLogger({\n env: { service: '@cipherstash/stack' },\n enabled: true,\n sampling: { rates },\n })\n}\n\n// Auto-init with defaults on first import\ninitStackLogger()\n\nexport { createRequestLogger }\n\n// Stringify only the first arg (the message string); drop subsequent args\n// which may contain sensitive objects (e.g. encryptConfig, plaintext).\nfunction safeMessage(args: unknown[]): string {\n return typeof args[0] === 'string' ? args[0] : ''\n}\n\n// Logger for simple one-off logs used across Stack interfaces.\nexport const logger = {\n debug(...args: unknown[]) {\n const log = createRequestLogger()\n log.set({\n level: 'debug',\n source: '@cipherstash/stack',\n message: safeMessage(args),\n })\n log.emit()\n },\n info(...args: unknown[]) {\n const log = createRequestLogger()\n log.set({ source: '@cipherstash/stack' })\n log.info(safeMessage(args))\n log.emit()\n },\n warn(...args: unknown[]) {\n const log = createRequestLogger()\n log.warn(safeMessage(args))\n log.emit()\n },\n error(...args: unknown[]) {\n const log = createRequestLogger()\n log.error(safeMessage(args))\n log.emit()\n },\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../node_modules/.pnpm/evlog@1.11.0_next@15.5.18_react-dom@19.2.3_react@19.2.3__react@19.2.3__react@19.2.3/node_modules/evlog/src/utils.ts","../../../node_modules/.pnpm/evlog@1.11.0_next@15.5.18_react-dom@19.2.3_react@19.2.3__react@19.2.3__react@19.2.3/node_modules/evlog/src/logger.ts","../src/utils/logger/index.ts"],"sourcesContent":["import type { EnvironmentContext, LogLevel } from './types'\n\nexport function formatDuration(ms: number): string {\n if (ms < 1000) {\n return `${Math.round(ms)}ms`\n }\n return `${(ms / 1000).toFixed(2)}s`\n}\n\nexport function isServer(): boolean {\n return typeof window === 'undefined'\n}\n\nexport function isClient(): boolean {\n return typeof window !== 'undefined'\n}\n\nexport function isDev(): boolean {\n if (typeof process !== 'undefined') {\n return process.env.NODE_ENV !== 'production'\n }\n if (typeof window !== 'undefined') {\n return true\n }\n return false\n}\n\nexport function detectEnvironment(): Partial<EnvironmentContext> {\n const env = typeof process !== 'undefined' ? process.env : {}\n const defaultEnvironment = isDev() ? 'development' : 'production'\n\n return {\n environment: env.NODE_ENV || defaultEnvironment,\n service: env.SERVICE_NAME || 'app',\n version: env.APP_VERSION,\n commitHash: env.COMMIT_SHA\n || env.GITHUB_SHA\n || env.VERCEL_GIT_COMMIT_SHA\n || env.CF_PAGES_COMMIT_SHA,\n region: env.VERCEL_REGION\n || env.AWS_REGION\n || env.FLY_REGION\n || env.CF_REGION,\n }\n}\n\nexport function getConsoleMethod(level: LogLevel): LogLevel {\n return level\n}\n\nexport const colors = {\n reset: '\\x1B[0m',\n bold: '\\x1B[1m',\n dim: '\\x1B[2m',\n red: '\\x1B[31m',\n green: '\\x1B[32m',\n yellow: '\\x1B[33m',\n blue: '\\x1B[34m',\n magenta: '\\x1B[35m',\n cyan: '\\x1B[36m',\n white: '\\x1B[37m',\n gray: '\\x1B[90m',\n} as const\n\nexport function getLevelColor(level: string): string {\n switch (level) {\n case 'error':\n return colors.red\n case 'warn':\n return colors.yellow\n case 'info':\n return colors.cyan\n case 'debug':\n return colors.gray\n default:\n return colors.white\n }\n}\n\n/** Headers that should never be passed to hooks for security */\nexport const SENSITIVE_HEADERS = [\n 'authorization',\n 'cookie',\n 'set-cookie',\n 'x-api-key',\n 'x-auth-token',\n 'proxy-authorization',\n]\n\nexport function filterSafeHeaders(headers: Record<string, string>): Record<string, string> {\n const safeHeaders: Record<string, string> = {}\n\n for (const [key, value] of Object.entries(headers)) {\n if (!SENSITIVE_HEADERS.includes(key.toLowerCase())) {\n safeHeaders[key] = value\n }\n }\n\n return safeHeaders\n}\n\n/**\n * Match a path against a glob pattern.\n * Supports * (any chars except /) and ** (any chars including /).\n */\nexport function matchesPattern(path: string, pattern: string): boolean {\n const regexPattern = pattern\n .replace(/[.+^${}()|[\\]\\\\]/g, '\\\\$&') // Escape special regex chars except * and ?\n .replace(/\\*\\*/g, '{{GLOBSTAR}}') // Temp placeholder for **\n .replace(/\\*/g, '[^/]*') // * matches anything except /\n .replace(/{{GLOBSTAR}}/g, '.*') // ** matches anything including /\n .replace(/\\?/g, '[^/]') // ? matches single char except /\n\n const regex = new RegExp(`^${regexPattern}$`)\n return regex.test(path)\n}\n","import type { DrainContext, EnvironmentContext, FieldContext, Log, LogLevel, LoggerConfig, RequestLogger, RequestLoggerOptions, SamplingConfig, TailSamplingContext, WideEvent } from './types'\nimport { colors, detectEnvironment, formatDuration, getConsoleMethod, getLevelColor, isDev, matchesPattern } from './utils'\n\nfunction isPlainObject(val: unknown): val is Record<string, unknown> {\n return val !== null && typeof val === 'object' && !Array.isArray(val)\n}\n\nfunction deepDefaults(base: Record<string, unknown>, defaults: Record<string, unknown>): Record<string, unknown> {\n const result = { ...base }\n for (const key in defaults) {\n const baseVal = result[key]\n const defaultVal = defaults[key]\n if (baseVal === undefined || baseVal === null) {\n result[key] = defaultVal\n } else if (isPlainObject(baseVal) && isPlainObject(defaultVal)) {\n result[key] = deepDefaults(baseVal, defaultVal)\n }\n }\n return result\n}\n\nlet globalEnv: EnvironmentContext = {\n service: 'app',\n environment: 'development',\n}\n\nlet globalPretty = isDev()\nlet globalSampling: SamplingConfig = {}\nlet globalStringify = true\nlet globalDrain: ((ctx: DrainContext) => void | Promise<void>) | undefined\nlet globalEnabled = true\n\n/**\n * Initialize the logger with configuration.\n * Call this once at application startup.\n */\nexport function initLogger(config: LoggerConfig = {}): void {\n globalEnabled = config.enabled ?? true\n const detected = detectEnvironment()\n\n globalEnv = {\n service: config.env?.service ?? detected.service ?? 'app',\n environment: config.env?.environment ?? detected.environment ?? 'development',\n version: config.env?.version ?? detected.version,\n commitHash: config.env?.commitHash ?? detected.commitHash,\n region: config.env?.region ?? detected.region,\n }\n\n globalPretty = config.pretty ?? isDev()\n globalSampling = config.sampling ?? {}\n globalStringify = config.stringify ?? true\n globalDrain = config.drain\n}\n\n/**\n * Check if logging is globally enabled.\n */\nexport function isEnabled(): boolean {\n return globalEnabled\n}\n\n/**\n * Determine if a log at the given level should be emitted based on sampling config.\n * Error level defaults to 100% (always logged) unless explicitly configured otherwise.\n */\nfunction shouldSample(level: LogLevel): boolean {\n const { rates } = globalSampling\n if (!rates) {\n return true // No sampling configured, log everything\n }\n\n // Error defaults to 100% unless explicitly set\n const percentage = level === 'error' && rates.error === undefined\n ? 100\n : rates[level] ?? 100\n\n // 0% = never log, 100% = always log\n if (percentage <= 0) return false\n if (percentage >= 100) return true\n\n return Math.random() * 100 < percentage\n}\n\n/**\n * Evaluate tail sampling conditions to determine if a log should be force-kept.\n * Returns true if ANY condition matches (OR logic).\n */\nexport function shouldKeep(ctx: TailSamplingContext): boolean {\n const { keep } = globalSampling\n if (!keep?.length) return false\n\n return keep.some((condition) => {\n if (condition.status !== undefined && ctx.status !== undefined && ctx.status >= condition.status) {\n return true\n }\n if (condition.duration !== undefined && ctx.duration !== undefined && ctx.duration >= condition.duration) {\n return true\n }\n if (condition.path && ctx.path && matchesPattern(ctx.path, condition.path)) {\n return true\n }\n return false\n })\n}\n\nfunction emitWideEvent(level: LogLevel, event: Record<string, unknown>, skipSamplingCheck = false): WideEvent | null {\n if (!globalEnabled) return null\n\n if (!skipSamplingCheck && !shouldSample(level)) {\n return null\n }\n\n const formatted: WideEvent = {\n timestamp: new Date().toISOString(),\n level,\n ...globalEnv,\n ...event,\n }\n\n if (globalPretty) {\n prettyPrintWideEvent(formatted)\n } else if (globalStringify) {\n console[getConsoleMethod(level)](JSON.stringify(formatted))\n } else {\n console[getConsoleMethod(level)](formatted)\n }\n\n if (globalDrain) {\n Promise.resolve(globalDrain({ event: formatted })).catch((err) => {\n console.error('[evlog] drain failed:', err)\n })\n }\n\n return formatted\n}\n\nfunction emitTaggedLog(level: LogLevel, tag: string, message: string): void {\n if (!globalEnabled) return\n\n if (globalPretty) {\n if (!shouldSample(level)) {\n return\n }\n const color = getLevelColor(level)\n const timestamp = new Date().toISOString().slice(11, 23)\n console.log(`${colors.dim}${timestamp}${colors.reset} ${color}[${tag}]${colors.reset} ${message}`)\n return\n }\n emitWideEvent(level, { tag, message })\n}\n\nfunction formatValue(value: unknown): string {\n if (value === null || value === undefined) {\n return String(value)\n }\n if (typeof value === 'object') {\n // Flatten object to key=value pairs\n const pairs: string[] = []\n for (const [k, v] of Object.entries(value as Record<string, unknown>)) {\n if (v !== undefined && v !== null) {\n if (typeof v === 'object') {\n // For nested objects, show as JSON\n pairs.push(`${k}=${JSON.stringify(v)}`)\n } else {\n pairs.push(`${k}=${v}`)\n }\n }\n }\n return pairs.join(' ')\n }\n return String(value)\n}\n\nfunction prettyPrintWideEvent(event: Record<string, unknown>): void {\n const { timestamp, level, service, environment, version, ...rest } = event\n const levelColor = getLevelColor(level as string)\n const ts = (timestamp as string).slice(11, 23)\n\n let header = `${colors.dim}${ts}${colors.reset} ${levelColor}${(level as string).toUpperCase()}${colors.reset}`\n header += ` ${colors.cyan}[${service}]${colors.reset}`\n\n if (rest.method && rest.path) {\n header += ` ${rest.method} ${rest.path}`\n delete rest.method\n delete rest.path\n }\n\n if (rest.status) {\n const statusColor = (rest.status as number) >= 400 ? colors.red : colors.green\n header += ` ${statusColor}${rest.status}${colors.reset}`\n delete rest.status\n }\n\n if (rest.duration) {\n header += ` ${colors.dim}in ${rest.duration}${colors.reset}`\n delete rest.duration\n }\n\n console.log(header)\n\n const entries = Object.entries(rest).filter(([_, v]) => v !== undefined)\n const lastIndex = entries.length - 1\n\n entries.forEach(([key, value], index) => {\n const isLast = index === lastIndex\n const prefix = isLast ? '└─' : '├─'\n const formatted = formatValue(value)\n console.log(` ${colors.dim}${prefix}${colors.reset} ${colors.cyan}${key}:${colors.reset} ${formatted}`)\n })\n}\n\nfunction createLogMethod(level: LogLevel) {\n return function logMethod(tagOrEvent: string | Record<string, unknown>, message?: string): void {\n if (typeof tagOrEvent === 'string' && message !== undefined) {\n emitTaggedLog(level, tagOrEvent, message)\n } else if (typeof tagOrEvent === 'object') {\n emitWideEvent(level, tagOrEvent)\n } else {\n emitTaggedLog(level, 'log', String(tagOrEvent))\n }\n }\n}\n\n/**\n * Simple logging API - as easy as console.log\n *\n * @example\n * ```ts\n * log.info('auth', 'User logged in')\n * log.error({ action: 'payment', error: 'failed' })\n * ```\n */\nconst _log: Log = {\n info: createLogMethod('info'),\n error: createLogMethod('error'),\n warn: createLogMethod('warn'),\n debug: createLogMethod('debug'),\n}\n\nexport { _log as log }\n\nconst noopLogger: RequestLogger = {\n set() {},\n error() {},\n info() {},\n warn() {},\n emit() {\n return null\n },\n getContext() {\n return {}\n },\n}\n\n/**\n * Create a request-scoped logger for building wide events.\n *\n * @example\n * ```ts\n * const log = createRequestLogger({ method: 'POST', path: '/checkout' })\n * log.set({ user: { id: '123' } })\n * log.set({ cart: { items: 3 } })\n * log.emit()\n * ```\n */\nexport function createRequestLogger<T extends object = Record<string, unknown>>(options: RequestLoggerOptions = {}): RequestLogger<T> {\n if (!globalEnabled) return noopLogger as RequestLogger<T>\n\n const startTime = Date.now()\n let context: Record<string, unknown> = {\n method: options.method,\n path: options.path,\n requestId: options.requestId,\n }\n let hasError = false\n let hasWarn = false\n\n function addRequestLog(level: 'info' | 'warn', message: string): void {\n const entry = {\n level,\n message,\n timestamp: new Date().toISOString(),\n }\n\n const requestLogs = Array.isArray(context.requestLogs)\n ? [...context.requestLogs, entry]\n : [entry]\n\n context = {\n ...context,\n requestLogs,\n }\n }\n\n return {\n set(data: FieldContext<T>): void {\n context = deepDefaults(data as Record<string, unknown>, context) as Record<string, unknown>\n },\n\n error(error: Error | string, errorContext?: FieldContext<T>): void {\n hasError = true\n const err = typeof error === 'string' ? new Error(error) : error\n\n const errorData = {\n ...(errorContext as Record<string, unknown>),\n error: {\n name: err.name,\n message: err.message,\n stack: err.stack,\n ...('status' in err && { status: (err as Record<string, unknown>).status }),\n ...('statusText' in err && { statusText: (err as Record<string, unknown>).statusText }),\n ...('statusCode' in err && { statusCode: (err as Record<string, unknown>).statusCode }),\n ...('statusMessage' in err && { statusMessage: (err as Record<string, unknown>).statusMessage }),\n ...('data' in err && { data: (err as Record<string, unknown>).data }),\n ...('cause' in err && { cause: (err as unknown as Record<string, unknown>).cause }),\n },\n }\n context = deepDefaults(errorData, context) as Record<string, unknown>\n },\n\n info(message: string, infoContext?: FieldContext<T>): void {\n addRequestLog('info', message)\n if (infoContext) {\n const { requestLogs: _, ...rest } = infoContext as Record<string, unknown>\n context = deepDefaults(rest, context) as Record<string, unknown>\n }\n },\n\n warn(message: string, warnContext?: FieldContext<T>): void {\n hasWarn = true\n addRequestLog('warn', message)\n if (warnContext) {\n const { requestLogs: _, ...rest } = warnContext as Record<string, unknown>\n context = deepDefaults(rest, context) as Record<string, unknown>\n }\n },\n\n emit(overrides?: FieldContext<T> & { _forceKeep?: boolean }): WideEvent | null {\n const durationMs = Date.now() - startTime\n const duration = formatDuration(durationMs)\n const level: LogLevel = hasError ? 'error' : hasWarn ? 'warn' : 'info'\n\n // Extract _forceKeep from overrides (set by evlog:emit:keep hook)\n const { _forceKeep, ...restOverrides } = (overrides ?? {}) as Record<string, unknown> & { _forceKeep?: boolean }\n\n // Build tail sampling context\n const tailCtx: TailSamplingContext = {\n status: (context.status ?? restOverrides.status) as number | undefined,\n duration: durationMs,\n path: context.path as string | undefined,\n method: context.method as string | undefined,\n context: { ...context, ...restOverrides },\n }\n\n // Tail sampling: force keep if hook or built-in conditions match\n const forceKeep = _forceKeep || shouldKeep(tailCtx)\n\n // Apply head sampling only if not force-kept\n if (!forceKeep && !shouldSample(level)) {\n return null\n }\n\n return emitWideEvent(level, {\n ...context,\n ...restOverrides,\n duration,\n }, true)\n },\n\n getContext(): FieldContext<T> & Record<string, unknown> {\n return { ...context }\n },\n }\n}\n\n/**\n * Get the current environment context.\n */\nexport function getEnvironment(): EnvironmentContext {\n return { ...globalEnv }\n}\n","import { createRequestLogger, initLogger } from 'evlog'\n\n/**\n * Log level for the Stack logger.\n *\n * Configured via the `STASH_STACK_LOG` environment variable.\n *\n * - `'error'` — Only errors (default when `STASH_STACK_LOG` is not set).\n * - `'info'` — Info and errors.\n * - `'debug'` — Debug, info, and errors.\n */\nexport type LogLevel = 'debug' | 'info' | 'error'\n\nconst validLevels: readonly LogLevel[] = ['debug', 'info', 'error'] as const\n\nfunction levelFromEnv(): LogLevel {\n const env = process.env.STASH_STACK_LOG\n if (env && validLevels.includes(env as LogLevel)) return env as LogLevel\n return 'error'\n}\n\nfunction samplingRatesForLevel(level: LogLevel): Record<string, number> {\n // evlog uses sampling rates: 100 = always emit, 0 = never emit\n switch (level) {\n case 'debug':\n return { debug: 100, info: 100, warn: 100, error: 100 }\n case 'info':\n return { debug: 0, info: 100, warn: 100, error: 100 }\n case 'error':\n default:\n return { debug: 0, info: 0, warn: 0, error: 100 }\n }\n}\n\nlet initialized = false\n\n/**\n * Initialize the Stack logger.\n *\n * The log level is read from the `STASH_STACK_LOG` environment variable.\n * When the variable is not set, the default is `'error'` (errors only).\n *\n * @internal\n */\nexport function initStackLogger(): void {\n if (initialized) return\n initialized = true\n\n const level = levelFromEnv()\n const rates = samplingRatesForLevel(level)\n\n initLogger({\n env: { service: '@cipherstash/stack' },\n enabled: true,\n sampling: { rates },\n })\n}\n\n// Auto-init with defaults on first import\ninitStackLogger()\n\nexport { createRequestLogger }\n\n// Stringify only the first arg (the message string); drop subsequent args\n// which may contain sensitive objects (e.g. encryptConfig, plaintext).\nfunction safeMessage(args: unknown[]): string {\n return typeof args[0] === 'string' ? args[0] : ''\n}\n\n// Logger for simple one-off logs used across Stack interfaces.\nexport const logger = {\n debug(...args: unknown[]) {\n const log = createRequestLogger()\n log.set({\n level: 'debug',\n source: '@cipherstash/stack',\n message: safeMessage(args),\n })\n log.emit()\n },\n info(...args: unknown[]) {\n const log = createRequestLogger()\n log.set({ source: '@cipherstash/stack' })\n log.info(safeMessage(args))\n log.emit()\n },\n warn(...args: unknown[]) {\n const log = createRequestLogger()\n log.warn(safeMessage(args))\n log.emit()\n },\n error(...args: unknown[]) {\n const log = createRequestLogger()\n log.error(safeMessage(args))\n log.emit()\n },\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,23 @@
1
+ // src/schema/match-defaults.ts
2
+ function defaultMatchOpts() {
3
+ return {
4
+ tokenizer: { kind: "ngram", token_length: 3 },
5
+ token_filters: [{ kind: "downcase" }],
6
+ k: 6,
7
+ m: 2048,
8
+ include_original: true
9
+ };
10
+ }
11
+ function cloneMatchOpts(opts) {
12
+ return {
13
+ ...opts,
14
+ tokenizer: { ...opts.tokenizer },
15
+ token_filters: opts.token_filters.map((f) => ({ ...f }))
16
+ };
17
+ }
18
+
19
+ export {
20
+ defaultMatchOpts,
21
+ cloneMatchOpts
22
+ };
23
+ //# sourceMappingURL=chunk-IADZCZEA.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/schema/match-defaults.ts"],"sourcesContent":["import type { MatchIndexOpts } from './index'\n\n/**\n * Fully-resolved match-index options: every field present and non-`undefined`.\n *\n * `MatchIndexOpts` (the user-facing tuning input) has all fields optional —\n * each is `.default(...).optional()` in the zod schema, so its inferred type is\n * `T | undefined`. This type pins the BUILT/resolved shape explicitly via\n * `NonNullable<...>`, which states the non-null intent directly and is robust\n * regardless of `Required<>`'s subtle, `exactOptionalPropertyTypes`-dependent\n * stripping semantics.\n */\nexport type BuiltMatchIndexOpts = {\n tokenizer: NonNullable<MatchIndexOpts['tokenizer']>\n token_filters: NonNullable<MatchIndexOpts['token_filters']>\n k: NonNullable<MatchIndexOpts['k']>\n m: NonNullable<MatchIndexOpts['m']>\n include_original: NonNullable<MatchIndexOpts['include_original']>\n}\n\n/**\n * Default match-index parameters — the single source of truth shared by the\n * v2 `freeTextSearch()` builder and the v3 domain builders (note\n * `include_original: true`, which is the v2 builder default rather than the\n * zod-schema default of `false`).\n *\n * This is a FACTORY (not a shared `const`) so every caller gets fresh, unaliased\n * nested objects (`tokenizer`, `token_filters` and the `{ kind: 'downcase' }`\n * inside it). A shared const would be shallow-copied by `{ ...DEFAULT }`, leaving\n * those nested objects aliased across every column — a caller mutating one built\n * config could then corrupt the defaults used by later columns.\n */\nexport function defaultMatchOpts(): BuiltMatchIndexOpts {\n return {\n tokenizer: { kind: 'ngram', token_length: 3 },\n token_filters: [{ kind: 'downcase' }],\n k: 6,\n m: 2048,\n include_original: true,\n }\n}\n\n/**\n * Deep-clone a built match block (`tokenizer` and `token_filters` are its only\n * nested values) so no emitted config or stored builder state ever aliases\n * another's nested objects — a caller mutating one cannot corrupt the other.\n */\nexport function cloneMatchOpts(opts: BuiltMatchIndexOpts): BuiltMatchIndexOpts {\n return {\n ...opts,\n tokenizer: { ...opts.tokenizer },\n token_filters: opts.token_filters.map((f) => ({ ...f })),\n }\n}\n"],"mappings":";AAgCO,SAAS,mBAAwC;AACtD,SAAO;AAAA,IACL,WAAW,EAAE,MAAM,SAAS,cAAc,EAAE;AAAA,IAC5C,eAAe,CAAC,EAAE,MAAM,WAAW,CAAC;AAAA,IACpC,GAAG;AAAA,IACH,GAAG;AAAA,IACH,kBAAkB;AAAA,EACpB;AACF;AAOO,SAAS,eAAe,MAAgD;AAC7E,SAAO;AAAA,IACL,GAAG;AAAA,IACH,WAAW,EAAE,GAAG,KAAK,UAAU;AAAA,IAC/B,eAAe,KAAK,cAAc,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,EAAE;AAAA,EACzD;AACF;","names":[]}
@@ -0,0 +1,209 @@
1
+ import {
2
+ BOOLEAN,
3
+ DATE,
4
+ DATE_EQ,
5
+ DATE_ORD,
6
+ DATE_ORD_ORE,
7
+ DOUBLE,
8
+ DOUBLE_EQ,
9
+ DOUBLE_ORD,
10
+ DOUBLE_ORD_ORE,
11
+ EncryptedBooleanColumn,
12
+ EncryptedDateColumn,
13
+ EncryptedDateEqColumn,
14
+ EncryptedDateOrdColumn,
15
+ EncryptedDateOrdOreColumn,
16
+ EncryptedDoubleColumn,
17
+ EncryptedDoubleEqColumn,
18
+ EncryptedDoubleOrdColumn,
19
+ EncryptedDoubleOrdOreColumn,
20
+ EncryptedIntegerColumn,
21
+ EncryptedIntegerEqColumn,
22
+ EncryptedIntegerOrdColumn,
23
+ EncryptedIntegerOrdOreColumn,
24
+ EncryptedNumericColumn,
25
+ EncryptedNumericEqColumn,
26
+ EncryptedNumericOrdColumn,
27
+ EncryptedNumericOrdOreColumn,
28
+ EncryptedRealColumn,
29
+ EncryptedRealEqColumn,
30
+ EncryptedRealOrdColumn,
31
+ EncryptedRealOrdOreColumn,
32
+ EncryptedSmallintColumn,
33
+ EncryptedSmallintEqColumn,
34
+ EncryptedSmallintOrdColumn,
35
+ EncryptedSmallintOrdOreColumn,
36
+ EncryptedTextColumn,
37
+ EncryptedTextEqColumn,
38
+ EncryptedTextMatchColumn,
39
+ EncryptedTextOrdColumn,
40
+ EncryptedTextOrdOreColumn,
41
+ EncryptedTextSearchColumn,
42
+ EncryptedTimestampColumn,
43
+ EncryptedTimestampEqColumn,
44
+ EncryptedTimestampOrdColumn,
45
+ EncryptedTimestampOrdOreColumn,
46
+ INTEGER,
47
+ INTEGER_EQ,
48
+ INTEGER_ORD,
49
+ INTEGER_ORD_ORE,
50
+ NUMERIC,
51
+ NUMERIC_EQ,
52
+ NUMERIC_ORD,
53
+ NUMERIC_ORD_ORE,
54
+ REAL,
55
+ REAL_EQ,
56
+ REAL_ORD,
57
+ REAL_ORD_ORE,
58
+ SMALLINT,
59
+ SMALLINT_EQ,
60
+ SMALLINT_ORD,
61
+ SMALLINT_ORD_ORE,
62
+ TEXT,
63
+ TEXT_EQ,
64
+ TEXT_MATCH,
65
+ TEXT_ORD,
66
+ TEXT_ORD_ORE,
67
+ TIMESTAMP,
68
+ TIMESTAMP_EQ,
69
+ TIMESTAMP_ORD,
70
+ TIMESTAMP_ORD_ORE
71
+ } from "./chunk-U66S7VIF.js";
72
+
73
+ // src/eql/v3/table.ts
74
+ var EncryptedTable = class {
75
+ constructor(tableName, columnBuilders) {
76
+ this.tableName = tableName;
77
+ this.columnBuilders = columnBuilders;
78
+ }
79
+ tableName;
80
+ columnBuilders;
81
+ build() {
82
+ const builtColumns = {};
83
+ for (const builder of Object.values(this.columnBuilders)) {
84
+ const name = builder.getName();
85
+ if (Object.hasOwn(builtColumns, name)) {
86
+ throw new Error(
87
+ `[eql/v3]: duplicate column name "${name}" in table "${this.tableName}" \u2014 two columns resolve to the same DB name`
88
+ );
89
+ }
90
+ builtColumns[name] = builder.build();
91
+ }
92
+ return {
93
+ tableName: this.tableName,
94
+ columns: builtColumns
95
+ };
96
+ }
97
+ /**
98
+ * Map each column's JS property name to its DB column name (`getName()`).
99
+ * The model path matches user models by property name but must address the
100
+ * encrypt config and FFI by DB name — `build()` keys columns by DB name, so
101
+ * the two only agree when property == name. This recovers the mapping that
102
+ * `build()` discards.
103
+ */
104
+ buildColumnKeyMap() {
105
+ const map = {};
106
+ for (const [property, builder] of Object.entries(this.columnBuilders)) {
107
+ map[property] = builder.getName();
108
+ }
109
+ return map;
110
+ }
111
+ };
112
+ var RESERVED_TABLE_KEYS = /* @__PURE__ */ new Set([
113
+ "tableName",
114
+ "columnBuilders",
115
+ "_columnType",
116
+ "build",
117
+ "buildColumnKeyMap"
118
+ ]);
119
+ function isReservedTableKey(tableBuilder, colName) {
120
+ return RESERVED_TABLE_KEYS.has(colName) || colName in tableBuilder;
121
+ }
122
+ function encryptedTable(tableName, columns) {
123
+ const tableBuilder = new EncryptedTable(
124
+ tableName,
125
+ columns
126
+ );
127
+ for (const [colName, colBuilder] of Object.entries(columns)) {
128
+ if (isReservedTableKey(tableBuilder, colName)) {
129
+ throw new Error(
130
+ `Column name "${colName}" collides with a reserved EncryptedTable property`
131
+ );
132
+ }
133
+ ;
134
+ tableBuilder[colName] = colBuilder;
135
+ }
136
+ return tableBuilder;
137
+ }
138
+ function buildEncryptConfig(...tables) {
139
+ const config = {
140
+ v: 1,
141
+ tables: {}
142
+ };
143
+ for (const tb of tables) {
144
+ const tableDef = tb.build();
145
+ if (Object.hasOwn(config.tables, tableDef.tableName)) {
146
+ throw new Error(
147
+ `[eql/v3]: duplicate table name "${tableDef.tableName}" passed to buildEncryptConfig \u2014 each table must have a unique name`
148
+ );
149
+ }
150
+ config.tables[tableDef.tableName] = tableDef.columns;
151
+ }
152
+ return config;
153
+ }
154
+
155
+ // src/eql/v3/types.ts
156
+ var types = {
157
+ // integer
158
+ Integer: (name) => new EncryptedIntegerColumn(name, INTEGER),
159
+ IntegerEq: (name) => new EncryptedIntegerEqColumn(name, INTEGER_EQ),
160
+ IntegerOrdOre: (name) => new EncryptedIntegerOrdOreColumn(name, INTEGER_ORD_ORE),
161
+ IntegerOrd: (name) => new EncryptedIntegerOrdColumn(name, INTEGER_ORD),
162
+ // smallint
163
+ Smallint: (name) => new EncryptedSmallintColumn(name, SMALLINT),
164
+ SmallintEq: (name) => new EncryptedSmallintEqColumn(name, SMALLINT_EQ),
165
+ SmallintOrdOre: (name) => new EncryptedSmallintOrdOreColumn(name, SMALLINT_ORD_ORE),
166
+ SmallintOrd: (name) => new EncryptedSmallintOrdColumn(name, SMALLINT_ORD),
167
+ // date
168
+ Date: (name) => new EncryptedDateColumn(name, DATE),
169
+ DateEq: (name) => new EncryptedDateEqColumn(name, DATE_EQ),
170
+ DateOrdOre: (name) => new EncryptedDateOrdOreColumn(name, DATE_ORD_ORE),
171
+ DateOrd: (name) => new EncryptedDateOrdColumn(name, DATE_ORD),
172
+ // timestamp
173
+ Timestamp: (name) => new EncryptedTimestampColumn(name, TIMESTAMP),
174
+ TimestampEq: (name) => new EncryptedTimestampEqColumn(name, TIMESTAMP_EQ),
175
+ TimestampOrdOre: (name) => new EncryptedTimestampOrdOreColumn(name, TIMESTAMP_ORD_ORE),
176
+ TimestampOrd: (name) => new EncryptedTimestampOrdColumn(name, TIMESTAMP_ORD),
177
+ // numeric
178
+ Numeric: (name) => new EncryptedNumericColumn(name, NUMERIC),
179
+ NumericEq: (name) => new EncryptedNumericEqColumn(name, NUMERIC_EQ),
180
+ NumericOrdOre: (name) => new EncryptedNumericOrdOreColumn(name, NUMERIC_ORD_ORE),
181
+ NumericOrd: (name) => new EncryptedNumericOrdColumn(name, NUMERIC_ORD),
182
+ // text
183
+ Text: (name) => new EncryptedTextColumn(name, TEXT),
184
+ TextEq: (name) => new EncryptedTextEqColumn(name, TEXT_EQ),
185
+ TextMatch: (name) => new EncryptedTextMatchColumn(name, TEXT_MATCH),
186
+ TextOrdOre: (name) => new EncryptedTextOrdOreColumn(name, TEXT_ORD_ORE),
187
+ TextOrd: (name) => new EncryptedTextOrdColumn(name, TEXT_ORD),
188
+ TextSearch: (name) => new EncryptedTextSearchColumn(name),
189
+ // boolean
190
+ Boolean: (name) => new EncryptedBooleanColumn(name, BOOLEAN),
191
+ // real
192
+ Real: (name) => new EncryptedRealColumn(name, REAL),
193
+ RealEq: (name) => new EncryptedRealEqColumn(name, REAL_EQ),
194
+ RealOrdOre: (name) => new EncryptedRealOrdOreColumn(name, REAL_ORD_ORE),
195
+ RealOrd: (name) => new EncryptedRealOrdColumn(name, REAL_ORD),
196
+ // double
197
+ Double: (name) => new EncryptedDoubleColumn(name, DOUBLE),
198
+ DoubleEq: (name) => new EncryptedDoubleEqColumn(name, DOUBLE_EQ),
199
+ DoubleOrdOre: (name) => new EncryptedDoubleOrdOreColumn(name, DOUBLE_ORD_ORE),
200
+ DoubleOrd: (name) => new EncryptedDoubleOrdColumn(name, DOUBLE_ORD)
201
+ };
202
+
203
+ export {
204
+ EncryptedTable,
205
+ encryptedTable,
206
+ buildEncryptConfig,
207
+ types
208
+ };
209
+ //# sourceMappingURL=chunk-IBSK6P33.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/eql/v3/table.ts","../src/eql/v3/types.ts"],"sourcesContent":["import type { ColumnSchema, EncryptConfig } from '@/schema'\nimport type { Encrypted } from '@/types'\nimport type {\n EncryptedV3TableColumn,\n PlaintextForColumn,\n QueryTypesForColumn,\n} from './columns'\n\ninterface TableDefinition {\n tableName: string\n columns: Record<string, ColumnSchema>\n}\n\n/**\n * A v3 encrypted table. Mirrors the v2 `EncryptedTable` but only accepts v3\n * column builders. Emits the same `{ tableName, columns }` definition shape.\n */\nexport class EncryptedTable<T extends EncryptedV3TableColumn> {\n /** @internal Type-level brand so TypeScript can infer `T` from `EncryptedTable<T>`. */\n declare readonly _columnType: T\n\n constructor(\n public readonly tableName: string,\n public readonly columnBuilders: T,\n ) {}\n\n build(): TableDefinition {\n const builtColumns: Record<string, ColumnSchema> = {}\n for (const builder of Object.values(this.columnBuilders)) {\n // Key by the column's DB name (`getName()`), NOT the JS property name.\n // `encrypt`/`decrypt` look columns up in the config by `column.getName()`,\n // so a camelCase JS key mapping to a snake_case DB column (e.g.\n // `createdOn: types.Date('created_on')`) must register under\n // `created_on` or the FFI reports \"column not found in Encrypt config\".\n const name = builder.getName()\n // Two JS properties resolving to the same DB name would silently overwrite\n // here (later wins), dropping the first column's config. Fail loudly —\n // matching the duplicate-tableName guard in buildEncryptConfig and the\n // reserved-key guard in encryptedTable.\n if (Object.hasOwn(builtColumns, name)) {\n throw new Error(\n `[eql/v3]: duplicate column name \"${name}\" in table \"${this.tableName}\" — two columns resolve to the same DB name`,\n )\n }\n builtColumns[name] = builder.build()\n }\n return {\n tableName: this.tableName,\n columns: builtColumns,\n }\n }\n\n /**\n * Map each column's JS property name to its DB column name (`getName()`).\n * The model path matches user models by property name but must address the\n * encrypt config and FFI by DB name — `build()` keys columns by DB name, so\n * the two only agree when property == name. This recovers the mapping that\n * `build()` discards.\n */\n buildColumnKeyMap(): Record<string, string> {\n const map: Record<string, string> = {}\n for (const [property, builder] of Object.entries(this.columnBuilders)) {\n map[property] = builder.getName()\n }\n return map\n }\n}\n\n/**\n * Own instance members of {@link EncryptedTable} that a column name must not\n * shadow. Because {@link encryptedTable} copies column builders onto the\n * instance for accessor access (`users.email`), a column named e.g. `build`\n * would otherwise overwrite the method that {@link buildEncryptConfig} relies\n * on. `_columnType` is a type-only `declare` (no runtime property) so it is\n * listed explicitly here rather than caught by the `in` check below.\n */\nconst RESERVED_TABLE_KEYS = new Set([\n 'tableName',\n 'columnBuilders',\n '_columnType',\n 'build',\n 'buildColumnKeyMap',\n])\n\n/**\n * Whether a column name would collide with a reserved property on the table\n * object — either an own member ({@link RESERVED_TABLE_KEYS}) or any inherited\n * `Object.prototype` member (`constructor`, `toString`, `valueOf`,\n * `hasOwnProperty`, …). The `in` check covers the prototype chain so assigning\n * the column as an own property can never shadow a prototype method/accessor.\n */\nfunction isReservedTableKey(tableBuilder: object, colName: string): boolean {\n return RESERVED_TABLE_KEYS.has(colName) || colName in tableBuilder\n}\n\n/**\n * Define a v3 encrypted table. Intentionally shadows the v2 `encryptedTable`\n * name but lives on the `/eql/v3` subpath — the importer picks the model by\n * import path. The returned object is also a column accessor (`users.email`).\n */\nexport function encryptedTable<T extends EncryptedV3TableColumn>(\n tableName: string,\n columns: T,\n): EncryptedTable<T> & T {\n const tableBuilder = new EncryptedTable(\n tableName,\n columns,\n ) as EncryptedTable<T> & T\n\n for (const [colName, colBuilder] of Object.entries(columns)) {\n if (isReservedTableKey(tableBuilder, colName)) {\n throw new Error(\n `Column name \"${colName}\" collides with a reserved EncryptedTable property`,\n )\n }\n ;(tableBuilder as EncryptedV3TableColumn)[colName] = colBuilder\n }\n\n return tableBuilder\n}\n\n/**\n * Build an `EncryptConfig` (`v: 1`) from one or more v3 tables. Emits the same\n * shape as v2's `buildEncryptConfig`.\n */\nexport function buildEncryptConfig(\n ...tables: Array<EncryptedTable<EncryptedV3TableColumn>>\n): EncryptConfig {\n const config: EncryptConfig = {\n v: 1,\n tables: {},\n }\n\n for (const tb of tables) {\n const tableDef = tb.build()\n // Config tables are keyed by name, so a duplicate would silently overwrite\n // the earlier table. Fail loudly instead. (v3-only additive guard; v2's\n // buildEncryptConfig keeps its existing silent-overwrite behavior.)\n if (Object.hasOwn(config.tables, tableDef.tableName)) {\n throw new Error(\n `[eql/v3]: duplicate table name \"${tableDef.tableName}\" passed to buildEncryptConfig — each table must have a unique name`,\n )\n }\n config.tables[tableDef.tableName] = tableDef.columns\n }\n\n return config\n}\n\n/**\n * Infer the plaintext (decrypted) shape from a v3 table schema. Each column maps\n * to the TypeScript type of its domain's `castAs` kind.\n */\nexport type InferPlaintext<T extends EncryptedTable<EncryptedV3TableColumn>> =\n T extends EncryptedTable<infer C>\n ? { [K in keyof C]: PlaintextForColumn<C[K]> }\n : never\n\n/**\n * Infer the encrypted shape from a v3 table schema. See {@link InferPlaintext}\n * for why no key-remap filter is needed in the flat single-type model.\n */\nexport type InferEncrypted<T extends EncryptedTable<EncryptedV3TableColumn>> =\n T extends EncryptedTable<infer C> ? { [K in keyof C]: Encrypted } : never\n\n// ---------------------------------------------------------------------------\n// Typed-client surface helpers (@cipherstash/stack/v3)\n// ---------------------------------------------------------------------------\n\n/** Any v3 table, regardless of its column map. */\nexport type AnyV3Table = EncryptedTable<EncryptedV3TableColumn>\n\n/** Union of the concrete column builders declared on a v3 table. */\nexport type ColumnsOf<T extends AnyV3Table> =\n T extends EncryptedTable<infer C> ? C[keyof C] : never\n\n/**\n * Union of the *queryable* column builders on a v3 table. Storage-only columns\n * (whose {@link QueryTypesForColumn} is `never`) are filtered out, so they can't\n * be passed to a query method.\n */\nexport type QueryableColumnsOf<T extends AnyV3Table> =\n T extends EncryptedTable<infer C>\n ? {\n [K in keyof C]: [QueryTypesForColumn<C[K]>] extends [never]\n ? never\n : C[K]\n }[keyof C]\n : never\n\n/**\n * The accepted input model for {@link import('@/encryption/v3').TypedEncryptionClient.encryptModel}.\n * `T` is inferred from the argument: keys that name a schema column are pinned to\n * the column's plaintext type (nullable if the field is nullable), so a wrong-typed\n * field fails assignability; all other keys pass through unchanged.\n */\nexport type V3ModelInput<Table extends AnyV3Table, T> = {\n [K in keyof T]: K extends keyof InferPlaintext<Table>\n ? null extends T[K]\n ? InferPlaintext<Table>[K] | null\n : InferPlaintext<Table>[K]\n : T[K]\n}\n\n/** The encrypted result model: schema columns become `Encrypted`, others pass through. */\nexport type V3EncryptedModel<Table extends AnyV3Table, T> = {\n [K in keyof T]: K extends keyof InferPlaintext<Table>\n ? null extends T[K]\n ? Encrypted | null\n : Encrypted\n : T[K]\n}\n\n/** The decrypted result model: schema columns become their plaintext type, others pass through. */\nexport type V3DecryptedModel<Table extends AnyV3Table, T> = {\n [K in keyof T]: K extends keyof InferPlaintext<Table>\n ? null extends T[K]\n ? InferPlaintext<Table>[K] | null\n : InferPlaintext<Table>[K]\n : T[K]\n}\n","import {\n BOOLEAN,\n DATE,\n DATE_EQ,\n DATE_ORD,\n DATE_ORD_ORE,\n EncryptedBooleanColumn,\n EncryptedDateColumn,\n EncryptedDateEqColumn,\n EncryptedDateOrdColumn,\n EncryptedDateOrdOreColumn,\n EncryptedRealColumn,\n EncryptedRealEqColumn,\n EncryptedRealOrdColumn,\n EncryptedRealOrdOreColumn,\n EncryptedDoubleColumn,\n EncryptedDoubleEqColumn,\n EncryptedDoubleOrdColumn,\n EncryptedDoubleOrdOreColumn,\n EncryptedSmallintColumn,\n EncryptedSmallintEqColumn,\n EncryptedSmallintOrdColumn,\n EncryptedSmallintOrdOreColumn,\n EncryptedIntegerColumn,\n EncryptedIntegerEqColumn,\n EncryptedIntegerOrdColumn,\n EncryptedIntegerOrdOreColumn,\n EncryptedNumericColumn,\n EncryptedNumericEqColumn,\n EncryptedNumericOrdColumn,\n EncryptedNumericOrdOreColumn,\n EncryptedTextColumn,\n EncryptedTextEqColumn,\n EncryptedTextMatchColumn,\n EncryptedTextOrdColumn,\n EncryptedTextOrdOreColumn,\n EncryptedTextSearchColumn,\n EncryptedTimestampColumn,\n EncryptedTimestampEqColumn,\n EncryptedTimestampOrdColumn,\n EncryptedTimestampOrdOreColumn,\n REAL,\n REAL_EQ,\n REAL_ORD,\n REAL_ORD_ORE,\n DOUBLE,\n DOUBLE_EQ,\n DOUBLE_ORD,\n DOUBLE_ORD_ORE,\n SMALLINT,\n SMALLINT_EQ,\n SMALLINT_ORD,\n SMALLINT_ORD_ORE,\n INTEGER,\n INTEGER_EQ,\n INTEGER_ORD,\n INTEGER_ORD_ORE,\n NUMERIC,\n NUMERIC_EQ,\n NUMERIC_ORD,\n NUMERIC_ORD_ORE,\n TEXT,\n TEXT_EQ,\n TEXT_MATCH,\n TEXT_ORD,\n TEXT_ORD_ORE,\n TIMESTAMP,\n TIMESTAMP_EQ,\n TIMESTAMP_ORD,\n TIMESTAMP_ORD_ORE,\n} from './columns'\n\n/**\n * The v3 column-type namespace. Each member is a factory that builds a concrete\n * EQL v3 column; the member name mirrors the underlying `eql_v3.<name>` domain\n * (strip the `eql_v3.` prefix, PascalCase each `_`-separated segment). So\n * `types.TextEq('actor')` builds an `eql_v3.text_eq` column, `types.IntegerOrd`\n * an `eql_v3.integer_ord`, `types.Timestamp` an `eql_v3.timestamp`, and so on.\n *\n * Each factory returns the CONCRETE column class instance (never the widened\n * `AnyEncryptedV3Column`) so per-column plaintext / query-capability inference\n * stays precise.\n *\n * ```ts\n * import { encryptedTable, types } from '@cipherstash/stack/eql/v3'\n *\n * const events = encryptedTable('events', {\n * actor: types.TextEq('actor'), // equality\n * weight: types.IntegerOrd('weight'), // order + range\n * createdAt: types.Timestamp('created_at'), // storage only\n * })\n * ```\n *\n * `types.TextSearch` keeps the chainable `.freeTextSearch(opts)` tuner (the\n * only capability-bearing chain — every other domain is fully described by its\n * type). bigint domains are intentionally absent pending lossless FFI\n * round-tripping (see ./columns).\n */\nexport const types = {\n // integer\n Integer: (name: string) => new EncryptedIntegerColumn(name, INTEGER),\n IntegerEq: (name: string) => new EncryptedIntegerEqColumn(name, INTEGER_EQ),\n IntegerOrdOre: (name: string) =>\n new EncryptedIntegerOrdOreColumn(name, INTEGER_ORD_ORE),\n IntegerOrd: (name: string) =>\n new EncryptedIntegerOrdColumn(name, INTEGER_ORD),\n\n // smallint\n Smallint: (name: string) => new EncryptedSmallintColumn(name, SMALLINT),\n SmallintEq: (name: string) =>\n new EncryptedSmallintEqColumn(name, SMALLINT_EQ),\n SmallintOrdOre: (name: string) =>\n new EncryptedSmallintOrdOreColumn(name, SMALLINT_ORD_ORE),\n SmallintOrd: (name: string) =>\n new EncryptedSmallintOrdColumn(name, SMALLINT_ORD),\n\n // date\n Date: (name: string) => new EncryptedDateColumn(name, DATE),\n DateEq: (name: string) => new EncryptedDateEqColumn(name, DATE_EQ),\n DateOrdOre: (name: string) =>\n new EncryptedDateOrdOreColumn(name, DATE_ORD_ORE),\n DateOrd: (name: string) => new EncryptedDateOrdColumn(name, DATE_ORD),\n\n // timestamp\n Timestamp: (name: string) => new EncryptedTimestampColumn(name, TIMESTAMP),\n TimestampEq: (name: string) =>\n new EncryptedTimestampEqColumn(name, TIMESTAMP_EQ),\n TimestampOrdOre: (name: string) =>\n new EncryptedTimestampOrdOreColumn(name, TIMESTAMP_ORD_ORE),\n TimestampOrd: (name: string) =>\n new EncryptedTimestampOrdColumn(name, TIMESTAMP_ORD),\n\n // numeric\n Numeric: (name: string) => new EncryptedNumericColumn(name, NUMERIC),\n NumericEq: (name: string) => new EncryptedNumericEqColumn(name, NUMERIC_EQ),\n NumericOrdOre: (name: string) =>\n new EncryptedNumericOrdOreColumn(name, NUMERIC_ORD_ORE),\n NumericOrd: (name: string) =>\n new EncryptedNumericOrdColumn(name, NUMERIC_ORD),\n\n // text\n Text: (name: string) => new EncryptedTextColumn(name, TEXT),\n TextEq: (name: string) => new EncryptedTextEqColumn(name, TEXT_EQ),\n TextMatch: (name: string) => new EncryptedTextMatchColumn(name, TEXT_MATCH),\n TextOrdOre: (name: string) =>\n new EncryptedTextOrdOreColumn(name, TEXT_ORD_ORE),\n TextOrd: (name: string) => new EncryptedTextOrdColumn(name, TEXT_ORD),\n TextSearch: (name: string) => new EncryptedTextSearchColumn(name),\n\n // boolean\n Boolean: (name: string) => new EncryptedBooleanColumn(name, BOOLEAN),\n\n // real\n Real: (name: string) => new EncryptedRealColumn(name, REAL),\n RealEq: (name: string) => new EncryptedRealEqColumn(name, REAL_EQ),\n RealOrdOre: (name: string) =>\n new EncryptedRealOrdOreColumn(name, REAL_ORD_ORE),\n RealOrd: (name: string) => new EncryptedRealOrdColumn(name, REAL_ORD),\n\n // double\n Double: (name: string) => new EncryptedDoubleColumn(name, DOUBLE),\n DoubleEq: (name: string) => new EncryptedDoubleEqColumn(name, DOUBLE_EQ),\n DoubleOrdOre: (name: string) =>\n new EncryptedDoubleOrdOreColumn(name, DOUBLE_ORD_ORE),\n DoubleOrd: (name: string) => new EncryptedDoubleOrdColumn(name, DOUBLE_ORD),\n} as const\n"],"mappings":"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","names":[]}
@@ -0,0 +1,17 @@
1
+ // ../../node_modules/.pnpm/@byteslice+result@0.2.0/node_modules/@byteslice/result/dist/result.mjs
2
+ function ensureError(ex) {
3
+ return ex instanceof Error ? ex : new Error("Something went wrong");
4
+ }
5
+ async function withResult(operation, onError, hooks) {
6
+ try {
7
+ return { data: await operation() };
8
+ } catch (ex) {
9
+ const error = hooks?.onException?.(ex) ?? ensureError(ex);
10
+ return { failure: onError(error) };
11
+ }
12
+ }
13
+
14
+ export {
15
+ withResult
16
+ };
17
+ //# sourceMappingURL=chunk-JSG2AMDI.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../node_modules/.pnpm/@byteslice+result@0.2.0/node_modules/@byteslice/result/dist/result.mjs"],"sourcesContent":["// src/result.ts\nfunction ensureError(ex) {\n return ex instanceof Error ? ex : new Error(\"Something went wrong\");\n}\nasync function withResult(operation, onError, hooks) {\n try {\n return { data: await operation() };\n } catch (ex) {\n const error = hooks?.onException?.(ex) ?? ensureError(ex);\n return { failure: onError(error) };\n }\n}\nexport {\n withResult\n};\n"],"mappings":";AACA,SAAS,YAAY,IAAI;AACvB,SAAO,cAAc,QAAQ,KAAK,IAAI,MAAM,sBAAsB;AACpE;AACA,eAAe,WAAW,WAAW,SAAS,OAAO;AACnD,MAAI;AACF,WAAO,EAAE,MAAM,MAAM,UAAU,EAAE;AAAA,EACnC,SAAS,IAAI;AACX,UAAM,QAAQ,OAAO,cAAc,EAAE,KAAK,YAAY,EAAE;AACxD,WAAO,EAAE,SAAS,QAAQ,KAAK,EAAE;AAAA,EACnC;AACF;","names":[]}