@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.22 kB
JavaScript
import{quoteIdentifier as a,sqlAffinityForKind as $,frameworkColumnDdl as y,OCC_VERSION_COLUMN as T,MAX_D1_TABLE_COLUMNS as d,columnRef as g,physicalIndexName as c}from"@lunora/d1/dialect";import{LunoraError as E}from"@lunora/errors";const v=e=>$(e),f=(e,i)=>{const o=[a(e),i.sqlType];return i.nullable||o.push("NOT NULL"),o.join(" ")},L=e=>{const i=Object.entries(e.columns).map(([s,r])=>` ${f(s,r)}`),o=[...y(),`${a(T)} INTEGER`],n=o.length+i.length;if(n>d)throw new E("VALIDATION_ERROR",`table "${e.name}" needs ${String(n)} 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}`),...i].join(`,
`);return`CREATE TABLE IF NOT EXISTS ${a(e.name)} (
${t}
);`},O=e=>`DROP TABLE IF EXISTS ${a(e)};`,C=(e,i,o)=>`ALTER TABLE ${a(e)} ADD COLUMN ${f(i,o)};`,m=(e,i)=>{const o=i.fields.map(t=>g(t)).join(", ");return`CREATE ${i.unique?"UNIQUE ":""}INDEX IF NOT EXISTS ${c(e,i.name)} ON ${a(e)} (${o});`},N=(e,i)=>`DROP INDEX IF EXISTS ${c(e,i)};`,u=e=>e.field===void 0?void 0:JSON.stringify({...e.field,optional:void 0}),I="https://lunora.sh/docs/concepts/migrations#relaxing-not-null-on-a-d1-table",S=(e,i,o,n,t)=>{const s=u(o),r=u(n);if(o.sqlType!==n.sqlType)t.push({kind:"columnTypeChange",summary:`column type change on ${e}.${i}: ${o.sqlType} → ${n.sqlType} (write SQL manually)`});else if(s!==void 0&&r!==void 0&&s!==r){const l=o.field?.kind===n.field?.kind?`${String(n.field?.kind)} shape/constraints changed`:`${String(o.field?.kind)} → ${String(n.field?.kind)}`;t.push({kind:"columnTypeChange",summary:`column type change on ${e}.${i}: ${l} (write SQL manually)`})}if(o.nullable!==n.nullable){const l=n.nullable?`rebuild the table — ${I}`:"write SQL manually";t.push({kind:"columnTypeChange",summary:`nullability change on ${e}.${i}: ${o.nullable?"NULL":"NOT NULL"} → ${n.nullable?"NULL":"NOT NULL"} (${l})`})}},b=(e,i,o,n,t)=>{for(const[s,r]of Object.entries(o)){const l=i[s];if(l===void 0){n.push({kind:"addColumn",sql:C(e,s,r),summary:`ADD COLUMN ${e}.${s}`});continue}S(e,s,l,r,t)}for(const s of Object.keys(i))o[s]===void 0&&t.push({kind:"dropColumn",summary:`DROP COLUMN ${e}.${s} (SQLite drop-column requires careful migration — write SQL manually)`})},q=(e,i,o,n,t)=>{for(const[s,r]of Object.entries(o)){const l=i[s];if(l===void 0){n.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(i))o[s]===void 0&&n.push({kind:"dropIndex",sql:N(e,s),summary:`DROP INDEX ${s}`})},D=(e,i,o)=>{o.push({kind:"createTable",sql:L(i),summary:`CREATE TABLE ${e}`});for(const n of Object.values(i.indexes))o.push({kind:"createIndex",sql:m(e,n),summary:`CREATE INDEX ${n.name} ON ${e}`})},w=(e,i)=>{const o=e?.tables??{},n=[],t=[];for(const[s,r]of Object.entries(i.tables)){const l=o[s];if(l===void 0){D(s,r,n);continue}b(s,l.columns,r.columns,n,t),q(s,l.indexes,r.indexes,n,t)}for(const s of Object.keys(o))i.tables[s]===void 0&&n.push({kind:"dropTable",sql:O(s),summary:`DROP TABLE ${s}`});return{empty:n.length===0&&t.length===0,entries:n,unsupported:t}},x=(e,i,o)=>{const n=[`-- Lunora migration: ${e}`,`-- Generated at ${o}`,"-- This file was produced by `lunora migrate generate`. Review carefully before applying.",""];for(const t of i.entries)n.push(`-- ${t.summary}`,t.sql,"");if(i.unsupported.length>0){n.push("-- ---------------------------------------------------------------","-- The following deltas are NOT auto-generated in v0.1.","-- Write the appropriate SQL below by hand:","--");for(const t of i.unsupported)n.push(`-- * ${t.summary}`);n.push("-- ---------------------------------------------------------------","")}return i.empty&&n.push("-- No changes detected. Re-running `lunora migrate generate` will overwrite this file.",""),n.join(`
`)};export{w as diffSnapshots,C as renderAddColumn,m as renderCreateIndex,L as renderCreateTable,N as renderDropIndex,O as renderDropTable,x as renderMigrationFile,v as validatorKindToSqlType};