@cipherstash/stack 0.18.0 → 1.0.0-rc.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 (111) hide show
  1. package/CHANGELOG.md +704 -0
  2. package/README.md +97 -79
  3. package/dist/adapter-kit.cjs +923 -0
  4. package/dist/adapter-kit.cjs.map +1 -0
  5. package/dist/adapter-kit.d.cts +82 -0
  6. package/dist/adapter-kit.d.ts +82 -0
  7. package/dist/adapter-kit.js +47 -0
  8. package/dist/adapter-kit.js.map +1 -0
  9. package/dist/base-operation-AOAIvsSB.d.cts +32 -0
  10. package/dist/base-operation-FXEzUXIq.d.ts +32 -0
  11. package/dist/{chunk-VPOTNP4K.js → chunk-3B5ZX3IS.js} +3 -1
  12. package/dist/chunk-3B5ZX3IS.js.map +1 -0
  13. package/dist/chunk-7333ZC6L.js +48 -0
  14. package/dist/chunk-7333ZC6L.js.map +1 -0
  15. package/dist/{chunk-XWPGAHBZ.js → chunk-BNO32ZMV.js} +1 -1
  16. package/dist/chunk-BNO32ZMV.js.map +1 -0
  17. package/dist/chunk-CLM7E4I6.js +4439 -0
  18. package/dist/chunk-CLM7E4I6.js.map +1 -0
  19. package/dist/{chunk-LLCCNKDL.js → chunk-HQANMV7R.js} +3 -3
  20. package/dist/{chunk-LLCCNKDL.js.map → chunk-HQANMV7R.js.map} +1 -1
  21. package/dist/chunk-JSG2AMDI.js +17 -0
  22. package/dist/chunk-JSG2AMDI.js.map +1 -0
  23. package/dist/chunk-OFQ555AX.js +191 -0
  24. package/dist/chunk-OFQ555AX.js.map +1 -0
  25. package/dist/chunk-PZ5AY32C.js +10 -0
  26. package/dist/chunk-PZ5AY32C.js.map +1 -0
  27. package/dist/chunk-V2Q3NYIH.js +494 -0
  28. package/dist/chunk-V2Q3NYIH.js.map +1 -0
  29. package/dist/chunk-X3JRXEIB.js +98 -0
  30. package/dist/chunk-X3JRXEIB.js.map +1 -0
  31. package/dist/{chunk-ZYOZHZMJ.js → chunk-ZTP5QJ27.js} +193 -169
  32. package/dist/chunk-ZTP5QJ27.js.map +1 -0
  33. package/dist/client.cjs +4124 -49
  34. package/dist/client.cjs.map +1 -1
  35. package/dist/client.d.cts +6 -5
  36. package/dist/client.d.ts +6 -5
  37. package/dist/client.js +3 -1
  38. package/dist/columns-D2_YzrCX.d.cts +622 -0
  39. package/dist/columns-rZc7fQHI.d.ts +622 -0
  40. package/dist/dynamodb/index.cjs +19 -12
  41. package/dist/dynamodb/index.cjs.map +1 -1
  42. package/dist/dynamodb/index.d.cts +3 -2
  43. package/dist/dynamodb/index.d.ts +3 -2
  44. package/dist/dynamodb/index.js +8 -10
  45. package/dist/dynamodb/index.js.map +1 -1
  46. package/dist/encryption/index.cjs +4496 -222
  47. package/dist/encryption/index.cjs.map +1 -1
  48. package/dist/encryption/index.d.cts +807 -6
  49. package/dist/encryption/index.d.ts +807 -6
  50. package/dist/encryption/index.js +15 -7
  51. package/dist/encryption/v3.cjs +7896 -0
  52. package/dist/encryption/v3.cjs.map +1 -0
  53. package/dist/encryption/v3.d.cts +103 -0
  54. package/dist/encryption/v3.d.ts +103 -0
  55. package/dist/encryption/v3.js +189 -0
  56. package/dist/encryption/v3.js.map +1 -0
  57. package/dist/eql/v3/index.cjs +663 -0
  58. package/dist/eql/v3/index.cjs.map +1 -0
  59. package/dist/eql/v3/index.d.cts +173 -0
  60. package/dist/eql/v3/index.d.ts +173 -0
  61. package/dist/eql/v3/index.js +99 -0
  62. package/dist/eql/v3/index.js.map +1 -0
  63. package/dist/errors/index.js +1 -0
  64. package/dist/identity/index.cjs +55 -35
  65. package/dist/identity/index.cjs.map +1 -1
  66. package/dist/identity/index.d.cts +54 -30
  67. package/dist/identity/index.d.ts +54 -30
  68. package/dist/identity/index.js +9 -177
  69. package/dist/identity/index.js.map +1 -1
  70. package/dist/index-BquA71_Y.d.ts +24 -0
  71. package/dist/index-fhWTOV0K.d.cts +24 -0
  72. package/dist/index.cjs +4547 -243
  73. package/dist/index.cjs.map +1 -1
  74. package/dist/index.d.cts +18 -19
  75. package/dist/index.d.ts +18 -19
  76. package/dist/index.js +20 -5
  77. package/dist/index.js.map +1 -1
  78. package/dist/schema/index.cjs +4128 -49
  79. package/dist/schema/index.cjs.map +1 -1
  80. package/dist/schema/index.d.cts +1 -1
  81. package/dist/schema/index.d.ts +1 -1
  82. package/dist/schema/index.js +3 -1
  83. package/dist/{types-public-BTxqjmtv.d.cts → types-public-QMjYNfQO.d.cts} +448 -251
  84. package/dist/{types-public-BTxqjmtv.d.ts → types-public-QMjYNfQO.d.ts} +448 -251
  85. package/dist/types-public.cjs.map +1 -1
  86. package/dist/types-public.d.cts +2 -2
  87. package/dist/types-public.d.ts +2 -2
  88. package/dist/types-public.js +2 -1
  89. package/dist/wasm-inline.d.ts +1643 -0
  90. package/dist/wasm-inline.js +4901 -0
  91. package/dist/wasm-inline.js.map +1 -0
  92. package/package.json +74 -52
  93. package/dist/chunk-VPOTNP4K.js.map +0 -1
  94. package/dist/chunk-XWPGAHBZ.js.map +0 -1
  95. package/dist/chunk-YWQXTZ5M.js +0 -383
  96. package/dist/chunk-YWQXTZ5M.js.map +0 -1
  97. package/dist/chunk-ZYOZHZMJ.js.map +0 -1
  98. package/dist/client-CIsfZ2zg.d.ts +0 -692
  99. package/dist/client-Dt98Rugc.d.cts +0 -692
  100. package/dist/drizzle/index.cjs +0 -1558
  101. package/dist/drizzle/index.cjs.map +0 -1
  102. package/dist/drizzle/index.d.cts +0 -358
  103. package/dist/drizzle/index.d.ts +0 -358
  104. package/dist/drizzle/index.js +0 -1215
  105. package/dist/drizzle/index.js.map +0 -1
  106. package/dist/supabase/index.cjs +0 -1526
  107. package/dist/supabase/index.cjs.map +0 -1
  108. package/dist/supabase/index.d.cts +0 -144
  109. package/dist/supabase/index.d.ts +0 -144
  110. package/dist/supabase/index.js +0 -899
  111. package/dist/supabase/index.js.map +0 -1
