import type { Sql } from 'postgres'; /** * Auto-create all Shade tables if they don't exist. * * Called on PostgresStorage / PostgresPrekeyStore construction. * Uses raw SQL (not Drizzle migrations) for zero-config deployment. * * All tables prefixed with `shade_` to avoid collisions when sharing * a PostgreSQL instance with another project. */ export async function ensureClientTables(sql: Sql): Promise { await sql` CREATE TABLE IF NOT EXISTS shade_identity ( id INTEGER PRIMARY KEY CHECK (id = 1), signing_public_key TEXT NOT NULL, signing_private_key TEXT NOT NULL, dh_public_key TEXT NOT NULL, dh_private_key TEXT NOT NULL ) `; await sql` CREATE TABLE IF NOT EXISTS shade_config ( key TEXT PRIMARY KEY, value TEXT NOT NULL ) `; await sql` CREATE TABLE IF NOT EXISTS shade_signed_prekeys ( key_id INTEGER PRIMARY KEY, data_json TEXT NOT NULL ) `; await sql` CREATE TABLE IF NOT EXISTS shade_one_time_prekeys ( key_id INTEGER PRIMARY KEY, data_json TEXT NOT NULL ) `; await sql` CREATE TABLE IF NOT EXISTS shade_sessions ( address TEXT PRIMARY KEY, state_json TEXT NOT NULL ) `; await sql` CREATE TABLE IF NOT EXISTS shade_trusted_identities ( address TEXT PRIMARY KEY, identity_key TEXT NOT NULL ) `; await sql` CREATE TABLE IF NOT EXISTS shade_retired_identities ( id SERIAL PRIMARY KEY, data_json TEXT NOT NULL, retired_at BIGINT NOT NULL ) `; await sql` CREATE INDEX IF NOT EXISTS shade_retired_at_idx ON shade_retired_identities(retired_at) `; } export async function ensurePrekeyServerTables(sql: Sql): Promise { await sql` CREATE TABLE IF NOT EXISTS shade_server_identities ( address TEXT PRIMARY KEY, identity_signing_key TEXT NOT NULL, identity_dh_key TEXT NOT NULL ) `; await sql` CREATE TABLE IF NOT EXISTS shade_server_signed_prekeys ( address TEXT PRIMARY KEY, key_id INTEGER NOT NULL, public_key TEXT NOT NULL, signature TEXT NOT NULL ) `; await sql` CREATE TABLE IF NOT EXISTS shade_server_one_time_prekeys ( id SERIAL PRIMARY KEY, address TEXT NOT NULL, key_id INTEGER NOT NULL, public_key TEXT NOT NULL ) `; await sql` CREATE INDEX IF NOT EXISTS shade_server_otp_address_idx ON shade_server_one_time_prekeys(address) `; }