@payloadcms-vectorize/pg 0.6.0-beta → 0.6.0-beta.2

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/bin-vectorize-migrate.ts"],"sourcesContent":["import type { SanitizedConfig } from 'payload'\nimport { getPayload } from 'payload'\nimport { readFileSync, writeFileSync, readdirSync, statSync, existsSync } from 'fs'\nimport { join, resolve } from 'path'\nimport toSnakeCase from 'to-snake-case'\n\nimport { getVectorizedPayload } from 'payloadcms-vectorize'\nimport { KnowledgePoolsConfig } from './types'\n\n/**\n * Get prior dims state from existing migrations\n */\nfunction getPriorDimsFromMigrations(\n migrationsDir: string,\n poolNames: string[],\n): Map<string, number | null> {\n const state = new Map<string, number | null>()\n\n // Initialize with null (unknown state)\n for (const poolName of poolNames) {\n state.set(poolName, null)\n }\n\n if (!existsSync(migrationsDir)) {\n return state\n }\n\n // Find all migration files and read them in reverse order (newest first)\n // Exclude index.ts/index.js as those are not migration files\n const migrationFiles = readdirSync(migrationsDir)\n .filter((f) => (f.endsWith('.ts') || f.endsWith('.js')) && f !== 'index.ts' && f !== 'index.js')\n .map((f) => ({\n name: f,\n path: join(migrationsDir, f),\n mtime: statSync(join(migrationsDir, f)).mtime,\n }))\n .sort((a, b) => b.mtime.getTime() - a.mtime.getTime())\n\n // Skip the most recent migration when determining prior dims, since it may contain\n // the pending dims change that we're trying to detect\n const filesToCheck = migrationFiles.slice(1)\n\n // Read migration files to find vector dims\n for (const file of filesToCheck) {\n try {\n const content = readFileSync(file.path, 'utf-8')\n\n // Extract only the UP function content to avoid matching values in DOWN function\n const upFunctionMatch = content.match(\n /export\\s+async\\s+function\\s+up\\s*\\([^)]*\\)[^{]*\\{([\\s\\S]*?)(?=\\}\\s*(?:export\\s+async\\s+function\\s+down|$))/i,\n )\n const upContent = upFunctionMatch ? upFunctionMatch[1] : content\n\n // Look for dims in vector column definition (pool-specific patterns)\n for (const poolName of poolNames) {\n const tableName = toSnakeCase(poolName)\n\n const pattern1 = new RegExp(\n `ALTER\\\\s+TABLE[^;]*?\"${tableName}\"[^;]*?vector\\\\((\\\\d+)\\\\)`,\n 'is',\n )\n const pattern2 = new RegExp(\n `CREATE\\\\s+TABLE[^;]*?\"${tableName}\"[^;]*?embedding[^;]*?vector\\\\((\\\\d+)\\\\)`,\n 'is',\n )\n const pattern3 = new RegExp(\n `\"${tableName}\"\\\\s*\\\\([^)]*embedding[^)]*vector\\\\((\\\\d+)\\\\)`,\n 'is',\n )\n\n const match1 = upContent.match(pattern1)\n const match2 = upContent.match(pattern2)\n const match3 = upContent.match(pattern3)\n\n const dimsMatch = match1 || match2 || match3\n\n if (dimsMatch && !state.get(poolName)) {\n const dims = parseInt(dimsMatch[1], 10)\n state.set(poolName, dims)\n }\n }\n } catch (err) {\n // Skip files that can't be read\n continue\n }\n }\n\n return state\n}\n\n/**\n * Generate SQL code for destructive dims change (truncate table)\n */\nfunction generateDimsChangeTruncateCode(\n tableName: string,\n schemaName: string,\n oldDims: number,\n newDims: number,\n): string {\n return ` // payloadcms-vectorize: WARNING - Changing dims from ${oldDims} to ${newDims} is DESTRUCTIVE\n // All existing embeddings will be deleted. You must re-embed all documents after this migration.\n // Truncate table (destructive - all embeddings are lost)\n // Use CASCADE to handle foreign key constraints\n await db.execute(sql.raw(\\`TRUNCATE TABLE \"${schemaName}\".\"${tableName}\" CASCADE\\`));`\n}\n\n/**\n * Generate SQL code for down migration (restore old dims column type)\n */\nfunction generateDimsChangeDownCode(\n tableName: string,\n schemaName: string,\n oldDims: number,\n): string {\n return ` // payloadcms-vectorize: Revert column type to old dimensions\n // WARNING: Data was truncated during up migration and cannot be restored.\n // You will need to re-embed all documents after rolling back.\n await db.execute(sql.raw(\\`ALTER TABLE \"${schemaName}\".\"${tableName}\" ALTER COLUMN embedding TYPE vector(${oldDims})\\`));`\n}\n\n/**\n * Patch a migration file with truncate SQL for dims changes\n */\nfunction patchMigrationFileForDimsChange(\n migrationPath: string,\n tableName: string,\n schemaName: string,\n oldDims: number,\n newDims: number,\n): void {\n let content = readFileSync(migrationPath, 'utf-8')\n\n // Ensure sql import exists for injected sql.raw usage\n const sqlImportRegex = /import\\s+\\{([^}]+)\\}\\s+from\\s+['\"]@payloadcms\\/db-postgres['\"]/\n const importMatch = content.match(sqlImportRegex)\n if (importMatch) {\n const imports = importMatch[1]\n .split(',')\n .map((part) => part.trim())\n .filter(Boolean)\n if (!imports.includes('sql')) {\n imports.push('sql')\n const updatedImport = `import { ${imports.join(', ')} } from '@payloadcms/db-postgres'`\n content = content.replace(importMatch[0], updatedImport)\n }\n } else {\n content = `import { sql } from '@payloadcms/db-postgres'\\n${content}`\n }\n\n // Generate SQL code\n const truncateCode = generateDimsChangeTruncateCode(tableName, schemaName, oldDims, newDims)\n const downCode = generateDimsChangeDownCode(tableName, schemaName, oldDims)\n\n // Find the up function and insert code before the closing brace\n const upFunctionMatch = content.match(\n /export\\s+async\\s+function\\s+up\\s*\\([^)]*\\)\\s*:\\s*Promise<void>\\s*\\{/i,\n )\n if (!upFunctionMatch) {\n throw new Error(`Could not find 'up' function in migration file: ${migrationPath}`)\n }\n\n const upFunctionStart = upFunctionMatch.index! + upFunctionMatch[0].length\n const downFunctionMatch = content.match(/export\\s+async\\s+function\\s+down\\s*\\([^)]*\\)/i)\n const searchEnd = downFunctionMatch ? downFunctionMatch.index! : content.length\n\n // Find the last closing brace before down function or end\n const upFunctionBody = content.substring(upFunctionStart, searchEnd)\n const lastBraceIndex = upFunctionBody.lastIndexOf('}')\n if (lastBraceIndex === -1) {\n throw new Error(\n `Could not find closing brace for 'up' function in migration file: ${migrationPath}`,\n )\n }\n\n // Insert our code before the closing brace\n const beforeBrace = content.substring(0, upFunctionStart + lastBraceIndex)\n const afterBrace = content.substring(upFunctionStart + lastBraceIndex)\n\n const codeToInsert = '\\n' + truncateCode + '\\n'\n let newContent = beforeBrace + codeToInsert + afterBrace\n\n // Handle down function\n if (downFunctionMatch) {\n const downFunctionStart = downFunctionMatch.index! + downFunctionMatch[0].length\n const downBraceMatch = newContent.substring(downFunctionStart).match(/\\{/)\n if (downBraceMatch) {\n const downBodyStart = downFunctionStart + downBraceMatch.index! + 1\n const downBody = newContent.substring(downBodyStart)\n const downLastBraceIndex = downBody.lastIndexOf('}')\n if (downLastBraceIndex !== -1) {\n const beforeDownBrace = newContent.substring(0, downBodyStart + downLastBraceIndex)\n const afterDownBrace = newContent.substring(downBodyStart + downLastBraceIndex)\n const downCodeToInsert = '\\n' + downCode + '\\n'\n newContent = beforeDownBrace + downCodeToInsert + afterDownBrace\n }\n }\n }\n\n writeFileSync(migrationPath, newContent, 'utf-8')\n}\n\n/**\n * Bin script entry point for patching vector migrations with truncate for dims changes\n *\n * NOTE: As of v0.5.3, the IVFFLAT index is created automatically via afterSchemaInitHook\n * using Drizzle's extraConfig. This script is only needed when changing dims, which\n * requires truncating the embeddings table (destructive operation).\n */\nexport const script = async (config: SanitizedConfig): Promise<void> => {\n // Get Payload instance to access static configs via VectorizedPayload\n const getPayloadOptions = {\n config,\n // In test environment, use unique key\n ...(process.env.TEST_ENV ? { key: `vectorize-migrate-${Date.now()}` } : {}),\n }\n\n const payload = await getPayload(getPayloadOptions)\n\n // Get static configs from VectorizedPayload\n const vectorizedPayload = getVectorizedPayload(payload)\n if (!vectorizedPayload) {\n throw new Error(\n '[payloadcms-vectorize] Vectorize plugin not found. Ensure payloadcmsVectorize is configured in your Payload config.',\n )\n }\n\n const staticConfigs = (\n vectorizedPayload.getDbAdapterCustom() as { _staticConfigs: KnowledgePoolsConfig }\n )._staticConfigs\n if (!staticConfigs || Object.keys(staticConfigs).length === 0) {\n throw new Error('[payloadcms-vectorize] No static configs found')\n }\n\n const poolNames = Object.keys(staticConfigs)\n const schemaName = (payload.db as any).schemaName || 'public'\n\n // Get migrations directory\n const dbMigrationDir = (payload.db as any).migrationDir\n const migrationsDir = dbMigrationDir || resolve(process.cwd(), 'src/migrations')\n\n // Get prior dims state from migrations\n const priorDims = getPriorDimsFromMigrations(migrationsDir, poolNames)\n\n // Check if any dims have changed\n const dimsChanges: Array<{\n poolName: string\n tableName: string\n oldDims: number\n newDims: number\n }> = []\n\n for (const poolName of poolNames) {\n const currentConfig = staticConfigs[poolName]\n const priorDimsValue = priorDims.get(poolName)\n const currentDims = currentConfig.dims\n\n // Only flag as change if we have a prior value AND it's different\n if (priorDimsValue !== null && priorDimsValue !== undefined && priorDimsValue !== currentDims) {\n dimsChanges.push({\n poolName,\n tableName: toSnakeCase(poolName),\n oldDims: priorDimsValue as number,\n newDims: currentDims,\n })\n }\n }\n\n // If no dims changes detected, show deprecation message\n if (dimsChanges.length === 0) {\n console.log(\n '\\n[payloadcms-vectorize] No dims changes detected. ' +\n 'This script is only needed when changing dims (which requires truncating the embeddings table). ',\n )\n return\n }\n\n // Dims changed - we need to patch the most recent migration with TRUNCATE\n console.log('\\n[payloadcms-vectorize] Detected dims changes:')\n for (const change of dimsChanges) {\n console.log(` - ${change.poolName}: ${change.oldDims} → ${change.newDims}`)\n }\n console.log('')\n\n // Find the most recent migration file\n if (!existsSync(migrationsDir)) {\n throw new Error(\n `[payloadcms-vectorize] Migrations directory not found: ${migrationsDir}\\n` +\n `Please run 'payload migrate:create' first to create a migration for the dims change.`,\n )\n }\n\n const migrationFiles = readdirSync(migrationsDir)\n .filter((f) => (f.endsWith('.ts') || f.endsWith('.js')) && f !== 'index.ts' && f !== 'index.js')\n .map((f) => ({\n name: f,\n path: join(migrationsDir, f),\n mtime: statSync(join(migrationsDir, f)).mtime,\n }))\n .sort((a, b) => b.mtime.getTime() - a.mtime.getTime())\n\n if (migrationFiles.length === 0) {\n throw new Error(\n `[payloadcms-vectorize] No migration files found in ${migrationsDir}\\n` +\n `Please run 'payload migrate:create' first to create a migration for the dims change.`,\n )\n }\n\n const latestMigration = migrationFiles[0]\n\n // Check if migration already has truncate code\n const migrationContent = readFileSync(latestMigration.path, 'utf-8')\n if (\n migrationContent.includes('TRUNCATE TABLE') &&\n migrationContent.includes('payloadcms-vectorize')\n ) {\n console.log(\n '[payloadcms-vectorize] Migration already patched with TRUNCATE. No changes needed.',\n )\n return\n }\n\n // Patch the migration for each dims change\n for (const change of dimsChanges) {\n patchMigrationFileForDimsChange(\n latestMigration.path,\n change.tableName,\n schemaName,\n change.oldDims,\n change.newDims,\n )\n }\n\n console.log(`[payloadcms-vectorize] Migration patched successfully: ${latestMigration.name}`)\n console.log('')\n console.log('⚠️ WARNING: This migration will TRUNCATE your embeddings table(s).')\n console.log(' All existing embeddings will be deleted.')\n console.log(' After running the migration, you must re-embed all documents.')\n console.log('')\n\n // Only exit if not in test environment\n if (process.env.NODE_ENV !== 'test' && !process.env.VITEST) {\n process.exit(0)\n }\n}\n"],"names":["getPayload","readFileSync","writeFileSync","readdirSync","statSync","existsSync","join","resolve","toSnakeCase","getVectorizedPayload","getPriorDimsFromMigrations","migrationsDir","poolNames","state","Map","poolName","set","migrationFiles","filter","f","endsWith","map","name","path","mtime","sort","a","b","getTime","filesToCheck","slice","file","content","upFunctionMatch","match","upContent","tableName","pattern1","RegExp","pattern2","pattern3","match1","match2","match3","dimsMatch","get","dims","parseInt","err","generateDimsChangeTruncateCode","schemaName","oldDims","newDims","generateDimsChangeDownCode","patchMigrationFileForDimsChange","migrationPath","sqlImportRegex","importMatch","imports","split","part","trim","Boolean","includes","push","updatedImport","replace","truncateCode","downCode","Error","upFunctionStart","index","length","downFunctionMatch","searchEnd","upFunctionBody","substring","lastBraceIndex","lastIndexOf","beforeBrace","afterBrace","codeToInsert","newContent","downFunctionStart","downBraceMatch","downBodyStart","downBody","downLastBraceIndex","beforeDownBrace","afterDownBrace","downCodeToInsert","script","config","getPayloadOptions","process","env","TEST_ENV","key","Date","now","payload","vectorizedPayload","staticConfigs","getDbAdapterCustom","_staticConfigs","Object","keys","db","dbMigrationDir","migrationDir","cwd","priorDims","dimsChanges","currentConfig","priorDimsValue","currentDims","undefined","console","log","change","latestMigration","migrationContent","NODE_ENV","VITEST","exit"],"mappings":"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"}
1
+ {"version":3,"sources":["../src/bin-vectorize-migrate.ts"],"sourcesContent":["import type { SanitizedConfig } from 'payload'\nimport { getPayload } from 'payload'\nimport { readFileSync, writeFileSync, readdirSync, statSync, existsSync } from 'fs'\nimport { join, resolve } from 'path'\nimport toSnakeCase from 'to-snake-case'\n\nimport { getVectorizedPayload } from 'payloadcms-vectorize'\nimport { KnowledgePoolsConfig } from './types.js'\n\n/**\n * Get prior dims state from existing migrations\n */\nfunction getPriorDimsFromMigrations(\n migrationsDir: string,\n poolNames: string[],\n): Map<string, number | null> {\n const state = new Map<string, number | null>()\n\n // Initialize with null (unknown state)\n for (const poolName of poolNames) {\n state.set(poolName, null)\n }\n\n if (!existsSync(migrationsDir)) {\n return state\n }\n\n // Find all migration files and read them in reverse order (newest first)\n // Exclude index.ts/index.js as those are not migration files\n const migrationFiles = readdirSync(migrationsDir)\n .filter((f) => (f.endsWith('.ts') || f.endsWith('.js')) && f !== 'index.ts' && f !== 'index.js')\n .map((f) => ({\n name: f,\n path: join(migrationsDir, f),\n mtime: statSync(join(migrationsDir, f)).mtime,\n }))\n .sort((a, b) => b.mtime.getTime() - a.mtime.getTime())\n\n // Skip the most recent migration when determining prior dims, since it may contain\n // the pending dims change that we're trying to detect\n const filesToCheck = migrationFiles.slice(1)\n\n // Read migration files to find vector dims\n for (const file of filesToCheck) {\n try {\n const content = readFileSync(file.path, 'utf-8')\n\n // Extract only the UP function content to avoid matching values in DOWN function\n const upFunctionMatch = content.match(\n /export\\s+async\\s+function\\s+up\\s*\\([^)]*\\)[^{]*\\{([\\s\\S]*?)(?=\\}\\s*(?:export\\s+async\\s+function\\s+down|$))/i,\n )\n const upContent = upFunctionMatch ? upFunctionMatch[1] : content\n\n // Look for dims in vector column definition (pool-specific patterns)\n for (const poolName of poolNames) {\n const tableName = toSnakeCase(poolName)\n\n const pattern1 = new RegExp(\n `ALTER\\\\s+TABLE[^;]*?\"${tableName}\"[^;]*?vector\\\\((\\\\d+)\\\\)`,\n 'is',\n )\n const pattern2 = new RegExp(\n `CREATE\\\\s+TABLE[^;]*?\"${tableName}\"[^;]*?embedding[^;]*?vector\\\\((\\\\d+)\\\\)`,\n 'is',\n )\n const pattern3 = new RegExp(\n `\"${tableName}\"\\\\s*\\\\([^)]*embedding[^)]*vector\\\\((\\\\d+)\\\\)`,\n 'is',\n )\n\n const match1 = upContent.match(pattern1)\n const match2 = upContent.match(pattern2)\n const match3 = upContent.match(pattern3)\n\n const dimsMatch = match1 || match2 || match3\n\n if (dimsMatch && !state.get(poolName)) {\n const dims = parseInt(dimsMatch[1], 10)\n state.set(poolName, dims)\n }\n }\n } catch (err) {\n // Skip files that can't be read\n continue\n }\n }\n\n return state\n}\n\n/**\n * Generate SQL code for destructive dims change (truncate table)\n */\nfunction generateDimsChangeTruncateCode(\n tableName: string,\n schemaName: string,\n oldDims: number,\n newDims: number,\n): string {\n return ` // payloadcms-vectorize: WARNING - Changing dims from ${oldDims} to ${newDims} is DESTRUCTIVE\n // All existing embeddings will be deleted. You must re-embed all documents after this migration.\n // Truncate table (destructive - all embeddings are lost)\n // Use CASCADE to handle foreign key constraints\n await db.execute(sql.raw(\\`TRUNCATE TABLE \"${schemaName}\".\"${tableName}\" CASCADE\\`));`\n}\n\n/**\n * Generate SQL code for down migration (restore old dims column type)\n */\nfunction generateDimsChangeDownCode(\n tableName: string,\n schemaName: string,\n oldDims: number,\n): string {\n return ` // payloadcms-vectorize: Revert column type to old dimensions\n // WARNING: Data was truncated during up migration and cannot be restored.\n // You will need to re-embed all documents after rolling back.\n await db.execute(sql.raw(\\`ALTER TABLE \"${schemaName}\".\"${tableName}\" ALTER COLUMN embedding TYPE vector(${oldDims})\\`));`\n}\n\n/**\n * Patch a migration file with truncate SQL for dims changes\n */\nfunction patchMigrationFileForDimsChange(\n migrationPath: string,\n tableName: string,\n schemaName: string,\n oldDims: number,\n newDims: number,\n): void {\n let content = readFileSync(migrationPath, 'utf-8')\n\n // Ensure sql import exists for injected sql.raw usage\n const sqlImportRegex = /import\\s+\\{([^}]+)\\}\\s+from\\s+['\"]@payloadcms\\/db-postgres['\"]/\n const importMatch = content.match(sqlImportRegex)\n if (importMatch) {\n const imports = importMatch[1]\n .split(',')\n .map((part) => part.trim())\n .filter(Boolean)\n if (!imports.includes('sql')) {\n imports.push('sql')\n const updatedImport = `import { ${imports.join(', ')} } from '@payloadcms/db-postgres'`\n content = content.replace(importMatch[0], updatedImport)\n }\n } else {\n content = `import { sql } from '@payloadcms/db-postgres'\\n${content}`\n }\n\n // Generate SQL code\n const truncateCode = generateDimsChangeTruncateCode(tableName, schemaName, oldDims, newDims)\n const downCode = generateDimsChangeDownCode(tableName, schemaName, oldDims)\n\n // Find the up function and insert code before the closing brace\n const upFunctionMatch = content.match(\n /export\\s+async\\s+function\\s+up\\s*\\([^)]*\\)\\s*:\\s*Promise<void>\\s*\\{/i,\n )\n if (!upFunctionMatch) {\n throw new Error(`Could not find 'up' function in migration file: ${migrationPath}`)\n }\n\n const upFunctionStart = upFunctionMatch.index! + upFunctionMatch[0].length\n const downFunctionMatch = content.match(/export\\s+async\\s+function\\s+down\\s*\\([^)]*\\)/i)\n const searchEnd = downFunctionMatch ? downFunctionMatch.index! : content.length\n\n // Find the last closing brace before down function or end\n const upFunctionBody = content.substring(upFunctionStart, searchEnd)\n const lastBraceIndex = upFunctionBody.lastIndexOf('}')\n if (lastBraceIndex === -1) {\n throw new Error(\n `Could not find closing brace for 'up' function in migration file: ${migrationPath}`,\n )\n }\n\n // Insert our code before the closing brace\n const beforeBrace = content.substring(0, upFunctionStart + lastBraceIndex)\n const afterBrace = content.substring(upFunctionStart + lastBraceIndex)\n\n const codeToInsert = '\\n' + truncateCode + '\\n'\n let newContent = beforeBrace + codeToInsert + afterBrace\n\n // Handle down function\n if (downFunctionMatch) {\n const downFunctionStart = downFunctionMatch.index! + downFunctionMatch[0].length\n const downBraceMatch = newContent.substring(downFunctionStart).match(/\\{/)\n if (downBraceMatch) {\n const downBodyStart = downFunctionStart + downBraceMatch.index! + 1\n const downBody = newContent.substring(downBodyStart)\n const downLastBraceIndex = downBody.lastIndexOf('}')\n if (downLastBraceIndex !== -1) {\n const beforeDownBrace = newContent.substring(0, downBodyStart + downLastBraceIndex)\n const afterDownBrace = newContent.substring(downBodyStart + downLastBraceIndex)\n const downCodeToInsert = '\\n' + downCode + '\\n'\n newContent = beforeDownBrace + downCodeToInsert + afterDownBrace\n }\n }\n }\n\n writeFileSync(migrationPath, newContent, 'utf-8')\n}\n\n/**\n * Bin script entry point for patching vector migrations with truncate for dims changes\n *\n * NOTE: As of v0.5.3, the IVFFLAT index is created automatically via afterSchemaInitHook\n * using Drizzle's extraConfig. This script is only needed when changing dims, which\n * requires truncating the embeddings table (destructive operation).\n */\nexport const script = async (config: SanitizedConfig): Promise<void> => {\n // Get Payload instance to access static configs via VectorizedPayload\n const getPayloadOptions = {\n config,\n // In test environment, use unique key\n ...(process.env.TEST_ENV ? { key: `vectorize-migrate-${Date.now()}` } : {}),\n }\n\n const payload = await getPayload(getPayloadOptions)\n\n // Get static configs from VectorizedPayload\n const vectorizedPayload = getVectorizedPayload(payload)\n if (!vectorizedPayload) {\n throw new Error(\n '[payloadcms-vectorize] Vectorize plugin not found. Ensure payloadcmsVectorize is configured in your Payload config.',\n )\n }\n\n const staticConfigs = (\n vectorizedPayload.getDbAdapterCustom() as { _staticConfigs: KnowledgePoolsConfig }\n )._staticConfigs\n if (!staticConfigs || Object.keys(staticConfigs).length === 0) {\n throw new Error('[payloadcms-vectorize] No static configs found')\n }\n\n const poolNames = Object.keys(staticConfigs)\n const schemaName = (payload.db as any).schemaName || 'public'\n\n // Get migrations directory\n const dbMigrationDir = (payload.db as any).migrationDir\n const migrationsDir = dbMigrationDir || resolve(process.cwd(), 'src/migrations')\n\n // Get prior dims state from migrations\n const priorDims = getPriorDimsFromMigrations(migrationsDir, poolNames)\n\n // Check if any dims have changed\n const dimsChanges: Array<{\n poolName: string\n tableName: string\n oldDims: number\n newDims: number\n }> = []\n\n for (const poolName of poolNames) {\n const currentConfig = staticConfigs[poolName]\n const priorDimsValue = priorDims.get(poolName)\n const currentDims = currentConfig.dims\n\n // Only flag as change if we have a prior value AND it's different\n if (priorDimsValue !== null && priorDimsValue !== undefined && priorDimsValue !== currentDims) {\n dimsChanges.push({\n poolName,\n tableName: toSnakeCase(poolName),\n oldDims: priorDimsValue as number,\n newDims: currentDims,\n })\n }\n }\n\n // If no dims changes detected, show deprecation message\n if (dimsChanges.length === 0) {\n console.log(\n '\\n[payloadcms-vectorize] No dims changes detected. ' +\n 'This script is only needed when changing dims (which requires truncating the embeddings table). ',\n )\n return\n }\n\n // Dims changed - we need to patch the most recent migration with TRUNCATE\n console.log('\\n[payloadcms-vectorize] Detected dims changes:')\n for (const change of dimsChanges) {\n console.log(` - ${change.poolName}: ${change.oldDims} → ${change.newDims}`)\n }\n console.log('')\n\n // Find the most recent migration file\n if (!existsSync(migrationsDir)) {\n throw new Error(\n `[payloadcms-vectorize] Migrations directory not found: ${migrationsDir}\\n` +\n `Please run 'payload migrate:create' first to create a migration for the dims change.`,\n )\n }\n\n const migrationFiles = readdirSync(migrationsDir)\n .filter((f) => (f.endsWith('.ts') || f.endsWith('.js')) && f !== 'index.ts' && f !== 'index.js')\n .map((f) => ({\n name: f,\n path: join(migrationsDir, f),\n mtime: statSync(join(migrationsDir, f)).mtime,\n }))\n .sort((a, b) => b.mtime.getTime() - a.mtime.getTime())\n\n if (migrationFiles.length === 0) {\n throw new Error(\n `[payloadcms-vectorize] No migration files found in ${migrationsDir}\\n` +\n `Please run 'payload migrate:create' first to create a migration for the dims change.`,\n )\n }\n\n const latestMigration = migrationFiles[0]\n\n // Check if migration already has truncate code\n const migrationContent = readFileSync(latestMigration.path, 'utf-8')\n if (\n migrationContent.includes('TRUNCATE TABLE') &&\n migrationContent.includes('payloadcms-vectorize')\n ) {\n console.log(\n '[payloadcms-vectorize] Migration already patched with TRUNCATE. No changes needed.',\n )\n return\n }\n\n // Patch the migration for each dims change\n for (const change of dimsChanges) {\n patchMigrationFileForDimsChange(\n latestMigration.path,\n change.tableName,\n schemaName,\n change.oldDims,\n change.newDims,\n )\n }\n\n console.log(`[payloadcms-vectorize] Migration patched successfully: ${latestMigration.name}`)\n console.log('')\n console.log('⚠️ WARNING: This migration will TRUNCATE your embeddings table(s).')\n console.log(' All existing embeddings will be deleted.')\n console.log(' After running the migration, you must re-embed all documents.')\n console.log('')\n\n // Only exit if not in test environment\n if (process.env.NODE_ENV !== 'test' && !process.env.VITEST) {\n process.exit(0)\n }\n}\n"],"names":["getPayload","readFileSync","writeFileSync","readdirSync","statSync","existsSync","join","resolve","toSnakeCase","getVectorizedPayload","getPriorDimsFromMigrations","migrationsDir","poolNames","state","Map","poolName","set","migrationFiles","filter","f","endsWith","map","name","path","mtime","sort","a","b","getTime","filesToCheck","slice","file","content","upFunctionMatch","match","upContent","tableName","pattern1","RegExp","pattern2","pattern3","match1","match2","match3","dimsMatch","get","dims","parseInt","err","generateDimsChangeTruncateCode","schemaName","oldDims","newDims","generateDimsChangeDownCode","patchMigrationFileForDimsChange","migrationPath","sqlImportRegex","importMatch","imports","split","part","trim","Boolean","includes","push","updatedImport","replace","truncateCode","downCode","Error","upFunctionStart","index","length","downFunctionMatch","searchEnd","upFunctionBody","substring","lastBraceIndex","lastIndexOf","beforeBrace","afterBrace","codeToInsert","newContent","downFunctionStart","downBraceMatch","downBodyStart","downBody","downLastBraceIndex","beforeDownBrace","afterDownBrace","downCodeToInsert","script","config","getPayloadOptions","process","env","TEST_ENV","key","Date","now","payload","vectorizedPayload","staticConfigs","getDbAdapterCustom","_staticConfigs","Object","keys","db","dbMigrationDir","migrationDir","cwd","priorDims","dimsChanges","currentConfig","priorDimsValue","currentDims","undefined","console","log","change","latestMigration","migrationContent","NODE_ENV","VITEST","exit"],"mappings":"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"}
package/dist/embed.js CHANGED
@@ -1,4 +1,4 @@
1
- import { isPostgresPayload } from './types';
1
+ import { isPostgresPayload } from './types.js';
2
2
  import toSnakeCase from 'to-snake-case';
3
3
  export default (async (payload, poolName, id, embedding)=>{
4
4
  const isPostgres = isPostgresPayload(payload);
package/dist/embed.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/embed.ts"],"sourcesContent":["import { Payload } from 'payload'\nimport { isPostgresPayload, PostgresPayload } from './types'\nimport toSnakeCase from 'to-snake-case'\n\nexport default async (\n payload: Payload,\n poolName: string,\n id: string,\n embedding: number[] | Float32Array,\n) => {\n const isPostgres = isPostgresPayload(payload)\n if (!isPostgres) {\n throw new Error('[@payloadcms-vectorize/pg] Only works with Postgres')\n }\n const runSQL = async (sql: string, params?: any[]) => {\n if (postgresPayload.db.pool?.query) return postgresPayload.db.pool.query(sql, params)\n if (postgresPayload.db.drizzle?.execute) return postgresPayload.db.drizzle.execute(sql, params)\n throw new Error('[@payloadcms-vectorize/pg] Failed to persist vector column')\n }\n const literal = `[${Array.from(embedding).join(',')}]`\n const postgresPayload = payload as PostgresPayload\n const schemaName = postgresPayload.db.schemaName || 'public'\n // Drizzle converts camelCase collection slugs to snake_case table names\n const sql =\n `UPDATE \"${schemaName}\".\"${toSnakeCase(poolName)}\" SET embedding = $1 WHERE id = $2` as string\n try {\n await runSQL(sql, [literal, id])\n } catch (e) {\n const errorMessage = (e as Error).message || (e as any).toString()\n payload.logger.error(\n `[@payloadcms-vectorize/pg] Failed to persist vector column: ${errorMessage}`,\n )\n throw new Error(`[@payloadcms-vectorize/pg] Failed to persist vector column: ${e}`)\n }\n}\n"],"names":["isPostgresPayload","toSnakeCase","payload","poolName","id","embedding","isPostgres","Error","runSQL","sql","params","postgresPayload","db","pool","query","drizzle","execute","literal","Array","from","join","schemaName","e","errorMessage","message","toString","logger","error"],"mappings":"AACA,SAASA,iBAAiB,QAAyB,UAAS;AAC5D,OAAOC,iBAAiB,gBAAe;AAEvC,eAAe,CAAA,OACbC,SACAC,UACAC,IACAC;IAEA,MAAMC,aAAaN,kBAAkBE;IACrC,IAAI,CAACI,YAAY;QACf,MAAM,IAAIC,MAAM;IAClB;IACA,MAAMC,SAAS,OAAOC,KAAaC;QACjC,IAAIC,gBAAgBC,EAAE,CAACC,IAAI,EAAEC,OAAO,OAAOH,gBAAgBC,EAAE,CAACC,IAAI,CAACC,KAAK,CAACL,KAAKC;QAC9E,IAAIC,gBAAgBC,EAAE,CAACG,OAAO,EAAEC,SAAS,OAAOL,gBAAgBC,EAAE,CAACG,OAAO,CAACC,OAAO,CAACP,KAAKC;QACxF,MAAM,IAAIH,MAAM;IAClB;IACA,MAAMU,UAAU,CAAC,CAAC,EAAEC,MAAMC,IAAI,CAACd,WAAWe,IAAI,CAAC,KAAK,CAAC,CAAC;IACtD,MAAMT,kBAAkBT;IACxB,MAAMmB,aAAaV,gBAAgBC,EAAE,CAACS,UAAU,IAAI;IACpD,wEAAwE;IACxE,MAAMZ,MACJ,CAAC,QAAQ,EAAEY,WAAW,GAAG,EAAEpB,YAAYE,UAAU,kCAAkC,CAAC;IACtF,IAAI;QACF,MAAMK,OAAOC,KAAK;YAACQ;YAASb;SAAG;IACjC,EAAE,OAAOkB,GAAG;QACV,MAAMC,eAAe,AAACD,EAAYE,OAAO,IAAI,AAACF,EAAUG,QAAQ;QAChEvB,QAAQwB,MAAM,CAACC,KAAK,CAClB,CAAC,4DAA4D,EAAEJ,cAAc;QAE/E,MAAM,IAAIhB,MAAM,CAAC,4DAA4D,EAAEe,GAAG;IACpF;AACF,CAAA,EAAC"}
1
+ {"version":3,"sources":["../src/embed.ts"],"sourcesContent":["import { Payload } from 'payload'\nimport { isPostgresPayload, PostgresPayload } from './types.js'\nimport toSnakeCase from 'to-snake-case'\n\nexport default async (\n payload: Payload,\n poolName: string,\n id: string,\n embedding: number[] | Float32Array,\n) => {\n const isPostgres = isPostgresPayload(payload)\n if (!isPostgres) {\n throw new Error('[@payloadcms-vectorize/pg] Only works with Postgres')\n }\n const runSQL = async (sql: string, params?: any[]) => {\n if (postgresPayload.db.pool?.query) return postgresPayload.db.pool.query(sql, params)\n if (postgresPayload.db.drizzle?.execute) return postgresPayload.db.drizzle.execute(sql, params)\n throw new Error('[@payloadcms-vectorize/pg] Failed to persist vector column')\n }\n const literal = `[${Array.from(embedding).join(',')}]`\n const postgresPayload = payload as PostgresPayload\n const schemaName = postgresPayload.db.schemaName || 'public'\n // Drizzle converts camelCase collection slugs to snake_case table names\n const sql =\n `UPDATE \"${schemaName}\".\"${toSnakeCase(poolName)}\" SET embedding = $1 WHERE id = $2` as string\n try {\n await runSQL(sql, [literal, id])\n } catch (e) {\n const errorMessage = (e as Error).message || (e as any).toString()\n payload.logger.error(\n `[@payloadcms-vectorize/pg] Failed to persist vector column: ${errorMessage}`,\n )\n throw new Error(`[@payloadcms-vectorize/pg] Failed to persist vector column: ${e}`)\n }\n}\n"],"names":["isPostgresPayload","toSnakeCase","payload","poolName","id","embedding","isPostgres","Error","runSQL","sql","params","postgresPayload","db","pool","query","drizzle","execute","literal","Array","from","join","schemaName","e","errorMessage","message","toString","logger","error"],"mappings":"AACA,SAASA,iBAAiB,QAAyB,aAAY;AAC/D,OAAOC,iBAAiB,gBAAe;AAEvC,eAAe,CAAA,OACbC,SACAC,UACAC,IACAC;IAEA,MAAMC,aAAaN,kBAAkBE;IACrC,IAAI,CAACI,YAAY;QACf,MAAM,IAAIC,MAAM;IAClB;IACA,MAAMC,SAAS,OAAOC,KAAaC;QACjC,IAAIC,gBAAgBC,EAAE,CAACC,IAAI,EAAEC,OAAO,OAAOH,gBAAgBC,EAAE,CAACC,IAAI,CAACC,KAAK,CAACL,KAAKC;QAC9E,IAAIC,gBAAgBC,EAAE,CAACG,OAAO,EAAEC,SAAS,OAAOL,gBAAgBC,EAAE,CAACG,OAAO,CAACC,OAAO,CAACP,KAAKC;QACxF,MAAM,IAAIH,MAAM;IAClB;IACA,MAAMU,UAAU,CAAC,CAAC,EAAEC,MAAMC,IAAI,CAACd,WAAWe,IAAI,CAAC,KAAK,CAAC,CAAC;IACtD,MAAMT,kBAAkBT;IACxB,MAAMmB,aAAaV,gBAAgBC,EAAE,CAACS,UAAU,IAAI;IACpD,wEAAwE;IACxE,MAAMZ,MACJ,CAAC,QAAQ,EAAEY,WAAW,GAAG,EAAEpB,YAAYE,UAAU,kCAAkC,CAAC;IACtF,IAAI;QACF,MAAMK,OAAOC,KAAK;YAACQ;YAASb;SAAG;IACjC,EAAE,OAAOkB,GAAG;QACV,MAAMC,eAAe,AAACD,EAAYE,OAAO,IAAI,AAACF,EAAUG,QAAQ;QAChEvB,QAAQwB,MAAM,CAACC,KAAK,CAClB,CAAC,4DAA4D,EAAEJ,cAAc;QAE/E,MAAM,IAAIhB,MAAM,CAAC,4DAA4D,EAAEe,GAAG;IACpF;AACF,CAAA,EAAC"}
package/dist/index.js CHANGED
@@ -3,8 +3,8 @@ import { customType, index } from '@payloadcms/db-postgres/drizzle/pg-core';
3
3
  import toSnakeCase from 'to-snake-case';
4
4
  import { fileURLToPath } from 'url';
5
5
  import { dirname, resolve } from 'path';
6
- import embed from './embed';
7
- import search from './search';
6
+ import embed from './embed.js';
7
+ import search from './search.js';
8
8
  export const createPostgresVectorIntegration = (config)=>{
9
9
  // Augment the generated schema so push/migrations are aware of our custom columns
10
10
  const afterSchemaInitHook = async ({ schema, extendTable })=>{
@@ -62,7 +62,7 @@ export const createPostgresVectorIntegration = (config)=>{
62
62
  };
63
63
  },
64
64
  search,
65
- embed
65
+ storeEmbedding: embed
66
66
  };
67
67
  return {
68
68
  afterSchemaInitHook,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { KnowledgePoolsConfig } from './types'\nimport type { PostgresAdapterArgs } from '@payloadcms/db-postgres'\nimport { clearEmbeddingsTables, registerEmbeddingsTable } from './drizzle.js'\nimport { customType, index } from '@payloadcms/db-postgres/drizzle/pg-core'\nimport toSnakeCase from 'to-snake-case'\nimport type { DbAdapter } from 'payloadcms-vectorize'\nimport { fileURLToPath } from 'url'\nimport { dirname, resolve } from 'path'\nimport embed from './embed'\nimport search from './search'\n\nexport type { KnowledgePoolsConfig as KnowledgePoolConfig }\n\nexport const createPostgresVectorIntegration = (\n config: KnowledgePoolsConfig,\n): {\n afterSchemaInitHook: Required<PostgresAdapterArgs>['afterSchemaInit'][number]\n adapter: DbAdapter\n} => {\n // Augment the generated schema so push/migrations are aware of our custom columns\n const afterSchemaInitHook: Required<PostgresAdapterArgs>['afterSchemaInit'][number] = async ({\n schema,\n extendTable,\n }) => {\n // Ensure registry reflects the latest schema\n clearEmbeddingsTables()\n\n // Extend schema for each knowledge pool\n for (const poolName in config) {\n const staticConfig = config[poolName]\n const dims = staticConfig.dims\n\n const vectorType = customType({\n dataType() {\n return `vector(${dims})`\n },\n })\n\n // Drizzle converts camelCase collection slugs to snake_case table names\n const tableName = toSnakeCase(poolName)\n const table = schema?.tables?.[tableName]\n if (!table) {\n throw new Error(\n `[@payloadcms-vectorize/pg] Embeddings table \"${poolName}\" (table: \"${tableName}\") not found during schema initialization. Ensure the collection has been registered.`,\n )\n }\n\n if (typeof extendTable === 'function') {\n extendTable({\n table,\n columns: {\n embedding: vectorType('embedding'),\n },\n extraConfig: (cols) => ({\n embeddingIvfflatIndex: index(`${tableName}_embedding_ivfflat`)\n .using('ivfflat', cols.embedding.op('vector_cosine_ops'))\n .with({ lists: staticConfig.ivfflatLists }),\n }),\n })\n }\n\n registerEmbeddingsTable(poolName, table)\n }\n\n return schema\n }\n\n const adapter: DbAdapter = {\n getConfigExtension: () => {\n // Register bin script for migration helper\n const __filename = fileURLToPath(import.meta.url)\n const __dirname = dirname(__filename)\n const binScriptPath = resolve(__dirname, 'bin-vectorize-migrate.js')\n\n return {\n bins: [\n {\n // Register bin script for migration helper\n key: 'vectorize:migrate',\n scriptPath: binScriptPath,\n },\n ],\n custom: {\n _staticConfigs: config,\n },\n }\n },\n search,\n embed,\n }\n\n return { afterSchemaInitHook, adapter }\n}\n"],"names":["clearEmbeddingsTables","registerEmbeddingsTable","customType","index","toSnakeCase","fileURLToPath","dirname","resolve","embed","search","createPostgresVectorIntegration","config","afterSchemaInitHook","schema","extendTable","poolName","staticConfig","dims","vectorType","dataType","tableName","table","tables","Error","columns","embedding","extraConfig","cols","embeddingIvfflatIndex","using","op","with","lists","ivfflatLists","adapter","getConfigExtension","__filename","url","__dirname","binScriptPath","bins","key","scriptPath","custom","_staticConfigs"],"mappings":"AAEA,SAASA,qBAAqB,EAAEC,uBAAuB,QAAQ,eAAc;AAC7E,SAASC,UAAU,EAAEC,KAAK,QAAQ,0CAAyC;AAC3E,OAAOC,iBAAiB,gBAAe;AAEvC,SAASC,aAAa,QAAQ,MAAK;AACnC,SAASC,OAAO,EAAEC,OAAO,QAAQ,OAAM;AACvC,OAAOC,WAAW,UAAS;AAC3B,OAAOC,YAAY,WAAU;AAI7B,OAAO,MAAMC,kCAAkC,CAC7CC;IAKA,kFAAkF;IAClF,MAAMC,sBAAgF,OAAO,EAC3FC,MAAM,EACNC,WAAW,EACZ;QACC,6CAA6C;QAC7Cd;QAEA,wCAAwC;QACxC,IAAK,MAAMe,YAAYJ,OAAQ;YAC7B,MAAMK,eAAeL,MAAM,CAACI,SAAS;YACrC,MAAME,OAAOD,aAAaC,IAAI;YAE9B,MAAMC,aAAahB,WAAW;gBAC5BiB;oBACE,OAAO,CAAC,OAAO,EAAEF,KAAK,CAAC,CAAC;gBAC1B;YACF;YAEA,wEAAwE;YACxE,MAAMG,YAAYhB,YAAYW;YAC9B,MAAMM,QAAQR,QAAQS,QAAQ,CAACF,UAAU;YACzC,IAAI,CAACC,OAAO;gBACV,MAAM,IAAIE,MACR,CAAC,6CAA6C,EAAER,SAAS,WAAW,EAAEK,UAAU,qFAAqF,CAAC;YAE1K;YAEA,IAAI,OAAON,gBAAgB,YAAY;gBACrCA,YAAY;oBACVO;oBACAG,SAAS;wBACPC,WAAWP,WAAW;oBACxB;oBACAQ,aAAa,CAACC,OAAU,CAAA;4BACtBC,uBAAuBzB,MAAM,GAAGiB,UAAU,kBAAkB,CAAC,EAC1DS,KAAK,CAAC,WAAWF,KAAKF,SAAS,CAACK,EAAE,CAAC,sBACnCC,IAAI,CAAC;gCAAEC,OAAOhB,aAAaiB,YAAY;4BAAC;wBAC7C,CAAA;gBACF;YACF;YAEAhC,wBAAwBc,UAAUM;QACpC;QAEA,OAAOR;IACT;IAEA,MAAMqB,UAAqB;QACzBC,oBAAoB;YAClB,2CAA2C;YAC3C,MAAMC,aAAa/B,cAAc,YAAYgC,GAAG;YAChD,MAAMC,YAAYhC,QAAQ8B;YAC1B,MAAMG,gBAAgBhC,QAAQ+B,WAAW;YAEzC,OAAO;gBACLE,MAAM;oBACJ;wBACE,2CAA2C;wBAC3CC,KAAK;wBACLC,YAAYH;oBACd;iBACD;gBACDI,QAAQ;oBACNC,gBAAgBjC;gBAClB;YACF;QACF;QACAF;QACAD;IACF;IAEA,OAAO;QAAEI;QAAqBsB;IAAQ;AACxC,EAAC"}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { KnowledgePoolsConfig } from './types.js'\nimport type { PostgresAdapterArgs } from '@payloadcms/db-postgres'\nimport { clearEmbeddingsTables, registerEmbeddingsTable } from './drizzle.js'\nimport { customType, index } from '@payloadcms/db-postgres/drizzle/pg-core'\nimport toSnakeCase from 'to-snake-case'\nimport type { DbAdapter } from 'payloadcms-vectorize'\nimport { fileURLToPath } from 'url'\nimport { dirname, resolve } from 'path'\nimport embed from './embed.js'\nimport search from './search.js'\n\nexport type { KnowledgePoolsConfig as KnowledgePoolConfig }\n\nexport const createPostgresVectorIntegration = (\n config: KnowledgePoolsConfig,\n): {\n afterSchemaInitHook: Required<PostgresAdapterArgs>['afterSchemaInit'][number]\n adapter: DbAdapter\n} => {\n // Augment the generated schema so push/migrations are aware of our custom columns\n const afterSchemaInitHook: Required<PostgresAdapterArgs>['afterSchemaInit'][number] = async ({\n schema,\n extendTable,\n }) => {\n // Ensure registry reflects the latest schema\n clearEmbeddingsTables()\n\n // Extend schema for each knowledge pool\n for (const poolName in config) {\n const staticConfig = config[poolName]\n const dims = staticConfig.dims\n\n const vectorType = customType({\n dataType() {\n return `vector(${dims})`\n },\n })\n\n // Drizzle converts camelCase collection slugs to snake_case table names\n const tableName = toSnakeCase(poolName)\n const table = schema?.tables?.[tableName]\n if (!table) {\n throw new Error(\n `[@payloadcms-vectorize/pg] Embeddings table \"${poolName}\" (table: \"${tableName}\") not found during schema initialization. Ensure the collection has been registered.`,\n )\n }\n\n if (typeof extendTable === 'function') {\n extendTable({\n table,\n columns: {\n embedding: vectorType('embedding'),\n },\n extraConfig: (cols) => ({\n embeddingIvfflatIndex: index(`${tableName}_embedding_ivfflat`)\n .using('ivfflat', cols.embedding.op('vector_cosine_ops'))\n .with({ lists: staticConfig.ivfflatLists }),\n }),\n })\n }\n\n registerEmbeddingsTable(poolName, table)\n }\n\n return schema\n }\n\n const adapter: DbAdapter = {\n getConfigExtension: () => {\n // Register bin script for migration helper\n const __filename = fileURLToPath(import.meta.url)\n const __dirname = dirname(__filename)\n const binScriptPath = resolve(__dirname, 'bin-vectorize-migrate.js')\n\n return {\n bins: [\n {\n // Register bin script for migration helper\n key: 'vectorize:migrate',\n scriptPath: binScriptPath,\n },\n ],\n custom: {\n _staticConfigs: config,\n },\n }\n },\n search,\n storeEmbedding: embed,\n }\n\n return { afterSchemaInitHook, adapter }\n}\n"],"names":["clearEmbeddingsTables","registerEmbeddingsTable","customType","index","toSnakeCase","fileURLToPath","dirname","resolve","embed","search","createPostgresVectorIntegration","config","afterSchemaInitHook","schema","extendTable","poolName","staticConfig","dims","vectorType","dataType","tableName","table","tables","Error","columns","embedding","extraConfig","cols","embeddingIvfflatIndex","using","op","with","lists","ivfflatLists","adapter","getConfigExtension","__filename","url","__dirname","binScriptPath","bins","key","scriptPath","custom","_staticConfigs","storeEmbedding"],"mappings":"AAEA,SAASA,qBAAqB,EAAEC,uBAAuB,QAAQ,eAAc;AAC7E,SAASC,UAAU,EAAEC,KAAK,QAAQ,0CAAyC;AAC3E,OAAOC,iBAAiB,gBAAe;AAEvC,SAASC,aAAa,QAAQ,MAAK;AACnC,SAASC,OAAO,EAAEC,OAAO,QAAQ,OAAM;AACvC,OAAOC,WAAW,aAAY;AAC9B,OAAOC,YAAY,cAAa;AAIhC,OAAO,MAAMC,kCAAkC,CAC7CC;IAKA,kFAAkF;IAClF,MAAMC,sBAAgF,OAAO,EAC3FC,MAAM,EACNC,WAAW,EACZ;QACC,6CAA6C;QAC7Cd;QAEA,wCAAwC;QACxC,IAAK,MAAMe,YAAYJ,OAAQ;YAC7B,MAAMK,eAAeL,MAAM,CAACI,SAAS;YACrC,MAAME,OAAOD,aAAaC,IAAI;YAE9B,MAAMC,aAAahB,WAAW;gBAC5BiB;oBACE,OAAO,CAAC,OAAO,EAAEF,KAAK,CAAC,CAAC;gBAC1B;YACF;YAEA,wEAAwE;YACxE,MAAMG,YAAYhB,YAAYW;YAC9B,MAAMM,QAAQR,QAAQS,QAAQ,CAACF,UAAU;YACzC,IAAI,CAACC,OAAO;gBACV,MAAM,IAAIE,MACR,CAAC,6CAA6C,EAAER,SAAS,WAAW,EAAEK,UAAU,qFAAqF,CAAC;YAE1K;YAEA,IAAI,OAAON,gBAAgB,YAAY;gBACrCA,YAAY;oBACVO;oBACAG,SAAS;wBACPC,WAAWP,WAAW;oBACxB;oBACAQ,aAAa,CAACC,OAAU,CAAA;4BACtBC,uBAAuBzB,MAAM,GAAGiB,UAAU,kBAAkB,CAAC,EAC1DS,KAAK,CAAC,WAAWF,KAAKF,SAAS,CAACK,EAAE,CAAC,sBACnCC,IAAI,CAAC;gCAAEC,OAAOhB,aAAaiB,YAAY;4BAAC;wBAC7C,CAAA;gBACF;YACF;YAEAhC,wBAAwBc,UAAUM;QACpC;QAEA,OAAOR;IACT;IAEA,MAAMqB,UAAqB;QACzBC,oBAAoB;YAClB,2CAA2C;YAC3C,MAAMC,aAAa/B,cAAc,YAAYgC,GAAG;YAChD,MAAMC,YAAYhC,QAAQ8B;YAC1B,MAAMG,gBAAgBhC,QAAQ+B,WAAW;YAEzC,OAAO;gBACLE,MAAM;oBACJ;wBACE,2CAA2C;wBAC3CC,KAAK;wBACLC,YAAYH;oBACd;iBACD;gBACDI,QAAQ;oBACNC,gBAAgBjC;gBAClB;YACF;QACF;QACAF;QACAoC,gBAAgBrC;IAClB;IAEA,OAAO;QAAEI;QAAqBsB;IAAQ;AACxC,EAAC"}
package/dist/search.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { sql, cosineDistance, inArray, eq, and, or, not, like, gt, gte, lt, lte, ne, isNull, isNotNull } from '@payloadcms/db-postgres/drizzle';
2
2
  import toSnakeCase from 'to-snake-case';
3
- import { getEmbeddingsTable } from './drizzle';
3
+ import { getEmbeddingsTable } from './drizzle.js';
4
4
  export default (async (payload, queryEmbedding, poolName, limit = 10, where)=>{
5
5
  const isPostgres = payload.db?.pool?.query || payload.db?.drizzle;
6
6
  if (!isPostgres) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/search.ts"],"sourcesContent":["import {\n sql,\n cosineDistance,\n inArray,\n eq,\n and,\n or,\n not,\n like,\n gt,\n gte,\n lt,\n lte,\n ne,\n isNull,\n isNotNull,\n} from '@payloadcms/db-postgres/drizzle'\nimport { BasePayload, Where } from 'payload'\nimport { KnowledgePoolName, VectorSearchResult } from 'payloadcms-vectorize'\nimport toSnakeCase from 'to-snake-case'\nimport { getEmbeddingsTable } from './drizzle'\n\nexport default async (\n payload: BasePayload,\n queryEmbedding: number[],\n poolName: KnowledgePoolName,\n limit: number = 10,\n where?: Where,\n): Promise<Array<VectorSearchResult>> => {\n const isPostgres = payload.db?.pool?.query || payload.db?.drizzle\n\n if (!isPostgres) {\n throw new Error('Only works with Postgres')\n }\n\n // In PayloadCMS, payload.db IS the adapter, and drizzle is at payload.db.drizzle\n const adapter = payload.db\n if (!adapter) {\n throw new Error('Drizzle adapter not found')\n }\n\n // Get drizzle instance\n const drizzle = adapter.drizzle\n if (!drizzle) {\n throw new Error('Drizzle instance not found in adapter')\n }\n\n // Get collection config and table name\n const collectionConfig = payload.collections[poolName]?.config\n if (!collectionConfig) {\n throw new Error(`Collection ${poolName} not found`)\n }\n\n const table = getEmbeddingsTable(poolName)\n if (!table) {\n throw new Error(\n `[payloadcms-vectorize] Embeddings table for knowledge pool \"${poolName}\" not registered. Ensure the plugin's afterSchemaInit hook ran and the pool exists.`,\n )\n }\n\n // Use Drizzle's query builder with cosineDistance function\n // cosineDistance returns distance, so we calculate score as 1 - distance\n // The table from fullSchema should have columns as direct properties\n const embeddingColumn = table.embedding\n if (!embeddingColumn) {\n throw new Error(\n `Embedding column not found in table for pool \"${poolName}\". Available properties: ${Object.keys(table).join(', ')}`,\n )\n }\n\n // Convert WHERE clause to Drizzle conditions\n let drizzleWhere: any = undefined\n if (where) {\n drizzleWhere = convertWhereToDrizzle(where, table, collectionConfig.flattenedFields)\n if (drizzleWhere === null) {\n // WHERE clause resulted in an empty condition (e.g., empty 'and' or 'or' array)\n // This semantically means \"match nothing\", so return empty results\n throw new Error(\n `[payloadcms-vectorize] WHERE clause resulted in no valid conditions. This typically occurs when using empty 'and' or 'or' arrays, or when all field conditions reference non-existent columns.`,\n )\n }\n if (drizzleWhere === undefined) {\n // WHERE clause could not be converted (invalid structure or unsupported operators)\n throw new Error(\n `[payloadcms-vectorize] WHERE clause could not be converted to Drizzle conditions. Please check that all field names exist and operators are supported.`,\n )\n }\n }\n\n // Build query using Drizzle's query builder\n // Column names in the table are camelCase (docId, chunkText, etc.)\n // but their database names are snake_case (doc_id, chunk_text, etc.)\n // The table from fullSchema should have columns as direct properties\n // Calculate score: 1 - cosineDistance (distance)\n // Need to cast 1 to numeric to avoid \"integer - vector\" error\n const distanceExpr = cosineDistance(embeddingColumn, queryEmbedding)\n\n // Build select object with score\n const selectObj: Record<string, any> = {\n id: table.id, // ensure we select id explicitly\n score: sql<number>`1 - (${distanceExpr})`,\n }\n\n // Add reserved + extension fields from collection config\n for (const field of collectionConfig.fields ?? []) {\n if (typeof field === 'object' && 'name' in field) {\n const name = field.name as string\n if (name in table) {\n selectObj[name] = table[name]\n } else if (toSnakeCase(name) in table) {\n selectObj[name] = table[toSnakeCase(name)]\n }\n }\n }\n\n let query: any = drizzle.select(selectObj).from(table)\n\n // Add WHERE clause if provided\n if (drizzleWhere) {\n query = query.where(drizzleWhere)\n }\n\n // Order by cosine distance (ascending = most similar first) and limit\n // Reuse the same distance expression for ordering\n query = query.orderBy(distanceExpr).limit(limit)\n\n // Execute the query\n const result = await query\n\n return mapRowsToResults(result, collectionConfig)\n}\n\n/**\n * Convert Payload WHERE clause to Drizzle conditions\n * Simplified version inspired by Payload's buildQuery\n */\nfunction convertWhereToDrizzle(where: Where, table: any, fields: any[]): any {\n if (!where || typeof where !== 'object') {\n return undefined\n }\n\n // Handle 'and' operator\n if ('and' in where && Array.isArray(where.and)) {\n const conditions = where.and\n .map((condition) => convertWhereToDrizzle(condition, table, fields))\n .filter((c) => c !== undefined && c !== null)\n if (conditions.length === 0) return null\n if (conditions.length === 1) return conditions[0]\n return and(...conditions)\n }\n\n // Handle 'or' operator\n if ('or' in where && Array.isArray(where.or)) {\n const conditions = where.or\n .map((condition) => convertWhereToDrizzle(condition, table, fields))\n .filter((c) => c !== undefined && c !== null)\n if (conditions.length === 0) return null\n if (conditions.length === 1) return conditions[0]\n return or(...conditions)\n }\n\n // Handle field conditions - collect all field conditions and combine with AND\n const fieldConditions: any[] = []\n for (const [fieldName, condition] of Object.entries(where)) {\n if (fieldName === 'and' || fieldName === 'or') continue\n\n // Get the column from the table\n // Drizzle tables have columns as direct properties\n // Try camelCase first, then snake_case as fallback\n // Use 'in' operator to check existence, then access the property\n let column: any = undefined\n if (fieldName in table) {\n column = table[fieldName]\n } else if (toSnakeCase(fieldName) in table) {\n column = table[toSnakeCase(fieldName)]\n } else if (table.columns) {\n // Fallback to table.columns if it exists\n if (fieldName in table.columns) {\n column = table.columns[fieldName]\n } else if (toSnakeCase(fieldName) in table.columns) {\n column = table.columns[toSnakeCase(fieldName)]\n }\n }\n\n if (!column) {\n // Field not found, skip (could be a nested field we don't support)\n continue\n }\n\n if (typeof condition !== 'object' || condition === null || Array.isArray(condition)) {\n continue\n }\n\n const cond = condition as Record<string, any>\n\n // Handle equals\n if ('equals' in cond) {\n fieldConditions.push(eq(column, cond.equals))\n continue\n }\n\n // Handle not_equals / notEquals\n if ('not_equals' in cond || 'notEquals' in cond) {\n fieldConditions.push(ne(column, cond.not_equals ?? cond.notEquals))\n continue\n }\n\n // Handle in\n if ('in' in cond && Array.isArray(cond.in)) {\n fieldConditions.push(inArray(column, cond.in))\n continue\n }\n\n // Handle not_in / notIn\n if ('not_in' in cond || 'notIn' in cond) {\n const values = cond.not_in ?? cond.notIn\n if (Array.isArray(values)) {\n fieldConditions.push(not(inArray(column, values)))\n }\n continue\n }\n\n // Handle like\n if ('like' in cond && typeof cond.like === 'string') {\n fieldConditions.push(like(column, cond.like))\n continue\n }\n\n // Handle contains\n if ('contains' in cond && typeof cond.contains === 'string') {\n fieldConditions.push(like(column, `%${cond.contains}%`))\n continue\n }\n\n // Handle greater_than / greaterThan\n if ('greater_than' in cond || 'greaterThan' in cond) {\n fieldConditions.push(gt(column, cond.greater_than ?? cond.greaterThan))\n continue\n }\n\n // Handle greater_than_equal / greaterThanEqual\n if ('greater_than_equal' in cond || 'greaterThanEqual' in cond) {\n fieldConditions.push(gte(column, cond.greater_than_equal ?? cond.greaterThanEqual))\n continue\n }\n\n // Handle less_than / lessThan\n if ('less_than' in cond || 'lessThan' in cond) {\n fieldConditions.push(lt(column, cond.less_than ?? cond.lessThan))\n continue\n }\n\n // Handle less_than_equal / lessThanEqual\n if ('less_than_equal' in cond || 'lessThanEqual' in cond) {\n fieldConditions.push(lte(column, cond.less_than_equal ?? cond.lessThanEqual))\n continue\n }\n\n // Handle exists (null check)\n if ('exists' in cond && typeof cond.exists === 'boolean') {\n fieldConditions.push(cond.exists ? isNotNull(column) : isNull(column))\n continue\n }\n }\n\n // Combine all field conditions with AND\n if (fieldConditions.length === 0) {\n return undefined\n }\n if (fieldConditions.length === 1) {\n return fieldConditions[0]\n }\n return and(...fieldConditions)\n}\n\nfunction mapRowsToResults(rows: any[], collectionConfig: any): Array<VectorSearchResult> {\n // Collect names of fields that are typed as number on the collection\n const numberFields = new Set<string>()\n if (collectionConfig?.fields) {\n for (const field of collectionConfig.fields) {\n if (typeof field === 'object' && 'name' in field && field.type === 'number') {\n numberFields.add(field.name as string)\n }\n }\n }\n\n return rows.map((row: any) => {\n // Drizzle returns columns with the names we selected (camelCase)\n // Handle both camelCase and snake_case for robustness\n const rawDocId = row.docId ?? row.doc_id\n const rawChunkIndex = row.chunkIndex ?? row.chunk_index\n const rawScore = row.score\n\n const result: any = {\n ...row,\n id: String(row.id),\n docId: String(rawDocId),\n score: typeof rawScore === 'number' ? rawScore : parseFloat(String(rawScore)),\n chunkIndex:\n typeof rawChunkIndex === 'number' ? rawChunkIndex : parseInt(String(rawChunkIndex), 10),\n }\n\n // Ensure any number fields from the schema are numbers in the result\n for (const fieldName of numberFields) {\n const value = result[fieldName]\n if (value != null && typeof value !== 'number') {\n const parsed = parseFloat(String(value))\n if (!Number.isNaN(parsed)) {\n result[fieldName] = parsed\n }\n }\n }\n\n return result\n })\n}\n"],"names":["sql","cosineDistance","inArray","eq","and","or","not","like","gt","gte","lt","lte","ne","isNull","isNotNull","toSnakeCase","getEmbeddingsTable","payload","queryEmbedding","poolName","limit","where","isPostgres","db","pool","query","drizzle","Error","adapter","collectionConfig","collections","config","table","embeddingColumn","embedding","Object","keys","join","drizzleWhere","undefined","convertWhereToDrizzle","flattenedFields","distanceExpr","selectObj","id","score","field","fields","name","select","from","orderBy","result","mapRowsToResults","Array","isArray","conditions","map","condition","filter","c","length","fieldConditions","fieldName","entries","column","columns","cond","push","equals","not_equals","notEquals","in","values","not_in","notIn","contains","greater_than","greaterThan","greater_than_equal","greaterThanEqual","less_than","lessThan","less_than_equal","lessThanEqual","exists","rows","numberFields","Set","type","add","row","rawDocId","docId","doc_id","rawChunkIndex","chunkIndex","chunk_index","rawScore","String","parseFloat","parseInt","value","parsed","Number","isNaN"],"mappings":"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"}
1
+ {"version":3,"sources":["../src/search.ts"],"sourcesContent":["import {\n sql,\n cosineDistance,\n inArray,\n eq,\n and,\n or,\n not,\n like,\n gt,\n gte,\n lt,\n lte,\n ne,\n isNull,\n isNotNull,\n} from '@payloadcms/db-postgres/drizzle'\nimport { BasePayload, Where } from 'payload'\nimport { KnowledgePoolName, VectorSearchResult } from 'payloadcms-vectorize'\nimport toSnakeCase from 'to-snake-case'\nimport { getEmbeddingsTable } from './drizzle.js'\n\nexport default async (\n payload: BasePayload,\n queryEmbedding: number[],\n poolName: KnowledgePoolName,\n limit: number = 10,\n where?: Where,\n): Promise<Array<VectorSearchResult>> => {\n const isPostgres = payload.db?.pool?.query || payload.db?.drizzle\n\n if (!isPostgres) {\n throw new Error('Only works with Postgres')\n }\n\n // In PayloadCMS, payload.db IS the adapter, and drizzle is at payload.db.drizzle\n const adapter = payload.db\n if (!adapter) {\n throw new Error('Drizzle adapter not found')\n }\n\n // Get drizzle instance\n const drizzle = adapter.drizzle\n if (!drizzle) {\n throw new Error('Drizzle instance not found in adapter')\n }\n\n // Get collection config and table name\n const collectionConfig = payload.collections[poolName]?.config\n if (!collectionConfig) {\n throw new Error(`Collection ${poolName} not found`)\n }\n\n const table = getEmbeddingsTable(poolName)\n if (!table) {\n throw new Error(\n `[payloadcms-vectorize] Embeddings table for knowledge pool \"${poolName}\" not registered. Ensure the plugin's afterSchemaInit hook ran and the pool exists.`,\n )\n }\n\n // Use Drizzle's query builder with cosineDistance function\n // cosineDistance returns distance, so we calculate score as 1 - distance\n // The table from fullSchema should have columns as direct properties\n const embeddingColumn = table.embedding\n if (!embeddingColumn) {\n throw new Error(\n `Embedding column not found in table for pool \"${poolName}\". Available properties: ${Object.keys(table).join(', ')}`,\n )\n }\n\n // Convert WHERE clause to Drizzle conditions\n let drizzleWhere: any = undefined\n if (where) {\n drizzleWhere = convertWhereToDrizzle(where, table, collectionConfig.flattenedFields)\n if (drizzleWhere === null) {\n // WHERE clause resulted in an empty condition (e.g., empty 'and' or 'or' array)\n // This semantically means \"match nothing\", so return empty results\n throw new Error(\n `[payloadcms-vectorize] WHERE clause resulted in no valid conditions. This typically occurs when using empty 'and' or 'or' arrays, or when all field conditions reference non-existent columns.`,\n )\n }\n if (drizzleWhere === undefined) {\n // WHERE clause could not be converted (invalid structure or unsupported operators)\n throw new Error(\n `[payloadcms-vectorize] WHERE clause could not be converted to Drizzle conditions. Please check that all field names exist and operators are supported.`,\n )\n }\n }\n\n // Build query using Drizzle's query builder\n // Column names in the table are camelCase (docId, chunkText, etc.)\n // but their database names are snake_case (doc_id, chunk_text, etc.)\n // The table from fullSchema should have columns as direct properties\n // Calculate score: 1 - cosineDistance (distance)\n // Need to cast 1 to numeric to avoid \"integer - vector\" error\n const distanceExpr = cosineDistance(embeddingColumn, queryEmbedding)\n\n // Build select object with score\n const selectObj: Record<string, any> = {\n id: table.id, // ensure we select id explicitly\n score: sql<number>`1 - (${distanceExpr})`,\n }\n\n // Add reserved + extension fields from collection config\n for (const field of collectionConfig.fields ?? []) {\n if (typeof field === 'object' && 'name' in field) {\n const name = field.name as string\n if (name in table) {\n selectObj[name] = table[name]\n } else if (toSnakeCase(name) in table) {\n selectObj[name] = table[toSnakeCase(name)]\n }\n }\n }\n\n let query: any = drizzle.select(selectObj).from(table)\n\n // Add WHERE clause if provided\n if (drizzleWhere) {\n query = query.where(drizzleWhere)\n }\n\n // Order by cosine distance (ascending = most similar first) and limit\n // Reuse the same distance expression for ordering\n query = query.orderBy(distanceExpr).limit(limit)\n\n // Execute the query\n const result = await query\n\n return mapRowsToResults(result, collectionConfig)\n}\n\n/**\n * Convert Payload WHERE clause to Drizzle conditions\n * Simplified version inspired by Payload's buildQuery\n */\nfunction convertWhereToDrizzle(where: Where, table: any, fields: any[]): any {\n if (!where || typeof where !== 'object') {\n return undefined\n }\n\n // Handle 'and' operator\n if ('and' in where && Array.isArray(where.and)) {\n const conditions = where.and\n .map((condition) => convertWhereToDrizzle(condition, table, fields))\n .filter((c) => c !== undefined && c !== null)\n if (conditions.length === 0) return null\n if (conditions.length === 1) return conditions[0]\n return and(...conditions)\n }\n\n // Handle 'or' operator\n if ('or' in where && Array.isArray(where.or)) {\n const conditions = where.or\n .map((condition) => convertWhereToDrizzle(condition, table, fields))\n .filter((c) => c !== undefined && c !== null)\n if (conditions.length === 0) return null\n if (conditions.length === 1) return conditions[0]\n return or(...conditions)\n }\n\n // Handle field conditions - collect all field conditions and combine with AND\n const fieldConditions: any[] = []\n for (const [fieldName, condition] of Object.entries(where)) {\n if (fieldName === 'and' || fieldName === 'or') continue\n\n // Get the column from the table\n // Drizzle tables have columns as direct properties\n // Try camelCase first, then snake_case as fallback\n // Use 'in' operator to check existence, then access the property\n let column: any = undefined\n if (fieldName in table) {\n column = table[fieldName]\n } else if (toSnakeCase(fieldName) in table) {\n column = table[toSnakeCase(fieldName)]\n } else if (table.columns) {\n // Fallback to table.columns if it exists\n if (fieldName in table.columns) {\n column = table.columns[fieldName]\n } else if (toSnakeCase(fieldName) in table.columns) {\n column = table.columns[toSnakeCase(fieldName)]\n }\n }\n\n if (!column) {\n // Field not found, skip (could be a nested field we don't support)\n continue\n }\n\n if (typeof condition !== 'object' || condition === null || Array.isArray(condition)) {\n continue\n }\n\n const cond = condition as Record<string, any>\n\n // Handle equals\n if ('equals' in cond) {\n fieldConditions.push(eq(column, cond.equals))\n continue\n }\n\n // Handle not_equals / notEquals\n if ('not_equals' in cond || 'notEquals' in cond) {\n fieldConditions.push(ne(column, cond.not_equals ?? cond.notEquals))\n continue\n }\n\n // Handle in\n if ('in' in cond && Array.isArray(cond.in)) {\n fieldConditions.push(inArray(column, cond.in))\n continue\n }\n\n // Handle not_in / notIn\n if ('not_in' in cond || 'notIn' in cond) {\n const values = cond.not_in ?? cond.notIn\n if (Array.isArray(values)) {\n fieldConditions.push(not(inArray(column, values)))\n }\n continue\n }\n\n // Handle like\n if ('like' in cond && typeof cond.like === 'string') {\n fieldConditions.push(like(column, cond.like))\n continue\n }\n\n // Handle contains\n if ('contains' in cond && typeof cond.contains === 'string') {\n fieldConditions.push(like(column, `%${cond.contains}%`))\n continue\n }\n\n // Handle greater_than / greaterThan\n if ('greater_than' in cond || 'greaterThan' in cond) {\n fieldConditions.push(gt(column, cond.greater_than ?? cond.greaterThan))\n continue\n }\n\n // Handle greater_than_equal / greaterThanEqual\n if ('greater_than_equal' in cond || 'greaterThanEqual' in cond) {\n fieldConditions.push(gte(column, cond.greater_than_equal ?? cond.greaterThanEqual))\n continue\n }\n\n // Handle less_than / lessThan\n if ('less_than' in cond || 'lessThan' in cond) {\n fieldConditions.push(lt(column, cond.less_than ?? cond.lessThan))\n continue\n }\n\n // Handle less_than_equal / lessThanEqual\n if ('less_than_equal' in cond || 'lessThanEqual' in cond) {\n fieldConditions.push(lte(column, cond.less_than_equal ?? cond.lessThanEqual))\n continue\n }\n\n // Handle exists (null check)\n if ('exists' in cond && typeof cond.exists === 'boolean') {\n fieldConditions.push(cond.exists ? isNotNull(column) : isNull(column))\n continue\n }\n }\n\n // Combine all field conditions with AND\n if (fieldConditions.length === 0) {\n return undefined\n }\n if (fieldConditions.length === 1) {\n return fieldConditions[0]\n }\n return and(...fieldConditions)\n}\n\nfunction mapRowsToResults(rows: any[], collectionConfig: any): Array<VectorSearchResult> {\n // Collect names of fields that are typed as number on the collection\n const numberFields = new Set<string>()\n if (collectionConfig?.fields) {\n for (const field of collectionConfig.fields) {\n if (typeof field === 'object' && 'name' in field && field.type === 'number') {\n numberFields.add(field.name as string)\n }\n }\n }\n\n return rows.map((row: any) => {\n // Drizzle returns columns with the names we selected (camelCase)\n // Handle both camelCase and snake_case for robustness\n const rawDocId = row.docId ?? row.doc_id\n const rawChunkIndex = row.chunkIndex ?? row.chunk_index\n const rawScore = row.score\n\n const result: any = {\n ...row,\n id: String(row.id),\n docId: String(rawDocId),\n score: typeof rawScore === 'number' ? rawScore : parseFloat(String(rawScore)),\n chunkIndex:\n typeof rawChunkIndex === 'number' ? rawChunkIndex : parseInt(String(rawChunkIndex), 10),\n }\n\n // Ensure any number fields from the schema are numbers in the result\n for (const fieldName of numberFields) {\n const value = result[fieldName]\n if (value != null && typeof value !== 'number') {\n const parsed = parseFloat(String(value))\n if (!Number.isNaN(parsed)) {\n result[fieldName] = parsed\n }\n }\n }\n\n return result\n })\n}\n"],"names":["sql","cosineDistance","inArray","eq","and","or","not","like","gt","gte","lt","lte","ne","isNull","isNotNull","toSnakeCase","getEmbeddingsTable","payload","queryEmbedding","poolName","limit","where","isPostgres","db","pool","query","drizzle","Error","adapter","collectionConfig","collections","config","table","embeddingColumn","embedding","Object","keys","join","drizzleWhere","undefined","convertWhereToDrizzle","flattenedFields","distanceExpr","selectObj","id","score","field","fields","name","select","from","orderBy","result","mapRowsToResults","Array","isArray","conditions","map","condition","filter","c","length","fieldConditions","fieldName","entries","column","columns","cond","push","equals","not_equals","notEquals","in","values","not_in","notIn","contains","greater_than","greaterThan","greater_than_equal","greaterThanEqual","less_than","lessThan","less_than_equal","lessThanEqual","exists","rows","numberFields","Set","type","add","row","rawDocId","docId","doc_id","rawChunkIndex","chunkIndex","chunk_index","rawScore","String","parseFloat","parseInt","value","parsed","Number","isNaN"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@payloadcms-vectorize/pg",
3
- "version": "0.6.0-beta",
3
+ "version": "0.6.0-beta.2",
4
4
  "description": "PostgreSQL adapter for payloadcms-vectorize",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -15,7 +15,7 @@
15
15
  "@payloadcms/db-postgres": ">=3.0.0 <4.0.0"
16
16
  },
17
17
  "devDependencies": {
18
- "payloadcms-vectorize": "0.6.0-beta"
18
+ "payloadcms-vectorize": "workspace:*"
19
19
  },
20
20
  "dependencies": {
21
21
  "to-snake-case": "1.0.0"
@@ -23,5 +23,9 @@
23
23
  "engines": {
24
24
  "node": "^18.20.2 || >=20.9.0",
25
25
  "pnpm": "^9 || ^10"
26
+ },
27
+ "publishConfig": {
28
+ "main": "./dist/index.js",
29
+ "types": "./dist/index.d.ts"
26
30
  }
27
- }
31
+ }