@@ -1,4 +1,4 @@
1
- // ../../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/dist/utils.mjs
1
+ // ../../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/dist/utils.mjs
2
2
  function formatDuration(ms) {
3
3
  if (ms < 1e3) return `${Math.round(ms)}ms`;
4
4
  return `${(ms / 1e3).toFixed(2)}s`;
@@ -54,7 +54,7 @@ function matchesPattern(path, pattern) {
54
54
  return new RegExp(`^${regexPattern}$`).test(path);
55
55
  }
56
56
 
57
- // ../../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/dist/logger.mjs
57
+ // ../../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/dist/logger.mjs
58
58
  function isPlainObject(val) {
59
59
  return val !== null && typeof val === "object" && !Array.isArray(val);
60
60
  }
@@ -362,4 +362,4 @@ export {
362
362
  createRequestLogger,
363
363
  logger
364
364
  };
365
- //# sourceMappingURL=chunk-LLCCNKDL.js.map
365
+ //# sourceMappingURL=chunk-HQANMV7R.js.map
@@ -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,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":[]}
@@ -0,0 +1,191 @@
1
+ import {
2
+ withResult
3
+ } from "./chunk-JSG2AMDI.js";
4
+ import {
5
+ logger
6
+ } from "./chunk-HQANMV7R.js";
7
+ import {
8
+ EncryptionErrorTypes
9
+ } from "./chunk-LBMC4D6D.js";
10
+
11
+ // src/utils/config/index.ts
12
+ import fs from "fs";
13
+ import path from "path";
14
+ function getWorkspaceCrn(tomlString) {
15
+ let currentSection = "";
16
+ let workspaceCrn;
17
+ const lines = tomlString.split(/\r?\n/);
18
+ for (const line of lines) {
19
+ const trimmedLine = line.trim();
20
+ if (!trimmedLine || trimmedLine.startsWith("#")) {
21
+ continue;
22
+ }
23
+ const sectionMatch = trimmedLine.match(/^\[([^\]]+)\]$/);
24
+ if (sectionMatch) {
25
+ currentSection = sectionMatch[1];
26
+ continue;
27
+ }
28
+ const kvMatch = trimmedLine.match(/^(\w+)\s*=\s*"([^"]+)"$/);
29
+ if (kvMatch) {
30
+ const [_, key, value] = kvMatch;
31
+ if (currentSection === "auth" && key === "workspace_crn") {
32
+ workspaceCrn = value;
33
+ break;
34
+ }
35
+ }
36
+ }
37
+ return workspaceCrn;
38
+ }
39
+ function extractWorkspaceIdFromCrn(crn) {
40
+ const match = crn.match(/crn:[^:]+:([^:]+)$/);
41
+ if (!match) {
42
+ throw new Error("Invalid CRN format");
43
+ }
44
+ return match[1];
45
+ }
46
+ function loadWorkSpaceId(suppliedCrn) {
47
+ const configPath = path.join(process.cwd(), "cipherstash.toml");
48
+ if (suppliedCrn) {
49
+ return extractWorkspaceIdFromCrn(suppliedCrn);
50
+ }
51
+ if (!fs.existsSync(configPath) && !process.env.CS_WORKSPACE_CRN) {
52
+ throw new Error(
53
+ "You have not defined a workspace CRN in your config file, or the CS_WORKSPACE_CRN environment variable."
54
+ );
55
+ }
56
+ if (process.env.CS_WORKSPACE_CRN) {
57
+ return extractWorkspaceIdFromCrn(process.env.CS_WORKSPACE_CRN);
58
+ }
59
+ if (!fs.existsSync(configPath)) {
60
+ throw new Error(
61
+ "You have not defined a workspace CRN in your config file, or the CS_WORKSPACE_CRN environment variable."
62
+ );
63
+ }
64
+ const tomlString = fs.readFileSync(configPath, "utf8");
65
+ const workspaceCrn = getWorkspaceCrn(tomlString);
66
+ if (!workspaceCrn) {
67
+ throw new Error(
68
+ "You have not defined a workspace CRN in your config file, or the CS_WORKSPACE_CRN environment variable."
69
+ );
70
+ }
71
+ return extractWorkspaceIdFromCrn(workspaceCrn);
72
+ }
73
+
74
+ // src/identity/index.ts
75
+ function resolveLockContext(input) {
76
+ return input instanceof LockContext || "identityContext" in input ? input.identityContext : input;
77
+ }
78
+ var LockContext = class {
79
+ ctsToken;
80
+ workspaceId;
81
+ context;
82
+ constructor({
83
+ context = { identityClaim: ["sub"] },
84
+ ctsToken
85
+ } = {}) {
86
+ const workspaceId = loadWorkSpaceId();
87
+ if (!workspaceId) {
88
+ throw new Error(
89
+ "You have not defined a workspace ID in your config file, or the CS_WORKSPACE_CRN environment variable."
90
+ );
91
+ }
92
+ if (ctsToken) {
93
+ this.ctsToken = ctsToken;
94
+ }
95
+ this.workspaceId = workspaceId;
96
+ this.context = context;
97
+ logger.debug("Successfully initialized the EQL lock context.");
98
+ }
99
+ /**
100
+ * The identity-claim context this lock context binds to, e.g.
101
+ * `{ identityClaim: ['sub'] }`. Resolved synchronously — `.withLockContext()`
102
+ * uses this directly; no CTS token is required.
103
+ */
104
+ get identityContext() {
105
+ return this.context;
106
+ }
107
+ /**
108
+ * Exchange a user's JWT for a CTS token and bind it to this lock context.
109
+ *
110
+ * @deprecated Per-operation CTS tokens were removed in protect-ffi 0.25.
111
+ * Authenticate the client as the user with an `OidcFederationStrategy`
112
+ * (`config.authStrategy`) instead, and pass the claim to `.withLockContext()`.
113
+ * The token fetched here is no longer used by encryption operations. This
114
+ * method is kept for backwards compatibility and will be removed in a
115
+ * future major release.
116
+ *
117
+ * @param jwtToken - A valid OIDC / JWT token for the current user.
118
+ * @returns A `Result` containing this `LockContext` or an error.
119
+ */
120
+ async identify(jwtToken) {
121
+ const workspaceId = this.workspaceId;
122
+ const ctsEndpoint = process.env.CS_CTS_ENDPOINT || "https://ap-southeast-2.aws.auth.viturhosted.net";
123
+ const ctsFetchResult = await withResult(
124
+ () => fetch(`${ctsEndpoint}/api/authorize`, {
125
+ method: "POST",
126
+ headers: {
127
+ "Content-Type": "application/json"
128
+ },
129
+ body: JSON.stringify({
130
+ workspaceId,
131
+ oidcToken: jwtToken
132
+ })
133
+ }),
134
+ (error) => ({
135
+ type: EncryptionErrorTypes.CtsTokenError,
136
+ message: error.message
137
+ })
138
+ );
139
+ if (ctsFetchResult.failure) {
140
+ return ctsFetchResult;
141
+ }
142
+ const identifiedLockContext = await withResult(
143
+ async () => {
144
+ const ctsToken = await ctsFetchResult.data.json();
145
+ if (!ctsToken.accessToken) {
146
+ throw new Error(
147
+ "The response from the CipherStash API did not contain an access token. Please contact support."
148
+ );
149
+ }
150
+ this.ctsToken = ctsToken;
151
+ return this;
152
+ },
153
+ (error) => ({
154
+ type: EncryptionErrorTypes.CtsTokenError,
155
+ message: error.message
156
+ })
157
+ );
158
+ return identifiedLockContext;
159
+ }
160
+ /**
161
+ * Retrieve the identity context (and CTS token, if one was set).
162
+ *
163
+ * @deprecated Encryption operations no longer consume a CTS token — they read
164
+ * the identity claim directly via {@link identityContext}. Pass the claim to
165
+ * `.withLockContext()` and authenticate the client with an
166
+ * `OidcFederationStrategy` instead. Kept for backwards compatibility; the
167
+ * returned `ctsToken` is `undefined` unless one was supplied to the
168
+ * constructor or {@link identify} was called.
169
+ */
170
+ getLockContext() {
171
+ return withResult(
172
+ () => ({
173
+ context: this.context,
174
+ // Only include `ctsToken` when one was actually set, so the
175
+ // returned shape matches the optional `ctsToken?` type rather
176
+ // than carrying an explicit `undefined`.
177
+ ...this.ctsToken ? { ctsToken: this.ctsToken } : {}
178
+ }),
179
+ (error) => ({
180
+ type: EncryptionErrorTypes.CtsTokenError,
181
+ message: error.message
182
+ })
183
+ );
184
+ }
185
+ };
186
+
187
+ export {
188
+ resolveLockContext,
189
+ LockContext
190
+ };
191
+ //# sourceMappingURL=chunk-OFQ555AX.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils/config/index.ts","../src/identity/index.ts"],"sourcesContent":["import fs from 'node:fs'\nimport path from 'node:path'\n\n/**\n * A lightweight function that parses a TOML-like string\n * and returns the `workspace_crn` value found under `[auth]`.\n *\n * @param tomlString The contents of the TOML file as a string.\n * @returns The workspace_crn if found, otherwise undefined.\n */\nfunction getWorkspaceCrn(tomlString: string): string | undefined {\n let currentSection = ''\n let workspaceCrn: string | undefined\n\n const lines = tomlString.split(/\\r?\\n/)\n\n for (const line of lines) {\n const trimmedLine = line.trim()\n\n if (!trimmedLine || trimmedLine.startsWith('#')) {\n continue\n }\n\n const sectionMatch = trimmedLine.match(/^\\[([^\\]]+)\\]$/)\n if (sectionMatch) {\n currentSection = sectionMatch[1]\n continue\n }\n\n const kvMatch = trimmedLine.match(/^(\\w+)\\s*=\\s*\"([^\"]+)\"$/)\n if (kvMatch) {\n const [_, key, value] = kvMatch\n\n if (currentSection === 'auth' && key === 'workspace_crn') {\n workspaceCrn = value\n break\n }\n }\n }\n\n return workspaceCrn\n}\n\n/**\n * Extracts the workspace ID from a CRN string.\n * CRN format: crn:region.aws:ID\n *\n * @param crn The CRN string to extract from\n * @returns The workspace ID portion of the CRN\n */\nexport function extractWorkspaceIdFromCrn(crn: string): string {\n const match = crn.match(/crn:[^:]+:([^:]+)$/)\n if (!match) {\n throw new Error('Invalid CRN format')\n }\n return match[1]\n}\n\nexport function loadWorkSpaceId(suppliedCrn?: string): string {\n const configPath = path.join(process.cwd(), 'cipherstash.toml')\n\n if (suppliedCrn) {\n return extractWorkspaceIdFromCrn(suppliedCrn)\n }\n\n if (!fs.existsSync(configPath) && !process.env.CS_WORKSPACE_CRN) {\n throw new Error(\n 'You have not defined a workspace CRN in your config file, or the CS_WORKSPACE_CRN environment variable.',\n )\n }\n\n // Environment variables take precedence over config files\n if (process.env.CS_WORKSPACE_CRN) {\n return extractWorkspaceIdFromCrn(process.env.CS_WORKSPACE_CRN)\n }\n\n if (!fs.existsSync(configPath)) {\n throw new Error(\n 'You have not defined a workspace CRN in your config file, or the CS_WORKSPACE_CRN environment variable.',\n )\n }\n\n const tomlString = fs.readFileSync(configPath, 'utf8')\n const workspaceCrn = getWorkspaceCrn(tomlString)\n\n if (!workspaceCrn) {\n throw new Error(\n 'You have not defined a workspace CRN in your config file, or the CS_WORKSPACE_CRN environment variable.',\n )\n }\n\n return extractWorkspaceIdFromCrn(workspaceCrn)\n}\n","import { type Result, withResult } from '@byteslice/result'\nimport { type EncryptionError, EncryptionErrorTypes } from '@/errors'\nimport { loadWorkSpaceId } from '@/utils/config'\nimport { logger } from '@/utils/logger'\n\nexport type CtsRegions = 'ap-southeast-2'\n\nexport type IdentifyOptions = {\n fetchFromCts?: boolean\n}\n\nexport type CtsToken = {\n accessToken: string\n expiry: number\n}\n\nexport type Context = {\n identityClaim: string[]\n}\n\nexport type LockContextOptions = {\n context?: Context\n ctsToken?: CtsToken\n}\n\nexport type GetLockContextResponse = {\n ctsToken?: CtsToken\n context: Context\n}\n\n/**\n * The accepted argument to `.withLockContext()` — either a {@link LockContext}\n * or a plain identity-claim spec (e.g. `{ identityClaim: ['sub'] }`).\n */\nexport type LockContextInput = LockContext | Context\n\n/**\n * Resolve a {@link LockContextInput} to the {@link Context} (identity claim)\n * that protect-ffi expects. Synchronous — no token round-trip.\n */\nexport function resolveLockContext(input: LockContextInput): Context {\n // Use a structural check as well as `instanceof` so a `LockContext`\n // constructed in another realm (or from a duplicate module instance) is still\n // resolved rather than slipping through as a raw `Context`.\n return input instanceof LockContext || 'identityContext' in input\n ? (input as LockContext).identityContext\n : input\n}\n\n/**\n * Binds an encryption/decryption operation to a user's identity by selecting\n * which JWT claim(s) ZeroKMS bakes into the data key's tag (the *lock context*).\n *\n * The claim **value** is resolved by ZeroKMS from the token that authenticates\n * the request — so to bind to a real end user, authenticate the client as that\n * user with an `OidcFederationStrategy` (from `@cipherstash/auth`) and pass the\n * claim to `.withLockContext()`. The same context must be supplied to decrypt.\n *\n * You can pass a plain `{ identityClaim }` directly — constructing a\n * `LockContext` is optional.\n *\n * @example\n * ```typescript\n * import { Encryption } from \"@cipherstash/stack\"\n * import { OidcFederationStrategy } from \"@cipherstash/auth\"\n *\n * // Authenticate the client as the end user (replaces the old identify() flow).\n * const client = await Encryption({\n * schemas,\n * config: {\n * authStrategy: OidcFederationStrategy.create(workspaceCrn, () => getJwt()),\n * },\n * })\n *\n * // Bind the key to the user's `sub` claim — no token, no identify().\n * const result = await client\n * .encrypt(value, { column: users.email, table: users })\n * .withLockContext({ identityClaim: [\"sub\"] })\n * ```\n */\nexport class LockContext {\n private ctsToken: CtsToken | undefined\n private workspaceId: string\n private context: Context\n\n constructor({\n context = { identityClaim: ['sub'] },\n ctsToken,\n }: LockContextOptions = {}) {\n const workspaceId = loadWorkSpaceId()\n\n if (!workspaceId) {\n throw new Error(\n 'You have not defined a workspace ID in your config file, or the CS_WORKSPACE_CRN environment variable.',\n )\n }\n\n if (ctsToken) {\n this.ctsToken = ctsToken\n }\n\n this.workspaceId = workspaceId\n this.context = context\n logger.debug('Successfully initialized the EQL lock context.')\n }\n\n /**\n * The identity-claim context this lock context binds to, e.g.\n * `{ identityClaim: ['sub'] }`. Resolved synchronously — `.withLockContext()`\n * uses this directly; no CTS token is required.\n */\n get identityContext(): Context {\n return this.context\n }\n\n /**\n * Exchange a user's JWT for a CTS token and bind it to this lock context.\n *\n * @deprecated Per-operation CTS tokens were removed in protect-ffi 0.25.\n * Authenticate the client as the user with an `OidcFederationStrategy`\n * (`config.authStrategy`) instead, and pass the claim to `.withLockContext()`.\n * The token fetched here is no longer used by encryption operations. This\n * method is kept for backwards compatibility and will be removed in a\n * future major release.\n *\n * @param jwtToken - A valid OIDC / JWT token for the current user.\n * @returns A `Result` containing this `LockContext` or an error.\n */\n async identify(\n jwtToken: string,\n ): Promise<Result<LockContext, EncryptionError>> {\n const workspaceId = this.workspaceId\n\n const ctsEndpoint =\n process.env.CS_CTS_ENDPOINT ||\n 'https://ap-southeast-2.aws.auth.viturhosted.net'\n\n const ctsFetchResult = await withResult(\n () =>\n fetch(`${ctsEndpoint}/api/authorize`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n workspaceId,\n oidcToken: jwtToken,\n }),\n }),\n (error) => ({\n type: EncryptionErrorTypes.CtsTokenError,\n message: error.message,\n }),\n )\n\n if (ctsFetchResult.failure) {\n return ctsFetchResult\n }\n\n const identifiedLockContext = await withResult(\n async () => {\n const ctsToken = (await ctsFetchResult.data.json()) as CtsToken\n\n if (!ctsToken.accessToken) {\n throw new Error(\n 'The response from the CipherStash API did not contain an access token. Please contact support.',\n )\n }\n\n this.ctsToken = ctsToken\n return this\n },\n (error) => ({\n type: EncryptionErrorTypes.CtsTokenError,\n message: error.message,\n }),\n )\n\n return identifiedLockContext\n }\n\n /**\n * Retrieve the identity context (and CTS token, if one was set).\n *\n * @deprecated Encryption operations no longer consume a CTS token — they read\n * the identity claim directly via {@link identityContext}. Pass the claim to\n * `.withLockContext()` and authenticate the client with an\n * `OidcFederationStrategy` instead. Kept for backwards compatibility; the\n * returned `ctsToken` is `undefined` unless one was supplied to the\n * constructor or {@link identify} was called.\n */\n getLockContext(): Promise<Result<GetLockContextResponse, EncryptionError>> {\n return withResult(\n () => ({\n context: this.context,\n // Only include `ctsToken` when one was actually set, so the\n // returned shape matches the optional `ctsToken?` type rather\n // than carrying an explicit `undefined`.\n ...(this.ctsToken ? { ctsToken: this.ctsToken } : {}),\n }),\n (error) => ({\n type: EncryptionErrorTypes.CtsTokenError,\n message: error.message,\n }),\n )\n }\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,10 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __export = (target, all) => {
3
+ for (var name in all)
4
+ __defProp(target, name, { get: all[name], enumerable: true });
5
+ };
6
+
7
+ export {
8
+ __export
9
+ };
10
+ //# sourceMappingURL=chunk-PZ5AY32C.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}