@lunora/cli
Version:
The Lunora CLI: init, dev, deploy, codegen, migrate, seed, doctor, insights, logs, registry, and the rest of the project commands
6 lines (5 loc) • 4.08 kB
JavaScript
import{quoteIdentifier as a,sqlAffinityForKind as $,frameworkColumnDdl as y,OCC_VERSION_COLUMN as T,MAX_D1_TABLE_COLUMNS as d,columnRef as E,physicalIndexName as c}from"@lunora/d1/dialect";import{LunoraError as g}from"@lunora/errors";const v=e=>$(e),f=(e,n)=>{const o=[a(e),n.sqlType];return n.nullable||o.push("NOT NULL"),o.join(" ")},O=e=>{const n=Object.entries(e.columns).map(([s,r])=>` ${f(s,r)}`),o=[...y(),`${a(T)} INTEGER`],i=o.length+n.length;if(i>d)throw new g("VALIDATION_ERROR",`table "${e.name}" needs ${String(i)} columns, over D1's ${String(d)}-column limit — split the table, or move the extra fields into one object field`);const t=[...o.map(s=>` ${s}`),...n].join(`,
`);return`CREATE TABLE IF NOT EXISTS ${a(e.name)} (
${t}
);`},L=e=>`DROP TABLE IF EXISTS ${a(e)};`,C=(e,n,o)=>`ALTER TABLE ${a(e)} ADD COLUMN ${f(n,o)};`,m=(e,n)=>{const o=n.fields.map(t=>E(t)).join(", ");return`CREATE ${n.unique?"UNIQUE ":""}INDEX IF NOT EXISTS ${c(e,n.name)} ON ${a(e)} (${o});`},I=(e,n)=>`DROP INDEX IF EXISTS ${c(e,n)};`,u=e=>e.field===void 0?void 0:JSON.stringify({...e.field,optional:void 0}),N=(e,n,o,i,t)=>{const s=u(o),r=u(i);if(o.sqlType!==i.sqlType)t.push({kind:"columnTypeChange",summary:`column type change on ${e}.${n}: ${o.sqlType} → ${i.sqlType} (write SQL manually)`});else if(s!==void 0&&r!==void 0&&s!==r){const l=o.field?.kind===i.field?.kind?`${String(i.field?.kind)} shape/constraints changed`:`${String(o.field?.kind)} → ${String(i.field?.kind)}`;t.push({kind:"columnTypeChange",summary:`column type change on ${e}.${n}: ${l} (write SQL manually)`})}o.nullable!==i.nullable&&t.push({kind:"columnTypeChange",summary:`nullability change on ${e}.${n}: ${o.nullable?"NULL":"NOT NULL"} → ${i.nullable?"NULL":"NOT NULL"} (write SQL manually)`})},S=(e,n,o,i,t)=>{for(const[s,r]of Object.entries(o)){const l=n[s];if(l===void 0){i.push({kind:"addColumn",sql:C(e,s,r),summary:`ADD COLUMN ${e}.${s}`});continue}N(e,s,l,r,t)}for(const s of Object.keys(n))o[s]===void 0&&t.push({kind:"dropColumn",summary:`DROP COLUMN ${e}.${s} (SQLite drop-column requires careful migration — write SQL manually)`})},q=(e,n,o,i,t)=>{for(const[s,r]of Object.entries(o)){const l=n[s];if(l===void 0){i.push({kind:"createIndex",sql:m(e,r),summary:`CREATE INDEX ${s} ON ${e}`});continue}(!(l.fields.length===r.fields.length&&l.fields.every((p,h)=>p===r.fields[h]))||l.unique!==r.unique)&&t.push({kind:"indexRename",summary:`index ${s} changed on ${e} — drop+create manually if intentional`})}for(const s of Object.keys(n))o[s]===void 0&&i.push({kind:"dropIndex",sql:I(e,s),summary:`DROP INDEX ${s}`})},k=(e,n,o)=>{o.push({kind:"createTable",sql:O(n),summary:`CREATE TABLE ${e}`});for(const i of Object.values(n.indexes))o.push({kind:"createIndex",sql:m(e,i),summary:`CREATE INDEX ${i.name} ON ${e}`})},A=(e,n)=>{const o=e?.tables??{},i=[],t=[];for(const[s,r]of Object.entries(n.tables)){const l=o[s];if(l===void 0){k(s,r,i);continue}S(s,l.columns,r.columns,i,t),q(s,l.indexes,r.indexes,i,t)}for(const s of Object.keys(o))n.tables[s]===void 0&&i.push({kind:"dropTable",sql:L(s),summary:`DROP TABLE ${s}`});return{empty:i.length===0&&t.length===0,entries:i,unsupported:t}},w=(e,n,o)=>{const i=[`-- Lunora migration: ${e}`,`-- Generated at ${o}`,"-- This file was produced by `lunora migrate generate`. Review carefully before applying.",""];for(const t of n.entries)i.push(`-- ${t.summary}`,t.sql,"");if(n.unsupported.length>0){i.push("-- ---------------------------------------------------------------","-- The following deltas are NOT auto-generated in v0.1.","-- Write the appropriate SQL below by hand:","--");for(const t of n.unsupported)i.push(`-- * ${t.summary}`);i.push("-- ---------------------------------------------------------------","")}return n.empty&&i.push("-- No changes detected. Re-running `lunora migrate generate` will overwrite this file.",""),i.join(`
`)};export{A as diffSnapshots,C as renderAddColumn,m as renderCreateIndex,O as renderCreateTable,I as renderDropIndex,L as renderDropTable,w as renderMigrationFile,v as validatorKindToSqlType};