diff --git a/packages/schema/__tests__/searchable-json.test.ts b/packages/schema/__tests__/searchable-json.test.ts new file mode 100644 index 00000000..4e94d920 --- /dev/null +++ b/packages/schema/__tests__/searchable-json.test.ts @@ -0,0 +1,44 @@ +import { describe, it, expect } from 'vitest' +import { buildEncryptConfig, csTable, csColumn } from '../src/index' + +describe('searchableJson()', () => { + it('sets cast_as to json and ste_vec marker on column build', () => { + const column = csColumn('metadata').searchableJson() + const config = column.build() + + expect(config.cast_as).toBe('json') + expect(config.indexes.ste_vec?.prefix).toBe('enabled') + }) + + it('is chainable', () => { + const column = csColumn('metadata') + expect(column.searchableJson()).toBe(column) + }) +}) + +describe('ProtectTable.build() with searchableJson', () => { + it('transforms prefix to table/column format', () => { + const users = csTable('users', { + metadata: csColumn('metadata').searchableJson() + }) + const built = users.build() + + expect(built.columns.metadata.cast_as).toBe('json') + expect(built.columns.metadata.indexes.ste_vec?.prefix).toBe('users/metadata') + }) +}) + +describe('buildEncryptConfig with searchableJson', () => { + it('emits ste_vec index with table/column prefix', () => { + const users = csTable('users', { + metadata: csColumn('metadata').searchableJson() + }) + + const config = buildEncryptConfig(users) + + expect(config.tables.users.metadata.cast_as).toBe('json') + expect(config.tables.users.metadata.indexes.ste_vec?.prefix).toBe( + 'users/metadata' + ) + }) +}) diff --git a/packages/schema/src/index.ts b/packages/schema/src/index.ts index b12b30de..dcc11c8c 100644 --- a/packages/schema/src/index.ts +++ b/packages/schema/src/index.ts @@ -211,13 +211,15 @@ export class ProtectColumn { } /** - * Enable a STE Vec index, uses the column name for the index. + * Configure this column for searchable encrypted JSON. + * Enables path queries ($.user.email) and containment queries ({ role: 'admin' }). + * Automatically sets cast_as to 'json'. */ - // NOTE: Leaving this commented out until stevec indexing for JSON is supported. - /*searchableJson() { - this.indexesValue.ste_vec = { prefix: this.columnName } + searchableJson() { + this.castAsValue = 'json' + this.indexesValue.ste_vec = { prefix: 'enabled' } return this - }*/ + } build() { return {