{"version":3,"sources":["../src/index.ts","../src/ffi/index.ts","../../utils/logger/index.ts","../src/helpers/jsonb.ts","../src/helpers/index.ts","../src/ffi/helpers/type-guards.ts","../src/ffi/operations/batch-encrypt-query.ts","../src/ffi/helpers/error-code.ts","../src/types.ts","../src/ffi/helpers/infer-index-type.ts","../src/ffi/helpers/validation.ts","../src/ffi/operations/base-operation.ts","../src/ffi/operations/bulk-decrypt.ts","../src/ffi/operations/bulk-decrypt-models.ts","../src/ffi/model-helpers.ts","../src/ffi/operations/bulk-encrypt.ts","../src/ffi/operations/bulk-encrypt-models.ts","../src/ffi/operations/decrypt.ts","../src/ffi/operations/decrypt-model.ts","../src/ffi/operations/deprecated/search-terms.ts","../src/ffi/operations/encrypt.ts","../src/ffi/operations/encrypt-model.ts","../src/ffi/operations/encrypt-query.ts","../src/identify/index.ts","../../utils/config/index.ts"],"sourcesContent":["import type { ProtectTable, ProtectTableColumn } from '@cipherstash/schema'\nimport { buildEncryptConfig } from '@cipherstash/schema'\nimport { ProtectClient } from './ffi'\nimport type { KeysetIdentifier } from './types'\n\n// Re-export FFI error types for programmatic error handling\nexport {\n  ProtectError as FfiProtectError,\n  type ProtectErrorCode,\n} from '@cipherstash/protect-ffi'\n\nexport const ProtectErrorTypes = {\n  ClientInitError: 'ClientInitError',\n  EncryptionError: 'EncryptionError',\n  DecryptionError: 'DecryptionError',\n  LockContextError: 'LockContextError',\n  CtsTokenError: 'CtsTokenError',\n}\n\nexport interface ProtectError {\n  type: (typeof ProtectErrorTypes)[keyof typeof ProtectErrorTypes]\n  message: string\n  code?: import('@cipherstash/protect-ffi').ProtectErrorCode\n}\n\ntype AtLeastOneCsTable<T> = [T, ...T[]]\n\nexport type ProtectClientConfig = {\n  schemas: AtLeastOneCsTable<ProtectTable<ProtectTableColumn>>\n\n  /**\n   * The CipherStash workspace CRN (Cloud Resource Name).\n   * Format: `crn:<region>.aws:<workspace-id>`.\n   * Can also be set via the `CS_WORKSPACE_CRN` environment variable.\n   */\n  workspaceCrn?: string\n\n  /**\n   * The API access key used for authenticating with the CipherStash API.\n   * Can also be set via the `CS_CLIENT_ACCESS_KEY` environment variable.\n   * Obtain this from the CipherStash dashboard after creating a workspace.\n   */\n  accessKey?: string\n\n  /**\n   * The client identifier used to authenticate with CipherStash services.\n   * Can also be set via the `CS_CLIENT_ID` environment variable.\n   * Generated during workspace onboarding in the CipherStash dashboard.\n   */\n  clientId?: string\n\n  /**\n   * The client key material used in combination with ZeroKMS for encryption operations.\n   * Can also be set via the `CS_CLIENT_KEY` environment variable.\n   * Generated during workspace onboarding in the CipherStash dashboard.\n   */\n  clientKey?: string\n\n  /**\n   * An optional keyset identifier for multi-tenant encryption.\n   * Each keyset provides cryptographic isolation, giving each tenant its own keyspace.\n   * Specify by name (`{ name: \"tenant-a\" }`) or UUID (`{ id: \"...\" }`).\n   * Keysets are created and managed in the CipherStash dashboard.\n   */\n  keyset?: KeysetIdentifier\n}\n\nfunction isValidUuid(uuid: string): boolean {\n  const uuidRegex =\n    /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i\n  return uuidRegex.test(uuid)\n}\n\n/* Initialize a Protect client with the provided configuration.\n\n  @param config - The configuration object for initializing the Protect client.\n\n  @see {@link ProtectClientConfig} for details on the configuration options.\n\n  @returns A Promise that resolves to an instance of ProtectClient.\n\n  @throws Will throw an error if no schemas are provided or if the keyset ID is not a valid UUID.\n*/\nexport const protect = async (\n  config: ProtectClientConfig,\n): Promise<ProtectClient> => {\n  const { schemas } = config\n\n  if (!schemas.length) {\n    throw new Error(\n      '[protect]: At least one csTable must be provided to initialize the protect client',\n    )\n  }\n\n  if (\n    config.keyset &&\n    'id' in config.keyset &&\n    !isValidUuid(config.keyset.id)\n  ) {\n    throw new Error(\n      '[protect]: Invalid UUID provided for keyset id. Must be a valid UUID.',\n    )\n  }\n\n  const clientConfig = {\n    workspaceCrn: config.workspaceCrn,\n    accessKey: config.accessKey,\n    clientId: config.clientId,\n    clientKey: config.clientKey,\n    keyset: config.keyset,\n  }\n\n  const client = new ProtectClient()\n  const encryptConfig = buildEncryptConfig(...schemas)\n\n  const result = await client.init({\n    encryptConfig,\n    ...clientConfig,\n  })\n\n  if (result.failure) {\n    throw new Error(`[protect]: ${result.failure.message}`)\n  }\n\n  return result.data\n}\n\nexport type { Result } from '@byteslice/result'\nexport type { ProtectClient } from './ffi'\nexport type { ProtectOperation } from './ffi/operations/base-operation'\nexport type { BulkEncryptOperation } from './ffi/operations/bulk-encrypt'\nexport type { BulkDecryptOperation } from './ffi/operations/bulk-decrypt'\nexport type { BulkEncryptModelsOperation } from './ffi/operations/bulk-encrypt-models'\nexport type { BulkDecryptModelsOperation } from './ffi/operations/bulk-decrypt-models'\nexport type { DecryptOperation } from './ffi/operations/decrypt'\nexport type { DecryptModelOperation } from './ffi/operations/decrypt-model'\nexport type { EncryptModelOperation } from './ffi/operations/encrypt-model'\nexport type { EncryptOperation } from './ffi/operations/encrypt'\n\n// Operations\nexport {\n  EncryptQueryOperation,\n  EncryptQueryOperationWithLockContext,\n} from './ffi/operations/encrypt-query'\nexport {\n  BatchEncryptQueryOperation,\n  BatchEncryptQueryOperationWithLockContext,\n} from './ffi/operations/batch-encrypt-query'\n\n// Helpers\nexport {\n  inferIndexType,\n  validateIndexType,\n} from './ffi/helpers/infer-index-type'\n\n// Types\nexport type {\n  QueryTypeName,\n  FfiIndexTypeName,\n  EncryptQueryOptions,\n  ScalarQueryTerm,\n} from './types'\n\nexport { queryTypes, queryTypeToFfi } from './types'\n\nexport { csTable, csColumn, csValue } from '@cipherstash/schema'\nexport type {\n  ProtectColumn,\n  ProtectTable,\n  ProtectTableColumn,\n  ProtectValue,\n} from '@cipherstash/schema'\n// LockContext class export (value export for instantiation)\nexport { LockContext } from './identify'\n\n// LockContext related type exports\nexport type {\n  CtsRegions,\n  IdentifyOptions,\n  CtsToken,\n  Context,\n  LockContextOptions,\n  GetLockContextResponse,\n} from './identify'\nexport * from './helpers'\nexport * from './types'\n","import { type Result, withResult } from '@byteslice/result'\nimport { type JsPlaintext, newClient } from '@cipherstash/protect-ffi'\nimport {\n  type EncryptConfig,\n  type ProtectTable,\n  type ProtectTableColumn,\n  encryptConfigSchema,\n} from '@cipherstash/schema'\nimport { type ProtectError, ProtectErrorTypes } from '..'\nimport { logger } from '../../../utils/logger'\nimport { toFfiKeysetIdentifier } from '../helpers'\nimport type {\n  BulkDecryptPayload,\n  BulkEncryptPayload,\n  Client,\n  Decrypted,\n  EncryptOptions,\n  EncryptQueryOptions,\n  Encrypted,\n  KeysetIdentifier,\n  ScalarQueryTerm,\n  SearchTerm,\n} from '../types'\nimport { isScalarQueryTermArray } from './helpers/type-guards'\nimport { BatchEncryptQueryOperation } from './operations/batch-encrypt-query'\nimport { BulkDecryptOperation } from './operations/bulk-decrypt'\nimport { BulkDecryptModelsOperation } from './operations/bulk-decrypt-models'\nimport { BulkEncryptOperation } from './operations/bulk-encrypt'\nimport { BulkEncryptModelsOperation } from './operations/bulk-encrypt-models'\nimport { DecryptOperation } from './operations/decrypt'\nimport { DecryptModelOperation } from './operations/decrypt-model'\nimport { SearchTermsOperation } from './operations/deprecated/search-terms'\nimport { EncryptOperation } from './operations/encrypt'\nimport { EncryptModelOperation } from './operations/encrypt-model'\nimport { EncryptQueryOperation } from './operations/encrypt-query'\n\nexport const noClientError = () =>\n  new Error(\n    'The EQL client has not been initialized. Please call init() before using the client.',\n  )\n\n/** The ProtectClient is the main entry point for interacting with the CipherStash Protect.js library.\n * It provides methods for encrypting and decrypting individual values, as well as models (objects) and bulk operations.\n *\n * The client must be initialized using the {@link protect} function before it can be used.\n */\nexport class ProtectClient {\n  private client: Client\n  private encryptConfig: EncryptConfig | undefined\n\n  /**\n   * Initializes the ProtectClient with the provided configuration.\n   * @internal\n   * @param config - The configuration object for initializing the client.\n   * @returns A promise that resolves to a {@link Result} containing the initialized ProtectClient or a {@link ProtectError}.\n   **/\n  async init(config: {\n    encryptConfig: EncryptConfig\n    workspaceCrn?: string\n    accessKey?: string\n    clientId?: string\n    clientKey?: string\n    keyset?: KeysetIdentifier\n  }): Promise<Result<ProtectClient, ProtectError>> {\n    return await withResult(\n      async () => {\n        const validated: EncryptConfig = encryptConfigSchema.parse(\n          config.encryptConfig,\n        )\n\n        logger.debug(\n          'Initializing the Protect.js client with the following encrypt config:',\n          {\n            encryptConfig: validated,\n          },\n        )\n\n        // newClient handles env var fallback internally via withEnvCredentials,\n        // so we pass config values through without manual fallback here.\n        this.client = await newClient({\n          encryptConfig: validated,\n          clientOpts: {\n            workspaceCrn: config.workspaceCrn,\n            accessKey: config.accessKey,\n            clientId: config.clientId,\n            clientKey: config.clientKey,\n            keyset: toFfiKeysetIdentifier(config.keyset),\n          },\n        })\n\n        this.encryptConfig = validated\n\n        logger.info('Successfully initialized the Protect.js client.')\n        return this\n      },\n      (error: unknown) => ({\n        type: ProtectErrorTypes.ClientInitError,\n        message: (error as Error).message,\n      }),\n    )\n  }\n\n  /**\n   * Encrypt a value - returns a promise which resolves to an encrypted value.\n   *\n   * @param plaintext - The plaintext value to be encrypted. Can be null.\n   * @param opts - Options specifying the column and table for encryption.\n   * @returns An EncryptOperation that can be awaited or chained with additional methods.\n   *\n   * @example\n   * The following example demonstrates how to encrypt a value using the Protect client.\n   * It includes defining an encryption schema with {@link csTable} and {@link csColumn},\n   * initializing the client with {@link protect}, and performing the encryption.\n   *\n   * `encrypt` returns an {@link EncryptOperation} which can be awaited to get a {@link Result}\n   * which can either be the encrypted value or a {@link ProtectError}.\n   *\n   * ```typescript\n   * // Define encryption schema\n   * import { csTable, csColumn } from \"@cipherstash/protect\"\n   * const userSchema = csTable(\"users\", {\n   *  email: csColumn(\"email\"),\n   * });\n   *\n   * // Initialize Protect client\n   * const protectClient = await protect({ schemas: [userSchema] })\n   *\n   * // Encrypt a value\n   * const encryptedResult = await protectClient.encrypt(\n   *  \"person@example.com\",\n   *  { column: userSchema.email, table: userSchema }\n   * )\n   *\n   * // Handle encryption result\n   * if (encryptedResult.failure) {\n   *   throw new Error(`Encryption failed: ${encryptedResult.failure.message}`);\n   * }\n   *\n   * console.log(\"Encrypted data:\", encryptedResult.data);\n   * ```\n   *\n   * @example\n   * When encrypting data, a {@link LockContext} can be provided to tie the encryption to a specific user or session.\n   * This ensures that the same lock context is required for decryption.\n   *\n   * The following example demonstrates how to create a lock context using a user's JWT token\n   * and use it during encryption.\n   *\n   * ```typescript\n   * // Define encryption schema and initialize client as above\n   *\n   * // Create a lock for the user's `sub` claim from their JWT\n   * const lc = new LockContext();\n   * const lockContext = await lc.identify(userJwt);\n   *\n   * if (lockContext.failure) {\n   *   // Handle the failure\n   * }\n   *\n   * // Encrypt a value with the lock context\n   * // Decryption will then require the same lock context\n   * const encryptedResult = await protectClient.encrypt(\n   *  \"person@example.com\",\n   *  { column: userSchema.email, table: userSchema }\n   * )\n   *  .withLockContext(lockContext)\n   * ```\n   *\n   * @see {@link Result}\n   * @see {@link csTable}\n   * @see {@link LockContext}\n   * @see {@link EncryptOperation}\n   */\n  encrypt(\n    plaintext: JsPlaintext | null,\n    opts: EncryptOptions,\n  ): EncryptOperation {\n    return new EncryptOperation(this.client, plaintext, opts)\n  }\n\n  /**\n   * Encrypt a query value - returns a promise which resolves to an encrypted query value.\n   *\n   * @param plaintext - The plaintext value to be encrypted for querying. Can be null.\n   * @param opts - Options specifying the column, table, and optional queryType for encryption.\n   * @returns An EncryptQueryOperation that can be awaited or chained with additional methods.\n   *\n   * @example\n   * The following example demonstrates how to encrypt a query value using the Protect client.\n   *\n   * ```typescript\n   * // Define encryption schema\n   * import { csTable, csColumn } from \"@cipherstash/protect\"\n   * const userSchema = csTable(\"users\", {\n   *  email: csColumn(\"email\").equality(),\n   * });\n   *\n   * // Initialize Protect client\n   * const protectClient = await protect({ schemas: [userSchema] })\n   *\n   * // Encrypt a query value\n   * const encryptedResult = await protectClient.encryptQuery(\n   *  \"person@example.com\",\n   *  { column: userSchema.email, table: userSchema, queryType: 'equality' }\n   * )\n   *\n   * // Handle encryption result\n   * if (encryptedResult.failure) {\n   *   throw new Error(`Encryption failed: ${encryptedResult.failure.message}`);\n   * }\n   *\n   * console.log(\"Encrypted query:\", encryptedResult.data);\n   * ```\n   *\n   * @example\n   * The queryType can be auto-inferred from the column's configured indexes:\n   *\n   * ```typescript\n   * // When queryType is omitted, it will be inferred from the column's indexes\n   * const encryptedResult = await protectClient.encryptQuery(\n   *  \"person@example.com\",\n   *  { column: userSchema.email, table: userSchema }\n   * )\n   * ```\n   *\n   * @see {@link EncryptQueryOperation}\n   *\n   * **JSONB columns (searchableJson):**\n   * When `queryType` is omitted on a `searchableJson()` column, the query operation is inferred:\n   * - String plaintext → `steVecSelector` (JSONPath queries like `'$.user.email'`)\n   * - Object/Array plaintext → `steVecTerm` (containment queries like `{ role: 'admin' }`)\n   */\n  encryptQuery(\n    plaintext: JsPlaintext | null,\n    opts: EncryptQueryOptions,\n  ): EncryptQueryOperation\n\n  /**\n   * Encrypt multiple values for use in queries (batch operation).\n   * @param terms - Array of query terms to encrypt\n   */\n  encryptQuery(terms: readonly ScalarQueryTerm[]): BatchEncryptQueryOperation\n\n  encryptQuery(\n    plaintextOrTerms: JsPlaintext | null | readonly ScalarQueryTerm[],\n    opts?: EncryptQueryOptions,\n  ): EncryptQueryOperation | BatchEncryptQueryOperation {\n    // Discriminate between ScalarQueryTerm[] and JsPlaintext (which can also be an array)\n    // using a type guard function\n    if (isScalarQueryTermArray(plaintextOrTerms)) {\n      return new BatchEncryptQueryOperation(this.client, plaintextOrTerms)\n    }\n\n    // Handle empty arrays: if opts provided, treat as single value; otherwise batch mode\n    // This maintains backward compatibility for encryptQuery([]) while allowing\n    // encryptQuery([], opts) to encrypt an empty array as a single value\n    if (\n      Array.isArray(plaintextOrTerms) &&\n      plaintextOrTerms.length === 0 &&\n      !opts\n    ) {\n      return new BatchEncryptQueryOperation(\n        this.client,\n        [] as readonly ScalarQueryTerm[],\n      )\n    }\n\n    return new EncryptQueryOperation(\n      this.client,\n      plaintextOrTerms as JsPlaintext | null,\n      opts!,\n    )\n  }\n\n  /**\n   * Decryption - returns a promise which resolves to a decrypted value.\n   *\n   * @param encryptedData - The encrypted data to be decrypted.\n   * @returns A DecryptOperation that can be awaited or chained with additional methods.\n   *\n   * @example\n   * The following example demonstrates how to decrypt a value that was previously encrypted using {@link encrypt} client.\n   * It includes encrypting a value first, then decrypting it, and handling the result.\n   *\n   * ```typescript\n   * const encryptedData = await eqlClient.encrypt(\n   *  \"person@example.com\",\n   *  { column: \"email\", table: \"users\" }\n   * )\n   * const decryptResult = await eqlClient.decrypt(encryptedData)\n   * if (decryptResult.failure) {\n   *   throw new Error(`Decryption failed: ${decryptResult.failure.message}`);\n   * }\n   * console.log(\"Decrypted data:\", decryptResult.data);\n   * ```\n   *\n   * @example\n   * Provide a lock context when decrypting:\n   * ```typescript\n   *    await eqlClient.decrypt(encryptedData)\n   *      .withLockContext(lockContext)\n   * ```\n   *\n   * @see {@link LockContext}\n   * @see {@link DecryptOperation}\n   */\n  decrypt(encryptedData: Encrypted): DecryptOperation {\n    return new DecryptOperation(this.client, encryptedData)\n  }\n\n  /**\n   * Encrypt a model based on its encryptConfig.\n   *\n   * @example\n   * ```typescript\n   * type User = {\n   *   id: string;\n   *   email: string; // encrypted\n   * }\n   *\n   * // Define the schema for the users table\n   * const usersSchema = csTable('users', {\n   *   email: csColumn('email').freeTextSearch().equality().orderAndRange(),\n   * })\n   *\n   * // Initialize the Protect client\n   * const protectClient = await protect({ schemas: [usersSchema] })\n   *\n   * // Encrypt a user model\n   * const encryptedModel = await protectClient.encryptModel<User>(\n   *   { id: 'user_123', email: 'person@example.com' },\n   *   usersSchema,\n   * )\n   * ```\n   */\n  encryptModel<T extends Record<string, unknown>>(\n    input: Decrypted<T>,\n    table: ProtectTable<ProtectTableColumn>,\n  ): EncryptModelOperation<T> {\n    return new EncryptModelOperation(this.client, input, table)\n  }\n\n  /**\n   * Decrypt a model with encrypted values\n   * Usage:\n   *    await eqlClient.decryptModel(encryptedModel)\n   *    await eqlClient.decryptModel(encryptedModel).withLockContext(lockContext)\n   */\n  decryptModel<T extends Record<string, unknown>>(\n    input: T,\n  ): DecryptModelOperation<T> {\n    return new DecryptModelOperation(this.client, input)\n  }\n\n  /**\n   * Bulk encrypt models with decrypted values\n   * Usage:\n   *    await eqlClient.bulkEncryptModels(decryptedModels, table)\n   *    await eqlClient.bulkEncryptModels(decryptedModels, table).withLockContext(lockContext)\n   */\n  bulkEncryptModels<T extends Record<string, unknown>>(\n    input: Array<Decrypted<T>>,\n    table: ProtectTable<ProtectTableColumn>,\n  ): BulkEncryptModelsOperation<T> {\n    return new BulkEncryptModelsOperation(this.client, input, table)\n  }\n\n  /**\n   * Bulk decrypt models with encrypted values\n   * Usage:\n   *    await eqlClient.bulkDecryptModels(encryptedModels)\n   *    await eqlClient.bulkDecryptModels(encryptedModels).withLockContext(lockContext)\n   */\n  bulkDecryptModels<T extends Record<string, unknown>>(\n    input: Array<T>,\n  ): BulkDecryptModelsOperation<T> {\n    return new BulkDecryptModelsOperation(this.client, input)\n  }\n\n  /**\n   * Bulk encryption - returns a thenable object.\n   * Usage:\n   *    await eqlClient.bulkEncrypt(plaintexts, { column, table })\n   *    await eqlClient.bulkEncrypt(plaintexts, { column, table }).withLockContext(lockContext)\n   */\n  bulkEncrypt(\n    plaintexts: BulkEncryptPayload,\n    opts: EncryptOptions,\n  ): BulkEncryptOperation {\n    return new BulkEncryptOperation(this.client, plaintexts, opts)\n  }\n\n  /**\n   * Bulk decryption - returns a thenable object.\n   * Usage:\n   *    await eqlClient.bulkDecrypt(encryptedPayloads)\n   *    await eqlClient.bulkDecrypt(encryptedPayloads).withLockContext(lockContext)\n   */\n  bulkDecrypt(encryptedPayloads: BulkDecryptPayload): BulkDecryptOperation {\n    return new BulkDecryptOperation(this.client, encryptedPayloads)\n  }\n\n  /**\n   * Create search terms to use in a query searching encrypted data\n   *\n   * @deprecated Use `encryptQuery(terms)` instead.\n   *\n   * Migration example:\n   * ```typescript\n   * // Before (deprecated)\n   * const result = await client.createSearchTerms([\n   *   { value: 'test', column: users.email, table: users }\n   * ])\n   *\n   * // After\n   * const result = await client.encryptQuery([\n   *   { value: 'test', column: users.email, table: users, queryType: 'equality' }\n   * ])\n   * ```\n   *\n   * Usage:\n   *    await eqlClient.createSearchTerms(searchTerms)\n   *    await eqlClient.createSearchTerms(searchTerms).withLockContext(lockContext)\n   */\n  createSearchTerms(terms: SearchTerm[]): SearchTermsOperation {\n    return new SearchTermsOperation(this.client, terms)\n  }\n\n}\n","function getLevelValue(level: string): number {\n  switch (level) {\n    case 'debug':\n      return 10\n    case 'info':\n      return 20\n    case 'error':\n      return 30\n    default:\n      return 30 // default to error level\n  }\n}\n\nconst envLogLevel = process.env.PROTECT_LOG_LEVEL || 'info'\nconst currentLevel = getLevelValue(envLogLevel)\n\nfunction debug(...args: unknown[]): void {\n  if (currentLevel <= getLevelValue('debug')) {\n    console.debug('[protect] DEBUG', ...args)\n  }\n}\n\nfunction info(...args: unknown[]): void {\n  if (currentLevel <= getLevelValue('info')) {\n    console.info('[protect] INFO', ...args)\n  }\n}\n\nfunction error(...args: unknown[]): void {\n  if (currentLevel <= getLevelValue('error')) {\n    console.error('[protect] ERROR', ...args)\n  }\n}\n\nexport const logger = {\n  debug,\n  info,\n  error,\n}\n","/**\n * JSONB path utilities for converting between path formats.\n *\n * These utilities support dot-notation and basic JSONPath-style array indices (e.g., \"[0]\").\n * Only limited validation is performed (forbidden prototype keys); callers should still\n * ensure segments are valid property names.\n */\n\n/**\n * Convert a dot-notation path to JSONPath selector format.\n *\n * @example\n * toJsonPath(\"user.email\")     // \"$.user.email\"\n * toJsonPath(\"$.user.email\")   // \"$.user.email\" (unchanged)\n * toJsonPath(\".user.email\")    // \"$.user.email\"\n * toJsonPath(\"name\")           // \"$.name\"\n */\nexport function toJsonPath(path: string): string {\n  if (!path || path === '$') return '$'\n  if (path.startsWith('$[')) return path\n  if (path.startsWith('$.')) return path\n  if (path.startsWith('$')) return `$.${path.slice(1)}`\n  if (path.startsWith('.')) return `$${path}`\n  if (path.startsWith('[')) return `$${path}`\n  return `$.${path}`\n}\n\n/**\n * Parse a JSONB path string into segments.\n * Handles both dot notation and JSONPath format.\n *\n * Returns an empty array for empty, null, or undefined input (defensive for JS consumers).\n *\n * @example\n * parseJsonbPath(\"user.email\")      // [\"user\", \"email\"]\n * parseJsonbPath(\"$.user.email\")    // [\"user\", \"email\"]\n * parseJsonbPath(\"name\")            // [\"name\"]\n * parseJsonbPath(\"$.name\")          // [\"name\"]\n */\nexport function parseJsonbPath(path: string): string[] {\n  if (!path || typeof path !== 'string') return []\n\n  // Remove leading $. or $ prefix\n  const normalized = path.replace(/^\\$\\.?/, '')\n\n  if (!normalized) return []\n\n  return normalized.split('.').filter(Boolean)\n}\n\n/**\n * Build a nested object from a dot-notation path and value.\n *\n * @example\n * buildNestedObject(\"user.role\", \"admin\")\n * // Returns: { user: { role: \"admin\" } }\n *\n * buildNestedObject(\"name\", \"alice\")\n * // Returns: { name: \"alice\" }\n *\n * buildNestedObject(\"a.b.c\", 123)\n * // Returns: { a: { b: { c: 123 } } }\n */\nconst FORBIDDEN_KEYS = ['__proto__', 'prototype', 'constructor']\n\nfunction validateSegment(segment: string): void {\n  if (FORBIDDEN_KEYS.includes(segment)) {\n    throw new Error(`Path contains forbidden segment: ${segment}`)\n  }\n}\n\nexport function buildNestedObject(\n  path: string,\n  value: unknown,\n): Record<string, unknown> {\n  if (!path) {\n    throw new Error('Path cannot be empty')\n  }\n\n  const segments = parseJsonbPath(path)\n  if (segments.length === 0) {\n    throw new Error('Path must contain at least one segment')\n  }\n\n  const result: Record<string, unknown> = Object.create(null)\n  let current = result\n\n  for (let i = 0; i < segments.length - 1; i++) {\n    const key = segments[i]\n    validateSegment(key)\n    current[key] = Object.create(null)\n    current = current[key] as Record<string, unknown>\n  }\n\n  const leafKey = segments[segments.length - 1]\n  validateSegment(leafKey)\n  current[leafKey] = value\n  return result\n}\n","import type {\n  Encrypted as CipherStashEncrypted,\n  EncryptedQuery as CipherStashEncryptedQuery,\n  EncryptedScalarQuery,\n  KeysetIdentifier as KeysetIdentifierFfi,\n} from '@cipherstash/protect-ffi'\nimport type {\n  Encrypted,\n  EncryptedQueryResult,\n  KeysetIdentifier,\n} from '../types'\n\n/**\n * The shape `encryptQuery` / `encryptQueryBulk` can return: a full storage\n * payload (`Encrypted`, returned for `ste_vec_term` containment queries) or a\n * query-only payload with no ciphertext (`EncryptedQuery`, returned for\n * scalar `unique`/`match`/`ore` lookups and `ste_vec_selector` path queries).\n *\n * TODO: duplicated in `@cipherstash/stack` — see\n * `packages/stack/src/encryption/helpers/index.ts`. Both copies should be\n * removed once `@cipherstash/protect-ffi` exports a named alias for the\n * `encryptQuery` return type (https://github.com/cipherstash/stack/pull/473).\n */\ntype EncryptedQueryTerm = CipherStashEncrypted | CipherStashEncryptedQuery\n\nexport type EncryptedPgComposite = {\n  data: Encrypted\n}\n\n/**\n * Helper function to transform an encrypted payload into a PostgreSQL composite type.\n * Use this when inserting data via Supabase or similar clients.\n */\nexport function encryptedToPgComposite(obj: Encrypted): EncryptedPgComposite {\n  return {\n    data: obj,\n  }\n}\n\n/**\n * Helper function to transform an encrypted payload into a PostgreSQL composite literal string.\n * Use this when querying with `.eq()` or similar equality operations in Supabase.\n *\n * @deprecated Use `encryptQuery()` with `returnType: 'composite-literal'` instead.\n * @example\n * ```typescript\n * // Before (deprecated):\n * const [encrypted] = await protectClient.encryptQuery([\n *   { value: searchValue, column, table, queryType: 'equality' }\n * ])\n * const literal = encryptedToCompositeLiteral(encrypted)\n * await supabase.from('table').select().eq('column', literal)\n *\n * // After (recommended):\n * const [searchTerm] = await protectClient.encryptQuery([\n *   { value: searchValue, column, table, queryType: 'equality', returnType: 'composite-literal' }\n * ])\n * await supabase.from('table').select().eq('column', searchTerm)\n * ```\n */\nexport function encryptedToCompositeLiteral(obj: EncryptedQueryTerm): string {\n  if (obj === null) {\n    throw new Error('encryptedToCompositeLiteral: obj cannot be null')\n  }\n  return `(${JSON.stringify(JSON.stringify(obj))})`\n}\n\n/**\n * Helper function to transform an encrypted payload into an escaped PostgreSQL composite literal string.\n * Use this when you need the composite literal format to be escaped as a string value.\n *\n * @deprecated Use `encryptQuery()` with `returnType: 'escaped-composite-literal'` instead.\n * See also: `encryptedToCompositeLiteral` for parallel deprecation guidance.\n * @example\n * ```typescript\n * // Before (deprecated):\n * const [encrypted] = await protectClient.encryptQuery([\n *   { value: searchValue, column, table, queryType: 'equality' }\n * ])\n * const escapedLiteral = encryptedToEscapedCompositeLiteral(encrypted)\n *\n * // After (recommended):\n * const [searchTerm] = await protectClient.encryptQuery([\n *   { value: searchValue, column, table, queryType: 'equality', returnType: 'escaped-composite-literal' }\n * ])\n * ```\n */\nexport function encryptedToEscapedCompositeLiteral(\n  obj: EncryptedQueryTerm,\n): string {\n  if (obj === null) {\n    throw new Error('encryptedToEscapedCompositeLiteral: obj cannot be null')\n  }\n  return JSON.stringify(encryptedToCompositeLiteral(obj))\n}\n\nexport function formatEncryptedResult(\n  encrypted: EncryptedQueryTerm,\n  returnType?: string,\n): EncryptedQueryResult {\n  if (returnType === 'composite-literal') {\n    return encryptedToCompositeLiteral(encrypted)\n  }\n  if (returnType === 'escaped-composite-literal') {\n    return encryptedToEscapedCompositeLiteral(encrypted)\n  }\n  return encrypted\n}\n\n/**\n * Helper function to transform a model's encrypted fields into PostgreSQL composite types\n */\nexport function modelToEncryptedPgComposites<T extends Record<string, unknown>>(\n  model: T,\n): T {\n  const result: Record<string, unknown> = {}\n\n  for (const [key, value] of Object.entries(model)) {\n    if (isEncryptedPayload(value)) {\n      result[key] = encryptedToPgComposite(value)\n    } else {\n      result[key] = value\n    }\n  }\n\n  return result as T\n}\n\n/**\n * Helper function to transform multiple models' encrypted fields into PostgreSQL composite types\n */\nexport function bulkModelsToEncryptedPgComposites<\n  T extends Record<string, unknown>,\n>(models: T[]): T[] {\n  return models.map((model) => modelToEncryptedPgComposites(model))\n}\n\nexport function toFfiKeysetIdentifier(\n  keyset: KeysetIdentifier | undefined,\n): KeysetIdentifierFfi | undefined {\n  if (!keyset) return undefined\n\n  if ('name' in keyset) {\n    return { Name: keyset.name }\n  }\n\n  return { Uuid: keyset.id }\n}\n\n/**\n * Helper function to check if a value is an encrypted payload\n */\nexport function isEncryptedPayload(value: unknown): value is Encrypted {\n  if (value === null) return false\n\n  // TODO: this can definitely be improved\n  if (typeof value === 'object') {\n    const obj = value as Encrypted\n    return (\n      obj !== null && 'v' in obj && ('c' in obj || 'sv' in obj) && 'i' in obj\n    )\n  }\n\n  return false\n}\n\n/**\n * Type guard narrowing a value to {@link EncryptedScalarQuery} — the scalar\n * query term (`unique` / `match` / `ore` lookup) returned by `encryptQuery` /\n * `encryptQueryBulk`. Unlike a storage payload it carries no ciphertext (`c`);\n * it carries exactly one lookup term: `hm`, `bf`, or `ob`.\n *\n * Use this to discriminate a scalar query term from a storage payload\n * (`EncryptedScalar`/`EncryptedSteVec`) or a `ste_vec_selector` query.\n */\nexport function isEncryptedScalarQuery(\n  value: unknown,\n): value is EncryptedScalarQuery {\n  if (value === null || typeof value !== 'object') return false\n\n  const obj = value as Record<string, unknown>\n\n  // `k: 'ct'` is the scalar discriminant; a query term never carries the\n  // ciphertext (`c`) that every storage payload has.\n  if (obj.k !== 'ct' || 'c' in obj) return false\n  if (\n    typeof obj.v !== 'number' ||\n    typeof obj.i !== 'object' ||\n    obj.i === null\n  ) {\n    return false\n  }\n\n  // Exactly one lookup term: `hm` (unique), `bf` (match), or `ob` (ore).\n  const lookupTerms = [\n    typeof obj.hm === 'string',\n    Array.isArray(obj.bf),\n    Array.isArray(obj.ob),\n  ].filter(Boolean)\n  return lookupTerms.length === 1\n}\n\nexport {\n  toJsonPath,\n  buildNestedObject,\n  parseJsonbPath,\n} from './jsonb'\n","import type { ScalarQueryTerm } from '../../types'\n\n/**\n * Type guard to check if a value is an array of ScalarQueryTerm objects.\n * Used to discriminate between single value and bulk encryption in encryptQuery overloads.\n */\nexport function isScalarQueryTermArray(\n  value: unknown,\n): value is readonly ScalarQueryTerm[] {\n  return (\n    Array.isArray(value) &&\n    value.length > 0 &&\n    typeof value[0] === 'object' &&\n    value[0] !== null &&\n    'column' in value[0] &&\n    'table' in value[0]\n  )\n}\n","import { type Result, withResult } from '@byteslice/result'\nimport {\n  type JsPlaintext,\n  type QueryPayload,\n  encryptQueryBulk as ffiEncryptQueryBulk,\n} from '@cipherstash/protect-ffi'\nimport type {\n  Encrypted as CipherStashEncrypted,\n  EncryptedQuery as CipherStashEncryptedQuery,\n} from '@cipherstash/protect-ffi'\nimport { type ProtectError, ProtectErrorTypes } from '../..'\nimport { logger } from '../../../../utils/logger'\nimport { formatEncryptedResult } from '../../helpers'\nimport type { Context, LockContext } from '../../identify'\nimport type { Client, EncryptedQueryResult, ScalarQueryTerm } from '../../types'\nimport { getErrorCode } from '../helpers/error-code'\nimport { resolveIndexType } from '../helpers/infer-index-type'\nimport {\n  assertValidNumericValue,\n  assertValueIndexCompatibility,\n} from '../helpers/validation'\nimport { noClientError } from '../index'\nimport { ProtectOperation } from './base-operation'\n\n/**\n * Separates null/undefined values from non-null terms in the input array.\n * Returns a set of indices where values are null/undefined and an array of non-null terms with their original indices.\n */\nfunction filterNullTerms(terms: readonly ScalarQueryTerm[]): {\n  nullIndices: Set<number>\n  nonNullTerms: { term: ScalarQueryTerm; originalIndex: number }[]\n} {\n  const nullIndices = new Set<number>()\n  const nonNullTerms: { term: ScalarQueryTerm; originalIndex: number }[] = []\n\n  terms.forEach((term, index) => {\n    if (term.value === null || term.value === undefined) {\n      nullIndices.add(index)\n    } else {\n      nonNullTerms.push({ term, originalIndex: index })\n    }\n  })\n\n  return { nullIndices, nonNullTerms }\n}\n\n/**\n * Validates and transforms a single term into a QueryPayload.\n * Throws an error if the value is NaN or Infinity.\n * Optionally includes lockContext if provided.\n */\nfunction buildQueryPayload(\n  term: ScalarQueryTerm,\n  lockContext?: Context,\n): QueryPayload {\n  assertValidNumericValue(term.value)\n\n  const { indexType, queryOp } = resolveIndexType(\n    term.column,\n    term.queryType,\n    term.value,\n  )\n\n  // Validate value/index compatibility\n  assertValueIndexCompatibility(term.value, indexType, term.column.getName())\n\n  const payload: QueryPayload = {\n    plaintext: term.value as JsPlaintext,\n    column: term.column.getName(),\n    table: term.table.tableName,\n    indexType,\n    queryOp,\n  }\n\n  if (lockContext != null) {\n    payload.lockContext = lockContext\n  }\n\n  return payload\n}\n\n/**\n * Reconstructs the results array with nulls in their original positions.\n * Non-null encrypted values are placed at their original indices.\n * Applies formatting based on term.returnType.\n */\nfunction assembleResults(\n  totalLength: number,\n  encryptedValues: (CipherStashEncrypted | CipherStashEncryptedQuery)[],\n  nonNullTerms: { term: ScalarQueryTerm; originalIndex: number }[],\n): EncryptedQueryResult[] {\n  const results: EncryptedQueryResult[] = new Array(totalLength).fill(null)\n\n  // Fill in encrypted values at their original positions, applying formatting\n  nonNullTerms.forEach(({ term, originalIndex }, i) => {\n    const encrypted = encryptedValues[i]\n\n    results[originalIndex] = formatEncryptedResult(encrypted, term.returnType)\n  })\n\n  return results\n}\n\n/**\n * @internal Use {@link ProtectClient.encryptQuery} with array input instead.\n */\nexport class BatchEncryptQueryOperation extends ProtectOperation<\n  EncryptedQueryResult[]\n> {\n  constructor(\n    private client: Client,\n    private terms: readonly ScalarQueryTerm[],\n  ) {\n    super()\n  }\n\n  public withLockContext(\n    lockContext: LockContext,\n  ): BatchEncryptQueryOperationWithLockContext {\n    return new BatchEncryptQueryOperationWithLockContext(\n      this.client,\n      this.terms,\n      lockContext,\n      this.auditMetadata,\n    )\n  }\n\n  public async execute(): Promise<\n    Result<EncryptedQueryResult[], ProtectError>\n  > {\n    logger.debug('Encrypting query terms', { count: this.terms.length })\n\n    if (this.terms.length === 0) {\n      return { data: [] }\n    }\n\n    const { nullIndices, nonNullTerms } = filterNullTerms(this.terms)\n\n    if (nonNullTerms.length === 0) {\n      return { data: this.terms.map(() => null) }\n    }\n\n    return await withResult(\n      async () => {\n        if (!this.client) throw noClientError()\n\n        const { metadata } = this.getAuditData()\n\n        const queries: QueryPayload[] = nonNullTerms.map(({ term }) =>\n          buildQueryPayload(term),\n        )\n\n        const encrypted = await ffiEncryptQueryBulk(this.client, {\n          queries,\n          unverifiedContext: metadata,\n        })\n\n        return assembleResults(this.terms.length, encrypted, nonNullTerms)\n      },\n      (error: unknown) => ({\n        type: ProtectErrorTypes.EncryptionError,\n        message: (error as Error).message,\n        code: getErrorCode(error),\n      }),\n    )\n  }\n}\n\n/**\n * @internal Use {@link ProtectClient.encryptQuery} with array input and `.withLockContext()` instead.\n */\nexport class BatchEncryptQueryOperationWithLockContext extends ProtectOperation<\n  EncryptedQueryResult[]\n> {\n  constructor(\n    private client: Client,\n    private terms: readonly ScalarQueryTerm[],\n    private lockContext: LockContext,\n    auditMetadata?: Record<string, unknown>,\n  ) {\n    super()\n    this.auditMetadata = auditMetadata\n  }\n\n  public async execute(): Promise<\n    Result<EncryptedQueryResult[], ProtectError>\n  > {\n    logger.debug('Encrypting query terms with lock context', {\n      count: this.terms.length,\n    })\n\n    if (this.terms.length === 0) {\n      return { data: [] }\n    }\n\n    // Check for all-null terms BEFORE fetching lockContext to avoid unnecessary network call\n    const { nullIndices, nonNullTerms } = filterNullTerms(this.terms)\n\n    if (nonNullTerms.length === 0) {\n      return { data: this.terms.map(() => null) }\n    }\n\n    const lockContextResult = await this.lockContext.getLockContext()\n    if (lockContextResult.failure) {\n      return { failure: lockContextResult.failure }\n    }\n\n    const { ctsToken, context } = lockContextResult.data\n\n    return await withResult(\n      async () => {\n        if (!this.client) throw noClientError()\n\n        const { metadata } = this.getAuditData()\n\n        const queries: QueryPayload[] = nonNullTerms.map(({ term }) =>\n          buildQueryPayload(term, context),\n        )\n\n        const encrypted = await ffiEncryptQueryBulk(this.client, {\n          queries,\n          serviceToken: ctsToken,\n          unverifiedContext: metadata,\n        })\n\n        return assembleResults(this.terms.length, encrypted, nonNullTerms)\n      },\n      (error: unknown) => ({\n        type: ProtectErrorTypes.EncryptionError,\n        message: (error as Error).message,\n        code: getErrorCode(error),\n      }),\n    )\n  }\n}\n","import {\n  ProtectError as FfiProtectError,\n  type ProtectErrorCode,\n} from '@cipherstash/protect-ffi'\n\n/**\n * Extracts FFI error code from an error if it's an FFI error, otherwise returns undefined.\n * Used to preserve specific error codes in ProtectError responses.\n */\nexport function getErrorCode(error: unknown): ProtectErrorCode | undefined {\n  return error instanceof FfiProtectError ? error.code : undefined\n}\n","import type {\n  Encrypted as CipherStashEncrypted,\n  EncryptedQuery as CipherStashEncryptedQuery,\n  JsPlaintext,\n  QueryOpName,\n  newClient,\n} from '@cipherstash/protect-ffi'\nimport type {\n  ProtectColumn,\n  ProtectTable,\n  ProtectTableColumn,\n  ProtectValue,\n} from '@cipherstash/schema'\n\n/**\n * Type to represent the client object\n */\nexport type Client = Awaited<ReturnType<typeof newClient>> | undefined\n\n/**\n * Type to represent an encrypted payload stored in the database. Always carries\n * a ciphertext — scalar payloads at the root (`c`), SteVec payloads at\n * `sv[0].c`. For search-term payloads returned by `encryptQuery`, see\n * {@link EncryptedQuery}.\n */\nexport type Encrypted = CipherStashEncrypted | null\n\n/**\n * Type to represent an encrypted query term (search needle) returned by\n * `encryptQuery` / `encryptQueryBulk` for scalar (`unique` / `match` / `ore`)\n * lookups and `ste_vec_selector` JSON path queries. Carries no ciphertext — it\n * is matched against stored values, never decrypted. JSON containment queries\n * (`ste_vec_term`) return a storage-shaped {@link Encrypted} payload instead.\n */\nexport type EncryptedQuery = CipherStashEncryptedQuery | null\n\n/**\n * Represents an encrypted payload in the database\n * @deprecated Use `Encrypted` instead\n */\nexport type EncryptedPayload = Encrypted | null\n\n/**\n * Represents an encrypted data object in the database\n * @deprecated Use `Encrypted` instead\n */\nexport type EncryptedData = Encrypted | null\n\n/**\n * Represents a value that will be encrypted and used in a search\n */\nexport type SearchTerm = {\n  value: JsPlaintext\n  column: ProtectColumn\n  table: ProtectTable<ProtectTableColumn>\n  returnType?: 'eql' | 'composite-literal' | 'escaped-composite-literal'\n}\n\nexport type KeysetIdentifier =\n  | {\n      name: string\n    }\n  | {\n      id: string\n    }\n\n/**\n * The return type of the search term based on the return type specified in the `SearchTerm` type.\n * - `eql` → an `Encrypted` storage payload (for `ste_vec_term` containment) or an\n *   {@link EncryptedQuery} term (for scalar lookups and `ste_vec_selector` queries).\n * - `composite-literal` → `string` where the value is a composite literal.\n * - `escaped-composite-literal` → `string` where the value is an escaped composite literal.\n */\nexport type EncryptedSearchTerm = Encrypted | EncryptedQuery | string\n\n/**\n * Result type for encryptQuery batch operations.\n * Can be an `Encrypted` storage payload (e.g. for `ste_vec_term`), an\n * {@link EncryptedQuery} term (for scalar lookups and `ste_vec_selector`),\n * a `string` (for composite-literal formats), or `null` (for null inputs).\n */\nexport type EncryptedQueryResult = Encrypted | EncryptedQuery | string | null\n\n/**\n * Represents a payload to be encrypted using the `encrypt` function\n */\nexport type EncryptPayload = JsPlaintext | null\n\n/**\n * Represents the options for encrypting a payload using the `encrypt` function\n */\nexport type EncryptOptions = {\n  column: ProtectColumn | ProtectValue\n  table: ProtectTable<ProtectTableColumn>\n}\n\n/**\n * Type to identify encrypted fields in a model\n */\nexport type EncryptedFields<T> = {\n  [K in keyof T as T[K] extends Encrypted ? K : never]: T[K]\n}\n\n/**\n * Type to identify non-encrypted fields in a model\n */\nexport type OtherFields<T> = {\n  [K in keyof T as T[K] extends Encrypted ? never : K]: T[K]\n}\n\n/**\n * Type to represent decrypted fields in a model\n */\nexport type DecryptedFields<T> = {\n  [K in keyof T as T[K] extends Encrypted ? K : never]: string\n}\n\n/**\n * Represents a model with plaintext (decrypted) values instead of the EQL/JSONB types\n */\nexport type Decrypted<T> = OtherFields<T> & DecryptedFields<T>\n\n/**\n * Types for bulk encryption and decryption operations.\n */\nexport type BulkEncryptPayload = Array<{\n  id?: string\n  plaintext: JsPlaintext | null\n}>\n\nexport type BulkEncryptedData = Array<{ id?: string; data: Encrypted }>\nexport type BulkDecryptPayload = Array<{ id?: string; data: Encrypted }>\nexport type BulkDecryptedData = Array<DecryptionResult<JsPlaintext | null>>\n\ntype DecryptionSuccess<T> = {\n  error?: never\n  data: T\n  id?: string\n}\n\ntype DecryptionError<T> = {\n  error: T\n  id?: string\n  data?: never\n}\n\nexport type DecryptionResult<T> = DecryptionSuccess<T> | DecryptionError<T>\n\n/**\n * User-facing query type names for encrypting query values.\n *\n * - `'equality'`: For exact match queries. {@link https://cipherstash.com/docs/platform/searchable-encryption/supported-queries/exact | Exact Queries}\n * - `'freeTextSearch'`: For text search queries. {@link https://cipherstash.com/docs/platform/searchable-encryption/supported-queries/match | Match Queries}\n * - `'orderAndRange'`: For comparison and range queries. {@link https://cipherstash.com/docs/platform/searchable-encryption/supported-queries/range | Range Queries}\n * - `'steVecSelector'`: For JSONPath selector queries (e.g., '$.user.email')\n * - `'steVecTerm'`: For containment queries (e.g., { role: 'admin' })\n * - `'searchableJson'`: Auto-infers selector or term based on plaintext type (recommended)\n *   - String values → ste_vec_selector (JSONPath queries)\n *   - Object/Array/Number/Boolean → ste_vec_term (containment queries)\n *\n * Note: For columns with an ste_vec index, `'searchableJson'` behaves identically to omitting\n * `queryType` entirely - both auto-infer the query operation from the plaintext type. Using\n * `'searchableJson'` explicitly is useful for code clarity and self-documenting intent.\n */\nexport type QueryTypeName =\n  | 'orderAndRange'\n  | 'freeTextSearch'\n  | 'equality'\n  | 'steVecSelector'\n  | 'steVecTerm'\n  | 'searchableJson'\n\n/**\n * Internal FFI index type names.\n * @internal\n */\nexport type FfiIndexTypeName = 'ore' | 'match' | 'unique' | 'ste_vec'\n\n/**\n * Query type constants for use with encryptQuery().\n */\nexport const queryTypes = {\n  orderAndRange: 'orderAndRange',\n  freeTextSearch: 'freeTextSearch',\n  equality: 'equality',\n  steVecSelector: 'steVecSelector',\n  steVecTerm: 'steVecTerm',\n  searchableJson: 'searchableJson',\n} as const satisfies Record<string, QueryTypeName>\n\n/**\n * Maps user-friendly query type names to FFI index type names.\n * @internal\n */\nexport const queryTypeToFfi: Record<QueryTypeName, FfiIndexTypeName> = {\n  orderAndRange: 'ore',\n  freeTextSearch: 'match',\n  equality: 'unique',\n  steVecSelector: 'ste_vec',\n  steVecTerm: 'ste_vec',\n  searchableJson: 'ste_vec',\n}\n\n/**\n * Maps query type names to FFI query operation names.\n * Returns undefined for query types that don't need a specific queryOp.\n * @internal\n */\nexport const queryTypeToQueryOp: Partial<Record<QueryTypeName, QueryOpName>> = {\n  steVecSelector: 'ste_vec_selector',\n  steVecTerm: 'ste_vec_term',\n}\n\n/**\n * Base type for query term options shared between single and bulk operations.\n * @internal\n */\nexport type QueryTermBase = {\n  column: ProtectColumn\n  table: ProtectTable<ProtectTableColumn>\n  queryType?: QueryTypeName // Optional - auto-infers if omitted\n  /**\n   * The format for the returned encrypted value:\n   * - `'eql'` (default) - Returns raw Encrypted object\n   * - `'composite-literal'` - Returns PostgreSQL composite literal format `(\"json\")`\n   * - `'escaped-composite-literal'` - Returns escaped format `\"(\\\"json\\\")\"`\n   */\n  returnType?: 'eql' | 'composite-literal' | 'escaped-composite-literal'\n}\n\n/**\n * Options for encrypting a single query term.\n */\nexport type EncryptQueryOptions = QueryTermBase\n\n/**\n * Individual query term for bulk operations.\n */\nexport type ScalarQueryTerm = QueryTermBase & {\n  value: JsPlaintext | null\n}\n","import type { JsPlaintext, QueryOpName } from '@cipherstash/protect-ffi'\nimport type { ProtectColumn } from '@cipherstash/schema'\nimport type { FfiIndexTypeName, QueryTypeName } from '../../types'\nimport { queryTypeToFfi, queryTypeToQueryOp } from '../../types'\n\n/**\n * Infer the primary index type from a column's configured indexes.\n * Priority: unique > match > ore > ste_vec (for scalar queries)\n */\nexport function inferIndexType(column: ProtectColumn): FfiIndexTypeName {\n  const config = column.build()\n  const indexes = config.indexes\n\n  if (!indexes || Object.keys(indexes).length === 0) {\n    throw new Error(`Column \"${column.getName()}\" has no indexes configured`)\n  }\n\n  // Priority order for inference\n  if (indexes.unique) return 'unique'\n  if (indexes.match) return 'match'\n  if (indexes.ore) return 'ore'\n  if (indexes.ste_vec) return 'ste_vec'\n\n  throw new Error(\n    `Column \"${column.getName()}\" has no suitable index for queries`,\n  )\n}\n\n/**\n * Infer the FFI query operation from plaintext type for STE Vec queries.\n * - String → ste_vec_selector (JSONPath queries like '$.user.email')\n * - Object/Array/Number/Boolean → ste_vec_term (containment queries)\n */\nexport function inferQueryOpFromPlaintext(plaintext: JsPlaintext): QueryOpName {\n  if (typeof plaintext === 'string') {\n    return 'ste_vec_selector'\n  }\n  // Objects, arrays, numbers, booleans are all valid JSONB containment values\n  if (\n    typeof plaintext === 'object' ||\n    typeof plaintext === 'number' ||\n    typeof plaintext === 'boolean' ||\n    typeof plaintext === 'bigint'\n  ) {\n    return 'ste_vec_term'\n  }\n  // This should never happen with valid JsPlaintext, but keep for safety\n  return 'ste_vec_term'\n}\n\n/**\n * Validate that the specified index type is configured on the column\n */\nexport function validateIndexType(\n  column: ProtectColumn,\n  indexType: FfiIndexTypeName,\n): void {\n  const config = column.build()\n  const indexes = config.indexes ?? {}\n\n  const indexMap: Record<string, boolean> = {\n    unique: !!indexes.unique,\n    match: !!indexes.match,\n    ore: !!indexes.ore,\n    ste_vec: !!indexes.ste_vec,\n  }\n\n  if (!indexMap[indexType]) {\n    throw new Error(\n      `Index type \"${indexType}\" is not configured on column \"${column.getName()}\"`,\n    )\n  }\n}\n\n/**\n * Resolve the index type and query operation for a query.\n * Validates the index type is configured on the column when queryType is explicit.\n * For ste_vec columns without explicit queryType, infers queryOp from plaintext shape.\n *\n * @param column - The column to resolve the index type for\n * @param queryType - Optional explicit query type (if provided, validates against column config)\n * @param plaintext - Optional plaintext value for queryOp inference on ste_vec columns\n * @returns The FFI index type name and optional query operation name\n * @throws Error if ste_vec is inferred but queryOp cannot be determined\n */\nexport function resolveIndexType(\n  column: ProtectColumn,\n  queryType?: QueryTypeName,\n  plaintext?: JsPlaintext | null,\n): { indexType: FfiIndexTypeName; queryOp?: QueryOpName } {\n  const indexType = queryType\n    ? queryTypeToFfi[queryType]\n    : inferIndexType(column)\n\n  if (queryType) {\n    validateIndexType(column, indexType)\n\n    // For searchableJson, infer queryOp from plaintext type (not from mapping)\n    if (queryType === 'searchableJson') {\n      if (plaintext === undefined || plaintext === null) {\n        return { indexType }\n      }\n      return { indexType, queryOp: inferQueryOpFromPlaintext(plaintext) }\n    }\n\n    return { indexType, queryOp: queryTypeToQueryOp[queryType] }\n  }\n\n  // ste_vec inferred without explicit queryType → must infer from plaintext\n  if (indexType === 'ste_vec') {\n    if (plaintext === undefined || plaintext === null) {\n      // Null plaintext handled by caller (returns null early) - no inference needed\n      return { indexType }\n    }\n    return { indexType, queryOp: inferQueryOpFromPlaintext(plaintext) }\n  }\n\n  // Non-ste_vec → no queryOp needed\n  return { indexType }\n}\n","import type { Result } from '@byteslice/result'\nimport { type ProtectError, ProtectErrorTypes } from '../..'\nimport type { FfiIndexTypeName } from '../../types'\n\n/**\n * Validates that a value is not NaN or Infinity.\n * Returns a failure Result if validation fails, undefined otherwise.\n * Use this in async flows that return Result types.\n *\n * Uses `never` as the success type so the result can be assigned to any Result<T, ProtectError>.\n *\n * @internal\n */\nexport function validateNumericValue(\n  value: unknown,\n): Result<never, ProtectError> | undefined {\n  if (typeof value === 'number' && Number.isNaN(value)) {\n    return {\n      failure: {\n        type: ProtectErrorTypes.EncryptionError,\n        message: '[protect]: Cannot encrypt NaN value',\n      },\n    }\n  }\n  if (typeof value === 'number' && !Number.isFinite(value)) {\n    return {\n      failure: {\n        type: ProtectErrorTypes.EncryptionError,\n        message: '[protect]: Cannot encrypt Infinity value',\n      },\n    }\n  }\n  return undefined\n}\n\n/**\n * Validates that a value is not NaN or Infinity.\n * Throws an error if validation fails.\n * Use this in sync flows where exceptions are caught.\n *\n * @internal\n */\nexport function assertValidNumericValue(value: unknown): void {\n  if (typeof value === 'number' && Number.isNaN(value)) {\n    throw new Error('[protect]: Cannot encrypt NaN value')\n  }\n  if (typeof value === 'number' && !Number.isFinite(value)) {\n    throw new Error('[protect]: Cannot encrypt Infinity value')\n  }\n}\n\n/**\n * Validates that the value type is compatible with the index type.\n * Match index (freeTextSearch) only supports string values.\n * Returns a failure Result if validation fails, undefined otherwise.\n * Use this in async flows that return Result types.\n *\n * @internal\n */\nexport function validateValueIndexCompatibility(\n  value: unknown,\n  indexType: FfiIndexTypeName,\n  columnName: string,\n): Result<never, ProtectError> | undefined {\n  if (typeof value === 'number' && indexType === 'match') {\n    return {\n      failure: {\n        type: ProtectErrorTypes.EncryptionError,\n        message: `[protect]: Cannot use 'match' index with numeric value on column \"${columnName}\". The 'freeTextSearch' index only supports string values. Configure the column with 'orderAndRange()' or 'equality()' for numeric queries.`,\n      },\n    }\n  }\n  return undefined\n}\n\n/**\n * Validates that the value type is compatible with the index type.\n * Match index (freeTextSearch) only supports string values.\n * Throws an error if validation fails.\n * Use this in sync flows where exceptions are caught.\n *\n * @internal\n */\nexport function assertValueIndexCompatibility(\n  value: unknown,\n  indexType: FfiIndexTypeName,\n  columnName: string,\n): void {\n  if (typeof value === 'number' && indexType === 'match') {\n    throw new Error(\n      `[protect]: Cannot use 'match' index with numeric value on column \"${columnName}\". The 'freeTextSearch' index only supports string values. Configure the column with 'orderAndRange()' or 'equality()' for numeric queries.`,\n    )\n  }\n}\n","import type { Result } from '@byteslice/result'\nimport type { ProtectError } from '../..'\n\nexport type AuditConfig = {\n  metadata?: Record<string, unknown>\n}\n\nexport type AuditData = {\n  metadata?: Record<string, unknown>\n}\n\nexport abstract class ProtectOperation<T> {\n  protected auditMetadata?: Record<string, unknown>\n\n  /**\n   * Attach audit metadata to this operation. Can be chained.\n   * @param config Configuration for ZeroKMS audit logging\n   * @param config.metadata Arbitrary JSON object for appending metadata to the audit log\n   */\n  audit(config: AuditConfig): this {\n    this.auditMetadata = config.metadata\n    return this\n  }\n\n  /**\n   * Get the audit data for this operation.\n   */\n  public getAuditData(): AuditData {\n    return {\n      metadata: this.auditMetadata,\n    }\n  }\n\n  /**\n   * Execute the operation and return a Result\n   */\n  abstract execute(): Promise<Result<T, ProtectError>>\n\n  /**\n   * Make the operation thenable\n   */\n  public then<TResult1 = Result<T, ProtectError>, TResult2 = never>(\n    onfulfilled?:\n      | ((value: Result<T, ProtectError>) => TResult1 | PromiseLike<TResult1>)\n      | null,\n    onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null,\n  ): Promise<TResult1 | TResult2> {\n    return this.execute().then(onfulfilled, onrejected)\n  }\n}\n","import { type Result, withResult } from '@byteslice/result'\nimport {\n  type Encrypted as CipherStashEncrypted,\n  type DecryptResult,\n  decryptBulkFallible,\n} from '@cipherstash/protect-ffi'\nimport { type ProtectError, ProtectErrorTypes } from '../..'\nimport { logger } from '../../../../utils/logger'\nimport type { Context, LockContext } from '../../identify'\nimport type { BulkDecryptPayload, BulkDecryptedData, Client } from '../../types'\nimport { getErrorCode } from '../helpers/error-code'\nimport { noClientError } from '../index'\nimport { ProtectOperation } from './base-operation'\n\n// Helper functions for better composability\nconst createDecryptPayloads = (\n  encryptedPayloads: BulkDecryptPayload,\n  lockContext?: Context,\n) => {\n  return encryptedPayloads\n    .map((item, index) => ({ ...item, originalIndex: index }))\n    .filter(({ data }) => data !== null)\n    .map(({ id, data, originalIndex }) => ({\n      id,\n      ciphertext: data as CipherStashEncrypted,\n      originalIndex,\n      ...(lockContext && { lockContext }),\n    }))\n}\n\nconst createNullResult = (\n  encryptedPayloads: BulkDecryptPayload,\n): BulkDecryptedData => {\n  return encryptedPayloads.map(({ id }) => ({\n    id,\n    data: null,\n  }))\n}\n\nconst mapDecryptedDataToResult = (\n  encryptedPayloads: BulkDecryptPayload,\n  decryptedData: DecryptResult[],\n): BulkDecryptedData => {\n  const result: BulkDecryptedData = new Array(encryptedPayloads.length)\n  let decryptedIndex = 0\n\n  for (let i = 0; i < encryptedPayloads.length; i++) {\n    if (encryptedPayloads[i].data === null) {\n      result[i] = { id: encryptedPayloads[i].id, data: null }\n    } else {\n      const decryptResult = decryptedData[decryptedIndex]\n      if ('error' in decryptResult) {\n        result[i] = {\n          id: encryptedPayloads[i].id,\n          error: decryptResult.error,\n        }\n      } else {\n        result[i] = {\n          id: encryptedPayloads[i].id,\n          data: decryptResult.data,\n        }\n      }\n      decryptedIndex++\n    }\n  }\n\n  return result\n}\n\nexport class BulkDecryptOperation extends ProtectOperation<BulkDecryptedData> {\n  private client: Client\n  private encryptedPayloads: BulkDecryptPayload\n\n  constructor(client: Client, encryptedPayloads: BulkDecryptPayload) {\n    super()\n    this.client = client\n    this.encryptedPayloads = encryptedPayloads\n  }\n\n  public withLockContext(\n    lockContext: LockContext,\n  ): BulkDecryptOperationWithLockContext {\n    return new BulkDecryptOperationWithLockContext(this, lockContext)\n  }\n\n  public async execute(): Promise<Result<BulkDecryptedData, ProtectError>> {\n    logger.debug('Bulk decrypting data WITHOUT a lock context')\n    return await withResult(\n      async () => {\n        if (!this.client) throw noClientError()\n        if (!this.encryptedPayloads || this.encryptedPayloads.length === 0)\n          return []\n\n        const nonNullPayloads = createDecryptPayloads(this.encryptedPayloads)\n\n        if (nonNullPayloads.length === 0) {\n          return createNullResult(this.encryptedPayloads)\n        }\n\n        const { metadata } = this.getAuditData()\n\n        const decryptedData = await decryptBulkFallible(this.client, {\n          ciphertexts: nonNullPayloads,\n          unverifiedContext: metadata,\n        })\n\n        return mapDecryptedDataToResult(this.encryptedPayloads, decryptedData)\n      },\n      (error: unknown) => ({\n        type: ProtectErrorTypes.DecryptionError,\n        message: (error as Error).message,\n        code: getErrorCode(error),\n      }),\n    )\n  }\n\n  public getOperation(): {\n    client: Client\n    encryptedPayloads: BulkDecryptPayload\n  } {\n    return {\n      client: this.client,\n      encryptedPayloads: this.encryptedPayloads,\n    }\n  }\n}\n\nexport class BulkDecryptOperationWithLockContext extends ProtectOperation<BulkDecryptedData> {\n  private operation: BulkDecryptOperation\n  private lockContext: LockContext\n\n  constructor(operation: BulkDecryptOperation, lockContext: LockContext) {\n    super()\n    this.operation = operation\n    this.lockContext = lockContext\n  }\n\n  public async execute(): Promise<Result<BulkDecryptedData, ProtectError>> {\n    return await withResult(\n      async () => {\n        const { client, encryptedPayloads } = this.operation.getOperation()\n        logger.debug('Bulk decrypting data WITH a lock context')\n\n        if (!client) throw noClientError()\n        if (!encryptedPayloads || encryptedPayloads.length === 0) return []\n\n        const context = await this.lockContext.getLockContext()\n        if (context.failure) {\n          throw new Error(`[protect]: ${context.failure.message}`)\n        }\n\n        const nonNullPayloads = createDecryptPayloads(\n          encryptedPayloads,\n          context.data.context,\n        )\n\n        if (nonNullPayloads.length === 0) {\n          return createNullResult(encryptedPayloads)\n        }\n\n        const { metadata } = this.getAuditData()\n\n        const decryptedData = await decryptBulkFallible(client, {\n          ciphertexts: nonNullPayloads,\n          serviceToken: context.data.ctsToken,\n          unverifiedContext: metadata,\n        })\n\n        return mapDecryptedDataToResult(encryptedPayloads, decryptedData)\n      },\n      (error: unknown) => ({\n        type: ProtectErrorTypes.DecryptionError,\n        message: (error as Error).message,\n        code: getErrorCode(error),\n      }),\n    )\n  }\n}\n","import { type Result, withResult } from '@byteslice/result'\nimport { type ProtectError, ProtectErrorTypes } from '../..'\nimport { logger } from '../../../../utils/logger'\nimport type { LockContext } from '../../identify'\nimport type { Client, Decrypted } from '../../types'\nimport { getErrorCode } from '../helpers/error-code'\nimport { noClientError } from '../index'\nimport {\n  bulkDecryptModels,\n  bulkDecryptModelsWithLockContext,\n} from '../model-helpers'\nimport { ProtectOperation } from './base-operation'\n\nexport class BulkDecryptModelsOperation<\n  T extends Record<string, unknown>,\n> extends ProtectOperation<Decrypted<T>[]> {\n  private client: Client\n  private models: T[]\n\n  constructor(client: Client, models: T[]) {\n    super()\n    this.client = client\n    this.models = models\n  }\n\n  public withLockContext(\n    lockContext: LockContext,\n  ): BulkDecryptModelsOperationWithLockContext<T> {\n    return new BulkDecryptModelsOperationWithLockContext(this, lockContext)\n  }\n\n  public async execute(): Promise<Result<Decrypted<T>[], ProtectError>> {\n    logger.debug('Bulk decrypting models WITHOUT a lock context')\n\n    return await withResult(\n      async () => {\n        if (!this.client) {\n          throw noClientError()\n        }\n\n        const auditData = this.getAuditData()\n\n        return await bulkDecryptModels<T>(this.models, this.client, auditData)\n      },\n      (error: unknown) => ({\n        type: ProtectErrorTypes.DecryptionError,\n        message: (error as Error).message,\n        code: getErrorCode(error),\n      }),\n    )\n  }\n\n  public getOperation(): {\n    client: Client\n    models: T[]\n  } {\n    return {\n      client: this.client,\n      models: this.models,\n    }\n  }\n}\n\nexport class BulkDecryptModelsOperationWithLockContext<\n  T extends Record<string, unknown>,\n> extends ProtectOperation<Decrypted<T>[]> {\n  private operation: BulkDecryptModelsOperation<T>\n  private lockContext: LockContext\n\n  constructor(\n    operation: BulkDecryptModelsOperation<T>,\n    lockContext: LockContext,\n  ) {\n    super()\n    this.operation = operation\n    this.lockContext = lockContext\n  }\n\n  public async execute(): Promise<Result<Decrypted<T>[], ProtectError>> {\n    return await withResult(\n      async () => {\n        const { client, models } = this.operation.getOperation()\n\n        logger.debug('Bulk decrypting models WITH a lock context')\n\n        if (!client) {\n          throw noClientError()\n        }\n\n        const context = await this.lockContext.getLockContext()\n\n        if (context.failure) {\n          throw new Error(`[protect]: ${context.failure.message}`)\n        }\n\n        const auditData = this.getAuditData()\n\n        return await bulkDecryptModelsWithLockContext<T>(\n          models,\n          client,\n          context.data,\n          auditData,\n        )\n      },\n      (error: unknown) => ({\n        type: ProtectErrorTypes.DecryptionError,\n        message: (error as Error).message,\n        code: getErrorCode(error),\n      }),\n    )\n  }\n}\n","import {\n  type Encrypted as CipherStashEncrypted,\n  type DecryptBulkOptions,\n  type JsPlaintext,\n  decryptBulk,\n  encryptBulk,\n} from '@cipherstash/protect-ffi'\nimport type { ProtectTable, ProtectTableColumn } from '@cipherstash/schema'\nimport { isEncryptedPayload } from '../helpers'\nimport type { GetLockContextResponse } from '../identify'\nimport type { Client, Decrypted, Encrypted } from '../types'\nimport type { AuditData } from './operations/base-operation'\n\n/**\n * Helper function to extract encrypted fields from a model\n */\nexport function extractEncryptedFields<T extends Record<string, unknown>>(\n  model: T,\n): Record<string, Encrypted> {\n  const result: Record<string, Encrypted> = {}\n\n  for (const [key, value] of Object.entries(model)) {\n    if (isEncryptedPayload(value)) {\n      result[key] = value\n    }\n  }\n\n  return result\n}\n\n/**\n * Helper function to extract non-encrypted fields from a model\n */\nexport function extractOtherFields<T extends Record<string, unknown>>(\n  model: T,\n): Record<string, unknown> {\n  const result: Record<string, unknown> = {}\n\n  for (const [key, value] of Object.entries(model)) {\n    if (!isEncryptedPayload(value)) {\n      result[key] = value\n    }\n  }\n\n  return result\n}\n\n/**\n * Helper function to merge encrypted and non-encrypted fields into a model\n */\nexport function mergeFields<T>(\n  otherFields: Record<string, unknown>,\n  encryptedFields: Record<string, Encrypted>,\n): T {\n  return { ...otherFields, ...encryptedFields } as T\n}\n\n/**\n * Base interface for bulk operation payloads\n */\ninterface BulkOperationPayload {\n  id: string\n  [key: string]: unknown\n}\n\n/**\n * Interface for bulk operation key mapping\n */\ninterface BulkOperationKeyMap {\n  modelIndex: number\n  fieldKey: string\n}\n\n/**\n * Helper function to handle single model bulk operations with mapping\n */\nasync function handleSingleModelBulkOperation<\n  T extends BulkOperationPayload,\n  R,\n>(\n  items: T[],\n  operation: (items: T[]) => Promise<R[]>,\n  keyMap: Record<string, string>,\n): Promise<Record<string, R>> {\n  if (items.length === 0) {\n    return {}\n  }\n\n  const results = await operation(items)\n  const mappedResults: Record<string, R> = {}\n\n  results.forEach((result, index) => {\n    const originalKey = keyMap[index.toString()]\n    mappedResults[originalKey] = result\n  })\n\n  return mappedResults\n}\n\n/**\n * Helper function to handle multiple model bulk operations with mapping\n */\nasync function handleMultiModelBulkOperation<T extends BulkOperationPayload, R>(\n  items: T[],\n  operation: (items: T[]) => Promise<R[]>,\n  keyMap: Record<string, BulkOperationKeyMap>,\n): Promise<Record<string, R>> {\n  if (items.length === 0) {\n    return {}\n  }\n\n  const results = await operation(items)\n  const mappedResults: Record<string, R> = {}\n\n  results.forEach((result, index) => {\n    const key = index.toString()\n    const { modelIndex, fieldKey } = keyMap[key]\n    mappedResults[`${modelIndex}-${fieldKey}`] = result\n  })\n\n  return mappedResults\n}\n\n/**\n * Helper function to prepare fields for decryption\n */\nfunction prepareFieldsForDecryption<T extends Record<string, unknown>>(\n  model: T,\n): {\n  otherFields: Record<string, unknown>\n  operationFields: Record<string, unknown>\n  keyMap: Record<string, string>\n  nullFields: Record<string, null | undefined>\n} {\n  const otherFields = { ...model } as Record<string, unknown>\n  const operationFields: Record<string, unknown> = {}\n  const nullFields: Record<string, null | undefined> = {}\n  const keyMap: Record<string, string> = {}\n  let index = 0\n\n  const processNestedFields = (obj: Record<string, unknown>, prefix = '') => {\n    for (const [key, value] of Object.entries(obj)) {\n      const fullKey = prefix ? `${prefix}.${key}` : key\n\n      if (value === null || value === undefined) {\n        nullFields[fullKey] = value\n        continue\n      }\n\n      if (typeof value === 'object' && !isEncryptedPayload(value)) {\n        // Recursively process nested objects\n        processNestedFields(value as Record<string, unknown>, fullKey)\n      } else if (isEncryptedPayload(value)) {\n        // This is an encrypted field\n        const id = index.toString()\n        keyMap[id] = fullKey\n        operationFields[fullKey] = value\n        index++\n\n        // Remove from otherFields\n        const parts = fullKey.split('.')\n        let current = otherFields\n        for (let i = 0; i < parts.length - 1; i++) {\n          current = current[parts[i]] as Record<string, unknown>\n        }\n        delete current[parts[parts.length - 1]]\n      }\n    }\n  }\n\n  processNestedFields(model)\n  return { otherFields, operationFields, keyMap, nullFields }\n}\n\n/**\n * Helper function to prepare fields for encryption\n */\nfunction prepareFieldsForEncryption<T extends Record<string, unknown>>(\n  model: T,\n  table: ProtectTable<ProtectTableColumn>,\n): {\n  otherFields: Record<string, unknown>\n  operationFields: Record<string, unknown>\n  keyMap: Record<string, string>\n  nullFields: Record<string, null | undefined>\n} {\n  const otherFields = { ...model } as Record<string, unknown>\n  const operationFields: Record<string, unknown> = {}\n  const nullFields: Record<string, null | undefined> = {}\n  const keyMap: Record<string, string> = {}\n  let index = 0\n\n  const processNestedFields = (\n    obj: Record<string, unknown>,\n    prefix = '',\n    columnPaths: string[] = [],\n  ) => {\n    for (const [key, value] of Object.entries(obj)) {\n      const fullKey = prefix ? `${prefix}.${key}` : key\n\n      if (value === null || value === undefined) {\n        nullFields[fullKey] = value\n        continue\n      }\n\n      if (\n        typeof value === 'object' &&\n        !isEncryptedPayload(value) &&\n        !columnPaths.includes(fullKey)\n      ) {\n        // Only process nested objects if they're in the schema\n        if (columnPaths.some((path) => path.startsWith(fullKey))) {\n          processNestedFields(\n            value as Record<string, unknown>,\n            fullKey,\n            columnPaths,\n          )\n        }\n      } else if (columnPaths.includes(fullKey)) {\n        // Only process fields that are explicitly defined in the schema\n        const id = index.toString()\n        keyMap[id] = fullKey\n        operationFields[fullKey] = value\n        index++\n\n        // Remove from otherFields\n        const parts = fullKey.split('.')\n        let current = otherFields\n        for (let i = 0; i < parts.length - 1; i++) {\n          current = current[parts[i]] as Record<string, unknown>\n        }\n        delete current[parts[parts.length - 1]]\n      }\n    }\n  }\n\n  // Get all column paths from the table schema\n  const columnPaths = Object.keys(table.build().columns)\n  processNestedFields(model, '', columnPaths)\n\n  return { otherFields, operationFields, keyMap, nullFields }\n}\n\n/**\n * Helper function to convert a model with encrypted fields to a decrypted model\n */\nexport async function decryptModelFields<T extends Record<string, unknown>>(\n  model: T,\n  client: Client,\n  auditData?: AuditData,\n): Promise<Decrypted<T>> {\n  if (!client) {\n    throw new Error('Client not initialized')\n  }\n\n  const { otherFields, operationFields, keyMap, nullFields } =\n    prepareFieldsForDecryption(model)\n\n  const bulkDecryptPayload = Object.entries(operationFields).map(\n    ([key, value]) => ({\n      id: key,\n      ciphertext: value as CipherStashEncrypted,\n    }),\n  )\n\n  const decryptedFields = await handleSingleModelBulkOperation(\n    bulkDecryptPayload,\n    (items) =>\n      decryptBulk(client, {\n        ciphertexts: items,\n        unverifiedContext: auditData?.metadata,\n      }),\n    keyMap,\n  )\n\n  // Helper function to set a nested value\n  const setNestedValue = (\n    obj: Record<string, unknown>,\n    path: string[],\n    value: unknown,\n  ) => {\n    let current = obj\n    for (let i = 0; i < path.length - 1; i++) {\n      const part = path[i]\n      if (!(part in current)) {\n        current[part] = {}\n      }\n      current = current[part] as Record<string, unknown>\n    }\n    current[path[path.length - 1]] = value\n  }\n\n  // Reconstruct the object with proper nesting\n  const result: Record<string, unknown> = { ...otherFields }\n\n  // First, reconstruct the null/undefined fields\n  for (const [key, value] of Object.entries(nullFields)) {\n    const parts = key.split('.')\n    setNestedValue(result, parts, value)\n  }\n\n  // Then, reconstruct the decrypted fields\n  for (const [key, value] of Object.entries(decryptedFields)) {\n    const parts = key.split('.')\n    setNestedValue(result, parts, value)\n  }\n\n  return result as Decrypted<T>\n}\n\n/**\n * Helper function to convert a decrypted model to a model with encrypted fields\n */\nexport async function encryptModelFields<T extends Record<string, unknown>>(\n  model: Decrypted<T>,\n  table: ProtectTable<ProtectTableColumn>,\n  client: Client,\n  auditData?: AuditData,\n): Promise<T> {\n  if (!client) {\n    throw new Error('Client not initialized')\n  }\n\n  const { otherFields, operationFields, keyMap, nullFields } =\n    prepareFieldsForEncryption(model, table)\n\n  const bulkEncryptPayload = Object.entries(operationFields).map(\n    ([key, value]) => ({\n      id: key,\n      plaintext: value as string,\n      table: table.tableName,\n      column: key,\n    }),\n  )\n\n  const encryptedData = await handleSingleModelBulkOperation(\n    bulkEncryptPayload,\n    (items) =>\n      encryptBulk(client, {\n        plaintexts: items,\n        unverifiedContext: auditData?.metadata,\n      }),\n    keyMap,\n  )\n\n  // Helper function to set a nested value\n  const setNestedValue = (\n    obj: Record<string, unknown>,\n    path: string[],\n    value: unknown,\n  ) => {\n    let current = obj\n    for (let i = 0; i < path.length - 1; i++) {\n      const part = path[i]\n      if (!(part in current)) {\n        current[part] = {}\n      }\n      current = current[part] as Record<string, unknown>\n    }\n    current[path[path.length - 1]] = value\n  }\n\n  // Reconstruct the object with proper nesting\n  const result: Record<string, unknown> = { ...otherFields }\n\n  // First, reconstruct the null/undefined fields\n  for (const [key, value] of Object.entries(nullFields)) {\n    const parts = key.split('.')\n    setNestedValue(result, parts, value)\n  }\n\n  // Then, reconstruct the encrypted fields\n  for (const [key, value] of Object.entries(encryptedData)) {\n    const parts = key.split('.')\n    setNestedValue(result, parts, value)\n  }\n\n  return result as T\n}\n\n/**\n * Helper function to convert a model with encrypted fields to a decrypted model with lock context\n */\nexport async function decryptModelFieldsWithLockContext<\n  T extends Record<string, unknown>,\n>(\n  model: T,\n  client: Client,\n  lockContext: GetLockContextResponse,\n  auditData?: AuditData,\n): Promise<Decrypted<T>> {\n  if (!client) {\n    throw new Error('Client not initialized')\n  }\n\n  if (!lockContext) {\n    throw new Error('Lock context is not initialized')\n  }\n\n  const { otherFields, operationFields, keyMap, nullFields } =\n    prepareFieldsForDecryption(model)\n\n  const bulkDecryptPayload = Object.entries(operationFields).map(\n    ([key, value]) => ({\n      id: key,\n      ciphertext: value as CipherStashEncrypted,\n      lockContext: lockContext.context,\n    }),\n  )\n\n  const decryptedFields = await handleSingleModelBulkOperation(\n    bulkDecryptPayload,\n    (items) =>\n      decryptBulk(client, {\n        ciphertexts: items,\n        serviceToken: lockContext.ctsToken,\n        unverifiedContext: auditData?.metadata,\n      }),\n    keyMap,\n  )\n\n  // Helper function to set a nested value\n  const setNestedValue = (\n    obj: Record<string, unknown>,\n    path: string[],\n    value: unknown,\n  ) => {\n    let current = obj\n    for (let i = 0; i < path.length - 1; i++) {\n      const part = path[i]\n      if (!(part in current)) {\n        current[part] = {}\n      }\n      current = current[part] as Record<string, unknown>\n    }\n    current[path[path.length - 1]] = value\n  }\n\n  // Reconstruct the object with proper nesting\n  const result: Record<string, unknown> = { ...otherFields }\n\n  // First, reconstruct the null/undefined fields\n  for (const [key, value] of Object.entries(nullFields)) {\n    const parts = key.split('.')\n    setNestedValue(result, parts, value)\n  }\n\n  // Then, reconstruct the decrypted fields\n  for (const [key, value] of Object.entries(decryptedFields)) {\n    const parts = key.split('.')\n    setNestedValue(result, parts, value)\n  }\n\n  return result as Decrypted<T>\n}\n\n/**\n * Helper function to convert a decrypted model to a model with encrypted fields with lock context\n */\nexport async function encryptModelFieldsWithLockContext<\n  T extends Record<string, unknown>,\n>(\n  model: Decrypted<T>,\n  table: ProtectTable<ProtectTableColumn>,\n  client: Client,\n  lockContext: GetLockContextResponse,\n  auditData?: AuditData,\n): Promise<T> {\n  if (!client) {\n    throw new Error('Client not initialized')\n  }\n\n  if (!lockContext) {\n    throw new Error('Lock context is not initialized')\n  }\n\n  const { otherFields, operationFields, keyMap, nullFields } =\n    prepareFieldsForEncryption(model, table)\n\n  const bulkEncryptPayload = Object.entries(operationFields).map(\n    ([key, value]) => ({\n      id: key,\n      plaintext: value as string,\n      table: table.tableName,\n      column: key,\n      lockContext: lockContext.context,\n    }),\n  )\n\n  const encryptedData = await handleSingleModelBulkOperation(\n    bulkEncryptPayload,\n    (items) =>\n      encryptBulk(client, {\n        plaintexts: items,\n        serviceToken: lockContext.ctsToken,\n        unverifiedContext: auditData?.metadata,\n      }),\n    keyMap,\n  )\n\n  // Helper function to set a nested value\n  const setNestedValue = (\n    obj: Record<string, unknown>,\n    path: string[],\n    value: unknown,\n  ) => {\n    let current = obj\n    for (let i = 0; i < path.length - 1; i++) {\n      const part = path[i]\n      if (!(part in current)) {\n        current[part] = {}\n      }\n      current = current[part] as Record<string, unknown>\n    }\n    current[path[path.length - 1]] = value\n  }\n\n  // Reconstruct the object with proper nesting\n  const result: Record<string, unknown> = { ...otherFields }\n\n  // First, reconstruct the null/undefined fields\n  for (const [key, value] of Object.entries(nullFields)) {\n    const parts = key.split('.')\n    setNestedValue(result, parts, value)\n  }\n\n  // Then, reconstruct the encrypted fields\n  for (const [key, value] of Object.entries(encryptedData)) {\n    const parts = key.split('.')\n    setNestedValue(result, parts, value)\n  }\n\n  return result as T\n}\n\n/**\n * Helper function to prepare multiple models for bulk operation\n */\nfunction prepareBulkModelsForOperation<T extends Record<string, unknown>>(\n  models: T[],\n  table?: ProtectTable<ProtectTableColumn>,\n): {\n  otherFields: Record<string, unknown>[]\n  operationFields: Record<string, unknown>[]\n  keyMap: Record<string, { modelIndex: number; fieldKey: string }>\n  nullFields: Record<string, null | undefined>[]\n} {\n  const otherFields: Record<string, unknown>[] = []\n  const operationFields: Record<string, unknown>[] = []\n  const nullFields: Record<string, null | undefined>[] = []\n  const keyMap: Record<string, { modelIndex: number; fieldKey: string }> = {}\n  let index = 0\n\n  for (let modelIndex = 0; modelIndex < models.length; modelIndex++) {\n    const model = models[modelIndex]\n    const modelOtherFields = { ...model } as Record<string, unknown>\n    const modelOperationFields: Record<string, unknown> = {}\n    const modelNullFields: Record<string, null | undefined> = {}\n\n    const processNestedFields = (\n      obj: Record<string, unknown>,\n      prefix = '',\n      columnPaths: string[] = [],\n    ) => {\n      for (const [key, value] of Object.entries(obj)) {\n        const fullKey = prefix ? `${prefix}.${key}` : key\n\n        if (value === null || value === undefined) {\n          modelNullFields[fullKey] = value\n          continue\n        }\n\n        if (\n          typeof value === 'object' &&\n          !isEncryptedPayload(value) &&\n          !columnPaths.includes(fullKey)\n        ) {\n          // Only process nested objects if they're in the schema\n          if (columnPaths.some((path) => path.startsWith(fullKey))) {\n            processNestedFields(\n              value as Record<string, unknown>,\n              fullKey,\n              columnPaths,\n            )\n          }\n        } else if (columnPaths.includes(fullKey)) {\n          // Only process fields that are explicitly defined in the schema\n          const id = index.toString()\n          keyMap[id] = { modelIndex, fieldKey: fullKey }\n          modelOperationFields[fullKey] = value\n          index++\n\n          // Remove from otherFields\n          const parts = fullKey.split('.')\n          let current = modelOtherFields\n          for (let i = 0; i < parts.length - 1; i++) {\n            current = current[parts[i]] as Record<string, unknown>\n          }\n          delete current[parts[parts.length - 1]]\n        }\n      }\n    }\n\n    if (table) {\n      // Get all column paths from the table schema\n      const columnPaths = Object.keys(table.build().columns)\n      processNestedFields(model, '', columnPaths)\n    } else {\n      // For decryption, process all encrypted fields\n      const processEncryptedFields = (\n        obj: Record<string, unknown>,\n        prefix = '',\n        columnPaths: string[] = [],\n      ) => {\n        for (const [key, value] of Object.entries(obj)) {\n          const fullKey = prefix ? `${prefix}.${key}` : key\n\n          if (value === null || value === undefined) {\n            modelNullFields[fullKey] = value\n            continue\n          }\n\n          if (\n            typeof value === 'object' &&\n            !isEncryptedPayload(value) &&\n            !columnPaths.includes(fullKey)\n          ) {\n            // Recursively process nested objects\n            processEncryptedFields(\n              value as Record<string, unknown>,\n              fullKey,\n              columnPaths,\n            )\n          } else if (isEncryptedPayload(value)) {\n            // This is an encrypted field\n            const id = index.toString()\n            keyMap[id] = { modelIndex, fieldKey: fullKey }\n            modelOperationFields[fullKey] = value\n            index++\n\n            // Remove from otherFields\n            const parts = fullKey.split('.')\n            let current = modelOtherFields\n            for (let i = 0; i < parts.length - 1; i++) {\n              current = current[parts[i]] as Record<string, unknown>\n            }\n            delete current[parts[parts.length - 1]]\n          }\n        }\n      }\n      processEncryptedFields(model)\n    }\n\n    otherFields.push(modelOtherFields)\n    operationFields.push(modelOperationFields)\n    nullFields.push(modelNullFields)\n  }\n\n  return { otherFields, operationFields, keyMap, nullFields }\n}\n\n/**\n * Helper function to convert multiple decrypted models to models with encrypted fields\n */\nexport async function bulkEncryptModels<T extends Record<string, unknown>>(\n  models: Decrypted<T>[],\n  table: ProtectTable<ProtectTableColumn>,\n  client: Client,\n  auditData?: AuditData,\n): Promise<T[]> {\n  if (!client) {\n    throw new Error('Client not initialized')\n  }\n\n  if (!models || models.length === 0) {\n    return []\n  }\n\n  const { otherFields, operationFields, keyMap, nullFields } =\n    prepareBulkModelsForOperation(models, table)\n\n  const bulkEncryptPayload = operationFields.flatMap((fields, modelIndex) =>\n    Object.entries(fields).map(([key, value]) => ({\n      id: `${modelIndex}-${key}`,\n      plaintext: value as string,\n      table: table.tableName,\n      column: key,\n    })),\n  )\n\n  const encryptedData = await handleMultiModelBulkOperation(\n    bulkEncryptPayload,\n    (items) =>\n      encryptBulk(client, {\n        plaintexts: items,\n        unverifiedContext: auditData?.metadata,\n      }),\n    keyMap,\n  )\n\n  // Helper function to set a nested value\n  const setNestedValue = (\n    obj: Record<string, unknown>,\n    path: string[],\n    value: unknown,\n  ) => {\n    let current = obj\n    for (let i = 0; i < path.length - 1; i++) {\n      const part = path[i]\n      if (!(part in current)) {\n        current[part] = {}\n      }\n      current = current[part] as Record<string, unknown>\n    }\n    current[path[path.length - 1]] = value\n  }\n\n  return models.map((_, modelIndex) => {\n    const result: Record<string, unknown> = { ...otherFields[modelIndex] }\n\n    // First, reconstruct the null/undefined fields\n    for (const [key, value] of Object.entries(nullFields[modelIndex])) {\n      const parts = key.split('.')\n      setNestedValue(result, parts, value)\n    }\n\n    // Then, reconstruct the encrypted fields\n    const modelData = Object.fromEntries(\n      Object.entries(encryptedData)\n        .filter(([key]) => {\n          const [idx] = key.split('-')\n          return Number.parseInt(idx) === modelIndex\n        })\n        .map(([key, value]) => {\n          const [_, fieldKey] = key.split('-')\n          return [fieldKey, value]\n        }),\n    )\n\n    for (const [key, value] of Object.entries(modelData)) {\n      const parts = key.split('.')\n      setNestedValue(result, parts, value)\n    }\n\n    return result as T\n  })\n}\n\n/**\n * Helper function to convert multiple models with encrypted fields to decrypted models\n */\nexport async function bulkDecryptModels<T extends Record<string, unknown>>(\n  models: T[],\n  client: Client,\n  auditData?: AuditData,\n): Promise<Decrypted<T>[]> {\n  if (!client) {\n    throw new Error('Client not initialized')\n  }\n\n  if (!models || models.length === 0) {\n    return []\n  }\n\n  const { otherFields, operationFields, keyMap, nullFields } =\n    prepareBulkModelsForOperation(models)\n\n  const bulkDecryptPayload = operationFields.flatMap((fields, modelIndex) =>\n    Object.entries(fields).map(([key, value]) => ({\n      id: `${modelIndex}-${key}`,\n      ciphertext: value as CipherStashEncrypted,\n    })),\n  )\n\n  const decryptedFields = await handleMultiModelBulkOperation(\n    bulkDecryptPayload,\n    (items) =>\n      decryptBulk(client, {\n        ciphertexts: items,\n        unverifiedContext: auditData?.metadata,\n      }),\n    keyMap,\n  )\n\n  // Helper function to set a nested value\n  const setNestedValue = (\n    obj: Record<string, unknown>,\n    path: string[],\n    value: unknown,\n  ) => {\n    let current = obj\n    for (let i = 0; i < path.length - 1; i++) {\n      const part = path[i]\n      if (!(part in current)) {\n        current[part] = {}\n      }\n      current = current[part] as Record<string, unknown>\n    }\n    current[path[path.length - 1]] = value\n  }\n\n  return models.map((_, modelIndex) => {\n    const result: Record<string, unknown> = { ...otherFields[modelIndex] }\n\n    // First, reconstruct the null/undefined fields\n    for (const [key, value] of Object.entries(nullFields[modelIndex])) {\n      const parts = key.split('.')\n      setNestedValue(result, parts, value)\n    }\n\n    // Then, reconstruct the decrypted fields\n    const modelData = Object.fromEntries(\n      Object.entries(decryptedFields)\n        .filter(([key]) => {\n          const [idx] = key.split('-')\n          return Number.parseInt(idx) === modelIndex\n        })\n        .map(([key, value]) => {\n          const [_, fieldKey] = key.split('-')\n          return [fieldKey, value]\n        }),\n    )\n\n    for (const [key, value] of Object.entries(modelData)) {\n      const parts = key.split('.')\n      setNestedValue(result, parts, value)\n    }\n\n    return result as Decrypted<T>\n  })\n}\n\n/**\n * Helper function to convert multiple models with encrypted fields to decrypted models with lock context\n */\nexport async function bulkDecryptModelsWithLockContext<\n  T extends Record<string, unknown>,\n>(\n  models: T[],\n  client: Client,\n  lockContext: GetLockContextResponse,\n  auditData?: AuditData,\n): Promise<Decrypted<T>[]> {\n  if (!client) {\n    throw new Error('Client not initialized')\n  }\n\n  if (!lockContext) {\n    throw new Error('Lock context is not initialized')\n  }\n\n  const { otherFields, operationFields, keyMap, nullFields } =\n    prepareBulkModelsForOperation(models)\n\n  const bulkDecryptPayload = operationFields.flatMap((fields, modelIndex) =>\n    Object.entries(fields).map(([key, value]) => ({\n      id: `${modelIndex}-${key}`,\n      ciphertext: value as CipherStashEncrypted,\n      lockContext: lockContext.context,\n    })),\n  )\n\n  const decryptedFields = await handleMultiModelBulkOperation(\n    bulkDecryptPayload,\n    (items) =>\n      decryptBulk(client, {\n        ciphertexts: items,\n        serviceToken: lockContext.ctsToken,\n        unverifiedContext: auditData?.metadata,\n      }),\n    keyMap,\n  )\n\n  // Reconstruct models\n  return models.map((_, modelIndex) => ({\n    ...otherFields[modelIndex],\n    ...nullFields[modelIndex],\n    ...Object.fromEntries(\n      Object.entries(decryptedFields)\n        .filter(([key]) => {\n          const [idx] = key.split('-')\n          return Number.parseInt(idx) === modelIndex\n        })\n        .map(([key, value]) => {\n          const [_, fieldKey] = key.split('-')\n          return [fieldKey, value]\n        }),\n    ),\n  })) as Decrypted<T>[]\n}\n\n/**\n * Helper function to convert multiple decrypted models to models with encrypted fields with lock context\n */\nexport async function bulkEncryptModelsWithLockContext<\n  T extends Record<string, unknown>,\n>(\n  models: Decrypted<T>[],\n  table: ProtectTable<ProtectTableColumn>,\n  client: Client,\n  lockContext: GetLockContextResponse,\n  auditData?: AuditData,\n): Promise<T[]> {\n  if (!client) {\n    throw new Error('Client not initialized')\n  }\n\n  if (!lockContext) {\n    throw new Error('Lock context is not initialized')\n  }\n\n  const { otherFields, operationFields, keyMap, nullFields } =\n    prepareBulkModelsForOperation(models, table)\n\n  const bulkEncryptPayload = operationFields.flatMap((fields, modelIndex) =>\n    Object.entries(fields).map(([key, value]) => ({\n      id: `${modelIndex}-${key}`,\n      plaintext: value as string,\n      table: table.tableName,\n      column: key,\n      lockContext: lockContext.context,\n    })),\n  )\n\n  const encryptedData = await handleMultiModelBulkOperation(\n    bulkEncryptPayload,\n    (items) =>\n      encryptBulk(client, {\n        plaintexts: items,\n        serviceToken: lockContext.ctsToken,\n        unverifiedContext: auditData?.metadata,\n      }),\n    keyMap,\n  )\n\n  // Reconstruct models\n  return models.map((_, modelIndex) => ({\n    ...otherFields[modelIndex],\n    ...nullFields[modelIndex],\n    ...Object.fromEntries(\n      Object.entries(encryptedData)\n        .filter(([key]) => {\n          const [idx] = key.split('-')\n          return Number.parseInt(idx) === modelIndex\n        })\n        .map(([key, value]) => {\n          const [_, fieldKey] = key.split('-')\n          return [fieldKey, value]\n        }),\n    ),\n  })) as T[]\n}\n","import { type Result, withResult } from '@byteslice/result'\nimport { type JsPlaintext, encryptBulk } from '@cipherstash/protect-ffi'\nimport type {\n  ProtectColumn,\n  ProtectTable,\n  ProtectTableColumn,\n  ProtectValue,\n} from '@cipherstash/schema'\nimport { type ProtectError, ProtectErrorTypes } from '../..'\nimport { logger } from '../../../../utils/logger'\nimport type { Context, LockContext } from '../../identify'\nimport type {\n  BulkEncryptPayload,\n  BulkEncryptedData,\n  Client,\n  EncryptOptions,\n  Encrypted,\n} from '../../types'\nimport { getErrorCode } from '../helpers/error-code'\nimport { noClientError } from '../index'\nimport { ProtectOperation } from './base-operation'\n\n// Helper functions for better composability\nconst createEncryptPayloads = (\n  plaintexts: BulkEncryptPayload,\n  column: ProtectColumn | ProtectValue,\n  table: ProtectTable<ProtectTableColumn>,\n  lockContext?: Context,\n) => {\n  return plaintexts\n    .map((item, index) => ({ ...item, originalIndex: index }))\n    .filter(({ plaintext }) => plaintext !== null)\n    .map(({ id, plaintext, originalIndex }) => ({\n      id,\n      plaintext: plaintext as JsPlaintext,\n      column: column.getName(),\n      table: table.tableName,\n      originalIndex,\n      ...(lockContext && { lockContext }),\n    }))\n}\n\nconst createNullResult = (\n  plaintexts: BulkEncryptPayload,\n): BulkEncryptedData => {\n  return plaintexts.map(({ id }) => ({ id, data: null }))\n}\n\nconst mapEncryptedDataToResult = (\n  plaintexts: BulkEncryptPayload,\n  encryptedData: Encrypted[],\n): BulkEncryptedData => {\n  const result: BulkEncryptedData = new Array(plaintexts.length)\n  let encryptedIndex = 0\n\n  for (let i = 0; i < plaintexts.length; i++) {\n    if (plaintexts[i].plaintext === null) {\n      result[i] = { id: plaintexts[i].id, data: null }\n    } else {\n      result[i] = {\n        id: plaintexts[i].id,\n        data: encryptedData[encryptedIndex],\n      }\n      encryptedIndex++\n    }\n  }\n\n  return result\n}\n\nexport class BulkEncryptOperation extends ProtectOperation<BulkEncryptedData> {\n  private client: Client\n  private plaintexts: BulkEncryptPayload\n  private column: ProtectColumn | ProtectValue\n  private table: ProtectTable<ProtectTableColumn>\n\n  constructor(\n    client: Client,\n    plaintexts: BulkEncryptPayload,\n    opts: EncryptOptions,\n  ) {\n    super()\n    this.client = client\n    this.plaintexts = plaintexts\n    this.column = opts.column\n    this.table = opts.table\n  }\n\n  public withLockContext(\n    lockContext: LockContext,\n  ): BulkEncryptOperationWithLockContext {\n    return new BulkEncryptOperationWithLockContext(this, lockContext)\n  }\n\n  public async execute(): Promise<Result<BulkEncryptedData, ProtectError>> {\n    logger.debug('Bulk encrypting data WITHOUT a lock context', {\n      column: this.column.getName(),\n      table: this.table.tableName,\n    })\n\n    return await withResult(\n      async () => {\n        if (!this.client) {\n          throw noClientError()\n        }\n        if (!this.plaintexts || this.plaintexts.length === 0) {\n          return []\n        }\n\n        const nonNullPayloads = createEncryptPayloads(\n          this.plaintexts,\n          this.column,\n          this.table,\n        )\n\n        if (nonNullPayloads.length === 0) {\n          return createNullResult(this.plaintexts)\n        }\n\n        const { metadata } = this.getAuditData()\n\n        const encryptedData = await encryptBulk(this.client, {\n          plaintexts: nonNullPayloads,\n          unverifiedContext: metadata,\n        })\n\n        return mapEncryptedDataToResult(this.plaintexts, encryptedData)\n      },\n      (error: unknown) => ({\n        type: ProtectErrorTypes.EncryptionError,\n        message: (error as Error).message,\n        code: getErrorCode(error),\n      }),\n    )\n  }\n\n  public getOperation(): {\n    client: Client\n    plaintexts: BulkEncryptPayload\n    column: ProtectColumn | ProtectValue\n    table: ProtectTable<ProtectTableColumn>\n  } {\n    return {\n      client: this.client,\n      plaintexts: this.plaintexts,\n      column: this.column,\n      table: this.table,\n    }\n  }\n}\n\nexport class BulkEncryptOperationWithLockContext extends ProtectOperation<BulkEncryptedData> {\n  private operation: BulkEncryptOperation\n  private lockContext: LockContext\n\n  constructor(operation: BulkEncryptOperation, lockContext: LockContext) {\n    super()\n    this.operation = operation\n    this.lockContext = lockContext\n  }\n\n  public async execute(): Promise<Result<BulkEncryptedData, ProtectError>> {\n    return await withResult(\n      async () => {\n        const { client, plaintexts, column, table } =\n          this.operation.getOperation()\n\n        logger.debug('Bulk encrypting data WITH a lock context', {\n          column: column.getName(),\n          table: table.tableName,\n        })\n\n        if (!client) {\n          throw noClientError()\n        }\n        if (!plaintexts || plaintexts.length === 0) {\n          return []\n        }\n\n        const context = await this.lockContext.getLockContext()\n        if (context.failure) {\n          throw new Error(`[protect]: ${context.failure.message}`)\n        }\n\n        const nonNullPayloads = createEncryptPayloads(\n          plaintexts,\n          column,\n          table,\n          context.data.context,\n        )\n\n        if (nonNullPayloads.length === 0) {\n          return createNullResult(plaintexts)\n        }\n\n        const { metadata } = this.getAuditData()\n\n        const encryptedData = await encryptBulk(client, {\n          plaintexts: nonNullPayloads,\n          serviceToken: context.data.ctsToken,\n          unverifiedContext: metadata,\n        })\n\n        return mapEncryptedDataToResult(plaintexts, encryptedData)\n      },\n      (error: unknown) => ({\n        type: ProtectErrorTypes.EncryptionError,\n        message: (error as Error).message,\n        code: getErrorCode(error),\n      }),\n    )\n  }\n}\n","import { type Result, withResult } from '@byteslice/result'\nimport type { ProtectTable, ProtectTableColumn } from '@cipherstash/schema'\nimport { type ProtectError, ProtectErrorTypes } from '../..'\nimport { logger } from '../../../../utils/logger'\nimport type { LockContext } from '../../identify'\nimport type { Client, Decrypted } from '../../types'\nimport { getErrorCode } from '../helpers/error-code'\nimport { noClientError } from '../index'\nimport {\n  bulkEncryptModels,\n  bulkEncryptModelsWithLockContext,\n} from '../model-helpers'\nimport { ProtectOperation } from './base-operation'\n\nexport class BulkEncryptModelsOperation<\n  T extends Record<string, unknown>,\n> extends ProtectOperation<T[]> {\n  private client: Client\n  private models: Decrypted<T>[]\n  private table: ProtectTable<ProtectTableColumn>\n\n  constructor(\n    client: Client,\n    models: Decrypted<T>[],\n    table: ProtectTable<ProtectTableColumn>,\n  ) {\n    super()\n    this.client = client\n    this.models = models\n    this.table = table\n  }\n\n  public withLockContext(\n    lockContext: LockContext,\n  ): BulkEncryptModelsOperationWithLockContext<T> {\n    return new BulkEncryptModelsOperationWithLockContext(this, lockContext)\n  }\n\n  public async execute(): Promise<Result<T[], ProtectError>> {\n    logger.debug('Bulk encrypting models WITHOUT a lock context', {\n      table: this.table.tableName,\n    })\n\n    return await withResult(\n      async () => {\n        if (!this.client) {\n          throw noClientError()\n        }\n\n        const auditData = this.getAuditData()\n\n        return await bulkEncryptModels<T>(\n          this.models,\n          this.table,\n          this.client,\n          auditData,\n        )\n      },\n      (error: unknown) => ({\n        type: ProtectErrorTypes.EncryptionError,\n        message: (error as Error).message,\n        code: getErrorCode(error),\n      }),\n    )\n  }\n\n  public getOperation(): {\n    client: Client\n    models: Decrypted<T>[]\n    table: ProtectTable<ProtectTableColumn>\n  } {\n    return {\n      client: this.client,\n      models: this.models,\n      table: this.table,\n    }\n  }\n}\n\nexport class BulkEncryptModelsOperationWithLockContext<\n  T extends Record<string, unknown>,\n> extends ProtectOperation<T[]> {\n  private operation: BulkEncryptModelsOperation<T>\n  private lockContext: LockContext\n\n  constructor(\n    operation: BulkEncryptModelsOperation<T>,\n    lockContext: LockContext,\n  ) {\n    super()\n    this.operation = operation\n    this.lockContext = lockContext\n  }\n\n  public async execute(): Promise<Result<T[], ProtectError>> {\n    return await withResult(\n      async () => {\n        const { client, models, table } = this.operation.getOperation()\n\n        logger.debug('Bulk encrypting models WITH a lock context', {\n          table: table.tableName,\n        })\n\n        if (!client) {\n          throw noClientError()\n        }\n\n        const context = await this.lockContext.getLockContext()\n\n        if (context.failure) {\n          throw new Error(`[protect]: ${context.failure.message}`)\n        }\n\n        const auditData = this.getAuditData()\n\n        return await bulkEncryptModelsWithLockContext<T>(\n          models,\n          table,\n          client,\n          context.data,\n          auditData,\n        )\n      },\n      (error: unknown) => ({\n        type: ProtectErrorTypes.EncryptionError,\n        message: (error as Error).message,\n        code: getErrorCode(error),\n      }),\n    )\n  }\n}\n","import { type Result, withResult } from '@byteslice/result'\nimport {\n  type JsPlaintext,\n  decrypt as ffiDecrypt,\n} from '@cipherstash/protect-ffi'\nimport { type ProtectError, ProtectErrorTypes } from '../..'\nimport { logger } from '../../../../utils/logger'\nimport type { LockContext } from '../../identify'\nimport type { Client, Encrypted } from '../../types'\nimport { getErrorCode } from '../helpers/error-code'\nimport { noClientError } from '../index'\nimport { ProtectOperation } from './base-operation'\n\n/**\n * Decrypts an encrypted payload using the provided client.\n * This is the type returned by the {@link ProtectClient.decrypt | decrypt} method of the {@link ProtectClient}.\n */\nexport class DecryptOperation extends ProtectOperation<JsPlaintext | null> {\n  private client: Client\n  private encryptedData: Encrypted\n\n  constructor(client: Client, encryptedData: Encrypted) {\n    super()\n    this.client = client\n    this.encryptedData = encryptedData\n  }\n\n  public withLockContext(\n    lockContext: LockContext,\n  ): DecryptOperationWithLockContext {\n    return new DecryptOperationWithLockContext(this, lockContext)\n  }\n\n  public async execute(): Promise<Result<JsPlaintext | null, ProtectError>> {\n    return await withResult(\n      async () => {\n        if (!this.client) {\n          throw noClientError()\n        }\n\n        if (this.encryptedData === null) {\n          return null\n        }\n\n        const { metadata } = this.getAuditData()\n\n        logger.debug('Decrypting data WITHOUT a lock context', {\n          metadata,\n        })\n\n        return await ffiDecrypt(this.client, {\n          ciphertext: this.encryptedData,\n          unverifiedContext: metadata,\n        })\n      },\n      (error: unknown) => ({\n        type: ProtectErrorTypes.DecryptionError,\n        message: (error as Error).message,\n        code: getErrorCode(error),\n      }),\n    )\n  }\n\n  public getOperation(): {\n    client: Client\n    encryptedData: Encrypted\n    auditData?: Record<string, unknown>\n  } {\n    return {\n      client: this.client,\n      encryptedData: this.encryptedData,\n      auditData: this.getAuditData(),\n    }\n  }\n}\n\nexport class DecryptOperationWithLockContext extends ProtectOperation<JsPlaintext | null> {\n  private operation: DecryptOperation\n  private lockContext: LockContext\n\n  constructor(operation: DecryptOperation, lockContext: LockContext) {\n    super()\n    this.operation = operation\n    this.lockContext = lockContext\n    const auditData = operation.getAuditData()\n    if (auditData) {\n      this.audit(auditData)\n    }\n  }\n\n  public async execute(): Promise<Result<JsPlaintext | null, ProtectError>> {\n    return await withResult(\n      async () => {\n        const { client, encryptedData } = this.operation.getOperation()\n\n        if (!client) {\n          throw noClientError()\n        }\n\n        if (encryptedData === null) {\n          return null\n        }\n\n        const { metadata } = this.getAuditData()\n\n        logger.debug('Decrypting data WITH a lock context', {\n          metadata,\n        })\n\n        const context = await this.lockContext.getLockContext()\n\n        if (context.failure) {\n          throw new Error(`[protect]: ${context.failure.message}`)\n        }\n\n        return await ffiDecrypt(client, {\n          ciphertext: encryptedData,\n          unverifiedContext: metadata,\n          lockContext: context.data.context,\n          serviceToken: context.data.ctsToken,\n        })\n      },\n      (error: unknown) => ({\n        type: ProtectErrorTypes.DecryptionError,\n        message: (error as Error).message,\n        code: getErrorCode(error),\n      }),\n    )\n  }\n}\n","import { type Result, withResult } from '@byteslice/result'\nimport { type ProtectError, ProtectErrorTypes } from '../..'\nimport { logger } from '../../../../utils/logger'\nimport type { LockContext } from '../../identify'\nimport type { Client, Decrypted } from '../../types'\nimport { getErrorCode } from '../helpers/error-code'\nimport { noClientError } from '../index'\nimport {\n  decryptModelFields,\n  decryptModelFieldsWithLockContext,\n} from '../model-helpers'\nimport { ProtectOperation } from './base-operation'\n\nexport class DecryptModelOperation<\n  T extends Record<string, unknown>,\n> extends ProtectOperation<Decrypted<T>> {\n  private client: Client\n  private model: T\n\n  constructor(client: Client, model: T) {\n    super()\n    this.client = client\n    this.model = model\n  }\n\n  public withLockContext(\n    lockContext: LockContext,\n  ): DecryptModelOperationWithLockContext<T> {\n    return new DecryptModelOperationWithLockContext(this, lockContext)\n  }\n\n  public async execute(): Promise<Result<Decrypted<T>, ProtectError>> {\n    logger.debug('Decrypting model WITHOUT a lock context')\n\n    return await withResult(\n      async () => {\n        if (!this.client) {\n          throw noClientError()\n        }\n\n        const auditData = this.getAuditData()\n\n        return await decryptModelFields<T>(this.model, this.client, auditData)\n      },\n      (error: unknown) => ({\n        type: ProtectErrorTypes.DecryptionError,\n        message: (error as Error).message,\n        code: getErrorCode(error),\n      }),\n    )\n  }\n\n  public getOperation(): {\n    client: Client\n    model: T\n  } {\n    return {\n      client: this.client,\n      model: this.model,\n    }\n  }\n}\n\nexport class DecryptModelOperationWithLockContext<\n  T extends Record<string, unknown>,\n> extends ProtectOperation<Decrypted<T>> {\n  private operation: DecryptModelOperation<T>\n  private lockContext: LockContext\n\n  constructor(operation: DecryptModelOperation<T>, lockContext: LockContext) {\n    super()\n    this.operation = operation\n    this.lockContext = lockContext\n  }\n\n  public async execute(): Promise<Result<Decrypted<T>, ProtectError>> {\n    return await withResult(\n      async () => {\n        const { client, model } = this.operation.getOperation()\n\n        logger.debug('Decrypting model WITH a lock context')\n\n        if (!client) {\n          throw noClientError()\n        }\n\n        const context = await this.lockContext.getLockContext()\n\n        if (context.failure) {\n          throw new Error(`[protect]: ${context.failure.message}`)\n        }\n\n        const auditData = this.getAuditData()\n\n        return await decryptModelFieldsWithLockContext<T>(\n          model,\n          client,\n          context.data,\n          auditData,\n        )\n      },\n      (error: unknown) => ({\n        type: ProtectErrorTypes.DecryptionError,\n        message: (error as Error).message,\n        code: getErrorCode(error),\n      }),\n    )\n  }\n}\n","import { type Result, withResult } from '@byteslice/result'\nimport { type QueryPayload, encryptQueryBulk } from '@cipherstash/protect-ffi'\nimport { noClientError } from '../..'\nimport { type ProtectError, ProtectErrorTypes } from '../../..'\nimport { logger } from '../../../../../utils/logger'\nimport type { LockContext } from '../../../identify'\nimport type { Client, EncryptedSearchTerm, SearchTerm } from '../../../types'\nimport { getErrorCode } from '../../helpers/error-code'\nimport { inferIndexType } from '../../helpers/infer-index-type'\nimport { ProtectOperation } from '../base-operation'\n\n/**\n * @deprecated Use `BatchEncryptQueryOperation` instead.\n * This class is maintained for backward compatibility only.\n */\nexport class SearchTermsOperation extends ProtectOperation<\n  EncryptedSearchTerm[]\n> {\n  constructor(\n    private client: Client,\n    private terms: SearchTerm[],\n  ) {\n    super()\n  }\n\n  public withLockContext(\n    lockContext: LockContext,\n  ): SearchTermsOperationWithLockContext {\n    return new SearchTermsOperationWithLockContext(this, lockContext)\n  }\n\n  public async execute(): Promise<Result<EncryptedSearchTerm[], ProtectError>> {\n    logger.debug('Creating search terms (deprecated API)', {\n      count: this.terms.length,\n    })\n\n    return await withResult(\n      async () => {\n        if (!this.client) throw noClientError()\n\n        const { metadata } = this.getAuditData()\n\n        const queries: QueryPayload[] = this.terms.map((term) => ({\n          plaintext: term.value,\n          column: term.column.getName(),\n          table: term.table.tableName,\n          indexType: inferIndexType(term.column),\n        }))\n\n        const encryptedTerms = await encryptQueryBulk(this.client, {\n          queries,\n          unverifiedContext: metadata,\n        })\n\n        return this.terms.map((term, index) => {\n          if (term.returnType === 'composite-literal') {\n            return `(${JSON.stringify(JSON.stringify(encryptedTerms[index]))})`\n          }\n          if (term.returnType === 'escaped-composite-literal') {\n            return `${JSON.stringify(`(${JSON.stringify(JSON.stringify(encryptedTerms[index]))})`)}`\n          }\n          return encryptedTerms[index]\n        })\n      },\n      (error: unknown) => ({\n        type: ProtectErrorTypes.EncryptionError,\n        message: (error as Error).message,\n        code: getErrorCode(error),\n      }),\n    )\n  }\n}\n\nexport class SearchTermsOperationWithLockContext extends ProtectOperation<\n  EncryptedSearchTerm[]\n> {\n  constructor(\n    private operation: SearchTermsOperation,\n    private lockContext: LockContext,\n  ) {\n    super()\n    this.auditMetadata = (operation as any).auditMetadata\n  }\n\n  public async execute(): Promise<Result<EncryptedSearchTerm[], ProtectError>> {\n    const lockContextResult = await this.lockContext.getLockContext()\n    if (lockContextResult.failure) {\n      return { failure: lockContextResult.failure }\n    }\n\n    const { ctsToken, context } = lockContextResult.data\n    const op = this.operation as any\n\n    return await withResult(\n      async () => {\n        if (!op.client) throw noClientError()\n\n        const { metadata } = this.getAuditData()\n\n        const queries: QueryPayload[] = op.terms.map((term: SearchTerm) => ({\n          plaintext: term.value,\n          column: term.column.getName(),\n          table: term.table.tableName,\n          indexType: inferIndexType(term.column),\n          lockContext: context,\n        }))\n\n        const encryptedTerms = await encryptQueryBulk(op.client, {\n          queries,\n          serviceToken: ctsToken,\n          unverifiedContext: metadata,\n        })\n\n        return op.terms.map((term: SearchTerm, index: number) => {\n          if (term.returnType === 'composite-literal') {\n            return `(${JSON.stringify(JSON.stringify(encryptedTerms[index]))})`\n          }\n          if (term.returnType === 'escaped-composite-literal') {\n            return `${JSON.stringify(`(${JSON.stringify(JSON.stringify(encryptedTerms[index]))})`)}`\n          }\n          return encryptedTerms[index]\n        })\n      },\n      (error: unknown) => ({\n        type: ProtectErrorTypes.EncryptionError,\n        message: (error as Error).message,\n        code: getErrorCode(error),\n      }),\n    )\n  }\n}\n","import { type Result, withResult } from '@byteslice/result'\nimport {\n  type JsPlaintext,\n  encrypt as ffiEncrypt,\n} from '@cipherstash/protect-ffi'\nimport type {\n  ProtectColumn,\n  ProtectTable,\n  ProtectTableColumn,\n  ProtectValue,\n} from '@cipherstash/schema'\nimport { type ProtectError, ProtectErrorTypes } from '../..'\nimport { logger } from '../../../../utils/logger'\nimport type { LockContext } from '../../identify'\nimport type { Client, EncryptOptions, Encrypted } from '../../types'\nimport { getErrorCode } from '../helpers/error-code'\nimport { noClientError } from '../index'\nimport { ProtectOperation } from './base-operation'\n\nexport class EncryptOperation extends ProtectOperation<Encrypted> {\n  private client: Client\n  private plaintext: JsPlaintext | null\n  private column: ProtectColumn | ProtectValue\n  private table: ProtectTable<ProtectTableColumn>\n\n  constructor(\n    client: Client,\n    plaintext: JsPlaintext | null,\n    opts: EncryptOptions,\n  ) {\n    super()\n    this.client = client\n    this.plaintext = plaintext\n    this.column = opts.column\n    this.table = opts.table\n  }\n\n  public withLockContext(\n    lockContext: LockContext,\n  ): EncryptOperationWithLockContext {\n    return new EncryptOperationWithLockContext(this, lockContext)\n  }\n\n  public async execute(): Promise<Result<Encrypted, ProtectError>> {\n    logger.debug('Encrypting data WITHOUT a lock context', {\n      column: this.column.getName(),\n      table: this.table.tableName,\n    })\n\n    return await withResult(\n      async () => {\n        if (!this.client) {\n          throw noClientError()\n        }\n\n        if (this.plaintext === null) {\n          return null\n        }\n\n        if (\n          typeof this.plaintext === 'number' &&\n          Number.isNaN(this.plaintext)\n        ) {\n          throw new Error('[protect]: Cannot encrypt NaN value')\n        }\n\n        if (\n          typeof this.plaintext === 'number' &&\n          !Number.isFinite(this.plaintext)\n        ) {\n          throw new Error('[protect]: Cannot encrypt Infinity value')\n        }\n\n        const { metadata } = this.getAuditData()\n\n        return await ffiEncrypt(this.client, {\n          plaintext: this.plaintext,\n          column: this.column.getName(),\n          table: this.table.tableName,\n          unverifiedContext: metadata,\n        })\n      },\n      (error: unknown) => ({\n        type: ProtectErrorTypes.EncryptionError,\n        message: (error as Error).message,\n        code: getErrorCode(error),\n      }),\n    )\n  }\n\n  public getOperation(): {\n    client: Client\n    plaintext: JsPlaintext | null\n    column: ProtectColumn | ProtectValue\n    table: ProtectTable<ProtectTableColumn>\n  } {\n    return {\n      client: this.client,\n      plaintext: this.plaintext,\n      column: this.column,\n      table: this.table,\n    }\n  }\n}\n\nexport class EncryptOperationWithLockContext extends ProtectOperation<Encrypted> {\n  private operation: EncryptOperation\n  private lockContext: LockContext\n\n  constructor(operation: EncryptOperation, lockContext: LockContext) {\n    super()\n    this.operation = operation\n    this.lockContext = lockContext\n  }\n\n  public async execute(): Promise<Result<Encrypted, ProtectError>> {\n    return await withResult(\n      async () => {\n        const { client, plaintext, column, table } =\n          this.operation.getOperation()\n\n        logger.debug('Encrypting data WITH a lock context', {\n          column: column,\n          table: table,\n        })\n\n        if (!client) {\n          throw noClientError()\n        }\n\n        if (plaintext === null) {\n          return null\n        }\n\n        const { metadata } = this.getAuditData()\n        const context = await this.lockContext.getLockContext()\n\n        if (context.failure) {\n          throw new Error(`[protect]: ${context.failure.message}`)\n        }\n\n        return await ffiEncrypt(client, {\n          plaintext,\n          column: column.getName(),\n          table: table.tableName,\n          lockContext: context.data.context,\n          serviceToken: context.data.ctsToken,\n          unverifiedContext: metadata,\n        })\n      },\n      (error: unknown) => ({\n        type: ProtectErrorTypes.EncryptionError,\n        message: (error as Error).message,\n        code: getErrorCode(error),\n      }),\n    )\n  }\n}\n","import { type Result, withResult } from '@byteslice/result'\nimport type { ProtectTable, ProtectTableColumn } from '@cipherstash/schema'\nimport { type ProtectError, ProtectErrorTypes } from '../..'\nimport { logger } from '../../../../utils/logger'\nimport type { LockContext } from '../../identify'\nimport type { Client, Decrypted } from '../../types'\nimport { getErrorCode } from '../helpers/error-code'\nimport { noClientError } from '../index'\nimport {\n  encryptModelFields,\n  encryptModelFieldsWithLockContext,\n} from '../model-helpers'\nimport { ProtectOperation } from './base-operation'\n\nexport class EncryptModelOperation<\n  T extends Record<string, unknown>,\n> extends ProtectOperation<T> {\n  private client: Client\n  private model: Decrypted<T>\n  private table: ProtectTable<ProtectTableColumn>\n\n  constructor(\n    client: Client,\n    model: Decrypted<T>,\n    table: ProtectTable<ProtectTableColumn>,\n  ) {\n    super()\n    this.client = client\n    this.model = model\n    this.table = table\n  }\n\n  public withLockContext(\n    lockContext: LockContext,\n  ): EncryptModelOperationWithLockContext<T> {\n    return new EncryptModelOperationWithLockContext(this, lockContext)\n  }\n\n  public async execute(): Promise<Result<T, ProtectError>> {\n    logger.debug('Encrypting model WITHOUT a lock context', {\n      table: this.table.tableName,\n    })\n\n    return await withResult(\n      async () => {\n        if (!this.client) {\n          throw noClientError()\n        }\n\n        const auditData = this.getAuditData()\n\n        return await encryptModelFields<T>(\n          this.model,\n          this.table,\n          this.client,\n          auditData,\n        )\n      },\n      (error: unknown) => ({\n        type: ProtectErrorTypes.EncryptionError,\n        message: (error as Error).message,\n        code: getErrorCode(error),\n      }),\n    )\n  }\n\n  public getOperation(): {\n    client: Client\n    model: Decrypted<T>\n    table: ProtectTable<ProtectTableColumn>\n  } {\n    return {\n      client: this.client,\n      model: this.model,\n      table: this.table,\n    }\n  }\n}\n\nexport class EncryptModelOperationWithLockContext<\n  T extends Record<string, unknown>,\n> extends ProtectOperation<T> {\n  private operation: EncryptModelOperation<T>\n  private lockContext: LockContext\n\n  constructor(operation: EncryptModelOperation<T>, lockContext: LockContext) {\n    super()\n    this.operation = operation\n    this.lockContext = lockContext\n  }\n\n  public async execute(): Promise<Result<T, ProtectError>> {\n    return await withResult(\n      async () => {\n        const { client, model, table } = this.operation.getOperation()\n\n        logger.debug('Encrypting model WITH a lock context', {\n          table: table.tableName,\n        })\n\n        if (!client) {\n          throw noClientError()\n        }\n\n        const context = await this.lockContext.getLockContext()\n\n        if (context.failure) {\n          throw new Error(`[protect]: ${context.failure.message}`)\n        }\n\n        const auditData = this.getAuditData()\n\n        return await encryptModelFieldsWithLockContext<T>(\n          model,\n          table,\n          client,\n          context.data,\n          auditData,\n        )\n      },\n      (error: unknown) => ({\n        type: ProtectErrorTypes.EncryptionError,\n        message: (error as Error).message,\n        code: getErrorCode(error),\n      }),\n    )\n  }\n}\n","import { type Result, withResult } from '@byteslice/result'\nimport {\n  type JsPlaintext,\n  encryptQuery as ffiEncryptQuery,\n} from '@cipherstash/protect-ffi'\nimport { type ProtectError, ProtectErrorTypes } from '../..'\nimport { logger } from '../../../../utils/logger'\nimport { formatEncryptedResult } from '../../helpers'\nimport type { LockContext } from '../../identify'\nimport type {\n  Client,\n  EncryptQueryOptions,\n  EncryptedQueryResult,\n} from '../../types'\nimport { getErrorCode } from '../helpers/error-code'\nimport { resolveIndexType } from '../helpers/infer-index-type'\nimport {\n  assertValueIndexCompatibility,\n  validateNumericValue,\n} from '../helpers/validation'\nimport { noClientError } from '../index'\nimport { ProtectOperation } from './base-operation'\n\n/**\n * @internal Use {@link ProtectClient.encryptQuery} instead.\n */\nexport class EncryptQueryOperation extends ProtectOperation<EncryptedQueryResult> {\n  constructor(\n    private client: Client,\n    private plaintext: JsPlaintext | null,\n    private opts: EncryptQueryOptions,\n  ) {\n    super()\n  }\n\n  public withLockContext(\n    lockContext: LockContext,\n  ): EncryptQueryOperationWithLockContext {\n    return new EncryptQueryOperationWithLockContext(\n      this.client,\n      this.plaintext,\n      this.opts,\n      lockContext,\n      this.auditMetadata,\n    )\n  }\n\n  public async execute(): Promise<Result<EncryptedQueryResult, ProtectError>> {\n    logger.debug('Encrypting query', {\n      column: this.opts.column.getName(),\n      table: this.opts.table.tableName,\n      queryType: this.opts.queryType,\n    })\n\n    if (this.plaintext === null || this.plaintext === undefined) {\n      return { data: null }\n    }\n\n    const validationError = validateNumericValue(this.plaintext)\n    if (validationError?.failure) {\n      return { failure: validationError.failure }\n    }\n\n    return await withResult(\n      async () => {\n        if (!this.client) throw noClientError()\n\n        const { metadata } = this.getAuditData()\n\n        const { indexType, queryOp } = resolveIndexType(\n          this.opts.column,\n          this.opts.queryType,\n          this.plaintext,\n        )\n\n        // Validate value/index compatibility\n        assertValueIndexCompatibility(\n          this.plaintext,\n          indexType,\n          this.opts.column.getName(),\n        )\n\n        const encrypted = await ffiEncryptQuery(this.client, {\n          plaintext: this.plaintext as JsPlaintext,\n          column: this.opts.column.getName(),\n          table: this.opts.table.tableName,\n          indexType,\n          queryOp,\n          unverifiedContext: metadata,\n        })\n\n        return formatEncryptedResult(encrypted, this.opts.returnType)\n      },\n      (error: unknown) => ({\n        type: ProtectErrorTypes.EncryptionError,\n        message: (error as Error).message,\n        code: getErrorCode(error),\n      }),\n    )\n  }\n\n  public getOperation() {\n    return { client: this.client, plaintext: this.plaintext, ...this.opts }\n  }\n}\n\n/**\n * @internal Use {@link ProtectClient.encryptQuery} with `.withLockContext()` instead.\n */\nexport class EncryptQueryOperationWithLockContext extends ProtectOperation<EncryptedQueryResult> {\n  constructor(\n    private client: Client,\n    private plaintext: JsPlaintext | null,\n    private opts: EncryptQueryOptions,\n    private lockContext: LockContext,\n    auditMetadata?: Record<string, unknown>,\n  ) {\n    super()\n    this.auditMetadata = auditMetadata\n  }\n\n  public async execute(): Promise<Result<EncryptedQueryResult, ProtectError>> {\n    if (this.plaintext === null || this.plaintext === undefined) {\n      return { data: null }\n    }\n\n    const validationError = validateNumericValue(this.plaintext)\n    if (validationError?.failure) {\n      return { failure: validationError.failure }\n    }\n\n    const lockContextResult = await this.lockContext.getLockContext()\n    if (lockContextResult.failure) {\n      return { failure: lockContextResult.failure }\n    }\n\n    const { ctsToken, context } = lockContextResult.data\n\n    return await withResult(\n      async () => {\n        if (!this.client) throw noClientError()\n\n        const { metadata } = this.getAuditData()\n\n        const { indexType, queryOp } = resolveIndexType(\n          this.opts.column,\n          this.opts.queryType,\n          this.plaintext,\n        )\n\n        // Validate value/index compatibility\n        assertValueIndexCompatibility(\n          this.plaintext,\n          indexType,\n          this.opts.column.getName(),\n        )\n\n        const encrypted = await ffiEncryptQuery(this.client, {\n          plaintext: this.plaintext as JsPlaintext,\n          column: this.opts.column.getName(),\n          table: this.opts.table.tableName,\n          indexType,\n          queryOp,\n          lockContext: context,\n          serviceToken: ctsToken,\n          unverifiedContext: metadata,\n        })\n\n        return formatEncryptedResult(encrypted, this.opts.returnType)\n      },\n      (error: unknown) => ({\n        type: ProtectErrorTypes.EncryptionError,\n        message: (error as Error).message,\n        code: getErrorCode(error),\n      }),\n    )\n  }\n}\n","import { type Result, withResult } from '@byteslice/result'\nimport { type ProtectError, ProtectErrorTypes } from '..'\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\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_ID 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  async identify(jwtToken: string): Promise<Result<LockContext, ProtectError>> {\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: ProtectErrorTypes.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: ProtectErrorTypes.CtsTokenError,\n        message: error.message,\n      }),\n    )\n\n    return identifiedLockContext\n  }\n\n  getLockContext(): Promise<Result<GetLockContextResponse, ProtectError>> {\n    return withResult(\n      () => {\n        if (!this.ctsToken?.accessToken && !this.ctsToken?.expiry) {\n          throw new Error(\n            'The CTS token is not set. Please call identify() with a users JWT token, or pass an existing CTS token to the LockContext constructor before calling getLockContext().',\n          )\n        }\n\n        return {\n          context: this.context,\n          ctsToken: this.ctsToken,\n        }\n      },\n      (error) => ({\n        type: ProtectErrorTypes.CtsTokenError,\n        message: error.message,\n      }),\n    )\n  }\n}\n","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 */\nfunction 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"],"mappings":"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","names":["import_schema","import_result","import_protect_ffi","path","import_protect_ffi","error","FfiProtectError","ffiEncryptQueryBulk","error","import_result","import_protect_ffi","error","import_result","import_protect_ffi","columnPaths","path","_","error","import_result","import_protect_ffi","createNullResult","error","import_result","error","import_result","import_protect_ffi","ffiDecrypt","error","import_result","error","import_result","import_protect_ffi","error","import_result","import_protect_ffi","ffiEncrypt","error","import_result","error","import_result","import_protect_ffi","ffiEncryptQuery","error","error","import_protect_ffi","import_schema","import_result","path","fs","error"]}