@cipherstash/stack 0.18.0 → 1.0.0-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (111) hide show
  1. package/CHANGELOG.md +704 -0
  2. package/README.md +97 -79
  3. package/dist/adapter-kit.cjs +923 -0
  4. package/dist/adapter-kit.cjs.map +1 -0
  5. package/dist/adapter-kit.d.cts +82 -0
  6. package/dist/adapter-kit.d.ts +82 -0
  7. package/dist/adapter-kit.js +47 -0
  8. package/dist/adapter-kit.js.map +1 -0
  9. package/dist/base-operation-AOAIvsSB.d.cts +32 -0
  10. package/dist/base-operation-FXEzUXIq.d.ts +32 -0
  11. package/dist/{chunk-VPOTNP4K.js → chunk-3B5ZX3IS.js} +3 -1
  12. package/dist/chunk-3B5ZX3IS.js.map +1 -0
  13. package/dist/chunk-7333ZC6L.js +48 -0
  14. package/dist/chunk-7333ZC6L.js.map +1 -0
  15. package/dist/{chunk-XWPGAHBZ.js → chunk-BNO32ZMV.js} +1 -1
  16. package/dist/chunk-BNO32ZMV.js.map +1 -0
  17. package/dist/chunk-CLM7E4I6.js +4439 -0
  18. package/dist/chunk-CLM7E4I6.js.map +1 -0
  19. package/dist/{chunk-LLCCNKDL.js → chunk-HQANMV7R.js} +3 -3
  20. package/dist/{chunk-LLCCNKDL.js.map → chunk-HQANMV7R.js.map} +1 -1
  21. package/dist/chunk-JSG2AMDI.js +17 -0
  22. package/dist/chunk-JSG2AMDI.js.map +1 -0
  23. package/dist/chunk-OFQ555AX.js +191 -0
  24. package/dist/chunk-OFQ555AX.js.map +1 -0
  25. package/dist/chunk-PZ5AY32C.js +10 -0
  26. package/dist/chunk-PZ5AY32C.js.map +1 -0
  27. package/dist/chunk-V2Q3NYIH.js +494 -0
  28. package/dist/chunk-V2Q3NYIH.js.map +1 -0
  29. package/dist/chunk-X3JRXEIB.js +98 -0
  30. package/dist/chunk-X3JRXEIB.js.map +1 -0
  31. package/dist/{chunk-ZYOZHZMJ.js → chunk-ZTP5QJ27.js} +193 -169
  32. package/dist/chunk-ZTP5QJ27.js.map +1 -0
  33. package/dist/client.cjs +4124 -49
  34. package/dist/client.cjs.map +1 -1
  35. package/dist/client.d.cts +6 -5
  36. package/dist/client.d.ts +6 -5
  37. package/dist/client.js +3 -1
  38. package/dist/columns-D2_YzrCX.d.cts +622 -0
  39. package/dist/columns-rZc7fQHI.d.ts +622 -0
  40. package/dist/dynamodb/index.cjs +19 -12
  41. package/dist/dynamodb/index.cjs.map +1 -1
  42. package/dist/dynamodb/index.d.cts +3 -2
  43. package/dist/dynamodb/index.d.ts +3 -2
  44. package/dist/dynamodb/index.js +8 -10
  45. package/dist/dynamodb/index.js.map +1 -1
  46. package/dist/encryption/index.cjs +4496 -222
  47. package/dist/encryption/index.cjs.map +1 -1
  48. package/dist/encryption/index.d.cts +807 -6
  49. package/dist/encryption/index.d.ts +807 -6
  50. package/dist/encryption/index.js +15 -7
  51. package/dist/encryption/v3.cjs +7896 -0
  52. package/dist/encryption/v3.cjs.map +1 -0
  53. package/dist/encryption/v3.d.cts +103 -0
  54. package/dist/encryption/v3.d.ts +103 -0
  55. package/dist/encryption/v3.js +189 -0
  56. package/dist/encryption/v3.js.map +1 -0
  57. package/dist/eql/v3/index.cjs +663 -0
  58. package/dist/eql/v3/index.cjs.map +1 -0
  59. package/dist/eql/v3/index.d.cts +173 -0
  60. package/dist/eql/v3/index.d.ts +173 -0
  61. package/dist/eql/v3/index.js +99 -0
  62. package/dist/eql/v3/index.js.map +1 -0
  63. package/dist/errors/index.js +1 -0
  64. package/dist/identity/index.cjs +55 -35
  65. package/dist/identity/index.cjs.map +1 -1
  66. package/dist/identity/index.d.cts +54 -30
  67. package/dist/identity/index.d.ts +54 -30
  68. package/dist/identity/index.js +9 -177
  69. package/dist/identity/index.js.map +1 -1
  70. package/dist/index-BquA71_Y.d.ts +24 -0
  71. package/dist/index-fhWTOV0K.d.cts +24 -0
  72. package/dist/index.cjs +4547 -243
  73. package/dist/index.cjs.map +1 -1
  74. package/dist/index.d.cts +18 -19
  75. package/dist/index.d.ts +18 -19
  76. package/dist/index.js +20 -5
  77. package/dist/index.js.map +1 -1
  78. package/dist/schema/index.cjs +4128 -49
  79. package/dist/schema/index.cjs.map +1 -1
  80. package/dist/schema/index.d.cts +1 -1
  81. package/dist/schema/index.d.ts +1 -1
  82. package/dist/schema/index.js +3 -1
  83. package/dist/{types-public-BTxqjmtv.d.cts → types-public-QMjYNfQO.d.cts} +448 -251
  84. package/dist/{types-public-BTxqjmtv.d.ts → types-public-QMjYNfQO.d.ts} +448 -251
  85. package/dist/types-public.cjs.map +1 -1
  86. package/dist/types-public.d.cts +2 -2
  87. package/dist/types-public.d.ts +2 -2
  88. package/dist/types-public.js +2 -1
  89. package/dist/wasm-inline.d.ts +1643 -0
  90. package/dist/wasm-inline.js +4901 -0
  91. package/dist/wasm-inline.js.map +1 -0
  92. package/package.json +74 -52
  93. package/dist/chunk-VPOTNP4K.js.map +0 -1
  94. package/dist/chunk-XWPGAHBZ.js.map +0 -1
  95. package/dist/chunk-YWQXTZ5M.js +0 -383
  96. package/dist/chunk-YWQXTZ5M.js.map +0 -1
  97. package/dist/chunk-ZYOZHZMJ.js.map +0 -1
  98. package/dist/client-CIsfZ2zg.d.ts +0 -692
  99. package/dist/client-Dt98Rugc.d.cts +0 -692
  100. package/dist/drizzle/index.cjs +0 -1558
  101. package/dist/drizzle/index.cjs.map +0 -1
  102. package/dist/drizzle/index.d.cts +0 -358
  103. package/dist/drizzle/index.d.ts +0 -358
  104. package/dist/drizzle/index.js +0 -1215
  105. package/dist/drizzle/index.js.map +0 -1
  106. package/dist/supabase/index.cjs +0 -1526
  107. package/dist/supabase/index.cjs.map +0 -1
  108. package/dist/supabase/index.d.cts +0 -144
  109. package/dist/supabase/index.d.ts +0 -144
  110. package/dist/supabase/index.js +0 -899
  111. package/dist/supabase/index.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/schema/index.ts"],"sourcesContent":["import type { Encrypted } from '@/types'\nimport { z } from 'zod'\n\n// ------------------------\n// Zod schemas\n// ------------------------\n\n/**\n * Allowed cast types for CipherStash schema fields.\n *\n * **Possible values:**\n * - `\"bigint\"`\n * - `\"boolean\"`\n * - `\"date\"`\n * - `\"number\"`\n * - `\"string\"`\n * - `\"json\"`\n * - `\"text\"`\n *\n * @remarks\n * This is a Zod enum used at runtime to validate schema definitions.\n * Use {@link CastAs} when typing your own code.\n *\n * @internal\n */\n/**\n * EQL cast types — the PostgreSQL-aligned types that EQL actually accepts.\n * These are stored in the `cast_as` field of the EncryptConfig.\n */\nexport const eqlCastAsEnum = z\n .enum([\n 'text',\n 'int',\n 'small_int',\n 'big_int',\n 'real',\n 'double',\n 'boolean',\n 'date',\n 'jsonb',\n ])\n .default('text')\n\n/**\n * SDK-facing data types — developer-friendly aliases accepted by `dataType()`.\n */\nexport const castAsEnum = z\n .enum(['bigint', 'boolean', 'date', 'number', 'string', 'json', 'text'])\n .default('text')\n\n/**\n * Map SDK-facing data types to EQL `cast_as` values.\n *\n * The SDK accepts developer-friendly types like `'string'` and `'number'`,\n * but EQL expects PostgreSQL-aligned types like `'text'` and `'double'`.\n */\nexport function toEqlCastAs(value: CastAs): EqlCastAs {\n switch (value) {\n case 'string':\n return 'text'\n case 'text':\n return 'text'\n case 'number':\n return 'double'\n case 'bigint':\n return 'big_int'\n case 'boolean':\n return 'boolean'\n case 'date':\n return 'date'\n case 'json':\n return 'jsonb'\n }\n}\n\nconst tokenFilterSchema = z.object({\n kind: z.literal('downcase'),\n})\n\nconst tokenizerSchema = z\n .union([\n z.object({\n kind: z.literal('standard'),\n }),\n z.object({\n kind: z.literal('ngram'),\n token_length: z.number(),\n }),\n ])\n .default({ kind: 'ngram', token_length: 3 })\n .optional()\n\nconst oreIndexOptsSchema = z.object({})\n\nconst uniqueIndexOptsSchema = z.object({\n token_filters: z.array(tokenFilterSchema).default([]).optional(),\n})\n\nconst matchIndexOptsSchema = z.object({\n tokenizer: tokenizerSchema,\n token_filters: z.array(tokenFilterSchema).default([]).optional(),\n k: z.number().default(6).optional(),\n m: z.number().default(2048).optional(),\n include_original: z.boolean().default(false).optional(),\n})\n\nconst arrayIndexModeSchema = z.union([\n z.literal('all'),\n z.literal('none'),\n z.object({\n item: z.boolean().optional(),\n wildcard: z.boolean().optional(),\n position: z.boolean().optional(),\n }),\n])\n\nconst steVecIndexOptsSchema = z.object({\n prefix: z.string(),\n array_index_mode: arrayIndexModeSchema.optional(),\n})\n\nconst indexesSchema = z\n .object({\n ore: oreIndexOptsSchema.optional(),\n unique: uniqueIndexOptsSchema.optional(),\n match: matchIndexOptsSchema.optional(),\n ste_vec: steVecIndexOptsSchema.optional(),\n })\n .default({})\n\nconst columnSchema = z\n .object({\n cast_as: castAsEnum,\n indexes: indexesSchema,\n })\n .default({})\n\nconst tableSchema = z.record(columnSchema).default({})\n\nconst tablesSchema = z.record(tableSchema).default({})\n\n/** @internal */\nexport const encryptConfigSchema = z.object({\n v: z.number(),\n tables: tablesSchema,\n})\n\n// ------------------------\n// Type definitions\n// ------------------------\n\n/**\n * Type-safe alias for {@link castAsEnum} used to specify the *unencrypted* data type of a column or value.\n * This is important because once encrypted, all data is stored as binary blobs.\n *\n * @see {@link castAsEnum} for possible values.\n */\nexport type CastAs = z.infer<typeof castAsEnum>\nexport type EqlCastAs = z.infer<typeof eqlCastAsEnum>\nexport type TokenFilter = z.infer<typeof tokenFilterSchema>\nexport type MatchIndexOpts = z.infer<typeof matchIndexOptsSchema>\nexport type SteVecIndexOpts = z.infer<typeof steVecIndexOptsSchema>\nexport type UniqueIndexOpts = z.infer<typeof uniqueIndexOptsSchema>\nexport type OreIndexOpts = z.infer<typeof oreIndexOptsSchema>\nexport type ColumnSchema = z.infer<typeof columnSchema>\n\n/**\n * Shape of table columns: either top-level {@link EncryptedColumn} or nested\n * objects whose leaves are {@link EncryptedField}. Used with {@link encryptedTable}.\n */\nexport type EncryptedTableColumn = {\n [key: string]:\n | EncryptedColumn\n | {\n [key: string]:\n | EncryptedField\n | {\n [key: string]:\n | EncryptedField\n | {\n [key: string]: EncryptedField\n }\n }\n }\n}\nexport type EncryptConfig = z.infer<typeof encryptConfigSchema>\n\n// ------------------------\n// Interface definitions\n// ------------------------\n\n/**\n * Builder for a nested encrypted field (encrypted but not searchable).\n * Create with {@link encryptedField}. Use inside nested objects in {@link encryptedTable};\n * supports `.dataType()` for plaintext type. No index methods (equality, orderAndRange, etc.).\n */\nexport class EncryptedField {\n private valueName: string\n private castAsValue: CastAs\n\n constructor(valueName: string) {\n this.valueName = valueName\n this.castAsValue = 'string'\n }\n\n /**\n * Set or override the plaintext data type for this field.\n *\n * By default all values are treated as `'string'`. Use this method to specify\n * a different type so the encryption layer knows how to encode the plaintext\n * before encrypting.\n *\n * @param castAs - The plaintext data type: `'string'`, `'number'`, `'boolean'`, `'date'`, `'text'`, `'bigint'`, or `'json'`.\n * @returns This `EncryptedField` instance for method chaining.\n *\n * @example\n * ```typescript\n * import { encryptedField } from \"@cipherstash/stack/schema\"\n *\n * const age = encryptedField(\"age\").dataType(\"number\")\n * ```\n */\n dataType(castAs: CastAs) {\n this.castAsValue = castAs\n return this\n }\n\n build() {\n return {\n cast_as: this.castAsValue,\n indexes: {},\n }\n }\n\n getName() {\n return this.valueName\n }\n}\n\nexport class EncryptedColumn {\n private columnName: string\n private castAsValue: CastAs\n private indexesValue: {\n ore?: OreIndexOpts\n unique?: UniqueIndexOpts\n match?: Required<MatchIndexOpts>\n ste_vec?: SteVecIndexOpts\n } = {}\n\n constructor(columnName: string) {\n this.columnName = columnName\n this.castAsValue = 'string'\n }\n\n /**\n * Set or override the plaintext data type for this column.\n *\n * By default all columns are treated as `'string'`. Use this method to specify\n * a different type so the encryption layer knows how to encode the plaintext\n * before encrypting.\n *\n * @param castAs - The plaintext data type: `'string'`, `'number'`, `'boolean'`, `'date'`, `'bigint'`, or `'json'`.\n * @returns This `EncryptedColumn` instance for method chaining.\n *\n * @example\n * ```typescript\n * import { encryptedColumn } from \"@cipherstash/stack/schema\"\n *\n * const dateOfBirth = encryptedColumn(\"date_of_birth\").dataType(\"date\")\n * ```\n */\n dataType(castAs: CastAs) {\n this.castAsValue = castAs\n return this\n }\n\n /**\n * Enable Order-Revealing Encryption (ORE) indexing on this column.\n *\n * ORE allows sorting, comparison, and range queries on encrypted data.\n * Use with `encryptQuery` and `queryType: 'orderAndRange'`.\n *\n * @returns This `EncryptedColumn` instance for method chaining.\n *\n * @example\n * ```typescript\n * import { encryptedTable, encryptedColumn } from \"@cipherstash/stack/schema\"\n *\n * const users = encryptedTable(\"users\", {\n * email: encryptedColumn(\"email\").orderAndRange(),\n * })\n * ```\n */\n orderAndRange() {\n this.indexesValue.ore = {}\n return this\n }\n\n /**\n * Enable an exact-match (unique) index on this column.\n *\n * Allows equality queries on encrypted data. Use with `encryptQuery`\n * and `queryType: 'equality'`.\n *\n * @param tokenFilters - Optional array of token filters (e.g. `[{ kind: 'downcase' }]`).\n * When omitted, no token filters are applied.\n * @returns This `EncryptedColumn` instance for method chaining.\n *\n * @example\n * ```typescript\n * import { encryptedTable, encryptedColumn } from \"@cipherstash/stack/schema\"\n *\n * const users = encryptedTable(\"users\", {\n * email: encryptedColumn(\"email\").equality(),\n * })\n * ```\n */\n equality(tokenFilters?: TokenFilter[]) {\n this.indexesValue.unique = {\n token_filters: tokenFilters ?? [],\n }\n return this\n }\n\n /**\n * Enable a full-text / fuzzy search (match) index on this column.\n *\n * Uses n-gram tokenization by default for substring and fuzzy matching.\n * Use with `encryptQuery` and `queryType: 'freeTextSearch'`.\n *\n * @param opts - Optional match index configuration. Defaults to 3-character ngram\n * tokenization with a downcase filter, `k=6`, `m=2048`, and `include_original=true`.\n * @returns This `EncryptedColumn` instance for method chaining.\n *\n * @example\n * ```typescript\n * import { encryptedTable, encryptedColumn } from \"@cipherstash/stack/schema\"\n *\n * const users = encryptedTable(\"users\", {\n * email: encryptedColumn(\"email\").freeTextSearch(),\n * })\n *\n * // With custom options\n * const posts = encryptedTable(\"posts\", {\n * body: encryptedColumn(\"body\").freeTextSearch({\n * tokenizer: { kind: \"ngram\", token_length: 4 },\n * k: 8,\n * m: 4096,\n * }),\n * })\n * ```\n */\n freeTextSearch(opts?: MatchIndexOpts) {\n // Provide defaults\n this.indexesValue.match = {\n tokenizer: opts?.tokenizer ?? { kind: 'ngram', token_length: 3 },\n token_filters: opts?.token_filters ?? [\n {\n kind: 'downcase',\n },\n ],\n k: opts?.k ?? 6,\n m: opts?.m ?? 2048,\n include_original: opts?.include_original ?? true,\n }\n return this\n }\n\n /**\n * Configure this column for searchable encrypted JSON (STE-Vec).\n *\n * Enables encrypted JSONPath selector queries (e.g. `'$.user.email'`) and\n * containment queries (e.g. `{ role: 'admin' }`). Automatically sets the\n * data type to `'json'`.\n *\n * When used with `encryptQuery`, the query operation is auto-inferred from\n * the plaintext type: strings become selector queries, objects/arrays become\n * containment queries.\n *\n * @returns This `EncryptedColumn` instance for method chaining.\n *\n * @example\n * ```typescript\n * import { encryptedTable, encryptedColumn } from \"@cipherstash/stack/schema\"\n *\n * const documents = encryptedTable(\"documents\", {\n * metadata: encryptedColumn(\"metadata\").searchableJson(),\n * })\n * ```\n */\n searchableJson() {\n this.castAsValue = 'json'\n this.indexesValue.ste_vec = { prefix: 'enabled', array_index_mode: 'all' }\n return this\n }\n\n build() {\n return {\n cast_as: this.castAsValue,\n indexes: this.indexesValue,\n }\n }\n\n getName() {\n return this.columnName\n }\n}\n\ninterface TableDefinition {\n tableName: string\n columns: Record<string, ColumnSchema>\n}\n\nexport class EncryptedTable<T extends EncryptedTableColumn> {\n /** @internal Type-level brand so TypeScript can infer `T` from `EncryptedTable<T>`. */\n declare readonly _columnType: T\n\n constructor(\n public readonly tableName: string,\n public readonly columnBuilders: T,\n ) {}\n\n /**\n * Compile this table schema into a `TableDefinition` used internally by the encryption client.\n *\n * Iterates over all column builders, calls `.build()` on each, and assembles\n * the final `{ tableName, columns }` structure. For `searchableJson()` columns,\n * the STE-Vec prefix is automatically set to `\"<tableName>/<columnName>\"`.\n *\n * @returns A `TableDefinition` containing the table name and built column configs.\n *\n * @example\n * ```typescript\n * const users = encryptedTable(\"users\", {\n * email: encryptedColumn(\"email\").equality(),\n * })\n *\n * const definition = users.build()\n * // { tableName: \"users\", columns: { email: { cast_as: \"string\", indexes: { unique: ... } } } }\n * ```\n */\n build(): TableDefinition {\n const builtColumns: Record<string, ColumnSchema> = {}\n\n const processColumn = (\n builder:\n | EncryptedColumn\n | Record<\n string,\n | EncryptedField\n | Record<\n string,\n | EncryptedField\n | Record<\n string,\n EncryptedField | Record<string, EncryptedField>\n >\n >\n >,\n colName: string,\n ) => {\n if (builder instanceof EncryptedColumn) {\n const builtColumn = builder.build()\n\n // Hanlde building the ste_vec index for JSON columns so users don't have to pass the prefix.\n if (\n builtColumn.cast_as === 'json' &&\n builtColumn.indexes.ste_vec?.prefix === 'enabled'\n ) {\n builtColumns[colName] = {\n ...builtColumn,\n indexes: {\n ...builtColumn.indexes,\n ste_vec: {\n ...builtColumn.indexes.ste_vec,\n prefix: `${this.tableName}/${colName}`,\n },\n },\n }\n } else {\n builtColumns[colName] = builtColumn\n }\n } else {\n for (const [key, value] of Object.entries(builder)) {\n if (value instanceof EncryptedField) {\n builtColumns[value.getName()] = value.build()\n } else {\n processColumn(value, key)\n }\n }\n }\n }\n\n for (const [colName, builder] of Object.entries(this.columnBuilders)) {\n processColumn(builder, colName)\n }\n\n return {\n tableName: this.tableName,\n columns: builtColumns,\n }\n }\n}\n\n// ------------------------\n// Schema type inference helpers\n// ------------------------\n\n/**\n * Infer the plaintext (decrypted) type from a EncryptedTable schema.\n *\n * @example\n * ```typescript\n * const users = encryptedTable(\"users\", {\n * email: encryptedColumn(\"email\").equality(),\n * name: encryptedColumn(\"name\"),\n * })\n *\n * type UserPlaintext = InferPlaintext<typeof users>\n * // => { email: string; name: string }\n * ```\n */\nexport type InferPlaintext<T extends EncryptedTable<any>> =\n T extends EncryptedTable<infer C>\n ? {\n [K in keyof C as C[K] extends EncryptedColumn | EncryptedField\n ? K\n : never]: string\n }\n : never\n\n/**\n * Infer the encrypted type from a EncryptedTable schema.\n *\n * @example\n * ```typescript\n * const users = encryptedTable(\"users\", {\n * email: encryptedColumn(\"email\").equality(),\n * })\n *\n * type UserEncrypted = InferEncrypted<typeof users>\n * // => { email: Encrypted }\n * ```\n */\nexport type InferEncrypted<T extends EncryptedTable<any>> =\n T extends EncryptedTable<infer C>\n ? {\n [K in keyof C as C[K] extends EncryptedColumn | EncryptedField\n ? K\n : never]: Encrypted\n }\n : never\n\n// ------------------------\n// User facing functions\n// ------------------------\n\n/**\n * Define an encrypted table schema.\n *\n * Creates a `EncryptedTable` that maps a database table name to a set of encrypted\n * column definitions. Pass the resulting object to `Encryption({ schemas: [...] })`\n * when initializing the client.\n *\n * The returned object is also a proxy that exposes each column builder directly,\n * so you can reference columns as `users.email` when calling `encrypt`, `decrypt`,\n * and `encryptQuery`.\n *\n * @param tableName - The name of the database table this schema represents.\n * @param columns - An object whose keys are logical column names and values are\n * {@link EncryptedColumn} from {@link encryptedColumn}, or nested objects whose\n * leaves are {@link EncryptedField} from {@link encryptedField}.\n * @returns A `EncryptedTable<T> & T` that can be used as both a schema definition\n * and a column accessor.\n *\n * @example\n * ```typescript\n * import { encryptedTable, encryptedColumn } from \"@cipherstash/stack/schema\"\n *\n * const users = encryptedTable(\"users\", {\n * email: encryptedColumn(\"email\").equality().freeTextSearch(),\n * address: encryptedColumn(\"address\"),\n * })\n *\n * // Use as schema\n * const client = await Encryption({ schemas: [users] })\n *\n * // Use as column accessor\n * await client.encrypt(\"hello@example.com\", { column: users.email, table: users })\n * ```\n */\nexport function encryptedTable<T extends EncryptedTableColumn>(\n tableName: string,\n columns: T,\n): EncryptedTable<T> & T {\n const tableBuilder = new EncryptedTable(\n tableName,\n columns,\n ) as EncryptedTable<T> & T\n\n for (const [colName, colBuilder] of Object.entries(columns)) {\n ;(tableBuilder as EncryptedTableColumn)[colName] = colBuilder\n }\n\n return tableBuilder\n}\n\n/**\n * Define an encrypted column within a table schema.\n *\n * Creates a `EncryptedColumn` builder for the given column name. Chain index\n * methods (`.equality()`, `.freeTextSearch()`, `.orderAndRange()`,\n * `.searchableJson()`) and/or `.dataType()` to configure searchable encryption\n * and the plaintext data type.\n *\n * @param columnName - The name of the database column to encrypt.\n * @returns A new `EncryptedColumn` builder.\n *\n * @example\n * ```typescript\n * import { encryptedTable, encryptedColumn } from \"@cipherstash/stack/schema\"\n *\n * const users = encryptedTable(\"users\", {\n * email: encryptedColumn(\"email\").equality().freeTextSearch().orderAndRange(),\n * })\n * ```\n */\nexport function encryptedColumn(columnName: string) {\n return new EncryptedColumn(columnName)\n}\n\n/**\n * Define an encrypted field for use in nested or structured schemas.\n *\n * `encryptedField` is similar to {@link encryptedColumn} but creates an {@link EncryptedField}\n * for nested fields that are encrypted but not searchable (no indexes). Use `.dataType()`\n * to specify the plaintext type.\n *\n * @param valueName - The name of the value field.\n * @returns A new `EncryptedField` builder.\n *\n * @example\n * ```typescript\n * import { encryptedTable, encryptedField } from \"@cipherstash/stack/schema\"\n *\n * const orders = encryptedTable(\"orders\", {\n * details: {\n * amount: encryptedField(\"amount\").dataType(\"number\"),\n * currency: encryptedField(\"currency\"),\n * },\n * })\n * ```\n */\nexport function encryptedField(valueName: string) {\n return new EncryptedField(valueName)\n}\n\n/**\n * Build an encrypt config from a list of encrypted tables.\n *\n * @param protectTables - The list of encrypted tables to build the config from.\n * @returns An encrypt config object.\n *\n * @example\n * ```typescript\n * import { buildEncryptConfig } from \"@cipherstash/stack/schema\"\n *\n * const users = encryptedTable(\"users\", {\n * email: encryptedColumn(\"email\").equality(),\n * })\n *\n * const orders = encryptedTable(\"orders\", {\n * amount: encryptedColumn(\"amount\").dataType(\"number\"),\n * })\n *\n * const config = buildEncryptConfig(users, orders)\n * console.log(config)\n * ```\n */\nexport function buildEncryptConfig(\n ...protectTables: Array<EncryptedTable<EncryptedTableColumn>>\n): EncryptConfig {\n const config: EncryptConfig = {\n v: 1,\n tables: {},\n }\n\n for (const tb of protectTables) {\n const tableDef = tb.build()\n config.tables[tableDef.tableName] = tableDef.columns\n }\n\n return config\n}\n"],"mappings":"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","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/encryption/index.ts","../../../node_modules/.pnpm/uuid@14.0.0/node_modules/uuid/dist-node/regex.js","../../../node_modules/.pnpm/uuid@14.0.0/node_modules/uuid/dist-node/validate.js","../src/encryption/helpers/type-guards.ts","../src/encryption/helpers/error-code.ts","../src/encryption/operations/batch-encrypt-query.ts","../src/encryption/helpers/infer-index-type.ts","../src/encryption/helpers/validation.ts","../src/encryption/operations/base-operation.ts","../src/encryption/operations/bulk-decrypt.ts","../src/encryption/operations/bulk-decrypt-models.ts","../src/encryption/helpers/model-helpers.ts","../src/encryption/operations/bulk-encrypt.ts","../src/encryption/operations/bulk-encrypt-models.ts","../src/encryption/operations/decrypt.ts","../src/encryption/operations/decrypt-model.ts","../src/encryption/operations/encrypt.ts","../src/encryption/operations/encrypt-model.ts","../src/encryption/operations/encrypt-query.ts"],"sourcesContent":["import { type EncryptionError, EncryptionErrorTypes } from '@/errors'\n// `LockContext` is imported type-only so the TSDoc {@link} references in the\n// comments below resolve; it is erased at compile time.\nimport type { LockContext } from '@/identity'\nimport {\n type EncryptConfig,\n type EncryptedTable,\n type EncryptedTableColumn,\n buildEncryptConfig,\n encryptConfigSchema,\n // Imported type-only for the TSDoc {@link} references in the comments below.\n type encryptedColumn,\n type encryptedField,\n type encryptedTable,\n} from '@/schema'\nimport type {\n BulkDecryptPayload,\n BulkEncryptPayload,\n Client,\n EncryptOptions,\n EncryptQueryOptions,\n Encrypted,\n EncryptedFromSchema,\n KeysetIdentifier,\n ScalarQueryTerm,\n} from '@/types'\nimport type { EncryptionClientConfig } from '@/types'\nimport { logger } from '@/utils/logger'\nimport { type Result, withResult } from '@byteslice/result'\nimport { type JsPlaintext, newClient } from '@cipherstash/protect-ffi'\nimport { validate as uuidValidate } from 'uuid'\nimport { toFfiKeysetIdentifier } from './helpers'\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 { EncryptOperation } from './operations/encrypt'\nimport { EncryptModelOperation } from './operations/encrypt-model'\nimport { EncryptQueryOperation } from './operations/encrypt-query'\n\n// Re-export the operation classes returned by EncryptionClient methods so they\n// are part of the public API and appear in the generated reference, allowing\n// TSDoc {@link} references and method return types to resolve to real pages.\nexport {\n EncryptOperation,\n EncryptQueryOperation,\n BatchEncryptQueryOperation,\n DecryptOperation,\n EncryptModelOperation,\n DecryptModelOperation,\n BulkEncryptOperation,\n BulkDecryptOperation,\n BulkEncryptModelsOperation,\n BulkDecryptModelsOperation,\n}\n\nexport const noClientError = () =>\n new Error(\n 'The Encryption client has not been initialized. Please call init() before using the client.',\n )\n\n/** The EncryptionClient is the main entry point for interacting with the CipherStash Encryption 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 Encryption} function before it can be used.\n */\nexport class EncryptionClient {\n private client: Client\n private encryptConfig: EncryptConfig | undefined\n\n /**\n * Initializes the EncryptionClient 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 EncryptionClient or an {@link EncryptionError}.\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<EncryptionClient, EncryptionError>> {\n return await withResult(\n async () => {\n const validated: EncryptConfig = encryptConfigSchema.parse(\n config.encryptConfig,\n )\n\n logger.debug(\n 'Initializing the Encryption client with the following 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.debug('Successfully initialized the Encryption client.')\n return this\n },\n (error: unknown) => ({\n type: EncryptionErrorTypes.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.\n * @param opts - Options specifying the column (or nested field) and table for encryption. See {@link EncryptOptions}.\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 Encryption client.\n * It includes defining an encryption schema with {@link encryptedTable} and {@link encryptedColumn},\n * initializing the client with {@link Encryption}, 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 an {@link EncryptionError}.\n *\n * ```typescript\n * // Define encryption schema\n * import { Encryption } from \"@cipherstash/stack\"\n * import { encryptedTable, encryptedColumn } from \"@cipherstash/stack/schema\"\n * const userSchema = encryptedTable(\"users\", {\n * email: encryptedColumn(\"email\"),\n * });\n *\n * // Initialize Encryption client\n * const client = await Encryption({ schemas: [userSchema] })\n *\n * // Encrypt a value\n * const encryptedResult = await client.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 client.encrypt(\n * \"person@example.com\",\n * { column: userSchema.email, table: userSchema }\n * )\n * .withLockContext(lockContext)\n * ```\n *\n * @see {@link EncryptOptions}\n * @see {@link Result}\n * @see {@link encryptedTable}\n * @see {@link encryptedColumn}\n * @see {@link encryptedField}\n * @see {@link LockContext}\n * @see {@link EncryptOperation}\n */\n encrypt(plaintext: JsPlaintext, opts: EncryptOptions): 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.\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 Encryption client.\n *\n * ```typescript\n * // Define encryption schema\n * import { Encryption } from \"@cipherstash/stack\"\n * import { encryptedTable, encryptedColumn } from \"@cipherstash/stack/schema\"\n * const userSchema = encryptedTable(\"users\", {\n * email: encryptedColumn(\"email\").equality(),\n * });\n *\n * // Initialize Encryption client\n * const client = await Encryption({ schemas: [userSchema] })\n *\n * // Encrypt a query value\n * const encryptedResult = await client.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 client.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,\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 | 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 if (!opts) {\n throw new Error('EncryptQueryOptions are required')\n }\n\n return new EncryptQueryOperation(\n this.client,\n plaintextOrTerms as JsPlaintext,\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 the {@link encrypt} method.\n * It includes encrypting a value first, then decrypting it, and handling the result.\n *\n * ```typescript\n * const encryptedData = await client.encrypt(\n * \"person@example.com\",\n * { column: \"email\", table: \"users\" }\n * )\n * const decryptResult = await client.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 client.decrypt(encryptedData)\n * .withLockContext(lockContext)\n * ```\n *\n * @remarks\n * The public input type rejects null, but at runtime `decrypt` will\n * short-circuit and return null when given a null ciphertext\n * (defense in depth for legacy / manually-NULLed DB rows reached via\n * casts or dynamic field walking). The narrow return type holds for\n * any caller that respects the input contract.\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 (object) based on the table schema.\n *\n * Only fields whose keys match columns defined in the table schema are encrypted.\n * All other fields are passed through unchanged. Returns a thenable operation\n * that supports `.withLockContext()` for identity-aware encryption.\n *\n * The return type is **schema-aware**: fields matching the table schema are\n * typed as `Encrypted`, while other fields retain their original types. For\n * best results, let TypeScript infer the type parameters from the arguments\n * rather than providing an explicit type argument.\n *\n * @param input - The model object with plaintext values to encrypt.\n * @param table - The table schema defining which fields to encrypt.\n * @returns An `EncryptModelOperation` that can be awaited to get a `Result`\n * containing the model with schema-defined fields typed as `Encrypted`,\n * or an `EncryptionError`.\n *\n * @example\n * ```typescript\n * import { Encryption } from \"@cipherstash/stack\"\n * import { encryptedTable, encryptedColumn } from \"@cipherstash/stack/schema\"\n *\n * type User = { id: string; email: string; createdAt: Date }\n *\n * const usersSchema = encryptedTable(\"users\", {\n * email: encryptedColumn(\"email\").equality(),\n * })\n *\n * const client = await Encryption({ schemas: [usersSchema] })\n *\n * // Let TypeScript infer the return type from the schema.\n * // result.data.email is typed as `Encrypted`, result.data.id stays `string`.\n * const result = await client.encryptModel(\n * { id: \"user_123\", email: \"alice@example.com\", createdAt: new Date() },\n * usersSchema,\n * )\n *\n * if (result.failure) {\n * console.error(result.failure.message)\n * } else {\n * console.log(result.data.id) // string\n * console.log(result.data.email) // Encrypted\n * }\n * ```\n */\n encryptModel<\n T extends Record<string, unknown>,\n S extends EncryptedTableColumn = EncryptedTableColumn,\n >(\n input: T,\n table: EncryptedTable<S>,\n ): EncryptModelOperation<EncryptedFromSchema<T, S>> {\n return new EncryptModelOperation(\n this.client,\n input as Record<string, unknown>,\n table,\n )\n }\n\n /**\n * Decrypt a model (object) whose fields contain encrypted values.\n *\n * Identifies encrypted fields automatically and decrypts them, returning the\n * model with plaintext values. Returns a thenable operation that supports\n * `.withLockContext()` for identity-aware decryption.\n *\n * @param input - The model object with encrypted field values.\n * @returns A `DecryptModelOperation<T>` that can be awaited to get a `Result`\n * containing the model with decrypted plaintext fields, or an `EncryptionError`.\n *\n * @example\n * ```typescript\n * // Decrypt a previously encrypted model\n * const decrypted = await client.decryptModel<User>(encryptedUser)\n *\n * if (decrypted.failure) {\n * console.error(decrypted.failure.message)\n * } else {\n * console.log(decrypted.data.email) // \"alice@example.com\"\n * }\n *\n * // With a lock context\n * const decrypted = await client\n * .decryptModel<User>(encryptedUser)\n * .withLockContext(lockContext)\n * ```\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 * Encrypt multiple models (objects) in a single bulk operation.\n *\n * Performs a single call to ZeroKMS regardless of the number of models,\n * while still using a unique key for each encrypted value. Only fields\n * matching the table schema are encrypted; other fields pass through unchanged.\n *\n * The return type is **schema-aware**: fields matching the table schema are\n * typed as `Encrypted`, while other fields retain their original types. For\n * best results, let TypeScript infer the type parameters from the arguments.\n *\n * @param input - An array of model objects with plaintext values to encrypt.\n * @param table - The table schema defining which fields to encrypt.\n * @returns A `BulkEncryptModelsOperation` that can be awaited to get a `Result`\n * containing an array of models with schema-defined fields typed as `Encrypted`,\n * or an `EncryptionError`.\n *\n * @example\n * ```typescript\n * import { Encryption } from \"@cipherstash/stack\"\n * import { encryptedTable, encryptedColumn } from \"@cipherstash/stack/schema\"\n *\n * type User = { id: string; email: string }\n *\n * const usersSchema = encryptedTable(\"users\", {\n * email: encryptedColumn(\"email\"),\n * })\n *\n * const client = await Encryption({ schemas: [usersSchema] })\n *\n * // Let TypeScript infer the return type from the schema.\n * // Each item's email is typed as `Encrypted`, id stays `string`.\n * const result = await client.bulkEncryptModels(\n * [\n * { id: \"1\", email: \"alice@example.com\" },\n * { id: \"2\", email: \"bob@example.com\" },\n * ],\n * usersSchema,\n * )\n *\n * if (!result.failure) {\n * console.log(result.data) // array of models with encrypted email fields\n * }\n * ```\n */\n bulkEncryptModels<\n T extends Record<string, unknown>,\n S extends EncryptedTableColumn = EncryptedTableColumn,\n >(\n input: Array<T>,\n table: EncryptedTable<S>,\n ): BulkEncryptModelsOperation<EncryptedFromSchema<T, S>> {\n return new BulkEncryptModelsOperation(\n this.client,\n input as Array<Record<string, unknown>>,\n table,\n )\n }\n\n /**\n * Decrypt multiple models (objects) in a single bulk operation.\n *\n * Performs a single call to ZeroKMS regardless of the number of models,\n * restoring all encrypted fields to their original plaintext values.\n *\n * @param input - An array of model objects with encrypted field values.\n * @returns A `BulkDecryptModelsOperation<T>` that can be awaited to get a `Result`\n * containing an array of models with decrypted plaintext fields, or an `EncryptionError`.\n *\n * @example\n * ```typescript\n * const encryptedUsers = encryptedResult.data // from bulkEncryptModels\n *\n * const result = await client.bulkDecryptModels<User>(encryptedUsers)\n *\n * if (!result.failure) {\n * for (const user of result.data) {\n * console.log(user.email) // plaintext email\n * }\n * }\n *\n * // With a lock context\n * const result = await client\n * .bulkDecryptModels<User>(encryptedUsers)\n * .withLockContext(lockContext)\n * ```\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 * Encrypt multiple plaintext values in a single bulk operation.\n *\n * Each value is encrypted with its own unique key via a single call to ZeroKMS.\n * Values can include optional `id` fields for correlating results back to\n * your application data.\n *\n * @param plaintexts - An array of objects with `plaintext` (and optional `id`) fields.\n * @param opts - Options specifying the target column (or nested {@link encryptedField}) and table. See {@link EncryptOptions}.\n * @returns A `BulkEncryptOperation` that can be awaited to get a `Result`\n * containing an array of `{ id?, data: Encrypted }` objects, or an `EncryptionError`.\n *\n * @example\n * ```typescript\n * import { Encryption } from \"@cipherstash/stack\"\n * import { encryptedTable, encryptedColumn } from \"@cipherstash/stack/schema\"\n *\n * const users = encryptedTable(\"users\", {\n * email: encryptedColumn(\"email\"),\n * })\n * const client = await Encryption({ schemas: [users] })\n *\n * const result = await client.bulkEncrypt(\n * [\n * { id: \"u1\", plaintext: \"alice@example.com\" },\n * { id: \"u2\", plaintext: \"bob@example.com\" },\n * ],\n * { column: users.email, table: users },\n * )\n *\n * if (!result.failure) {\n * // result.data = [{ id: \"u1\", data: Encrypted }, { id: \"u2\", data: Encrypted }, ...]\n * console.log(result.data)\n * }\n * ```\n */\n bulkEncrypt(\n plaintexts: BulkEncryptPayload,\n opts: EncryptOptions,\n ): BulkEncryptOperation {\n return new BulkEncryptOperation(this.client, plaintexts, opts)\n }\n\n /**\n * Decrypt multiple encrypted values in a single bulk operation.\n *\n * Performs a single call to ZeroKMS to decrypt all values. The result uses\n * a multi-status pattern: each item in the returned array has either a `data`\n * field (success) or an `error` field (failure), allowing graceful handling\n * of partial failures.\n *\n * @param encryptedPayloads - An array of objects with `data` (encrypted payload) and optional `id` fields.\n * @returns A `BulkDecryptOperation` that can be awaited to get a `Result`\n * containing an array of `{ id?, data: plaintext }` or `{ id?, error: string }` objects,\n * or an `EncryptionError` if the entire operation fails.\n *\n * @example\n * ```typescript\n * const encrypted = await client.bulkEncrypt(plaintexts, { column: users.email, table: users })\n *\n * const result = await client.bulkDecrypt(encrypted.data)\n *\n * if (!result.failure) {\n * for (const item of result.data) {\n * if (\"data\" in item) {\n * console.log(`${item.id}: ${item.data}`)\n * } else {\n * console.error(`${item.id} failed: ${item.error}`)\n * }\n * }\n * }\n * ```\n */\n bulkDecrypt(encryptedPayloads: BulkDecryptPayload): BulkDecryptOperation {\n return new BulkDecryptOperation(this.client, encryptedPayloads)\n }\n\n /**\n * Get the encrypt config object.\n *\n * @returns The encrypt config object.\n */\n getEncryptConfig(): EncryptConfig | undefined {\n return this.encryptConfig\n }\n}\n\n/**\n * Creates and initializes an Encryption client for encrypting and decrypting data with CipherStash.\n *\n * Provide at least one schema (from {@link encryptedTable}) so the client knows which tables and\n * columns to use. Credentials are read from the optional `config` or from the environment\n * (`CS_WORKSPACE_CRN`, `CS_CLIENT_ID`, `CS_CLIENT_KEY`, `CS_CLIENT_ACCESS_KEY`).\n *\n * @param config - Initialization options. Must include `schemas`; optionally include `config` for\n * workspace/keys. Logging is configured via the `STASH_STACK_LOG` environment variable\n * (`debug | info | error`, default: `error`).\n * @returns A Promise that resolves to an initialized {@link EncryptionClient} ready for\n * {@link EncryptionClient.encrypt}, {@link EncryptionClient.decrypt}, and related operations.\n *\n * @throws Throws if `schemas` is empty, or if a keyset `id` is supplied but is not a valid UUID.\n * Also throws if the client fails to initialize (e.g. invalid credentials or config).\n *\n * @example\n * ```typescript\n * import { Encryption, encryptedTable, encryptedColumn } from \"@cipherstash/stack\"\n *\n * const users = encryptedTable(\"users\", {\n * email: encryptedColumn(\"email\"),\n * })\n * const client = await Encryption({ schemas: [users] })\n * const result = await client.encrypt(\"alice@example.com\", { column: users.email, table: users })\n * ```\n *\n * @see {@link EncryptionClientConfig} for full config options.\n * @see {@link EncryptionClient} for available methods after initialization.\n */\nexport const Encryption = async (\n config: EncryptionClientConfig,\n): Promise<EncryptionClient> => {\n const { schemas, config: clientConfig } = config\n\n if (!schemas.length) {\n throw new Error(\n '[encryption]: At least one encryptedTable must be provided to initialize the encryption client',\n )\n }\n\n if (\n clientConfig?.keyset &&\n 'id' in clientConfig.keyset &&\n !uuidValidate(clientConfig.keyset.id)\n ) {\n throw new Error(\n '[encryption]: Invalid UUID provided for keyset id. Must be a valid UUID.',\n )\n }\n\n const client = new EncryptionClient()\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(`[encryption]: ${result.failure.message}`)\n }\n\n return result.data\n}\n","export default /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$/i;\n","import REGEX from './regex.js';\nfunction validate(uuid) {\n return typeof uuid === 'string' && REGEX.test(uuid);\n}\nexport default validate;\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 {\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 { formatEncryptedResult } from '@/encryption/helpers'\nimport { getErrorCode } from '@/encryption/helpers/error-code'\nimport { type EncryptionError, EncryptionErrorTypes } from '@/errors'\nimport type { Context, LockContext } from '@/identity'\nimport type { Client, EncryptedQueryResult, ScalarQueryTerm } from '@/types'\nimport { createRequestLogger } from '@/utils/logger'\nimport { 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 { resolveIndexType } from '../helpers/infer-index-type'\nimport {\n assertValidNumericValue,\n assertValueIndexCompatibility,\n} from '../helpers/validation'\nimport { noClientError } from '../index'\nimport { EncryptionOperation } from './base-operation'\n\n// Separates null/undefined values from non-null terms in the input array\n// so they bypass the FFI call. Original indices are tracked so the\n// reassembled result preserves position.\nfunction filterNullTerms(terms: readonly ScalarQueryTerm[]): {\n nonNullTerms: { term: ScalarQueryTerm; originalIndex: number }[]\n} {\n const nonNullTerms: { term: ScalarQueryTerm; originalIndex: number }[] = []\n terms.forEach((term, index) => {\n if (term.value !== null && term.value !== undefined) {\n nonNullTerms.push({ term, originalIndex: index })\n }\n })\n return { 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 * Reassembles the result array, slotting null at the original indices of\n * filtered-out terms and formatting encrypted values for non-null terms.\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 nonNullTerms.forEach(({ term, originalIndex }, i) => {\n results[originalIndex] = formatEncryptedResult(\n encryptedValues[i],\n term.returnType,\n )\n })\n return results\n}\n\nexport class BatchEncryptQueryOperation extends EncryptionOperation<\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[], EncryptionError>\n > {\n const log = createRequestLogger()\n log.set({\n op: 'batchEncryptQuery',\n count: this.terms.length,\n lockContext: false,\n })\n\n if (this.terms.length === 0) {\n log.emit()\n return { data: [] }\n }\n\n const { nonNullTerms } = filterNullTerms(this.terms)\n\n if (nonNullTerms.length === 0) {\n log.emit()\n return { data: this.terms.map(() => null) }\n }\n\n const result = 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 log.set({ errorCode: getErrorCode(error) ?? 'unknown' })\n return {\n type: EncryptionErrorTypes.EncryptionError,\n message: (error as Error).message,\n code: getErrorCode(error),\n }\n },\n )\n log.emit()\n return result\n }\n}\n\nexport class BatchEncryptQueryOperationWithLockContext extends EncryptionOperation<\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[], EncryptionError>\n > {\n const log = createRequestLogger()\n log.set({\n op: 'batchEncryptQuery',\n count: this.terms.length,\n lockContext: true,\n })\n\n if (this.terms.length === 0) {\n log.emit()\n return { data: [] }\n }\n\n // Check for all-null terms BEFORE fetching lockContext to avoid an\n // unnecessary network call.\n const { nonNullTerms } = filterNullTerms(this.terms)\n\n if (nonNullTerms.length === 0) {\n log.emit()\n return { data: this.terms.map(() => null) }\n }\n\n const lockContextResult = await this.lockContext.getLockContext()\n if (lockContextResult.failure) {\n log.emit()\n return { failure: lockContextResult.failure }\n }\n\n const { ctsToken, context } = lockContextResult.data\n\n const result = 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 log.set({ errorCode: getErrorCode(error) ?? 'unknown' })\n return {\n type: EncryptionErrorTypes.EncryptionError,\n message: (error as Error).message,\n code: getErrorCode(error),\n }\n },\n )\n log.emit()\n return result\n }\n}\n","import type { EncryptedColumn } from '@/schema'\nimport type { JsPlaintext, QueryOpName } from '@cipherstash/protect-ffi'\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: EncryptedColumn): 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: EncryptedColumn,\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: EncryptedColumn,\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 EncryptionError, EncryptionErrorTypes } from '@/errors'\nimport type { FfiIndexTypeName } from '@/types'\nimport type { Result } from '@byteslice/result'\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, EncryptionError>.\n *\n * @internal\n */\nexport function validateNumericValue(\n value: unknown,\n): Result<never, EncryptionError> | undefined {\n if (typeof value === 'number' && Number.isNaN(value)) {\n return {\n failure: {\n type: EncryptionErrorTypes.EncryptionError,\n message: '[encryption]: Cannot encrypt NaN value',\n },\n }\n }\n if (typeof value === 'number' && !Number.isFinite(value)) {\n return {\n failure: {\n type: EncryptionErrorTypes.EncryptionError,\n message: '[encryption]: 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('[encryption]: Cannot encrypt NaN value')\n }\n if (typeof value === 'number' && !Number.isFinite(value)) {\n throw new Error('[encryption]: 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, EncryptionError> | undefined {\n if (typeof value === 'number' && indexType === 'match') {\n return {\n failure: {\n type: EncryptionErrorTypes.EncryptionError,\n message: `[encryption]: 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 `[encryption]: 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 { EncryptionError } from '@/errors'\nimport type { Result } from '@byteslice/result'\n\nexport type AuditConfig = {\n metadata?: Record<string, unknown>\n}\n\nexport type AuditData = {\n metadata?: Record<string, unknown>\n}\n\nexport abstract class EncryptionOperation<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, EncryptionError>>\n\n /**\n * Make the operation thenable\n */\n public then<TResult1 = Result<T, EncryptionError>, TResult2 = never>(\n onfulfilled?:\n | ((\n value: Result<T, EncryptionError>,\n ) => 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 { getErrorCode } from '@/encryption/helpers/error-code'\nimport { type EncryptionError, EncryptionErrorTypes } from '@/errors'\nimport type { Context, LockContext } from '@/identity'\nimport type { BulkDecryptPayload, BulkDecryptedData, Client } from '@/types'\nimport { createRequestLogger } from '@/utils/logger'\nimport { type Result, withResult } from '@byteslice/result'\nimport {\n type Encrypted as CipherStashEncrypted,\n type DecryptResult,\n decryptBulkFallible,\n} from '@cipherstash/protect-ffi'\nimport { noClientError } from '../index'\nimport { EncryptionOperation } from './base-operation'\n\n// Drops nulls so they don't reach protect-ffi's bulk decrypt. The\n// dropped positions are re-inserted as null in `mapDecryptedDataToResult`.\nconst createDecryptPayloads = (\n encryptedPayloads: BulkDecryptPayload,\n lockContext?: Context,\n) => {\n return encryptedPayloads\n .filter(({ data }) => data !== null)\n .map(({ id, data }) => ({\n id,\n ciphertext: data as CipherStashEncrypted,\n ...(lockContext && { lockContext }),\n }))\n}\n\nconst createNullResult = (\n encryptedPayloads: BulkDecryptPayload,\n): BulkDecryptedData =>\n encryptedPayloads.map(({ id }) => ({ id, data: null }))\n\nconst mapDecryptedDataToResult = (\n encryptedPayloads: BulkDecryptPayload,\n decryptedData: DecryptResult[],\n): BulkDecryptedData => {\n const result: BulkDecryptedData = new Array(encryptedPayloads.length)\n let decryptedIndex = 0\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] = { id: encryptedPayloads[i].id, error: decryptResult.error }\n } else {\n result[i] = { id: encryptedPayloads[i].id, data: decryptResult.data }\n }\n decryptedIndex++\n }\n }\n return result\n}\n\nexport class BulkDecryptOperation extends EncryptionOperation<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, EncryptionError>> {\n const log = createRequestLogger()\n log.set({\n op: 'bulkDecrypt',\n count: this.encryptedPayloads?.length ?? 0,\n lockContext: false,\n })\n\n const result = 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 log.set({ errorCode: getErrorCode(error) ?? 'unknown' })\n return {\n type: EncryptionErrorTypes.DecryptionError,\n message: (error as Error).message,\n code: getErrorCode(error),\n }\n },\n )\n log.emit()\n return result\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 EncryptionOperation<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 const auditData = operation.getAuditData()\n if (auditData) {\n this.audit(auditData)\n }\n }\n\n public async execute(): Promise<Result<BulkDecryptedData, EncryptionError>> {\n const { client, encryptedPayloads } = this.operation.getOperation()\n\n const log = createRequestLogger()\n log.set({\n op: 'bulkDecrypt',\n count: encryptedPayloads?.length ?? 0,\n lockContext: true,\n })\n\n const result = await withResult(\n async () => {\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(`[encryption]: ${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 log.set({ errorCode: getErrorCode(error) ?? 'unknown' })\n return {\n type: EncryptionErrorTypes.DecryptionError,\n message: (error as Error).message,\n code: getErrorCode(error),\n }\n },\n )\n log.emit()\n return result\n }\n}\n","import { getErrorCode } from '@/encryption/helpers/error-code'\nimport { type EncryptionError, EncryptionErrorTypes } from '@/errors'\nimport type { LockContext } from '@/identity'\nimport type { Client, Decrypted } from '@/types'\nimport { createRequestLogger } from '@/utils/logger'\nimport { type Result, withResult } from '@byteslice/result'\nimport {\n bulkDecryptModels,\n bulkDecryptModelsWithLockContext,\n} from '../helpers/model-helpers'\nimport { noClientError } from '../index'\nimport { EncryptionOperation } from './base-operation'\n\nexport class BulkDecryptModelsOperation<\n T extends Record<string, unknown>,\n> extends EncryptionOperation<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>[], EncryptionError>> {\n const log = createRequestLogger()\n log.set({\n op: 'bulkDecryptModels',\n count: this.models.length,\n lockContext: false,\n })\n\n const result = 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 log.set({ errorCode: getErrorCode(error) ?? 'unknown' })\n return {\n type: EncryptionErrorTypes.DecryptionError,\n message: (error as Error).message,\n code: getErrorCode(error),\n }\n },\n )\n log.emit()\n return result\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 EncryptionOperation<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 const auditData = operation.getAuditData()\n if (auditData) {\n this.audit(auditData)\n }\n }\n\n public async execute(): Promise<Result<Decrypted<T>[], EncryptionError>> {\n const { client, models } = this.operation.getOperation()\n\n const log = createRequestLogger()\n log.set({\n op: 'bulkDecryptModels',\n count: models.length,\n lockContext: true,\n })\n\n const result = await withResult(\n async () => {\n if (!client) {\n throw noClientError()\n }\n\n const context = await this.lockContext.getLockContext()\n\n if (context.failure) {\n throw new Error(`[encryption]: ${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 log.set({ errorCode: getErrorCode(error) ?? 'unknown' })\n return {\n type: EncryptionErrorTypes.DecryptionError,\n message: (error as Error).message,\n code: getErrorCode(error),\n }\n },\n )\n log.emit()\n return result\n }\n}\n","import { isEncryptedPayload } from '@/encryption/helpers'\nimport type { AuditData } from '@/encryption/operations/base-operation'\nimport type { GetLockContextResponse } from '@/identity'\nimport type { EncryptedTable, EncryptedTableColumn } from '@/schema'\nimport type { Client, Decrypted, Encrypted } from '@/types'\nimport {\n type Encrypted as CipherStashEncrypted,\n decryptBulk,\n encryptBulk,\n} from '@cipherstash/protect-ffi'\n\n/**\n * Sets a value at a nested path in an object, creating intermediate objects as needed.\n * Includes prototype pollution protection.\n */\nfunction setNestedValue(\n obj: Record<string, unknown>,\n path: string[],\n value: unknown,\n): void {\n const FORBIDDEN_KEYS = ['__proto__', 'prototype', 'constructor']\n let current: Record<string, unknown> = obj\n for (let i = 0; i < path.length - 1; i++) {\n const part = path[i]\n if (FORBIDDEN_KEYS.includes(part)) {\n throw new Error(`[encryption]: Forbidden key \"${part}\" in field path`)\n }\n if (\n !(part in current) ||\n typeof current[part] !== 'object' ||\n current[part] === null\n ) {\n current[part] = {}\n }\n current = current[part] as Record<string, unknown>\n }\n const lastKey = path[path.length - 1]\n if (FORBIDDEN_KEYS.includes(lastKey)) {\n throw new Error(`[encryption]: Forbidden key \"${lastKey}\" in field path`)\n }\n current[lastKey] = value\n}\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: EncryptedTable<EncryptedTableColumn>,\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 // 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(\n model: Record<string, unknown>,\n table: EncryptedTable<EncryptedTableColumn>,\n client: Client,\n auditData?: AuditData,\n): Promise<Record<string, unknown>> {\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 // 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\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 // 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 model: Record<string, unknown>,\n table: EncryptedTable<EncryptedTableColumn>,\n client: Client,\n lockContext: GetLockContextResponse,\n auditData?: AuditData,\n): Promise<Record<string, unknown>> {\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 // 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\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?: EncryptedTable<EncryptedTableColumn>,\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(\n models: Record<string, unknown>[],\n table: EncryptedTable<EncryptedTableColumn>,\n client: Client,\n auditData?: AuditData,\n): Promise<Record<string, unknown>[]> {\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 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\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 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 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 decrypted models to models with encrypted fields with lock context\n */\nexport async function bulkEncryptModelsWithLockContext(\n models: Record<string, unknown>[],\n table: EncryptedTable<EncryptedTableColumn>,\n client: Client,\n lockContext: GetLockContextResponse,\n auditData?: AuditData,\n): Promise<Record<string, unknown>[]> {\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 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\n })\n}\n","import { getErrorCode } from '@/encryption/helpers/error-code'\nimport { type EncryptionError, EncryptionErrorTypes } from '@/errors'\nimport type { Context, LockContext } from '@/identity'\nimport type {\n EncryptedColumn,\n EncryptedField,\n EncryptedTable,\n EncryptedTableColumn,\n} from '@/schema'\nimport type {\n BulkEncryptPayload,\n BulkEncryptedData,\n Client,\n Encrypted,\n EncryptOptions,\n} from '@/types'\nimport { createRequestLogger } from '@/utils/logger'\nimport { type Result, withResult } from '@byteslice/result'\nimport { type JsPlaintext, encryptBulk } from '@cipherstash/protect-ffi'\nimport { noClientError } from '../index'\nimport { EncryptionOperation } from './base-operation'\n\n// Drops nulls so they don't reach protect-ffi (which would otherwise\n// produce a SteVec wrapping the JSON null). The dropped positions are\n// re-inserted as null in `mapEncryptedDataToResult`.\nconst createEncryptPayloads = (\n plaintexts: BulkEncryptPayload,\n column: EncryptedColumn | EncryptedField,\n table: EncryptedTable<EncryptedTableColumn>,\n lockContext?: Context,\n) => {\n return plaintexts\n .filter(({ plaintext }) => plaintext !== null)\n .map(({ id, plaintext }) => ({\n id,\n plaintext: plaintext as JsPlaintext,\n column: column.getName(),\n table: table.tableName,\n ...(lockContext && { lockContext }),\n }))\n}\n\nconst createNullResult = (\n plaintexts: BulkEncryptPayload,\n): BulkEncryptedData => plaintexts.map(({ id }) => ({ id, data: null }))\n\nconst mapEncryptedDataToResult = (\n plaintexts: BulkEncryptPayload,\n encryptedData: Encrypted[],\n): BulkEncryptedData => {\n const result: BulkEncryptedData = new Array(plaintexts.length)\n let encryptedIndex = 0\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] = { id: plaintexts[i].id, data: encryptedData[encryptedIndex] }\n encryptedIndex++\n }\n }\n return result\n}\n\nexport class BulkEncryptOperation extends EncryptionOperation<BulkEncryptedData> {\n private client: Client\n private plaintexts: BulkEncryptPayload\n private column: EncryptedColumn | EncryptedField\n private table: EncryptedTable<EncryptedTableColumn>\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, EncryptionError>> {\n const log = createRequestLogger()\n log.set({\n op: 'bulkEncrypt',\n table: this.table.tableName,\n column: this.column.getName(),\n count: this.plaintexts?.length ?? 0,\n lockContext: false,\n })\n\n const result = 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 log.set({ errorCode: getErrorCode(error) ?? 'unknown' })\n return {\n type: EncryptionErrorTypes.EncryptionError,\n message: (error as Error).message,\n code: getErrorCode(error),\n }\n },\n )\n log.emit()\n return result\n }\n\n public getOperation(): {\n client: Client\n plaintexts: BulkEncryptPayload\n column: EncryptedColumn | EncryptedField\n table: EncryptedTable<EncryptedTableColumn>\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 EncryptionOperation<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 const auditData = operation.getAuditData()\n if (auditData) {\n this.audit(auditData)\n }\n }\n\n public async execute(): Promise<Result<BulkEncryptedData, EncryptionError>> {\n const { client, plaintexts, column, table } = this.operation.getOperation()\n\n const log = createRequestLogger()\n log.set({\n op: 'bulkEncrypt',\n table: table.tableName,\n column: column.getName(),\n count: plaintexts?.length ?? 0,\n lockContext: true,\n })\n\n const result = await withResult(\n async () => {\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(`[encryption]: ${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 log.set({ errorCode: getErrorCode(error) ?? 'unknown' })\n return {\n type: EncryptionErrorTypes.EncryptionError,\n message: (error as Error).message,\n code: getErrorCode(error),\n }\n },\n )\n log.emit()\n return result\n }\n}\n","import { getErrorCode } from '@/encryption/helpers/error-code'\nimport { type EncryptionError, EncryptionErrorTypes } from '@/errors'\nimport type { LockContext } from '@/identity'\nimport type { EncryptedTable, EncryptedTableColumn } from '@/schema'\nimport type { Client } from '@/types'\nimport { createRequestLogger } from '@/utils/logger'\nimport { type Result, withResult } from '@byteslice/result'\nimport {\n bulkEncryptModels,\n bulkEncryptModelsWithLockContext,\n} from '../helpers/model-helpers'\nimport { noClientError } from '../index'\nimport { EncryptionOperation } from './base-operation'\n\nexport class BulkEncryptModelsOperation<\n T extends Record<string, unknown>,\n> extends EncryptionOperation<T[]> {\n private client: Client\n private models: Record<string, unknown>[]\n private table: EncryptedTable<EncryptedTableColumn>\n\n constructor(\n client: Client,\n models: Record<string, unknown>[],\n table: EncryptedTable<EncryptedTableColumn>,\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[], EncryptionError>> {\n const log = createRequestLogger()\n log.set({\n op: 'bulkEncryptModels',\n table: this.table.tableName,\n count: this.models.length,\n lockContext: false,\n })\n\n const result = await withResult(\n async () => {\n if (!this.client) {\n throw noClientError()\n }\n\n const auditData = this.getAuditData()\n\n return (await bulkEncryptModels(\n this.models,\n this.table,\n this.client,\n auditData,\n )) as T[]\n },\n (error: unknown) => {\n log.set({ errorCode: getErrorCode(error) ?? 'unknown' })\n return {\n type: EncryptionErrorTypes.EncryptionError,\n message: (error as Error).message,\n code: getErrorCode(error),\n }\n },\n )\n log.emit()\n return result\n }\n\n public getOperation(): {\n client: Client\n models: Record<string, unknown>[]\n table: EncryptedTable<EncryptedTableColumn>\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 EncryptionOperation<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 const auditData = operation.getAuditData()\n if (auditData) {\n this.audit(auditData)\n }\n }\n\n public async execute(): Promise<Result<T[], EncryptionError>> {\n const { client, models, table } = this.operation.getOperation()\n\n const log = createRequestLogger()\n log.set({\n op: 'bulkEncryptModels',\n table: table.tableName,\n count: models.length,\n lockContext: true,\n })\n\n const result = await withResult(\n async () => {\n if (!client) {\n throw noClientError()\n }\n\n const context = await this.lockContext.getLockContext()\n\n if (context.failure) {\n throw new Error(`[encryption]: ${context.failure.message}`)\n }\n\n const auditData = this.getAuditData()\n\n return (await bulkEncryptModelsWithLockContext(\n models,\n table,\n client,\n context.data,\n auditData,\n )) as T[]\n },\n (error: unknown) => {\n log.set({ errorCode: getErrorCode(error) ?? 'unknown' })\n return {\n type: EncryptionErrorTypes.EncryptionError,\n message: (error as Error).message,\n code: getErrorCode(error),\n }\n },\n )\n log.emit()\n return result\n }\n}\n","import { getErrorCode } from '@/encryption/helpers/error-code'\nimport { type EncryptionError, EncryptionErrorTypes } from '@/errors'\nimport type { LockContext } from '@/identity'\nimport type { Client, Encrypted } from '@/types'\nimport { createRequestLogger } from '@/utils/logger'\nimport { type Result, withResult } from '@byteslice/result'\nimport {\n type JsPlaintext,\n decrypt as ffiDecrypt,\n} from '@cipherstash/protect-ffi'\nimport { noClientError } from '../index'\nimport { EncryptionOperation } from './base-operation'\n\n/**\n * Decrypts an encrypted payload using the provided client.\n * This is the type returned by the {@link EncryptionClient.decrypt | decrypt} method of the {@link EncryptionClient}.\n */\nexport class DecryptOperation extends EncryptionOperation<JsPlaintext> {\n private client: Client\n // Internally widened to allow null so the runtime guard below can\n // short-circuit on legacy / manually-NULLed rows. The public\n // `Encryption.decrypt()` signature still rejects null at the type\n // layer; this is defense in depth for direct construction.\n private encryptedData: Encrypted | null\n\n constructor(client: Client, encryptedData: Encrypted | null) {\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, EncryptionError>> {\n const log = createRequestLogger()\n log.set({\n op: 'decrypt',\n lockContext: false,\n })\n\n const result = await withResult(\n async () => {\n if (!this.client) {\n throw noClientError()\n }\n\n if (this.encryptedData === null) {\n // See encrypt.ts for the same defense-in-depth pattern.\n return null as unknown as JsPlaintext\n }\n\n const { metadata } = this.getAuditData()\n\n return await ffiDecrypt(this.client, {\n ciphertext: this.encryptedData,\n unverifiedContext: metadata,\n })\n },\n (error: unknown) => {\n log.set({ errorCode: getErrorCode(error) ?? 'unknown' })\n return {\n type: EncryptionErrorTypes.DecryptionError,\n message: (error as Error).message,\n code: getErrorCode(error),\n }\n },\n )\n log.emit()\n return result\n }\n\n public getOperation(): {\n client: Client\n encryptedData: Encrypted | null\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 EncryptionOperation<JsPlaintext> {\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, EncryptionError>> {\n const log = createRequestLogger()\n log.set({\n op: 'decrypt',\n lockContext: true,\n })\n\n const result = 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 as unknown as JsPlaintext\n }\n\n const { metadata } = this.getAuditData()\n\n const context = await this.lockContext.getLockContext()\n\n if (context.failure) {\n throw new Error(`[encryption]: ${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 log.set({ errorCode: getErrorCode(error) ?? 'unknown' })\n return {\n type: EncryptionErrorTypes.DecryptionError,\n message: (error as Error).message,\n code: getErrorCode(error),\n }\n },\n )\n log.emit()\n return result\n }\n}\n","import { getErrorCode } from '@/encryption/helpers/error-code'\nimport { type EncryptionError, EncryptionErrorTypes } from '@/errors'\nimport type { LockContext } from '@/identity'\nimport type { Client, Decrypted } from '@/types'\nimport { createRequestLogger } from '@/utils/logger'\nimport { type Result, withResult } from '@byteslice/result'\nimport {\n decryptModelFields,\n decryptModelFieldsWithLockContext,\n} from '../helpers/model-helpers'\nimport { noClientError } from '../index'\nimport { EncryptionOperation } from './base-operation'\n\nexport class DecryptModelOperation<\n T extends Record<string, unknown>,\n> extends EncryptionOperation<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>, EncryptionError>> {\n const log = createRequestLogger()\n log.set({\n op: 'decryptModel',\n lockContext: false,\n })\n\n const result = 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 log.set({ errorCode: getErrorCode(error) ?? 'unknown' })\n return {\n type: EncryptionErrorTypes.DecryptionError,\n message: (error as Error).message,\n code: getErrorCode(error),\n }\n },\n )\n log.emit()\n return result\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 EncryptionOperation<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 const auditData = operation.getAuditData()\n if (auditData) {\n this.audit(auditData)\n }\n }\n\n public async execute(): Promise<Result<Decrypted<T>, EncryptionError>> {\n const log = createRequestLogger()\n log.set({\n op: 'decryptModel',\n lockContext: true,\n })\n\n const result = await withResult(\n async () => {\n const { client, model } = this.operation.getOperation()\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(`[encryption]: ${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 log.set({ errorCode: getErrorCode(error) ?? 'unknown' })\n return {\n type: EncryptionErrorTypes.DecryptionError,\n message: (error as Error).message,\n code: getErrorCode(error),\n }\n },\n )\n log.emit()\n return result\n }\n}\n","import { getErrorCode } from '@/encryption/helpers/error-code'\nimport { type EncryptionError, EncryptionErrorTypes } from '@/errors'\nimport type { LockContext } from '@/identity'\nimport type {\n EncryptedColumn,\n EncryptedField,\n EncryptedTable,\n EncryptedTableColumn,\n} from '@/schema'\nimport type { Client, EncryptOptions, Encrypted } from '@/types'\nimport { createRequestLogger } from '@/utils/logger'\nimport { type Result, withResult } from '@byteslice/result'\nimport {\n type JsPlaintext,\n encrypt as ffiEncrypt,\n} from '@cipherstash/protect-ffi'\nimport { noClientError } from '../index'\nimport { EncryptionOperation } from './base-operation'\n\nexport class EncryptOperation extends EncryptionOperation<Encrypted> {\n private client: Client\n // Internally widened to allow null so the runtime guard below can\n // short-circuit. The public `Encryption.encrypt()` signature still\n // rejects null at the type layer; this is defense in depth for callers\n // that reach this class through casts or dynamic field walking.\n private plaintext: JsPlaintext | null\n private column: EncryptedColumn | EncryptedField\n private table: EncryptedTable<EncryptedTableColumn>\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, EncryptionError>> {\n const log = createRequestLogger()\n log.set({\n op: 'encrypt',\n table: this.table.tableName,\n column: this.column.getName(),\n lockContext: false,\n })\n\n const result = await withResult(\n async () => {\n if (!this.client) {\n throw noClientError()\n }\n\n if (this.plaintext === null) {\n // Defense in depth: the public `Encryption.encrypt()` signature\n // rejects null, but null can still arrive here via casts or\n // dynamic field walking. Return null directly so the result\n // matches DB NULL semantics rather than encrypting JSON null\n // into a SteVec. The cast acknowledges the type-narrow\n // contract at the public boundary.\n return null as unknown as Encrypted\n }\n\n if (\n typeof this.plaintext === 'number' &&\n Number.isNaN(this.plaintext)\n ) {\n throw new Error('[encryption]: Cannot encrypt NaN value')\n }\n\n if (\n typeof this.plaintext === 'number' &&\n !Number.isFinite(this.plaintext)\n ) {\n throw new Error('[encryption]: 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 log.set({ errorCode: getErrorCode(error) ?? 'unknown' })\n return {\n type: EncryptionErrorTypes.EncryptionError,\n message: (error as Error).message,\n code: getErrorCode(error),\n }\n },\n )\n log.emit()\n return result\n }\n\n public getOperation(): {\n client: Client\n plaintext: JsPlaintext | null\n column: EncryptedColumn | EncryptedField\n table: EncryptedTable<EncryptedTableColumn>\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 EncryptionOperation<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 const auditData = operation.getAuditData()\n if (auditData) {\n this.audit(auditData)\n }\n }\n\n public async execute(): Promise<Result<Encrypted, EncryptionError>> {\n const { client, plaintext, column, table } = this.operation.getOperation()\n\n const log = createRequestLogger()\n log.set({\n op: 'encrypt',\n table: table.tableName,\n column: column.getName(),\n lockContext: true,\n })\n\n const result = await withResult(\n async () => {\n if (!client) {\n throw noClientError()\n }\n\n if (plaintext === null) {\n return null as unknown as Encrypted\n }\n\n const { metadata } = this.getAuditData()\n const context = await this.lockContext.getLockContext()\n\n if (context.failure) {\n throw new Error(`[encryption]: ${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 log.set({ errorCode: getErrorCode(error) ?? 'unknown' })\n return {\n type: EncryptionErrorTypes.EncryptionError,\n message: (error as Error).message,\n code: getErrorCode(error),\n }\n },\n )\n log.emit()\n return result\n }\n}\n","import { getErrorCode } from '@/encryption/helpers/error-code'\nimport { type EncryptionError, EncryptionErrorTypes } from '@/errors'\nimport type { LockContext } from '@/identity'\nimport type { EncryptedTable, EncryptedTableColumn } from '@/schema'\nimport type { Client } from '@/types'\nimport { createRequestLogger } from '@/utils/logger'\nimport { type Result, withResult } from '@byteslice/result'\nimport {\n encryptModelFields,\n encryptModelFieldsWithLockContext,\n} from '../helpers/model-helpers'\nimport { noClientError } from '../index'\nimport { EncryptionOperation } from './base-operation'\n\nexport class EncryptModelOperation<\n T extends Record<string, unknown>,\n> extends EncryptionOperation<T> {\n private client: Client\n private model: Record<string, unknown>\n private table: EncryptedTable<EncryptedTableColumn>\n\n constructor(\n client: Client,\n model: Record<string, unknown>,\n table: EncryptedTable<EncryptedTableColumn>,\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, EncryptionError>> {\n const log = createRequestLogger()\n log.set({\n op: 'encryptModel',\n table: this.table.tableName,\n lockContext: false,\n })\n\n const result = await withResult(\n async () => {\n if (!this.client) {\n throw noClientError()\n }\n\n const auditData = this.getAuditData()\n\n return (await encryptModelFields(\n this.model,\n this.table,\n this.client,\n auditData,\n )) as T\n },\n (error: unknown) => {\n log.set({ errorCode: getErrorCode(error) ?? 'unknown' })\n return {\n type: EncryptionErrorTypes.EncryptionError,\n message: (error as Error).message,\n code: getErrorCode(error),\n }\n },\n )\n log.emit()\n return result\n }\n\n public getOperation(): {\n client: Client\n model: Record<string, unknown>\n table: EncryptedTable<EncryptedTableColumn>\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 EncryptionOperation<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 const auditData = operation.getAuditData()\n if (auditData) {\n this.audit(auditData)\n }\n }\n\n public async execute(): Promise<Result<T, EncryptionError>> {\n const { client, model, table } = this.operation.getOperation()\n\n const log = createRequestLogger()\n log.set({\n op: 'encryptModel',\n table: table.tableName,\n lockContext: true,\n })\n\n const result = await withResult(\n async () => {\n if (!client) {\n throw noClientError()\n }\n\n const context = await this.lockContext.getLockContext()\n\n if (context.failure) {\n throw new Error(`[encryption]: ${context.failure.message}`)\n }\n\n const auditData = this.getAuditData()\n\n return (await encryptModelFieldsWithLockContext(\n model,\n table,\n client,\n context.data,\n auditData,\n )) as T\n },\n (error: unknown) => {\n log.set({ errorCode: getErrorCode(error) ?? 'unknown' })\n return {\n type: EncryptionErrorTypes.EncryptionError,\n message: (error as Error).message,\n code: getErrorCode(error),\n }\n },\n )\n log.emit()\n return result\n }\n}\n","import { formatEncryptedResult } from '@/encryption/helpers'\nimport { getErrorCode } from '@/encryption/helpers/error-code'\nimport { type EncryptionError, EncryptionErrorTypes } from '@/errors'\nimport type { LockContext } from '@/identity'\nimport type { Client, EncryptQueryOptions, EncryptedQueryResult } from '@/types'\nimport { createRequestLogger } from '@/utils/logger'\nimport { type Result, withResult } from '@byteslice/result'\nimport {\n type JsPlaintext,\n encryptQuery as ffiEncryptQuery,\n} from '@cipherstash/protect-ffi'\nimport { resolveIndexType } from '../helpers/infer-index-type'\nimport {\n assertValueIndexCompatibility,\n validateNumericValue,\n} from '../helpers/validation'\nimport { noClientError } from '../index'\nimport { EncryptionOperation } from './base-operation'\n\nexport class EncryptQueryOperation extends EncryptionOperation<EncryptedQueryResult> {\n constructor(\n private client: Client,\n private plaintext: JsPlaintext | null | undefined,\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<\n Result<EncryptedQueryResult, EncryptionError>\n > {\n const log = createRequestLogger()\n log.set({\n op: 'encryptQuery',\n table: this.opts.table.tableName,\n column: this.opts.column.getName(),\n queryType: this.opts.queryType,\n lockContext: false,\n })\n\n if (this.plaintext === null || this.plaintext === undefined) {\n log.emit()\n return { data: null }\n }\n\n const plaintext: JsPlaintext = this.plaintext\n\n const validationError = validateNumericValue(plaintext)\n if (validationError?.failure) {\n log.emit()\n return { failure: validationError.failure }\n }\n\n const result = 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 plaintext,\n )\n\n // Validate value/index compatibility\n assertValueIndexCompatibility(\n plaintext,\n indexType,\n this.opts.column.getName(),\n )\n\n const encrypted = await ffiEncryptQuery(this.client, {\n plaintext,\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 log.set({ errorCode: getErrorCode(error) ?? 'unknown' })\n return {\n type: EncryptionErrorTypes.EncryptionError,\n message: (error as Error).message,\n code: getErrorCode(error),\n }\n },\n )\n log.emit()\n return result\n }\n\n public getOperation() {\n return { client: this.client, plaintext: this.plaintext, ...this.opts }\n }\n}\n\nexport class EncryptQueryOperationWithLockContext extends EncryptionOperation<EncryptedQueryResult> {\n constructor(\n private client: Client,\n private plaintext: JsPlaintext | null | undefined,\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<\n Result<EncryptedQueryResult, EncryptionError>\n > {\n const log = createRequestLogger()\n log.set({\n op: 'encryptQuery',\n table: this.opts.table.tableName,\n column: this.opts.column.getName(),\n queryType: this.opts.queryType,\n lockContext: true,\n })\n\n if (this.plaintext === null || this.plaintext === undefined) {\n log.emit()\n return { data: null }\n }\n\n const plaintext: JsPlaintext = this.plaintext\n\n const validationError = validateNumericValue(plaintext)\n if (validationError?.failure) {\n log.emit()\n return { failure: validationError.failure }\n }\n\n const lockContextResult = await this.lockContext.getLockContext()\n if (lockContextResult.failure) {\n log.emit()\n return { failure: lockContextResult.failure }\n }\n\n const { ctsToken, context } = lockContextResult.data\n\n const result = 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 plaintext,\n )\n\n // Validate value/index compatibility\n assertValueIndexCompatibility(\n plaintext,\n indexType,\n this.opts.column.getName(),\n )\n\n const encrypted = await ffiEncryptQuery(this.client, {\n plaintext,\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 log.set({ errorCode: getErrorCode(error) ?? 'unknown' })\n return {\n type: EncryptionErrorTypes.EncryptionError,\n message: (error as Error).message,\n code: getErrorCode(error),\n }\n },\n )\n log.emit()\n return result\n }\n}\n"],"mappings":"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","names":["withResult","withResult","withResult","withResult","columnPaths","_","withResult","withResult","encryptBulk","createNullResult","withResult","encryptBulk","withResult","withResult","withResult","withResult","withResult","withResult","withResult","withResult","withResult","withResult","withResult","withResult","withResult"]}