import { runtimeError } from '@prisma-next/framework-components/runtime'; import type { ContractCodecRegistry, SqlCodecCallContext, } from '@prisma-next/sql-relational-core/ast'; import { encodeParamsWithMetadata } from '../codecs/encoding'; import type { PreparedStatementInternals } from './prepared-statement'; /** * Resolve a PreparedStatement's slot order to the unencoded values it * will carry into encode. Literal slots come from the lowered AST; * bind slots are looked up by name on `userParams`. Missing user params * surface `RUNTIME.PREPARE_MISSING_PARAM` so the caller cannot silently * bind `undefined`. */ export function resolvePreparedSlotValues( ps: PreparedStatementInternals, userParams: Record, ): unknown[] { return ps.slots.map((slot) => { if (slot.kind === 'literal') return slot.value; if (!Object.hasOwn(userParams, slot.name)) { throw runtimeError( 'RUNTIME.PREPARE_MISSING_PARAM', `Prepared statement execute is missing parameter '${slot.name}'`, { name: slot.name }, ); } return userParams[slot.name]; }); } export async function encodePreparedParams( ps: PreparedStatementInternals, userParams: Record, ctx: SqlCodecCallContext, contractCodecs?: ContractCodecRegistry, ): Promise { const resolved = resolvePreparedSlotValues(ps, userParams); return encodeParamsWithMetadata(resolved, ps.paramMetadata, ctx, contractCodecs); }