UNPKG

@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) 3.35 kB
import{quoteIdentifier as l,sqlAffinityForKind as f,frameworkColumnDdl as y,columnRef as $,physicalIndexName as u}from"@lunora/d1/dialect";const q=e=>f(e),d=(e,n)=>{const s=[l(e),n.sqlType];return n.nullable||s.push("NOT NULL"),s.join(" ")},T=e=>{const n=Object.entries(e.columns).map(([r,a])=>` ${d(r,a)}`),s=[...y().map(r=>` ${r}`),...n].join(`, `);return`CREATE TABLE IF NOT EXISTS ${l(e.name)} ( ${s} );`},h=e=>`DROP TABLE IF EXISTS ${l(e)};`,b=(e,n,s)=>`ALTER TABLE ${l(e)} ADD COLUMN ${d(n,s)};`,m=(e,n)=>{const s=n.fields.map(r=>$(r)).join(", ");return`CREATE ${n.unique?"UNIQUE ":""}INDEX IF NOT EXISTS ${u(e,n.name)} ON ${l(e)} (${s});`},E=(e,n)=>`DROP INDEX IF EXISTS ${u(e,n)};`,L=(e,n,s,r,a)=>{s.sqlType!==r.sqlType&&a.push({kind:"columnTypeChange",summary:`column type change on ${e}.${n}: ${s.sqlType}${r.sqlType} (write SQL manually)`}),s.nullable!==r.nullable&&a.push({kind:"columnTypeChange",summary:`nullability change on ${e}.${n}: ${s.nullable?"NULL":"NOT NULL"}${r.nullable?"NULL":"NOT NULL"} (write SQL manually)`})},N=(e,n,s,r,a)=>{for(const[o,i]of Object.entries(s)){const t=n[o];if(t===void 0){r.push({kind:"addColumn",sql:b(e,o,i),summary:`ADD COLUMN ${e}.${o}`});continue}L(e,o,t,i,a)}for(const o of Object.keys(n))s[o]===void 0&&a.push({kind:"dropColumn",summary:`DROP COLUMN ${e}.${o} (SQLite drop-column requires careful migration — write SQL manually)`})},O=(e,n,s,r,a)=>{for(const[o,i]of Object.entries(s)){const t=n[o];if(t===void 0){r.push({kind:"createIndex",sql:m(e,i),summary:`CREATE INDEX ${o} ON ${e}`});continue}(!(t.fields.length===i.fields.length&&t.fields.every((p,c)=>p===i.fields[c]))||t.unique!==i.unique)&&a.push({kind:"indexRename",summary:`index ${o} changed on ${e} — drop+create manually if intentional`})}for(const o of Object.keys(n))s[o]===void 0&&r.push({kind:"dropIndex",sql:E(e,o),summary:`DROP INDEX ${o}`})},g=(e,n,s)=>{s.push({kind:"createTable",sql:T(n),summary:`CREATE TABLE ${e}`});for(const r of Object.values(n.indexes))s.push({kind:"createIndex",sql:m(e,r),summary:`CREATE INDEX ${r.name} ON ${e}`})},D=(e,n)=>{const s=e?.tables??{},r=[],a=[];for(const[o,i]of Object.entries(n.tables)){const t=s[o];if(t===void 0){g(o,i,r);continue}N(o,t.columns,i.columns,r,a),O(o,t.indexes,i.indexes,r,a)}for(const o of Object.keys(s))n.tables[o]===void 0&&r.push({kind:"dropTable",sql:h(o),summary:`DROP TABLE ${o}`});return{empty:r.length===0&&a.length===0,entries:r,unsupported:a}},C=(e,n,s)=>{const r=[`-- Lunora migration: ${e}`,`-- Generated at ${s}`,"-- This file was produced by `lunora migrate generate`. Review carefully before applying.",""];for(const a of n.entries)r.push(`-- ${a.summary}`,a.sql,"");if(n.unsupported.length>0){r.push("-- ---------------------------------------------------------------","-- The following deltas are NOT auto-generated in v0.1.","-- Write the appropriate SQL below by hand:","--");for(const a of n.unsupported)r.push(`-- * ${a.summary}`);r.push("-- ---------------------------------------------------------------","")}return n.empty&&r.push("-- No changes detected. Re-running `lunora migrate generate` will overwrite this file.",""),r.join(` `)};export{D as diffSnapshots,b as renderAddColumn,m as renderCreateIndex,T as renderCreateTable,E as renderDropIndex,h as renderDropTable,C as renderMigrationFile,q as validatorKindToSqlType};