@noormdev/cli 1.0.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunk-FQKJMLMW.js +1 -0
- package/dist/chunk-WOT6VMZA.js +1 -0
- package/dist/engine-Z55HXOAZ.js +1 -0
- package/dist/index.js +2100 -0
- package/dist/mssql-GVXYXFBZ.js +1 -0
- package/dist/mysql-LUTQ2CEP.js +1 -0
- package/dist/postgres-DEDRRMUE.js +1 -0
- package/dist/sqlite-OQR7CVXV.js +1 -0
- package/package.json +35 -0
- package/scripts/postinstall.js +80 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,2100 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import{a as k,c as Ms,e as gi}from"./chunk-FQKJMLMW.js";import{a as ot}from"./chunk-WOT6VMZA.js";import QF from"meow";import{render as ZF}from"ink";import{useState as PS,useCallback as Jc}from"react";import{Box as an,Text as Nr,Spacer as IN,useInput as ON}from"ink";import{createContext as QS,useContext as ZS,useState as eC,useCallback as Dm,useMemo as iy,useId as tC,useEffect as rC}from"react";import{jsx as nC}from"react/jsx-runtime";var sy=QS(null);function ay({children:t}){let[e,r]=eC([]),n=Dm((c,l)=>{r(m=>m.some(d=>d.id===c)?m:[...m,{id:c,label:l}])},[]),o=Dm(c=>{r(l=>{let m=l.findIndex(d=>d.id===c);return m===-1?l:[...l.slice(0,m),...l.slice(m+1)]})},[]),i=Dm(c=>e.length===0?!1:e[e.length-1].id===c,[e]),s=iy(()=>e.length===0?null:e[e.length-1].id,[e]),a=iy(()=>({push:n,pop:o,isActive:i,activeId:s,stack:e}),[n,o,i,s,e]);return nC(sy.Provider,{value:a,children:t})}function Pm(){let t=ZS(sy);if(!t)throw new Error("useFocusContext must be used within a FocusProvider");return t}function A(t){let e=typeof t=="string"?{label:t}:t??{},{label:r,skip:n=!1}=e,{push:o,pop:i,isActive:s}=Pm(),a=tC();return rC(()=>{if(!n)return o(a,r),()=>{i(a)}},[a,r,o,i,n]),{isFocused:n?!1:s(a),focusId:a}}import{createContext as aE,useContext as cE,useState as Ed,useCallback as Gl,useMemo as lE}from"react";function cy(t){return t.split("/")[0]}function Nm(t){if(t==="home")return null;let e=t.split("/");return e.length===1?"home":e.slice(0,-1).join("/")}import{existsSync as Ga,mkdirSync as by,readFileSync as Sy,writeFileSync as Cy}from"fs";import{dirname as wy,join as SC}from"path";import{attemptSync as Qi,attempt as Ty}from"@logosdx/utils";import{homedir as oC}from"os";import{join as rl}from"path";import{chmod as ly,mkdir as iC,readFile as Bm,stat as uy,writeFile as Fm}from"fs/promises";import{attempt as uo,attemptSync as sC}from"@logosdx/utils";var Ua=rl(oC(),".noorm"),el=rl(Ua,"identity.key"),tl=rl(Ua,"identity.pub"),my=384,dy=420,py=rl(Ua,"identity.json");async function fy(){let[,t]=await uo(()=>iC(Ua,{recursive:!0}));if(t)throw new Error(`Failed to create ${Ua}: ${t.message}`)}async function Lm(t){await fy();let[,e]=await uo(()=>Fm(el,t.privateKey,{encoding:"utf8",mode:my}));if(e)throw new Error(`Failed to write private key: ${e.message}`);await uo(()=>ly(el,my));let[,r]=await uo(()=>Fm(tl,t.publicKey,{encoding:"utf8",mode:dy}));if(r)throw new Error(`Failed to write public key: ${r.message}`);await uo(()=>ly(tl,dy))}async function nl(t){await fy();let e={identityHash:t.identityHash,name:t.name,email:t.email,publicKey:t.publicKey,machine:t.machine,os:t.os,createdAt:t.createdAt},[,r]=await uo(()=>Fm(py,JSON.stringify(e,null,2),{encoding:"utf8"}));if(r)throw new Error(`Failed to write identity metadata: ${r.message}`)}async function Ya(){let[t,e]=await uo(()=>Bm(py,{encoding:"utf8"}));if(e){if(e.code==="ENOENT")return null;throw new Error(`Failed to read identity metadata: ${e.message}`)}let[r,n]=sC(()=>JSON.parse(t));return n?null:r}async function $s(){let[t,e]=await uo(()=>Bm(el,{encoding:"utf8"}));if(e){if(e.code==="ENOENT")return null;throw new Error(`Failed to read private key: ${e.message}`)}return t.trim()}async function ol(){let[t,e]=await uo(()=>Bm(tl,{encoding:"utf8"}));if(e){if(e.code==="ENOENT")return null;throw new Error(`Failed to read public key: ${e.message}`)}return t.trim()}async function Wa(){let[t]=await uo(()=>uy(el)),[e]=await uo(()=>uy(tl));return!!t&&!!e}import{createCipheriv as fC,createDecipheriv as gC,randomBytes as yC}from"crypto";import{generateKeyPairSync as aC,createCipheriv as cC,createDecipheriv as lC,createPrivateKey as uC,createPublicKey as mC,diffieHellman as dC,hkdfSync as gy,randomBytes as pC}from"crypto";function il(){let{publicKey:t,privateKey:e}=aC("x25519",{publicKeyEncoding:{type:"spki",format:"der"},privateKeyEncoding:{type:"pkcs8",format:"der"}});return{publicKey:t.toString("hex"),privateKey:e.toString("hex")}}function yy(t,e){let r=uC({key:Buffer.from(t,"hex"),format:"der",type:"pkcs8"}),n=mC({key:Buffer.from(e,"hex"),format:"der",type:"spki"});return dC({privateKey:r,publicKey:n})}function hy(t,e){return Buffer.from(gy("sha256",t,Buffer.alloc(0),e,32))}function Im(t,e,r,n){let o=il(),i=yy(o.privateKey,e),s=hy(i,"noorm-config-share"),a=pC(16),c=cC("aes-256-gcm",s,a),l=Buffer.concat([c.update(t,"utf8"),c.final()]),m=c.getAuthTag();return{version:1,sender:r,recipient:n,ephemeralPubKey:o.publicKey,iv:a.toString("hex"),authTag:m.toString("hex"),ciphertext:l.toString("hex")}}function Om(t,e){if(t.version!==1)throw new Error(`Unsupported payload version: ${t.version}`);let r=yy(e,t.ephemeralPubKey),n=hy(r,"noorm-config-share"),o=lC("aes-256-gcm",n,Buffer.from(t.iv,"hex"));return o.setAuthTag(Buffer.from(t.authTag,"hex")),Buffer.concat([o.update(Buffer.from(t.ciphertext,"hex")),o.final()]).toString("utf8")}function sl(t){let e=Buffer.from(t,"hex");return Buffer.from(gy("sha256",e,Buffer.alloc(0),"noorm-state-encryption",32))}var al="aes-256-gcm",hC=16,xy=16;function Am(t,e){let r=sl(e),n=yC(hC),o=fC(al,r,n,{authTagLength:xy}),i=Buffer.concat([o.update(t,"utf8"),o.final()]),s=o.getAuthTag();return{algorithm:al,iv:n.toString("base64"),authTag:s.toString("base64"),ciphertext:i.toString("base64")}}function cl(t,e){if(t.algorithm!==al)throw new Error(`Unsupported algorithm: ${t.algorithm}`);let r=sl(e),n=Buffer.from(t.iv,"base64"),o=Buffer.from(t.authTag,"base64"),i=Buffer.from(t.ciphertext,"base64"),s=gC(al,r,n,{authTagLength:xy});return s.setAuthTag(o),Buffer.concat([s.update(i),s.final()]).toString("utf8")}function Mm(t){return{version:t,knownUsers:{},activeConfig:null,configs:{},secrets:{},globalSecrets:{}}}function ll(t,e){if(typeof t!="object"||t===null)throw new Error("Invalid state format: expected object");let r=t,n=r.version,o={version:e,knownUsers:r.knownUsers??{},activeConfig:r.activeConfig??null,configs:r.configs??{},secrets:r.secrets??{},globalSecrets:r.globalSecrets??{}};return n!==e&&k.emit("state:migrated",{from:n??"unknown",to:e}),o}function ul(t,e){if(typeof t!="object"||t===null)return!0;let r=t;return r.version!==e||!("globalSecrets"in r)||!("identity"in r)||!("knownUsers"in r)}import{createRequire as xC}from"module";var bC=xC(import.meta.url);function ml(){return bC("../../../package.json").version}var CC=".noorm",wC="state.enc",Zi=class{constructor(e,r={}){this.projectRoot=e;this.privateKey=r.privateKey;let n=r.stateDir??CC,o=r.stateFile??wC;this.statePath=SC(e,n,o)}state=null;privateKey;statePath;loaded=!1;async load(){if(this.loaded)return;if(!this.privateKey){let[d]=await Ty(()=>$s());d&&(this.privateKey=d)}let e=ml();if(!Ga(this.statePath)){this.state=Mm(e),this.loaded=!0,k.emit("state:loaded",{configCount:0,activeConfig:null,version:e});return}if(!this.privateKey)throw new Error("Private key required to decrypt state. Set up identity with: noorm init");let[r,n]=Qi(()=>Sy(this.statePath,"utf8"));if(n)throw k.emit("error",{source:"state",error:n}),n;let[o,i]=Qi(()=>JSON.parse(r));if(i)throw k.emit("error",{source:"state",error:i}),new Error("Failed to parse state file. File may be corrupted.");let[s,a]=Qi(()=>cl(o,this.privateKey));if(a)throw k.emit("error",{source:"state",error:a}),new Error("Failed to decrypt state. Wrong key or corrupted file.");let[c,l]=Qi(()=>JSON.parse(s));if(l)throw k.emit("error",{source:"state",error:l}),new Error("Failed to parse decrypted state.");let m=ul(c,e);this.state=ll(c,e),this.loaded=!0,m&&this.persist(),k.emit("state:loaded",{configCount:Object.keys(this.state.configs).length,activeConfig:this.state.activeConfig,version:this.state.version})}async reloadPrivateKey(){let[e]=await Ty(()=>$s());return e?(this.privateKey=e,!0):!1}persist(){if(!this.privateKey)throw new Error("Private key required to save state. Set up identity with: noorm init");let e=this.getState(),r=wy(this.statePath);Ga(r)||by(r,{recursive:!0});let n=JSON.stringify(e),o=Am(n,this.privateKey),[,i]=Qi(()=>Cy(this.statePath,JSON.stringify(o,null,2)));if(i)throw k.emit("error",{source:"state",error:i}),i;k.emit("state:persisted",{configCount:Object.keys(e.configs).length})}getState(){if(!this.loaded||!this.state)throw new Error("StateManager not loaded. Call load() first.");return this.state}getConfig(e){return this.getState().configs[e]??null}async setConfig(e,r){let n=this.getState(),o=!n.configs[e];n.configs[e]=r,this.persist(),k.emit(o?"config:created":"config:updated",{name:e,fields:Object.keys(r)})}async deleteConfig(e){let r=this.getState();delete r.configs[e],delete r.secrets[e],r.activeConfig===e&&(r.activeConfig=null),this.persist(),k.emit("config:deleted",{name:e})}listConfigs(){let e=this.getState();return Object.entries(e.configs).map(([r,n])=>({name:r,type:n.type,isTest:n.isTest,protected:n.protected,isActive:e.activeConfig===r,dialect:n.connection.dialect,database:n.connection.database}))}getActiveConfig(){let e=this.getState();return e.activeConfig?e.configs[e.activeConfig]??null:null}getActiveConfigName(){return this.getState().activeConfig}async setActiveConfig(e){let r=this.getState();if(!r.configs[e])throw new Error(`Config "${e}" does not exist.`);let n=r.activeConfig;r.activeConfig=e,this.persist(),k.emit("config:activated",{name:e,previous:n})}getSecret(e,r){return this.getState().secrets[e]?.[r]??null}getAllSecrets(e){let r=this.getState();return r.secrets[e]?{...r.secrets[e]}:{}}async setSecret(e,r,n){let o=this.getState();if(!o.configs[e])throw new Error(`Config "${e}" does not exist.`);o.secrets[e]||(o.secrets[e]={}),o.secrets[e][r]=n,this.persist(),k.emit("secret:set",{configName:e,key:r})}async deleteSecret(e,r){let n=this.getState();n.secrets[e]&&(delete n.secrets[e][r],this.persist(),k.emit("secret:deleted",{configName:e,key:r}))}listSecrets(e){let r=this.getState();return Object.keys(r.secrets[e]??{})}getGlobalSecret(e){return this.getState().globalSecrets[e]??null}getAllGlobalSecrets(){return{...this.getState().globalSecrets}}async setGlobalSecret(e,r){let n=this.getState();n.globalSecrets[e]=r,this.persist(),k.emit("global-secret:set",{key:e})}async deleteGlobalSecret(e){let r=this.getState();e in r.globalSecrets&&(delete r.globalSecrets[e],this.persist(),k.emit("global-secret:deleted",{key:e}))}listGlobalSecrets(){let e=this.getState();return Object.keys(e.globalSecrets)}getKnownUsers(){return{...this.getState().knownUsers}}getKnownUser(e){return this.getState().knownUsers[e]??null}findKnownUsersByEmail(e){let r=this.getState();return Object.values(r.knownUsers).filter(n=>n.email===e)}async addKnownUser(e){let r=this.getState();r.knownUsers[e.identityHash]=e,this.persist(),k.emit("known-user:added",{email:e.email,source:e.source})}async addKnownUsers(e){let r=this.getState();for(let n of e)r.knownUsers[n.identityHash]=n;this.persist()}getVersion(){return this.getState().version}exists(){return Ga(this.statePath)}getStatePath(){return this.statePath}exportEncrypted(){return Ga(this.statePath)?Sy(this.statePath,"utf8"):null}async importEncrypted(e){if(!this.privateKey)throw new Error("Private key required to import state.");let[r,n]=Qi(()=>JSON.parse(e));if(n)throw n;let[,o]=Qi(()=>cl(r,this.privateKey));if(o)throw o;let i=wy(this.statePath);Ga(i)||by(i,{recursive:!0}),Cy(this.statePath,e),this.loaded=!1,await this.load()}setPrivateKey(e){this.privateKey=e}hasPrivateKey(){return!!this.privateKey}};var $m=null;function Ur(t){if(!$m){let e=t??process.cwd();$m=new Zi(e)}return $m}async function Xa(t){let e=Ur(t);return await e.load(),e}import{sql as TC}from"kysely";import{retry as EC,attempt as qm}from"@logosdx/utils";import{attempt as Ey}from"@logosdx/utils";var Hm=class{#t=new Map;#e=new Map;#o=1;#r=!1;#i=null;constructor(){this.#i=k.on("app:shutdown",async()=>{process.env.NOORM_DEBUG&&console.error(`[ConnectionManager] app:shutdown received, closing ${this.size} connections`),this.#r=!0,await this.closeAll(),process.env.NOORM_DEBUG&&console.error("[ConnectionManager] all connections closed")})}track(e,r){let n=this.#o++;return this.#e.set(n,{conn:e,configName:r,createdAt:new Date}),n}untrack(e){this.#e.delete(e)}async getConnection(e,r){let n=e.name;if(this.#t.has(n))return this.#t.get(n);let o=await r(e);return this.#t.set(n,o),o}async closeCached(e){let r=this.#t.get(e);if(r){let[,n]=await Ey(()=>r.destroy());this.#t.delete(e),n?k.emit("error",{source:"connection",error:n}):k.emit("connection:close",{configName:e})}}async closeAll(){let r=Array.from(this.#t.keys());for(let o of r)await this.closeCached(o);let n=Array.from(this.#e.entries());for(let[o,i]of n){let s=Promise.race([i.conn.destroy(),new Promise(c=>setTimeout(c,5e3))]),[,a]=await Ey(()=>s);this.#e.delete(o),a?k.emit("error",{source:"connection",error:a}):k.emit("connection:close",{configName:i.configName})}}hasCached(e){return this.#t.has(e)}get size(){return this.#t.size+this.#e.size}get isShuttingDown(){return this.#r}dispose(){this.#i&&(this.#i(),this.#i=null)}},jm=null;function js(){return jm||(jm=new Hm),jm}async function RC(t){switch(t){case"sqlite":return(await import("./sqlite-OQR7CVXV.js")).createSqliteConnection;case"postgres":return(await import("./postgres-DEDRRMUE.js")).createPostgresConnection;case"mysql":return(await import("./mysql-LUTQ2CEP.js")).createMysqlConnection;case"mssql":return(await import("./mssql-GVXYXFBZ.js")).createMssqlConnection;default:throw new Error(`Unsupported dialect: ${t}`)}}function kC(t){return{postgres:"npm install pg",mysql:"npm install mysql2",sqlite:"npm install better-sqlite3",mssql:"npm install tedious tarn"}[t]}async function K(t,e="__default__"){let[r,n]=await qm(()=>EC(async()=>{let[l,m]=await qm(()=>RC(t.dialect));if(m)throw m.message.includes("Cannot find module")?new Error(`Missing driver for ${t.dialect}. Install it with:
|
|
3
|
+
`+kC(t.dialect)):m;let d=await l(t);return await TC`SELECT 1`.execute(d.db),d},{retries:3,delay:1e3,backoff:2,jitterFactor:.1,shouldRetry:l=>{let m=l.message.toLowerCase();return m.includes("authentication")||m.includes("password")||m.includes("missing driver")?!1:m.includes("econnrefused")||m.includes("etimedout")||m.includes("too many connections")||m.includes("connection reset")}}));if(n)throw k.emit("connection:error",{configName:e,error:n.message}),n;let o=js(),i=o.track(r,e),s=r.destroy,a=async()=>{o.untrack(i),await s(),k.emit("connection:close",{configName:e})},c={db:r.db,dialect:r.dialect,destroy:a};return k.emit("connection:open",{configName:e,dialect:t.dialect}),c}var _C={postgres:"postgres",mysql:void 0,sqlite:void 0,mssql:"master"};async function de(t,e={}){let r=t;if(e.testServerOnly&&t.dialect!=="sqlite"){let i=_C[t.dialect];r={...t,database:i??t.database}}let[n,o]=await qm(()=>K(r,"__test__"));return o?{ok:!1,error:o.message}:(await n.destroy(),{ok:!0})}import{z as Z}from"zod";var DC=Z.enum(["postgres","mysql","sqlite","mssql"]),PC=Z.enum(["string","password","api_key","connection_string"]),NC=Z.enum(["local","remote"]),FC=Z.enum(["silent","error","warn","info","verbose"]),BC=Z.number().int().min(1,"Port must be at least 1").max(65535,"Port must be at most 65535"),LC=Z.string().regex(/^\d+\s*(b|kb|mb|gb)$/i,'Invalid file size format (e.g., "10mb")'),Ry=Z.object({key:Z.string().min(1,"Secret key is required"),type:PC,description:Z.string().optional(),required:Z.boolean().default(!0)}),IC=Z.object({dialect:DC.optional(),host:Z.string().optional(),port:BC.optional(),database:Z.string().optional(),user:Z.string().optional(),password:Z.string().optional(),ssl:Z.boolean().optional(),isTest:Z.boolean().optional(),protected:Z.boolean().optional()}),OC=Z.object({description:Z.string().optional(),locked:Z.boolean().default(!1),defaults:IC.optional(),secrets:Z.array(Ry).optional()}),AC=Z.object({name:Z.string().optional(),protected:Z.boolean().optional(),isTest:Z.boolean().optional(),type:NC.optional()}).refine(t=>Object.keys(t).length>0,{message:"Rule match must specify at least one condition"}),MC=Z.object({match:AC,include:Z.array(Z.string()).optional(),exclude:Z.array(Z.string()).optional()}).refine(t=>t.include||t.exclude,{message:"Rule must specify at least one of include or exclude"}),$C=Z.object({include:Z.array(Z.string()).optional(),exclude:Z.array(Z.string()).optional()}),jC=Z.object({sql:Z.string().optional(),changes:Z.string().optional()}),HC=Z.object({enabled:Z.boolean().default(!1),stages:Z.array(Z.string()).optional()}),qC=Z.object({enabled:Z.boolean().default(!0),level:FC.default("info"),file:Z.string().default(".noorm/noorm.log"),maxSize:LC.default("10mb"),maxFiles:Z.number().int().min(1).default(5)}),ky=Z.object({build:$C.optional(),paths:jC.optional(),rules:Z.array(MC).optional(),stages:Z.record(Z.string(),OC).optional(),strict:HC.optional(),logging:qC.optional(),secrets:Z.array(Ry).optional()}),za=class extends Error{constructor(r,n,o){super(r);this.field=n;this.issues=o;this.name="SettingsValidationError"}};function dl(t){let e=ky.safeParse(t);if(!e.success){let r=e.error.issues[0];throw new za(r?.message??"Settings validation failed",r?.path.join(".")||"unknown",e.error.issues)}return e.data}var pl={include:[],exclude:[]},Hs={sql:"./sql",changes:"./changes"},fl={enabled:!1,stages:[]},Km={enabled:!0,level:"info",file:".noorm/noorm.log",maxSize:"10mb",maxFiles:5},es={build:pl,paths:Hs,rules:[],stages:{},strict:fl,logging:Km};function Ja(){return{build:{include:[...pl.include??[]],exclude:[...pl.exclude??[]]},paths:{...Hs},rules:[],stages:{},strict:{...fl,stages:[...fl.stages??[]]},logging:{...Km}}}var qs=".noorm";function Vm(t,e){return!(t.name!==void 0&&e.name!==t.name||t.protected!==void 0&&e.protected!==t.protected||t.isTest!==void 0&&e.isTest!==t.isTest||t.type!==void 0&&e.type!==t.type)}function Um(t,e){return Vm(t.match,e)?{matched:!0,include:t.include??[],exclude:t.exclude??[]}:{matched:!1,include:[],exclude:[]}}function Qa(t,e){let r=[],n=new Set,o=new Set;for(let i of t){let s=Um(i,e);if(s.matched){r.push(i);for(let a of s.include)n.add(a),o.delete(a);for(let a of s.exclude)o.add(a),n.delete(a)}}return{matchedRules:r,include:Array.from(n),exclude:Array.from(o)}}function _y(t,e,r){let n=new Set(t),o=new Set(e);for(let i of r.include)n.add(i),o.delete(i);for(let i of r.exclude)o.add(i),n.delete(i);return{include:Array.from(n),exclude:Array.from(o)}}function yi(t,e,r,n){let o=Qa(r,n);return _y(t,e,o)}import{readFile as KC,writeFile as VC,mkdir as UC,access as YC}from"fs/promises";import{join as vy}from"path";import{parse as WC,stringify as GC}from"yaml";import{attempt as Za}from"@logosdx/utils";var ts=class{#t;#e;#o;#r=null;#i=!1;constructor(e,r={}){this.#t=e,this.#e=r.settingsDir??qs,this.#o=r.settingsFile??"settings.yml"}get settingsDirPath(){return vy(this.#t,this.#e)}get settingsFilePath(){return vy(this.settingsDirPath,this.#o)}async exists(){let[e,r]=await Za(()=>YC(this.settingsFilePath));return!r}async load(){if(!await this.exists())return this.#r=Ja(),this.#i=!0,k.emit("settings:loaded",{path:this.settingsFilePath,settings:this.#r,fromFile:!1}),this.#r;let[r,n]=await Za(()=>KC(this.settingsFilePath,"utf-8"));if(n)throw new Error(`Failed to read settings file: ${n.message}`);let[o,i]=await Za(()=>WC(r));if(i)throw new Error(`Invalid YAML in settings file: ${i.message}`);return o==null?(this.#r=Ja(),this.#i=!0,k.emit("settings:loaded",{path:this.settingsFilePath,settings:this.#r,fromFile:!0}),this.#r):(this.#r=dl(o),this.#i=!0,k.emit("settings:loaded",{path:this.settingsFilePath,settings:this.#r,fromFile:!0}),this.#r)}async save(){this.#n();let[e,r]=await Za(()=>UC(this.settingsDirPath,{recursive:!0}));if(r)throw new Error(`Failed to create settings directory: ${r.message}`);let n=GC(this.#r,{indent:4,lineWidth:120}),[o,i]=await Za(()=>VC(this.settingsFilePath,n,"utf-8"));if(i)throw new Error(`Failed to write settings file: ${i.message}`);k.emit("settings:saved",{path:this.settingsFilePath})}async init(e=!1){if(await this.exists()&&!e)throw new Error("Settings file already exists. Use force=true to overwrite.");this.#r=Ja(),this.#i=!0,await this.save(),k.emit("settings:initialized",{path:this.settingsFilePath,force:e})}get isLoaded(){return this.#i}get settings(){return this.#n(),this.#r}getBuild(){return this.#n(),this.#r.build??es.build}getPaths(){return this.#n(),this.#r.paths??es.paths}getRules(){return this.#n(),this.#r.rules??[]}getStages(){return this.#n(),this.#r.stages??{}}getStage(e){return this.getStages()[e]}hasStage(e){return e in this.getStages()}getStrict(){return this.#n(),this.#r.strict??es.strict}getLogging(){return this.#n(),this.#r.logging??es.logging}evaluateRules(e){this.#n();let r=this.getRules();return Qa(r,e)}getEffectiveBuildPaths(e){this.#n();let r=this.getBuild(),n=this.getRules();return yi(r.include??[],r.exclude??[],n,e)}isStageLockedByName(e){return this.getStage(e)?.locked===!0}getRequiredSecrets(e){this.#n();let r=this.#r.secrets??[],o=this.getStage(e)?.secrets??[],i=new Map;for(let s of r)s.required!==!1&&i.set(s.key,s);for(let s of o)s.required!==!1&&i.set(s.key,s);return Array.from(i.values()).map(s=>({key:s.key,type:s.type,description:s.description}))}getStageDefaults(e){return this.getStage(e)?.defaults??{}}stageEnforcesProtected(e){return this.getStageDefaults(e).protected===!0}stageEnforcesIsTest(e){return this.getStageDefaults(e).isTest===!0}isStrictModeEnabled(){return this.getStrict().enabled===!0}getRequiredStages(){let e=this.getStrict();return e.enabled?e.stages??[]:[]}async setStage(e,r){this.#n(),this.#r.stages||(this.#r.stages={}),this.#r.stages[e]=r,await this.save(),k.emit("settings:stage-set",{name:e,stage:r})}async removeStage(e){return this.#n(),!this.#r.stages||!(e in this.#r.stages)?!1:(delete this.#r.stages[e],await this.save(),k.emit("settings:stage-removed",{name:e}),!0)}async addRule(e){this.#n(),this.#r.rules||(this.#r.rules=[]),this.#r.rules.push(e),await this.save(),k.emit("settings:rule-added",{rule:e})}async removeRule(e){if(this.#n(),!this.#r.rules||e<0||e>=this.#r.rules.length)return!1;let[r]=this.#r.rules.splice(e,1);return await this.save(),k.emit("settings:rule-removed",{index:e,rule:r}),!0}async setBuild(e){this.#n(),this.#r.build=e,await this.save(),k.emit("settings:build-updated",{build:e})}async setPaths(e){this.#n(),this.#r.paths=e,await this.save(),k.emit("settings:paths-updated",{paths:e})}async setStrict(e){this.#n(),this.#r.strict=e,await this.save(),k.emit("settings:strict-updated",{strict:e})}async setLogging(e){this.#n(),this.#r.logging=e,await this.save(),k.emit("settings:logging-updated",{logging:e})}getUniversalSecrets(){return this.#n(),this.#r.secrets??[]}async addUniversalSecret(e){if(this.#n(),this.#r.secrets||(this.#r.secrets=[]),this.#r.secrets.find(n=>n.key===e.key))throw new Error(`Universal secret "${e.key}" already exists`);this.#r.secrets.push(e),await this.save(),k.emit("settings:secret-added",{secret:e,scope:"universal"})}async updateUniversalSecret(e,r){if(this.#n(),!this.#r.secrets)throw new Error(`Universal secret "${e}" not found`);let n=this.#r.secrets.findIndex(o=>o.key===e);if(n===-1)throw new Error(`Universal secret "${e}" not found`);this.#r.secrets[n]=r,await this.save(),k.emit("settings:secret-updated",{key:e,secret:r,scope:"universal"})}async removeUniversalSecret(e){if(this.#n(),!this.#r.secrets)return!1;let r=this.#r.secrets.findIndex(n=>n.key===e);return r===-1?!1:(this.#r.secrets.splice(r,1),await this.save(),k.emit("settings:secret-removed",{key:e,scope:"universal"}),!0)}async addStageSecret(e,r){this.#n();let n=this.getStage(e);if(!n)throw new Error(`Stage "${e}" not found`);if(n.secrets||(n.secrets=[]),n.secrets.find(i=>i.key===r.key))throw new Error(`Secret "${r.key}" already exists in stage "${e}"`);n.secrets.push(r),await this.setStage(e,n),k.emit("settings:secret-added",{secret:r,scope:"stage",stageName:e})}async updateStageSecret(e,r,n){this.#n();let o=this.getStage(e);if(!o)throw new Error(`Stage "${e}" not found`);if(!o.secrets)throw new Error(`Secret "${r}" not found in stage "${e}"`);let i=o.secrets.findIndex(s=>s.key===r);if(i===-1)throw new Error(`Secret "${r}" not found in stage "${e}"`);o.secrets[i]=n,await this.setStage(e,o),k.emit("settings:secret-updated",{key:r,secret:n,scope:"stage",stageName:e})}async removeStageSecret(e,r){this.#n();let n=this.getStage(e);if(!n||!n.secrets)return!1;let o=n.secrets.findIndex(i=>i.key===r);return o===-1?!1:(n.secrets.splice(o,1),await this.setStage(e,n),k.emit("settings:secret-removed",{key:r,scope:"stage",stageName:e}),!0)}#n(){if(!this.#i||!this.#r)throw new Error("SettingsManager not loaded. Call load() first.")}},Ym=null;function hi(t,e){return Ym||(Ym=new ts(t,e)),Ym}var Wm={operations:3e4,locks:5e3,connections:1e4,logger:1e4};function gl(t){return{projectRoot:t,mode:"tui",timeouts:{...Wm},registerSignalHandlers:!0}}var Fr={signals:new Map,exception:null,rejection:null};function yl(t){let e=["SIGINT","SIGTERM","SIGHUP"];for(let r of e){let n=Fr.signals.get(r);n&&process.removeListener(r,n);let o=()=>{k.emit("app:signal",{signal:r}),t(r)};process.on(r,o),Fr.signals.set(r,o)}return()=>{for(let r of e){let n=Fr.signals.get(r);n&&(process.removeListener(r,n),Fr.signals.delete(r))}}}function hl(t){Fr.exception&&process.removeListener("uncaughtException",Fr.exception),Fr.rejection&&process.removeListener("unhandledRejection",Fr.rejection);let e=n=>{k.emit("app:exception",{error:n,type:"exception"}),t(n,"exception")},r=(n,o)=>{let i=n instanceof Error?n:new Error(String(n));k.emit("app:exception",{error:i,type:"rejection"}),t(i,"rejection")};return process.on("uncaughtException",e),process.on("unhandledRejection",r),Fr.exception=e,Fr.rejection=r,()=>{Fr.exception&&(process.removeListener("uncaughtException",Fr.exception),Fr.exception=null),Fr.rejection&&(process.removeListener("unhandledRejection",Fr.rejection),Fr.rejection=null)}}import{attempt as Gm}from"@logosdx/utils";var QC=["stopping","completing","releasing","flushing","exiting"],ec=class{#t;#e="idle";#o=null;#r=null;#i=null;#n=0;#l=new Map;#s=null;#a=null;#c=null;constructor(e){let r=gl(e.projectRoot);this.#t={...r,...e,timeouts:{...r.timeouts,...e.timeouts}}}get state(){return this.#e}get mode(){return this.#t.mode}get startedAt(){return this.#o}get exitCode(){return this.#n}get isRunning(){return this.#e==="running"}get isShuttingDown(){return this.#e==="shutting_down"}getState(){return{state:this.#e,mode:this.#t.mode,startedAt:this.#o??void 0,shuttingDownAt:this.#r??void 0,shutdownReason:this.#i??void 0,exitCode:this.#n}}registerResource(e){this.#l.set(e.name,{...e,priority:e.priority??0})}unregisterResource(e){return this.#l.delete(e)}async start(){if(this.#e!=="idle")throw new Error(`Cannot start from state: ${this.#e}`);this.#e="starting",k.emit("app:starting",{mode:this.#t.mode}),this.#t.registerSignalHandlers&&(this.#s=yl(async e=>this.#y(e)),this.#a=hl(async(e,r)=>{await this.#m(e,r)})),this.#b(),this.#e="running",this.#o=new Date,k.emit("app:ready",{mode:this.#t.mode,startedAt:this.#o})}async shutdown(e="programmatic",r=0){if(this.#c)return this.#c;if(this.#e==="running")return k.emit("app:shutdown",{reason:e,exitCode:r}),this.#c=this.#u(e,r),this.#c}setExitCode(e){this.#n=e}async#u(e,r){this.#e="shutting_down",this.#r=new Date,this.#i=e,this.#n=r;for(let n of QC){if(n==="exiting")continue;let[,o]=await Gm(()=>this.#g(n));o&&k.emit("app:shutdown:phase",{phase:n,status:"timeout",error:o})}this.#h(),this.#e="stopped",k.emit("app:exit",{code:this.#n})}async#g(e){k.emit("app:shutdown:phase",{phase:e,status:"running"});let r=Date.now(),n=Array.from(this.#l.values()).filter(c=>c.phase===e).sort((c,l)=>(c.priority??0)-(l.priority??0)),o=this.#f(e),[,i]=await Gm(()=>this.#p(()=>this.#d(n),o)),s=Date.now()-r,a=i?"timeout":"completed";k.emit("app:shutdown:phase",{phase:e,status:a,durationMs:s,error:i??void 0})}async#d(e){for(let r of e){let[,n]=await Gm(()=>r.cleanup());n&&k.emit("error",{source:"lifecycle",error:n,context:{resource:r.name}})}}async#p(e,r){return new Promise((n,o)=>{let i=setTimeout(()=>{o(new Error(`Timeout after ${r}ms`))},r);e().then(s=>{clearTimeout(i),n(s)}).catch(s=>{clearTimeout(i),o(s)})})}#f(e){switch(e){case"stopping":return 1e3;case"completing":return this.#t.timeouts.operations;case"releasing":return Math.max(this.#t.timeouts.locks,this.#t.timeouts.connections);case"flushing":return this.#t.timeouts.logger;case"exiting":return 1e3;default:return 5e3}}async#y(e){this.#e==="shutting_down"&&(k.emit("app:fatal",{error:new Error(`Forced exit on second ${e}`)}),process.exit(128+this.#x(e))),await this.shutdown("signal",0)}async#m(e,r){k.emit("app:fatal",{error:e,type:r}),this.#h(),this.#e="failed",this.#n=1,k.emit("app:exit",{code:1})}#x(e){switch(e){case"SIGINT":return 2;case"SIGTERM":return 15;case"SIGHUP":return 1;default:return 0}}#b(){this.registerResource({name:"connections",phase:"releasing",priority:10,cleanup:async()=>{await js().closeAll()}})}#h(){this.#s&&(this.#s(),this.#s=null),this.#a&&(this.#a(),this.#a=null)}},Xm=null;function xl(t,e){if(!Xm){if(!t)throw new Error("projectRoot is required when creating LifecycleManager");Xm=new ec({projectRoot:t,...e})}return Xm}import{relative as rw,sep as zm}from"path";function bl(t,e,r,n){let o=a=>a.split(/[\\/]/).join(zm),i=r.map(o),s=n.map(o);return t.filter(a=>{let c=rw(e,a),l=i.length===0||i.some(d=>c===d||c.startsWith(d+zm)),m=s.some(d=>c===d||c.startsWith(d+zm));return l&&!m})}var G=Object.freeze({version:"__noorm_version__",change:"__noorm_change__",executions:"__noorm_executions__",lock:"__noorm_lock__",identities:"__noorm_identities__"});var Br=Object.freeze({schema:1,state:1,settings:1}),xi=class extends Error{constructor(r,n,o){super(`${r} version ${n} is newer than CLI supports (${o}). Please upgrade noorm.`);this.layer=r;this.current=n;this.expected=o;this.name="VersionMismatchError"}},jo=class extends Error{constructor(r,n,o){super(`${r} migration v${n} failed: ${o.message}`);this.layer=r;this.version=n;this.cause=o;this.name="MigrationError"}};import{sql as ow}from"kysely";import{attempt as rc}from"@logosdx/utils";import{sql as Ks}from"kysely";function tc(t,e){return e==="postgres"?t.addColumn("id","serial",r=>r.primaryKey()):t.addColumn("id","integer",r=>r.primaryKey().autoIncrement())}var Py={version:1,description:"Create initial tracking tables",async up(t,e){await tc(t.schema.createTable("__noorm_version__"),e).addColumn("cli_version","varchar(50)",r=>r.notNull()).addColumn("noorm_version","integer",r=>r.notNull()).addColumn("state_version","integer",r=>r.notNull()).addColumn("settings_version","integer",r=>r.notNull()).addColumn("installed_at","timestamp",r=>r.notNull().defaultTo(Ks`CURRENT_TIMESTAMP`)).addColumn("upgraded_at","timestamp",r=>r.notNull().defaultTo(Ks`CURRENT_TIMESTAMP`)).execute(),await tc(t.schema.createTable("__noorm_change__"),e).addColumn("name","varchar(255)",r=>r.notNull()).addColumn("change_type","varchar(50)",r=>r.notNull()).addColumn("direction","varchar(50)",r=>r.notNull()).addColumn("checksum","varchar(64)",r=>r.notNull().defaultTo("")).addColumn("executed_at","timestamp",r=>r.notNull().defaultTo(Ks`CURRENT_TIMESTAMP`)).addColumn("executed_by","varchar(255)",r=>r.notNull().defaultTo("")).addColumn("config_name","varchar(255)",r=>r.notNull().defaultTo("")).addColumn("cli_version","varchar(50)",r=>r.notNull().defaultTo("")).addColumn("status","varchar(50)",r=>r.notNull()).addColumn("error_message","text",r=>r.notNull().defaultTo("")).addColumn("duration_ms","integer",r=>r.notNull().defaultTo(0)).execute(),await tc(t.schema.createTable("__noorm_executions__"),e).addColumn("change_id","integer",r=>r.notNull().references("__noorm_change__.id").onDelete("cascade")).addColumn("filepath","varchar(500)",r=>r.notNull()).addColumn("file_type","varchar(10)",r=>r.notNull()).addColumn("checksum","varchar(64)",r=>r.notNull().defaultTo("")).addColumn("cli_version","varchar(50)",r=>r.notNull().defaultTo("")).addColumn("status","varchar(50)",r=>r.notNull()).addColumn("error_message","text",r=>r.notNull().defaultTo("")).addColumn("skip_reason","varchar(100)",r=>r.notNull().defaultTo("")).addColumn("duration_ms","integer",r=>r.notNull().defaultTo(0)).execute(),await tc(t.schema.createTable("__noorm_lock__"),e).addColumn("config_name","varchar(255)",r=>r.notNull().unique()).addColumn("locked_by","varchar(255)",r=>r.notNull()).addColumn("locked_at","timestamp",r=>r.notNull().defaultTo(Ks`CURRENT_TIMESTAMP`)).addColumn("expires_at","timestamp",r=>r.notNull()).addColumn("reason","varchar(255)",r=>r.notNull().defaultTo("")).execute(),await tc(t.schema.createTable("__noorm_identities__"),e).addColumn("identity_hash","varchar(64)",r=>r.notNull().unique()).addColumn("email","varchar(255)",r=>r.notNull()).addColumn("name","varchar(255)",r=>r.notNull()).addColumn("machine","varchar(255)",r=>r.notNull()).addColumn("os","varchar(255)",r=>r.notNull()).addColumn("public_key","text",r=>r.notNull()).addColumn("registered_at","timestamp",r=>r.notNull().defaultTo(Ks`CURRENT_TIMESTAMP`)).addColumn("last_seen_at","timestamp",r=>r.notNull().defaultTo(Ks`CURRENT_TIMESTAMP`)).execute(),await t.schema.createIndex("idx_executions_change_id").on("__noorm_executions__").column("change_id").execute(),await t.schema.createIndex("idx_change_name_config").on("__noorm_change__").columns(["name","config_name"]).execute()},async down(t,e){await t.schema.dropIndex("idx_change_name_config").execute(),await t.schema.dropIndex("idx_executions_change_id").execute(),await t.schema.dropTable("__noorm_identities__").execute(),await t.schema.dropTable("__noorm_lock__").execute(),await t.schema.dropTable("__noorm_executions__").execute(),await t.schema.dropTable("__noorm_change__").execute(),await t.schema.dropTable("__noorm_version__").execute()}};var Ny=[Py];async function mo(t){let[e,r]=await rc(async()=>(await ow`SELECT 1 FROM __noorm_version__ LIMIT 1`.execute(t),!0));return r?!1:e}async function Jm(t){if(!await mo(t))return 0;let[r,n]=await rc(async()=>t.selectFrom("__noorm_version__").select("noorm_version").orderBy("id","desc").limit(1).executeTakeFirst());return n?0:r?.noorm_version??0}async function Sl(t){let e=await Jm(t),r=Br.schema;return k.emit("version:schema:checking",{current:e}),{current:e,expected:r,needsMigration:e<r,isNewer:e>r}}async function nc(t,e,r,n){let o=performance.now();k.emit("version:schema:migrating",{from:0,to:Br.schema});for(let s of Ny){let[,a]=await rc(()=>s.up(t,e));if(a)throw new jo("schema",s.version,a)}await t.insertInto("__noorm_version__").values({cli_version:r,noorm_version:Br.schema,state_version:n?.stateVersion??Br.state,settings_version:n?.settingsVersion??Br.settings}).execute();let i=performance.now()-o;k.emit("version:schema:migrated",{from:0,to:Br.schema,durationMs:i})}async function Qm(t){if(!await mo(t))return null;let[r,n]=await rc(async()=>t.selectFrom("__noorm_version__").select(["state_version","settings_version"]).orderBy("id","desc").limit(1).executeTakeFirst());return n||!r?null:{stateVersion:r.state_version,settingsVersion:r.settings_version}}async function Cl(t,e,r,n){let o=await Sl(t);if(o.isNewer)throw k.emit("version:mismatch",{layer:"schema",current:o.current,expected:o.expected}),new xi("schema",o.current,o.expected);if(!o.needsMigration)return;if(o.current===0){await nc(t,e,r,n);return}let i=performance.now();k.emit("version:schema:migrating",{from:o.current,to:Br.schema});let s=await Qm(t),a=Ny.filter(l=>l.version>o.current);for(let l of a){let[,m]=await rc(()=>l.up(t,e));if(m)throw new jo("schema",l.version,m)}await t.insertInto("__noorm_version__").values({cli_version:r,noorm_version:Br.schema,state_version:n?.stateVersion??s?.stateVersion??Br.state,settings_version:n?.settingsVersion??s?.settingsVersion??Br.settings}).execute();let c=performance.now()-i;k.emit("version:schema:migrated",{from:o.current,to:Br.schema,durationMs:c})}async function wl(t,e,r,n){await Cl(t,e,r,n)}import{attemptSync as ZL}from"@logosdx/utils";import{attemptSync as aI}from"@logosdx/utils";var Vs={dialect:"postgres",timeout:3e5,wait:!1,waitTimeout:3e4,pollInterval:1e3};var Do=class extends Error{constructor(r,n,o,i,s){let a=o.toISOString(),c=i.toISOString(),l=s?` (${s})`:"";super(`Lock for '${r}' held by ${n} since ${a}, expires ${c}${l}`);this.configName=r;this.holder=n;this.heldSince=o;this.expiresAt=i;this.reason=s}name="LockAcquireError"},rs=class extends Error{constructor(r,n,o){super(`Lock for '${r}' expired at ${o.toISOString()}`);this.configName=r;this.identity=n;this.expiredAt=o}name="LockExpiredError"},Ho=class extends Error{constructor(r,n){super(`No lock found for '${r}' held by ${n}`);this.configName=r;this.identity=n}name="LockNotFoundError"},qo=class extends Error{constructor(r,n,o){super(`Cannot release lock for '${r}': held by ${o}, not ${n}`);this.configName=r;this.requestedBy=n;this.actualHolder=o}name="LockOwnershipError"};import{attempt as dw}from"@logosdx/utils";function Tl(t,e){return e==="sqlite"?t.toISOString():t}var oc=class{async acquire(e,r,n,o={}){let i={...Vs,...o},s=Date.now();for(k.emit("lock:acquiring",{configName:r,identity:n});;){await this.cleanupExpired(e,r,i.dialect);let a=await this.getLock(e,r);if(!a){let l=await this.createLock(e,r,n,i);return k.emit("lock:acquired",{configName:r,identity:n,expiresAt:l.expiresAt}),l}if(a.lockedBy===n){let l=await this.extendLock(e,r,n,i);return k.emit("lock:acquired",{configName:r,identity:n,expiresAt:l.expiresAt}),l}if(k.emit("lock:blocked",{configName:r,holder:a.lockedBy,heldSince:a.lockedAt}),!i.wait)throw new Do(r,a.lockedBy,a.lockedAt,a.expiresAt,a.reason);if(Date.now()-s>=i.waitTimeout)throw new Do(r,a.lockedBy,a.lockedAt,a.expiresAt,a.reason);await pw(i.pollInterval)}}async release(e,r,n){let o=await this.getLock(e,r);if(!o)throw new Ho(r,n);if(o.lockedBy!==n)throw new qo(r,n,o.lockedBy);await e.deleteFrom(G.lock).where("config_name","=",r).where("locked_by","=",n).execute(),k.emit("lock:released",{configName:r,identity:n})}async forceRelease(e,r){let n=await this.getLock(e,r);return n?(await e.deleteFrom(G.lock).where("config_name","=",r).execute(),k.emit("lock:released",{configName:r,identity:n.lockedBy}),!0):!1}async withLock(e,r,n,o,i={}){await this.acquire(e,r,n,i);try{return await o()}finally{let[,s]=await dw(()=>this.release(e,r,n));s&&k.emit("error",{source:"lock",error:s,context:{configName:r,identity:n}})}}async validate(e,r,n,o="postgres"){let i=await this.getLock(e,r);if(!i)throw new Ho(r,n);if(i.lockedBy!==n)throw new qo(r,n,i.lockedBy);if(i.expiresAt<new Date)throw await this.cleanupExpired(e,r,o),new rs(r,n,i.expiresAt)}async extend(e,r,n,o={}){return await this.validate(e,r,n),this.extendLock(e,r,n,o)}async status(e,r,n="postgres"){await this.cleanupExpired(e,r,n);let o=await this.getLock(e,r);return{isLocked:o!==null,lock:o}}async getLock(e,r){let n=await e.selectFrom(G.lock).selectAll().where("config_name","=",r).executeTakeFirst();return n?{lockedBy:n.locked_by,lockedAt:new Date(n.locked_at),expiresAt:new Date(n.expires_at),reason:n.reason||void 0}:null}async createLock(e,r,n,o){let i=new Date,s=new Date(i.getTime()+o.timeout);return await e.insertInto(G.lock).values({config_name:r,locked_by:n,locked_at:Tl(i,o.dialect),expires_at:Tl(s,o.dialect),reason:o.reason??""}).execute(),{lockedBy:n,lockedAt:i,expiresAt:s,reason:o.reason}}async extendLock(e,r,n,o){let i=o.dialect??Vs.dialect,s=o.timeout??Vs.timeout,a=new Date,c=new Date(a.getTime()+s),l={expires_at:Tl(c,i)};return o.reason!==void 0&&(l.reason=o.reason),await e.updateTable(G.lock).set(l).where("config_name","=",r).where("locked_by","=",n).execute(),await this.getLock(e,r)}async cleanupExpired(e,r,n="postgres"){let i=Tl(new Date,n),s=await e.selectFrom(G.lock).select(["locked_by"]).where("config_name","=",r).where("expires_at","<",i).executeTakeFirst();s&&(await e.deleteFrom(G.lock).where("config_name","=",r).where("expires_at","<",i).execute(),k.emit("lock:expired",{configName:r,previousHolder:s.locked_by}))}},Zm=null;function mt(){return Zm||(Zm=new oc),Zm}function pw(t){return new Promise(e=>setTimeout(e,t))}import El from"path";import{readFile as Uw,readdir as Yw,writeFile as Ky,mkdir as Ww}from"fs/promises";import{sql as Vy}from"kysely";import{attempt as Lr,attemptSync as Uy}from"@logosdx/utils";import{execSync as My}from"child_process";import{userInfo as $w}from"os";import{attemptSync as $y}from"@logosdx/utils";function kn(t={}){let e;return t.configIdentity?e=jy(t.configIdentity,"config"):t.cryptoIdentity?e=jw(t.cryptoIdentity):process.env.NOORM_IDENTITY?e=jy(process.env.NOORM_IDENTITY,"env"):t.skipGit?e=Hy():e=Hw()??Hy(),k.emit("identity:resolved",{name:e.name,email:e.email,source:e.source}),e}function jw(t){return{name:t.name,email:t.email,source:"state"}}function jy(t,e){let r=t.trim(),n=r.match(/^(.+?)\s*<([^>]+)>$/);return n?{name:n[1].trim(),email:n[2].trim(),source:e}:{name:r,source:e}}function Hw(){let[t,e]=$y(()=>My("git config user.name",{encoding:"utf8",timeout:5e3,stdio:["pipe","pipe","pipe"]}).trim());if(e||!t)return null;let[r]=$y(()=>My("git config user.email",{encoding:"utf8",timeout:5e3,stdio:["pipe","pipe","pipe"]}).trim());return{name:t,email:r||void 0,source:"git"}}function Hy(){return{name:$w().username,source:"system"}}function Ft(t){return t.email?`${t.name} <${t.email}>`:t.name}import{createHash as qy}from"crypto";import{readFile as qw}from"fs/promises";import{attempt as Kw}from"@logosdx/utils";async function cn(t){let[e,r]=await Kw(()=>qw(t,"utf-8"));if(r)throw new Error(`Failed to read file for checksum: ${t}`,{cause:r});return Us(e)}function Us(t){return qy("sha256").update(t,"utf-8").digest("hex")}function ns(t){let r=[...t].sort().join("");return qy("sha256").update(r,"utf-8").digest("hex")}import{sql as Vw}from"kysely";import{attempt as Ko}from"@logosdx/utils";var Vo=class{#t;#e;constructor(e,r){this.#t=e,this.#e=r}async needsRun(e,r,n){if(n)return{needsRun:!0,reason:"force"};let[o,i]=await Ko(()=>this.#t.selectFrom(G.executions).innerJoin(G.change,`${G.change}.id`,`${G.executions}.change_id`).select(s=>[s.ref(`${G.executions}.checksum`).as("checksum"),s.ref(`${G.executions}.status`).as("exec_status"),s.ref(`${G.change}.status`).as("change_status")]).where(`${G.executions}.filepath`,"=",e).where(`${G.change}.config_name`,"=",this.#e).orderBy(`${G.executions}.id`,"desc").limit(1).executeTakeFirst());return i?(k.emit("error",{source:"runner",error:i,context:{filepath:e,operation:"needs-run-check"}}),{needsRun:!0,reason:"new"}):o?o.exec_status==="failed"?{needsRun:!0,reason:"failed",previousChecksum:o.checksum}:o.exec_status==="pending"||o.exec_status==="skipped"?{needsRun:!0,reason:"new"}:o.change_status==="stale"?{needsRun:!0,reason:"stale",previousChecksum:o.checksum}:o.checksum!==r?{needsRun:!0,reason:"changed",previousChecksum:o.checksum}:{needsRun:!1,skipReason:"unchanged",previousChecksum:o.checksum}:{needsRun:!0,reason:"new"}}async createOperation(e){let n=(e.direction??"commit")==="commit"?"change":"revert",[o,i]=await Ko(()=>this.#t.insertInto(G.change).values({name:e.name,change_type:e.changeType,direction:n,status:"pending",config_name:e.configName,executed_by:e.executedBy}).returning("id").executeTakeFirstOrThrow());if(i)throw new Error("Failed to create operation record",{cause:i});let s=o?.id;if(s==null){let[a,c]=await Ko(()=>Vw`SELECT last_insert_rowid() as id`.execute(this.#t));if(c||!a?.rows?.[0]?.id)throw new Error("Failed to retrieve last insert row id");s=a.rows[0].id}if(typeof s!="number"||!Number.isFinite(s)||s<=0)throw new Error(`Invalid operation ID returned: ${s}`);return s}async recordExecution(e){let[,r]=await Ko(()=>this.#t.insertInto(G.executions).values({change_id:e.changeId,filepath:e.filepath,file_type:"sql",checksum:e.checksum,status:e.status,skip_reason:e.skipReason??"",error_message:e.errorMessage??"",duration_ms:Math.round(e.durationMs??0)}).execute());r&&k.emit("error",{source:"runner",error:r,context:{filepath:e.filepath,operation:"record-execution"}})}async finalizeOperation(e,r,n,o,i){let s=i?i.slice(0,2e3):"",[a,c]=await Ko(()=>this.#t.updateTable(G.change).set({status:r,duration_ms:Math.round(n),checksum:o??"",error_message:s}).where("id","=",e).executeTakeFirst());if(c){let m=c instanceof Error?c.message:String(c);return k.emit("error",{source:"runner",error:c,context:{operationId:e,operation:"finalize-operation"}}),`Failed to finalize operation ${e}: ${m}`}if(Number(a?.numUpdatedRows??0)===0){let m=`No operation record found with id ${e}`;return k.emit("error",{source:"runner",error:new Error(m),context:{operationId:e,operation:"finalize-operation"}}),m}return null}async createFileRecords(e,r){if(r.length===0)return null;let n=r.map(i=>({change_id:e,filepath:i.filepath,file_type:i.fileType,checksum:i.checksum,status:"pending"})),[,o]=await Ko(()=>this.#t.insertInto(G.executions).values(n).execute());if(o){let i=o instanceof Error?o.message:String(o);return k.emit("error",{source:"runner",error:o,context:{operationId:e,operation:"create-file-records"}}),`Failed to create file records: ${i}`}return null}async updateFileExecution(e,r,n,o,i,s){let[a,c]=await Ko(()=>this.#t.updateTable(G.executions).set({status:n,duration_ms:Math.round(o),error_message:i??"",skip_reason:s??""}).where("change_id","=",e).where("filepath","=",r).executeTakeFirst());if(c){let m=c instanceof Error?c.message:String(c);return k.emit("error",{source:"runner",error:c,context:{filepath:r,operation:"update-file-execution"}}),`Failed to update file execution ${r}: ${m}`}if(Number(a?.numUpdatedRows??0)===0){let m=`No execution record found for ${r} (operationId: ${e})`;return k.emit("error",{source:"runner",error:new Error(m),context:{operationId:e,filepath:r,operation:"update-file-execution"}}),m}return null}async skipRemainingFiles(e,r){let[,n]=await Ko(()=>this.#t.updateTable(G.executions).set({status:"skipped",skip_reason:r}).where("change_id","=",e).where("status","=","pending").execute());return n?(k.emit("error",{source:"runner",error:n,context:{operationId:e,operation:"skip-remaining-files"}}),`Failed to skip remaining files: ${n instanceof Error?n.message:String(n)}`):null}async needsRunByName(e,r,n){if(n)return{needsRun:!0,reason:"force"};let[o,i]=await Ko(()=>this.#t.selectFrom(G.change).select(["status","checksum"]).where("name","=",e).where("direction","=","change").where("config_name","=",this.#e).orderBy("id","desc").limit(1).executeTakeFirst());return i?(k.emit("error",{source:"runner",error:i,context:{name:e,operation:"needs-run-by-name"}}),{needsRun:!0,reason:"new"}):o?o.status==="failed"?{needsRun:!0,reason:"failed",previousChecksum:o.checksum}:o.status==="reverted"?{needsRun:!0,reason:"stale",previousChecksum:o.checksum}:o.status==="stale"?{needsRun:!0,reason:"stale",previousChecksum:o.checksum}:o.checksum!==r?{needsRun:!0,reason:"changed",previousChecksum:o.checksum}:{needsRun:!1,skipReason:"already-run",previousChecksum:o.checksum}:{needsRun:!0,reason:"new"}}};var Gw=[".sql",".sql.tmpl"],Xw=`-- ============================================================
|
|
4
|
+
-- File: %FILE%
|
|
5
|
+
-- ============================================================
|
|
6
|
+
|
|
7
|
+
`;async function Ys(t,e,r={}){let n=performance.now(),o={...ic,...r},[i,s]=await Lr(()=>Yn(e));if(s)return k.emit("error",{source:"runner",error:s,context:{sqlPath:e,operation:"discover-files"}}),Rl(s.message,performance.now()-n);k.emit("build:start",{sqlPath:e,fileCount:i.length});let a=await td(t,i,o,"build");return k.emit("build:complete",{status:a.status,filesRun:a.filesRun,filesSkipped:a.filesSkipped,filesFailed:a.filesFailed,durationMs:a.durationMs}),a}async function Ws(t,e,r={}){let n={...ic,...r};k.emit("run:file",{filepath:e,configName:t.configName});let o=new Vo(t.db,t.configName),i=`run:${new Date().toISOString()}`,[s,a]=await Lr(()=>o.createOperation({name:i,changeType:"run",configName:t.configName,executedBy:Ft(t.identity)}));if(a)return k.emit("error",{source:"runner",error:a,context:{filepath:e,operation:"create-operation"}}),{filepath:e,checksum:"",status:"failed",error:a.message};let c=await Jw(t,e,n,o,s);return await o.finalizeOperation(s,c.status==="failed"?"failed":"success",Math.round(c.durationMs??0),c.checksum,c.error),c}async function kl(t,e,r={}){let n=performance.now(),o={...ic,...r},[i,s]=await Lr(()=>Yn(e));return s?(k.emit("error",{source:"runner",error:s,context:{dirpath:e,operation:"discover-files"}}),Rl(s.message,performance.now()-n)):(k.emit("run:dir",{dirpath:e,fileCount:i.length,configName:t.configName}),td(t,i,o,"run"))}async function os(t,e,r={}){let n={...ic,...r};return k.emit("run:files",{fileCount:e.length,configName:t.configName}),td(t,e,n,"run")}async function ed(t,e,r){let n=[],o=[];for(let s of e){let[a,c]=await Lr(()=>_l(t,s));if(c){n.push({filepath:s,checksum:"",status:"failed",error:c.message});continue}let l=await cn(s);n.push({filepath:s,checksum:l,status:"success",renderedSql:a}),o.push(Xw.replace("%FILE%",s)+a)}let i=o.join(`
|
|
8
|
+
|
|
9
|
+
`);if(r){let[,s]=await Lr(()=>Ky(r,i,"utf-8"));s&&k.emit("error",{source:"runner",error:s,context:{output:r,operation:"write-preview"}})}return n}var ic={force:!1,concurrency:1,abortOnError:!0,dryRun:!1,preview:!1,output:null};async function Yy(t,e,r,n){let o=performance.now(),i={...ic,...r},s=e.map(x=>x.path);if(i.preview){let x=await ed(t,s,i.output),C=performance.now()-o;return{status:x.every(b=>b.status!=="failed")?"success":"failed",files:x,filesRun:0,filesSkipped:0,filesFailed:x.filter(b=>b.status==="failed").length,durationMs:C}}if(i.dryRun){let x=await Qw(t,s),C=performance.now()-o;return{status:x.every(b=>b.status!=="failed")?"success":"failed",files:x,filesRun:x.filter(b=>b.status==="success").length,filesSkipped:0,filesFailed:x.filter(b=>b.status==="failed").length,durationMs:C}}let a=n.tracker??new Vo(t.db,t.configName),[c,l]=await Lr(()=>a.createOperation({name:n.operationName,changeType:n.changeType,direction:n.direction,configName:t.configName,executedBy:Ft(t.identity)}));if(l)return k.emit("error",{source:"runner:create-operation",error:l,context:{operationName:n.operationName}}),Rl(l.message,performance.now()-o);let m=[];for(let x of e){let C=x.checksum;if(!C){let[b,v]=await Lr(()=>cn(x.path));C=v?"":b}m.push({filepath:x.path,fileType:x.type,checksum:C})}let d=await a.createFileRecords(c,m);if(d)return k.emit("error",{source:"runner:create-file-records",error:new Error(d),context:{operationId:c}}),await a.finalizeOperation(c,"failed",0,"",d),Rl(d,performance.now()-o);let u=[],p=!1;for(let x=0;x<e.length;x++){let C=e[x],b=m[x],v=await zw(t,C.path,b.checksum,i,a,c,n.changeType);if(u.push(v),v.status==="failed"&&i.abortOnError){p=!0;let P=await a.skipRemainingFiles(c,`Skipped due to failure in ${C.path}`);P&&k.emit("error",{source:"runner:skip-remaining",error:new Error(P),context:{operationId:c}});break}}let g=u.filter(x=>x.status==="success").length,h=u.filter(x=>x.status==="skipped").length,f=u.filter(x=>x.status==="failed").length,w=performance.now()-o,S="success";(f>0||p)&&(S=g>0?"partial":"failed");let E=n.checksum??ns(m.map(x=>x.checksum)),T=S==="success"?"success":"failed",R=await a.finalizeOperation(c,T,Math.round(w),E,p?u.find(x=>x.status==="failed")?.error:void 0);return R&&k.emit("error",{source:"runner:finalize",error:new Error(R),context:{operationId:c}}),{status:S,files:u,filesRun:g,filesSkipped:h,filesFailed:f,durationMs:w,changeId:c}}async function td(t,e,r,n){let o=e.map(s=>({path:s,type:"sql"})),i={changeType:n,direction:"commit",operationName:`${n}:${new Date().toISOString()}`};return Yy(t,o,r,i)}async function zw(t,e,r,n,o,i,s){let a=performance.now(),[c,l]=await Lr(()=>_l(t,e));if(l){let f=performance.now()-a,w={filepath:e,checksum:r||"",status:"failed",error:l.message,durationMs:f};return await o.updateFileExecution(i,e,"failed",Math.round(f),l.message),k.emit("file:after",{filepath:e,status:"failed",durationMs:f,error:l.message}),w}let[m,d]=Uy(()=>Us(c)),u=d?r:m;if(k.emit("file:before",{filepath:e,checksum:u,configName:t.configName}),s!=="change"){let f=await o.needsRun(e,u,n.force);if(!f.needsRun){let w={filepath:e,checksum:u,status:"skipped",skipReason:f.skipReason};return await o.updateFileExecution(i,e,"skipped",0,void 0,f.skipReason),k.emit("file:skip",{filepath:e,reason:f.skipReason}),w}}let[,p]=await Lr(()=>Vy.raw(c).execute(t.db)),g=performance.now()-a;if(p){let f={filepath:e,checksum:u,status:"failed",error:p.message,durationMs:g};return await o.updateFileExecution(i,e,"failed",Math.round(g),p.message),k.emit("file:after",{filepath:e,status:"failed",durationMs:g,error:p.message}),f}let h={filepath:e,checksum:u,status:"success",durationMs:g};return await o.updateFileExecution(i,e,"success",Math.round(g)),k.emit("file:after",{filepath:e,status:"success",durationMs:g}),h}async function Jw(t,e,r,n,o){let i=performance.now(),[s,a]=await Lr(()=>_l(t,e));if(a){let g=performance.now()-i,h={filepath:e,checksum:"",status:"failed",error:a.message,durationMs:g};return await n.recordExecution({changeId:o,filepath:e,checksum:"",status:"failed",errorMessage:a.message,durationMs:Math.round(g)}),k.emit("file:after",{filepath:e,status:"failed",durationMs:g,error:a.message}),h}let[c,l]=Uy(()=>Us(s));if(l){let g={filepath:e,checksum:"",status:"failed",error:l.message,durationMs:performance.now()-i};return await n.recordExecution({changeId:o,filepath:e,checksum:"",status:"failed",errorMessage:l.message,durationMs:Math.round(g.durationMs??0)}),k.emit("file:after",{filepath:e,status:"failed",durationMs:g.durationMs??0,error:l.message}),g}k.emit("file:before",{filepath:e,checksum:c,configName:t.configName});let m=await n.needsRun(e,c,r.force);if(!m.needsRun){let g={filepath:e,checksum:c,status:"skipped",skipReason:m.skipReason};return await n.recordExecution({changeId:o,filepath:e,checksum:c,status:"skipped",skipReason:m.skipReason}),k.emit("file:skip",{filepath:e,reason:m.skipReason}),g}let[,d]=await Lr(()=>Vy.raw(s).execute(t.db)),u=performance.now()-i;if(d){let g={filepath:e,checksum:c,status:"failed",error:d.message,durationMs:u};return await n.recordExecution({changeId:o,filepath:e,checksum:c,status:"failed",errorMessage:d.message,durationMs:Math.round(u)}),k.emit("file:after",{filepath:e,status:"failed",durationMs:u,error:d.message}),g}let p={filepath:e,checksum:c,status:"success",durationMs:u};return await n.recordExecution({changeId:o,filepath:e,checksum:c,status:"success",durationMs:Math.round(u)}),k.emit("file:after",{filepath:e,status:"success",durationMs:u}),p}async function _l(t,e){if(Ms(e))return(await gi(e,{projectRoot:t.projectRoot,config:t.config,secrets:t.secrets,globalSecrets:t.globalSecrets})).sql;let[r,n]=await Lr(()=>Uw(e,"utf-8"));if(n)throw new Error(`Failed to read file: ${e}`,{cause:n});return r}async function Qw(t,e){let r=[];for(let n of e){let o=performance.now(),[i,s]=await Lr(()=>cn(n));if(s){r.push({filepath:n,checksum:"",status:"failed",error:s.message,durationMs:performance.now()-o});continue}let[a,c]=await Lr(()=>_l(t,n));if(c){r.push({filepath:n,checksum:i,status:"failed",error:c.message,durationMs:performance.now()-o});continue}let[,l]=await Lr(()=>Zw(t.projectRoot,n,a)),m=performance.now()-o;l&&k.emit("error",{source:"runner",error:l,context:{filepath:n,operation:"dry-run-write"}});let d=Wy(t.projectRoot,n);k.emit("file:dry-run",{filepath:n,outputPath:d}),r.push({filepath:n,checksum:i,status:"success",durationMs:m,renderedSql:a})}return r}function Wy(t,e){let r=El.relative(t,e),n=r.endsWith(".tmpl")?r.slice(0,-5):r;return El.join(t,"tmp",n)}async function Zw(t,e,r){let n=Wy(t,e),o=El.dirname(n);await Ww(o,{recursive:!0}),await Ky(n,r,"utf-8")}async function Yn(t){let e=[];async function r(n){let[o,i]=await Lr(()=>Yw(n,{withFileTypes:!0}));if(i)throw new Error(`Failed to read directory: ${n}`,{cause:i});for(let s of o){let a=El.join(n,s.name);s.isDirectory()?await r(a):s.isFile()&&eT(s.name)&&e.push(a)}}return await r(t),e.sort()}function eT(t){return Gw.some(e=>t.endsWith(e))}function Rl(t,e){return{status:"failed",files:[],filesRun:0,filesSkipped:0,filesFailed:0,durationMs:e}}import{sql as vl}from"kysely";import{attempt as rT}from"@logosdx/utils";async function rd(t,e){let r={...t,database:"postgres"},n=await K(r,"__system__"),[o,i]=await rT(()=>e(n));if(await n.destroy(),i)throw i;return o}var Dl={getSystemDatabase(){return"postgres"},async databaseExists(t,e){return rd(t,async r=>(await vl`
|
|
10
|
+
SELECT EXISTS(
|
|
11
|
+
SELECT 1 FROM pg_database WHERE datname = ${e}
|
|
12
|
+
) as exists
|
|
13
|
+
`.execute(r.db)).rows[0]?.exists??!1)},async createDatabase(t,e){await this.databaseExists(t,e)||await rd(t,async n=>{await vl.raw(`CREATE DATABASE "${e}"`).execute(n.db)})},async dropDatabase(t,e){await rd(t,async r=>{await vl`
|
|
14
|
+
SELECT pg_terminate_backend(pg_stat_activity.pid)
|
|
15
|
+
FROM pg_stat_activity
|
|
16
|
+
WHERE pg_stat_activity.datname = ${e}
|
|
17
|
+
AND pid <> pg_backend_pid()
|
|
18
|
+
`.execute(r.db),await vl.raw(`DROP DATABASE IF EXISTS "${e}"`).execute(r.db)})}};import{sql as nd}from"kysely";import{attempt as nT}from"@logosdx/utils";async function od(t,e){let r={...t,database:""},n=await K(r,"__system__"),[o,i]=await nT(()=>e(n));if(await n.destroy(),i)throw i;return o}var Pl={getSystemDatabase(){},async databaseExists(t,e){return od(t,async r=>((await nd`
|
|
19
|
+
SELECT COUNT(*) as count
|
|
20
|
+
FROM information_schema.schemata
|
|
21
|
+
WHERE schema_name = ${e}
|
|
22
|
+
`.execute(r.db)).rows[0]?.count??0)>0)},async createDatabase(t,e){await od(t,async r=>{await nd.raw(`CREATE DATABASE IF NOT EXISTS \`${e}\``).execute(r.db)})},async dropDatabase(t,e){await od(t,async r=>{await nd.raw(`DROP DATABASE IF EXISTS \`${e}\``).execute(r.db)})}};import{sql as id}from"kysely";import{attempt as oT}from"@logosdx/utils";async function sd(t,e){let r={...t,database:"master"},n=await K(r,"__system__"),[o,i]=await oT(()=>e(n));if(await n.destroy(),i)throw i;return o}var Nl={getSystemDatabase(){return"master"},async databaseExists(t,e){return sd(t,async r=>((await id`
|
|
23
|
+
SELECT COUNT(*) as count
|
|
24
|
+
FROM sys.databases
|
|
25
|
+
WHERE name = ${e}
|
|
26
|
+
`.execute(r.db)).rows[0]?.count??0)>0)},async createDatabase(t,e){await this.databaseExists(t,e)||await sd(t,async n=>{await id.raw(`CREATE DATABASE [${e}]`).execute(n.db)})},async dropDatabase(t,e){await sd(t,async r=>{await id.raw(`
|
|
27
|
+
IF EXISTS(SELECT 1 FROM sys.databases WHERE name = '${e}')
|
|
28
|
+
BEGIN
|
|
29
|
+
ALTER DATABASE [${e}] SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
|
|
30
|
+
DROP DATABASE [${e}];
|
|
31
|
+
END
|
|
32
|
+
`).execute(r.db)})}};import{existsSync as Gy,unlinkSync as iT}from"fs";import{attemptSync as sT}from"@logosdx/utils";var Fl={getSystemDatabase(){},async databaseExists(t,e){let r=t.filename??e;return r===":memory:"?!0:Gy(r)},async createDatabase(t,e){},async dropDatabase(t,e){let r=t.filename??e;if(r===":memory:"||!Gy(r))return;let[,n]=sT(()=>iT(r));if(n)throw n}};var Xy={postgres:Dl,mysql:Pl,mssql:Nl,sqlite:Fl};function Gs(t){return Xy[t]}import{attempt as Xs}from"@logosdx/utils";async function is(t){let e=await de(t,{testServerOnly:!0});if(!e.ok)return{serverOk:!1,exists:!1,trackingInitialized:!1,error:e.error};let r=Gs(t.dialect),[n,o]=await Xs(()=>r.databaseExists(t,t.database));if(o)return{serverOk:!0,exists:!1,trackingInitialized:!1,error:o.message};if(!n)return{serverOk:!0,exists:!1,trackingInitialized:!1};let[i,s]=await Xs(async()=>{let a=await K(t,"__check__"),c=a.db,l=await mo(c);return await a.destroy(),l});return s?{serverOk:!0,exists:!0,trackingInitialized:!1,error:s.message}:{serverOk:!0,exists:!0,trackingInitialized:i??!1}}async function Bl(t,e,r={}){let{ifNotExists:n=!0,initializeTracking:o=!0}=r,i=t.database,s=Gs(t.dialect),a=await is(t);if(!a.serverOk)return{ok:!1,error:a.error};k.emit("db:creating",{configName:e,database:i});let c=Date.now(),l=!1,m=!1;if(a.exists){if(!n)return{ok:!1,error:`Database "${i}" already exists`}}else{let[,u]=await Xs(()=>s.createDatabase(t,i));if(u)return{ok:!1,error:u.message};l=!0}if(o&&!a.trackingInitialized){let[,u]=await Xs(async()=>{let p=await K(t,e),g=p.db;k.emit("db:bootstrap",{configName:e,tables:["__noorm_version__","__noorm_executions__","__noorm_lock__"]}),await nc(g,t.dialect,"1.0.0"),await p.destroy()});if(u)return{ok:!1,error:u.message};m=!0}let d=Date.now()-c;return k.emit("db:created",{configName:e,database:i,durationMs:d}),{ok:!0,created:l,trackingInitialized:m}}async function Ll(t,e,r={}){let{trackingOnly:n=!1}=r,o=t.database;if(k.emit("db:destroying",{configName:e,database:o}),n){let[,i]=await Xs(async()=>{let s=await K(t,e),a=s.db;if(await mo(a)){await a.deleteFrom("__noorm_executions__").execute();try{await a.deleteFrom("__noorm_change__").execute()}catch{}}await s.destroy()});if(i)return{ok:!1,error:i.message}}else{let i=Gs(t.dialect),[,s]=await Xs(()=>i.dropDatabase(t,o));if(s)return{ok:!1,error:s.message}}return k.emit("db:destroyed",{configName:e,database:o}),{ok:!0}}import{attempt as fo}from"@logosdx/utils";import{sql as xd}from"kysely";import{readFile as $T}from"fs/promises";import{join as jT}from"path";import{attempt as ad}from"@logosdx/utils";import{sql as se}from"kysely";var Yr=["pg_catalog","information_schema","pg_toast"],zy={async getOverview(t){let[e,r,n,o,i,s,a]=await Promise.all([se`
|
|
33
|
+
SELECT COUNT(*)::text as count
|
|
34
|
+
FROM information_schema.tables
|
|
35
|
+
WHERE table_schema NOT IN (${se.join(Yr)})
|
|
36
|
+
AND table_type = 'BASE TABLE'
|
|
37
|
+
`.execute(t),se`
|
|
38
|
+
SELECT COUNT(*)::text as count
|
|
39
|
+
FROM information_schema.views
|
|
40
|
+
WHERE table_schema NOT IN (${se.join(Yr)})
|
|
41
|
+
`.execute(t),se`
|
|
42
|
+
SELECT COUNT(*)::text as count
|
|
43
|
+
FROM pg_proc p
|
|
44
|
+
JOIN pg_namespace n ON p.pronamespace = n.oid
|
|
45
|
+
WHERE n.nspname NOT IN (${se.join(Yr)})
|
|
46
|
+
AND p.prokind = 'p'
|
|
47
|
+
AND NOT EXISTS (
|
|
48
|
+
SELECT 1 FROM pg_depend d
|
|
49
|
+
WHERE d.objid = p.oid
|
|
50
|
+
AND d.deptype = 'e'
|
|
51
|
+
)
|
|
52
|
+
`.execute(t),se`
|
|
53
|
+
SELECT COUNT(*)::text as count
|
|
54
|
+
FROM pg_proc p
|
|
55
|
+
JOIN pg_namespace n ON p.pronamespace = n.oid
|
|
56
|
+
WHERE n.nspname NOT IN (${se.join(Yr)})
|
|
57
|
+
AND p.prokind = 'f'
|
|
58
|
+
AND NOT EXISTS (
|
|
59
|
+
SELECT 1 FROM pg_depend d
|
|
60
|
+
WHERE d.objid = p.oid
|
|
61
|
+
AND d.deptype = 'e'
|
|
62
|
+
)
|
|
63
|
+
`.execute(t),se`
|
|
64
|
+
SELECT COUNT(*)::text as count
|
|
65
|
+
FROM pg_type t
|
|
66
|
+
JOIN pg_namespace n ON t.typnamespace = n.oid
|
|
67
|
+
WHERE n.nspname NOT IN (${se.join(Yr)})
|
|
68
|
+
AND t.typtype IN ('e', 'c', 'd')
|
|
69
|
+
AND NOT EXISTS (
|
|
70
|
+
SELECT 1 FROM pg_depend d
|
|
71
|
+
WHERE d.objid = t.oid
|
|
72
|
+
AND d.deptype = 'e'
|
|
73
|
+
)
|
|
74
|
+
AND NOT EXISTS (
|
|
75
|
+
SELECT 1 FROM pg_class c
|
|
76
|
+
WHERE c.reltype = t.oid
|
|
77
|
+
AND c.relkind IN ('r', 'v', 'm', 'p')
|
|
78
|
+
)
|
|
79
|
+
`.execute(t),se`
|
|
80
|
+
SELECT COUNT(*)::text as count
|
|
81
|
+
FROM pg_indexes
|
|
82
|
+
WHERE schemaname NOT IN (${se.join(Yr)})
|
|
83
|
+
`.execute(t),se`
|
|
84
|
+
SELECT COUNT(*)::text as count
|
|
85
|
+
FROM information_schema.table_constraints
|
|
86
|
+
WHERE constraint_type = 'FOREIGN KEY'
|
|
87
|
+
AND table_schema NOT IN (${se.join(Yr)})
|
|
88
|
+
`.execute(t)]);return{tables:parseInt(e.rows[0]?.count??"0",10),views:parseInt(r.rows[0]?.count??"0",10),procedures:parseInt(n.rows[0]?.count??"0",10),functions:parseInt(o.rows[0]?.count??"0",10),types:parseInt(i.rows[0]?.count??"0",10),indexes:parseInt(s.rows[0]?.count??"0",10),foreignKeys:parseInt(a.rows[0]?.count??"0",10),triggers:0,locks:0,connections:0}},async listTables(t){return(await se`
|
|
89
|
+
SELECT
|
|
90
|
+
t.table_name,
|
|
91
|
+
t.table_schema,
|
|
92
|
+
(
|
|
93
|
+
SELECT COUNT(*)::text
|
|
94
|
+
FROM information_schema.columns c
|
|
95
|
+
WHERE c.table_schema = t.table_schema
|
|
96
|
+
AND c.table_name = t.table_name
|
|
97
|
+
) as column_count,
|
|
98
|
+
COALESCE(
|
|
99
|
+
(
|
|
100
|
+
SELECT reltuples::bigint::text
|
|
101
|
+
FROM pg_class pc
|
|
102
|
+
JOIN pg_namespace pn ON pc.relnamespace = pn.oid
|
|
103
|
+
WHERE pc.relname = t.table_name
|
|
104
|
+
AND pn.nspname = t.table_schema
|
|
105
|
+
),
|
|
106
|
+
'0'
|
|
107
|
+
) as row_estimate
|
|
108
|
+
FROM information_schema.tables t
|
|
109
|
+
WHERE t.table_schema NOT IN (${se.join(Yr)})
|
|
110
|
+
AND t.table_type = 'BASE TABLE'
|
|
111
|
+
ORDER BY t.table_schema, t.table_name
|
|
112
|
+
`.execute(t)).rows.map(r=>({name:r.table_name,schema:r.table_schema,columnCount:parseInt(r.column_count,10),rowCountEstimate:parseInt(r.row_estimate,10)>0?parseInt(r.row_estimate,10):void 0}))},async listViews(t){return(await se`
|
|
113
|
+
SELECT
|
|
114
|
+
v.table_name,
|
|
115
|
+
v.table_schema,
|
|
116
|
+
(
|
|
117
|
+
SELECT COUNT(*)::text
|
|
118
|
+
FROM information_schema.columns c
|
|
119
|
+
WHERE c.table_schema = v.table_schema
|
|
120
|
+
AND c.table_name = v.table_name
|
|
121
|
+
) as column_count,
|
|
122
|
+
v.is_updatable
|
|
123
|
+
FROM information_schema.views v
|
|
124
|
+
WHERE v.table_schema NOT IN (${se.join(Yr)})
|
|
125
|
+
ORDER BY v.table_schema, v.table_name
|
|
126
|
+
`.execute(t)).rows.map(r=>({name:r.table_name,schema:r.table_schema,columnCount:parseInt(r.column_count,10),isUpdatable:r.is_updatable==="YES"}))},async listProcedures(t){return(await se`
|
|
127
|
+
SELECT
|
|
128
|
+
p.proname,
|
|
129
|
+
n.nspname,
|
|
130
|
+
p.pronargs::text as param_count
|
|
131
|
+
FROM pg_proc p
|
|
132
|
+
JOIN pg_namespace n ON p.pronamespace = n.oid
|
|
133
|
+
WHERE n.nspname NOT IN (${se.join(Yr)})
|
|
134
|
+
AND p.prokind = 'p'
|
|
135
|
+
AND NOT EXISTS (
|
|
136
|
+
SELECT 1 FROM pg_depend d
|
|
137
|
+
WHERE d.objid = p.oid
|
|
138
|
+
AND d.deptype = 'e'
|
|
139
|
+
)
|
|
140
|
+
ORDER BY n.nspname, p.proname
|
|
141
|
+
`.execute(t)).rows.map(r=>({name:r.proname,schema:r.nspname,parameterCount:parseInt(r.param_count,10)}))},async listFunctions(t){return(await se`
|
|
142
|
+
SELECT
|
|
143
|
+
p.proname,
|
|
144
|
+
n.nspname,
|
|
145
|
+
p.pronargs::text as param_count,
|
|
146
|
+
pg_get_function_result(p.oid) as return_type
|
|
147
|
+
FROM pg_proc p
|
|
148
|
+
JOIN pg_namespace n ON p.pronamespace = n.oid
|
|
149
|
+
WHERE n.nspname NOT IN (${se.join(Yr)})
|
|
150
|
+
AND p.prokind = 'f'
|
|
151
|
+
AND NOT EXISTS (
|
|
152
|
+
SELECT 1 FROM pg_depend d
|
|
153
|
+
WHERE d.objid = p.oid
|
|
154
|
+
AND d.deptype = 'e'
|
|
155
|
+
)
|
|
156
|
+
ORDER BY n.nspname, p.proname
|
|
157
|
+
`.execute(t)).rows.map(r=>({name:r.proname,schema:r.nspname,parameterCount:parseInt(r.param_count,10),returnType:r.return_type}))},async listTypes(t){return(await se`
|
|
158
|
+
SELECT
|
|
159
|
+
t.typname,
|
|
160
|
+
n.nspname,
|
|
161
|
+
t.typtype,
|
|
162
|
+
CASE
|
|
163
|
+
WHEN t.typtype = 'e' THEN (
|
|
164
|
+
SELECT COUNT(*)::text
|
|
165
|
+
FROM pg_enum e
|
|
166
|
+
WHERE e.enumtypid = t.oid
|
|
167
|
+
)
|
|
168
|
+
ELSE NULL
|
|
169
|
+
END as value_count
|
|
170
|
+
FROM pg_type t
|
|
171
|
+
JOIN pg_namespace n ON t.typnamespace = n.oid
|
|
172
|
+
WHERE n.nspname NOT IN (${se.join(Yr)})
|
|
173
|
+
AND t.typtype IN ('e', 'c', 'd')
|
|
174
|
+
AND NOT EXISTS (
|
|
175
|
+
SELECT 1 FROM pg_depend d
|
|
176
|
+
WHERE d.objid = t.oid
|
|
177
|
+
AND d.deptype = 'e'
|
|
178
|
+
)
|
|
179
|
+
AND NOT EXISTS (
|
|
180
|
+
SELECT 1 FROM pg_class c
|
|
181
|
+
WHERE c.reltype = t.oid
|
|
182
|
+
AND c.relkind IN ('r', 'v', 'm', 'p')
|
|
183
|
+
)
|
|
184
|
+
ORDER BY n.nspname, t.typname
|
|
185
|
+
`.execute(t)).rows.map(r=>({name:r.typname,schema:r.nspname,kind:r.typtype==="e"?"enum":r.typtype==="c"?"composite":r.typtype==="d"?"domain":"other",valueCount:r.value_count?parseInt(r.value_count,10):void 0}))},async listIndexes(t){return(await se`
|
|
186
|
+
SELECT
|
|
187
|
+
i.indexname,
|
|
188
|
+
i.schemaname,
|
|
189
|
+
i.tablename,
|
|
190
|
+
i.indexdef,
|
|
191
|
+
COALESCE(
|
|
192
|
+
EXISTS (
|
|
193
|
+
SELECT 1 FROM pg_constraint c
|
|
194
|
+
JOIN pg_class idx ON idx.oid = c.conindid
|
|
195
|
+
JOIN pg_class tbl ON tbl.oid = c.conrelid
|
|
196
|
+
JOIN pg_namespace n ON n.oid = tbl.relnamespace
|
|
197
|
+
WHERE c.contype = 'p'
|
|
198
|
+
AND idx.relname = i.indexname
|
|
199
|
+
AND n.nspname = i.schemaname
|
|
200
|
+
),
|
|
201
|
+
false
|
|
202
|
+
) as is_primary
|
|
203
|
+
FROM pg_indexes i
|
|
204
|
+
WHERE i.schemaname NOT IN (${se.join(Yr)})
|
|
205
|
+
ORDER BY i.schemaname, i.tablename, i.indexname
|
|
206
|
+
`.execute(t)).rows.map(r=>{let n=r.is_primary,o=r.indexdef.includes("UNIQUE")||n,i=r.indexdef.match(/\(([^)]+)\)/),s=i?.[1]?i[1].split(",").map(a=>a.trim()):[];return{name:r.indexname,schema:r.schemaname,tableName:r.tablename,tableSchema:r.schemaname,columns:s,isUnique:o,isPrimary:n}})},async listForeignKeys(t){let e=await se`
|
|
207
|
+
SELECT
|
|
208
|
+
tc.constraint_name,
|
|
209
|
+
tc.table_schema,
|
|
210
|
+
tc.table_name,
|
|
211
|
+
kcu.column_name,
|
|
212
|
+
ccu.table_schema AS foreign_table_schema,
|
|
213
|
+
ccu.table_name AS foreign_table_name,
|
|
214
|
+
ccu.column_name AS foreign_column_name,
|
|
215
|
+
rc.update_rule,
|
|
216
|
+
rc.delete_rule
|
|
217
|
+
FROM information_schema.table_constraints tc
|
|
218
|
+
JOIN information_schema.key_column_usage kcu
|
|
219
|
+
ON tc.constraint_name = kcu.constraint_name
|
|
220
|
+
AND tc.table_schema = kcu.table_schema
|
|
221
|
+
JOIN information_schema.constraint_column_usage ccu
|
|
222
|
+
ON tc.constraint_name = ccu.constraint_name
|
|
223
|
+
AND tc.table_schema = ccu.table_schema
|
|
224
|
+
JOIN information_schema.referential_constraints rc
|
|
225
|
+
ON tc.constraint_name = rc.constraint_name
|
|
226
|
+
AND tc.table_schema = rc.constraint_schema
|
|
227
|
+
WHERE tc.constraint_type = 'FOREIGN KEY'
|
|
228
|
+
AND tc.table_schema NOT IN (${se.join(Yr)})
|
|
229
|
+
ORDER BY tc.table_schema, tc.table_name, tc.constraint_name
|
|
230
|
+
`.execute(t),r=new Map;for(let n of e.rows){let o=`${n.table_schema}.${n.constraint_name}`;if(!r.has(o))r.set(o,{name:n.constraint_name,schema:n.table_schema,tableName:n.table_name,tableSchema:n.table_schema,columns:[n.column_name],referencedTable:n.foreign_table_name,referencedSchema:n.foreign_table_schema,referencedColumns:[n.foreign_column_name],onUpdate:n.update_rule,onDelete:n.delete_rule});else{let i=r.get(o);i.columns.push(n.column_name),i.referencedColumns.push(n.foreign_column_name)}}return Array.from(r.values())},async getTableDetail(t,e,r="public"){let n=await se`
|
|
231
|
+
SELECT
|
|
232
|
+
column_name,
|
|
233
|
+
data_type,
|
|
234
|
+
is_nullable,
|
|
235
|
+
column_default,
|
|
236
|
+
ordinal_position::text
|
|
237
|
+
FROM information_schema.columns
|
|
238
|
+
WHERE table_schema = ${r}
|
|
239
|
+
AND table_name = ${e}
|
|
240
|
+
ORDER BY ordinal_position
|
|
241
|
+
`.execute(t);if(n.rows.length===0)return null;let o=await se`
|
|
242
|
+
SELECT kcu.column_name
|
|
243
|
+
FROM information_schema.table_constraints tc
|
|
244
|
+
JOIN information_schema.key_column_usage kcu
|
|
245
|
+
ON tc.constraint_name = kcu.constraint_name
|
|
246
|
+
AND tc.table_schema = kcu.table_schema
|
|
247
|
+
WHERE tc.constraint_type = 'PRIMARY KEY'
|
|
248
|
+
AND tc.table_schema = ${r}
|
|
249
|
+
AND tc.table_name = ${e}
|
|
250
|
+
`.execute(t),i=new Set(o.rows.map(p=>p.column_name)),s=await se`
|
|
251
|
+
SELECT reltuples::bigint::text
|
|
252
|
+
FROM pg_class pc
|
|
253
|
+
JOIN pg_namespace pn ON pc.relnamespace = pn.oid
|
|
254
|
+
WHERE pc.relname = ${e}
|
|
255
|
+
AND pn.nspname = ${r}
|
|
256
|
+
`.execute(t),a=parseInt(s.rows[0]?.reltuples??"0",10),c=n.rows.map(p=>({name:p.column_name,dataType:p.data_type,isNullable:p.is_nullable==="YES",defaultValue:p.column_default??void 0,isPrimaryKey:i.has(p.column_name),ordinalPosition:parseInt(p.ordinal_position,10)})),m=(await this.listIndexes(t)).filter(p=>p.tableName===e&&p.tableSchema===r),u=(await this.listForeignKeys(t)).filter(p=>p.tableName===e&&p.tableSchema===r);return{name:e,schema:r,columns:c,indexes:m,foreignKeys:u,rowCountEstimate:a>0?a:void 0}},async getViewDetail(t,e,r="public"){let n=await se`
|
|
257
|
+
SELECT is_updatable, view_definition
|
|
258
|
+
FROM information_schema.views
|
|
259
|
+
WHERE table_schema = ${r}
|
|
260
|
+
AND table_name = ${e}
|
|
261
|
+
`.execute(t);if(n.rows.length===0)return null;let i=(await se`
|
|
262
|
+
SELECT
|
|
263
|
+
column_name,
|
|
264
|
+
data_type,
|
|
265
|
+
is_nullable,
|
|
266
|
+
column_default,
|
|
267
|
+
ordinal_position::text
|
|
268
|
+
FROM information_schema.columns
|
|
269
|
+
WHERE table_schema = ${r}
|
|
270
|
+
AND table_name = ${e}
|
|
271
|
+
ORDER BY ordinal_position
|
|
272
|
+
`.execute(t)).rows.map(a=>({name:a.column_name,dataType:a.data_type,isNullable:a.is_nullable==="YES",defaultValue:a.column_default??void 0,isPrimaryKey:!1,ordinalPosition:parseInt(a.ordinal_position,10)})),s=n.rows[0];return{name:e,schema:r,columns:i,definition:s?.view_definition??void 0,isUpdatable:s?.is_updatable==="YES"}},async getProcedureDetail(t,e,r="public"){let o=(await se`
|
|
273
|
+
SELECT p.oid::text, p.prosrc
|
|
274
|
+
FROM pg_proc p
|
|
275
|
+
JOIN pg_namespace n ON p.pronamespace = n.oid
|
|
276
|
+
WHERE n.nspname = ${r}
|
|
277
|
+
AND p.proname = ${e}
|
|
278
|
+
AND p.prokind = 'p'
|
|
279
|
+
`.execute(t)).rows[0];if(!o)return null;let i=o.oid,a=(await se`
|
|
280
|
+
SELECT
|
|
281
|
+
parameter_name,
|
|
282
|
+
data_type,
|
|
283
|
+
parameter_mode,
|
|
284
|
+
ordinal_position::text,
|
|
285
|
+
parameter_default
|
|
286
|
+
FROM information_schema.parameters
|
|
287
|
+
WHERE specific_schema = ${r}
|
|
288
|
+
AND specific_name = ${e||se.raw(`'_' || ${i}`)}
|
|
289
|
+
ORDER BY ordinal_position
|
|
290
|
+
`.execute(t)).rows.map(c=>({name:c.parameter_name??`$${c.ordinal_position}`,dataType:c.data_type,mode:c.parameter_mode,defaultValue:c.parameter_default??void 0,ordinalPosition:parseInt(c.ordinal_position,10)}));return{name:e,schema:r,parameters:a,definition:o.prosrc}},async getFunctionDetail(t,e,r="public"){let o=(await se`
|
|
291
|
+
SELECT
|
|
292
|
+
p.oid::text,
|
|
293
|
+
p.prosrc,
|
|
294
|
+
pg_get_function_result(p.oid) as return_type,
|
|
295
|
+
l.lanname as language
|
|
296
|
+
FROM pg_proc p
|
|
297
|
+
JOIN pg_namespace n ON p.pronamespace = n.oid
|
|
298
|
+
JOIN pg_language l ON p.prolang = l.oid
|
|
299
|
+
WHERE n.nspname = ${r}
|
|
300
|
+
AND p.proname = ${e}
|
|
301
|
+
AND p.prokind = 'f'
|
|
302
|
+
`.execute(t)).rows[0];if(!o)return null;let i=o.oid,a=(await se`
|
|
303
|
+
SELECT
|
|
304
|
+
parameter_name,
|
|
305
|
+
data_type,
|
|
306
|
+
parameter_mode,
|
|
307
|
+
ordinal_position::text,
|
|
308
|
+
parameter_default
|
|
309
|
+
FROM information_schema.parameters
|
|
310
|
+
WHERE specific_schema = ${r}
|
|
311
|
+
AND specific_name = ${e+"_"+i}
|
|
312
|
+
AND parameter_mode IN ('IN', 'INOUT')
|
|
313
|
+
ORDER BY ordinal_position
|
|
314
|
+
`.execute(t)).rows.map(c=>({name:c.parameter_name??`$${c.ordinal_position}`,dataType:c.data_type,mode:c.parameter_mode,defaultValue:c.parameter_default??void 0,ordinalPosition:parseInt(c.ordinal_position,10)}));return{name:e,schema:r,parameters:a,returnType:o.return_type,definition:o.prosrc,language:o.language}},async getTypeDetail(t,e,r="public"){let o=(await se`
|
|
315
|
+
SELECT
|
|
316
|
+
t.oid::text,
|
|
317
|
+
t.typtype,
|
|
318
|
+
CASE
|
|
319
|
+
WHEN t.typtype = 'd' THEN pg_catalog.format_type(t.typbasetype, t.typtypmod)
|
|
320
|
+
ELSE NULL
|
|
321
|
+
END as basetype
|
|
322
|
+
FROM pg_type t
|
|
323
|
+
JOIN pg_namespace n ON t.typnamespace = n.oid
|
|
324
|
+
WHERE n.nspname = ${r}
|
|
325
|
+
AND t.typname = ${e}
|
|
326
|
+
AND t.typtype IN ('e', 'c', 'd')
|
|
327
|
+
`.execute(t)).rows[0];if(!o)return null;let i=o.typtype==="e"?"enum":o.typtype==="c"?"composite":o.typtype==="d"?"domain":"other",s,a;return i==="enum"?s=(await se`
|
|
328
|
+
SELECT enumlabel
|
|
329
|
+
FROM pg_enum
|
|
330
|
+
WHERE enumtypid = ${o.oid}::oid
|
|
331
|
+
ORDER BY enumsortorder
|
|
332
|
+
`.execute(t)).rows.map(l=>l.enumlabel):i==="composite"&&(a=(await se`
|
|
333
|
+
SELECT
|
|
334
|
+
a.attname,
|
|
335
|
+
t.typname,
|
|
336
|
+
a.attnotnull,
|
|
337
|
+
a.attnum::text
|
|
338
|
+
FROM pg_attribute a
|
|
339
|
+
JOIN pg_type t ON a.atttypid = t.oid
|
|
340
|
+
WHERE a.attrelid = ${o.oid}::oid::regclass
|
|
341
|
+
AND a.attnum > 0
|
|
342
|
+
ORDER BY a.attnum
|
|
343
|
+
`.execute(t)).rows.map(l=>({name:l.attname,dataType:l.typname,isNullable:!l.attnotnull,isPrimaryKey:!1,ordinalPosition:parseInt(l.attnum,10)}))),{name:e,schema:r,kind:i,values:s,attributes:a,baseType:o.basetype??void 0}},async listTriggers(t){let e=await se`
|
|
344
|
+
SELECT DISTINCT
|
|
345
|
+
trigger_name,
|
|
346
|
+
trigger_schema,
|
|
347
|
+
event_object_table,
|
|
348
|
+
event_object_schema,
|
|
349
|
+
action_timing,
|
|
350
|
+
event_manipulation
|
|
351
|
+
FROM information_schema.triggers
|
|
352
|
+
WHERE trigger_schema NOT IN (${se.join(Yr)})
|
|
353
|
+
ORDER BY trigger_schema, event_object_table, trigger_name
|
|
354
|
+
`.execute(t),r=new Map;for(let n of e.rows){let o=`${n.trigger_schema}.${n.trigger_name}`,i=r.get(o);i?i.events.push(n.event_manipulation):r.set(o,{name:n.trigger_name,schema:n.trigger_schema,tableName:n.event_object_table,tableSchema:n.event_object_schema,timing:n.action_timing,events:[n.event_manipulation]})}return Array.from(r.values())},async listLocks(t){return(await se`
|
|
355
|
+
SELECT
|
|
356
|
+
l.pid,
|
|
357
|
+
l.locktype,
|
|
358
|
+
l.relation::regclass::text as relation,
|
|
359
|
+
l.mode,
|
|
360
|
+
l.granted
|
|
361
|
+
FROM pg_locks l
|
|
362
|
+
WHERE l.locktype != 'virtualxid'
|
|
363
|
+
ORDER BY l.pid, l.locktype
|
|
364
|
+
`.execute(t)).rows.map(r=>({pid:r.pid,lockType:r.locktype,objectName:r.relation??void 0,mode:r.mode,granted:r.granted}))},async listConnections(t){return(await se`
|
|
365
|
+
SELECT
|
|
366
|
+
pid,
|
|
367
|
+
usename,
|
|
368
|
+
datname,
|
|
369
|
+
application_name,
|
|
370
|
+
client_addr::text,
|
|
371
|
+
backend_start,
|
|
372
|
+
COALESCE(state, 'unknown') as state
|
|
373
|
+
FROM pg_stat_activity
|
|
374
|
+
WHERE datname = current_database()
|
|
375
|
+
AND pid != pg_backend_pid()
|
|
376
|
+
ORDER BY backend_start DESC
|
|
377
|
+
`.execute(t)).rows.map(r=>({pid:r.pid,username:r.usename,database:r.datname,applicationName:r.application_name||void 0,clientAddress:r.client_addr??void 0,backendStart:r.backend_start,state:r.state}))},async getTriggerDetail(t,e,r="public"){let n=await se`
|
|
378
|
+
SELECT
|
|
379
|
+
trigger_name,
|
|
380
|
+
event_object_table,
|
|
381
|
+
action_timing,
|
|
382
|
+
event_manipulation,
|
|
383
|
+
action_statement
|
|
384
|
+
FROM information_schema.triggers
|
|
385
|
+
WHERE trigger_name = ${e}
|
|
386
|
+
AND trigger_schema = ${r}
|
|
387
|
+
`.execute(t);if(n.rows.length===0)return null;let o=n.rows.map(s=>s.event_manipulation),i=n.rows[0];return{name:i.trigger_name,schema:r,tableName:i.event_object_table,tableSchema:r,timing:i.action_timing,events:o,definition:i.action_statement,isEnabled:!0}}};import{attempt as aT}from"@logosdx/utils";import{sql as Re}from"kysely";var Jy={async getOverview(t){let r=(await Re`SELECT DATABASE() as db`.execute(t)).rows[0]?.db;if(!r)return{tables:0,views:0,procedures:0,functions:0,types:0,indexes:0,foreignKeys:0,triggers:0,locks:0,connections:0};let[n,o,i,s,a,c]=await Promise.all([Re`
|
|
388
|
+
SELECT COUNT(*) as count
|
|
389
|
+
FROM information_schema.tables
|
|
390
|
+
WHERE table_schema = ${r}
|
|
391
|
+
AND table_type = 'BASE TABLE'
|
|
392
|
+
`.execute(t),Re`
|
|
393
|
+
SELECT COUNT(*) as count
|
|
394
|
+
FROM information_schema.views
|
|
395
|
+
WHERE table_schema = ${r}
|
|
396
|
+
`.execute(t),Re`
|
|
397
|
+
SELECT COUNT(*) as count
|
|
398
|
+
FROM information_schema.routines
|
|
399
|
+
WHERE routine_schema = ${r}
|
|
400
|
+
AND routine_type = 'PROCEDURE'
|
|
401
|
+
`.execute(t),Re`
|
|
402
|
+
SELECT COUNT(*) as count
|
|
403
|
+
FROM information_schema.routines
|
|
404
|
+
WHERE routine_schema = ${r}
|
|
405
|
+
AND routine_type = 'FUNCTION'
|
|
406
|
+
`.execute(t),Re`
|
|
407
|
+
SELECT COUNT(DISTINCT index_name) as count
|
|
408
|
+
FROM information_schema.statistics
|
|
409
|
+
WHERE table_schema = ${r}
|
|
410
|
+
`.execute(t),Re`
|
|
411
|
+
SELECT COUNT(*) as count
|
|
412
|
+
FROM information_schema.table_constraints
|
|
413
|
+
WHERE constraint_schema = ${r}
|
|
414
|
+
AND constraint_type = 'FOREIGN KEY'
|
|
415
|
+
`.execute(t)]);return{tables:parseInt(String(n.rows[0]?.count??"0"),10),views:parseInt(String(o.rows[0]?.count??"0"),10),procedures:parseInt(String(i.rows[0]?.count??"0"),10),functions:parseInt(String(s.rows[0]?.count??"0"),10),types:0,indexes:parseInt(String(a.rows[0]?.count??"0"),10),foreignKeys:parseInt(String(c.rows[0]?.count??"0"),10),triggers:0,locks:0,connections:0}},async listTables(t){let r=(await Re`SELECT DATABASE() as db`.execute(t)).rows[0]?.db;return r?(await Re`
|
|
416
|
+
SELECT
|
|
417
|
+
t.table_name AS table_name,
|
|
418
|
+
t.table_schema AS table_schema,
|
|
419
|
+
(
|
|
420
|
+
SELECT COUNT(*)
|
|
421
|
+
FROM information_schema.columns c
|
|
422
|
+
WHERE c.table_schema = t.table_schema
|
|
423
|
+
AND c.table_name = t.table_name
|
|
424
|
+
) AS column_count,
|
|
425
|
+
t.table_rows AS table_rows
|
|
426
|
+
FROM information_schema.tables t
|
|
427
|
+
WHERE t.table_schema = ${r}
|
|
428
|
+
AND t.table_type = 'BASE TABLE'
|
|
429
|
+
ORDER BY t.table_name
|
|
430
|
+
`.execute(t)).rows.map(o=>({name:o.table_name,schema:o.table_schema,columnCount:parseInt(String(o.column_count),10),rowCountEstimate:o.table_rows?parseInt(String(o.table_rows),10):void 0})):[]},async listViews(t){let r=(await Re`SELECT DATABASE() as db`.execute(t)).rows[0]?.db;return r?(await Re`
|
|
431
|
+
SELECT
|
|
432
|
+
v.table_name AS table_name,
|
|
433
|
+
v.table_schema AS table_schema,
|
|
434
|
+
(
|
|
435
|
+
SELECT COUNT(*)
|
|
436
|
+
FROM information_schema.columns c
|
|
437
|
+
WHERE c.table_schema = v.table_schema
|
|
438
|
+
AND c.table_name = v.table_name
|
|
439
|
+
) AS column_count,
|
|
440
|
+
v.is_updatable AS is_updatable
|
|
441
|
+
FROM information_schema.views v
|
|
442
|
+
WHERE v.table_schema = ${r}
|
|
443
|
+
ORDER BY v.table_name
|
|
444
|
+
`.execute(t)).rows.map(o=>({name:o.table_name,schema:o.table_schema,columnCount:parseInt(String(o.column_count),10),isUpdatable:o.is_updatable==="YES"})):[]},async listProcedures(t){let r=(await Re`SELECT DATABASE() as db`.execute(t)).rows[0]?.db;return r?(await Re`
|
|
445
|
+
SELECT
|
|
446
|
+
r.routine_name AS routine_name,
|
|
447
|
+
r.routine_schema AS routine_schema,
|
|
448
|
+
(
|
|
449
|
+
SELECT COUNT(*)
|
|
450
|
+
FROM information_schema.parameters p
|
|
451
|
+
WHERE p.specific_schema = r.routine_schema
|
|
452
|
+
AND p.specific_name = r.specific_name
|
|
453
|
+
AND p.ordinal_position > 0
|
|
454
|
+
) AS param_count
|
|
455
|
+
FROM information_schema.routines r
|
|
456
|
+
WHERE r.routine_schema = ${r}
|
|
457
|
+
AND r.routine_type = 'PROCEDURE'
|
|
458
|
+
ORDER BY r.routine_name
|
|
459
|
+
`.execute(t)).rows.map(o=>({name:o.routine_name,schema:o.routine_schema,parameterCount:parseInt(String(o.param_count),10)})):[]},async listFunctions(t){let r=(await Re`SELECT DATABASE() as db`.execute(t)).rows[0]?.db;return r?(await Re`
|
|
460
|
+
SELECT
|
|
461
|
+
r.routine_name AS routine_name,
|
|
462
|
+
r.routine_schema AS routine_schema,
|
|
463
|
+
(
|
|
464
|
+
SELECT COUNT(*)
|
|
465
|
+
FROM information_schema.parameters p
|
|
466
|
+
WHERE p.specific_schema = r.routine_schema
|
|
467
|
+
AND p.specific_name = r.specific_name
|
|
468
|
+
AND p.ordinal_position > 0
|
|
469
|
+
) AS param_count,
|
|
470
|
+
COALESCE(r.data_type, 'unknown') AS data_type
|
|
471
|
+
FROM information_schema.routines r
|
|
472
|
+
WHERE r.routine_schema = ${r}
|
|
473
|
+
AND r.routine_type = 'FUNCTION'
|
|
474
|
+
ORDER BY r.routine_name
|
|
475
|
+
`.execute(t)).rows.map(o=>({name:o.routine_name,schema:o.routine_schema,parameterCount:parseInt(String(o.param_count),10),returnType:o.data_type})):[]},async listTypes(t){return[]},async listIndexes(t){let r=(await Re`SELECT DATABASE() as db`.execute(t)).rows[0]?.db;if(!r)return[];let n=await Re`
|
|
476
|
+
SELECT
|
|
477
|
+
index_name AS index_name,
|
|
478
|
+
table_name AS table_name,
|
|
479
|
+
column_name AS column_name,
|
|
480
|
+
non_unique AS non_unique,
|
|
481
|
+
seq_in_index AS seq_in_index
|
|
482
|
+
FROM information_schema.statistics
|
|
483
|
+
WHERE table_schema = ${r}
|
|
484
|
+
ORDER BY table_name, index_name, seq_in_index
|
|
485
|
+
`.execute(t),o=new Map;for(let i of n.rows){let s=`${i.table_name}.${i.index_name}`;o.has(s)?o.get(s).columns.push(i.column_name):o.set(s,{name:i.index_name,schema:r,tableName:i.table_name,tableSchema:r,columns:[i.column_name],isUnique:i.non_unique===0,isPrimary:i.index_name==="PRIMARY"})}return Array.from(o.values())},async listForeignKeys(t){let r=(await Re`SELECT DATABASE() as db`.execute(t)).rows[0]?.db;if(!r)return[];let n=await Re`
|
|
486
|
+
SELECT
|
|
487
|
+
kcu.constraint_name AS constraint_name,
|
|
488
|
+
kcu.table_name AS table_name,
|
|
489
|
+
kcu.column_name AS column_name,
|
|
490
|
+
kcu.referenced_table_name AS referenced_table_name,
|
|
491
|
+
kcu.referenced_column_name AS referenced_column_name,
|
|
492
|
+
rc.update_rule AS update_rule,
|
|
493
|
+
rc.delete_rule AS delete_rule
|
|
494
|
+
FROM information_schema.key_column_usage kcu
|
|
495
|
+
JOIN information_schema.referential_constraints rc
|
|
496
|
+
ON kcu.constraint_name = rc.constraint_name
|
|
497
|
+
AND kcu.constraint_schema = rc.constraint_schema
|
|
498
|
+
WHERE kcu.constraint_schema = ${r}
|
|
499
|
+
AND kcu.referenced_table_name IS NOT NULL
|
|
500
|
+
ORDER BY kcu.table_name, kcu.constraint_name, kcu.ordinal_position
|
|
501
|
+
`.execute(t),o=new Map;for(let i of n.rows){let s=`${i.table_name}.${i.constraint_name}`;if(!o.has(s))o.set(s,{name:i.constraint_name,schema:r,tableName:i.table_name,tableSchema:r,columns:[i.column_name],referencedTable:i.referenced_table_name,referencedSchema:r,referencedColumns:[i.referenced_column_name],onUpdate:i.update_rule,onDelete:i.delete_rule});else{let a=o.get(s);a.columns.push(i.column_name),a.referencedColumns.push(i.referenced_column_name)}}return Array.from(o.values())},async getTableDetail(t,e,r){let n=await Re`SELECT DATABASE() as db`.execute(t),o=r??n.rows[0]?.db;if(!o)return null;let i=await Re`
|
|
502
|
+
SELECT
|
|
503
|
+
column_name AS column_name,
|
|
504
|
+
data_type AS data_type,
|
|
505
|
+
is_nullable AS is_nullable,
|
|
506
|
+
column_default AS column_default,
|
|
507
|
+
ordinal_position AS ordinal_position,
|
|
508
|
+
column_key AS column_key
|
|
509
|
+
FROM information_schema.columns
|
|
510
|
+
WHERE table_schema = ${o}
|
|
511
|
+
AND table_name = ${e}
|
|
512
|
+
ORDER BY ordinal_position
|
|
513
|
+
`.execute(t);if(i.rows.length===0)return null;let s=i.rows.map(p=>({name:p.column_name,dataType:p.data_type,isNullable:p.is_nullable==="YES",defaultValue:p.column_default??void 0,isPrimaryKey:p.column_key==="PRI",ordinalPosition:p.ordinal_position})),a=await Re`
|
|
514
|
+
SELECT table_rows AS table_rows
|
|
515
|
+
FROM information_schema.tables
|
|
516
|
+
WHERE table_schema = ${o}
|
|
517
|
+
AND table_name = ${e}
|
|
518
|
+
`.execute(t),c=a.rows[0]?.table_rows?parseInt(String(a.rows[0].table_rows),10):void 0,m=(await this.listIndexes(t)).filter(p=>p.tableName===e),u=(await this.listForeignKeys(t)).filter(p=>p.tableName===e);return{name:e,schema:o,columns:s,indexes:m,foreignKeys:u,rowCountEstimate:c}},async getViewDetail(t,e,r){let n=await Re`SELECT DATABASE() as db`.execute(t),o=r??n.rows[0]?.db;if(!o)return null;let i=await Re`
|
|
519
|
+
SELECT is_updatable AS is_updatable, view_definition AS view_definition
|
|
520
|
+
FROM information_schema.views
|
|
521
|
+
WHERE table_schema = ${o}
|
|
522
|
+
AND table_name = ${e}
|
|
523
|
+
`.execute(t);if(i.rows.length===0)return null;let a=(await Re`
|
|
524
|
+
SELECT
|
|
525
|
+
column_name AS column_name,
|
|
526
|
+
data_type AS data_type,
|
|
527
|
+
is_nullable AS is_nullable,
|
|
528
|
+
column_default AS column_default,
|
|
529
|
+
ordinal_position AS ordinal_position
|
|
530
|
+
FROM information_schema.columns
|
|
531
|
+
WHERE table_schema = ${o}
|
|
532
|
+
AND table_name = ${e}
|
|
533
|
+
ORDER BY ordinal_position
|
|
534
|
+
`.execute(t)).rows.map(l=>({name:l.column_name,dataType:l.data_type,isNullable:l.is_nullable==="YES",defaultValue:l.column_default??void 0,isPrimaryKey:!1,ordinalPosition:l.ordinal_position})),c=i.rows[0];return{name:e,schema:o,columns:a,definition:c?.view_definition??void 0,isUpdatable:c?.is_updatable==="YES"}},async getProcedureDetail(t,e,r){let n=await Re`SELECT DATABASE() as db`.execute(t),o=r??n.rows[0]?.db;if(!o)return null;let s=(await Re`
|
|
535
|
+
SELECT routine_definition AS routine_definition, specific_name AS specific_name
|
|
536
|
+
FROM information_schema.routines
|
|
537
|
+
WHERE routine_schema = ${o}
|
|
538
|
+
AND routine_name = ${e}
|
|
539
|
+
AND routine_type = 'PROCEDURE'
|
|
540
|
+
`.execute(t)).rows[0];if(!s)return null;let c=(await Re`
|
|
541
|
+
SELECT
|
|
542
|
+
parameter_name AS parameter_name,
|
|
543
|
+
data_type AS data_type,
|
|
544
|
+
parameter_mode AS parameter_mode,
|
|
545
|
+
ordinal_position AS ordinal_position
|
|
546
|
+
FROM information_schema.parameters
|
|
547
|
+
WHERE specific_schema = ${o}
|
|
548
|
+
AND specific_name = ${s.specific_name}
|
|
549
|
+
AND ordinal_position > 0
|
|
550
|
+
ORDER BY ordinal_position
|
|
551
|
+
`.execute(t)).rows.map(l=>({name:l.parameter_name??`param${l.ordinal_position}`,dataType:l.data_type,mode:l.parameter_mode??"IN",ordinalPosition:l.ordinal_position}));return{name:e,schema:o,parameters:c,definition:s.routine_definition??void 0}},async getFunctionDetail(t,e,r){let n=await Re`SELECT DATABASE() as db`.execute(t),o=r??n.rows[0]?.db;if(!o)return null;let s=(await Re`
|
|
552
|
+
SELECT routine_definition AS routine_definition, specific_name AS specific_name, data_type AS data_type
|
|
553
|
+
FROM information_schema.routines
|
|
554
|
+
WHERE routine_schema = ${o}
|
|
555
|
+
AND routine_name = ${e}
|
|
556
|
+
AND routine_type = 'FUNCTION'
|
|
557
|
+
`.execute(t)).rows[0];if(!s)return null;let c=(await Re`
|
|
558
|
+
SELECT
|
|
559
|
+
parameter_name AS parameter_name,
|
|
560
|
+
data_type AS data_type,
|
|
561
|
+
parameter_mode AS parameter_mode,
|
|
562
|
+
ordinal_position AS ordinal_position
|
|
563
|
+
FROM information_schema.parameters
|
|
564
|
+
WHERE specific_schema = ${o}
|
|
565
|
+
AND specific_name = ${s.specific_name}
|
|
566
|
+
AND ordinal_position > 0
|
|
567
|
+
ORDER BY ordinal_position
|
|
568
|
+
`.execute(t)).rows.map(l=>({name:l.parameter_name??`param${l.ordinal_position}`,dataType:l.data_type,mode:l.parameter_mode??"IN",ordinalPosition:l.ordinal_position}));return{name:e,schema:o,parameters:c,returnType:s.data_type,definition:s.routine_definition??void 0}},async getTypeDetail(t,e,r){return null},async listTriggers(t){return(await Re`
|
|
569
|
+
SELECT
|
|
570
|
+
TRIGGER_NAME,
|
|
571
|
+
TRIGGER_SCHEMA,
|
|
572
|
+
EVENT_OBJECT_TABLE,
|
|
573
|
+
ACTION_TIMING,
|
|
574
|
+
EVENT_MANIPULATION
|
|
575
|
+
FROM information_schema.TRIGGERS
|
|
576
|
+
WHERE TRIGGER_SCHEMA = DATABASE()
|
|
577
|
+
ORDER BY EVENT_OBJECT_TABLE, TRIGGER_NAME
|
|
578
|
+
`.execute(t)).rows.map(r=>({name:r.TRIGGER_NAME,schema:r.TRIGGER_SCHEMA,tableName:r.EVENT_OBJECT_TABLE,tableSchema:r.TRIGGER_SCHEMA,timing:r.ACTION_TIMING,events:[r.EVENT_MANIPULATION]}))},async listLocks(t){let[e,r]=await aT(()=>Re`
|
|
579
|
+
SELECT
|
|
580
|
+
OBJECT_TYPE,
|
|
581
|
+
OBJECT_NAME,
|
|
582
|
+
LOCK_TYPE,
|
|
583
|
+
LOCK_STATUS,
|
|
584
|
+
OWNER_THREAD_ID
|
|
585
|
+
FROM performance_schema.metadata_locks
|
|
586
|
+
WHERE OBJECT_SCHEMA = DATABASE()
|
|
587
|
+
ORDER BY OWNER_THREAD_ID
|
|
588
|
+
`.execute(t));return r?[]:e.rows.map(n=>({pid:n.OWNER_THREAD_ID,lockType:n.OBJECT_TYPE,objectName:n.OBJECT_NAME??void 0,mode:n.LOCK_TYPE,granted:n.LOCK_STATUS==="GRANTED"}))},async listConnections(t){return(await Re`
|
|
589
|
+
SELECT
|
|
590
|
+
ID,
|
|
591
|
+
USER,
|
|
592
|
+
HOST,
|
|
593
|
+
DB,
|
|
594
|
+
STATE,
|
|
595
|
+
INFO
|
|
596
|
+
FROM information_schema.PROCESSLIST
|
|
597
|
+
WHERE DB = DATABASE()
|
|
598
|
+
AND ID != CONNECTION_ID()
|
|
599
|
+
ORDER BY ID
|
|
600
|
+
`.execute(t)).rows.map(r=>({pid:r.ID,username:r.USER,database:r.DB,clientAddress:r.HOST,state:r.STATE||"unknown"}))},async getTriggerDetail(t,e,r){let n=await Re`
|
|
601
|
+
SELECT
|
|
602
|
+
TRIGGER_NAME,
|
|
603
|
+
EVENT_OBJECT_TABLE,
|
|
604
|
+
ACTION_TIMING,
|
|
605
|
+
EVENT_MANIPULATION,
|
|
606
|
+
ACTION_STATEMENT
|
|
607
|
+
FROM information_schema.TRIGGERS
|
|
608
|
+
WHERE TRIGGER_NAME = ${e}
|
|
609
|
+
AND TRIGGER_SCHEMA = DATABASE()
|
|
610
|
+
`.execute(t);if(n.rows.length===0)return null;let o=n.rows[0];return{name:o.TRIGGER_NAME,schema:r||void 0,tableName:o.EVENT_OBJECT_TABLE,tableSchema:r,timing:o.ACTION_TIMING,events:[o.EVENT_MANIPULATION],definition:o.ACTION_STATEMENT,isEnabled:!0}}};import{sql as ae}from"kysely";var Wr=["sys","INFORMATION_SCHEMA","guest"],Qy={async getOverview(t){let[e,r,n,o,i,s,a]=await Promise.all([ae`
|
|
611
|
+
SELECT COUNT(*) as count
|
|
612
|
+
FROM sys.tables t
|
|
613
|
+
JOIN sys.schemas s ON t.schema_id = s.schema_id
|
|
614
|
+
WHERE s.name NOT IN (${ae.join(Wr)})
|
|
615
|
+
`.execute(t),ae`
|
|
616
|
+
SELECT COUNT(*) as count
|
|
617
|
+
FROM sys.views v
|
|
618
|
+
JOIN sys.schemas s ON v.schema_id = s.schema_id
|
|
619
|
+
WHERE s.name NOT IN (${ae.join(Wr)})
|
|
620
|
+
`.execute(t),ae`
|
|
621
|
+
SELECT COUNT(*) as count
|
|
622
|
+
FROM sys.procedures p
|
|
623
|
+
JOIN sys.schemas s ON p.schema_id = s.schema_id
|
|
624
|
+
WHERE s.name NOT IN (${ae.join(Wr)})
|
|
625
|
+
`.execute(t),ae`
|
|
626
|
+
SELECT COUNT(*) as count
|
|
627
|
+
FROM sys.objects o
|
|
628
|
+
JOIN sys.schemas s ON o.schema_id = s.schema_id
|
|
629
|
+
WHERE o.type IN ('FN', 'IF', 'TF')
|
|
630
|
+
AND s.name NOT IN (${ae.join(Wr)})
|
|
631
|
+
`.execute(t),ae`
|
|
632
|
+
SELECT COUNT(*) as count
|
|
633
|
+
FROM sys.types t
|
|
634
|
+
JOIN sys.schemas s ON t.schema_id = s.schema_id
|
|
635
|
+
WHERE t.is_user_defined = 1
|
|
636
|
+
AND s.name NOT IN (${ae.join(Wr)})
|
|
637
|
+
`.execute(t),ae`
|
|
638
|
+
SELECT COUNT(*) as count
|
|
639
|
+
FROM sys.indexes i
|
|
640
|
+
JOIN sys.tables t ON i.object_id = t.object_id
|
|
641
|
+
JOIN sys.schemas s ON t.schema_id = s.schema_id
|
|
642
|
+
WHERE i.name IS NOT NULL
|
|
643
|
+
AND s.name NOT IN (${ae.join(Wr)})
|
|
644
|
+
`.execute(t),ae`
|
|
645
|
+
SELECT COUNT(*) as count
|
|
646
|
+
FROM sys.foreign_keys fk
|
|
647
|
+
JOIN sys.schemas s ON fk.schema_id = s.schema_id
|
|
648
|
+
WHERE s.name NOT IN (${ae.join(Wr)})
|
|
649
|
+
`.execute(t)]);return{tables:e.rows[0]?.count??0,views:r.rows[0]?.count??0,procedures:n.rows[0]?.count??0,functions:o.rows[0]?.count??0,types:i.rows[0]?.count??0,indexes:s.rows[0]?.count??0,foreignKeys:a.rows[0]?.count??0,triggers:0,locks:0,connections:0}},async listTables(t){return(await ae`
|
|
650
|
+
SELECT
|
|
651
|
+
t.name as table_name,
|
|
652
|
+
s.name as schema_name,
|
|
653
|
+
(
|
|
654
|
+
SELECT COUNT(*)
|
|
655
|
+
FROM sys.columns c
|
|
656
|
+
WHERE c.object_id = t.object_id
|
|
657
|
+
) as column_count,
|
|
658
|
+
ISNULL(p.rows, 0) as row_count
|
|
659
|
+
FROM sys.tables t
|
|
660
|
+
JOIN sys.schemas s ON t.schema_id = s.schema_id
|
|
661
|
+
LEFT JOIN sys.partitions p ON t.object_id = p.object_id AND p.index_id IN (0, 1)
|
|
662
|
+
WHERE s.name NOT IN (${ae.join(Wr)})
|
|
663
|
+
ORDER BY s.name, t.name
|
|
664
|
+
`.execute(t)).rows.map(r=>({name:r.table_name,schema:r.schema_name,columnCount:r.column_count,rowCountEstimate:r.row_count>0?r.row_count:void 0}))},async listViews(t){return(await ae`
|
|
665
|
+
SELECT
|
|
666
|
+
v.name as view_name,
|
|
667
|
+
s.name as schema_name,
|
|
668
|
+
(
|
|
669
|
+
SELECT COUNT(*)
|
|
670
|
+
FROM sys.columns c
|
|
671
|
+
WHERE c.object_id = v.object_id
|
|
672
|
+
) as column_count
|
|
673
|
+
FROM sys.views v
|
|
674
|
+
JOIN sys.schemas s ON v.schema_id = s.schema_id
|
|
675
|
+
WHERE s.name NOT IN (${ae.join(Wr)})
|
|
676
|
+
ORDER BY s.name, v.name
|
|
677
|
+
`.execute(t)).rows.map(r=>({name:r.view_name,schema:r.schema_name,columnCount:r.column_count,isUpdatable:!1}))},async listProcedures(t){return(await ae`
|
|
678
|
+
SELECT
|
|
679
|
+
p.name as proc_name,
|
|
680
|
+
s.name as schema_name,
|
|
681
|
+
(
|
|
682
|
+
SELECT COUNT(*)
|
|
683
|
+
FROM sys.parameters pr
|
|
684
|
+
WHERE pr.object_id = p.object_id
|
|
685
|
+
AND pr.parameter_id > 0
|
|
686
|
+
) as param_count
|
|
687
|
+
FROM sys.procedures p
|
|
688
|
+
JOIN sys.schemas s ON p.schema_id = s.schema_id
|
|
689
|
+
WHERE s.name NOT IN (${ae.join(Wr)})
|
|
690
|
+
ORDER BY s.name, p.name
|
|
691
|
+
`.execute(t)).rows.map(r=>({name:r.proc_name,schema:r.schema_name,parameterCount:r.param_count}))},async listFunctions(t){return(await ae`
|
|
692
|
+
SELECT
|
|
693
|
+
o.name as func_name,
|
|
694
|
+
s.name as schema_name,
|
|
695
|
+
(
|
|
696
|
+
SELECT COUNT(*)
|
|
697
|
+
FROM sys.parameters p
|
|
698
|
+
WHERE p.object_id = o.object_id
|
|
699
|
+
AND p.parameter_id > 0
|
|
700
|
+
) as param_count,
|
|
701
|
+
CASE o.type
|
|
702
|
+
WHEN 'FN' THEN 'scalar'
|
|
703
|
+
WHEN 'IF' THEN 'inline table'
|
|
704
|
+
WHEN 'TF' THEN 'table'
|
|
705
|
+
ELSE 'unknown'
|
|
706
|
+
END as return_type
|
|
707
|
+
FROM sys.objects o
|
|
708
|
+
JOIN sys.schemas s ON o.schema_id = s.schema_id
|
|
709
|
+
WHERE o.type IN ('FN', 'IF', 'TF')
|
|
710
|
+
AND s.name NOT IN (${ae.join(Wr)})
|
|
711
|
+
ORDER BY s.name, o.name
|
|
712
|
+
`.execute(t)).rows.map(r=>({name:r.func_name,schema:r.schema_name,parameterCount:r.param_count,returnType:r.return_type}))},async listTypes(t){return(await ae`
|
|
713
|
+
SELECT
|
|
714
|
+
t.name as type_name,
|
|
715
|
+
s.name as schema_name,
|
|
716
|
+
t.is_table_type
|
|
717
|
+
FROM sys.types t
|
|
718
|
+
JOIN sys.schemas s ON t.schema_id = s.schema_id
|
|
719
|
+
WHERE t.is_user_defined = 1
|
|
720
|
+
AND s.name NOT IN (${ae.join(Wr)})
|
|
721
|
+
ORDER BY s.name, t.name
|
|
722
|
+
`.execute(t)).rows.map(r=>({name:r.type_name,schema:r.schema_name,kind:r.is_table_type?"composite":"domain"}))},async listIndexes(t){return(await ae`
|
|
723
|
+
SELECT
|
|
724
|
+
i.name as index_name,
|
|
725
|
+
s.name as schema_name,
|
|
726
|
+
t.name as table_name,
|
|
727
|
+
i.is_unique,
|
|
728
|
+
i.is_primary_key,
|
|
729
|
+
STRING_AGG(c.name, ', ') WITHIN GROUP (ORDER BY ic.key_ordinal) as column_names
|
|
730
|
+
FROM sys.indexes i
|
|
731
|
+
JOIN sys.tables t ON i.object_id = t.object_id
|
|
732
|
+
JOIN sys.schemas s ON t.schema_id = s.schema_id
|
|
733
|
+
JOIN sys.index_columns ic ON i.object_id = ic.object_id AND i.index_id = ic.index_id
|
|
734
|
+
JOIN sys.columns c ON ic.object_id = c.object_id AND ic.column_id = c.column_id
|
|
735
|
+
WHERE i.name IS NOT NULL
|
|
736
|
+
AND s.name NOT IN (${ae.join(Wr)})
|
|
737
|
+
GROUP BY i.name, s.name, t.name, i.is_unique, i.is_primary_key
|
|
738
|
+
ORDER BY s.name, t.name, i.name
|
|
739
|
+
`.execute(t)).rows.map(r=>({name:r.index_name,schema:r.schema_name,tableName:r.table_name,tableSchema:r.schema_name,columns:r.column_names.split(", "),isUnique:r.is_unique,isPrimary:r.is_primary_key}))},async listForeignKeys(t){let e=await ae`
|
|
740
|
+
SELECT
|
|
741
|
+
fk.name as fk_name,
|
|
742
|
+
s.name as schema_name,
|
|
743
|
+
t.name as table_name,
|
|
744
|
+
c.name as column_name,
|
|
745
|
+
rs.name as ref_schema,
|
|
746
|
+
rt.name as ref_table,
|
|
747
|
+
rc.name as ref_column,
|
|
748
|
+
CASE fk.delete_referential_action
|
|
749
|
+
WHEN 0 THEN 'NO ACTION'
|
|
750
|
+
WHEN 1 THEN 'CASCADE'
|
|
751
|
+
WHEN 2 THEN 'SET NULL'
|
|
752
|
+
WHEN 3 THEN 'SET DEFAULT'
|
|
753
|
+
END as delete_action,
|
|
754
|
+
CASE fk.update_referential_action
|
|
755
|
+
WHEN 0 THEN 'NO ACTION'
|
|
756
|
+
WHEN 1 THEN 'CASCADE'
|
|
757
|
+
WHEN 2 THEN 'SET NULL'
|
|
758
|
+
WHEN 3 THEN 'SET DEFAULT'
|
|
759
|
+
END as update_action
|
|
760
|
+
FROM sys.foreign_keys fk
|
|
761
|
+
JOIN sys.foreign_key_columns fkc ON fk.object_id = fkc.constraint_object_id
|
|
762
|
+
JOIN sys.tables t ON fk.parent_object_id = t.object_id
|
|
763
|
+
JOIN sys.schemas s ON t.schema_id = s.schema_id
|
|
764
|
+
JOIN sys.columns c ON fkc.parent_object_id = c.object_id AND fkc.parent_column_id = c.column_id
|
|
765
|
+
JOIN sys.tables rt ON fk.referenced_object_id = rt.object_id
|
|
766
|
+
JOIN sys.schemas rs ON rt.schema_id = rs.schema_id
|
|
767
|
+
JOIN sys.columns rc ON fkc.referenced_object_id = rc.object_id AND fkc.referenced_column_id = rc.column_id
|
|
768
|
+
WHERE s.name NOT IN (${ae.join(Wr)})
|
|
769
|
+
ORDER BY s.name, t.name, fk.name, fkc.constraint_column_id
|
|
770
|
+
`.execute(t),r=new Map;for(let n of e.rows){let o=`${n.schema_name}.${n.fk_name}`;if(!r.has(o))r.set(o,{name:n.fk_name,schema:n.schema_name,tableName:n.table_name,tableSchema:n.schema_name,columns:[n.column_name],referencedTable:n.ref_table,referencedSchema:n.ref_schema,referencedColumns:[n.ref_column],onDelete:n.delete_action,onUpdate:n.update_action});else{let i=r.get(o);i.columns.push(n.column_name),i.referencedColumns.push(n.ref_column)}}return Array.from(r.values())},async getTableDetail(t,e,r="dbo"){let n=await ae`
|
|
771
|
+
SELECT
|
|
772
|
+
c.name as column_name,
|
|
773
|
+
TYPE_NAME(c.user_type_id) as data_type,
|
|
774
|
+
c.is_nullable,
|
|
775
|
+
OBJECT_DEFINITION(c.default_object_id) as column_default,
|
|
776
|
+
c.column_id as ordinal_position,
|
|
777
|
+
c.is_identity
|
|
778
|
+
FROM sys.columns c
|
|
779
|
+
JOIN sys.tables t ON c.object_id = t.object_id
|
|
780
|
+
JOIN sys.schemas s ON t.schema_id = s.schema_id
|
|
781
|
+
WHERE t.name = ${e}
|
|
782
|
+
AND s.name = ${r}
|
|
783
|
+
ORDER BY c.column_id
|
|
784
|
+
`.execute(t);if(n.rows.length===0)return null;let o=await ae`
|
|
785
|
+
SELECT c.name as column_name
|
|
786
|
+
FROM sys.indexes i
|
|
787
|
+
JOIN sys.index_columns ic ON i.object_id = ic.object_id AND i.index_id = ic.index_id
|
|
788
|
+
JOIN sys.columns c ON ic.object_id = c.object_id AND ic.column_id = c.column_id
|
|
789
|
+
JOIN sys.tables t ON i.object_id = t.object_id
|
|
790
|
+
JOIN sys.schemas s ON t.schema_id = s.schema_id
|
|
791
|
+
WHERE i.is_primary_key = 1
|
|
792
|
+
AND t.name = ${e}
|
|
793
|
+
AND s.name = ${r}
|
|
794
|
+
`.execute(t),i=new Set(o.rows.map(u=>u.column_name)),s=await ae`
|
|
795
|
+
SELECT SUM(p.rows) as row_count
|
|
796
|
+
FROM sys.partitions p
|
|
797
|
+
JOIN sys.tables t ON p.object_id = t.object_id
|
|
798
|
+
JOIN sys.schemas s ON t.schema_id = s.schema_id
|
|
799
|
+
WHERE p.index_id IN (0, 1)
|
|
800
|
+
AND t.name = ${e}
|
|
801
|
+
AND s.name = ${r}
|
|
802
|
+
`.execute(t),a=n.rows.map(u=>({name:u.column_name,dataType:u.data_type,isNullable:u.is_nullable,defaultValue:u.column_default??void 0,isPrimaryKey:i.has(u.column_name),ordinalPosition:u.ordinal_position})),l=(await this.listIndexes(t)).filter(u=>u.tableName===e&&u.tableSchema===r),d=(await this.listForeignKeys(t)).filter(u=>u.tableName===e&&u.tableSchema===r);return{name:e,schema:r,columns:a,indexes:l,foreignKeys:d,rowCountEstimate:s.rows[0]?.row_count??void 0}},async getViewDetail(t,e,r="dbo"){if((await ae`
|
|
803
|
+
SELECT v.object_id
|
|
804
|
+
FROM sys.views v
|
|
805
|
+
JOIN sys.schemas s ON v.schema_id = s.schema_id
|
|
806
|
+
WHERE v.name = ${e}
|
|
807
|
+
AND s.name = ${r}
|
|
808
|
+
`.execute(t)).rows.length===0)return null;let o=await ae`
|
|
809
|
+
SELECT
|
|
810
|
+
c.name as column_name,
|
|
811
|
+
TYPE_NAME(c.user_type_id) as data_type,
|
|
812
|
+
c.is_nullable,
|
|
813
|
+
c.column_id as ordinal_position
|
|
814
|
+
FROM sys.columns c
|
|
815
|
+
JOIN sys.views v ON c.object_id = v.object_id
|
|
816
|
+
JOIN sys.schemas s ON v.schema_id = s.schema_id
|
|
817
|
+
WHERE v.name = ${e}
|
|
818
|
+
AND s.name = ${r}
|
|
819
|
+
ORDER BY c.column_id
|
|
820
|
+
`.execute(t),i=await ae`
|
|
821
|
+
SELECT OBJECT_DEFINITION(OBJECT_ID(${r+"."+e})) as definition
|
|
822
|
+
`.execute(t),s=o.rows.map(a=>({name:a.column_name,dataType:a.data_type,isNullable:a.is_nullable,isPrimaryKey:!1,ordinalPosition:a.ordinal_position}));return{name:e,schema:r,columns:s,definition:i.rows[0]?.definition??void 0,isUpdatable:!1}},async getProcedureDetail(t,e,r="dbo"){let o=(await ae`
|
|
823
|
+
SELECT OBJECT_DEFINITION(p.object_id) as definition
|
|
824
|
+
FROM sys.procedures p
|
|
825
|
+
JOIN sys.schemas s ON p.schema_id = s.schema_id
|
|
826
|
+
WHERE p.name = ${e}
|
|
827
|
+
AND s.name = ${r}
|
|
828
|
+
`.execute(t)).rows[0];if(!o)return null;let s=(await ae`
|
|
829
|
+
SELECT
|
|
830
|
+
pr.name as parameter_name,
|
|
831
|
+
TYPE_NAME(pr.user_type_id) as data_type,
|
|
832
|
+
pr.is_output,
|
|
833
|
+
pr.parameter_id as ordinal_position,
|
|
834
|
+
pr.has_default_value as has_default
|
|
835
|
+
FROM sys.parameters pr
|
|
836
|
+
JOIN sys.procedures p ON pr.object_id = p.object_id
|
|
837
|
+
JOIN sys.schemas s ON p.schema_id = s.schema_id
|
|
838
|
+
WHERE p.name = ${e}
|
|
839
|
+
AND s.name = ${r}
|
|
840
|
+
AND pr.parameter_id > 0
|
|
841
|
+
ORDER BY pr.parameter_id
|
|
842
|
+
`.execute(t)).rows.map(a=>({name:a.parameter_name.replace(/^@/,""),dataType:a.data_type,mode:a.is_output?"OUT":"IN",ordinalPosition:a.ordinal_position}));return{name:e,schema:r,parameters:s,definition:o.definition??void 0}},async getFunctionDetail(t,e,r="dbo"){let o=(await ae`
|
|
843
|
+
SELECT
|
|
844
|
+
OBJECT_DEFINITION(o.object_id) as definition,
|
|
845
|
+
o.type as func_type
|
|
846
|
+
FROM sys.objects o
|
|
847
|
+
JOIN sys.schemas s ON o.schema_id = s.schema_id
|
|
848
|
+
WHERE o.name = ${e}
|
|
849
|
+
AND s.name = ${r}
|
|
850
|
+
AND o.type IN ('FN', 'IF', 'TF')
|
|
851
|
+
`.execute(t)).rows[0];if(!o)return null;let s=(await ae`
|
|
852
|
+
SELECT
|
|
853
|
+
pr.name as parameter_name,
|
|
854
|
+
TYPE_NAME(pr.user_type_id) as data_type,
|
|
855
|
+
pr.parameter_id as ordinal_position
|
|
856
|
+
FROM sys.parameters pr
|
|
857
|
+
JOIN sys.objects o ON pr.object_id = o.object_id
|
|
858
|
+
JOIN sys.schemas s ON o.schema_id = s.schema_id
|
|
859
|
+
WHERE o.name = ${e}
|
|
860
|
+
AND s.name = ${r}
|
|
861
|
+
AND pr.parameter_id > 0
|
|
862
|
+
ORDER BY pr.parameter_id
|
|
863
|
+
`.execute(t)).rows.map(c=>({name:c.parameter_name.replace(/^@/,""),dataType:c.data_type,mode:"IN",ordinalPosition:c.ordinal_position})),a=o.func_type==="FN"?"scalar":o.func_type==="IF"?"inline table":"table";return{name:e,schema:r,parameters:s,returnType:a,definition:o.definition??void 0}},async getTypeDetail(t,e,r="dbo"){let o=(await ae`
|
|
864
|
+
SELECT
|
|
865
|
+
t.is_table_type,
|
|
866
|
+
TYPE_NAME(t.system_type_id) as base_type
|
|
867
|
+
FROM sys.types t
|
|
868
|
+
JOIN sys.schemas s ON t.schema_id = s.schema_id
|
|
869
|
+
WHERE t.name = ${e}
|
|
870
|
+
AND s.name = ${r}
|
|
871
|
+
AND t.is_user_defined = 1
|
|
872
|
+
`.execute(t)).rows[0];if(!o)return null;let i;return o.is_table_type&&(i=(await ae`
|
|
873
|
+
SELECT
|
|
874
|
+
c.name as column_name,
|
|
875
|
+
TYPE_NAME(c.user_type_id) as data_type,
|
|
876
|
+
c.is_nullable,
|
|
877
|
+
c.column_id as ordinal_position
|
|
878
|
+
FROM sys.table_types tt
|
|
879
|
+
JOIN sys.columns c ON tt.type_table_object_id = c.object_id
|
|
880
|
+
JOIN sys.schemas s ON tt.schema_id = s.schema_id
|
|
881
|
+
WHERE tt.name = ${e}
|
|
882
|
+
AND s.name = ${r}
|
|
883
|
+
ORDER BY c.column_id
|
|
884
|
+
`.execute(t)).rows.map(a=>({name:a.column_name,dataType:a.data_type,isNullable:a.is_nullable,isPrimaryKey:!1,ordinalPosition:a.ordinal_position}))),{name:e,schema:r,kind:o.is_table_type?"composite":"domain",attributes:i,baseType:o.base_type??void 0}},async listTriggers(t){let e=await ae`
|
|
885
|
+
SELECT
|
|
886
|
+
t.name AS trigger_name,
|
|
887
|
+
s.name AS schema_name,
|
|
888
|
+
OBJECT_NAME(t.parent_id) AS table_name,
|
|
889
|
+
t.is_instead_of_trigger,
|
|
890
|
+
t.is_disabled,
|
|
891
|
+
te.type_desc
|
|
892
|
+
FROM sys.triggers t
|
|
893
|
+
INNER JOIN sys.trigger_events te ON t.object_id = te.object_id
|
|
894
|
+
INNER JOIN sys.tables tab ON t.parent_id = tab.object_id
|
|
895
|
+
INNER JOIN sys.schemas s ON tab.schema_id = s.schema_id
|
|
896
|
+
WHERE s.name NOT IN (${ae.join(Wr)})
|
|
897
|
+
ORDER BY s.name, table_name, t.name
|
|
898
|
+
`.execute(t),r=new Map;for(let n of e.rows){let o=`${n.schema_name}.${n.trigger_name}`,i=n.type_desc,s=r.get(o);s?s.events.includes(i)||s.events.push(i):r.set(o,{name:n.trigger_name,schema:n.schema_name,tableName:n.table_name,tableSchema:n.schema_name,timing:n.is_instead_of_trigger?"INSTEAD OF":"AFTER",events:[i]})}return Array.from(r.values())},async listLocks(t){return(await ae`
|
|
899
|
+
SELECT
|
|
900
|
+
request_session_id,
|
|
901
|
+
resource_type,
|
|
902
|
+
resource_description,
|
|
903
|
+
request_mode,
|
|
904
|
+
request_status
|
|
905
|
+
FROM sys.dm_tran_locks
|
|
906
|
+
WHERE resource_database_id = DB_ID()
|
|
907
|
+
ORDER BY request_session_id
|
|
908
|
+
`.execute(t)).rows.map(r=>({pid:r.request_session_id,lockType:r.resource_type,objectName:r.resource_description||void 0,mode:r.request_mode,granted:r.request_status==="GRANT"}))},async listConnections(t){return(await ae`
|
|
909
|
+
SELECT
|
|
910
|
+
s.session_id,
|
|
911
|
+
s.login_name,
|
|
912
|
+
s.host_name,
|
|
913
|
+
s.program_name,
|
|
914
|
+
s.status,
|
|
915
|
+
s.login_time
|
|
916
|
+
FROM sys.dm_exec_sessions s
|
|
917
|
+
WHERE s.database_id = DB_ID()
|
|
918
|
+
AND s.session_id != @@SPID
|
|
919
|
+
ORDER BY s.login_time DESC
|
|
920
|
+
`.execute(t)).rows.map(r=>({pid:r.session_id,username:r.login_name,database:"current",applicationName:r.program_name||void 0,clientAddress:r.host_name||void 0,backendStart:r.login_time,state:r.status}))},async getTriggerDetail(t,e,r="dbo"){let n=await ae`
|
|
921
|
+
SELECT
|
|
922
|
+
t.name AS trigger_name,
|
|
923
|
+
OBJECT_NAME(t.parent_id) AS table_name,
|
|
924
|
+
t.is_instead_of_trigger,
|
|
925
|
+
t.is_disabled,
|
|
926
|
+
OBJECT_DEFINITION(t.object_id) AS definition,
|
|
927
|
+
te.type_desc
|
|
928
|
+
FROM sys.triggers t
|
|
929
|
+
INNER JOIN sys.trigger_events te ON t.object_id = te.object_id
|
|
930
|
+
INNER JOIN sys.tables tab ON t.parent_id = tab.object_id
|
|
931
|
+
INNER JOIN sys.schemas s ON tab.schema_id = s.schema_id
|
|
932
|
+
WHERE t.name = ${e}
|
|
933
|
+
AND s.name = ${r}
|
|
934
|
+
`.execute(t);if(n.rows.length===0)return null;let o=[...new Set(n.rows.map(s=>s.type_desc))],i=n.rows[0];return{name:i.trigger_name,schema:r,tableName:i.table_name,tableSchema:r,timing:i.is_instead_of_trigger?"INSTEAD OF":"AFTER",events:o,definition:i.definition,isEnabled:!i.is_disabled}}};import{sql as qe}from"kysely";var Zy={async getOverview(t){let[e,r,n]=await Promise.all([qe`
|
|
935
|
+
SELECT COUNT(*) as count
|
|
936
|
+
FROM sqlite_master
|
|
937
|
+
WHERE type = 'table'
|
|
938
|
+
AND name NOT LIKE 'sqlite_%'
|
|
939
|
+
`.execute(t),qe`
|
|
940
|
+
SELECT COUNT(*) as count
|
|
941
|
+
FROM sqlite_master
|
|
942
|
+
WHERE type = 'view'
|
|
943
|
+
`.execute(t),qe`
|
|
944
|
+
SELECT COUNT(*) as count
|
|
945
|
+
FROM sqlite_master
|
|
946
|
+
WHERE type = 'index'
|
|
947
|
+
AND name NOT LIKE 'sqlite_%'
|
|
948
|
+
`.execute(t)]),o=await qe`
|
|
949
|
+
SELECT name FROM sqlite_master WHERE type = 'table' AND name NOT LIKE 'sqlite_%'
|
|
950
|
+
`.execute(t),i=0;for(let s of o.rows){let a=await qe`
|
|
951
|
+
PRAGMA foreign_key_list(${qe.raw(`"${s.name}"`)})
|
|
952
|
+
`.execute(t),c=new Set(a.rows.map(l=>l.id));i+=c.size}return{tables:e.rows[0]?.count??0,views:r.rows[0]?.count??0,procedures:0,functions:0,types:0,indexes:n.rows[0]?.count??0,foreignKeys:i,triggers:0,locks:0,connections:0}},async listTables(t){let e=await qe`
|
|
953
|
+
SELECT name
|
|
954
|
+
FROM sqlite_master
|
|
955
|
+
WHERE type = 'table'
|
|
956
|
+
AND name NOT LIKE 'sqlite_%'
|
|
957
|
+
ORDER BY name
|
|
958
|
+
`.execute(t),r=[];for(let n of e.rows){let o=await qe`
|
|
959
|
+
PRAGMA table_info(${qe.raw(`"${n.name}"`)})
|
|
960
|
+
`.execute(t),i=await qe`
|
|
961
|
+
SELECT COUNT(*) as count FROM ${qe.raw(`"${n.name}"`)}
|
|
962
|
+
`.execute(t);r.push({name:n.name,columnCount:o.rows.length,rowCountEstimate:i.rows[0]?.count})}return r},async listViews(t){let e=await qe`
|
|
963
|
+
SELECT name
|
|
964
|
+
FROM sqlite_master
|
|
965
|
+
WHERE type = 'view'
|
|
966
|
+
ORDER BY name
|
|
967
|
+
`.execute(t),r=[];for(let n of e.rows){let o=await qe`
|
|
968
|
+
PRAGMA table_info(${qe.raw(`"${n.name}"`)})
|
|
969
|
+
`.execute(t);r.push({name:n.name,columnCount:o.rows.length,isUpdatable:!1})}return r},async listProcedures(t){return[]},async listFunctions(t){return[]},async listTypes(t){return[]},async listIndexes(t){let e=await qe`
|
|
970
|
+
SELECT name, tbl_name, sql
|
|
971
|
+
FROM sqlite_master
|
|
972
|
+
WHERE type = 'index'
|
|
973
|
+
AND name NOT LIKE 'sqlite_%'
|
|
974
|
+
ORDER BY tbl_name, name
|
|
975
|
+
`.execute(t),r=[];for(let n of e.rows){let i=(await qe`
|
|
976
|
+
PRAGMA index_info(${qe.raw(`"${n.name}"`)})
|
|
977
|
+
`.execute(t)).rows.map(c=>c.name),s=n.sql?.toUpperCase().includes("UNIQUE")??!1,a=n.name.startsWith("sqlite_autoindex_");r.push({name:n.name,tableName:n.tbl_name,columns:i,isUnique:s||a,isPrimary:a})}return r},async listForeignKeys(t){let e=await qe`
|
|
978
|
+
SELECT name FROM sqlite_master WHERE type = 'table' AND name NOT LIKE 'sqlite_%'
|
|
979
|
+
`.execute(t),r=[];for(let n of e.rows){let o=await qe`
|
|
980
|
+
PRAGMA foreign_key_list(${qe.raw(`"${n.name}"`)})
|
|
981
|
+
`.execute(t),i=new Map;for(let s of o.rows)if(!i.has(s.id))i.set(s.id,{name:`fk_${n.name}_${s.id}`,tableName:n.name,columns:[s.from],referencedTable:s.table,referencedColumns:[s.to],onUpdate:s.on_update,onDelete:s.on_delete});else{let a=i.get(s.id);a.columns.push(s.from),a.referencedColumns.push(s.to)}r.push(...i.values())}return r},async getTableDetail(t,e,r){if((await qe`
|
|
982
|
+
SELECT name FROM sqlite_master WHERE type = 'table' AND name = ${e}
|
|
983
|
+
`.execute(t)).rows.length===0)return null;let i=(await qe`
|
|
984
|
+
PRAGMA table_info(${qe.raw(`"${e}"`)})
|
|
985
|
+
`.execute(t)).rows.map(d=>({name:d.name,dataType:d.type||"ANY",isNullable:d.notnull===0,defaultValue:d.dflt_value??void 0,isPrimaryKey:d.pk>0,ordinalPosition:d.cid+1})),s=await qe`
|
|
986
|
+
SELECT COUNT(*) as count FROM ${qe.raw(`"${e}"`)}
|
|
987
|
+
`.execute(t),c=(await this.listIndexes(t)).filter(d=>d.tableName===e),m=(await this.listForeignKeys(t)).filter(d=>d.tableName===e);return{name:e,columns:i,indexes:c,foreignKeys:m,rowCountEstimate:s.rows[0]?.count}},async getViewDetail(t,e,r){let o=(await qe`
|
|
988
|
+
SELECT sql FROM sqlite_master WHERE type = 'view' AND name = ${e}
|
|
989
|
+
`.execute(t)).rows[0];if(!o)return null;let s=(await qe`
|
|
990
|
+
PRAGMA table_info(${qe.raw(`"${e}"`)})
|
|
991
|
+
`.execute(t)).rows.map(a=>({name:a.name,dataType:a.type||"ANY",isNullable:a.notnull===0,defaultValue:a.dflt_value??void 0,isPrimaryKey:!1,ordinalPosition:a.cid+1}));return{name:e,columns:s,definition:o.sql??void 0,isUpdatable:!1}},async getProcedureDetail(t,e,r){return null},async getFunctionDetail(t,e,r){return null},async getTypeDetail(t,e,r){return null},async listTriggers(t){return(await qe`
|
|
992
|
+
SELECT name, tbl_name, sql
|
|
993
|
+
FROM sqlite_master
|
|
994
|
+
WHERE type = 'trigger'
|
|
995
|
+
ORDER BY tbl_name, name
|
|
996
|
+
`.execute(t)).rows.map(r=>{let n=r.sql.toUpperCase(),o="AFTER";n.includes("BEFORE")?o="BEFORE":n.includes("INSTEAD OF")&&(o="INSTEAD OF");let i=[];return n.includes("INSERT")&&i.push("INSERT"),n.includes("UPDATE")&&i.push("UPDATE"),n.includes("DELETE")&&i.push("DELETE"),{name:r.name,tableName:r.tbl_name,timing:o,events:i.length>0?i:["INSERT"]}})},async listLocks(t){return[]},async listConnections(t){return[]},async getTriggerDetail(t,e){let r=await qe`
|
|
997
|
+
SELECT name, tbl_name, sql
|
|
998
|
+
FROM sqlite_master
|
|
999
|
+
WHERE type = 'trigger'
|
|
1000
|
+
AND name = ${e}
|
|
1001
|
+
`.execute(t);if(r.rows.length===0)return null;let n=r.rows[0],o=n.sql.toUpperCase(),i="AFTER";o.includes("BEFORE")?i="BEFORE":o.includes("INSTEAD OF")&&(i="INSTEAD OF");let s=[];return o.includes("INSERT")&&s.push("INSERT"),o.includes("UPDATE")&&s.push("UPDATE"),o.includes("DELETE")&&s.push("DELETE"),{name:n.name,tableName:n.tbl_name,timing:i,events:s.length>0?s:["INSERT"],definition:n.sql,isEnabled:!0}}};var cT={postgres:zy,mysql:Jy,mssql:Qy,sqlite:Zy};function sc(t){return cT[t]}function bi(t){return t?.startsWith("__noorm_")??!1}async function ac(t,e,r={}){let n=sc(e);if(!r.includeNoormTables){let[s,a,c,l,m,d,u,p,g,h]=await Promise.all([n.listTables(t),n.listViews(t),n.listProcedures(t),n.listFunctions(t),n.listTypes(t),n.listIndexes(t),n.listForeignKeys(t),n.listTriggers(t),n.listLocks(t),n.listConnections(t)]);return{tables:s.filter(f=>!bi(f.name)).length,views:a.length,procedures:c.length,functions:l.length,types:m.length,indexes:d.filter(f=>!bi(f.tableName)).length,foreignKeys:u.filter(f=>!bi(f.tableName)).length,triggers:p.filter(f=>!bi(f.tableName)).length,locks:g.length,connections:h.length}}let[o,i]=await ad(()=>n.getOverview(t));if(i)throw k.emit("error",{source:"explore",error:i}),i;return o}async function Gr(t,e,r,n={}){let o=sc(e),i={tables:()=>o.listTables(t),views:()=>o.listViews(t),procedures:()=>o.listProcedures(t),functions:()=>o.listFunctions(t),types:()=>o.listTypes(t),indexes:()=>o.listIndexes(t),foreignKeys:()=>o.listForeignKeys(t),triggers:()=>o.listTriggers(t),locks:()=>o.listLocks(t),connections:()=>o.listConnections(t)},[s,a]=await ad(()=>i[r]());if(a)throw k.emit("error",{source:"explore",error:a}),a;if(!n.includeNoormTables){if(r==="tables")return s.filter(c=>!bi(c.name));if(r==="indexes")return s.filter(c=>!bi(c.tableName));if(r==="foreignKeys")return s.filter(c=>!bi(c.tableName));if(r==="triggers")return s.filter(c=>!bi(c.tableName))}return s}async function cc(t,e,r,n,o){let i=sc(e),s={tables:()=>i.getTableDetail(t,n,o),views:()=>i.getViewDetail(t,n,o),procedures:()=>i.getProcedureDetail(t,n,o),functions:()=>i.getFunctionDetail(t,n,o),types:()=>i.getTypeDetail(t,n,o),triggers:()=>i.getTriggerDetail(t,n,o)},[a,c]=await ad(()=>s[r]());if(c)throw k.emit("error",{source:"explore",error:c}),c;return a}function cd(t,e){switch(t){case"tables":{let r=e,n=[`${r.columnCount} columns`];return r.rowCountEstimate!==void 0&&n.push(`~${lT(r.rowCountEstimate)} rows`),n.join(", ")}case"views":{let r=e;return`${r.columnCount} columns${r.isUpdatable?", updatable":""}`}case"procedures":return`${e.parameterCount} parameters`;case"functions":{let r=e;return`${r.parameterCount} params \u2192 ${r.returnType}`}case"types":{let r=e;return r.kind==="enum"&&r.valueCount!==void 0?`enum (${r.valueCount} values)`:r.kind}case"indexes":{let r=e,n=[`on ${r.tableName}`];return r.isPrimary?n.push("PRIMARY"):r.isUnique&&n.push("UNIQUE"),n.join(", ")}case"foreignKeys":{let r=e;return`${r.tableName} \u2192 ${r.referencedTable}`}case"triggers":{let r=e;return`${r.timing} ${r.events.join("/")} on ${r.tableName}`}case"locks":{let r=e;return`${r.lockType} ${r.mode}${r.objectName?` on ${r.objectName}`:""}${r.granted?"":" (waiting)"}`}case"connections":{let r=e;return`${r.username}@${r.database} (${r.state})`}default:return""}}function lT(t){return t>=1e6?`${(t/1e6).toFixed(1)}M`:t>=1e3?`${(t/1e3).toFixed(1)}K`:t.toString()}function Il(t){return`"${t.replace(/"/g,'""')}"`}function ss(t,e){return e&&e!=="public"?`${Il(e)}.${Il(t)}`:Il(t)}var ld={disableForeignKeyChecks(){return"SET session_replication_role = 'replica'"},enableForeignKeyChecks(){return"SET session_replication_role = 'origin'"},truncateTable(t,e,r=!0){return`TRUNCATE TABLE ${ss(t,e)}${r?" RESTART IDENTITY":""} CASCADE`},dropTable(t,e){return`DROP TABLE IF EXISTS ${ss(t,e)} CASCADE`},dropView(t,e){return`DROP VIEW IF EXISTS ${ss(t,e)} CASCADE`},dropFunction(t,e){return`DROP FUNCTION IF EXISTS ${ss(t,e)} CASCADE`},dropProcedure(t,e){return`DROP PROCEDURE IF EXISTS ${ss(t,e)} CASCADE`},dropType(t,e){return`DROP TYPE IF EXISTS ${ss(t,e)} CASCADE`},dropForeignKey(t,e,r){return`ALTER TABLE ${ss(e,r)} DROP CONSTRAINT IF EXISTS ${Il(t)}`}};function Ol(t){return`\`${t.replace(/`/g,"``")}\``}function zs(t,e){return e?`${Ol(e)}.${Ol(t)}`:Ol(t)}var ud={disableForeignKeyChecks(){return"SET FOREIGN_KEY_CHECKS = 0"},enableForeignKeyChecks(){return"SET FOREIGN_KEY_CHECKS = 1"},truncateTable(t,e,r=!0){return`TRUNCATE TABLE ${zs(t,e)}`},dropTable(t,e){return`DROP TABLE IF EXISTS ${zs(t,e)}`},dropView(t,e){return`DROP VIEW IF EXISTS ${zs(t,e)}`},dropFunction(t,e){return`DROP FUNCTION IF EXISTS ${zs(t,e)}`},dropProcedure(t,e){return`DROP PROCEDURE IF EXISTS ${zs(t,e)}`},dropType(t,e){return"-- MySQL does not support custom types"},dropForeignKey(t,e,r){return`ALTER TABLE ${zs(e,r)} DROP FOREIGN KEY ${Ol(t)}`}};function Al(t){return`[${t.replace(/\]/g,"]]")}]`}function as(t,e){return e&&e!=="dbo"?`${Al(e)}.${Al(t)}`:Al(t)}var md={disableForeignKeyChecks(){return"EXEC sp_MSforeachtable 'ALTER TABLE ? NOCHECK CONSTRAINT ALL'"},enableForeignKeyChecks(){return"EXEC sp_MSforeachtable 'ALTER TABLE ? CHECK CONSTRAINT ALL'"},truncateTable(t,e,r=!0){let o=`DELETE FROM ${as(t,e)}`;if(r){let i=e&&e!=="dbo"?`${e}.${t}`:t;return`${o}; IF EXISTS (SELECT * FROM sys.identity_columns WHERE OBJECT_NAME(object_id) = '${t}') DBCC CHECKIDENT ('${i}', RESEED, 0)`}return o},dropTable(t,e){return`DROP TABLE IF EXISTS ${as(t,e)}`},dropView(t,e){return`DROP VIEW IF EXISTS ${as(t,e)}`},dropFunction(t,e){return`DROP FUNCTION IF EXISTS ${as(t,e)}`},dropProcedure(t,e){return`DROP PROCEDURE IF EXISTS ${as(t,e)}`},dropType(t,e){return`DROP TYPE IF EXISTS ${as(t,e)}`},dropForeignKey(t,e,r){return`ALTER TABLE ${as(e,r)} DROP CONSTRAINT ${Al(t)}`}};function dd(t){return`"${t.replace(/"/g,'""')}"`}var pd={disableForeignKeyChecks(){return"PRAGMA foreign_keys = OFF"},enableForeignKeyChecks(){return"PRAGMA foreign_keys = ON"},truncateTable(t,e,r=!1){return`DELETE FROM ${dd(t)}`},dropTable(t,e){return`DROP TABLE IF EXISTS ${dd(t)}`},dropView(t,e){return`DROP VIEW IF EXISTS ${dd(t)}`},dropFunction(t,e){return"-- SQLite does not support user-defined functions"},dropProcedure(t,e){return"-- SQLite does not support stored procedures"},dropType(t,e){return"-- SQLite does not support custom types"},dropForeignKey(t,e,r){return"-- SQLite does not support dropping individual FK constraints"}};function lc(t){switch(t){case"postgres":return ld;case"mysql":return ud;case"mssql":return md;case"sqlite":return pd;default:{let e=t;throw new Error(`Unknown dialect: ${e}`)}}}var fd={force:!1,dryRun:!1,preview:!1,output:null},eh={...fd,abortOnError:!0},ln=class extends Error{constructor(r,n){super(`Invalid change '${r}': ${n}`);this.changeName=r;this.issue=n}name="ChangeValidationError"},Si=class extends Error{constructor(r){super(`Change not found: ${r}`);this.changeName=r}name="ChangeNotFoundError"};var Js=class extends Error{constructor(r){super(`Cannot revert '${r}': not applied`);this.changeName=r}name="ChangeNotAppliedError"},Qs=class extends Error{constructor(r){super(`Change '${r}' is orphaned (folder deleted from disk)`);this.changeName=r}name="ChangeOrphanedError"},Zs=class extends Error{constructor(r,n){super(`Manifest '${r}' references missing file: ${n}`);this.manifestPath=r;this.missingPath=n}name="ManifestReferenceError"};import Wn from"path";import{readdir as oh,readFile as uT,stat as ih,access as sh}from"fs/promises";import{constants as ah}from"fs";import{attempt as po}from"@logosdx/utils";var mT=[".sql",".sql.tmpl"],dT=".txt",pT=/^(\d{4}-\d{2}-\d{2})-(.+)$/,fT=/^(\d{3})_(.+)$/;async function ea(t,e){let[r,n]=await po(()=>ih(t));if(n||!r?.isDirectory())throw new Si(Wn.basename(t));let o=Wn.basename(t),{date:i,description:s}=gT(o),a=Wn.join(t,"change"),[c,l]=await po(()=>th(a,e));if(l&&!rh(l))throw l;let m=Wn.join(t,"revert"),[d,u]=await po(()=>th(m,e));if(u&&!rh(u))throw u;let p=Wn.join(t,"changelog.md"),g=await hT(p);if((!c||c.length===0)&&(!d||d.length===0))throw new ln(o,"Must have at least change/ or revert/ folder with files");return{name:o,path:t,date:i,description:s,changeFiles:c??[],revertFiles:d??[],hasChangelog:g}}async function At(t,e){let[r]=await po(()=>ih(t));if(!r)return[];let[n,o]=await po(()=>oh(t,{withFileTypes:!0}));if(o)return k.emit("error",{source:"change",error:o,context:{changesDir:t,operation:"discover"}}),[];let i=n.filter(a=>a.isDirectory()),s=[];for(let a of i){let c=Wn.join(t,a.name),[l,m]=await po(()=>ea(c,e));if(m){k.emit("error",{source:"change",error:m,context:{folder:a.name,operation:"parse"}});continue}s.push(l)}return s.sort((a,c)=>a.name.localeCompare(c.name))}async function ta(t,e){let[r,n]=await po(()=>uT(t,"utf-8"));if(n)throw new Error(`Failed to read manifest: ${t}`,{cause:n});let o=r.split(`
|
|
1002
|
+
`).map(s=>s.trim()).filter(s=>s&&!s.startsWith("#"));if(o.length===0)throw new ln(Wn.basename(Wn.dirname(Wn.dirname(t))),`Empty manifest file: ${Wn.basename(t)}`);let i=[];for(let s of o){let a=Wn.join(e,s),[c]=await po(()=>sh(a,ah.R_OK));if(c===void 0)i.push(a);else throw new Zs(t,s)}return i.sort()}function Ml(t){let e=t.changeFiles.map(i=>i.filename),r=nh(e);if(r.length>0)throw new ln(t.name,`Duplicate files in change/: ${r.join(", ")}`);let n=t.revertFiles.map(i=>i.filename),o=nh(n);if(o.length>0)throw new ln(t.name,`Duplicate files in revert/: ${o.join(", ")}`)}function $l(t){return t.revertFiles.length>0}function gT(t){let e=t.match(pT);if(e&&e[1]&&e[2]){let r=e[1],n=e[2],o=new Date(r);if(!isNaN(o.getTime()))return{date:o,description:n}}return{date:null,description:t}}async function th(t,e){let[r,n]=await po(()=>oh(t,{withFileTypes:!0}));if(n)throw n;let o=[];for(let i of r){if(!i.isFile())continue;let s=i.name,a=Wn.join(t,s),c=yT(s);if(!c)continue;let l={filename:s,path:a,type:c};if(c==="txt"&&e){let[m,d]=await po(()=>ta(a,e));if(d)throw d;l.resolvedPaths=m}o.push(l)}return o.sort((i,s)=>i.filename.localeCompare(s.filename))}function yT(t){if(t.endsWith(dT))return"txt";for(let e of mT)if(t.endsWith(e))return"sql";return null}async function hT(t){let[,e]=await po(()=>sh(t,ah.R_OK));return e===null}function rh(t){return t.code==="ENOENT"}function nh(t){let e=new Set,r=new Set;for(let n of t)e.has(n)&&r.add(n),e.add(n);return Array.from(r)}function jl(t){let e=t.match(fT);return e&&e[1]?parseInt(e[1],10):null}import ra from"path";import{mkdir as gd,writeFile as lh,rename as AO,unlink as MO,rm as xT,stat as bT}from"fs/promises";import{attempt as Hl}from"@logosdx/utils";var ST=`-- TODO: Add SQL statements here
|
|
1003
|
+
`,CT=`# Changelog
|
|
1004
|
+
|
|
1005
|
+
## Description
|
|
1006
|
+
|
|
1007
|
+
TODO: Describe the purpose of this change.
|
|
1008
|
+
|
|
1009
|
+
## Changes
|
|
1010
|
+
|
|
1011
|
+
- TODO: List changes
|
|
1012
|
+
|
|
1013
|
+
## Impact
|
|
1014
|
+
|
|
1015
|
+
TODO: Describe any impact on existing data or functionality.
|
|
1016
|
+
`;async function ql(t,e){let r=e.date??new Date,n=wT(r),o=uh(e.description),i=`${n}-${o}`,s=ra.join(t,i),[a]=await Hl(()=>bT(s));if(a)throw new Error(`Change already exists: ${i}`);let[,c]=await Hl(()=>gd(s,{recursive:!0}));if(c)throw new Error(`Failed to create change directory: ${s}`,{cause:c});let l=ra.join(s,"change"),m=ra.join(s,"revert");await gd(l,{recursive:!0}),await gd(m,{recursive:!0});let d=ra.join(s,"changelog.md");return await lh(d,CT,"utf-8"),k.emit("change:created",{name:i,path:s}),{name:i,path:s,date:r,description:o,changeFiles:[],revertFiles:[],hasChangelog:!0}}async function uc(t,e,r){let n=e==="change"?t.changeFiles:t.revertFiles,i=ET(n)+1,s=uh(r.name),a=r.type==="txt"?".txt":".sql",c=`${TT(i)}_${s}${a}`,l=ra.join(t.path,e),m=ra.join(l,c),d;r.content?d=r.content:r.type==="txt"&&r.paths?d=r.paths.join(`
|
|
1017
|
+
`)+`
|
|
1018
|
+
`:d=ST;let[,u]=await Hl(()=>lh(m,d,"utf-8"));if(u)throw new Error(`Failed to create file: ${m}`,{cause:u});let p={filename:c,path:m,type:r.type};r.type==="txt"&&r.paths&&(p.resolvedPaths=r.paths);let g=[...n,p].sort((h,f)=>h.filename.localeCompare(f.filename));return e==="change"?{...t,changeFiles:g}:{...t,revertFiles:g}}async function na(t){let[,e]=await Hl(()=>xT(t.path,{recursive:!0,force:!0}));if(e)throw new Error(`Failed to delete change: ${t.path}`,{cause:e})}function wT(t){let e=t.getFullYear(),r=String(t.getMonth()+1).padStart(2,"0"),n=String(t.getDate()).padStart(2,"0");return`${e}-${r}-${n}`}function uh(t){return t.toLowerCase().trim().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")}function TT(t){return String(t).padStart(3,"0")}function ET(t){let e=0;for(let r of t){let n=jl(r.filename);n!==null&&n>e&&(e=n)}return e}import{sql as RT}from"kysely";import{attempt as ar}from"@logosdx/utils";var Oe=class{#t;#e;constructor(e,r){this.#t=e,this.#e=r}async getStatus(e){let[r,n]=await ar(()=>this.#t.selectFrom(G.change).select(["name","status","executed_at","executed_by","error_message","checksum"]).where("name","=",e).where("change_type","=","change").where("direction","=","change").where("config_name","=",this.#e).orderBy("id","desc").limit(1).executeTakeFirst());if(n)return k.emit("error",{source:"change",error:n,context:{name:e,operation:"get-status"}}),null;if(!r)return null;let[o]=await ar(()=>this.#t.selectFrom(G.change).select(["executed_at"]).where("name","=",e).where("change_type","=","change").where("direction","=","revert").where("status","=","success").where("config_name","=",this.#e).orderBy("id","desc").limit(1).executeTakeFirst());return{name:r.name,status:r.status,appliedAt:r.executed_at,appliedBy:r.executed_by,revertedAt:o?.executed_at??null,errorMessage:r.error_message||null}}async getAllStatuses(){let e=new Map,[r,n]=await ar(()=>this.#t.selectFrom(G.change).select(["id","name","status","executed_at","executed_by","error_message"]).where("change_type","=","change").where("direction","=","change").where("config_name","=",this.#e).orderBy("id","desc").execute());if(n)return k.emit("error",{source:"change",error:n,context:{operation:"get-all-statuses"}}),e;for(let i of r)e.has(i.name)||e.set(i.name,{name:i.name,status:i.status,appliedAt:i.executed_at,appliedBy:i.executed_by,revertedAt:null,errorMessage:i.error_message||null});let[o]=await ar(()=>this.#t.selectFrom(G.change).select(["name","executed_at"]).where("change_type","=","change").where("direction","=","revert").where("status","=","success").where("config_name","=",this.#e).orderBy("id","desc").execute());if(o){let i=new Set;for(let s of o)if(!i.has(s.name)&&e.has(s.name)){let a=e.get(s.name);a.revertedAt=s.executed_at,i.add(s.name)}}return e}async needsRun(e,r,n){if(n)return{needsRun:!0,reason:"force"};let[o,i]=await ar(()=>this.#t.selectFrom(G.change).select(["status","checksum"]).where("name","=",e).where("change_type","=","change").where("direction","=","change").where("config_name","=",this.#e).orderBy("id","desc").limit(1).executeTakeFirst());return i?(k.emit("error",{source:"change",error:i,context:{name:e,operation:"needs-run-check"}}),{needsRun:!0,reason:"new"}):o?o.status==="failed"?{needsRun:!0,reason:"failed",previousChecksum:o.checksum,previousStatus:o.status}:o.status==="reverted"?{needsRun:!0,reason:"reverted",previousChecksum:o.checksum,previousStatus:o.status}:o.status==="stale"?{needsRun:!0,reason:"stale",previousChecksum:o.checksum,previousStatus:o.status}:o.checksum!==r?{needsRun:!0,reason:"changed",previousChecksum:o.checksum,previousStatus:o.status}:{needsRun:!1,skipReason:"already applied",previousChecksum:o.checksum,previousStatus:o.status}:{needsRun:!0,reason:"new"}}async createOperation(e){let[r,n]=await ar(()=>this.#t.insertInto(G.change).values({name:e.name,change_type:"change",direction:e.direction,status:"pending",config_name:this.#e,executed_by:e.executedBy}).returning("id").executeTakeFirstOrThrow());if(n)throw new Error("Failed to create change operation record",{cause:n});let o=r?.id;if(o==null){let[i,s]=await ar(()=>RT`SELECT last_insert_rowid() as id`.execute(this.#t));if(s||!i?.rows?.[0]?.id)throw new Error("Failed to retrieve last insert row id");o=i.rows[0].id}if(typeof o!="number"||!Number.isFinite(o)||o<=0)throw new Error(`Invalid operation ID returned: ${o}`);return o}async createFileRecords(e,r){if(r.length===0)return null;let n=r.map(i=>({change_id:e,filepath:i.filepath,file_type:i.fileType,checksum:i.checksum,status:"pending"})),[,o]=await ar(()=>this.#t.insertInto(G.executions).values(n).execute());if(o){let i=o instanceof Error?o.message:String(o);return k.emit("error",{source:"change",error:o,context:{operationId:e,operation:"create-file-records"}}),`Failed to create file records: ${i}`}return null}async updateFileExecution(e,r,n,o,i,s){let[a,c]=await ar(()=>this.#t.updateTable(G.executions).set({status:n,duration_ms:Math.round(o),error_message:i??"",skip_reason:s??""}).where("change_id","=",e).where("filepath","=",r).executeTakeFirst());if(c){let m=c instanceof Error?c.message:String(c);return k.emit("error",{source:"change",error:c,context:{filepath:r,operation:"update-file-execution"}}),`Failed to update file execution ${r}: ${m}`}if(Number(a?.numUpdatedRows??0)===0){let m=`No execution record found for ${r} (operationId: ${e})`;return k.emit("error",{source:"change",error:new Error(m),context:{operationId:e,filepath:r,operation:"update-file-execution"}}),m}return null}async skipRemainingFiles(e,r){let[,n]=await ar(()=>this.#t.updateTable(G.executions).set({status:"skipped",skip_reason:r}).where("change_id","=",e).where("status","=","pending").execute());return n?(k.emit("error",{source:"change",error:n,context:{operationId:e,operation:"skip-remaining-files"}}),`Failed to skip remaining files: ${n instanceof Error?n.message:String(n)}`):null}async finalizeOperation(e,r,n,o,i){let s=i?i.slice(0,2e3):"",[a,c]=await ar(()=>this.#t.updateTable(G.change).set({status:r,checksum:n,duration_ms:Math.round(o),error_message:s}).where("id","=",e).executeTakeFirst());if(c){let m=c instanceof Error?c.message:String(c);return k.emit("error",{source:"change",error:c,context:{operationId:e,operation:"finalize-operation"}}),`Failed to finalize operation ${e}: ${m}`}if(Number(a?.numUpdatedRows??0)===0){let m=`No operation record found with id ${e}`;return k.emit("error",{source:"change",error:new Error(m),context:{operationId:e,operation:"finalize-operation"}}),m}return null}async recordReset(e,r){let[n,o]=await ar(()=>this.#t.insertInto(G.change).values({name:"__reset__",change_type:"change",direction:"change",status:"success",config_name:this.#e,executed_by:e,error_message:r??"",duration_ms:0,checksum:""}).returning("id").executeTakeFirstOrThrow());return o?(k.emit("error",{source:"change",error:o,context:{operation:"record-reset"}}),0):n.id}async deleteRecords(e){let[r,n]=await ar(()=>this.#t.selectFrom(G.change).select(["id"]).where("name","=",e).where("change_type","=","change").where("config_name","=",this.#e).execute());if(n||!r||r.length===0)return;let o=r.map(a=>a.id),[,i]=await ar(()=>this.#t.deleteFrom(G.executions).where("change_id","in",o).execute());i&&k.emit("error",{source:"change",error:i,context:{name:e,operation:"delete-executions"}});let[,s]=await ar(()=>this.#t.deleteFrom(G.change).where("id","in",o).execute());s&&k.emit("error",{source:"change",error:s,context:{name:e,operation:"delete-change"}})}async getHistory(e,r){let n=this.#t.selectFrom(G.change).select(["id","name","direction","status","executed_at","executed_by","duration_ms","error_message","checksum"]).where("change_type","=","change").where("config_name","=",this.#e).orderBy("id","desc");e&&(n=n.where("name","=",e)),r&&(n=n.limit(r));let[o,i]=await ar(()=>n.execute());return i?(k.emit("error",{source:"change",error:i,context:{name:e,operation:"get-history"}}),[]):o.map(s=>({id:s.id,name:s.name,direction:s.direction,status:s.status,executedAt:s.executed_at,executedBy:s.executed_by,durationMs:s.duration_ms,errorMessage:s.error_message||null,checksum:s.checksum}))}async getUnifiedHistory(e,r){let n=this.#t.selectFrom(G.change).select(["id","name","change_type","direction","status","executed_at","executed_by","duration_ms","error_message","checksum"]).where("config_name","=",this.#e).orderBy("id","desc");e&&e.length>0&&(n=n.where("change_type","in",e)),r&&(n=n.limit(r));let[o,i]=await ar(()=>n.execute());return i?(k.emit("error",{source:"change",error:i,context:{operation:"get-unified-history"}}),[]):o.map(s=>({id:s.id,name:s.name,changeType:s.change_type,direction:s.direction,status:s.status,executedAt:s.executed_at,executedBy:s.executed_by,durationMs:s.duration_ms,errorMessage:s.error_message||null,checksum:s.checksum}))}async getBuildRunHistory(e){return this.getUnifiedHistory(["build","run"],e)}async getFileHistory(e){let[r,n]=await ar(()=>this.#t.selectFrom(G.executions).select(["id","change_id","filepath","file_type","checksum","status","skip_reason","error_message","duration_ms"]).where("change_id","=",e).orderBy("id","asc").execute());return n?(k.emit("error",{source:"change",error:n,context:{operationId:e,operation:"get-file-history"}}),[]):r.map(o=>({id:o.id,changeId:o.change_id,filepath:o.filepath,fileType:o.file_type,checksum:o.checksum,status:o.status,skipReason:o.skip_reason||null,errorMessage:o.error_message||null,durationMs:o.duration_ms}))}async getOrphaned(e){let r=await this.getAllStatuses(),n=[];for(let[o]of r)e.has(o)||n.push(o);return n}};import{attempt as Kl}from"@logosdx/utils";var cs=class extends Vo{#t;#e;constructor(e,r){super(e,r),this.#t=e,this.#e=r}async canRevert(e,r){let[n,o]=await Kl(()=>this.#t.selectFrom(G.change).select(["status"]).where("name","=",e).where("change_type","=","change").where("direction","=","change").where("config_name","=",this.#e).orderBy("id","desc").limit(1).executeTakeFirst());if(o)return k.emit("error",{source:"change",error:o,context:{name:e,operation:"can-revert"}}),{canRevert:!1,reason:"database error"};if(!n)return{canRevert:!1,reason:"not applied"};if(r)return{canRevert:!0,status:n.status};switch(n.status){case"pending":return{canRevert:!1,reason:"not applied yet",status:n.status};case"success":return{canRevert:!0,status:n.status};case"failed":return{canRevert:!0,status:n.status};case"reverted":return{canRevert:!1,reason:"already reverted",status:n.status};case"stale":return{canRevert:!1,reason:"schema was torn down",status:n.status};default:return{canRevert:!1,reason:"unknown status"}}}async markAsReverted(e){let[r]=await Kl(()=>this.#t.selectFrom(G.change).select(["id"]).where("name","=",e).where("change_type","=","change").where("direction","=","change").where("config_name","=",this.#e).orderBy("id","desc").limit(1).executeTakeFirst());r&&await Kl(()=>this.#t.updateTable(G.change).set({status:"reverted"}).where("id","=",r.id).execute())}async markAllAsStale(){let[e,r]=await Kl(()=>this.#t.updateTable(G.change).set({status:"stale"}).where("direction","=","change").where("status","in",["success","failed","pending"]).where("config_name","=",this.#e).execute());return r?(k.emit("error",{source:"change",error:r,context:{operation:"mark-all-stale"}}),0):e.reduce((n,o)=>n+Number(o.numUpdatedRows??0),0)}};import ls from"path";import{readFile as mh,writeFile as kT,mkdir as _T}from"fs/promises";import{sql as vT}from"kysely";import{attempt as Ht,attemptSync as DT}from"@logosdx/utils";var dh={force:!1,dryRun:!1,preview:!1,output:null},PT="-- TODO: Add SQL statements here";async function Ci(t,e,r={}){let n=performance.now(),o={...dh,...r},[,i]=DT(()=>{Ml(e)});if(i)return k.emit("error",{source:"change",error:i,context:{name:e.name,operation:"validate"}}),Vl(e.name,"change",i.message,n);let s=e.changeFiles;if(s.length===0)throw new ln(e.name,"No files in change/ folder");let[a,c]=await Ht(()=>FT(s));if(c||!a)throw new ln(e.name,"Files are empty or contain only template placeholders. Edit the SQL files before running.");let[l,m]=await Ht(()=>gh(s,t.sqlDir));if(m)return Vl(e.name,"change",m.message,n);let d=ns(l),u=new Oe(t.db,t.configName);if(!o.dryRun&&!o.preview){let S=await u.needsRun(e.name,d,o.force);if(!S.needsRun)return k.emit("change:skip",{name:e.name,reason:S.skipReason??"already applied"}),{name:e.name,direction:"change",status:"success",files:[],durationMs:performance.now()-n}}if(o.dryRun)return yh(t,e,s,"change",n);if(o.preview)return fh(t,e,s,"change",o.output,n);let p=mt(),g=Ft(t.identity),[,h]=await Ht(()=>p.acquire(t.db,t.configName,g,{reason:`Change: ${e.name}`,dialect:t.dialect}));if(h)throw h;let[f,w]=await Ht(()=>ph(t,e,s,"change",d,u,n));if(await Ht(()=>p.release(t.db,t.configName,g)),w)throw w;return f}async function wi(t,e,r={}){let n=performance.now(),o={...dh,...r};if(!$l(e))throw new ln(e.name,"No revert files (revert/ folder is empty or missing)");let i=e.revertFiles,[s,a]=await Ht(()=>gh(i,t.sqlDir));if(a)return Vl(e.name,"revert",a.message,n);let c=ns(s),l=new Oe(t.db,t.configName),m=new cs(t.db,t.configName);if(!o.dryRun&&!o.preview){let f=await m.canRevert(e.name,o.force);if(!f.canRevert){if(f.reason==="not applied")throw new Js(e.name);return k.emit("change:skip",{name:e.name,reason:f.reason??"cannot revert"}),{name:e.name,direction:"revert",status:"success",files:[],durationMs:performance.now()-n}}}if(o.dryRun)return yh(t,e,i,"revert",n);if(o.preview)return fh(t,e,i,"revert",o.output,n);let d=mt(),u=Ft(t.identity),[,p]=await Ht(()=>d.acquire(t.db,t.configName,u,{reason:`Revert: ${e.name}`,dialect:t.dialect}));if(p)throw p;let[g,h]=await Ht(()=>ph(t,e,i,"revert",c,l,n));if(await Ht(()=>d.release(t.db,t.configName,u)),h)throw h;return g.status==="success"&&await m.markAsReverted(e.name),g}async function ph(t,e,r,n,o,i,s){let a=await yd(r,t.sqlDir),[c,l]=await Ht(()=>i.createOperation({name:e.name,direction:n,executedBy:Ft(t.identity)}));if(l)return k.emit("error",{source:"change",error:l,context:{name:e.name,operation:"create-operation"}}),Vl(e.name,n,l.message,s);let m=new Map;for(let C of a){let[b]=await Ht(()=>cn(C.path));m.set(C.path,b??"")}let d=await i.createFileRecords(c,a.map(C=>({filepath:C.path,fileType:C.type,checksum:m.get(C.path)??""})));if(d)return await i.finalizeOperation(c,"failed",o,0,d),{name:e.name,direction:n,status:"failed",files:[],durationMs:performance.now()-s,error:d,operationId:c};k.emit("change:start",{name:e.name,direction:n,files:a.map(C=>C.path)});let u=[],p=!1,g,h,[,f]=await Ht(async()=>{for(let C=0;C<a.length;C++){let b=a[C];if(!b)continue;k.emit("change:file",{change:e.name,filepath:b.path,index:C,total:a.length});let v=performance.now(),[P,_]=await Ht(()=>hd(t,b.path));if(_){let D=performance.now()-v;p=!0,g=b.path,h=_.message,u.push({filepath:b.path,checksum:m.get(b.path)??"",status:"failed",error:_.message,durationMs:D});let F=await i.updateFileExecution(c,b.path,"failed",D,_.message);F&&k.emit("error",{source:"change",error:new Error(F),context:{filepath:b.path,operation:"update-failed-record"}});break}let[,O]=await Ht(()=>vT.raw(P).execute(t.db)),N=performance.now()-v;if(O){p=!0,g=b.path,h=O.message,u.push({filepath:b.path,checksum:m.get(b.path)??"",status:"failed",error:O.message,durationMs:N});let D=await i.updateFileExecution(c,b.path,"failed",N,O.message);D&&k.emit("error",{source:"change",error:new Error(D),context:{filepath:b.path,operation:"update-failed-record"}});break}u.push({filepath:b.path,checksum:m.get(b.path)??"",status:"success",durationMs:N});let B=await i.updateFileExecution(c,b.path,"success",N);B&&k.emit("error",{source:"change",error:new Error(B),context:{filepath:b.path,operation:"update-success-record"}})}});if(f&&(p||(p=!0,h=f.message),k.emit("error",{source:"change",error:f,context:{name:e.name,operation:"execute-files"}})),p){let C=g?`${ls.basename(g)} failed: ${h??"unknown error"}`:"change failed",b=await i.skipRemainingFiles(c,C);b&&k.emit("error",{source:"change",error:new Error(b),context:{operationId:c,operation:"skip-remaining-files"}})}let w=performance.now()-s,S=p?"failed":"success",E=g?`${ls.basename(g)}: ${h??"unknown error"}`:h,T=await i.finalizeOperation(c,S,o,w,p?E:void 0),R=T?"failed":S,x=T?`${E??"Execution succeeded but finalization failed"}. Additionally: ${T}`:E;return k.emit("change:complete",{name:e.name,direction:n,status:R,durationMs:w}),{name:e.name,direction:n,status:R,files:u,durationMs:w,error:R==="failed"?x:void 0,operationId:c}}async function fh(t,e,r,n,o,i){let s=await yd(r,t.sqlDir),a=[],c=[];for(let l of s){let m=performance.now(),[d]=await Ht(()=>cn(l.path)),[u,p]=await Ht(()=>hd(t,l.path));if(p){a.push({filepath:l.path,checksum:d??"",status:"failed",error:p.message,durationMs:performance.now()-m});continue}c.push(NT(l.path)+u),a.push({filepath:l.path,checksum:d??"",status:"success",durationMs:performance.now()-m,renderedSql:u})}if(o){let{writeFile:l}=await import("fs/promises"),m=c.join(`
|
|
1019
|
+
|
|
1020
|
+
`);await l(o,m,"utf-8")}return{name:e.name,direction:n,status:a.every(l=>l.status==="success")?"success":"failed",files:a,durationMs:performance.now()-i}}async function yd(t,e){let r=[];for(let n of t)if(n.type==="txt")if(n.resolvedPaths)for(let o of n.resolvedPaths)r.push({filename:ls.basename(o),path:o,type:"sql"});else{let o=await ta(n.path,e);for(let i of o)r.push({filename:ls.basename(i),path:i,type:"sql"})}else r.push(n);return r}async function gh(t,e){let r=[];for(let n of t){let o=await cn(n.path);if(r.push(o),n.type==="txt"){let i=n.resolvedPaths??await ta(n.path,e);for(let s of i){let a=await cn(s);r.push(a)}}}return r}function NT(t){return`-- ============================================================
|
|
1021
|
+
-- File: ${t}
|
|
1022
|
+
-- ============================================================
|
|
1023
|
+
|
|
1024
|
+
`}async function FT(t){for(let e of t){if(e.type==="txt")return!0;let[r,n]=await Ht(()=>mh(e.path,"utf-8"));if(n)continue;let o=r?.trim()??"";if(o&&o!==PT)return!0}return!1}function Vl(t,e,r,n){return{name:t,direction:e,status:"failed",files:[],durationMs:performance.now()-n,error:r}}async function yh(t,e,r,n,o){let i=await yd(r,t.sqlDir),s=[];for(let a of i){let c=performance.now(),[l]=await Ht(()=>cn(a.path)),[m,d]=await Ht(()=>hd(t,a.path));if(d){s.push({filepath:a.path,checksum:l??"",status:"failed",error:d.message,durationMs:performance.now()-c});continue}let[,u]=await Ht(()=>LT(t.projectRoot,a.path,m)),p=performance.now()-c;u&&k.emit("error",{source:"change",error:u,context:{filepath:a.path,operation:"dry-run-write"}}),s.push({filepath:a.path,checksum:l??"",status:"success",durationMs:p,renderedSql:m})}return{name:e.name,direction:n,status:s.every(a=>a.status==="success")?"success":"failed",files:s,durationMs:performance.now()-o}}function BT(t,e){let r=ls.relative(t,e),n=r.endsWith(".tmpl")?r.slice(0,-5):r;return ls.join(t,"tmp",n)}async function LT(t,e,r){let n=BT(t,e),o=ls.dirname(n);await _T(o,{recursive:!0}),await kT(n,r,"utf-8")}async function hd(t,e){if(Ms(e))return(await gi(e,{projectRoot:t.projectRoot,config:void 0,secrets:void 0,globalSecrets:void 0})).sql;let[r,n]=await Ht(()=>mh(e,"utf-8"));if(n)throw new Error(`Failed to read file: ${e}`,{cause:n});return r}import hh from"path";import{attempt as Ul}from"@logosdx/utils";var xh={force:!1,dryRun:!1,preview:!1,output:null,abortOnError:!0},Gn=class{#t;#e;constructor(e){this.#t=e,this.#e=new Oe(e.db,e.configName)}async list(){let e=await At(this.#t.changesDir,this.#t.sqlDir),r=await this.#e.getAllStatuses(),n=new Set(e.map(s=>s.name)),o=await this.#e.getOrphaned(n),i=[];for(let s of e){let a=r.get(s.name);i.push({...s,name:s.name,status:a?.status??"pending",appliedAt:a?.appliedAt??null,appliedBy:a?.appliedBy??null,revertedAt:a?.revertedAt??null,errorMessage:a?.errorMessage??null,isNew:!a,orphaned:!1})}for(let s of o){let a=r.get(s);i.push({name:s,status:a.status,appliedAt:a.appliedAt,appliedBy:a.appliedBy,revertedAt:a.revertedAt,errorMessage:a.errorMessage,isNew:!1,orphaned:!0,path:void 0,date:void 0,description:void 0,changeFiles:void 0,revertFiles:void 0,hasChangelog:void 0})}return i.sort((s,a)=>s.name.localeCompare(a.name))}async run(e,r={}){let n=await this.#o(e);return Ci(this.#t,n,r)}async runChange(e,r={}){return Ci(this.#t,e,r)}async revert(e,r={}){let n=await this.#o(e);return wi(this.#t,n,r)}async revertChange(e,r={}){return wi(this.#t,e,r)}async next(e=1,r={}){let n={...xh,...r},o=performance.now(),s=(await this.list()).filter(m=>!m.orphaned&&(m.status==="pending"||m.status==="reverted")).slice(0,e);if(s.length===0)return{status:"success",changes:[],executed:0,skipped:0,failed:0,durationMs:performance.now()-o};let a=[],c=0,l=0;for(let m of s){let[d,u]=await Ul(()=>this.#o(m.name));if(u){if(a.push({name:m.name,direction:"change",status:"failed",files:[],durationMs:0,error:u.message}),c++,n.abortOnError)break;continue}let p=await Ci(this.#t,d,n);if(a.push(p),p.status==="success")l++;else if(c++,n.abortOnError)break}return{status:c>0?l>0?"partial":"failed":"success",changes:a,executed:l,skipped:s.length-l-c,failed:c,durationMs:performance.now()-o}}async ff(e={}){let n=(await this.list()).filter(o=>!o.orphaned&&(o.status==="pending"||o.status==="reverted")).length;return this.next(n,e)}async rewind(e,r={}){let n={...xh,...r},o=performance.now(),s=(await this.list()).filter(u=>!u.orphaned&&u.status==="success"&&u.appliedAt).sort((u,p)=>{let g=u.appliedAt?.getTime()??0;return(p.appliedAt?.getTime()??0)-g}),a;if(typeof e=="number")a=s.slice(0,e);else{let u=s.findIndex(p=>p.name===e);if(u===-1)return{status:"failed",changes:[],executed:0,skipped:0,failed:1,durationMs:performance.now()-o};a=s.slice(0,u+1)}if(a.length===0)return{status:"success",changes:[],executed:0,skipped:0,failed:0,durationMs:performance.now()-o};let c=[],l=0,m=0,d=0;for(let u of a){if(u.status==="reverted"){c.push({name:u.name,direction:"revert",status:"success",files:[],durationMs:0}),d++;continue}let[p,g]=await Ul(()=>this.#o(u.name));if(g){if(c.push({name:u.name,direction:"revert",status:"failed",files:[],durationMs:0,error:g.message}),l++,n.abortOnError)break;continue}let h=await wi(this.#t,p,n);if(c.push(h),h.status==="success")m++;else if(l++,n.abortOnError)break}return{status:l>0?m>0?"partial":"failed":"success",changes:c,executed:m,skipped:d,failed:l,durationMs:performance.now()-o}}async getHistory(e,r){return this.#e.getHistory(e,r)}async getFileHistory(e){return this.#e.getFileHistory(e)}async remove(e,r){if(r.disk){let n=hh.join(this.#t.changesDir,e),[o,i]=await Ul(()=>ea(n,this.#t.sqlDir));!i&&o&&await na(o)}r.db&&await this.#e.deleteRecords(e)}async get(e){return(await this.list()).find(n=>n.name===e)??null}async load(e){return this.#o(e)}async#o(e){let r=hh.join(this.#t.changesDir,e),[n,o]=await Ul(()=>ea(r,this.#t.sqlDir));if(o)throw await this.#e.getStatus(e)?new Qs(e):new Si(e);return n}};var HT=new Set(Object.values(G));function Yl(t){return t?t.startsWith("__noorm_")||HT.has(t):!1}async function oa(t,e,r={}){let n=performance.now(),o=lc(e),i=[],s=[],a=[];k.emit("teardown:start",{type:"truncate"});let[c,l]=await fo(()=>Gr(t,e,"tables",{includeNoormTables:!0}));if(l)throw k.emit("teardown:error",{error:l,object:null}),l;let m=new Set(r.preserve??[]);for(let p of c){let g=p.name;if(Yl(g)){a.push(g);continue}if(m.has(g)){a.push(g);continue}if(r.only&&!r.only.includes(g)){a.push(g);continue}s.push(g)}i.push(o.disableForeignKeyChecks());for(let p of s)i.push(o.truncateTable(p,void 0,r.restartIdentity??!0));if(i.push(o.enableForeignKeyChecks()),!r.dryRun)for(let p of i){if(p.startsWith("--"))continue;let g=p.includes("; ")?p.split("; ").map(h=>h.trim()).filter(h=>h.length>0):[p];for(let h of g){k.emit("teardown:progress",{category:"tables",object:h.includes("DELETE")||h.includes("TRUNCATE")?h:null,action:"truncating"});let[,f]=await fo(()=>xd.raw(h).execute(t));if(f)throw k.emit("teardown:error",{error:f,object:h}),f}}let d=Math.round(performance.now()-n),u={truncated:s,preserved:a,statements:i,durationMs:d};return k.emit("teardown:complete",{result:u}),u}async function us(t,e,r={}){let n=performance.now(),o=lc(e),i=[],s=[],a={tables:[],views:[],functions:[],procedures:[],types:[],foreignKeys:[]};k.emit("teardown:start",{type:"schema"});let c=new Set(r.preserveTables??[]),[[l,m],[d,u],[p,g],[h,f],[w,S],[E,T]]=await Promise.all([fo(()=>Gr(t,e,"tables",{includeNoormTables:!0})),fo(()=>Gr(t,e,"views")),fo(()=>Gr(t,e,"functions")),fo(()=>Gr(t,e,"procedures")),fo(()=>Gr(t,e,"types")),fo(()=>Gr(t,e,"foreignKeys"))]);if(m)throw m;if(u)throw u;if(g)throw g;if(f)throw f;if(S)throw S;if(T)throw T;for(let C of E){let b=C.tableName;Yl(b)||c.has(b)||(a.foreignKeys.push(C.name),i.push(o.dropForeignKey(C.name,b,C.schema)))}if(!r.keepViews)for(let C of d)a.views.push(C.name),i.push(o.dropView(C.name,C.schema));for(let C of l){let b=C.name;if(Yl(b)){s.push(b);continue}if(c.has(b)){s.push(b);continue}a.tables.push(b),i.push(o.dropTable(b,C.schema))}if(!r.keepFunctions)for(let C of p)a.functions.push(C.name),i.push(o.dropFunction(C.name,C.schema));if(!r.keepProcedures)for(let C of h)a.procedures.push(C.name),i.push(o.dropProcedure(C.name,C.schema));if(!r.keepTypes)for(let C of w)a.types.push(C.name),i.push(o.dropType(C.name,C.schema));if(!r.dryRun)for(let C of i){if(C.startsWith("--"))continue;k.emit("teardown:progress",{category:"tables",object:C,action:"dropping"});let[,b]=await fo(()=>xd.raw(C).execute(t));if(b)throw k.emit("teardown:error",{error:b,object:C}),b}let R=Math.round(performance.now()-n),x={dropped:a,preserved:s,statements:i,durationMs:R};if(r.postScript&&!r.dryRun){let C=await qT(t,r.postScript);x.postScriptResult=C}if(r.configName&&r.executedBy&&!r.dryRun){let C=new cs(t,r.configName),b=new Oe(t,r.configName);x.staleCount=await C.markAllAsStale();let v=[`${a.tables.length} tables`,`${a.views.length} views`,`${a.functions.length} functions`,`${a.procedures.length} procedures`];x.resetRecordId=await b.recordReset(r.executedBy,`Schema teardown: dropped ${v.join(", ")}`)}return k.emit("teardown:complete",{result:x}),x}async function Wl(t,e,r={}){let n=await us(t,e,{...r,dryRun:!0});return{toDrop:n.dropped,toPreserve:n.preserved,statements:n.statements}}async function qT(t,e){let r=jT(process.cwd(),e),[n,o]=await fo(()=>$T(r,"utf-8"));if(o)return{executed:!1,error:`Failed to read script: ${o.message}`};let i=n.split(";").map(s=>s.trim()).filter(s=>s.length>0&&!s.startsWith("--"));for(let s of i){let[,a]=await fo(()=>xd.raw(s).execute(t));if(a)return{executed:!1,error:`Script failed: ${a.message}`}}return{executed:!0}}import{gzip as KT,gunzip as VT}from"zlib";import{promisify as Eh}from"util";import{readFile as bh,writeFile as Sh,mkdir as Ch,unlink as wh,readdir as Th,stat as UT}from"fs/promises";import{join as Ti}from"path";import{randomUUID as YT}from"crypto";import{attempt as ms,attemptSync as WT}from"@logosdx/utils";var GT=Eh(KT),XT=Eh(VT),zT="1.0.0",bd="sql-history",go=class{#t;#e;#o;constructor(e,r){this.#t=e,this.#e=Ti(e,".noorm",bd,`${r}.json`),this.#o=Ti(e,".noorm",bd,r)}async#r(){await Ch(Ti(this.#t,".noorm",bd),{recursive:!0}),await Ch(this.#o,{recursive:!0})}async load(){let[e,r]=await ms(()=>bh(this.#e,"utf-8"));if(r)return[];let[n,o]=WT(()=>JSON.parse(e));return o?[]:this.#l(n.entries)}async addEntry(e,r){await this.#r();let n=YT(),o;r.success&&r.rows&&r.rows.length>0&&(o=`${n}.results.gz`,await this.saveResults(n,r));let i={id:n,query:e,executedAt:new Date,durationMs:r.durationMs,success:r.success,errorMessage:r.errorMessage,rowCount:r.rows?.length??r.rowsAffected,resultsFile:o},s=await this.load();return s.unshift(i),await this.#i(s),n}async saveResults(e,r){await this.#r();let n=JSON.stringify({columns:r.columns,rows:r.rows}),o=await GT(n),i=Ti(this.#o,`${e}.results.gz`);await Sh(i,o)}async loadResults(e){let r=Ti(this.#o,`${e}.results.gz`),[n,o]=await ms(()=>bh(r));if(o)return null;let i=await XT(n),s=JSON.parse(i.toString());return{success:!0,columns:s.columns,rows:s.rows,durationMs:0}}async getRecent(e=50){return(await this.load()).slice(0,e)}async clearOlderThan(e){let r=await this.load(),n=new Date;n.setMonth(n.getMonth()-e);let o=[],i=[];for(let a of r)a.executedAt>=n?o.push(a):i.push(a);let s=0;for(let a of i)if(a.resultsFile){let c=Ti(this.#o,a.resultsFile),[,l]=await ms(()=>wh(c));l||s++}return await this.#i(o),{entriesRemoved:i.length,filesRemoved:s}}async clearAll(){let e=await this.load(),r=0,[n]=await ms(()=>Th(this.#o));if(n){for(let o of n)if(o.endsWith(".results.gz")){let i=Ti(this.#o,o),[,s]=await ms(()=>wh(i));s||r++}}return await this.#i([]),{entriesRemoved:e.length,filesRemoved:r}}async getStats(){let e=await this.load(),r=0,[n]=await ms(()=>Th(this.#o));if(n){for(let o of n)if(o.endsWith(".results.gz")){let i=Ti(this.#o,o),[s]=await ms(()=>UT(i));s&&(r+=s.size)}}return{entryCount:e.length,resultsSize:r}}async#i(e){await this.#r();let r={version:zT,entries:this.#n(e)};await Sh(this.#e,JSON.stringify(r,null,2))}#n(e){return e.map(r=>({id:r.id,query:r.query,executedAt:r.executedAt.toISOString(),durationMs:r.durationMs,success:r.success,errorMessage:r.errorMessage,rowCount:r.rowCount,resultsFile:r.resultsFile}))}#l(e){return e.map(r=>({id:r.id,query:r.query,executedAt:new Date(r.executedAt),durationMs:r.durationMs,success:r.success,errorMessage:r.errorMessage,rowCount:r.rowCount,resultsFile:r.resultsFile}))}};import{sql as JT}from"kysely";import{attempt as QT}from"@logosdx/utils";async function Sd(t,e,r){let n=performance.now();k.emit("sql-terminal:execute:before",{query:e,configName:r});let[o,i]=await QT(()=>JT.raw(e).execute(t)),s=performance.now()-n;if(i){let d=i instanceof Error?i.message:String(i);return k.emit("sql-terminal:execute:after",{query:e,configName:r,success:!1,durationMs:s,error:d}),{success:!1,errorMessage:d,durationMs:s}}let a=o.rows??[],c=a[0],l=c?Object.keys(c):[],m=o.numAffectedRows!==void 0?Number(o.numAffectedRows):void 0;return k.emit("sql-terminal:execute:after",{query:e,configName:r,success:!0,durationMs:s,rowCount:a.length,rowsAffected:m}),{success:!0,columns:l,rows:a,rowsAffected:m,durationMs:s}}import Yt from"ansis";var Pe={primary:"#3B82F6",success:"#10B981",warning:"#F59E0B",error:"#EF4444",info:"#8B5CF6",debug:"#8B5CF6",action:"#3B82F6",secondary:"#6B7280",muted:"#9CA3AF",destructive:"#EF4444",text:"#F3F4F6",textDim:"#D1D5DB",border:"#4B5563",borderLight:"#6B7280",background:"#1F2937"},Te={primary:t=>Yt.hex(Pe.primary)(t),success:t=>Yt.hex(Pe.success)(t),warning:t=>Yt.hex(Pe.warning)(t),error:t=>Yt.hex(Pe.error)(t),info:t=>Yt.hex(Pe.info)(t),debug:t=>Yt.hex(Pe.debug)(t),action:t=>Yt.hex(Pe.action)(t),secondary:t=>Yt.hex(Pe.secondary)(t),muted:t=>Yt.hex(Pe.muted)(t),destructive:t=>Yt.hex(Pe.destructive)(t),text:t=>Yt.hex(Pe.text)(t),textDim:t=>Yt.hex(Pe.textDim)(t),border:t=>Yt.hex(Pe.border)(t),borderLight:t=>Yt.hex(Pe.borderLight)(t),bold:Yt.bold,dim:Yt.dim,italic:Yt.italic,underline:Yt.underline,inverse:Yt.inverse,reset:Yt.reset},mc={success:"\u2713",error:"\u2717",warning:"\u26A0",info:"\u2022",debug:"\u25CB",pending:"\u25CC",arrow:"\u2192",bullet:"\u2022",check:"\u2713",cross:"\u2717",star:"\u2605",dot:"\xB7"};var Uo={string(t){return Te.text(t)},number(t){return Te.warning(String(t))},boolean(t){return t?Te.success("true"):Te.error("false")},nil(){return Te.muted("null")},pair(t,e){let r=typeof e=="number"?Uo.number(e):typeof e=="boolean"?Uo.boolean(e):e==null?Uo.nil():Uo.string(String(e));return`${Te.muted(t)}=${r}`},path(t){return Te.info(t)},duration(t){return t<1e3?Te.muted(`${t}ms`):Te.muted(`${(t/1e3).toFixed(2)}s`)},count(t,e,r){let n=t===1?e:r??`${e}s`;return`${Te.warning(String(t))} ${Te.text(n)}`}},ia={error:Te.error,warn:Te.warning,info:Te.info,debug:Te.debug},sa={error:mc.error,warn:mc.warning,info:mc.info,debug:mc.debug};import{default as X0}from"ansis";import St from"ansis";var $e={h1:t=>St.bold(St.hex(Pe.primary)(t)),h2:t=>St.bold(St.hex(Pe.text)(t)),h3:t=>St.bold(St.hex(Pe.textDim)(t)),code:t=>St.hex(Pe.info)(t),codeDelimiter:t=>St.hex(Pe.muted)(t),text:t=>St.hex(Pe.text)(t),muted:t=>St.hex(Pe.muted)(t),bold:t=>St.bold(St.hex(Pe.text)(t)),italic:t=>St.italic(St.hex(Pe.textDim)(t)),blockquote:t=>St.dim(St.italic(St.hex(Pe.textDim)(t))),command:t=>St.hex(Pe.primary)(t),subcommand:t=>St.hex(Pe.info)(t),flag:t=>St.hex(Pe.warning)(t),placeholder:t=>St.hex(Pe.muted)(t),required:t=>St.hex(Pe.warning)(t),argument:t=>St.italic(St.hex(Pe.textDim)(t)),example:t=>St.hex(Pe.textDim)(t)};function Cd(t){let e=t;return e=e.replace(/`([^`]+)`/g,(r,n)=>$e.code(n)),e=e.replace(/\*\*([^*]+)\*\*/g,(r,n)=>$e.bold(n)),e=e.replace(/(?<!\*)\*([^*]+)\*(?!\*)/g,(r,n)=>$e.italic(n)),e=e.replace(/\[([^\]]+)\]/g,(r,n)=>$e.placeholder("[")+$e.placeholder(n)+$e.placeholder("]")),e=e.replace(/<([^>]+)>/g,(r,n)=>$e.muted("<")+$e.required(n)+$e.muted(">")),e=e.replace(/\b([A-Z]{2,})\b/g,(r,n)=>$e.argument(n)),e}function ZT(t){let e=t.trim();if(!e.includes("noorm")&&!e.startsWith("$"))return t;let r=t.match(/^(\s*)/)?.[1]||"",n=e,o="";n.startsWith("$")&&(o=$e.muted("$ "),n=n.slice(1).trim());let i=n.split(/\s+/),s=[],a=!1,c=!1;for(let l of i){if(l==="noorm"){s.push($e.command("noorm")),a=!0;continue}if(l.startsWith("-")){s.push($e.flag(l));continue}if(l.startsWith("[")&&l.endsWith("]")){let m=l.slice(1,-1);s.push($e.placeholder("[")+$e.placeholder(m)+$e.placeholder("]"));continue}if(l.startsWith("<")&&l.endsWith(">")){let m=l.slice(1,-1);s.push($e.muted("<")+$e.required(m)+$e.muted(">"));continue}if(/^[A-Z]{2,}$/.test(l)){s.push($e.argument(l));continue}if(a&&!c&&!l.startsWith("-")){s.push($e.subcommand(l)),c=!0;continue}s.push($e.text(l))}return r+o+s.join(" ")}function eE(t){let e=t.match(/^(#{1,3})\s+(.+)$/);return e&&e[1]&&e[2]?{level:e[1].length,text:e[2]}:null}function tE(t){let e=t.match(/^>\s*(.*)$/);return e?e[1]||"":null}function Rt(t){let e=t.split(`
|
|
1025
|
+
`),r=[],n=!1;for(let o of e){if(o.trim().startsWith("```")){n?(n=!1,r.push($e.codeDelimiter(o))):(n=!0,r.push($e.codeDelimiter(o)));continue}if(n){r.push($e.code(o));continue}let i=eE(o);if(i){let a=i.level===1?$e.h1:i.level===2?$e.h2:$e.h3;r.push(a(i.text));continue}let s=tE(o);if(s!==null){let a=Cd(s);r.push($e.blockquote(" "+a));continue}if(/^(\s{4,}|\t)/.test(o)){o.includes("noorm")||o.trim().startsWith("$")?r.push(ZT(o)):r.push($e.example(Cd(o)));continue}if(o.trim()===""){r.push("");continue}r.push($e.text(Cd(o)))}return r.join(`
|
|
1026
|
+
`)}import{attempt as dc}from"@logosdx/utils";var Ei=[{key:"version",name:G.version,displayName:"Version",description:"Version tracking"},{key:"change",name:G.change,displayName:"Changes",description:"Operation batch tracking"},{key:"executions",name:G.executions,displayName:"Executions",description:"File execution records"},{key:"lock",name:G.lock,displayName:"Locks",description:"Concurrent operation locks"},{key:"identities",name:G.identities,displayName:"Identities",description:"Team member identities"}],rE={[G.version]:["id","cli_version","noorm_version","state_version","settings_version","installed_at","upgraded_at"],[G.change]:["id","name","change_type","direction","checksum","executed_at","executed_by","config_name","cli_version","status","error_message","duration_ms"],[G.executions]:["id","change_id","filepath","file_type","checksum","cli_version","status","error_message","skip_reason","duration_ms"],[G.lock]:["id","config_name","locked_by","locked_at","expires_at","reason"],[G.identities]:["id","identity_hash","email","name","machine","os","public_key","registered_at","last_seen_at"]};function Ri(t){return{async getTableCounts(){let e=[];for(let r of Ei){let[n,o]=await dc(()=>t.selectFrom(r.name).select(t.fn.count("id").as("count")).executeTakeFirst());o?(k.emit("error",{source:"debug",error:o,context:{table:r.name,operation:"count"}}),e.push({table:r.name,count:0})):e.push({table:r.name,count:Number(n?.count??0)})}return e},async getTableRows(e,r={}){let{limit:n=100,sortColumn:o="id",sortDirection:i="desc"}=r,[s,a]=await dc(()=>t.selectFrom(e).selectAll().orderBy(o,i).limit(n).execute());return a?(k.emit("error",{source:"debug",error:a,context:{table:e,operation:"get-rows"}}),[]):s},async getRowById(e,r){let[n,o]=await dc(()=>t.selectFrom(e).selectAll().where("id","=",r).executeTakeFirst());return o?(k.emit("error",{source:"debug",error:o,context:{table:e,id:r,operation:"get-row"}}),null):n??null},async deleteRowById(e,r){let[n,o]=await dc(()=>t.deleteFrom(e).where("id","=",r).executeTakeFirst());return o?(k.emit("error",{source:"debug",error:o,context:{table:e,id:r,operation:"delete-row"}}),!1):Number(n?.numDeletedRows??0)>0},async deleteRowsByIds(e,r){if(r.length===0)return 0;let[n,o]=await dc(()=>t.deleteFrom(e).where("id","in",r).execute());return o?(k.emit("error",{source:"debug",error:o,context:{table:e,ids:r,operation:"delete-rows"}}),0):n.reduce((i,s)=>i+Number(s.numDeletedRows??0),0)},getTableColumns(e){return rE[e]??["id"]}}}function aa(t){return Ei.find(e=>e.name===t)}import{existsSync as Rh,realpathSync as wd}from"fs";import{join as kh,dirname as oE,resolve as iE}from"path";import{homedir as sE}from"os";function _h(t){let e=wd(process.cwd()),r=wd(iE(t??e)),n=wd(sE()),o=kh(n,qs),i=Rh(o)?o:null,s=r;for(;;){let a=kh(s,qs);if(Rh(a)){if(s===n)break;return{projectRoot:s,homeNoorm:i,hasProject:!0,originalCwd:e}}let c=oE(s);if(c===s||s===n)break;s=c}return{projectRoot:null,homeNoorm:i,hasProject:!1,originalCwd:e}}function Td(t={}){let{chdir:e=!0}=t,r=_h();return r.hasProject&&r.projectRoot&&e&&process.chdir(r.projectRoot),r}import{jsx as mE}from"react/jsx-runtime";function uE(t){if(t==="home")return[];let e=[],r=Nm(t);for(;r!==null;)e.unshift(r),r=Nm(r);return e.map(n=>({route:n,params:{}}))}var vh=aE(null);function Dh({initialRoute:t="home",initialParams:e={},children:r}){let[n,o]=Ed(t),[i,s]=Ed(e),[a,c]=Ed(()=>uE(t)),l=Gl((g,h={})=>{let f=n;g===n&&JSON.stringify(h)===JSON.stringify(i)||(c(w=>[...w,{route:n,params:i}]),o(g),s(h),k.emit("router:navigated",{from:f,to:g,params:{...h}}))},[n,i,a]),m=Gl(()=>{if(a.length===0)return;let g=n,h=a[a.length-1];c(f=>f.slice(0,-1)),o(h.route),s(h.params),k.emit("router:popped",{popped:g,to:h.route})},[a,n]),d=Gl((g,h={})=>{o(g),s(h)},[]),u=Gl(()=>{c([]),o("home"),s({})},[]),p=lE(()=>({route:n,params:i,history:a,navigate:l,back:m,replace:d,reset:u,canGoBack:a.length>0,section:cy(n)}),[n,i,a,l,m,d,u]);return mE(vh.Provider,{value:p,children:r})}function I(){let t=cE(vh);if(!t)throw new Error("useRouter must be used within a RouterProvider");return t}import{useInput as dx}from"ink";import{useCallback as mR,useState as z$}from"react";import{createContext as dE,useContext as pE,useCallback as fE,useEffect as gE,useRef as Rd,useState as yE}from"react";import{useApp as hE,Box as Ph}from"ink";import{Spinner as xE}from"@inkjs/ui";import{jsx as pc}from"react/jsx-runtime";var Nh=dE(null);function bE(){return pc(Ph,{flexDirection:"column",padding:1,children:pc(Ph,{children:pc(xE,{label:"Gracefully shutting down..."})})})}function Fh({children:t,projectRoot:e}){let{exit:r}=hE(),n=Rd(null),o=Rd(!1),i=Rd(!1),[s,a]=yE(!1);gE(()=>{let m=xl(e,{mode:"tui"});return n.current=m,m.start().then(()=>{i.current=!0,process.env.NOORM_DEBUG&&console.error("[ShutdownProvider] LifecycleManager started, state:",m.state)}).catch(d=>{console.error("Failed to start lifecycle manager:",d)}),()=>{n.current&&!o.current&&n.current.shutdown("programmatic").catch(()=>{})}},[e]);let l={gracefulExit:fE(async()=>{if(o.current)return;o.current=!0,a(!0),await new Promise(d=>setTimeout(d,50)),process.env.NOORM_DEBUG&&console.error("[ShutdownProvider] gracefulExit called, lifecycle state:",n.current?.state,"ready:",i.current);let m=0;for(;!i.current&&m<50;)await new Promise(d=>setTimeout(d,10)),m++;n.current&&(await n.current.shutdown("user"),process.env.NOORM_DEBUG&&console.error("[ShutdownProvider] shutdown complete, calling exit()")),r()},[r]),isShuttingDown:s};return pc(Nh.Provider,{value:l,children:s?pc(bE,{}):t})}function Xl(){let t=pE(Nh);if(!t)throw new Error("useShutdown must be used within a ShutdownProvider");return t}import{createContext as rR,useContext as nR,useState as Xr,useEffect as rx,useCallback as Po,useMemo as nx}from"react";import{Text as A$}from"ink";import{attempt as ox,attemptSync as Ud}from"@logosdx/utils";import{execSync as oR}from"child_process";import{readFileSync as iR,existsSync as sR}from"fs";import{join as aR,basename as cR}from"path";import{createHash as SE}from"crypto";function zl(t){if(!t.email||!t.name||!t.machine||!t.os)throw new Error("All fields required for identity hash: email, name, machine, os");let e=[t.email,t.name,t.machine,t.os].join("\0");return SE("sha256").update(e,"utf8").digest("hex")}function fc(t,e=8){return t.slice(0,e)}import{execSync as Bh}from"child_process";import{hostname as kd,platform as _d,release as vd,userInfo as CE}from"os";import{attemptSync as Lh}from"@logosdx/utils";function Dd(){let[t]=Lh(()=>Bh("git config user.name",{encoding:"utf8",timeout:5e3,stdio:["pipe","pipe","pipe"]}).trim()),[e]=Lh(()=>Bh("git config user.email",{encoding:"utf8",timeout:5e3,stdio:["pipe","pipe","pipe"]}).trim());return{name:t||CE().username,email:e||"",machine:kd(),os:`${_d()} ${vd()}`}}async function gc(t,e=!0){if(!t.name?.trim())throw new Error("Name is required for identity");if(!t.email?.trim())throw new Error("Email is required for identity");let r=t.machine?.trim()||kd(),n=`${_d()} ${vd()}`,o=il(),i=zl({email:t.email.trim(),name:t.name.trim(),machine:r,os:n}),s={identityHash:i,name:t.name.trim(),email:t.email.trim(),publicKey:o.publicKey,machine:r,os:n,createdAt:new Date().toISOString()};return e&&(await Lm(o),await nl(s)),k.emit("identity:created",{identityHash:i,name:s.name,email:s.email,machine:s.machine}),{identity:s,keypair:o}}async function yc(t){if(!t.name?.trim())throw new Error("Name is required for identity");if(!t.email?.trim())throw new Error("Email is required for identity");let e=await ol();if(!e)return null;let r=t.machine?.trim()||kd(),n=`${_d()} ${vd()}`,o=zl({email:t.email.trim(),name:t.name.trim(),machine:r,os:n}),i={identityHash:o,name:t.name.trim(),email:t.email.trim(),publicKey:e,machine:r,os:n,createdAt:new Date().toISOString()};return await nl(i),k.emit("identity:created",{identityHash:o,name:i.name,email:i.email,machine:i.machine}),i}async function ds(){let t=await Ya();if(!t)return null;let e=await ol();return e?{...t,publicKey:e}:null}import{attempt as Yo}from"@logosdx/utils";import{createWriteStream as zE}from"fs";import{join as JE}from"path";import{mkdir as QE}from"fs/promises";import{dirname as ZE}from"path";import{attempt as eR}from"@logosdx/utils";var wE=["CI","CONTINUOUS_INTEGRATION","GITHUB_ACTIONS","GITLAB_CI","CIRCLECI","TRAVIS","JENKINS_URL","BUILDKITE","TEAMCITY_VERSION","TF_BUILD","BITBUCKET_BUILD_NUMBER"];function ps(){if(process.env.NOORM_HEADLESS==="true")return!0;for(let t of wE)if(process.env[t])return!0;return!process.stdout.isTTY}function Ih(){return process.env.NODE_ENV==="development"||process.env.NOORM_DEV==="true"}function Oh(){return process.env.NOORM_CONFIG}import{join as VE,dirname as UE}from"path";import{createWriteStream as YE}from"fs";import{mkdir as WE}from"fs/promises";import Md from"dayjs";var Pd={silent:0,error:1,warn:2,info:3,verbose:4},Nd={enabled:!0,level:"info",file:".noorm/noorm.log",maxSize:"10mb",maxFiles:5};var TE=[/^error$/,/:error$/,/:failed$/],EE=[/:warning$/,/:blocked$/,/:expired$/],RE=[/:start$/,/:complete$/,/:created$/,/:deleted$/,/:updated$/,/:activated$/,/:loaded$/,/:persisted$/,/:migrated$/,/:acquired$/,/:released$/,/:resolved$/,/:open$/,/:close$/,/:set$/,/:rotated$/,/:flushed$/,/:started$/,/:initialized$/,/:after$/,/:skip$/,/:dry-run$/];function hc(t){for(let e of TE)if(e.test(t))return"error";for(let e of EE)if(e.test(t))return"warn";for(let e of RE)if(e.test(t))return"info";return"debug"}function Fd(t,e){if(e==="silent")return!1;if(e==="verbose")return!0;let r=hc(t),n=kE(r),o=Pd[e];return n<=o}function kE(t){switch(t){case"error":return 1;case"warn":return 2;case"info":return 3;case"debug":return 4}}import{attemptSync as _E}from"@logosdx/utils";var vE={"file:before":t=>`Executing ${t.filepath}`,"file:after":t=>t.status==="success"?`Executed ${t.filepath} (${t.durationMs}ms)`:`Failed ${t.filepath}: ${t.error}`,"file:skip":t=>`Skipped ${t.filepath} (${t.reason})`,"change:start":t=>`Starting ${t.direction} for ${t.name} (${t.files?.length??0} files)`,"change:file":t=>`${t.change}: ${t.filepath} (${t.index}/${t.total})`,"change:complete":t=>`${t.direction} ${t.name}: ${t.status} (${t.durationMs}ms)`,"build:start":t=>`Starting schema build (${t.fileCount} files)`,"build:complete":t=>t.status==="success"?`Build complete: ${t.filesRun} run, ${t.filesSkipped} skipped (${t.durationMs}ms)`:`Build failed after ${t.filesRun} files (${t.durationMs}ms)`,"run:file":t=>`Running ${t.filepath} on ${t.configName}`,"run:dir":t=>`Running directory ${t.dirpath} (${t.fileCount} files) on ${t.configName}`,"lock:acquiring":t=>`Acquiring lock for ${t.configName} as ${t.identity}`,"lock:acquired":t=>`Lock acquired for ${t.configName}`,"lock:released":t=>`Lock released for ${t.configName}`,"lock:blocked":t=>`Lock blocked: ${t.configName} held by ${t.holder}`,"lock:expired":t=>`Lock expired for ${t.configName} (was held by ${t.previousHolder})`,"state:loaded":t=>`State loaded: ${t.configCount} configs, version ${t.version}`,"state:persisted":t=>`State saved: ${t.configCount} configs`,"state:migrated":t=>`State migrated from ${t.from} to ${t.to}`,"config:created":t=>`Created config: ${t.name}`,"config:updated":t=>`Updated config ${t.name}: ${t.fields?.join(", ")}`,"config:deleted":t=>`Deleted config: ${t.name}`,"config:activated":t=>`Activated config: ${t.name}${t.previous?` (was ${t.previous})`:""}`,"secret:set":t=>`Set secret ${t.key} for ${t.configName}`,"secret:deleted":t=>`Deleted secret ${t.key} from ${t.configName}`,"global-secret:set":t=>`Set global secret: ${t.key}`,"global-secret:deleted":t=>`Deleted global secret: ${t.key}`,"db:creating":t=>`Creating database ${t.database} for ${t.configName}`,"db:created":t=>`Created database ${t.database} (${t.durationMs}ms)`,"db:destroying":t=>`Destroying database ${t.database} for ${t.configName}`,"db:destroyed":t=>`Destroyed database ${t.database}`,"db:bootstrap":t=>`Bootstrapped ${t.tables?.length??0} tables for ${t.configName}`,"template:render":t=>`Rendered template ${t.filepath} (${t.durationMs}ms)`,"template:load":t=>`Loaded ${t.format} data from ${t.filepath}`,"identity:resolved":t=>`Identity resolved: ${t.name} (${t.source})`,"identity:created":t=>`Created identity: ${t.name} <${t.email}>`,"identity:synced":t=>`Synced ${t.discovered} identities for ${t.configName}`,"identity:registered":t=>`Registered identity for ${t.configName}`,"config:exported":t=>`Exported ${t.configName} to ${t.recipient}`,"config:imported":t=>`Imported ${t.configName} from ${t.from}`,"connection:open":t=>`Connected to ${t.configName} (${t.dialect})`,"connection:close":t=>`Disconnected from ${t.configName}`,"connection:error":t=>`Connection error for ${t.configName}: ${t.error}`,"logger:started":t=>`Logger started: ${t.file} at ${t.level} level`,"logger:rotated":t=>`Rotated log: ${t.oldFile} -> ${t.newFile}`,"logger:error":t=>`Logger error: ${t.error?.message??t.error}`,"logger:flushed":t=>`Flushed ${t.entriesWritten} log entries`,"settings:loaded":t=>`Settings loaded from ${t.path}`,"settings:saved":t=>`Settings saved to ${t.path}`,"settings:initialized":t=>`Settings initialized at ${t.path}${t.force?" (forced)":""}`,error:t=>`Error in ${t.source}: ${DE(t.error)}`};function DE(t){if(t==null)return"Unknown error";if(t instanceof Error||typeof t=="object"&&"message"in t&&typeof t.message=="string")return t.message;if(typeof t=="object"){let e=t;if(e.code&&e.severity){let n=[`${e.severity} ${e.code}`];return e.routine&&n.push(`in ${e.routine}`),e.where&&n.push(`- ${String(e.where).slice(0,100)}`),n.join(" ")}let r=Object.keys(e).slice(0,3);if(r.length>0)return`{${r.map(n=>`${n}: ${PE(e[n])}`).join(", ")}}`}return String(t)}function PE(t){return t==null?String(t):typeof t=="string"?t.length>30?`"${t.slice(0,27)}..."`:`"${t}"`:typeof t=="number"||typeof t=="boolean"?String(t):"[...]"}function Bd(t,e){let r=vE[t];if(r){let[o,i]=_E(()=>r(e));if(!i&&o!==null)return o}let n=Object.entries(e).slice(0,3).map(([o,i])=>`${o}=${NE(i)}`);return n.length===0?t.replace(/:/g," "):`${t.replace(/:/g," ")}: ${n.join(", ")}`}function NE(t){return t==null?String(t):typeof t=="string"?t.length>50?`"${t.slice(0,47)}..."`:`"${t}"`:typeof t=="number"||typeof t=="boolean"?String(t):Array.isArray(t)?`[${t.length} items]`:typeof t=="object"?`{${Object.keys(t).length} keys}`:String(t)}import vM from"ansis";import{attemptSync as FE}from"@logosdx/utils";var BE={error:{icon:sa.error,color:ia.error},warn:{icon:sa.warn,color:ia.warn},info:{icon:sa.info,color:ia.info},debug:{icon:sa.debug,color:ia.debug}};function LE(t){if(t===null)return Uo.nil();if(t===void 0)return Te.muted("undefined");if(typeof t=="string")return t.length>50?Te.text(`"${t.slice(0,47)}..."`):Te.text(t);if(typeof t=="number")return Uo.number(t);if(typeof t=="boolean")return Uo.boolean(t);if(t instanceof Date)return Te.muted(t.toISOString());if(t instanceof Error)return Te.error(t.message);if(Array.isArray(t))return t.length===0?Te.muted("[]"):t.length<=3&&t.every(e=>typeof e=="string"||typeof e=="number")?Te.text(`[${t.join(", ")}]`):Te.muted(`[${t.length} items]`);if(typeof t=="object"){let[e,r]=FE(()=>JSON.stringify(t));return r?Te.muted("[object]"):Te.text(e.length>60?e.slice(0,57)+"...":e)}return Te.text(String(t))}function IE(t){let e=[];for(let[r,n]of Object.entries(t))e.push(`${Te.muted(r)}=${LE(n)}`);return e.join(" ")}function Ld(t,e,r,n){let o=BE[t],i=o.color(o.icon),s=o.color(e),a=`${i} ${s} ${Te.text(r)}`;return n&&Object.keys(n).length>0&&(a+=` ${IE(n)}`),a}var OE={success:Te.success("\u2713"),failed:Te.error("\u2717"),partial:Te.warning("\u26A0"),pending:Te.warning("\u25CB"),skipped:Te.muted("\u25CB"),reverted:Te.info("\u21A9")};var Ah=12,yo=new Set;function AE(t){return t.replace(/[-_\s]+(.)?/g,(e,r)=>r?r.toUpperCase():"").replace(/^[A-Z]/,e=>e.toLowerCase())}function ME(t){return t.replace(/[-\s]+/g,"_").replace(/([a-z])([A-Z])/g,"$1_$2").toLowerCase()}function $E(t){return t.replace(/[_\s]+/g,"-").replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase()}function Mh(t){return t.replace(/[-_\s]+/g," ").replace(/([a-z])([A-Z])/g,"$1 $2").split(" ").map(e=>e.charAt(0).toUpperCase()+e.slice(1).toLowerCase()).join("")}function Id(t){return t.replace(/[-_\s]/g,"")}function xc(t){for(let e of t){let r=[e,`noorm_${e}`];for(let n of r)yo.add(n),yo.add(n.toLowerCase()),yo.add(n.toUpperCase()),yo.add(AE(n)),yo.add(ME(n)),yo.add($E(n)),yo.add(Mh(n)),yo.add(Id(n)),yo.add(Id(n).toLowerCase()),yo.add(Id(n).toUpperCase())}}xc(["password","pass","secret","token","key","credential","api_key","apikey","access_key","secret_key","db_pass","db_password","redis_pass","client_secret","private_key","encryption_key","auth_token","bearer_token","jwt_secret","session_secret"]);function Jl(t,e,r){let n=t.length,o=Math.min(n,Ah),i=Math.min(Math.ceil(n/5),4)||1,s="*".repeat(o);return r==="verbose"&&n>=4&&(s=t.slice(0,i)+"*".repeat(Math.max(0,o-4)),s.length<o&&(s+="*".repeat(o-s.length))),n>Ah&&(s+="..."),`<${Mh(e)} ${s} (${n}) />`}function Od(t){if(t.stages){for(let e of Object.values(t.stages))if(e.secrets&&Array.isArray(e.secrets)){let r=e.secrets.map(n=>n.key);xc(r)}}}function Ad(){let t=[];return t.push(k.on("secret:set",({key:e})=>{xc([e])})),t.push(k.on("global-secret:set",({key:e})=>{xc([e])})),()=>t.forEach(e=>e())}function ca(t,e){if(t==null||typeof t!="object"||t instanceof URL||t instanceof Date)return t;if(Array.isArray(t))return t.map(n=>typeof n=="object"&&n!==null?ca(n,e):n);let r={...t};for(let n in r){let o=Object.getOwnPropertyDescriptor(r,n);if(o&&!o.writable&&!o.set)continue;let i=r[n];yo.has(n)&&typeof i=="string"?r[n]=Jl(i,n,e):typeof i=="object"&&i!==null&&(r[n]=ca(i,e))}return r}import{stat as jE,rename as HE,readdir as qE,unlink as KE}from"fs/promises";import{dirname as jh,basename as Hh,join as qh,extname as Kh}from"path";import{attempt as Ql}from"@logosdx/utils";function Vh(t){let e=t.toLowerCase().match(/^(\d+(?:\.\d+)?)\s*(b|kb|mb|gb)?$/);if(!e||!e[1])throw new Error(`Invalid size format: ${t}`);let r=parseFloat(e[1]),n=e[2]??"b",i={b:1,kb:1024,mb:1024*1024,gb:1024*1024*1024}[n];if(i===void 0)throw new Error(`Invalid size unit: ${n}`);return Math.floor(r*i)}function Uh(t){let e=jh(t),r=Kh(t),n=Hh(t,r),o=new Date().toISOString().replace(/:/g,"-").replace(/\.\d+Z$/,"");return qh(e,`${n}.${o}${r}`)}async function Yh(t,e){let[r,n]=await Ql(()=>jE(t));return n?!1:r.size>=e}async function Wh(t){let e=Uh(t),[r,n]=await Ql(()=>HE(t,e));if(n)throw new Error(`Failed to rotate log file: ${n.message}`);return e}async function Gh(t){let e=jh(t),r=Kh(t),n=Hh(t,r),o=new RegExp(`^${$h(n)}\\.\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}${$h(r)}$`),[i,s]=await Ql(()=>qE(e));return s?[]:i.filter(a=>o.test(a)).map(a=>qh(e,a)).sort().reverse()}async function Xh(t,e){let n=(await Gh(t)).slice(e),o=[];for(let i of n){let[s,a]=await Ql(()=>KE(i));a||o.push(i)}return o}async function Zl(t,e,r){let n=Vh(e);if(!await Yh(t,n))return{rotated:!1};let i=await Wh(t),s=await Xh(t,r);return{rotated:!0,oldFile:t,newFile:i,deletedFiles:s.length>0?s:void 0}}function $h(t){return t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}import{merge as GE}from"@logosdx/utils";function zh(t,e){for(let[r,n]of Object.entries(t))if(!(r in e))if(n==null)e[r]=n;else if(Array.isArray(n))e[r]=JSON.stringify(n);else if(typeof n=="object")for(let[o,i]of Object.entries(n)){let s=`${r}.${o}`;s in e||(e[s]=typeof i=="object"&&i!==null?JSON.stringify(i):i)}else e[r]=n}var ki=class{#t;#e;#o;#r=null;#i=null;#n=!1;#l=!1;#s=null;#a="idle";#c=null;#u=null;constructor(e){this.#t=e.projectRoot,this.#e={...Nd,...e.config},this.#o=e.context??{},this.#l=e.json??ps(),this.#l&&(this.#n=!1),e.console?(this.#i=e.console,this.#n=e.color??!0):ps()&&(this.#i=process.stdout,this.#n=e.color??!0),e.file&&(this.#r=e.file),this.#u=k.on("app:shutdown",async()=>{await this.stop()})}get state(){return this.#a}get level(){return this.#e.level}get filepath(){return VE(this.#t,this.#e.file)}get isEnabled(){return this.#e.enabled&&this.#e.level!=="silent"}get stats(){return this.#a!=="running"||!this.#s?null:{pending:this.#s.pending,totalWritten:this.#s.stats.processed}}async flush(){!this.#s||this.#a!=="running"||await this.#s.flush()}setContext(e){this.#o={...this.#o,...e}}clearContext(){this.#o={}}async start(){if(this.#a==="idle"&&this.isEnabled){if(!this.#r&&this.#e.file){let e=this.filepath;await WE(UE(e),{recursive:!0}),this.#r=YE(e,{flags:"a"})}if(this.#r){let e=await Zl(this.filepath,this.#e.maxSize,this.#e.maxFiles);e.rotated&&k.emit("logger:rotated",{oldFile:e.oldFile,newFile:e.newFile}),this.#c=setInterval(()=>{this.#y()},6e4)}this.#s=k.queue(/./,e=>{let{event:r,data:n}=e;this.#g(r,n)},{name:"logger",autoStart:!0,concurrency:1,type:"fifo",debug:process.env.NOORM_LOGGER_DEBUG==="true"}),this.#a="running",k.emit("logger:started",{file:this.filepath,level:this.#e.level})}}async stop(){this.#a==="running"&&(this.#a="flushing",this.#c&&(clearInterval(this.#c),this.#c=null),this.#s&&(await this.#s.stop(),this.#s=null),this.#r&&this.#r!==process.stdout&&this.#r!==process.stderr&&await new Promise(e=>{this.#r.end(()=>e())}),this.#u&&(this.#u(),this.#u=null),this.#a="stopped")}#g(e,r){if(e.startsWith("logger:")||!Fd(e,this.#e.level))return;let n=hc(e);(e.endsWith(":complete")||e.endsWith(":after"))&&r.status!=="success"&&r.status!=="skipped"&&(n="error"),r.error&&(n="error");let o=ca({...r},this.#e.level),i=Bd(e,o);this.#d(n,e,i,o),this.#p(n,e,i,o)}#d(e,r,n,o){if(!this.#i)return;let i=o&&Object.keys(o).length>0;if(this.#l){let s=this.#f(e,r,n,o,i);this.#i.write(JSON.stringify(s)+`
|
|
1027
|
+
`)}else if(this.#n){let s=Md().format("YY-MM-DD HH:mm:ss"),a=Ld(e,r,n,i?o:void 0);this.#i.write(`[${s}] ${a}
|
|
1028
|
+
`)}else{let s=Md().format("YY-MM-DD HH:mm:ss"),a=e.toUpperCase().padEnd(5),c=`[${s}] [${a}] [${r}] ${n}`;i&&(c+=` ${JSON.stringify(o)}`),this.#i.write(c+`
|
|
1029
|
+
`)}}#p(e,r,n,o){if(!this.#r)return;let i=o&&Object.keys(o).length>0,s=this.#f(e,r,n,o,i);this.#r.write(JSON.stringify(s)+`
|
|
1030
|
+
`)}#f(e,r,n,o,i){let s={time:Md().format("YYYY-MM-DDTHH:mm:ss.SSSZ"),type:r,level:e,message:n};return i&&Object.keys(o).length>0&&zh(o,s),this.#o&&Object.keys(this.#o).length>0&&zh(this.#o,s),s}async#y(){if(!this.#r||this.#a!=="running")return;let e=await Zl(this.filepath,this.#e.maxSize,this.#e.maxFiles);e.rotated&&k.emit("logger:rotated",{oldFile:e.oldFile,newFile:e.newFile})}info(e,r){this.#m("info",e,r)}warn(e,r){this.#m("warn",e,r)}error(e,r){this.#m("error",e,r)}debug(e,r){this.#m("debug",e,r)}#m(e,r,n){if(!this.isEnabled||this.#a!=="running")return;let o={error:1,warn:2,info:3,debug:4},i={silent:0,error:1,warn:2,info:3,verbose:4};if(o[e]>i[this.#e.level])return;let s=n?ca({...n},this.#e.level):{};this.#d(e,"log",r,s),this.#p(e,"log",r,s)}},$d=null;function jd(t){if(!$d&&t){let e={projectRoot:"",settings:{}};typeof t=="string"?e.projectRoot=t:e=GE(e,t),$d=new ki(e)}return $d}var tR=null,Jh=null,Hd=null;function qd(t){Jh||(tR=Ad(),Jh=k.once("settings:loaded",async e=>{let{settings:r}=e;if(!r.logging?.enabled)return;Od(r);let n;if(!ps()){let o=JE(t,r.logging.file??".noorm/noorm.log"),[,i]=await eR(()=>QE(ZE(o),{recursive:!0}));i||(n=zE(o,{flags:"a"}))}Hd=new ki({projectRoot:t,settings:r,config:r.logging,file:n}),await Hd.start()}))}function Kd(){return Hd??jd()}async function Qh(t,e){let[r,n]=await Yo(()=>t.selectFrom("__noorm_identities__").select(["id"]).where("identity_hash","=",e.identityHash).executeTakeFirst());if(n)return k.emit("error",{source:"identity:register:select",error:n,context:{identityHash:e.identityHash,name:e.name,email:e.email}}),{ok:!1,registered:!1,error:n.message};if(r){let[,i]=await Yo(()=>t.updateTable("__noorm_identities__").set({last_seen_at:new Date}).where("identity_hash","=",e.identityHash).execute());return i?(k.emit("error",{source:"identity:register:update",error:i,context:{identityHash:e.identityHash,name:e.name,email:e.email}}),{ok:!1,registered:!1,error:i.message}):{ok:!0,registered:!1}}let[,o]=await Yo(()=>t.insertInto("__noorm_identities__").values({identity_hash:e.identityHash,email:e.email,name:e.name,machine:e.machine,os:e.os,public_key:e.publicKey}).execute());return o?(k.emit("error",{source:"identity:register:insert",error:o,context:{identityHash:e.identityHash,name:e.name,email:e.email}}),{ok:!1,registered:!1,error:o.message}):(k.emit("identity:registered",{identityHash:e.identityHash,name:e.name,email:e.email}),{ok:!0,registered:!0})}async function Zh(t,e){let[r,n]=await Yo(()=>t.selectFrom("__noorm_identities__").selectAll().execute());return n?{ok:!1,users:[],error:n.message}:{ok:!0,users:(r??[]).map(i=>({identityHash:i.identity_hash,email:i.email,name:i.name,publicKey:i.public_key,machine:i.machine,os:i.os,lastSeen:i.last_seen_at instanceof Date?i.last_seen_at.toISOString():String(i.last_seen_at),source:e}))}}async function ex(t,e,r){let[n,o]=await Yo(()=>mo(t));if(o)return{ok:!1,error:o.message};if(!n)return{ok:!0,knownUsersCount:0};let i=!1;if(e){let l=await Qh(t,e);if(!l.ok)return{ok:!1,error:l.error};i=l.registered}let[s,a]=await Yo(()=>t.selectFrom("__noorm_identities__").select(t.fn.count("id").as("count")).executeTakeFirst());if(a)return{ok:!1,error:a.message};let c=Number(s?.count??0);return k.emit("identity:synced",{configName:r,registered:i,knownUsersCount:c}),{ok:!0,registered:i,knownUsersCount:c}}async function fs(t){let[e]=await Yo(()=>ds());if(Kd()?.info("Loaded existing identity",{identity:e}),!e)return{ok:!0,knownUsersCount:0};let[r,n]=await Yo(()=>K(t.connection,t.name));if(n)return k.emit("error",{source:"identity:sync:connection",error:n,context:{configName:t.name}}),{ok:!0,knownUsersCount:0};let o=r.db,i=await ex(o,e,t.name);if(!i.ok)return i;if(i.knownUsersCount&&i.knownUsersCount>0){let[s,a]=await Yo(()=>Zh(o,t.name));if(a)return k.emit("error",{source:"identity:fetch-known-users",error:a,context:{configName:t.name}}),{ok:!1,error:a.message};let{ok:c,users:l,error:m}=s;return c?{...i,knownUsers:l}:{ok:!1,error:m}}return i}var Vd=null;function Zt(t={}){return t.configIdentity||t.cryptoIdentity?kn(t):(Vd||(Vd=kn(t)),Vd)}function tx(t){return Zt({configIdentity:t.identity})}import{Fragment as U$,jsx as uR,jsxs as Y$}from"react/jsx-runtime";function lR(t){let e=aR(t,"package.json");if(sR(e)){let[n]=Ud(()=>iR(e,"utf8"));if(n){let[o]=Ud(()=>JSON.parse(n));if(o?.name)return o.name}}let[r]=Ud(()=>oR("git remote get-url origin",{cwd:t,encoding:"utf8",timeout:5e3,stdio:["pipe","pipe","pipe"]}).trim());if(r){let n=r.match(/[/:]([\w.-]+)\/([\w.-]+?)(?:\.git)?$/);if(n)return`${n[1]}/${n[2]}`}return cR(t)}var ix=rR(null);function sx({projectRoot:t=process.cwd(),autoLoad:e=!0,children:r}){let n=nx(()=>lR(t),[t]),[o,i]=Xr("not-initialized"),[s,a]=Xr(null),[c,l]=Xr(null),[m,d]=Xr(null),[u,p]=Xr(null),[g,h]=Xr(null),[f,w]=Xr([]),[S,E]=Xr(null),[T,R]=Xr(null),[x,C]=Xr("disconnected"),[b,v]=Xr(null),[P,_]=Xr({status:"free"}),[O,N]=Xr({dryRun:!1,force:!1}),[B,D]=Xr({}),[F,M]=Xr(!0),H=Po(()=>{N(ie=>({...ie,dryRun:!ie.dryRun}))},[]),V=Po(()=>{N(ie=>({...ie,force:!ie.force}))},[]),U=Po((ie,Ce)=>{D(Qt=>({...Qt,[ie]:Ce}))},[]),j=Po(()=>{D({})},[]),Q=Po(async(ie,Ce)=>{ie&&(p(ie.getActiveConfig()),h(ie.getActiveConfigName()),w(ie.listConfigs()));let[Qt]=await ox(()=>ds());E(Qt??null),Ce&&Ce.isLoaded&&R(Ce.settings)},[]),fe=Po(async(ie,Ce)=>{if(!Ce.isLoaded||!ie.hasPrivateKey())return;let Qt=Ce.getStages(),Va=ie.listConfigs(),oy={};for(let As of Va)oy[As.name]=!0;let zS={sql:Ce.settings?.paths?.sql??"./sql",changes:Ce.settings?.paths?.changes??"./changes"};for(let[As,Un]of Object.entries(Qt)){if(oy[As]||!Un.defaults?.dialect)continue;let JS={name:As,type:Un.defaults.host&&Un.defaults.host!=="localhost"?"remote":"local",isTest:Un.defaults.isTest??!1,protected:Un.defaults.protected??!1,connection:{dialect:Un.defaults.dialect,host:Un.defaults.host??"localhost",port:Un.defaults.port,database:Un.defaults.database??As,user:Un.defaults.user,password:Un.defaults.password,ssl:Un.defaults.ssl},paths:zS};await ie.setConfig(As,JS)}},[]),xe=Po(async()=>{i("loading"),a(null);let ie=Ur(t),Ce=hi(t),[,Qt]=await ox(async()=>{await ie.load(),await Ce.load()});if(Qt){a(Qt instanceof Error?Qt:new Error(String(Qt))),i("error");return}await fe(ie,Ce),l(ie),d(Ce),Q(ie,Ce),i("ready")},[t,Q,fe]),oe=Po(async()=>{Q(c,m)},[c,m,Q]),Je=Po(async ie=>{c&&await c.setActiveConfig(ie)},[c]);rx(()=>{e&&o==="not-initialized"&&xe()},[e,o,xe]),rx(()=>{let ie=[];return ie.push(k.on("state:loaded",Ce=>{h(Ce.activeConfig),c&&(p(c.getActiveConfig()),w(c.listConfigs())),ds().then(Qt=>E(Qt))})),ie.push(k.on("config:activated",Ce=>{h(Ce.name),c&&(p(c.getConfig(Ce.name)),w(c.listConfigs()))})),ie.push(k.on("config:created",()=>{c&&w(c.listConfigs())})),ie.push(k.on("config:deleted",()=>{c&&(p(c.getActiveConfig()),h(c.getActiveConfigName()),w(c.listConfigs()))})),ie.push(k.on("identity:created",Ce=>{ds().then(Qt=>E(Qt))})),ie.push(k.on("connection:open",Ce=>{C("connected"),v(Ce.configName)})),ie.push(k.on("connection:close",Ce=>{b===Ce.configName&&(C("disconnected"),v(null))})),ie.push(k.on("connection:error",Ce=>{(b===Ce.configName||!b)&&C("error")})),ie.push(k.on("lock:acquired",Ce=>{_({status:"locked",holder:Ce.identity,expiresAt:Ce.expiresAt})})),ie.push(k.on("lock:released",()=>{_({status:"free"})})),ie.push(k.on("lock:blocked",Ce=>{_({status:"blocked",holder:Ce.holder,since:Ce.heldSince})})),ie.push(k.on("lock:expired",()=>{_({status:"free"})})),()=>{for(let Ce of ie)Ce()}},[c,b]);let Vr=nx(()=>({loadingStatus:o,error:s,projectName:n,projectRoot:t,stateManager:c,settingsManager:m,activeConfig:u,activeConfigName:g,configs:f,identity:S,hasIdentity:S!==null,settings:T,connectionStatus:x,connectedConfig:b,lockStatus:P,globalModes:O,toggleDryRun:H,toggleForce:V,exploreFilters:B,setExploreFilter:U,clearExploreFilters:j,helpKeyEnabled:F,setHelpKeyEnabled:M,refresh:oe,setActiveConfig:Je}),[o,s,n,t,c,m,u,g,f,S,T,x,b,P,O,H,V,B,U,j,F,oe,Je]);return uR(ix.Provider,{value:Vr,children:r})}function L(){let t=nR(ix);if(!t)throw new Error("useAppContext must be used within an AppContextProvider");return t}function eu(){let{activeConfig:t,activeConfigName:e,configs:r}=L();return{activeConfig:t,activeConfigName:e,configs:r}}function ax(){let{connectionStatus:t,connectedConfig:e}=L();return{connectionStatus:t,connectedConfig:e}}function cx(){let{lockStatus:t}=L();return{lockStatus:t}}function lx(){let{projectName:t}=L();return{projectName:t}}function cr(){let{settings:t,settingsManager:e}=L();return{settings:t,settingsManager:e}}function _n(){let{globalModes:t}=L();return t}function ux(){let{globalModes:t,toggleDryRun:e}=L();return{isDryRun:t.dryRun,toggleDryRun:e}}function mx(){let{globalModes:t,toggleForce:e}=L();return{isForce:t.force,toggleForce:e}}function tu(){let{exploreFilters:t,setExploreFilter:e,clearExploreFilters:r}=L(),n=Po(o=>t[o],[t]);return{filters:t,getFilter:n,setFilter:e,clearFilters:r}}import{Fragment as fR,jsx as gR}from"react/jsx-runtime";var dR=4,pR=750,gs={count:0,lastPress:0};function px({children:t,onHelp:e,onEscape:r,onToggleDryRun:n,onToggleForce:o,onToggleLogViewer:i,onOpenSqlTerminal:s,onDebugMode:a}){let{gracefulExit:c}=Xl(),{stack:l}=Pm(),{helpKeyEnabled:m}=L();return dx((d,u)=>{if(u.ctrl&&d==="c"){c();return}if(u.shift&&d==="L"){i?.();return}if(u.shift&&d==="Q"){s?.();return}if(l.length<=1){if(d==="?"&&m&&e?.(),d==="?"){if(Date.now()-gs.lastPress>pR&&(gs.count=0),gs.lastPress=Date.now(),gs.count+=1,gs.count>=dR){gs.count=0,a?.();return}return}else gs.count=0;if(d==="D"){n?.();return}if(d==="F"){o?.();return}}u.escape&&r&&r()}),gR(fR,{children:t})}function fx(t,e){dx(mR((r,n)=>{t&&e(r,n)},[t,e]))}import{Suspense as NN}from"react";import{Box as FN,Text as BN}from"ink";import{useState as np,useEffect as Lk,useCallback as op,useMemo as Ik}from"react";import{Box as Ne,Text as W,useInput as Ok}from"ink";import{attempt as Ak}from"@logosdx/utils";import{Box as gx,Text as yR}from"ink";import{jsx as yx,jsxs as hR}from"react/jsx-runtime";function y({title:t,titleColor:e="cyan",borderStyle:r="round",borderColor:n="gray",paddingX:o=1,paddingY:i=0,width:s,children:a}){return hR(gx,{flexDirection:"column",borderStyle:r,borderColor:n,paddingX:o,paddingY:i,width:s,children:[t&&yx(gx,{marginBottom:1,children:yx(yR,{bold:!0,color:e,children:t})}),a]})}import{Box as sj,Text as aj}from"ink";import{jsx as lj,jsxs as uj}from"react/jsx-runtime";import{useState as bR,useEffect as hx,useMemo as ru,useRef as bc}from"react";import{Box as nu,Text as ys,useInput as SR}from"ink";import{jsx as Yd,jsxs as _i}from"react/jsx-runtime";function dt({items:t,onSelect:e,onHighlight:r,emptyLabel:n="No items",visibleCount:o=5,focusLabel:i,isFocused:s,defaultValue:a,isDisabled:c=!1,showDescriptionBelow:l=!1,numberNav:m=!1,multiSelect:d=!1,onToggle:u,onSubmit:p,onCancel:g}){let h=s!==void 0,f=A({label:i??"SelectList",skip:h}),w=h?s:f.isFocused,S=ru(()=>t.filter(D=>!D.disabled),[t]),E=bc(S),T=bc(e),R=bc(u),x=bc(p),C=bc(g);E.current=S,T.current=e,R.current=u,x.current=p,C.current=g;let b=ru(()=>{if(!a)return 0;let D=S.findIndex(F=>F.key===a);return D>=0?D:0},[a,S]),[v,P]=bR(b);hx(()=>{if(S.length===0){P(0);return}v>=S.length&&P(S.length-1)},[S.length,v]);let _=ru(()=>{if(S.length<=o)return 0;let D=Math.floor(o/2),F=v-D;return F<0&&(F=0),F>S.length-o&&(F=S.length-o),F},[v,S.length,o]),O=ru(()=>S.slice(_,_+o),[S,_,o]);if(hx(()=>{let D=S[v];D&&r&&r(D)},[v,S,r]),SR((D,F)=>{if(!(!w||c)){if(F.escape){let M=C.current;M&&M();return}if(F.upArrow){P(M=>M>0?M-1:E.current.length-1);return}if(F.downArrow){P(M=>M<E.current.length-1?M+1:0);return}if(D===" "&&d){let M=E.current,H=R.current,V=M[v];V&&H&&H(V);return}if(F.return){if(d){let M=x.current;M&&M()}else{let M=E.current,H=T.current,V=M[v];V&&H&&H(V)}return}if(m){let M=parseInt(D,10);if(M>=1&&M<=9){let H=E.current,V=T.current,U=H[M-1];U&&V&&V(U)}}}}),S.length===0)return Yd(nu,{children:Yd(ys,{dimColor:!0,children:n})});let N=_>0,B=_+o<S.length;return _i(nu,{flexDirection:"column",children:[N&&_i(ys,{dimColor:!0,children:[" \u2191 ",_," more"]}),O.map((D,F)=>{let M=_+F,H=M===v,V=m?M<9?`${M+1} `:" ":"";return _i(nu,{flexDirection:"column",children:[_i(nu,{children:[m&&Yd(ys,{dimColor:!0,children:V}),_i(ys,{color:H&&w?"cyan":void 0,bold:H&&w,children:[H?"\u276F ":" ",D.icon?`${D.icon} `:"",D.label,!l&&D.description&&_i(ys,{dimColor:!0,children:[" ",D.description]})]})]}),l&&D.description&&_i(ys,{dimColor:!0,children:[" ",D.description]})]},D.key)}),B&&_i(ys,{dimColor:!0,children:[" \u2193 ",S.length-_-o," more"]})]})}import{useState as ou,useMemo as CR,useCallback as iu,useRef as su,useEffect as wR}from"react";import{Box as au,Text as la,useInput as TR}from"ink";import{TextInput as ER}from"@inkjs/ui";import{jsx as Wo,jsxs as Wd}from"react/jsx-runtime";function vi({items:t,onSelect:e,onHighlight:r,searchPlaceholder:n="Search...",emptyLabel:o="No items",noResultsLabel:i="No matches",visibleCount:s=8,focusLabel:a,isFocused:c,numberNav:l=!1,initialSearchTerm:m="",initialHighlightedKey:d,onFilterChange:u,onCancel:p}){let g=c!==void 0,h=A({label:a??"SearchableList",skip:g}),f=g?c:h.isFocused,[w,S]=ou(m),[E,T]=ou(!1),[R,x]=ou(0),[C,b]=ou(d),v=su(E),P=su(u);P.current=u;let _=CR(()=>{if(!w.trim())return t;let j=w.toLowerCase().trim();return t.filter(Q=>Q.label.toLowerCase().includes(j)||(Q.description?.toLowerCase().includes(j)??!1))},[t,w]),O=su(E),N=su(w);O.current=E,N.current=w;let B=iu(j=>{S(j),P.current&&P.current({searchTerm:j,highlightedKey:C})},[C]),D=iu(()=>{T(!1)},[]),F=iu(()=>{S(""),x(j=>j+1),P.current&&P.current({searchTerm:"",highlightedKey:C})},[C]),M=iu(j=>{b(j.key),P.current&&P.current({searchTerm:N.current,highlightedKey:j.key}),r&&r(j)},[r]);TR((j,Q)=>{if(f){if(j==="/"&&!O.current){T(!0);return}if(Q.escape){if(O.current){N.current?F():T(!1);return}p&&p();return}}}),wR(()=>{v.current=E},[E]);let H=t.length>0,V=_.length>0,U=w.trim().length>0;return Wd(au,{flexDirection:"column",gap:1,children:[Wd(au,{children:[Wo(la,{dimColor:!E,children:"/"}),Wo(au,{marginLeft:1,flexGrow:1,children:E?Wo(ER,{placeholder:n,defaultValue:w,onChange:B,onSubmit:D},R):Wo(la,{dimColor:!0,children:w||n})}),U&&Wd(la,{dimColor:!0,children:[" (",_.length," matches)"]})]}),H?V?Wo(dt,{items:_,onSelect:e,onHighlight:M,visibleCount:s,isFocused:f&&!E,numberNav:l,defaultValue:C}):Wo(la,{dimColor:!0,children:i}):Wo(la,{dimColor:!0,children:o}),Wo(au,{children:Wo(la,{dimColor:!0,children:E?"[Esc] "+(w?"Clear":"Exit search"):"[/] Search"})})]})}import{Box as vj,Text as Dj}from"ink";import{jsx as Fj,jsxs as Nj}from"react/jsx-runtime";import{Box as xx,Text as cu}from"ink";import{jsx as bx,jsxs as lu}from"react/jsx-runtime";var RR={pending:{icon:"\u25CB",color:"gray"},running:{icon:"\u25CF",color:"blue"},success:{icon:"\u2713",color:"green"},error:{icon:"\u2717",color:"red"},warning:{icon:"\u26A0",color:"yellow"},skipped:{icon:"\u2212",color:"gray"}};function lr({items:t,showIcons:e=!0,maxVisible:r}){let n=r?t.slice(-r):t,o=r?Math.max(0,t.length-r):0;return lu(xx,{flexDirection:"column",children:[o>0&&lu(cu,{dimColor:!0,children:["... ",o," more items above"]}),n.map((i,s)=>{let a=RR[i.status],c=i.key??`${i.label}-${s}`;return lu(xx,{gap:1,children:[e&&bx(cu,{color:a.color,children:a.icon}),bx(cu,{children:i.label}),i.detail&&lu(cu,{dimColor:!0,children:["(",i.detail,")"]})]},c)})]})}import{useState as ua,useCallback as hs,useMemo as Sx,useId as _R,useEffect as vR,useRef as DR}from"react";import{Box as Go,Text as Xn,useInput as wx}from"ink";import{TextInput as Cx}from"@inkjs/ui";import{Fragment as NR,jsx as un,jsxs as ho}from"react/jsx-runtime";function PR({options:t,value:e,onChange:r,isActive:n,onConfirm:o}){let i=Sx(()=>{let p=t.findIndex(g=>g.value===e);return p>=0?p:0},[t,e]),[s,a]=ua(i);vR(()=>{a(i)},[i]),wx((p,g)=>{if(n){if(g.upArrow){a(h=>h>0?h-1:t.length-1);return}if(g.downArrow){a(h=>h<t.length-1?h+1:0);return}if(g.return){let h=t[s];h&&(r(h.value),o())}}});let c=4,l=Sx(()=>{if(t.length<=c)return 0;let p=Math.floor(c/2),g=s-p;return g<0&&(g=0),g>t.length-c&&(g=t.length-c),g},[s,t.length]),m=t.slice(l,l+c),d=l>0,u=l+c<t.length;return ho(Go,{flexDirection:"column",children:[d&&un(Xn,{dimColor:!0,children:" \u2191 more"}),m.map((p,g)=>{let f=l+g===s,w=p.value===e;return un(Go,{children:ho(Xn,{color:f&&n?"cyan":void 0,bold:f&&n,children:[f?"\u276F ":" ",p.label,w&&!f&&" \u2713"]})},p.value)}),u&&un(Xn,{dimColor:!0,children:" \u2193 more"})]})}function Ke({fields:t,onSubmit:e,onCancel:r,submitLabel:n="Submit",focusLabel:o="Form",busy:i=!1,busyLabel:s="Working...",statusError:a}){let{isFocused:c}=A(o),l=_R(),[m,d]=ua(0),[u,p]=ua(()=>{let N={};for(let B of t)B.defaultValue!==void 0?N[B.key]=B.defaultValue:B.type==="checkbox"?N[B.key]=!1:N[B.key]="";return N}),[g,h]=ua({}),[f,w]=ua(!1),[S,E]=ua(!1),T=t[m],R=hs(()=>{d(N=>(N+1)%t.length)},[t.length]),x=hs(()=>{d(N=>(N-1+t.length)%t.length)},[t.length]),C=hs((N,B)=>{p(D=>({...D,[N]:B})),h(D=>{if(!D[N])return D;let F={...D};return delete F[N],F})},[]),b=DR({}),v=hs(N=>(b.current[N]||(b.current[N]=B=>C(N,B)),b.current[N]),[C]),P=hs(()=>{let N={};for(let B of t){let D=u[B.key];if(B.required&&(D===""||D===void 0)){N[B.key]="Required";continue}if(B.validate){let F=B.validate(D??"");F&&(N[B.key]=F)}}return h(N),Object.keys(N).length===0},[t,u]),_=hs(()=>{i||S||(w(!0),E(!0),P()?e(u):E(!1))},[i,S,P,u,e]),O=hs(()=>{let N=t[m];if(!N)return;let B=u[N.key];(N.type==="checkbox"?B===!0:typeof B=="string"&&B!=="")?C(N.key,N.type==="checkbox"?!1:""):r?.()},[m,t,u,C,r]);return wx((N,B)=>{if(!c)return;let D=T?.type,F=D==="select",M=D==="text"||D==="password";if(B.tab){R();return}if(!F){if(B.downArrow){R();return}if(B.upArrow){x();return}}if(B.return&&!F&&!M){_();return}if(B.escape){O();return}D==="checkbox"&&N===" "&&T&&C(T.key,!u[T.key])}),ho(Go,{flexDirection:"column",gap:1,children:[t.map((N,B)=>{let D=B===m&&c,F=g[N.key],M=u[N.key];return ho(Go,{flexDirection:"column",children:[un(Go,{gap:1,children:ho(Xn,{color:D?"cyan":"white",children:[D?"\u203A ":" ",N.label,N.required&&un(Xn,{color:"red",children:"*"})]})}),ho(Go,{marginLeft:2,children:[N.type==="text"&&un(Cx,{placeholder:N.placeholder??"",defaultValue:String(N.defaultValue??""),onChange:v(N.key),onSubmit:_,isDisabled:!D}),N.type==="password"&&un(Cx,{placeholder:N.placeholder??"",defaultValue:String(N.defaultValue??""),onChange:v(N.key),onSubmit:_,isDisabled:!D}),N.type==="select"&&N.options&&un(PR,{options:N.options,value:String(M??""),onChange:v(N.key),isActive:D,onConfirm:R}),N.type==="checkbox"&&ho(Xn,{children:[M?"\u2611":"\u2610"," ",M?"Yes":"No"]})]}),F&&f&&un(Go,{marginLeft:2,children:un(Xn,{color:"red",children:F})})]},N.key)}),ho(Go,{marginTop:1,justifyContent:"space-between",children:[un(Go,{gap:2,children:i?un(Xn,{dimColor:!0,children:s}):ho(NR,{children:[ho(Xn,{dimColor:!0,children:["[Enter] ",n]}),un(Xn,{dimColor:!0,children:"[Esc] Cancel"}),un(Xn,{dimColor:!0,children:"[\u2191\u2193] Navigate"})]})}),a&&ho(Xn,{color:"red",children:["\u2718 ",a]})]})]})}import{TextInput as FR}from"@inkjs/ui";import{Spinner as $,ProgressBar as qR,Alert as Xd,StatusMessage as _e,Badge as KR}from"@inkjs/ui";import{createContext as BR,useContext as LR,useState as IR,useCallback as Tx,useEffect as OR}from"react";import{Box as AR,Text as MR}from"ink";import{jsx as Gd,jsxs as HR}from"react/jsx-runtime";var Ex=BR(null),$R={success:{icon:"\u2713",color:"green"},error:{icon:"\u2718",color:"red"},info:{icon:"\u2139",color:"blue"},warning:{icon:"\u26A0",color:"yellow"}};function jR({toast:t}){let e=$R[t.variant];return Gd(AR,{children:HR(MR,{color:e.color,children:[e.icon," ",t.message]})})}function uu({children:t}){let[e,r]=IR(null);OR(()=>{if(!e)return;let i=e.duration??3e3,s=setTimeout(()=>{r(null)},i);return()=>clearTimeout(s)},[e]);let n=Tx(i=>{let s=`toast-${Date.now()}`;r({id:s,...i})},[]),o=Tx(()=>{r(null)},[]);return Gd(Ex.Provider,{value:{toast:e,showToast:n,dismissToast:o},children:t})}function q(){let t=LR(Ex);if(!t)throw new Error("useToast must be used within a ToastProvider");return t}function mu(){let{toast:t}=q();return t?Gd(jR,{toast:t}):null}import{useState as VR}from"react";import{Box as Rx,Text as zd,useInput as UR}from"ink";import{jsx as kx,jsxs as du}from"react/jsx-runtime";var YR={default:"cyan",danger:"red",warning:"yellow"};function ee({message:t,title:e="Confirm",onConfirm:r,onCancel:n,defaultChoice:o="confirm",variant:i="default",focusLabel:s="Confirm",isFocused:a}){let c=a!==void 0,l=A({label:s,skip:c}),m=c?a:l.isFocused,[d,u]=VR(o==="confirm"?"yes":"no");return UR((p,g)=>{if(m){if(p.toLowerCase()==="y"){r();return}if(p.toLowerCase()==="n"){n();return}if(g.leftArrow||g.rightArrow){u(h=>h==="yes"?"no":"yes");return}if(g.tab){u(h=>h==="yes"?"no":"yes");return}if(g.return){d==="yes"?r():n();return}g.escape&&n()}}),kx(y,{title:e,borderColor:YR[i],paddingX:2,paddingY:1,children:du(Rx,{flexDirection:"column",gap:1,children:[kx(zd,{children:t}),du(Rx,{gap:2,children:[du(zd,{color:d==="yes"?"green":void 0,bold:d==="yes",children:[d==="yes"?"\u276F ":" ","Yes (y)"]}),du(zd,{color:d==="no"?"red":void 0,bold:d==="no",children:[d==="no"?"\u276F ":" ","No (n)"]})]})]})})}import{useState as _x,useCallback as WR,useRef as GR}from"react";import{Box as Jd,Text as Di,useInput as XR}from"ink";import{TextInput as zR}from"@inkjs/ui";import{jsx as Xo,jsxs as pu}from"react/jsx-runtime";function pt({configName:t,action:e,onConfirm:r,onCancel:n,focusLabel:o="ProtectedConfirm",isFocused:i}){let s=i!==void 0,a=A({label:o,skip:s}),c=s?i:a.isFocused,l=`yes-${t}`,[m,d]=_x(""),[u,p]=_x(null),h=GR(w=>{d(w),p(null)}).current,f=WR(()=>{m===l?r():p(`Type "${l}" to confirm`)},[m,l,r]);return XR((w,S)=>{c&&(S.escape&&(m?(d(""),p(null)):n()),S.return&&f())}),Xo(y,{title:"Protected Configuration",borderColor:"red",paddingX:2,paddingY:1,children:pu(Jd,{flexDirection:"column",gap:1,children:[pu(Di,{children:["You are about to"," ",Xo(Di,{color:"red",bold:!0,children:e})," ","the protected configuration"," ",Xo(Di,{color:"yellow",bold:!0,children:t}),"."]}),pu(Di,{children:["Type"," ",Xo(Di,{color:"cyan",bold:!0,children:l})," ","to confirm:"]}),Xo(Jd,{marginTop:1,children:Xo(zR,{placeholder:l,defaultValue:m,onChange:h,isDisabled:!c})}),u&&Xo(Di,{color:"red",children:u}),pu(Jd,{marginTop:1,gap:2,children:[Xo(Di,{dimColor:!0,children:"[Enter] Confirm"}),Xo(Di,{dimColor:!0,children:"[Esc] Cancel"})]})]})})}import{useState as Sc,useCallback as xs,useMemo as vx}from"react";import{Box as ma,Text as xo,useInput as JR}from"ink";import{TextInput as QR}from"@inkjs/ui";import{jsx as bo,jsxs as Pi}from"react/jsx-runtime";function ZR(t,e){if(!e.trim())return t;let r=e.toLowerCase().split(/\s+/).filter(Boolean),n=t;for(let o of r)n=n.filter(i=>i.toLowerCase().includes(o));return n}function fu({files:t,selected:e=[],onSelect:r,onCancel:n,visibleCount:o=8,focusLabel:i="FilePicker"}){let{isFocused:s}=A(i),[a,c]=Sc("search"),[l,m]=Sc(""),[d,u]=Sc(()=>new Set(e)),[p,g]=Sc(0),[h,f]=Sc(0),w=vx(()=>ZR(t,l),[t,l]),S=vx(()=>w.slice(h,h+o),[w,h,o]),E=a==="search"?"Search":a==="select"?"Select":"Accept",T=xs(_=>{u(O=>{let N=new Set(O);return N.has(_)?N.delete(_):N.add(_),N})},[]),R=xs(()=>{c(_=>_==="search"?"select":_==="select"?"accept":"search")},[]),x=xs(()=>{if(p>0)g(_=>_-1),p<=h&&f(_=>Math.max(0,_-1));else if(w.length>0){let _=w.length-1;g(_),f(Math.max(0,_-o+1))}},[p,h,w.length,o]),C=xs(()=>{p<w.length-1?(g(_=>_+1),p>=h+o-1&&f(_=>_+1)):w.length>0&&(g(0),f(0))},[p,h,w.length,o]),b=xs(()=>{if(a==="accept")r(Array.from(d));else if(a==="select"){let _=w[p];_&&T(_)}else R()},[a,d,w,p,T,R,r]),v=xs(()=>{a==="search"&&l?(m(""),g(0),f(0)):n()},[a,l,n]);JR((_,O)=>{if(s){if(O.tab){R();return}if(O.escape){v();return}if(O.return){b();return}if(a==="select"){if(O.upArrow){x();return}if(O.downArrow){C();return}if(_===" "){let N=w[p];N&&T(N)}}}});let P=xs(_=>{m(_),g(0),f(0)},[]);return bo(y,{title:`Select Files [${E} Mode]`,borderColor:"cyan",paddingX:1,paddingY:1,children:Pi(ma,{flexDirection:"column",gap:1,children:[Pi(ma,{gap:1,children:[bo(xo,{dimColor:!0,children:"Search:"}),a==="search"?bo(QR,{placeholder:"Type to filter...",defaultValue:l,onChange:P,isDisabled:!s}):bo(xo,{children:l||"(all files)"})]}),Pi(ma,{flexDirection:"column",children:[h>0&&Pi(xo,{dimColor:!0,children:[" \u2191 ",h," more above"]}),S.map((_,O)=>{let N=h+O,B=a==="select"&&N===p,D=d.has(_);return bo(ma,{children:Pi(xo,{color:B?"cyan":void 0,children:[B?"\u203A ":" ",D?"\u2611 ":"\u2610 ",_]})},_)}),w.length===0&&bo(xo,{dimColor:!0,children:" No files match search"}),h+o<w.length&&Pi(xo,{dimColor:!0,children:[" ","\u2193 ",w.length-h-o," more below"]})]}),bo(ma,{children:Pi(xo,{dimColor:!0,children:[w.length," files shown (",d.size," selected)"]})}),Pi(ma,{gap:2,children:[bo(xo,{dimColor:!0,children:"[Tab] switch mode"}),a==="select"&&bo(xo,{dimColor:!0,children:"[Space] toggle"}),a==="accept"&&bo(xo,{dimColor:!0,children:"[Enter] accept"}),bo(xo,{dimColor:!0,children:"[Esc] cancel"})]})]})})}import{Box as Cc,Text as da}from"ink";import{Badge as Dx}from"@inkjs/ui";import{jsx as zo,jsxs as gu}from"react/jsx-runtime";var ek={free:{label:"UNLOCKED",color:"green"},locked:{label:"LOCKED",color:"red"},blocked:{label:"BLOCKED",color:"yellow"},expired:{label:"EXPIRED",color:"yellow"}};function Px(t){let e=Date.now(),r=t.getTime()-e,n=Math.abs(r),o=Math.floor(n/6e4),i=Math.floor(o/60);if(i>0){let a=`${i}h ${o%60}m`;return r>0?`in ${a}`:`${a} ago`}let s=`${o}m`;return r>0?`in ${s}`:`${s} ago`}function pa({status:t,holder:e,since:r,expires:n,compact:o=!1}){let i=ek[t];return o?zo(Dx,{color:i.color,children:i.label}):gu(Cc,{flexDirection:"column",gap:1,children:[zo(Cc,{gap:1,children:zo(Dx,{color:i.color,children:i.label})}),e&&t!=="free"&&gu(Cc,{gap:1,children:[zo(da,{dimColor:!0,children:"Holder:"}),zo(da,{children:e})]}),r&&t!=="free"&&gu(Cc,{gap:1,children:[zo(da,{dimColor:!0,children:"Since:"}),zo(da,{children:Px(r)})]}),n&&t==="locked"&&gu(Cc,{gap:1,children:[zo(da,{dimColor:!0,children:"Expires:"}),zo(da,{children:Px(n)})]})]})}import{Box as fa,Text as bs}from"ink";import{Badge as Nx}from"@inkjs/ui";import{jsx as Jo,jsxs as ga}from"react/jsx-runtime";var tk={disconnected:{label:"DISCONNECTED",color:"yellow"},connecting:{label:"CONNECTING",color:"blue"},connected:{label:"CONNECTED",color:"green"},error:{label:"ERROR",color:"red"}};function wc({status:t,configName:e,dialect:r,error:n,compact:o=!1}){let i=tk[t];return o?ga(fa,{gap:1,children:[Jo(Nx,{color:i.color,children:i.label}),e&&t==="connected"&&ga(bs,{dimColor:!0,children:["(",e,")"]})]}):ga(fa,{flexDirection:"column",gap:1,children:[Jo(fa,{gap:1,children:Jo(Nx,{color:i.color,children:i.label})}),e&&t==="connected"&&ga(fa,{gap:1,children:[Jo(bs,{dimColor:!0,children:"Config:"}),Jo(bs,{children:e})]}),r&&t==="connected"&&ga(fa,{gap:1,children:[Jo(bs,{dimColor:!0,children:"Dialect:"}),Jo(bs,{children:r})]}),n&&t==="error"&&ga(fa,{gap:1,children:[Jo(bs,{dimColor:!0,children:"Error:"}),Jo(bs,{color:"red",children:n})]})]})}import{useMemo as rk}from"react";var yu=[{label:"String",value:"string"},{label:"Password",value:"password"},{label:"API Key",value:"api_key"},{label:"Connection String",value:"connection_string"}],Qd=/^[A-Za-z][A-Za-z0-9_]*$/;function hu(t){let e=t.trim();if(!e)return"Key is required";if(!Qd.test(e))return"Key must start with a letter, contain only letters, numbers, underscores"}function xu(t,e){let r=t.trim();if(e.includes(r))return"Secret key already exists"}import{jsx as nk}from"react/jsx-runtime";function ya({existingSecret:t,existingKeys:e,isAddMode:r,onSubmit:n,onCancel:o,busy:i=!1,error:s=null,focusLabel:a="SecretDefinitionForm"}){let c=rk(()=>[{key:"key",label:"Secret Key",type:"text",required:!0,defaultValue:t?.key??"",placeholder:"e.g., DB_PASSWORD, api_key",validate:m=>{if(typeof m!="string")return"Key is required";let d=m.trim(),u=hu(d);if(u)return u;if(r){let p=xu(d,e);if(p)return p}}},{key:"type",label:"Secret Type",type:"select",required:!0,options:[...yu],defaultValue:t?.type??"string"},{key:"description",label:"Description",type:"text",defaultValue:t?.description??"",placeholder:"e.g., Database password for production"},{key:"required",label:"Required",type:"checkbox",defaultValue:t?.required!==!1}],[t,r,e]);return nk(Ke,{fields:c,onSubmit:m=>{let u={key:String(m.key).trim(),type:String(m.type),description:m.description?String(m.description):void 0,required:!!m.required};n(u)},onCancel:o,submitLabel:r?"Create":"Save Changes",focusLabel:a,busy:i,busyLabel:"Saving...",statusError:s??void 0})}import{useState as bu,useCallback as Su,useMemo as Fx,useEffect as Bx}from"react";import{Box as Tc,Text as So,useInput as ok}from"ink";import{jsx as vn,jsxs as ha}from"react/jsx-runtime";function xa({secrets:t,scopeLabel:e,onAdd:r,onEdit:n,onDelete:o,deleteWarning:i,isFocused:s,onBack:a}){let[c,l]=bu(null),[m,d]=bu(null),[u,p]=bu(!1),[g,h]=bu(new Set),f=Fx(()=>g.size===0?t:t.filter(x=>!g.has(x.key)),[t,g]);Bx(()=>{g.size>0&&h(new Set)},[t]);let w=Fx(()=>f.length===0?[]:f.map(x=>({key:x.key,label:x.key,value:{key:x.key,type:x.type,description:x.description,required:x.required!==!1},description:`(${x.type})${x.required===!1?" [optional]":""}`,icon:x.required!==!1?"\u25CF":"\u25CB"})),[f]);Bx(()=>{if(w.length===0){l(null);return}c&&w.some(C=>C.value.key===c)||l(w[0].value.key)},[w,c]);let S=Su(x=>{g.has(x.value.key)||n(x.value.key)},[n,g]),E=Su(x=>{l(x.value.key)},[]),T=Su(async()=>{if(m){p(!0);try{if(await o(m),h(x=>new Set([...x,m])),c===m){let x=f.filter(C=>C.key!==m);l(x[0]?.key??null)}}finally{p(!1),d(null)}}},[m,o,c,f]),R=Su(()=>{d(null)},[]);if(ok((x,C)=>{if(!(!s||m)){if(C.escape){a();return}if(x==="a"){r();return}if(!(!c||g.has(c))){if(x==="e"){n(c);return}if(x==="d"){d(c);return}}}}),m){let x=f.find(C=>C.key===m);return vn(Tc,{flexDirection:"column",gap:1,children:vn(y,{title:"Delete Secret Definition",paddingX:2,paddingY:1,borderColor:"yellow",children:ha(Tc,{flexDirection:"column",gap:1,children:[x?.description&&vn(So,{dimColor:!0,children:x.description}),i&&ha(So,{color:"yellow",children:["Warning: ",i]}),vn(ee,{message:`Delete secret definition "${m}"?`,onConfirm:T,onCancel:R,variant:"warning",isFocused:s&&!u})]})})})}return ha(Tc,{flexDirection:"column",gap:1,children:[vn(So,{dimColor:!0,children:e==="universal"?"These secret definitions apply to all stages.":`Secret definitions for ${e}.`}),w.length===0?ha(Tc,{flexDirection:"column",gap:1,children:[vn(So,{dimColor:!0,children:"No secrets defined."}),ha(So,{children:["Press ",vn(So,{color:"cyan",children:"a"})," to add a secret definition."]})]}):vn(dt,{items:w,onSelect:S,onHighlight:E,isFocused:s,visibleCount:8,showDescriptionBelow:!0})]})}function ba(){return ha(Tc,{gap:2,flexWrap:"wrap",children:[vn(So,{dimColor:!0,children:"[a] Add"}),vn(So,{dimColor:!0,children:"[e] Edit"}),vn(So,{dimColor:!0,children:"[d] Delete"}),vn(So,{dimColor:!0,children:"[Enter] Edit"}),vn(So,{dimColor:!0,children:"[Esc] Back"})]})}import{useMemo as ik}from"react";import{Box as Zd,Text as Cu}from"ink";import{jsx as Sa,jsxs as Lx}from"react/jsx-runtime";function wu({secretKey:t,secretDefinition:e,unsetRequired:r=[],secretExists:n=!1,onSubmit:o,onCancel:i,busy:s=!1,error:a=null,focusLabel:c="SecretValueForm"}){let l=!t,m=ik(()=>{let u=[];if(l){let g="e.g., MY_SECRET_KEY";r.length>0&&(g=r.slice(0,3).map(f=>f.key).join(", ")+(r.length>3?"...":"")),u.push({key:"secretKey",label:"Secret Key",type:"text",required:!0,placeholder:g,validate:h=>{let f=String(h).trim();if(!f)return"Key is required";if(!/^[A-Za-z][A-Za-z0-9_]*$/.test(f))return"Key must start with letter, contain only letters, numbers, underscores"}})}let p=e?.type==="password"||e?.type==="api_key";return u.push({key:"value",label:"Value",type:p?"password":"text",required:!0,placeholder:e?.description??"Enter secret value",validate:g=>{let h=String(g).trim();if(!h)return"Value is required";if(e?.type==="connection_string")try{new URL(h)}catch{return"Invalid connection string (must be a valid URI)"}}}),u},[l,r,e]),d=u=>{let p=t;if(p||(p=String(u.secretKey??"").trim()),!p)return;let g=String(u.value??"").trim();o(p,g)};return Lx(Zd,{flexDirection:"column",gap:1,children:[e?.description&&Sa(Cu,{dimColor:!0,children:e.description}),n&&Sa(Cu,{color:"yellow",children:"This will overwrite the existing value."}),l&&r.length>0&&Lx(Zd,{flexDirection:"column",children:[Sa(Cu,{dimColor:!0,children:"Missing required secrets:"}),Sa(Zd,{gap:1,flexWrap:"wrap",children:r.map(u=>Sa(Cu,{color:"yellow",children:u.key},u.key))})]}),Sa(Ke,{fields:m,onSubmit:d,onCancel:i,submitLabel:"Save",focusLabel:c,busy:s,busyLabel:"Saving secret...",statusError:a??void 0})]})}import{useState as sk,useCallback as Ix,useMemo as Ox,useEffect as ak}from"react";import{Box as Tu,Text as Co,useInput as ck}from"ink";import{jsx as Fi,jsxs as Ni}from"react/jsx-runtime";function Eu({secrets:t,summary:e,onAdd:r,onEdit:n,onDelete:o,canDelete:i,onDeleteBlocked:s,isFocused:a,onBack:c}){let[l,m]=sk(null),d=Ox(()=>{if(e)return e;let h=t.filter(S=>S.isRequired).length,f=t.filter(S=>S.isRequired&&!S.isSet).length,w=t.filter(S=>!S.isRequired).length;return{required:h,missing:f,optional:w}},[e,t]),u=Ox(()=>t.map(h=>{let f="";h.isRequired&&(f=`(${h.type??"string"})`,h.isSet||(f+=" [missing]")),h.maskedValue&&(f+=` ${h.maskedValue}`);let w=f?`${h.key} ${f}`:h.key;return{key:h.key,label:w,value:h,description:h.description,icon:h.isSet?"\u2713":"\u2717"}}),[t]);ak(()=>{if(u.length===0){m(null);return}l&&u.some(f=>f.value.key===l)||m(u[0]?.value.key??null)},[u,l]);let p=Ix(h=>{n(h.value.key)},[n]),g=Ix(h=>{m(h.value.key)},[]);return ck((h,f)=>{if(a){if(f.escape){c();return}if(h==="a"){r();return}if(l){if(h==="d"){if(i&&!i(l)){s?.(l);return}o(l);return}if(h==="e"){n(l);return}}}}),Ni(Tu,{flexDirection:"column",gap:1,children:[Ni(Tu,{gap:2,children:[d.required>0&&Ni(Co,{children:["Required: ",d.required-d.missing,"/",d.required,d.missing>0&&Ni(Co,{color:"yellow",children:[" (",d.missing," missing)"]})]}),d.optional>0&&Ni(Co,{dimColor:!0,children:["Optional: ",d.optional]})]}),t.length===0?Ni(Tu,{flexDirection:"column",gap:1,children:[Fi(Co,{dimColor:!0,children:"No secrets defined."}),Ni(Co,{children:["Press ",Fi(Co,{color:"cyan",children:"a"})," to add a secret."]})]}):Fi(dt,{items:u,onSelect:p,onHighlight:g,isFocused:a,visibleCount:10,showDescriptionBelow:!0})]})}function Ru(){return Ni(Tu,{gap:2,flexWrap:"wrap",children:[Fi(Co,{dimColor:!0,children:"[a] Add"}),Fi(Co,{dimColor:!0,children:"[e] Edit"}),Fi(Co,{dimColor:!0,children:"[d] Delete"}),Fi(Co,{dimColor:!0,children:"[Enter] Edit"}),Fi(Co,{dimColor:!0,children:"[Esc] Back"})]})}import{useState as Ss,useEffect as tp,useCallback as dk,useRef as pk,useMemo as fk}from"react";import{Box as mn,Text as Bt,useInput as gk}from"ink";import*as Ax from"fs/promises";import{attempt as lk,attemptSync as uk}from"@logosdx/utils";async function ep(t,e={}){let{limit:r=500}=e,[n,o]=await lk(()=>Ax.readFile(t,"utf-8"));if(o)return{entries:[],totalLines:0,hasMore:!1};let i=n.trim().split(`
|
|
1031
|
+
`).filter(Boolean),s=i.length;if(s===0)return{entries:[],totalLines:0,hasMore:!1};let a=Math.max(0,i.length-r),c=i.slice(a),l=[];for(let m=c.length-1;m>=0;m--){let d=c[m];if(!d)continue;let[u,p]=uk(()=>JSON.parse(d));!p&&u&&mk(u)&&l.push(u)}return{entries:l,totalLines:s,hasMore:a>0}}function mk(t){if(typeof t!="object"||t===null)return!1;let e=t;return typeof e.time=="string"&&typeof e.level=="string"&&typeof e.type=="string"&&typeof e.message=="string"}import{jsx as it,jsxs as No}from"react/jsx-runtime";var yk=2e3,ku=12,hk=".noorm/noorm.log";function xk(t){switch(t){case"error":return"red";case"warn":return"yellow";case"info":return"green";case"debug":return"gray";default:return"white"}}function bk(t){try{return new Date(t).toLocaleTimeString("en-US",{hour12:!1})}catch{return t.slice(11,19)}}function _u({onClose:t}){let{isFocused:e}=A("LogViewerOverlay"),{settings:r}=L(),[n,o]=Ss([]),[i,s]=Ss(!0),[a,c]=Ss(""),[l,m]=Ss(!1),[d,u]=Ss(0),[p,g]=Ss(!1),[h,f]=Ss(!1),w=pk(a);w.current=a;let S=r?.logging?.file??hk,E=dk(async()=>{let C=await ep(S,{limit:500});o(C.entries),s(!1)},[S]);tp(()=>{E()},[E]),tp(()=>{if(h)return;let C=setInterval(E,yk);return()=>clearInterval(C)},[E,h]);let T=fk(()=>{if(!a)return n;let C=a.toLowerCase();return n.filter(b=>b.type.toLowerCase().includes(C)||b.message.toLowerCase().includes(C)||b.level.toLowerCase().includes(C))},[n,a]);tp(()=>{u(0)},[a]),gk((C,b)=>{if(e){if(b.escape){if(p){g(!1);return}if(l){m(!1),c("");return}t();return}if(!p){if(l){b.backspace||b.delete?c(v=>v.slice(0,-1)):b.return?m(!1):C&&!b.ctrl&&!b.meta&&C.length===1&&c(v=>v+C);return}if(C==="/"){m(!0);return}if(C===" "){f(v=>!v);return}if(C==="r"||C==="R"){E();return}if(C==="g"){u(0);return}if(C==="G"){u(Math.max(0,T.length-1));return}b.upArrow?u(v=>Math.max(0,v-1)):b.downArrow?u(v=>Math.min(T.length-1,v+1)):b.pageUp?u(v=>Math.max(0,v-ku)):b.pageDown&&u(v=>Math.min(T.length-1,v+ku)),b.return&&T[d]&&g(!0)}}});let R=Math.max(0,d-Math.floor(ku/2)),x=T.slice(R,R+ku);if(p&&T[d]){let C=T[d];return No(mn,{flexDirection:"column",minHeight:20,children:[No(mn,{borderStyle:"single",borderBottom:!0,borderTop:!1,borderLeft:!1,borderRight:!1,borderColor:"blue",paddingX:1,gap:2,children:[it(Bt,{bold:!0,color:"blue",children:"Log Entry Detail"}),it(Bt,{dimColor:!0,children:"[Esc] Back"})]}),it(mn,{flexDirection:"column",paddingX:1,paddingY:1,flexGrow:1,children:it(Bt,{wrap:"wrap",children:JSON.stringify(C,null,2)})}),it(mn,{borderStyle:"single",borderTop:!0,borderBottom:!1,borderLeft:!1,borderRight:!1,borderColor:"gray",paddingX:1,children:it(Bt,{dimColor:!0,children:"[Esc] Back to list"})})]})}return No(mn,{flexDirection:"column",minHeight:20,children:[No(mn,{borderStyle:"single",borderBottom:!0,borderTop:!1,borderLeft:!1,borderRight:!1,borderColor:"blue",paddingX:1,gap:2,children:[it(Bt,{bold:!0,color:"blue",children:"Logs"}),h?it(Bt,{color:"yellow",children:"PAUSED"}):it(Bt,{color:"green",children:"LIVE"}),No(Bt,{dimColor:!0,children:["(",T.length," entries)"]})]}),No(mn,{paddingX:1,paddingTop:1,children:[it(Bt,{dimColor:!0,children:"/"}),l?No(Bt,{children:[a,it(Bt,{inverse:!0,children:" "})]}):it(Bt,{dimColor:!0,children:a||" type / to search"})]}),it(mn,{flexDirection:"column",paddingX:1,paddingY:1,flexGrow:1,children:i?it($,{label:"Loading logs..."}):T.length===0?it(Bt,{dimColor:!0,children:n.length===0?"No log entries found":"No entries match your search"}):it(mn,{flexDirection:"column",children:x.map((C,b)=>{let v=R+b,P=v===d;return No(mn,{gap:1,children:[it(Bt,{inverse:P,children:P?">":" "}),it(mn,{width:8,children:it(Bt,{dimColor:!0,children:bk(C.time)})}),it(mn,{width:6,children:it(Bt,{color:xk(C.level),children:C.level.toUpperCase().padEnd(5)})}),it(mn,{width:25,children:it(Bt,{color:"cyan",children:C.type.slice(0,24)})}),it(Bt,{children:C.message.slice(0,45)})]},`${C.time}-${v}`)})})}),No(mn,{borderStyle:"single",borderTop:!0,borderBottom:!1,borderLeft:!1,borderRight:!1,borderColor:"gray",paddingX:1,gap:2,children:[it(Bt,{dimColor:!0,children:"[/] Search"}),it(Bt,{dimColor:!0,children:"[g/G] Top/Bottom"}),No(Bt,{dimColor:!0,children:["[Space] ",h?"Resume":"Pause"]}),it(Bt,{dimColor:!0,children:"[Enter] Detail"}),it(Bt,{dimColor:!0,children:"[Shift+L] Close"})]})]})}import{useState as Mx,useRef as Sk,useEffect as Ck}from"react";import{Box as vu,Text as Cs,useInput as wk}from"ink";import{jsx as Ca,jsxs as Ec}from"react/jsx-runtime";function Du({value:t,onChange:e,onSubmit:r,onHistoryNavigate:n,disabled:o=!1,active:i=!0,historyBrowsing:s=!1,placeholder:a="Enter SQL query..."}){let c=i&&!o,[l,m]=Mx(!1),[d,u]=Mx(t.length),p=Sk(t);Ck(()=>{t!==p.current&&(u(t.length),p.current=t)},[t]);let g=(C,b)=>{p.current=C,e(C),u(b)};wk((C,b)=>{if(c){if(b.shift&&b.tab){m(v=>!v);return}if(b.escape){l&&m(!1);return}if((b.upArrow||b.downArrow)&&(t.trim()===""||s)){n(b.upArrow?"up":"down");return}if(b.leftArrow){u(v=>Math.max(0,v-1));return}if(b.rightArrow){u(v=>Math.min(t.length,v+1));return}if(!(b.upArrow||b.downArrow)){if(b.return){if(b.shift||l){let v=t.slice(0,d),P=t.slice(d);g(v+`
|
|
1032
|
+
`+P,d+1)}else t.trim()&&r(t);return}if(b.tab&&!b.shift){let v=t.slice(0,d),P=t.slice(d);g(v+" "+P,d+4);return}if(b.backspace||b.delete){if(d>0){let v=t.slice(0,d-1),P=t.slice(d);g(v+P,d-1)}return}if(C){let v=t.slice(0,d),P=t.slice(d);g(v+C+P,d+C.length)}}}});let h=t.split(`
|
|
1033
|
+
`),f=t.length===0&&!o,w=l?"[EDIT]>":">",S=l?"yellow":"cyan",E=0,T=d,R=0;for(let C=0;C<h.length;C++){let b=h[C].length;if(R+b>=d){E=C,T=d-R;break}R+=b+1}let x=(C,b)=>{if(!(c&&b===E))return Ca(Cs,{color:o?"gray":void 0,children:C||" "});let P=C.slice(0,T),_=C[T]??" ",O=C.slice(T+1);return Ec(Cs,{color:o?"gray":void 0,children:[P,Ca(Cs,{inverse:!0,children:_}),O]})};return Ec(vu,{flexDirection:"column",children:[Ca(vu,{flexDirection:"column",children:h.map((C,b)=>Ec(vu,{children:[b===0?Ec(Cs,{color:o?"gray":S,children:[w," "]}):Ec(Cs,{color:"gray",children:[" "," "]}),f&&b===0?Ca(Cs,{dimColor:!0,children:a}):x(C,b)]},b))}),Ca(vu,{marginTop:1,children:Ca(Cs,{dimColor:!0,children:l?"[Shift+Tab] Exit edit [Enter] New line":"[Shift+Tab] Edit mode [Enter] Execute [Shift+Enter] New line"})})]})}import{useState as wa,useMemo as Ta,useCallback as Tk,useEffect as $x}from"react";import{Box as zn,Text as qt,useInput as Ek}from"ink";import{Fragment as Nk,jsx as er,jsxs as zr}from"react/jsx-runtime";var Rk=[/^created[_-]?at$/i,/^updated[_-]?at$/i,/^modified[_-]?at$/i,/^timestamp$/i,/^datetime$/i,/^date$/i,/[_-]at$/i,/[_-]date$/i,/[_-]time$/i,/^created$/i,/^updated$/i,/^modified$/i],kk=[/^id$/i,/^_id$/i,/[_-]id$/i];function _k(t){if(t==null)return!1;if(t instanceof Date)return!0;if(typeof t=="string"){if(/^\d{4}-\d{2}-\d{2}/.test(t)||/^\d{1,2}[/-]\d{1,2}[/-]\d{2,4}/.test(t))return!0;let e=Date.parse(t);if(!isNaN(e)){let r=new Date(e).getFullYear();return r>=1970&&r<=2100}}return typeof t=="number"&&(t>1e9&&t<2e9||t>1e12&&t<2e12)}function vk(t,e){for(let r of Rk)for(let n of t)if(r.test(n)&&e.slice(0,10).some(i=>{let s=i[n];return s!=null}))return n;for(let r of t)if(e.slice(0,5).map(i=>i[r]).filter(_k).length>=3)return r;return null}function Dk(t,e){for(let r of kk)for(let n of t)if(r.test(n)&&e.slice(0,5).map(s=>s[n]).filter(s=>typeof s=="number"||typeof s=="string"&&/^\d+$/.test(s)).length>=1)return n;return null}function Pk(t,e){return t.length<=e?t:t.slice(0,e-1)+"\u2026"}function Pu(t){return t===null?"NULL":t===void 0?"":typeof t=="object"?JSON.stringify(t):String(t)}function Ea({columns:t,rows:e,maxVisibleRows:r=15,maxColumnWidth:n=30,active:o=!0,onEscape:i,autoSort:s=!0}){let a=o,c=Ta(()=>{if(!s||t.length===0||e.length===0)return null;let B=vk(t,e);if(B)return{column:B,direction:"desc"};let D=Dk(t,e);return D?{column:D,direction:"desc"}:null},[s,t,e]),[l,m]=wa("browse"),[d,u]=wa({term:"",column:null}),[p,g]=wa(c),[h,f]=wa(0),[w,S]=wa(0),[E,T]=wa(0);$x(()=>{g(c)},[c]);let R=Ta(()=>{let B={};for(let D of t){let F=D.length;for(let M of e){let H=Pu(M[D]);F=Math.max(F,H.length)}B[D]=Math.min(F,n)}return B},[t,e,n]),x=Ta(()=>{if(!d.term)return e;let B=d.term.toLowerCase();return e.filter(D=>{if(d.column)return Pu(D[d.column]).toLowerCase().includes(B);for(let F of t)if(Pu(D[F]).toLowerCase().includes(B))return!0;return!1})},[e,d,t]),C=Ta(()=>p?[...x].sort((B,D)=>{let F=B[p.column],M=D[p.column];if(F==null)return p.direction==="asc"?1:-1;if(M==null)return p.direction==="asc"?-1:1;let H=0;return typeof F=="number"&&typeof M=="number"?H=F-M:H=String(F).localeCompare(String(M)),p.direction==="asc"?H:-H}):x,[x,p]),b=Ta(()=>C.slice(h,h+r),[C,h,r]);$x(()=>{f(0),S(0)},[d.term,d.column]),Ek((B,D)=>{if(a){if(l==="filter"){if(D.tab){if(d.column===null){let F=t[0];u(M=>({...M,column:F??null}))}else{let M=(t.indexOf(d.column)+1)%(t.length+1),H=M===t.length?null:t[M]??null;u(V=>({...V,column:H}))}return}if(D.escape){u({term:"",column:null}),m("browse");return}if(D.return){m("browse");return}if(D.backspace){u(F=>({...F,term:F.term.slice(0,-1)}));return}if(B&&!D.ctrl&&!D.meta){u(F=>({...F,term:F.term+B}));return}return}if(l==="sort"){if(D.leftArrow){T(F=>F>0?F-1:t.length-1);return}if(D.rightArrow){T(F=>F<t.length-1?F+1:0);return}if(B==="a"){let F=t[E];F&&(g({column:F,direction:"asc"}),m("browse"));return}if(B==="d"){let F=t[E];F&&(g({column:F,direction:"desc"}),m("browse"));return}if(D.escape||D.return){m("browse");return}return}if(D.upArrow){w>0&&(S(F=>F-1),w-1<h&&f(F=>Math.max(0,F-1)));return}if(D.downArrow){w<C.length-1&&(S(F=>F+1),w+1>=h+r&&f(F=>F+1));return}if(B==="/"){m("filter");return}if(B==="s"){m("sort"),T(p?t.indexOf(p.column):0);return}if(B==="c"){u({term:"",column:null}),g(null);return}if(D.escape){i?.();return}}});let v=Tk((B,D,F)=>er(zn,{children:t.map((M,H)=>{let V=R[M]??M.length,j=Pk(Pu(B[M]),V).padEnd(V);return zr(zn,{children:[H>0&&er(qt,{dimColor:!0,children:" | "}),er(qt,{inverse:F,color:void 0,children:j})]},M)})},D),[t,R]),P=Ta(()=>{let B=0;for(let D of t)B+=R[D]??D.length;return B+=(t.length-1)*3,B},[t,R]),_=d.term.length>0,O=p!==null,N=_&&x.length!==e.length;return zr(zn,{flexDirection:"column",children:[zr(zn,{marginBottom:1,gap:2,children:[_&&zr(qt,{children:[er(qt,{dimColor:!0,children:"Filter: "}),zr(qt,{color:"yellow",children:['"',d.term,'"']}),er(qt,{dimColor:!0,children:" in "}),zr(qt,{color:"cyan",children:["[",d.column??"All","]"]})]}),O&&zr(qt,{children:[er(qt,{dimColor:!0,children:"Sort: "}),er(qt,{color:"cyan",children:p.column}),zr(qt,{children:[" ",p.direction==="asc"?"\u2191":"\u2193"]})]}),l==="filter"&&er(qt,{color:"yellow",children:"[Tab] Column [Enter] Apply [Esc] Cancel"}),l==="sort"&&zr(qt,{color:"yellow",children:["[\u2190/\u2192] Column: ",t[E]," [a] Asc [d] Desc"]})]}),C.length===0?er(zn,{children:er(qt,{dimColor:!0,children:_?"No matching rows":"No results"})}):zr(Nk,{children:[er(zn,{children:t.map((B,D)=>{let F=R[B]??B.length,M=B.padEnd(F),H=p?.column===B;return zr(zn,{children:[D>0&&er(qt,{dimColor:!0,children:" | "}),zr(qt,{bold:!0,color:H?"cyan":void 0,children:[M,H&&p&&(p.direction==="asc"?"\u2191":"\u2193")]})]},B)})}),er(zn,{children:er(qt,{dimColor:!0,children:"\u2500".repeat(P)})}),h>0&&er(zn,{children:zr(qt,{dimColor:!0,children:["\u2191 ",h," more above"]})}),b.map((B,D)=>{let F=h+D;return v(B,F,F===w)}),h+r<C.length&&er(zn,{children:zr(qt,{dimColor:!0,children:["\u2193 ",C.length-h-r," more below"]})})]}),er(zn,{marginTop:1,children:zr(qt,{dimColor:!0,children:[C.length," row",C.length!==1?"s":"",N&&` (filtered from ${e.length})`]})}),l==="browse"&&er(zn,{children:er(qt,{dimColor:!0,children:"[/] Filter [s] Sort [c] Clear [\u2191/\u2193] Navigate"})})]})}import rp from"dayjs";import Fk from"dayjs/plugin/relativeTime.js";import Bk from"dayjs/plugin/utc.js";rp.extend(Fk);rp.extend(Bk);function Bi(t){return rp(typeof t=="string"?t:+t).fromNow()}import{Fragment as jx,jsx as Y,jsxs as ye}from"react/jsx-runtime";function Mk(t){let e=t.toLowerCase();return e.includes("does not exist")||e.includes("unknown database")||e.includes("database")&&e.includes("not found")}function Hx({params:t}){let{gracefulExit:e}=Xl(),{navigate:r}=I(),{isFocused:n}=A("home"),{activeConfig:o,activeConfigName:i,configs:s,loadingStatus:a,hasIdentity:c,settings:l,settingsManager:m,stateManager:d}=L(),[u,p]=np({connection:"none",pendingCount:null,lockStatus:null}),[g,h]=np([]),[f,w]=np(!0),S=Ik(()=>{if(!m||!d||!l)return[];let x=l.stages??{},C=[];for(let b of s){let v=x[b.name]?b.name:null;if(!v)continue;let P=m.getRequiredSecrets(v),_=d.listSecrets(b.name),O={};for(let B of _)O[B]=!0;let N=P.filter(B=>!O[B.key]).map(B=>B.key);C.push({configName:b.name,stageName:v,complete:N.length===0,missingSecrets:N})}return C},[s,l,m,d]);Lk(()=>{if(!o||a!=="ready"){w(!1);return}let x=!1;return(async()=>{w(!0),p(_=>({..._,connection:"checking"}));let b=await de(o.connection);if(x)return;if(!b.ok){let _=b.error??"Connection failed";p({connection:Mk(_)?"db-missing":"error",connectionError:_,pendingCount:null,lockStatus:null}),w(!1);return}let[v,P]=await Ak(async()=>{let _=await K(o.connection,i??"__status__"),O=_.db;if(x)return await _.destroy(),null;let B=await mt().status(O,i??""),D=new Oe(O,i??""),F=await At(o.paths.changes,o.paths.sql),M=await D.getAllStatuses(),H=0;for(let U of F){let j=M.get(U.name);(!j||j.status==="pending"||j.status==="reverted")&&H++}let V=await D.getUnifiedHistory(void 0,5);return await _.destroy(),{lockStatus:B,pendingCount:H,history:V}});P?x||p({connection:"error",connectionError:P instanceof Error?P.message:String(P),pendingCount:null,lockStatus:null}):v&&!x&&(p({connection:"connected",pendingCount:v.pendingCount,lockStatus:v.lockStatus}),h(v.history)),w(!1)})(),()=>{x=!0}},[o,i,a]),Ok((x,C)=>{if(n){if(x==="q"){e();return}x==="c"?r("config"):x==="g"?r("change"):x==="r"?r("run"):x==="d"?r("db"):x==="l"?r("lock"):x==="s"?r("settings"):x==="k"?r("secret"):x==="i"?r("identity"):x==="1"?r("run/build"):x==="2"?r("change/ff"):x==="3"&&r("lock/status")}});let E=op(()=>{switch(u.connection){case"checking":return Y($,{label:"Checking..."});case"connected":return ye(Ne,{gap:1,children:[Y(W,{color:"green",children:"\u25CF"}),Y(W,{children:"Connected"})]});case"db-missing":return ye(Ne,{flexDirection:"column",children:[ye(Ne,{gap:1,children:[Y(W,{color:"yellow",children:"\u25CF"}),Y(W,{color:"yellow",children:"Success"})]}),u.connectionError&&ye(W,{dimColor:!0,wrap:"truncate",children:[" ",u.connectionError]})]});case"error":return ye(Ne,{flexDirection:"column",children:[ye(Ne,{gap:1,children:[Y(W,{color:"red",children:"\u25CF"}),Y(W,{color:"red",children:"Error"})]}),u.connectionError&&ye(W,{dimColor:!0,wrap:"truncate",children:[" ",u.connectionError]})]});default:return ye(Ne,{gap:1,children:[Y(W,{color:"gray",children:"\u25CB"}),Y(W,{dimColor:!0,children:"Not connected"})]})}},[u]),T=op(()=>u.lockStatus?u.lockStatus.isLocked&&u.lockStatus.lock?ye(Ne,{gap:1,children:[Y(W,{color:"yellow",children:"LOCKED"}),ye(W,{dimColor:!0,children:["by ",u.lockStatus.lock.lockedBy]})]}):Y(W,{color:"green",children:"FREE"}):Y(W,{dimColor:!0,children:"-"}),[u.lockStatus]),R=op(()=>u.pendingCount===null?Y(W,{dimColor:!0,children:"-"}):u.pendingCount===0?Y(W,{color:"green",children:"0 pending"}):ye(W,{color:"yellow",children:[u.pendingCount," pending"]}),[u.pendingCount]);return a==="ready"&&s.length===0?ye(Ne,{flexDirection:"column",padding:1,children:[ye(Ne,{marginBottom:1,children:[Y(W,{bold:!0,children:"noorm"}),Y(W,{dimColor:!0,children:" - Database Schema & Change Manager"})]}),Y(y,{title:"Welcome",paddingX:2,paddingY:1,borderColor:"cyan",children:ye(Ne,{flexDirection:"column",gap:1,children:[Y(W,{children:"Welcome to noorm!"}),Y(W,{dimColor:!0,children:"No database configurations found."}),ye(Ne,{marginTop:1,children:[Y(W,{children:"Press "}),Y(W,{color:"cyan",bold:!0,children:"[c]"}),Y(W,{children:" to create your first configuration."})]})]})}),Y(Ne,{marginTop:1,children:Y(W,{dimColor:!0,children:"[c] Config [q] Quit"})})]}):a==="ready"&&!o?ye(Ne,{flexDirection:"column",padding:1,children:[ye(Ne,{marginBottom:1,children:[Y(W,{bold:!0,children:"noorm"}),Y(W,{dimColor:!0,children:" - Database Schema & Change Manager"})]}),Y(y,{title:"Select Config",paddingX:2,paddingY:1,borderColor:"yellow",children:ye(Ne,{flexDirection:"column",gap:1,children:[ye(W,{children:["You have ",Y(W,{color:"cyan",children:s.length})," configuration(s), but none is active."]}),ye(Ne,{marginTop:1,children:[Y(W,{children:"Press "}),Y(W,{color:"cyan",bold:!0,children:"[c]"}),Y(W,{children:" to select a configuration to use."})]})]})}),Y(Ne,{marginTop:1,children:Y(W,{dimColor:!0,children:"[c] Config [q] Quit"})})]}):ye(Ne,{flexDirection:"column",padding:1,children:[ye(Ne,{marginBottom:1,children:[Y(W,{bold:!0,children:"noorm"}),Y(W,{dimColor:!0,children:" - Database Schema & Change Manager"})]}),ye(Ne,{marginBottom:1,gap:2,children:[Y(W,{children:"Active Config: "}),Y(W,{color:"cyan",bold:!0,children:i??"none"}),Y(W,{dimColor:!0,children:"|"}),ye(W,{dimColor:!0,children:["Configs: ",s.length]}),!c&&ye(jx,{children:[Y(W,{dimColor:!0,children:"|"}),Y(W,{color:"yellow",children:"No identity (run init)"})]})]}),ye(Ne,{gap:2,marginBottom:1,children:[Y(Ne,{flexDirection:"column",flexGrow:1,children:Y(y,{title:"Status",paddingX:2,paddingY:1,children:ye(Ne,{flexDirection:"column",gap:0,children:[ye(Ne,{gap:1,children:[Y(W,{dimColor:!0,children:"Connection:"}),E()]}),ye(Ne,{gap:1,children:[Y(W,{dimColor:!0,children:"Pending:"}),f?Y($,{}):R()]}),ye(Ne,{gap:1,children:[Y(W,{dimColor:!0,children:"Lock:"}),f?Y($,{}):T()]}),S.length>0&&ye(jx,{children:[Y(Ne,{marginTop:1,children:Y(W,{dimColor:!0,children:"Stage Configs:"})}),S.map(x=>Y(Ne,{marginLeft:2,children:ye(W,{children:[Y(W,{color:x.complete?"green":void 0,children:x.complete?"\u2713":" "})," ",x.configName,!x.complete&&x.missingSecrets.length>0&&ye(W,{color:"red",children:[" ","\u2717 secrets (",x.missingSecrets.length,")"]})]})},x.configName))]})]})})}),Y(Ne,{flexDirection:"column",flexGrow:1,children:Y(y,{title:"Quick Actions",paddingX:2,paddingY:1,children:ye(Ne,{flexDirection:"column",gap:0,children:[ye(W,{children:[Y(W,{color:"cyan",children:"[1]"})," Run Build"]}),ye(W,{children:[Y(W,{color:"cyan",children:"[2]"})," Apply Changes (ff)"]}),ye(W,{children:[Y(W,{color:"cyan",children:"[3]"})," View Lock Status"]})]})})})]}),Y(y,{title:"Recent Activity",paddingX:2,paddingY:1,children:f?Y($,{label:"Loading activity..."}):g.length===0?Y(W,{dimColor:!0,children:"No recent activity"}):Y(Ne,{flexDirection:"column",gap:0,children:g.map(x=>{let C=x.status==="success",b=C?"green":"red",v=C?"[OK]":"[ERR]",P,_;switch(x.changeType){case"build":P="[BUILD]",_="blue";break;case"run":P="[RUN]",_="magenta";break;default:P=x.direction==="revert"?"Reverted":"Applied",_=x.direction==="revert"?"yellow":void 0;break}let O=x.durationMs?`(${(x.durationMs/1e3).toFixed(1)}s)`:"";return ye(Ne,{gap:1,children:[Y(W,{color:b,children:v}),Y(W,{color:_,children:P}),Y(W,{children:x.name}),ye(W,{dimColor:!0,children:[Bi(x.executedAt)," ",O]})]},x.id)})})}),ye(Ne,{marginTop:1,flexWrap:"wrap",columnGap:2,children:[Y(W,{dimColor:!0,children:"[c] Config"}),Y(W,{dimColor:!0,children:"[g] Change"}),Y(W,{dimColor:!0,children:"[r] Run"}),Y(W,{dimColor:!0,children:"[d] DB"}),Y(W,{dimColor:!0,children:"[l] Lock"}),Y(W,{dimColor:!0,children:"[s] Settings"}),Y(W,{dimColor:!0,children:"[k] Secrets"}),Y(W,{dimColor:!0,children:"[i] Identity"}),Y(W,{dimColor:!0,children:"[q] Quit"})]})]})}import{Box as Rc,Text as Ra}from"ink";import{jsx as ka,jsxs as kc}from"react/jsx-runtime";function qx({params:t}){let{route:e,navigate:r,back:n,canGoBack:o}=I(),{isFocused:i}=A("not-found-screen");return fx(i,(s,a)=>{a.return||s==="h"?r("home"):a.escape&&o&&n()}),kc(Rc,{flexDirection:"column",padding:1,children:[kc(Rc,{flexDirection:"column",borderStyle:"round",borderColor:"red",paddingX:2,paddingY:1,children:[ka(Ra,{bold:!0,color:"red",children:"Screen Not Found"}),kc(Rc,{marginTop:1,flexDirection:"column",children:[kc(Ra,{children:[ka(Ra,{dimColor:!0,children:"Route: "}),ka(Ra,{color:"yellow",children:e})]}),ka(Rc,{marginTop:1,children:ka(Ra,{dimColor:!0,children:"This screen has not been implemented yet."})})]})]}),ka(Rc,{marginTop:1,children:kc(Ra,{dimColor:!0,children:["[Enter] go home ",o?"[Esc] go back":""]})})]})}import{useState as Li,useEffect as qk,useCallback as ws}from"react";import{Box as dn,Text as pn}from"ink";import{existsSync as Vx,mkdirSync as sp,writeFileSync as ap,readFileSync as Kk,appendFileSync as Vk}from"fs";import{useInput as Uk}from"ink";import{join as Ts}from"path";import{attempt as Ux}from"@logosdx/utils";import{useState as Kx,useEffect as $k,useCallback as jk}from"react";import{Box as wo,Text as Jr}from"ink";import{jsx as Wt,jsxs as Qo}from"react/jsx-runtime";function _c({onComplete:t,onCancel:e,isRegeneration:r=!1}){let[n,o]=Kx(null),[i,s]=Kx(!0);$k(()=>{let l=Dd();o(l),s(!1)},[]);let a=jk(l=>{t({name:l.name,email:l.email,machine:l.machine,os:n?.os??""})},[n?.os,t]);if(i||!n)return Wt(wo,{flexDirection:"column",padding:1,children:Wt(wo,{children:Wt($,{label:"Detecting identity defaults..."})})});let c=[{key:"name",label:"Name",type:"text",defaultValue:n.name,required:!0,placeholder:"Your name"},{key:"email",label:"Email",type:"text",defaultValue:n.email,required:!0,placeholder:"your@email.com",validate:l=>{if(typeof l=="string"&&!l.includes("@"))return"Invalid email address"}},{key:"machine",label:"Machine",type:"text",defaultValue:n.machine,required:!0,placeholder:"Machine name"}];return Qo(wo,{flexDirection:"column",children:[Qo(y,{title:r?"Regenerate Identity":"Welcome to noorm",titleColor:"cyan",children:[r?Qo(wo,{flexDirection:"column",marginBottom:1,children:[Wt(Jr,{color:"yellow",children:"You are regenerating your identity."}),Qo(wo,{flexDirection:"column",marginLeft:2,marginTop:1,children:[Wt(Jr,{dimColor:!0,children:"\u2022 Your keypair will be replaced"}),Wt(Jr,{dimColor:!0,children:"\u2022 Old encrypted data becomes unreadable"}),Wt(Jr,{dimColor:!0,children:"\u2022 Team members need your new public key"})]})]}):Qo(wo,{flexDirection:"column",marginBottom:1,children:[Wt(Jr,{children:"Let's set up your identity. This is used for:"}),Qo(wo,{flexDirection:"column",marginLeft:2,marginTop:1,children:[Qo(Jr,{children:[Wt(Jr,{dimColor:!0,children:"\u2022"})," Tracking who made changes (audit trail)"]}),Qo(Jr,{children:[Wt(Jr,{dimColor:!0,children:"\u2022"})," Securely sharing configs with teammates"]})]})]}),Wt(wo,{flexDirection:"column",marginBottom:1,children:Wt(Jr,{dimColor:!0,children:"We've pre-filled what we could detect:"})})]}),Wt(wo,{marginTop:1,children:Wt(Ke,{fields:c,onSubmit:a,onCancel:e,submitLabel:r?"Regenerate":"Continue"})}),Wt(wo,{marginTop:1,flexDirection:"column",children:Qo(Jr,{dimColor:!0,children:[Wt(Jr,{children:"OS: "}),Wt(Jr,{children:n.os}),Wt(Jr,{dimColor:!0,children:" (auto-detected)"})]})}),Wt(wo,{marginTop:1,children:Wt(Jr,{dimColor:!0,children:r?"Your identity hash will change after regeneration.":"On continue, we'll generate your keypair for secure config sharing."})})]})}import{useCallback as Hk}from"react";import{Box as Zo,Text as Lt}from"ink";import{jsx as tr,jsxs as Qr}from"react/jsx-runtime";function ip({sqlPath:t="./sql",changesPath:e="./changes",onAddConfig:r,onSkipConfig:n,onCancel:o}){let i=[{key:"add",label:"Yes, set up my first config",value:"add",icon:"\u2713"},{key:"skip",label:"No, I'll do it later",value:"skip",icon:"\u2192"}],s=Hk(a=>{a.key==="add"?r():n()},[r,n]);return Qr(Zo,{flexDirection:"column",children:[Qr(y,{title:"Initialize noorm",titleColor:"cyan",children:[tr(Zo,{flexDirection:"column",marginBottom:1,children:tr(Lt,{children:"This will create the noorm directory structure in your project."})}),Qr(Zo,{flexDirection:"column",marginBottom:1,children:[tr(Lt,{bold:!0,children:"Paths:"}),Qr(Zo,{flexDirection:"column",marginLeft:2,marginTop:1,children:[Qr(Lt,{children:[tr(Lt,{dimColor:!0,children:"SQL: "}),tr(Lt,{color:"cyan",children:t})]}),Qr(Lt,{children:[tr(Lt,{dimColor:!0,children:"Changes: "}),tr(Lt,{color:"cyan",children:e})]})]})]}),Qr(Zo,{flexDirection:"column",marginBottom:1,children:[tr(Lt,{bold:!0,children:"Will create:"}),Qr(Zo,{flexDirection:"column",marginLeft:2,marginTop:1,children:[Qr(Lt,{dimColor:!0,children:[tr(Lt,{children:"\u2022 "}),Qr(Lt,{children:[t,"/.gitkeep"]})]}),Qr(Lt,{dimColor:!0,children:[tr(Lt,{children:"\u2022 "}),Qr(Lt,{children:[e,"/.gitkeep"]})]}),Qr(Lt,{dimColor:!0,children:[tr(Lt,{children:"\u2022 "}),tr(Lt,{children:".noorm/settings.yml"})]}),Qr(Lt,{dimColor:!0,children:[tr(Lt,{children:"\u2022 "}),tr(Lt,{children:".noorm/state.enc"})]})]})]})]}),Qr(Zo,{marginTop:1,flexDirection:"column",children:[tr(Lt,{bold:!0,children:"Would you like to add a database configuration now?"}),tr(Zo,{marginTop:1,children:tr(dt,{items:i,onSelect:s,focusLabel:"project-setup-select"})})]}),tr(Zo,{marginTop:1,children:tr(Lt,{dimColor:!0,children:"[\u2191\u2193] navigate [Enter] select [Esc] cancel"})})]})}import{Fragment as Yk,jsx as Qe,jsxs as Ii}from"react/jsx-runtime";function cp({params:t}){let{navigate:e,back:r}=I(),{refresh:n}=L(),o=!!t.force,[i,s]=Li(!1),a=o||i,[c,l]=Li("check"),[m,d]=Li(null),[u,p]=Li(null),[g,h]=Li(!1),[f,w]=Li(!1),[S,E]=Li([]),[T,R]=Li(!1),x=process.cwd();qk(()=>{(async()=>{let D=Ts(x,".noorm"),F=Vx(D),M=await Wa();h(M);let V=await Ya()!==null;w(V),l(F&&!a?"already-init":M&&V?"project":"identity")})()},[x,a]);let C=ws(B=>{p(B),l("project")},[]),b=ws(()=>{r()},[r]),v=ws(()=>{s(!0),l(g&&f?"project":"identity")},[g,f]),P=ws(async()=>{l("creating");let B=[{label:"Creating directories",status:"pending"},{label:"Generating keypair",status:"pending"},{label:"Creating settings.yml",status:"pending"},{label:"Initializing state",status:"pending"},{label:"Updating .gitignore",status:"pending"}];g&&B.splice(1,1),E([...B]);let D=(M,H)=>{let V=B[M];V&&(B[M]={...V,...H},E([...B]))},[,F]=await Ux(async()=>{D(0,{status:"running"});let M=Ts(x,"sql"),H=Ts(x,"changes"),V=Ts(x,".noorm");sp(M,{recursive:!0}),ap(Ts(M,".gitkeep"),"",{flag:"a"}),sp(H,{recursive:!0}),ap(Ts(H,".gitkeep"),"",{flag:"a"}),sp(V,{recursive:!0}),D(0,{status:"success"});let U=1,j;if(!g&&u){D(U,{status:"running"});let[Qt,Va]=await Ux(()=>gc({name:u.name,email:u.email,machine:u.machine}));if(Va)throw D(U,{status:"error",detail:Va.message}),Va;j=Qt.keypair.privateKey,D(U,{status:"success"}),U++}else U=1;let Q=g?1:2;D(Q,{status:"running"}),await new ts(x).init(a),D(Q,{status:"success"});let xe=g?2:3;D(xe,{status:"running"}),await new Zi(x,{privateKey:j}).load(),g&&u&&!f&&await yc({name:u.name,email:u.email,machine:u.machine}),D(xe,{status:"success"});let Je=g?3:4;D(Je,{status:"running"});let Vr=Ts(x,".gitignore"),ie=`
|
|
1034
|
+
# noorm
|
|
1035
|
+
.noorm/state.enc
|
|
1036
|
+
.noorm/*.log
|
|
1037
|
+
`;Vx(Vr)?Kk(Vr,"utf-8").includes(".noorm/state.enc")||Vk(Vr,ie):ap(Vr,ie.trimStart()),D(Je,{status:"success"}),k.emit("init:complete",{projectRoot:x,hasIdentity:!g}),await Ur(x).reloadPrivateKey(),await n()});if(F){d(F instanceof Error?F:new Error(String(F))),l("error");return}l("complete")},[x,u,g,f,a,n]),_=ws(async()=>{R(!0),await P()},[P]),O=ws(async()=>{R(!1),await P()},[P]),N=ws(()=>{T?e("config/add",{fromInit:!0}):e("home")},[e,T]);switch(Uk((B,D)=>{c!=="complete"&&c!=="error"||(c==="complete"?(D.return||B===" ")&&N():c==="error"&&(D.return||D.escape)&&r())}),c){case"check":return Qe(dn,{flexDirection:"column",padding:1,children:Qe($,{label:"Checking existing state..."})});case"already-init":return Qe(dn,{flexDirection:"column",padding:1,children:Qe(ee,{title:"Already Initialized",message:"This project has already been initialized. Do you want to reinitialize? This will overwrite existing settings.",onConfirm:v,onCancel:b,variant:"warning"})});case"identity":return Qe(dn,{flexDirection:"column",padding:1,children:Qe(_c,{onComplete:C,onCancel:b})});case"project":return Qe(dn,{flexDirection:"column",padding:1,children:Qe(ip,{onAddConfig:_,onSkipConfig:O,onCancel:b})});case"creating":return Qe(dn,{flexDirection:"column",padding:1,children:Qe(y,{title:"Initializing...",titleColor:"cyan",children:Qe(lr,{items:S})})});case"complete":return Qe(dn,{flexDirection:"column",padding:1,children:Qe(y,{title:"Initialization Complete",titleColor:"green",children:Ii(dn,{flexDirection:"column",children:[Qe(pn,{color:"green",children:"noorm has been initialized successfully."}),Ii(dn,{marginTop:1,flexDirection:"column",children:[Qe(pn,{dimColor:!0,children:"Created:"}),Ii(dn,{flexDirection:"column",marginLeft:2,children:[Qe(pn,{children:"\u2022 sql/.gitkeep"}),Qe(pn,{children:"\u2022 changes/.gitkeep"}),Qe(pn,{children:"\u2022 .noorm/settings.yml"}),Qe(pn,{children:"\u2022 .noorm/state.enc"}),!g&&Ii(Yk,{children:[Qe(pn,{children:"\u2022 ~/.noorm/identity.key"}),Qe(pn,{children:"\u2022 ~/.noorm/identity.pub"})]})]})]}),T&&Qe(dn,{marginTop:1,children:Ii(pn,{children:["Press ",Qe(pn,{color:"cyan",children:"Enter"})," to add your first database config."]})}),!T&&Qe(dn,{marginTop:1,children:Ii(pn,{children:["Press ",Qe(pn,{color:"cyan",children:"Enter"})," to go to home screen."]})})]})})});case"error":return Ii(dn,{flexDirection:"column",padding:1,children:[Qe(Xd,{variant:"error",children:Ii(pn,{children:["Initialization failed: ",m?.message]})}),Qe(dn,{marginTop:1,children:Qe(pn,{dimColor:!0,children:"Press Enter or Esc to go back."})})]});default:return Qe(dn,{})}}import{useState as Wk,useCallback as Yx}from"react";import{Box as lp,Text as Jn,useInput as Gk}from"ink";import{jsx as Dn,jsxs as Nu}from"react/jsx-runtime";function up({params:t}){let{navigate:e,back:r}=I(),{isFocused:n}=A("ConfigList"),{configs:o,stateManager:i,refresh:s}=L(),[a,c]=Wk(o.length>0?o[0]?.name??null:null),l=o.map(u=>({key:u.name,label:u.name,value:{name:u.name,dialect:u.dialect,isActive:u.isActive,protected:u.protected,isTest:u.isTest},description:`${u.dialect}${u.isActive?" (active)":""}${u.protected?" [protected]":""}${u.isTest?" [test]":""}`,icon:u.isActive?"\u25CF":"\u25CB"})),m=Yx(async u=>{if(i)if(u.value.isActive)e("config/edit",{name:u.value.name});else{await i.setActiveConfig(u.value.name);let p=i.getConfig(u.value.name);if(p){let g=await fs(p);g.ok&&g.knownUsers?.length&&await i.addKnownUsers(g.knownUsers)}await s()}},[i,e,s]),d=Yx(u=>{c(u.value.name)},[]);return Gk((u,p)=>{if(n){if(p.escape){r();return}if(u==="a"){e("config/add");return}if(u==="i"){e("config/import");return}if(a){if(u==="e"){e("config/edit",{name:a});return}if(u==="d"){e("config/rm",{name:a});return}if(u==="c"){e("config/cp",{name:a});return}if(u==="x"){e("config/export",{name:a});return}if(u==="v"){e("config/validate",{name:a});return}}}}),Nu(lp,{flexDirection:"column",gap:1,children:[Dn(y,{title:"Configurations",paddingX:1,paddingY:1,children:o.length===0?Nu(lp,{flexDirection:"column",gap:1,children:[Dn(Jn,{dimColor:!0,children:"No configurations found."}),Nu(Jn,{children:["Press ",Dn(Jn,{color:"cyan",children:"a"})," to add your first config."]})]}):Dn(dt,{items:l,onSelect:m,onHighlight:d,isFocused:n,visibleCount:8})}),Nu(lp,{flexWrap:"wrap",columnGap:2,children:[Dn(Jn,{dimColor:!0,children:"[a] Add"}),Dn(Jn,{dimColor:!0,children:"[e] Edit"}),Dn(Jn,{dimColor:!0,children:"[d] Delete"}),Dn(Jn,{dimColor:!0,children:"[c] Copy"}),Dn(Jn,{dimColor:!0,children:"[x] Export"}),Dn(Jn,{dimColor:!0,children:"[i] Import"}),Dn(Jn,{dimColor:!0,children:"[v] Validate"}),Dn(Jn,{dimColor:!0,children:"[Enter] Use"}),Dn(Jn,{dimColor:!0,children:"[Esc] Back"})]})]})}import{useState as mp,useCallback as Wx}from"react";import{attempt as Xk}from"@logosdx/utils";import{jsx as Gx}from"react/jsx-runtime";var zk={postgres:5432,mysql:3306,sqlite:0,mssql:1433};function dp({params:t}){let{back:e,navigate:r}=I(),n=!!t.fromInit,{stateManager:o,configs:i,refresh:s}=L(),{showToast:a}=q(),[c,l]=mp(!1),[m,d]=mp("Testing connection..."),[u,p]=mp(null),g=[{key:"name",label:"Config Name",type:"text",required:!0,placeholder:"e.g., dev, staging, prod",validate:w=>{if(typeof w!="string")return"Name is required";if(!/^[a-z0-9_-]+$/i.test(w))return"Only letters, numbers, hyphens, underscores";if(i.some(S=>S.name===w))return"Config name already exists"}},{key:"dialect",label:"Database Type",type:"select",required:!0,options:[{label:"PostgreSQL",value:"postgres"},{label:"MySQL",value:"mysql"},{label:"SQLite",value:"sqlite"},{label:"SQL Server",value:"mssql"}],defaultValue:"postgres"},{key:"host",label:"Host",type:"text",placeholder:"localhost",defaultValue:"localhost"},{key:"port",label:"Port",type:"text",placeholder:"5432",validate:w=>{if(typeof w!="string"||!w)return;let S=parseInt(w,10);if(isNaN(S)||S<1||S>65535)return"Port must be 1-65535"}},{key:"database",label:"Database",type:"text",required:!0,placeholder:"myapp_dev"},{key:"user",label:"Username",type:"text",placeholder:"postgres"},{key:"password",label:"Password",type:"password",placeholder:"(optional)"},{key:"sqlPath",label:"SQL Path",type:"text",defaultValue:"./sql",placeholder:"./sql"},{key:"changesPath",label:"Changes Path",type:"text",defaultValue:"./changes",placeholder:"./changes"},{key:"protected",label:"Protected (requires confirmation for destructive ops)",type:"checkbox",defaultValue:!1},{key:"isTest",label:"Test Database (skipped in production builds)",type:"checkbox",defaultValue:!1}],h=Wx(async w=>{if(!o){p("State manager not available");return}let S=w.dialect,E=S==="sqlite",T={dialect:S,host:E?void 0:String(w.host||"localhost"),port:E?void 0:w.port?parseInt(String(w.port),10):zk[S],database:String(w.database),user:E?void 0:w.user?String(w.user):void 0,password:E?void 0:w.password?String(w.password):void 0};l(!0),d("Testing connection..."),p(null);let R=await de(T,{testServerOnly:!0});if(!R.ok){p(R.error??"Connection failed"),l(!1);return}let x=String(w.name),C={name:x,type:"local",isTest:!!w.isTest,protected:!!w.protected,connection:T,paths:{sql:String(w.sqlPath||"./sql"),changes:String(w.changesPath||"./changes")}};d("Saving configuration...");let[b,v]=await Xk(async()=>{await o.setConfig(C.name,C),i.length===0&&await o.setActiveConfig(C.name),await s()});if(v){p(v instanceof Error?v.message:String(v)),l(!1);return}a({message:`Configuration "${x}" created`,variant:"success"}),n?r("home"):e()},[o,i,s,a,e,r,n]),f=Wx(()=>{n?r("home"):e()},[e,r,n]);return Gx(y,{title:"Add Configuration",paddingX:2,paddingY:1,children:Gx(Ke,{fields:g,onSubmit:h,onCancel:f,submitLabel:"Create Config",focusLabel:"ConfigAddForm",busy:c,busyLabel:m,statusError:u??void 0})})}import{useState as pp,useCallback as Xx,useMemo as zx}from"react";import{Text as Jx}from"ink";import{attempt as Jk}from"@logosdx/utils";import{jsx as vc,jsxs as Qk}from"react/jsx-runtime";function fp({params:t}){let{back:e}=I(),{stateManager:r,refresh:n}=L(),{showToast:o}=q(),i=t.name,[s,a]=pp(!1),[c,l]=pp("Testing connection..."),[m,d]=pp(null),u=zx(()=>!r||!i?null:r.getConfig(i),[r,i]),p=zx(()=>u?[{key:"name",label:"Config Name",type:"text",required:!0,defaultValue:u.name,validate:f=>{if(typeof f!="string")return"Name is required";if(!/^[a-z0-9_-]+$/i.test(f))return"Only letters, numbers, hyphens, underscores"}},{key:"dialect",label:"Database Type (cannot be changed)",type:"text",defaultValue:u.connection.dialect},{key:"host",label:"Host",type:"text",defaultValue:u.connection.host??"localhost"},{key:"port",label:"Port",type:"text",defaultValue:String(u.connection.port??""),validate:f=>{if(typeof f!="string"||!f)return;let w=parseInt(f,10);if(isNaN(w)||w<1||w>65535)return"Port must be 1-65535"}},{key:"database",label:"Database",type:"text",required:!0,defaultValue:u.connection.database},{key:"user",label:"Username",type:"text",defaultValue:u.connection.user??""},{key:"password",label:"Password",type:"password",defaultValue:u.connection.password??"",placeholder:"(unchanged if empty)"},{key:"sqlPath",label:"SQL Path",type:"text",defaultValue:u.paths.sql},{key:"changesPath",label:"Changes Path",type:"text",defaultValue:u.paths.changes},{key:"protected",label:"Protected",type:"checkbox",defaultValue:u.protected},{key:"isTest",label:"Test Database",type:"checkbox",defaultValue:u.isTest}]:[],[u]),g=Xx(async f=>{if(!r||!u||!i){d("Config not found");return}let w=u.connection.dialect,S=w==="sqlite",E={dialect:w,host:S?void 0:String(f.host||"localhost"),port:S?void 0:f.port?parseInt(String(f.port),10):u.connection.port,database:String(f.database),user:S?void 0:f.user?String(f.user):void 0,password:S?void 0:f.password?String(f.password):u.connection.password};a(!0),l("Testing connection..."),d(null);let T=await de(E,{testServerOnly:!0});if(!T.ok){d(T.error??"Connection failed"),a(!1);return}let R=String(f.name),x={...u,name:R,isTest:!!f.isTest,protected:!!f.protected,connection:E,paths:{sql:String(f.sqlPath||"./sql"),changes:String(f.changesPath||"./changes")}};l("Saving changes...");let[C,b]=await Jk(async()=>{R!==i&&await r.deleteConfig(i),await r.setConfig(x.name,x),await n()});if(b){d(b instanceof Error?b.message:String(b)),a(!1);return}o({message:`Configuration "${R}" updated`,variant:"success"}),e()},[r,u,i,n,o,e]),h=Xx(()=>{e()},[e]);return i?u?vc(y,{title:`Edit: ${i}`,paddingX:2,paddingY:1,children:vc(Ke,{fields:p,onSubmit:g,onCancel:h,submitLabel:"Save Changes",focusLabel:"ConfigEditForm",busy:s,busyLabel:c,statusError:m??void 0})}):vc(y,{title:"Edit Configuration",paddingX:2,paddingY:1,borderColor:"red",children:Qk(Jx,{color:"red",children:['Config "',i,'" not found.']})}):vc(y,{title:"Edit Configuration",paddingX:2,paddingY:1,borderColor:"yellow",children:vc(Jx,{color:"yellow",children:"No config name provided. Use: noorm config:edit <name>"})})}import{useState as Zk,useCallback as Qx,useMemo as e_}from"react";import{Box as Es,Text as Rs,useInput as t_}from"ink";import{attempt as r_}from"@logosdx/utils";import{jsx as Rr,jsxs as Dc}from"react/jsx-runtime";function gp({params:t}){let{back:e}=I(),{isFocused:r}=A("ConfigRemove"),{stateManager:n,activeConfigName:o,refresh:i}=L(),{showToast:s}=q(),a=t.name,[c,l]=Zk(!1),m=e_(()=>!n||!a?null:n.getConfig(a),[n,a]),d=a===o,u=Qx(async()=>{if(!n||!a){s({message:"Config not found",variant:"error"}),e();return}l(!0);let[g,h]=await r_(async()=>{await n.deleteConfig(a),await i()});if(h){s({message:h instanceof Error?h.message:String(h),variant:"error"}),l(!1);return}s({message:`Configuration "${a}" deleted`,variant:"success"}),e()},[n,a,i,s,e]),p=Qx(()=>{e()},[e]);return t_((g,h)=>{r&&(!a||!m||d)&&(h.escape||h.return)&&e()}),a?m?d?Dc(Es,{flexDirection:"column",gap:1,children:[Rr(y,{title:"Delete Configuration",paddingX:2,paddingY:1,borderColor:"yellow",children:Dc(Es,{flexDirection:"column",gap:1,children:[Rr(Rs,{color:"yellow",children:"Cannot delete the active configuration."}),Rr(Rs,{children:"Switch to a different config first with: noorm config:use <name>"})]})}),Rr(Es,{flexWrap:"wrap",columnGap:2,children:Rr(Rs,{dimColor:!0,children:"[Enter/Esc] Back"})})]}):c?Rr(y,{title:`Delete: ${a}`,paddingX:2,paddingY:1,children:Rr($,{label:"Deleting configuration..."})}):m.protected?Rr(pt,{configName:a,action:"delete",onConfirm:u,onCancel:p,isFocused:r}):Rr(y,{title:`Delete: ${a}`,paddingX:2,paddingY:1,borderColor:"yellow",children:Rr(ee,{message:`Are you sure you want to delete configuration "${a}"?`,onConfirm:u,onCancel:p,variant:"warning",isFocused:r})}):Dc(Es,{flexDirection:"column",gap:1,children:[Rr(y,{title:"Delete Configuration",paddingX:2,paddingY:1,borderColor:"red",children:Dc(Rs,{color:"red",children:['Config "',a,'" not found.']})}),Rr(Es,{flexWrap:"wrap",columnGap:2,children:Rr(Rs,{dimColor:!0,children:"[Enter/Esc] Back"})})]}):Dc(Es,{flexDirection:"column",gap:1,children:[Rr(y,{title:"Delete Configuration",paddingX:2,paddingY:1,borderColor:"yellow",children:Rr(Rs,{color:"yellow",children:"No config name provided. Use: noorm config:rm <name>"})}),Rr(Es,{flexWrap:"wrap",columnGap:2,children:Rr(Rs,{dimColor:!0,children:"[Enter/Esc] Back"})})]})}import{useState as yp,useCallback as Fu,useMemo as n_}from"react";import{Box as hp,Text as Oi,useInput as o_}from"ink";import{TextInput as i_}from"@inkjs/ui";import{attempt as s_}from"@logosdx/utils";import{jsx as Qn,jsxs as Pc}from"react/jsx-runtime";function xp({params:t}){let{back:e}=I(),{isFocused:r}=A("ConfigCopy"),{stateManager:n,configs:o,refresh:i}=L(),{showToast:s}=q(),a=t.name,[c,l]=yp(!1),[m,d]=yp(""),[u,p]=yp(null),g=n_(()=>!n||!a?null:n.getConfig(a),[n,a]),h=Fu(E=>E?/^[a-z0-9_-]+$/i.test(E)?o.some(T=>T.name===E)?"Config name already exists":null:"Only letters, numbers, hyphens, underscores":"Name is required",[o]),f=Fu(E=>{d(E),p(null)},[]),w=Fu(async()=>{if(!n||!g||!a){s({message:"Config not found",variant:"error"}),e();return}let E=h(m);if(E){p(E);return}l(!0);let[T,R]=await s_(async()=>{let x={...g,name:m};await n.setConfig(m,x),await i()});if(R){s({message:R instanceof Error?R.message:String(R),variant:"error"}),l(!1);return}s({message:`Configuration copied to "${m}"`,variant:"success"}),e()},[n,g,a,m,h,i,s,e]),S=Fu(()=>{e()},[e]);return o_((E,T)=>{if(!(!r||c)){if(T.return){w();return}T.escape&&(m?d(""):S())}}),a?g?c?Qn(y,{title:`Copy: ${a}`,paddingX:2,paddingY:1,children:Qn($,{label:"Copying configuration..."})}):Qn(y,{title:`Copy: ${a}`,paddingX:2,paddingY:1,children:Pc(hp,{flexDirection:"column",gap:1,children:[Pc(Oi,{children:["Create a copy of ",Qn(Oi,{color:"cyan",children:a})]}),Pc(hp,{marginTop:1,children:[Qn(Oi,{children:"New name: "}),Qn(i_,{placeholder:`${a}-copy`,defaultValue:m,onChange:f,isDisabled:!r})]}),u&&Qn(Oi,{color:"red",children:u}),Pc(hp,{marginTop:1,gap:2,children:[Qn(Oi,{dimColor:!0,children:"[Enter] Copy"}),Qn(Oi,{dimColor:!0,children:"[Esc] Cancel"})]})]})}):Qn(y,{title:"Copy Configuration",paddingX:2,paddingY:1,borderColor:"red",children:Pc(Oi,{color:"red",children:['Config "',a,'" not found.']})}):Qn(y,{title:"Copy Configuration",paddingX:2,paddingY:1,borderColor:"yellow",children:Qn(Oi,{color:"yellow",children:"No config name provided. Use: noorm config:cp <name>"})})}import{useState as Zx,useEffect as a_,useMemo as c_}from"react";import{Box as Bu,Text as Lu,useInput as l_}from"ink";import{attempt as u_}from"@logosdx/utils";import{jsx as Pn,jsxs as bp}from"react/jsx-runtime";function Sp({params:t}){let{navigate:e,back:r}=I(),{isFocused:n}=A("ConfigUse"),{stateManager:o,activeConfigName:i,refresh:s}=L(),a=t.name,[c,l]=Zx("switching"),[m,d]=Zx(null),u=c_(()=>!o||!a?null:o.getConfig(a),[o,a]),p=a===i;if(a_(()=>{if(!o||!a||!u){d("Config not found"),l("error");return}if(p){l("complete");return}(async()=>{let[h,f]=await u_(async()=>{await o.setActiveConfig(a);let w=await fs(u);w.ok&&w.knownUsers?.length&&await o.addKnownUsers(w.knownUsers),await s()});if(f){d(f instanceof Error?f.message:String(f)),l("error");return}l("complete")})()},[o,a,u,p,s]),l_((g,h)=>{n&&(c==="complete"||c==="error")&&r()}),!a)return Pn(y,{title:"Set Active Configuration",paddingX:2,paddingY:1,borderColor:"yellow",children:Pn(Lu,{color:"yellow",children:"No config name provided. Use: noorm config:use <name>"})});if(!u)return Pn(y,{title:"Set Active Configuration",paddingX:2,paddingY:1,borderColor:"red",children:bp(Lu,{color:"red",children:['Config "',a,'" not found.']})});if(c==="switching")return Pn(y,{title:`Use: ${a}`,paddingX:2,paddingY:1,children:Pn($,{label:"Switching configuration..."})});if(c==="complete"){let g=p?`Configuration "${a}" is already active.`:`Switched to configuration "${a}".`;return Pn(y,{title:`Use: ${a}`,paddingX:2,paddingY:1,borderColor:"green",children:bp(Bu,{flexDirection:"column",gap:1,children:[Pn(_e,{variant:"success",children:g}),Pn(Bu,{marginTop:1,children:Pn(Lu,{dimColor:!0,children:"Press any key to continue..."})})]})})}return Pn(y,{title:`Use: ${a}`,paddingX:2,paddingY:1,borderColor:"red",children:bp(Bu,{flexDirection:"column",gap:1,children:[Pn(_e,{variant:"error",children:m}),Pn(Bu,{marginTop:1,children:Pn(Lu,{dimColor:!0,children:"Press any key to continue..."})})]})})}import{useState as Cp,useEffect as m_,useMemo as d_}from"react";import{Box as Iu,Text as ks,useInput as p_}from"ink";import{jsx as Nn,jsxs as Ou}from"react/jsx-runtime";function wp({params:t}){let{navigate:e,back:r}=I(),{isFocused:n}=A("ConfigValidate"),{stateManager:o}=L(),i=t.name,[s,a]=Cp("validating"),[c,l]=Cp([]),[m,d]=Cp(!0),u=d_(()=>!o||!i?null:o.getConfig(i),[o,i]);if(m_(()=>{if(!o||!i||!u)return;(async()=>{let w=[],S=!0;w.push({key:"connection",label:"Connection",status:"pending",detail:"Testing database connection..."}),l([...w]);let E=await de(u.connection);E.ok?w[0]={...w[0],status:"success",detail:"Connection successful"}:(w[0]={...w[0],status:"error",detail:E.error??"Connection failed"},S=!1),l([...w]);let T=[{key:"name",label:"Name",value:u.name},{key:"database",label:"Database",value:u.connection.database},{key:"sqlPath",label:"SQL Path",value:u.paths.sql},{key:"changesPath",label:"Changes Path",value:u.paths.changes}];for(let x of T){let C=!!x.value;w.push({key:x.key,label:x.label,status:C?"success":"error",detail:C?x.value:"Not set"}),C||(S=!1)}if(l([...w]),u.connection.dialect!=="sqlite"){let x=!!u.connection.host;w.push({key:"host",label:"Host",status:x?"success":"error",detail:x?u.connection.host:"Not set"}),x||(S=!1),l([...w])}let R=o.listSecrets(i);R.length>0&&(w.push({key:"secrets",label:"Secrets",status:"success",detail:`${R.length} secret(s) configured`}),l([...w])),d(S),a("complete")})()},[o,i,u]),p_((f,w)=>{n&&s==="complete"&&(w.escape?r():f==="k"?e("secret",{name:i}):f==="e"&&e("config/edit",{name:i}))}),!i)return Nn(y,{title:"Validate Configuration",paddingX:2,paddingY:1,borderColor:"yellow",children:Nn(ks,{color:"yellow",children:"No config name provided. Use: noorm config:validate <name>"})});if(!u)return Nn(y,{title:"Validate Configuration",paddingX:2,paddingY:1,borderColor:"red",children:Ou(ks,{color:"red",children:['Config "',i,'" not found.']})});if(s==="validating"&&c.length===0)return Nn(y,{title:`Validate: ${i}`,paddingX:2,paddingY:1,children:Nn($,{label:"Validating configuration..."})});let p=m?"green":"red",g=m?"VALID":"INCOMPLETE",h=m?"green":"red";return Nn(y,{title:`Validate: ${i}`,paddingX:2,paddingY:1,borderColor:p,children:Ou(Iu,{flexDirection:"column",gap:1,children:[Ou(Iu,{gap:1,children:[Nn(ks,{children:"Status:"}),Nn(ks,{color:h,bold:!0,children:g})]}),Nn(Iu,{marginTop:1,children:Nn(lr,{items:c})}),Ou(Iu,{marginTop:1,flexWrap:"wrap",columnGap:2,children:[Nn(ks,{dimColor:!0,children:"[e] Edit"}),Nn(ks,{dimColor:!0,children:"[k] Secrets"}),Nn(ks,{dimColor:!0,children:"[Esc] Back"})]})]})})}import{useState as _a,useCallback as Tp,useMemo as f_}from"react";import{Box as ei,Text as fn,useInput as g_}from"ink";import{TextInput as y_}from"@inkjs/ui";import{writeFileSync as h_}from"fs";import{join as x_}from"path";import{attempt as b_}from"@logosdx/utils";import{jsx as ft,jsxs as Fo}from"react/jsx-runtime";function Ep({params:t}){let{navigate:e,back:r}=I(),{isFocused:n}=A("ConfigExport"),{stateManager:o,identity:i}=L(),s=t.name,[a,c]=_a("recipient-email"),[l,m]=_a(""),[d,u]=_a([]),[p,g]=_a(null),[h,f]=_a(""),[w,S]=_a(null),E=f_(()=>!o||!s?null:o.getConfig(s),[o,s]),T=Tp(()=>{if(!o||!l)return;let C=o.findKnownUsersByEmail(l);if(C.length===0){S(`No known users with email "${l}". Import their identity first.`),c("error");return}C.length===1?(g(C[0]),x(C[0])):(u(C),c("select-identity"))},[o,l]),R=Tp(C=>{g(C.value),x(C.value)},[]),x=Tp(async C=>{if(!o||!E||!i||!s){S("Missing required data"),c("error");return}c("exporting");let[b,v]=await b_(async()=>{let P={config:{name:E.name,type:E.type,isTest:E.isTest,protected:E.protected,connection:{dialect:E.connection.dialect,host:E.connection.host,port:E.connection.port,database:E.connection.database,ssl:E.connection.ssl},paths:E.paths},secrets:o.getAllSecrets(s)},_=Im(JSON.stringify(P),C.publicKey,i.email,C.email),O=`${s}.noorm.enc`,N=x_(process.cwd(),O);h_(N,JSON.stringify(_,null,2)),f(O)});if(v){S(v instanceof Error?v.message:String(v)),c("error");return}c("complete")},[o,E,i,s]);if(g_((C,b)=>{if(n){if(a==="recipient-email"){if(b.return){T();return}if(b.escape){l?m(""):r();return}}(a==="complete"||a==="error")&&r()}}),!s)return ft(y,{title:"Export Configuration",paddingX:2,paddingY:1,borderColor:"yellow",children:ft(fn,{color:"yellow",children:"No config name provided. Use: noorm config:export <name>"})});if(!E)return ft(y,{title:"Export Configuration",paddingX:2,paddingY:1,borderColor:"red",children:Fo(fn,{color:"red",children:['Config "',s,'" not found.']})});if(!i)return ft(y,{title:"Export Configuration",paddingX:2,paddingY:1,borderColor:"yellow",children:ft(fn,{color:"yellow",children:"No identity set up. Run 'noorm init' first."})});if(a==="recipient-email")return ft(y,{title:`Export: ${s}`,paddingX:2,paddingY:1,children:Fo(ei,{flexDirection:"column",gap:1,children:[ft(fn,{children:"Export configuration for sharing with another user."}),ft(fn,{dimColor:!0,children:"Note: Database user/password will NOT be included."}),Fo(ei,{marginTop:1,children:[ft(fn,{children:"Recipient email: "}),ft(y_,{placeholder:"alice@example.com",defaultValue:l,onChange:m,isDisabled:!n})]}),Fo(ei,{marginTop:1,gap:2,children:[ft(fn,{dimColor:!0,children:"[Enter] Continue"}),ft(fn,{dimColor:!0,children:"[Esc] Cancel"})]})]})});if(a==="select-identity"){let C=d.map(b=>({key:b.identityHash,label:`${b.machine} (${b.os})`,value:b,description:`Last seen: ${b.lastSeen??"unknown"}`}));return ft(y,{title:`Export: ${s}`,paddingX:2,paddingY:1,children:Fo(ei,{flexDirection:"column",gap:1,children:[Fo(fn,{children:["Multiple identities found for ",l,":"]}),ft(ei,{marginTop:1,children:ft(dt,{items:C,onSelect:R,focusLabel:"ConfigExportIdentity"})})]})})}return a==="exporting"?ft(y,{title:`Export: ${s}`,paddingX:2,paddingY:1,children:ft($,{label:"Encrypting and exporting..."})}):a==="complete"?ft(y,{title:`Export: ${s}`,paddingX:2,paddingY:1,borderColor:"green",children:Fo(ei,{flexDirection:"column",gap:1,children:[ft(_e,{variant:"success",children:"Configuration exported successfully!"}),Fo(fn,{children:["File: ",ft(fn,{color:"cyan",children:h})]}),Fo(fn,{dimColor:!0,children:["Share this file with ",p?.email??l,". They can import it with: noorm config:import ",h]}),ft(ei,{marginTop:1,children:ft(fn,{dimColor:!0,children:"Press any key to continue..."})})]})}):ft(y,{title:`Export: ${s}`,paddingX:2,paddingY:1,borderColor:"red",children:Fo(ei,{flexDirection:"column",gap:1,children:[ft(_e,{variant:"error",children:w}),ft(ei,{marginTop:1,children:ft(fn,{dimColor:!0,children:"Press any key to continue..."})})]})})}import{useState as va,useCallback as Da,useMemo as S_,useEffect as C_}from"react";import{Box as Bo,Text as kr,useInput as w_}from"ink";import{readFileSync as T_,existsSync as E_,readdirSync as R_}from"fs";import{join as k_}from"path";import{attempt as eb,attemptSync as Nc}from"@logosdx/utils";import{jsx as gt,jsxs as gn}from"react/jsx-runtime";function Rp({params:t}){let{navigate:e,back:r}=I(),{stateManager:n,configs:o,refresh:i}=L(),s=t.path,[a,c]=va(s?"decrypting":"file-select"),[l,m]=va(s??""),[d,u]=va(null),[p,g]=va(""),[h,f]=va(null),[w,S]=va(""),E=Da(_=>o.some(O=>O.name===_),[o]),T=Da(async _=>{if(c("decrypting"),!E_(_)){f(`File not found: ${_}`),c("error");return}let[O,N]=Nc(()=>T_(_,"utf8"));if(N){f("Could not read file."),c("error");return}let[B,D]=Nc(()=>JSON.parse(O));if(D){f("Invalid file format. Not a valid noorm export file."),c("error");return}g(B.sender);let[F,M]=await eb(()=>$s());if(M||!F){f('No private key found. Run "noorm init" first.'),c("error");return}let[H,V]=Nc(()=>Om(B,F));if(V){f("Could not decrypt file. You may not be the intended recipient."),c("error");return}let[U,j]=Nc(()=>JSON.parse(H));if(j){f("Decrypted content is invalid. File may be corrupted."),c("error");return}u(U),c("preview")},[]),R=Da(async _=>{m(_),await T(_)},[T]);C_(()=>{s&&a==="decrypting"&&T(s)},[s,a,T]);let x=Da(async _=>{if(!n||!d){f("Import data not available"),c("error");return}c("saving");let[O,N]=await eb(async()=>{let B=String(_.name||d.config.name),D={name:B,type:d.config.type??"local",isTest:d.config.isTest??!1,protected:d.config.protected??!1,connection:{dialect:d.config.connection?.dialect??"postgres",host:d.config.connection?.host,port:d.config.connection?.port,database:d.config.connection?.database??"",user:_.user?String(_.user):void 0,password:_.password?String(_.password):void 0,ssl:d.config.connection?.ssl},paths:{sql:d.config.paths?.sql??"./sql",changes:d.config.paths?.changes??"./changes"}};await n.setConfig(B,D);for(let[F,M]of Object.entries(d.secrets))await n.setSecret(B,F,M);await i(),S(B)});if(N){f(N instanceof Error?N.message:String(N)),c("error");return}c("complete")},[n,d,i]),C=Da(()=>{r()},[r]);w_(()=>{(a==="complete"||a==="error")&&r()});let b=S_(()=>{let[_,O]=Nc(()=>R_(process.cwd()));return O?[]:_.filter(N=>N.endsWith(".noorm.enc"))},[]),v=b.map(_=>({key:_,label:_,value:_})),P=Da(_=>{R(k_(process.cwd(),_.value))},[R]);if(a==="file-select")return b.length===0?gt(y,{title:"Import Configuration",paddingX:2,paddingY:1,borderColor:"yellow",children:gn(Bo,{flexDirection:"column",gap:1,children:[gt(kr,{color:"yellow",children:"No .noorm.enc files found in current directory."}),gt(kr,{dimColor:!0,children:"Use: noorm config:import <file>"}),gt(Bo,{marginTop:1,children:gt(kr,{dimColor:!0,children:"[Esc] Go back"})})]})}):gt(y,{title:"Import Configuration",paddingX:2,paddingY:1,children:gn(Bo,{flexDirection:"column",gap:1,children:[gt(kr,{children:"Select a file to import:"}),gt(dt,{items:v,onSelect:P,onCancel:r,focusLabel:"ConfigImportFile"})]})});if(a==="decrypting")return gt(y,{title:"Import Configuration",paddingX:2,paddingY:1,children:gt($,{label:"Decrypting file..."})});if(a==="preview"&&d){let _=d.config.name??"imported",O=E(_),N=[{key:"name",label:O?"Config Name (rename required)":"Config Name",type:"text",required:!0,defaultValue:O?`${_}-imported`:_,validate:D=>{if(typeof D!="string"||!D)return"Name is required";if(!/^[a-z0-9_-]+$/i.test(D))return"Only letters, numbers, hyphens, underscores";if(E(D))return"Config name already exists"}},{key:"user",label:"Database User",type:"text",required:!0,placeholder:"postgres"},{key:"password",label:"Database Password",type:"password",placeholder:"(required)"}],B=Object.keys(d.secrets).length;return gt(y,{title:"Import Configuration",paddingX:2,paddingY:1,children:gn(Bo,{flexDirection:"column",gap:1,children:[gn(Bo,{flexDirection:"column",children:[gn(kr,{children:["From: ",gt(kr,{color:"cyan",children:p})]}),gn(kr,{children:["Dialect:"," ",gt(kr,{color:"cyan",children:d.config.connection?.dialect})]}),gn(kr,{children:["Database:"," ",gt(kr,{color:"cyan",children:d.config.connection?.database})]}),gn(kr,{children:["Host:"," ",gn(kr,{color:"cyan",children:[d.config.connection?.host,":",d.config.connection?.port]})]}),gn(kr,{children:["Secrets: ",gn(kr,{color:"cyan",children:[B," included"]})]})]}),gt(Bo,{marginTop:1,children:gt(kr,{bold:!0,children:"Enter your database credentials:"})}),gt(Ke,{fields:N,onSubmit:x,onCancel:C,submitLabel:"Import",focusLabel:"ConfigImportForm"})]})})}return a==="saving"?gt(y,{title:"Import Configuration",paddingX:2,paddingY:1,children:gt($,{label:"Saving configuration..."})}):a==="complete"?gt(y,{title:"Import Configuration",paddingX:2,paddingY:1,borderColor:"green",children:gn(Bo,{flexDirection:"column",gap:1,children:[gn(_e,{variant:"success",children:['Configuration "',w,'" imported successfully!']}),gt(Bo,{marginTop:1,children:gt(kr,{dimColor:!0,children:"Press any key to continue..."})})]})}):gt(y,{title:"Import Configuration",paddingX:2,paddingY:1,borderColor:"red",children:gn(Bo,{flexDirection:"column",gap:1,children:[gt(_e,{variant:"error",children:h}),gt(Bo,{marginTop:1,children:gt(kr,{dimColor:!0,children:"Press any key to continue..."})})]})})}import{useState as Au,useEffect as __,useMemo as v_}from"react";import{Box as Lo,Text as ve,useInput as D_}from"ink";import{attempt as P_}from"@logosdx/utils";import{Fragment as F_,jsx as Ve,jsxs as Gt}from"react/jsx-runtime";function N_(t){if(t.orphaned)return{symbol:"!",color:"yellow"};switch(t.status){case"success":return{symbol:"\u2713",color:"green"};case"failed":return{symbol:"\u2717",color:"red"};case"reverted":return{symbol:"\u21A9",color:"yellow"};default:return{symbol:"\u25CB",color:"gray"}}}function kp({params:t}){let{navigate:e,back:r}=I(),{isFocused:n}=A("ChangeList"),{activeConfig:o,activeConfigName:i,loadingStatus:s}=L(),[a,c]=Au([]),[l,m]=Au(!0),[d,u]=Au(null),[p,g]=Au(0);__(()=>{if(!o||s!=="ready"){m(!1);return}let T=!1;return(async()=>{m(!0),u(null);let[x,C]=await P_(async()=>{let b=await At(o.paths.changes,o.paths.sql),v=await K(o.connection,i??"__list__"),P=v.db,O=await new Oe(P,i??"").getAllStatuses();if(await v.destroy(),T)return;let N=[];for(let D of b){let F=O.get(D.name);N.push({name:D.name,path:D.path,date:D.date,description:D.description,changeFiles:D.changeFiles,revertFiles:D.revertFiles,hasChangelog:D.hasChangelog,status:F?.status??"pending",appliedAt:F?.appliedAt??null,appliedBy:F?.appliedBy??null,revertedAt:F?.revertedAt??null,errorMessage:F?.errorMessage??null,isNew:!F,orphaned:!1})}let B=new Set(b.map(D=>D.name));for(let[D,F]of O)B.has(D)||N.push({name:D,path:"",date:null,description:D,status:F.status,appliedAt:F.appliedAt,appliedBy:F.appliedBy,revertedAt:F.revertedAt,errorMessage:F.errorMessage,isNew:!1,orphaned:!0});N.sort((D,F)=>{if(D.status==="pending"&&F.status!=="pending")return-1;if(F.status==="pending"&&D.status!=="pending")return 1;let M=D.date?.getTime()??0;return(F.date?.getTime()??0)-M}),c(N)});C&&(T||u(C instanceof Error?C.message:String(C))),m(!1)})(),()=>{T=!0}},[o,i,s]);let h=v_(()=>a[p],[a,p]);if(D_((T,R)=>{if(n){if(R.upArrow){g(x=>Math.max(0,x-1));return}if(R.downArrow){g(x=>Math.min(a.length-1,x+1));return}if(R.escape){r();return}if(T==="a"){e("change/add");return}if(T==="e"&&h&&!h.orphaned){e("change/edit",{name:h.name});return}if(T==="d"&&h){e("change/rm",{name:h.name});return}if(T==="r"&&h&&(h.status==="pending"||h.status==="failed")){e("change/run",{name:h.name});return}if(T==="v"&&h&&h.status==="success"){e("change/revert",{name:h.name});return}if(T==="n"){e("change/next");return}if(T==="f"){e("change/ff");return}if(T==="w"){e("change/rewind");return}if(T==="h"){e("change/history");return}R.return&&h&&(h.status==="pending"||h.status==="failed"?e("change/run",{name:h.name}):h.status==="success"&&e("change/revert",{name:h.name}))}}),!o)return Ve(y,{title:"Changes",paddingX:2,paddingY:1,borderColor:"yellow",children:Ve(ve,{color:"yellow",children:"No active configuration. Press 'c' to manage configs."})});if(l)return Ve(y,{title:"Changes",paddingX:2,paddingY:1,children:Ve($,{label:"Loading changes..."})});if(d)return Ve(y,{title:"Changes",paddingX:2,paddingY:1,borderColor:"red",children:Gt(Lo,{flexDirection:"column",gap:1,children:[Gt(ve,{color:"red",children:["Failed to load changes: ",d]}),Ve(ve,{dimColor:!0,children:"Press Esc to go back"})]})});let f=a.filter(T=>T.status==="success").length,w=a.filter(T=>T.status==="pending").length,S=a.filter(T=>T.status==="failed").length,E=a.filter(T=>T.orphaned).length;return Ve(y,{title:"Changes",paddingX:2,paddingY:1,children:Gt(Lo,{flexDirection:"column",gap:1,children:[Gt(Lo,{gap:2,children:[Gt(ve,{children:["Total: ",Ve(ve,{bold:!0,children:a.length})]}),Gt(ve,{children:["Applied: ",Ve(ve,{color:"green",children:f})]}),Gt(ve,{children:["Pending: ",Ve(ve,{color:"yellow",children:w})]}),S>0&&Gt(ve,{children:["Failed: ",Ve(ve,{color:"red",children:S})]}),E>0&&Gt(ve,{children:["Orphaned: ",Ve(ve,{color:"yellow",children:E})]})]}),a.length===0?Ve(Lo,{marginTop:1,children:Ve(ve,{dimColor:!0,children:"No changes found. Press [a] to create one."})}):Ve(Lo,{flexDirection:"column",marginTop:1,children:a.map((T,R)=>{let x=R===p,C=N_(T);return Gt(Lo,{children:[Ve(ve,{color:x?"cyan":void 0,children:x?">":" "}),Gt(ve,{color:C.color,children:[" ",C.symbol," "]}),Ve(ve,{color:x?"cyan":T.orphaned?"yellow":void 0,bold:x,children:T.name}),Gt(ve,{dimColor:!0,children:[T.status==="success"&&T.appliedAt&&Gt(F_,{children:[" ",Bi(T.appliedAt)]}),T.status==="pending"&&" pending",T.status==="reverted"&&" reverted",T.status==="failed"&&" failed",T.orphaned&&" (orphaned)"]})]},T.name)})}),h&&Gt(Lo,{marginTop:1,flexDirection:"column",borderStyle:"single",borderColor:h.status==="failed"?"red":"gray",paddingX:1,children:[Ve(ve,{bold:!0,children:h.name}),Gt(Lo,{gap:2,children:[Gt(ve,{dimColor:!0,children:["Change files: ",h.changeFiles?.length??0]}),Gt(ve,{dimColor:!0,children:["Revert files: ",h.revertFiles?.length??0]})]}),h.appliedBy&&Gt(ve,{dimColor:!0,children:["Applied by: ",h.appliedBy]}),h.status==="failed"&&h.errorMessage&&Gt(Lo,{flexDirection:"column",marginTop:1,children:[Ve(ve,{color:"red",bold:!0,children:"Error:"}),Ve(ve,{color:"red",wrap:"wrap",children:h.errorMessage})]})]}),Gt(Lo,{marginTop:1,flexWrap:"wrap",columnGap:2,children:[Ve(ve,{dimColor:!0,children:"[a] Add"}),Ve(ve,{dimColor:!0,children:"[e] Edit"}),Ve(ve,{dimColor:!0,children:"[d] Delete"}),Ve(ve,{dimColor:!0,children:"[r] Run"}),Ve(ve,{dimColor:!0,children:"[v] Revert"}),Ve(ve,{dimColor:!0,children:"[n] Next"}),Ve(ve,{dimColor:!0,children:"[f] FF"}),Ve(ve,{dimColor:!0,children:"[w] Rewind"}),Ve(ve,{dimColor:!0,children:"[h] History"}),Ve(ve,{dimColor:!0,children:"[Esc] Back"})]})]})})}import{useState as $u,useCallback as Dp}from"react";import{existsSync as B_}from"fs";import{join as L_}from"path";import{Box as _s,Text as To,useInput as I_}from"ink";import{TextInput as O_}from"@inkjs/ui";import{attempt as A_}from"@logosdx/utils";import{execSync as Pa}from"child_process";import{platform as tb}from"os";import{attemptSync as Mu}from"@logosdx/utils";function _p(t){let e=tb();if(e==="darwin"){Pa("pbcopy",{input:t,encoding:"utf8"});return}if(e==="linux"){let[,r]=Mu(()=>Pa("xclip -selection clipboard",{input:t,encoding:"utf8"}));if(!r)return;let[,n]=Mu(()=>Pa("xsel --clipboard --input",{input:t,encoding:"utf8"}));if(!n)return;throw new Error("No clipboard utility found. Install xclip or xsel.")}if(e==="win32"){Pa("clip",{input:t,encoding:"utf8"});return}throw new Error(`Clipboard not supported on ${e}`)}function vp(){let t=tb();if(t==="darwin"||t==="win32")return!0;if(t==="linux"){let[,e]=Mu(()=>Pa("which xclip",{encoding:"utf8"}));if(!e)return!0;let[,r]=Mu(()=>Pa("which xsel",{encoding:"utf8"}));return!r}return!1}function Fc(t){return t.replace(/[^a-zA-Z0-9]+/g," ").trim().replace(/\s+/g," ").toLowerCase().replace(/\s/g,"-").replace(/-+/g,"-").replace(/^-|-$/g,"")}import{jsx as ur,jsxs as ti}from"react/jsx-runtime";function Pp({params:t}){let{navigate:e,back:r}=I(),{isFocused:n}=A("ChangeAdd"),{activeConfig:o,settings:i}=L(),s=t.name??"",[a,c]=$u(s?"creating":"input"),[l,m]=$u(s),[d,u]=$u(""),[p,g]=$u(null),h=Fc(l),f=Dp(E=>Fc(E)?null:"Description is required",[]),w=Dp(async E=>{if(!o){g("No active configuration"),c("error");return}let T=f(E);if(T){g(T),c("error");return}let R=Fc(E),C=`${new Date().toISOString().slice(0,10)}-${R}`,b=L_(o.paths.changes,C);if(B_(b)){g(`Change "${C}" already exists`),c("error");return}c("creating");let[v,P]=await A_(async()=>{let _=await ql(o.paths.changes,{description:R});await uc(_,"change",{name:"change",type:"sql"}),await uc(_,"revert",{name:"revert",type:"sql"}),u(_.name),c("complete")});P&&(g(P instanceof Error?P.message:String(P)),c("error"))},[o,f]);s&&a==="creating"&&!d&&!p&&w(s);let S=Dp(()=>{w(l)},[l,w]);return I_((E,T)=>{if(n){if(a==="input"){if(T.return){S();return}if(T.escape){l?m(""):r();return}}if(a==="complete"){E==="e"?e("change/edit",{name:d}):r();return}a==="error"&&(E==="r"?(g(null),c("input")):r())}}),o?a==="input"?ur(y,{title:"Add Change",paddingX:2,paddingY:1,children:ti(_s,{flexDirection:"column",gap:1,children:[ur(To,{children:"Describe the change you want to make:"}),ti(_s,{marginTop:1,children:[ur(To,{children:"Description: "}),ur(O_,{placeholder:"Add user roles table",defaultValue:l,onChange:m,isDisabled:!n})]}),h&&ti(To,{dimColor:!0,children:["Folder: ",new Date().toISOString().slice(0,10),"-",h]}),ti(_s,{marginTop:1,flexWrap:"wrap",columnGap:2,children:[ur(To,{dimColor:!0,children:"[Enter] Create"}),ur(To,{dimColor:!0,children:"[Esc] Cancel"})]})]})}):a==="creating"?ur(y,{title:"Add Change",paddingX:2,paddingY:1,children:ur($,{label:"Creating change folder..."})}):a==="complete"?ur(y,{title:"Add Change",paddingX:2,paddingY:1,borderColor:"green",children:ti(_s,{flexDirection:"column",gap:1,children:[ti(_e,{variant:"success",children:['Change "',d,'" created!']}),ur(To,{dimColor:!0,children:"Created folder structure with template files."}),ti(_s,{marginTop:1,flexWrap:"wrap",columnGap:2,children:[ur(To,{dimColor:!0,children:"[e] Edit in editor"}),ur(To,{dimColor:!0,children:"[any] Back to list"})]})]})}):ur(y,{title:"Add Change",paddingX:2,paddingY:1,borderColor:"red",children:ti(_s,{flexDirection:"column",gap:1,children:[ur(_e,{variant:"error",children:p}),ti(_s,{marginTop:1,flexWrap:"wrap",columnGap:2,children:[ur(To,{dimColor:!0,children:"[r] Retry"}),ur(To,{dimColor:!0,children:"[any] Back"})]})]})}):ur(y,{title:"Add Change",paddingX:2,paddingY:1,borderColor:"yellow",children:ur(To,{color:"yellow",children:"No active configuration. Press 'c' to manage configs."})})}import{useState as Np,useEffect as M_}from"react";import{Box as ju,Text as Bc,useInput as $_}from"ink";import{spawn as j_}from"child_process";import{attempt as H_}from"@logosdx/utils";import{jsx as Zr,jsxs as Hu}from"react/jsx-runtime";function Fp({params:t}){let{navigate:e,back:r}=I(),{isFocused:n}=A("ChangeEdit"),{activeConfig:o,settings:i}=L(),s=t.name,[a,c]=Np("loading"),[l,m]=Np(""),[d,u]=Np(null);return M_(()=>{if(!o||!s){c("loading");return}let p=!1;return(async()=>{let[h,f]=await H_(async()=>{let S=(await At(o.paths.changes,o.paths.sql)).find(R=>R.name===s);if(!S)throw new Error(`Change not found: ${s}`);if(p)return;m(S.path),c("opening");let E=process.env.EDITOR||process.env.VISUAL||"code";j_(E,[S.path],{detached:!0,stdio:"ignore"}).unref(),c("complete")});f&&(p||(u(f instanceof Error?f.message:String(f)),c("error")))})(),()=>{p=!0}},[o,s]),$_((p,g)=>{n&&(a==="complete"||a==="error")&&r()}),s?o?a==="loading"?Zr(y,{title:"Edit Change",paddingX:2,paddingY:1,children:Zr($,{label:"Finding change..."})}):a==="opening"?Zr(y,{title:"Edit Change",paddingX:2,paddingY:1,children:Zr($,{label:"Opening in editor..."})}):a==="complete"?Zr(y,{title:"Edit Change",paddingX:2,paddingY:1,borderColor:"green",children:Hu(ju,{flexDirection:"column",gap:1,children:[Hu(_e,{variant:"success",children:['Opened "',s,'" in editor']}),Hu(Bc,{dimColor:!0,children:["Path: ",l]}),Zr(ju,{marginTop:1,children:Zr(Bc,{dimColor:!0,children:"Press any key to continue..."})})]})}):Zr(y,{title:"Edit Change",paddingX:2,paddingY:1,borderColor:"red",children:Hu(ju,{flexDirection:"column",gap:1,children:[Zr(_e,{variant:"error",children:d}),Zr(ju,{marginTop:1,children:Zr(Bc,{dimColor:!0,children:"Press any key to continue..."})})]})}):Zr(y,{title:"Edit Change",paddingX:2,paddingY:1,borderColor:"yellow",children:Zr(Bc,{color:"yellow",children:"No active configuration."})}):Zr(y,{title:"Edit Change",paddingX:2,paddingY:1,borderColor:"yellow",children:Zr(Bc,{color:"yellow",children:"No change name provided."})})}import{useState as Lc,useEffect as q_,useCallback as rb}from"react";import{Box as Na,Text as Ai,useInput as K_}from"ink";import{attempt as nb}from"@logosdx/utils";import{jsx as Xt,jsxs as Fa}from"react/jsx-runtime";function Bp({params:t}){let{navigate:e,back:r}=I(),{isFocused:n}=A("ChangeRemove"),{activeConfig:o,activeConfigName:i}=L(),s=t.name,[a,c]=Lc("loading"),[l,m]=Lc(null),[d,u]=Lc(null),[p,g]=Lc(!1),[h,f]=Lc(null);q_(()=>{if(!o||!s)return;let E=!1;return(async()=>{let[R,x]=await nb(async()=>{let b=(await At(o.paths.changes,o.paths.sql)).find(B=>B.name===s),v=await K(o.connection,i??"__rm__"),P=v.db,N=(await new Oe(P,i??"").getAllStatuses()).get(s);if(await v.destroy(),!E){if(b)m(b),g(!1);else if(N)g(!0);else throw new Error(`Change not found: ${s}`);u(N??null),c("confirm")}});x&&(E||(f(x instanceof Error?x.message:String(x)),c("error")))})(),()=>{E=!0}},[o,i,s]);let w=rb(async()=>{if(!o)return;c("deleting");let[E,T]=await nb(async()=>{if(l&&await na(l),d){let R=await K(o.connection,i??"__rm__"),x=R.db;await new Oe(x,i??"").deleteRecords(s),await R.destroy()}c("complete")});T&&(f(T instanceof Error?T.message:String(T)),c("error"))},[o,i,l,d,s]),S=rb(()=>{r()},[r]);if(K_((E,T)=>{n&&(a==="complete"||a==="error")&&r()}),!s)return Xt(y,{title:"Delete Change",paddingX:2,paddingY:1,borderColor:"yellow",children:Xt(Ai,{color:"yellow",children:"No change name provided."})});if(!o)return Xt(y,{title:"Delete Change",paddingX:2,paddingY:1,borderColor:"yellow",children:Xt(Ai,{color:"yellow",children:"No active configuration."})});if(a==="loading")return Xt(y,{title:"Delete Change",paddingX:2,paddingY:1,children:Xt($,{label:"Loading change..."})});if(a==="confirm"){let E=d?.status==="success"?"This change has been applied to the database.":p?"This is an orphaned change (exists in DB but not on disk).":"This change has not been applied.";return Xt(y,{title:"Delete Change",paddingX:2,paddingY:1,borderColor:"yellow",children:Fa(Na,{flexDirection:"column",gap:1,children:[Fa(Ai,{children:["Delete change:"," ",Xt(Ai,{bold:!0,color:"cyan",children:s})]}),l&&Xt(Na,{flexDirection:"column",children:Fa(Ai,{dimColor:!0,children:["Files: ",l.changeFiles.length," change,"," ",l.revertFiles.length," revert"]})}),Xt(Ai,{color:"yellow",children:E}),Xt(ee,{message:"Are you sure you want to delete this change?",onConfirm:w,onCancel:S,isFocused:n})]})})}return a==="deleting"?Xt(y,{title:"Delete Change",paddingX:2,paddingY:1,children:Xt($,{label:"Deleting change..."})}):a==="complete"?Xt(y,{title:"Delete Change",paddingX:2,paddingY:1,borderColor:"green",children:Fa(Na,{flexDirection:"column",gap:1,children:[Fa(_e,{variant:"success",children:['Change "',s,'" deleted.']}),Xt(Na,{marginTop:1,children:Xt(Ai,{dimColor:!0,children:"Press any key to continue..."})})]})}):Xt(y,{title:"Delete Change",paddingX:2,paddingY:1,borderColor:"red",children:Fa(Na,{flexDirection:"column",gap:1,children:[Xt(_e,{variant:"error",children:h}),Xt(Na,{marginTop:1,children:Xt(Ai,{dimColor:!0,children:"Press any key to continue..."})})]})})}import{useState as vs,useEffect as ob,useCallback as ib}from"react";import{readFile as V_}from"fs/promises";import{Box as Zn,Text as rr,useInput as U_}from"ink";import{ProgressBar as Y_}from"@inkjs/ui";import{attempt as Lp}from"@logosdx/utils";import{jsx as lt,jsxs as mr}from"react/jsx-runtime";var W_=`-- TODO: Add SQL statements here
|
|
1038
|
+
`;async function G_(t){if(t.changeFiles.length===0)return"Change has no files to execute";let e=!1;for(let r of t.changeFiles){if(r.type==="txt"){e=!0;continue}let[n,o]=await Lp(()=>V_(r.path,"utf-8"));if(o)continue;let i=n?.trim()??"";if(i&&i!==W_.trim()){e=!0;break}}return e?null:"Change files are empty or contain only template placeholders. Edit the SQL files before running."}function Ip({params:t}){let{navigate:e,back:r}=I(),{isFocused:n}=A("ChangeRun"),{activeConfig:o,activeConfigName:i,stateManager:s,identity:a}=L(),c=t.name,[l,m]=vs("loading"),[d,u]=vs(null),[p,g]=vs(null),[h,f]=vs({current:0,total:0}),[w,S]=vs(""),[E,T]=vs(null),[R,x]=vs(!1);ob(()=>{if(!o||!c)return;let P=!1;return(async()=>{let[O,N]=await Lp(async()=>{let D=(await At(o.paths.changes,o.paths.sql)).find(Q=>Q.name===c);if(!D)throw new Error(`Change not found: ${c}`);let F=await K(o.connection,i??"__run__"),M=F.db,U=(await new Oe(M,i??"").getAllStatuses()).get(c);if(await F.destroy(),P)return;if(U?.status==="success")throw new Error(`Change "${c}" is already applied`);let j=await G_(D);if(j)throw new Error(j);u(D),x(o.protected??!1),m("confirm")});N&&(P||(T(N instanceof Error?N.message:String(N)),m("error")))})(),()=>{P=!0}},[o,i,c]),ob(()=>{let P=k.on("change:file",_=>{_.change===c&&(f({current:_.index,total:_.total}),S(_.filepath))});return()=>{P()}},[c]);let C=ib(async()=>{if(!o||!d||!s)return;m("running"),f({current:0,total:d.changeFiles.length});let[P,_]=await Lp(async()=>{let O=await K(o.connection,i??"__run__"),N=O.db,B=kn({cryptoIdentity:a??null}),D={db:N,configName:i??"",identity:B,projectRoot:process.cwd(),changesDir:o.paths.changes,sqlDir:o.paths.sql},F=await Ci(D,d);await O.destroy(),g(F),m(F.status==="success"?"complete":"error"),F.status!=="success"&&T(F.error??"Execution failed")});_&&(T(_ instanceof Error?_.message:String(_)),m("error"))},[o,i,d,s]),b=ib(()=>{r()},[r]);if(U_((P,_)=>{n&&(l==="complete"||l==="error")&&r()}),!c)return lt(y,{title:"Run Change",paddingX:2,paddingY:1,borderColor:"yellow",children:lt(rr,{color:"yellow",children:"No change name provided."})});if(!o)return lt(y,{title:"Run Change",paddingX:2,paddingY:1,borderColor:"yellow",children:lt(rr,{color:"yellow",children:"No active configuration."})});if(l==="loading")return lt(y,{title:"Run Change",paddingX:2,paddingY:1,children:lt($,{label:"Loading change..."})});if(l==="confirm"&&d){let P=mr(Zn,{flexDirection:"column",gap:1,children:[mr(rr,{children:["Run change:"," ",lt(rr,{bold:!0,color:"cyan",children:c})]}),mr(rr,{children:["On config: ",lt(rr,{bold:!0,children:i})]}),mr(rr,{dimColor:!0,children:["Files to execute: ",d.changeFiles.length]})]});return R?lt(y,{title:"Run Change",paddingX:2,paddingY:1,borderColor:"yellow",children:mr(Zn,{flexDirection:"column",gap:1,children:[P,lt(pt,{configName:i??"config",action:"apply this change",onConfirm:C,onCancel:b,isFocused:n})]})}):lt(y,{title:"Run Change",paddingX:2,paddingY:1,children:mr(Zn,{flexDirection:"column",gap:1,children:[P,lt(ee,{message:"Apply this change?",onConfirm:C,onCancel:b,isFocused:n})]})})}if(l==="running"){let P=h.total>0?h.current/h.total:0;return lt(y,{title:"Run Change",paddingX:2,paddingY:1,children:mr(Zn,{flexDirection:"column",gap:1,children:[mr(rr,{children:["Applying:"," ",lt(rr,{bold:!0,color:"cyan",children:c})]}),lt(Zn,{width:50,children:lt(Y_,{value:P})}),mr(rr,{dimColor:!0,children:[h.current,"/",h.total," files",w&&` - ${w.split("/").pop()}`]})]})})}if(l==="complete"&&p)return lt(y,{title:"Run Change",paddingX:2,paddingY:1,borderColor:"green",children:mr(Zn,{flexDirection:"column",gap:1,children:[mr(_e,{variant:"success",children:['Change "',c,'" applied successfully!']}),mr(rr,{dimColor:!0,children:["Duration: ",p.durationMs,"ms | Files: ",p.files?.length??0]}),lt(Zn,{marginTop:1,children:lt(rr,{dimColor:!0,children:"Press any key to continue..."})})]})});let v=p?.files?.find(P=>P.status==="failed");return lt(y,{title:"Run Change",paddingX:2,paddingY:1,borderColor:"red",children:mr(Zn,{flexDirection:"column",gap:1,children:[lt(_e,{variant:"error",children:"Failed to apply change"}),v&&mr(Zn,{flexDirection:"column",marginTop:1,children:[mr(rr,{color:"red",bold:!0,children:["Error in ",v.filepath.split("/").pop(),":"]}),lt(rr,{color:"red",wrap:"wrap",children:v.error})]}),!v&&E&<(Zn,{flexDirection:"column",marginTop:1,children:lt(rr,{color:"red",wrap:"wrap",children:E})}),p?.files&&p.files.length>0&&mr(Zn,{flexDirection:"column",marginTop:1,children:[lt(rr,{dimColor:!0,bold:!0,children:"File execution summary:"}),p.files.map((P,_)=>{let O=P.filepath.split("/").pop(),N=P.status==="success"?"\u2713":P.status==="failed"?"\u2717":"\u25CB",B=P.status==="success"?"green":P.status==="failed"?"red":"yellow";return mr(rr,{color:B,children:[N," ",O,P.status==="failed"&&P.error&&mr(rr,{dimColor:!0,children:[" - ",P.error.slice(0,60),P.error.length>60?"...":""]})]},_)})]}),lt(Zn,{marginTop:1,children:lt(rr,{dimColor:!0,children:"Press any key to continue..."})})]})})}import{useState as Ds,useEffect as sb,useCallback as ab}from"react";import{Box as Io,Text as en,useInput as X_}from"ink";import{ProgressBar as z_}from"@inkjs/ui";import{attempt as cb}from"@logosdx/utils";import{jsx as It,jsxs as Ir}from"react/jsx-runtime";function Op({params:t}){let{navigate:e,back:r}=I(),{isFocused:n}=A("ChangeRevert"),{activeConfig:o,activeConfigName:i,identity:s}=L(),a=t.name,[c,l]=Ds("loading"),[m,d]=Ds(null),[u,p]=Ds(null),[g,h]=Ds({current:0,total:0}),[f,w]=Ds(""),[S,E]=Ds(null),[T,R]=Ds(!1);sb(()=>{if(!o||!a)return;let b=!1;return(async()=>{let[P,_]=await cb(async()=>{let N=(await At(o.paths.changes,o.paths.sql)).find(V=>V.name===a);if(!N)throw new Error(`Change not found: ${a}`);let B=await K(o.connection,i??"__revert__"),D=B.db,H=(await new Oe(D,i??"").getAllStatuses()).get(a);if(await B.destroy(),!b){if(H?.status!=="success")throw new Error(`Change "${a}" is not applied`);if(N.revertFiles.length===0)throw new Error(`Change "${a}" has no revert files`);d(N),R(o.protected??!1),l("confirm")}});_&&(b||(E(_ instanceof Error?_.message:String(_)),l("error")))})(),()=>{b=!0}},[o,i,a]),sb(()=>{let b=k.on("change:file",v=>{v.change===a&&(h({current:v.index,total:v.total}),w(v.filepath))});return()=>{b()}},[a]);let x=ab(async()=>{if(!o||!m)return;l("reverting"),h({current:0,total:m.revertFiles.length});let[b,v]=await cb(async()=>{let P=await K(o.connection,i??"__revert__"),_=P.db,O=kn({cryptoIdentity:s??null}),N={db:_,configName:i??"",identity:O,projectRoot:process.cwd(),changesDir:o.paths.changes,sqlDir:o.paths.sql},B=await wi(N,m);await P.destroy(),p(B),l(B.status==="success"?"complete":"error"),B.status!=="success"&&E(B.error??"Revert failed")});v&&(E(v instanceof Error?v.message:String(v)),l("error"))},[o,i,m,s]),C=ab(()=>{r()},[r]);if(X_((b,v)=>{n&&(c==="complete"||c==="error")&&r()}),!a)return It(y,{title:"Revert Change",paddingX:2,paddingY:1,borderColor:"yellow",children:It(en,{color:"yellow",children:"No change name provided."})});if(!o)return It(y,{title:"Revert Change",paddingX:2,paddingY:1,borderColor:"yellow",children:It(en,{color:"yellow",children:"No active configuration."})});if(c==="loading")return It(y,{title:"Revert Change",paddingX:2,paddingY:1,children:It($,{label:"Loading change..."})});if(c==="confirm"&&m){let b=Ir(Io,{flexDirection:"column",gap:1,children:[Ir(en,{children:["Revert change:"," ",It(en,{bold:!0,color:"yellow",children:a})]}),Ir(en,{children:["On config: ",It(en,{bold:!0,children:i})]}),Ir(en,{dimColor:!0,children:["Revert files to execute: ",m.revertFiles.length]})]});return T?It(y,{title:"Revert Change",paddingX:2,paddingY:1,borderColor:"yellow",children:Ir(Io,{flexDirection:"column",gap:1,children:[b,It(pt,{configName:i??"config",action:"revert this change",onConfirm:x,onCancel:C,isFocused:n})]})}):It(y,{title:"Revert Change",paddingX:2,paddingY:1,children:Ir(Io,{flexDirection:"column",gap:1,children:[b,It(ee,{message:"Revert this change?",onConfirm:x,onCancel:C,isFocused:n})]})})}if(c==="reverting"){let b=g.total>0?g.current/g.total:0;return It(y,{title:"Revert Change",paddingX:2,paddingY:1,children:Ir(Io,{flexDirection:"column",gap:1,children:[Ir(en,{children:["Reverting:"," ",It(en,{bold:!0,color:"yellow",children:a})]}),It(Io,{width:50,children:It(z_,{value:b})}),Ir(en,{dimColor:!0,children:[g.current,"/",g.total," files",f&&` - ${f.split("/").pop()}`]})]})})}return c==="complete"&&u?It(y,{title:"Revert Change",paddingX:2,paddingY:1,borderColor:"green",children:Ir(Io,{flexDirection:"column",gap:1,children:[Ir(_e,{variant:"success",children:['Change "',a,'" reverted successfully!']}),Ir(en,{dimColor:!0,children:["Duration: ",u.durationMs,"ms | Files: ",u.files?.length??0]}),It(Io,{marginTop:1,children:It(en,{dimColor:!0,children:"Press any key to continue..."})})]})}):It(y,{title:"Revert Change",paddingX:2,paddingY:1,borderColor:"red",children:Ir(Io,{flexDirection:"column",gap:1,children:[Ir(_e,{variant:"error",children:["Failed to revert change: ",S]}),u?.files&&Ir(Io,{flexDirection:"column",children:[It(en,{dimColor:!0,children:"Executed files:"}),u.files.map((b,v)=>Ir(en,{color:b.status==="success"?"green":"red",children:[b.status==="success"?"\u2713":"\u2717"," ",b.filepath.split("/").pop()]},v))]}),It(Io,{marginTop:1,children:It(en,{dimColor:!0,children:"Press any key to continue..."})})]})})}import{useState as ri,useEffect as lb,useCallback as Ap,useMemo as J_}from"react";import{Box as yn,Text as hn,useInput as Q_}from"ink";import{TextInput as Z_,ProgressBar as ev}from"@inkjs/ui";import{attempt as ub}from"@logosdx/utils";import{jsx as Ue,jsxs as Or}from"react/jsx-runtime";function Mp({params:t}){let{navigate:e,back:r}=I(),{isFocused:n}=A("ChangeNext"),{activeConfig:o,activeConfigName:i,stateManager:s,identity:a}=L(),c=t.count?parseInt(String(t.count),10):1,[l,m]=ri("loading"),[d,u]=ri([]),[p,g]=ri(c),[h,f]=ri(String(c)),[w,S]=ri([]),[E,T]=ri(""),[R,x]=ri({current:0,total:0}),[C,b]=ri(null),[v,P]=ri(!1);lb(()=>{if(!o)return;let D=!1;return(async()=>{let[M,H]=await ub(async()=>{let V=await At(o.paths.changes,o.paths.sql),U=await K(o.connection,i??"__next__"),j=U.db,fe=await new Oe(j,i??"").getAllStatuses();if(await U.destroy(),D)return;let xe=V.filter(oe=>{let Je=fe.get(oe.name);return!Je||Je.status==="pending"||Je.status==="reverted"}).map(oe=>({name:oe.name,path:oe.path,date:oe.date,description:oe.description,status:"pending",appliedAt:null,appliedBy:null,revertedAt:null,errorMessage:null,isNew:!0,orphaned:!1,changeFiles:oe.changeFiles,revertFiles:oe.revertFiles})).sort((oe,Je)=>{let Vr=oe.date?.getTime()??0,ie=Je.date?.getTime()??0;return Vr-ie});u(xe),P(o.protected??!1),xe.length===0?(b("No pending changes"),m("error")):c>0?m("confirm"):m("input")});H&&(D||(b(H instanceof Error?H.message:String(H)),m("error")))})(),()=>{D=!0}},[o,i,c]),lb(()=>{let D=k.on("change:start",M=>{T(M.name)}),F=k.on("change:complete",M=>{S(H=>[...H,{key:M.name,label:M.name,status:M.status==="success"?"success":"error",detail:`${M.durationMs}ms`}]),x(H=>({...H,current:H.current+1}))});return()=>{D(),F()}},[]);let _=J_(()=>d.slice(0,p),[d,p]),O=Ap(()=>{let D=parseInt(h,10);isNaN(D)||D<1||(g(Math.min(D,d.length)),m("confirm"))},[h,d.length]),N=Ap(async()=>{if(!o||!s||_.length===0)return;m("running"),x({current:0,total:_.length}),S([]);let[D,F]=await ub(async()=>{let M=await K(o.connection,i??"__next__"),H=M.db,V=kn({cryptoIdentity:a??null}),j=await new Gn({db:H,configName:i??"",identity:V,projectRoot:process.cwd(),changesDir:o.paths.changes,sqlDir:o.paths.sql}).next(p);await M.destroy(),j.failed>0?(b(`${j.failed} change(s) failed`),m("error")):m("complete")});F&&(b(F instanceof Error?F.message:String(F)),m("error"))},[o,i,s,_,p]),B=Ap(()=>{r()},[r]);if(Q_((D,F)=>{n&&(l==="input"&&(F.return?O():F.escape&&r()),(l==="complete"||l==="error")&&r())}),!o)return Ue(y,{title:"Apply Next Changes",paddingX:2,paddingY:1,borderColor:"yellow",children:Ue(hn,{color:"yellow",children:"No active configuration."})});if(l==="loading")return Ue(y,{title:"Apply Next Changes",paddingX:2,paddingY:1,children:Ue($,{label:"Loading pending changes..."})});if(l==="input")return Ue(y,{title:"Apply Next Changes",paddingX:2,paddingY:1,children:Or(yn,{flexDirection:"column",gap:1,children:[Or(hn,{children:["Pending changes: ",Ue(hn,{bold:!0,children:d.length})]}),Or(yn,{marginTop:1,children:[Ue(hn,{children:"How many to apply? "}),Ue(Z_,{placeholder:"1",defaultValue:h,onChange:f,isDisabled:!n})]}),Or(yn,{marginTop:1,gap:2,children:[Ue(hn,{dimColor:!0,children:"[Enter] Continue"}),Ue(hn,{dimColor:!0,children:"[Esc] Cancel"})]})]})});if(l==="confirm"){let D=Or(yn,{flexDirection:"column",gap:1,children:[Or(hn,{children:["Apply"," ",Ue(hn,{bold:!0,color:"cyan",children:p})," ","change(s):"]}),Or(yn,{flexDirection:"column",marginTop:1,children:[_.slice(0,5).map(F=>Or(hn,{dimColor:!0,children:[" ","\u2022 ",F.name]},F.name)),_.length>5&&Or(hn,{dimColor:!0,children:[" ... and ",_.length-5," more"]})]})]});return v?Ue(y,{title:"Apply Next Changes",paddingX:2,paddingY:1,borderColor:"yellow",children:Or(yn,{flexDirection:"column",gap:1,children:[D,Ue(pt,{configName:i??"config",action:"apply these changes",onConfirm:N,onCancel:B,isFocused:n})]})}):Ue(y,{title:"Apply Next Changes",paddingX:2,paddingY:1,children:Or(yn,{flexDirection:"column",gap:1,children:[D,Ue(ee,{message:"Apply these changes?",onConfirm:N,onCancel:B,isFocused:n})]})})}if(l==="running"){let D=R.total>0?R.current/R.total:0;return Ue(y,{title:"Apply Next Changes",paddingX:2,paddingY:1,children:Or(yn,{flexDirection:"column",gap:1,children:[Ue(hn,{children:"Applying changes..."}),Ue(yn,{width:50,children:Ue(ev,{value:D})}),Or(hn,{dimColor:!0,children:[R.current,"/",R.total,E&&` - ${E}`]}),w.length>0&&Ue(yn,{marginTop:1,children:Ue(lr,{items:w})})]})})}if(l==="complete"){let D=w.filter(F=>F.status==="success").length;return Ue(y,{title:"Apply Next Changes",paddingX:2,paddingY:1,borderColor:"green",children:Or(yn,{flexDirection:"column",gap:1,children:[Or(_e,{variant:"success",children:["Applied ",D," change(s) successfully!"]}),Ue(lr,{items:w}),Ue(yn,{marginTop:1,children:Ue(hn,{dimColor:!0,children:"Press any key to continue..."})})]})})}return Ue(y,{title:"Apply Next Changes",paddingX:2,paddingY:1,borderColor:"red",children:Or(yn,{flexDirection:"column",gap:1,children:[Ue(_e,{variant:"error",children:C}),w.length>0&&Ue(lr,{items:w}),Ue(yn,{marginTop:1,children:Ue(hn,{dimColor:!0,children:"Press any key to continue..."})})]})})}import{useState as Ps,useEffect as mb,useCallback as db}from"react";import{readFile as tv}from"fs/promises";import{Box as Eo,Text as ni,useInput as rv}from"ink";import{ProgressBar as nv}from"@inkjs/ui";import{attempt as $p}from"@logosdx/utils";import{jsx as kt,jsxs as eo}from"react/jsx-runtime";var ov=`-- TODO: Add SQL statements here
|
|
1039
|
+
`;async function iv(t){if(t.changeFiles.length===0)return`"${t.name}" has no files to execute`;let e=!1;for(let r of t.changeFiles){if(r.type==="txt"){e=!0;continue}let[n,o]=await $p(()=>tv(r.path,"utf-8"));if(o)continue;let i=n?.trim()??"";if(i&&i!==ov.trim()){e=!0;break}}return e?null:`"${t.name}" has empty or template-only files`}function jp({params:t}){let{navigate:e,back:r}=I(),{isFocused:n}=A("ChangeFF"),{activeConfig:o,activeConfigName:i,stateManager:s,identity:a}=L(),[c,l]=Ps("loading"),[m,d]=Ps([]),[u,p]=Ps([]),[g,h]=Ps(""),[f,w]=Ps({current:0,total:0}),[S,E]=Ps(null),[T,R]=Ps(!1);mb(()=>{if(!o)return;let b=!1;return(async()=>{let[P,_]=await $p(async()=>{let O=await At(o.paths.changes,o.paths.sql),N=await K(o.connection,i??"__ff__"),B=N.db,F=await new Oe(B,i??"").getAllStatuses();if(await N.destroy(),b)return;let M=O.filter(V=>{let U=F.get(V.name);return!U||U.status==="pending"||U.status==="reverted"}).map(V=>({name:V.name,path:V.path,date:V.date,description:V.description,status:"pending",appliedAt:null,appliedBy:null,revertedAt:null,errorMessage:null,isNew:!0,orphaned:!1,changeFiles:V.changeFiles,revertFiles:V.revertFiles})).sort((V,U)=>{let j=V.date?.getTime()??0,Q=U.date?.getTime()??0;return j-Q}),H=[];for(let V of O.filter(U=>M.some(j=>j.name===U.name)))await iv(V)&&H.push(V.name);if(H.length>0){let V=H.slice(0,3).join(", "),U=H.length>3?` and ${H.length-3} more`:"";throw new Error(`Cannot fast-forward: ${V}${U} have empty or template-only files. Edit the SQL files before running.`)}d(M),R(o.protected??!1),M.length===0?(E("No pending changes"),l("error")):l("confirm")});_&&(b||(E(_ instanceof Error?_.message:String(_)),l("error")))})(),()=>{b=!0}},[o,i]),mb(()=>{let b=k.on("change:start",P=>{h(P.name)}),v=k.on("change:complete",P=>{p(_=>[..._,{key:P.name,label:P.name,status:P.status==="success"?"success":"error",detail:`${P.durationMs}ms`}]),w(_=>({..._,current:_.current+1}))});return()=>{b(),v()}},[]);let x=db(async()=>{if(!o||!s||m.length===0)return;l("running"),w({current:0,total:m.length}),p([]);let[b,v]=await $p(async()=>{let P=await K(o.connection,i??"__ff__"),_=P.db,O=kn({cryptoIdentity:a??null}),B=await new Gn({db:_,configName:i??"",identity:O,projectRoot:process.cwd(),changesDir:o.paths.changes,sqlDir:o.paths.sql}).ff();await P.destroy(),B.failed>0?(E(`${B.failed} change(s) failed`),l("error")):l("complete")});v&&(E(v instanceof Error?v.message:String(v)),l("error"))},[o,i,s,m]),C=db(()=>{r()},[r]);if(rv((b,v)=>{n&&(c==="complete"||c==="error")&&r()}),!o)return kt(y,{title:"Fast-Forward",paddingX:2,paddingY:1,borderColor:"yellow",children:kt(ni,{color:"yellow",children:"No active configuration."})});if(c==="loading")return kt(y,{title:"Fast-Forward",paddingX:2,paddingY:1,children:kt($,{label:"Loading pending changes..."})});if(c==="confirm"){let b=eo(Eo,{flexDirection:"column",gap:1,children:[eo(ni,{children:["Apply"," ",kt(ni,{bold:!0,color:"cyan",children:m.length})," ","pending change(s):"]}),eo(Eo,{flexDirection:"column",marginTop:1,children:[m.slice(0,5).map(v=>eo(ni,{dimColor:!0,children:[" ","\u2022 ",v.name]},v.name)),m.length>5&&eo(ni,{dimColor:!0,children:[" ... and ",m.length-5," more"]})]})]});return T?kt(y,{title:"Fast-Forward",paddingX:2,paddingY:1,borderColor:"yellow",children:eo(Eo,{flexDirection:"column",gap:1,children:[b,kt(pt,{configName:i??"config",action:"apply all pending changes",onConfirm:x,onCancel:C,isFocused:n})]})}):kt(y,{title:"Fast-Forward",paddingX:2,paddingY:1,children:eo(Eo,{flexDirection:"column",gap:1,children:[b,kt(ee,{message:"Apply all pending changes?",onConfirm:x,onCancel:C,isFocused:n})]})})}if(c==="running"){let b=f.total>0?f.current/f.total:0;return kt(y,{title:"Fast-Forward",paddingX:2,paddingY:1,children:eo(Eo,{flexDirection:"column",gap:1,children:[kt(ni,{children:"Applying all pending changes..."}),kt(Eo,{width:50,children:kt(nv,{value:b})}),eo(ni,{dimColor:!0,children:[f.current,"/",f.total,g&&` - ${g}`]}),u.length>0&&kt(Eo,{marginTop:1,children:kt(lr,{items:u})})]})})}if(c==="complete"){let b=u.filter(v=>v.status==="success").length;return kt(y,{title:"Fast-Forward",paddingX:2,paddingY:1,borderColor:"green",children:eo(Eo,{flexDirection:"column",gap:1,children:[eo(_e,{variant:"success",children:["Applied ",b," change(s) successfully!"]}),kt(lr,{items:u}),kt(Eo,{marginTop:1,children:kt(ni,{dimColor:!0,children:"Press any key to continue..."})})]})})}return kt(y,{title:"Fast-Forward",paddingX:2,paddingY:1,borderColor:"red",children:eo(Eo,{flexDirection:"column",gap:1,children:[kt(_e,{variant:"error",children:S}),u.length>0&&kt(lr,{items:u}),kt(Eo,{marginTop:1,children:kt(ni,{dimColor:!0,children:"Press any key to continue..."})})]})})}import{useState as oi,useEffect as pb,useCallback as Hp}from"react";import{Box as tn,Text as _r,useInput as sv}from"ink";import{TextInput as av,ProgressBar as cv}from"@inkjs/ui";import{attempt as fb}from"@logosdx/utils";import{jsx as Ae,jsxs as dr}from"react/jsx-runtime";function qp({params:t}){let{navigate:e,back:r}=I(),{isFocused:n}=A("ChangeRewind"),{activeConfig:o,activeConfigName:i,stateManager:s,identity:a}=L(),c=t.count?String(t.count):t.name??"",[l,m]=oi("loading"),[d,u]=oi([]),[p,g]=oi([]),[h,f]=oi(c),[w,S]=oi([]),[E,T]=oi(""),[R,x]=oi({current:0,total:0}),[C,b]=oi(null),[v,P]=oi(!1);pb(()=>{if(!o)return;let D=!1;return(async()=>{let[M,H]=await fb(async()=>{let V=await At(o.paths.changes,o.paths.sql),U=await K(o.connection,i??"__rewind__"),j=U.db,fe=await new Oe(j,i??"").getAllStatuses();if(await U.destroy(),D)return;let xe=V.filter(oe=>fe.get(oe.name)?.status==="success").map(oe=>{let Je=fe.get(oe.name);return{name:oe.name,path:oe.path,date:oe.date,description:oe.description,status:"success",appliedAt:Je.appliedAt,appliedBy:Je.appliedBy,revertedAt:null,errorMessage:null,isNew:!1,orphaned:!1,changeFiles:oe.changeFiles,revertFiles:oe.revertFiles}}).sort((oe,Je)=>{let Vr=oe.appliedAt?.getTime()??0;return(Je.appliedAt?.getTime()??0)-Vr});if(u(xe),P(o.protected??!1),xe.length===0)b("No applied changes to revert"),m("error");else if(c){let oe=_(c,xe);oe.error?(b(oe.error),m("error")):(g(oe.changes),m("confirm"))}else m("input")});H&&(D||(b(H instanceof Error?H.message:String(H)),m("error")))})(),()=>{D=!0}},[o,i,c]),pb(()=>{let D=k.on("change:start",M=>{T(M.name)}),F=k.on("change:complete",M=>{S(H=>[...H,{key:M.name,label:M.name,status:M.status==="success"?"success":"error",detail:`${M.durationMs}ms`}]),x(H=>({...H,current:H.current+1}))});return()=>{D(),F()}},[]);let _=(D,F)=>{let M=parseInt(D,10);if(!isNaN(M)&&M>0)return M>F.length?{changes:[],error:`Only ${F.length} applied changes available`}:{changes:F.slice(0,M)};let H=F.findIndex(V=>V.name===D);return H===-1?{changes:[],error:`Change not found or not applied: ${D}`}:{changes:F.slice(0,H+1)}},O=Hp(()=>{if(!h.trim())return;let D=_(h.trim(),d);D.error?(b(D.error),m("error")):(g(D.changes),m("confirm"))},[h,d]),N=Hp(async()=>{if(!o||!s||p.length===0)return;m("running"),x({current:0,total:p.length}),S([]);let[D,F]=await fb(async()=>{let M=await K(o.connection,i??"__rewind__"),H=M.db,V=kn({cryptoIdentity:a??null}),j=await new Gn({db:H,configName:i??"",identity:V,projectRoot:process.cwd(),changesDir:o.paths.changes,sqlDir:o.paths.sql}).rewind(p.length);await M.destroy(),j.failed>0?(b(`${j.failed} revert(s) failed`),m("error")):m("complete")});F&&(b(F instanceof Error?F.message:String(F)),m("error"))},[o,i,s,p]),B=Hp(()=>{r()},[r]);if(sv((D,F)=>{n&&(l==="input"&&(F.return?O():F.escape&&r()),(l==="complete"||l==="error")&&r())}),!o)return Ae(y,{title:"Rewind Changes",paddingX:2,paddingY:1,borderColor:"yellow",children:Ae(_r,{color:"yellow",children:"No active configuration."})});if(l==="loading")return Ae(y,{title:"Rewind Changes",paddingX:2,paddingY:1,children:Ae($,{label:"Loading applied changes..."})});if(l==="input")return Ae(y,{title:"Rewind Changes",paddingX:2,paddingY:1,children:dr(tn,{flexDirection:"column",gap:1,children:[dr(_r,{children:["Applied changes: ",Ae(_r,{bold:!0,children:d.length})]}),dr(tn,{flexDirection:"column",marginTop:1,children:[Ae(_r,{dimColor:!0,children:"Recent applied (newest first):"}),d.slice(0,5).map(D=>dr(_r,{dimColor:!0,children:[" ","\u2022 ",D.name]},D.name))]}),dr(tn,{marginTop:1,children:[Ae(_r,{children:"Revert (count or name): "}),Ae(av,{placeholder:"1 or change-name",defaultValue:h,onChange:f,isDisabled:!n})]}),dr(tn,{marginTop:1,gap:2,children:[Ae(_r,{dimColor:!0,children:"[Enter] Continue"}),Ae(_r,{dimColor:!0,children:"[Esc] Cancel"})]})]})});if(l==="confirm"){let D=dr(tn,{flexDirection:"column",gap:1,children:[dr(_r,{children:["Revert"," ",Ae(_r,{bold:!0,color:"yellow",children:p.length})," ","change(s):"]}),dr(tn,{flexDirection:"column",marginTop:1,children:[p.slice(0,5).map(F=>dr(_r,{dimColor:!0,children:[" ","\u2022 ",F.name]},F.name)),p.length>5&&dr(_r,{dimColor:!0,children:[" ... and ",p.length-5," more"]})]}),Ae(_r,{color:"yellow",children:"This will revert in reverse order (newest first)."})]});return v?Ae(y,{title:"Rewind Changes",paddingX:2,paddingY:1,borderColor:"yellow",children:dr(tn,{flexDirection:"column",gap:1,children:[D,Ae(pt,{configName:i??"config",action:"revert these changes",onConfirm:N,onCancel:B,isFocused:n})]})}):Ae(y,{title:"Rewind Changes",paddingX:2,paddingY:1,children:dr(tn,{flexDirection:"column",gap:1,children:[D,Ae(ee,{message:"Revert these changes?",onConfirm:N,onCancel:B,isFocused:n})]})})}if(l==="running"){let D=R.total>0?R.current/R.total:0;return Ae(y,{title:"Rewind Changes",paddingX:2,paddingY:1,children:dr(tn,{flexDirection:"column",gap:1,children:[Ae(_r,{children:"Reverting changes..."}),Ae(tn,{width:50,children:Ae(cv,{value:D})}),dr(_r,{dimColor:!0,children:[R.current,"/",R.total,E&&` - ${E}`]}),w.length>0&&Ae(tn,{marginTop:1,children:Ae(lr,{items:w})})]})})}if(l==="complete"){let D=w.filter(F=>F.status==="success").length;return Ae(y,{title:"Rewind Changes",paddingX:2,paddingY:1,borderColor:"green",children:dr(tn,{flexDirection:"column",gap:1,children:[dr(_e,{variant:"success",children:["Reverted ",D," change(s) successfully!"]}),Ae(lr,{items:w}),Ae(tn,{marginTop:1,children:Ae(_r,{dimColor:!0,children:"Press any key to continue..."})})]})})}return Ae(y,{title:"Rewind Changes",paddingX:2,paddingY:1,borderColor:"red",children:dr(tn,{flexDirection:"column",gap:1,children:[Ae(_e,{variant:"error",children:C}),w.length>0&&Ae(lr,{items:w}),Ae(tn,{marginTop:1,children:Ae(_r,{dimColor:!0,children:"Press any key to continue..."})})]})})}import{useState as qu,useEffect as lv,useMemo as uv}from"react";import{Box as ii,Text as Ze,useInput as mv}from"ink";import{attempt as dv}from"@logosdx/utils";import{jsx as Kt,jsxs as Mt}from"react/jsx-runtime";function pv(t){switch(t){case"build":return{label:"[BUILD]",color:"blue"};case"run":return{label:"[RUN]",color:"magenta"};default:return{label:"[CHANGESET]",color:"cyan"}}}function Kp({params:t}){let{navigate:e,back:r}=I(),{isFocused:n}=A("ChangeHistory"),{activeConfig:o,activeConfigName:i,loadingStatus:s}=L(),[a,c]=qu([]),[l,m]=qu(!0),[d,u]=qu(null),[p,g]=qu(0);lv(()=>{if(!o||s!=="ready"){m(!1);return}let R=!1;return(async()=>{m(!0),u(null);let[C,b]=await dv(async()=>{let v=await K(o.connection,i??"__history__"),P=v.db,O=await new Oe(P,i??"").getUnifiedHistory(void 0,50);await v.destroy(),!R&&c(O)});b&&(R||u(b instanceof Error?b.message:String(b))),m(!1)})(),()=>{R=!0}},[o,i,s]);let h=uv(()=>a[p],[a,p]);if(mv((R,x)=>{if(n){if(x.upArrow){g(C=>Math.max(0,C-1));return}if(x.downArrow){g(C=>Math.min(a.length-1,C+1));return}if(x.escape){r();return}if(x.return&&h){e("change/history/detail",{operationId:h.id,name:h.name});return}}}),!o)return Kt(y,{title:"Execution History",paddingX:2,paddingY:1,borderColor:"yellow",children:Kt(Ze,{color:"yellow",children:"No active configuration. Press 'c' to manage configs."})});if(l)return Kt(y,{title:"Execution History",paddingX:2,paddingY:1,children:Kt($,{label:"Loading history..."})});if(d)return Kt(y,{title:"Execution History",paddingX:2,paddingY:1,borderColor:"red",children:Mt(ii,{flexDirection:"column",gap:1,children:[Mt(Ze,{color:"red",children:["Failed to load history: ",d]}),Kt(Ze,{dimColor:!0,children:"Press Esc to go back"})]})});let f=a.filter(R=>R.changeType==="change").length,w=a.filter(R=>R.changeType==="build").length,S=a.filter(R=>R.changeType==="run").length,E=a.filter(R=>R.status==="success").length,T=a.filter(R=>R.status==="failed").length;return Kt(y,{title:"Execution History",paddingX:2,paddingY:1,children:Mt(ii,{flexDirection:"column",gap:1,children:[Mt(ii,{gap:2,flexWrap:"wrap",children:[Mt(Ze,{children:["Total: ",Kt(Ze,{bold:!0,children:a.length})]}),Mt(Ze,{children:["Changes: ",Kt(Ze,{color:"cyan",children:f})]}),Mt(Ze,{children:["Builds: ",Kt(Ze,{color:"blue",children:w})]}),Mt(Ze,{children:["Runs: ",Kt(Ze,{color:"magenta",children:S})]}),Mt(Ze,{children:["Success: ",Kt(Ze,{color:"green",children:E})]}),T>0&&Mt(Ze,{children:["Failed: ",Kt(Ze,{color:"red",children:T})]})]}),a.length===0?Kt(ii,{marginTop:1,children:Kt(Ze,{dimColor:!0,children:"No execution history found."})}):Mt(ii,{flexDirection:"column",marginTop:1,children:[a.slice(0,15).map((R,x)=>{let C=x===p,b=pv(R.changeType),v=R.status==="success",P=v?"green":"red",_=v?"[OK]":"[ERR]",O=R.durationMs?`(${(R.durationMs/1e3).toFixed(1)}s)`:"";return Mt(ii,{children:[Kt(Ze,{color:C?"cyan":void 0,children:C?">":" "}),Mt(Ze,{color:P,children:[" ",_," "]}),Mt(Ze,{color:b.color,children:[b.label," "]}),Kt(Ze,{color:C?"cyan":void 0,bold:C,children:R.name}),Mt(Ze,{dimColor:!0,children:[" ",Bi(R.executedAt)," ",O]})]},R.id)}),a.length>15&&Mt(Ze,{dimColor:!0,children:["...and ",a.length-15," more"]})]}),h&&Mt(ii,{marginTop:1,flexDirection:"column",borderStyle:"single",borderColor:"gray",paddingX:1,children:[Kt(Ze,{bold:!0,children:h.name}),Mt(ii,{gap:2,children:[Mt(Ze,{dimColor:!0,children:["By: ",h.executedBy]}),Mt(Ze,{dimColor:!0,children:["Duration: ",(h.durationMs/1e3).toFixed(2),"s"]})]}),h.status==="failed"&&h.errorMessage&&Mt(Ze,{color:"red",children:["Error: ",h.errorMessage.slice(0,80),h.errorMessage.length>80?"...":""]}),Kt(Ze,{dimColor:!0,children:"Press Enter to view file details"})]}),Mt(ii,{marginTop:1,gap:2,children:[Kt(Ze,{dimColor:!0,children:"[Enter] View Files"}),Kt(Ze,{dimColor:!0,children:"[Esc] Back"})]})]})})}import{useState as Ku,useEffect as fv,useMemo as gv}from"react";import{Box as Mi,Text as Ct,useInput as yv}from"ink";import{attempt as hv}from"@logosdx/utils";import{jsx as zt,jsxs as nr}from"react/jsx-runtime";function xv(t){switch(t){case"success":return{icon:"[OK]",color:"green"};case"failed":return{icon:"[ERR]",color:"red"};case"skipped":return{icon:"[-]",color:"yellow"};default:return{icon:"[...]",color:"gray"}}}function bv(t){return t.split("/").pop()??t}function Vp({params:t}){let{back:e}=I(),{isFocused:r}=A("ChangeHistoryDetail"),{activeConfig:n,activeConfigName:o,loadingStatus:i}=L(),s=t.operationId,a=t.name??"Operation",[c,l]=Ku([]),[m,d]=Ku(!0),[u,p]=Ku(null),[g,h]=Ku(0);fv(()=>{if(!n||i!=="ready"||!s){d(!1);return}let T=!1;return(async()=>{d(!0),p(null);let[x,C]=await hv(async()=>{let b=await K(n.connection,o??"__detail__"),v=b.db,_=await new Oe(v,o??"").getFileHistory(s);await b.destroy(),!T&&l(_)});C&&(T||p(C instanceof Error?C.message:String(C))),d(!1)})(),()=>{T=!0}},[n,o,i,s]);let f=gv(()=>c[g],[c,g]);if(yv((T,R)=>{if(r){if(R.upArrow){h(x=>Math.max(0,x-1));return}if(R.downArrow){h(x=>Math.min(c.length-1,x+1));return}if(R.escape){e();return}}}),!s)return zt(y,{title:"File Executions",paddingX:2,paddingY:1,borderColor:"yellow",children:zt(Ct,{color:"yellow",children:"No operation selected."})});if(!n)return zt(y,{title:"File Executions",paddingX:2,paddingY:1,borderColor:"yellow",children:zt(Ct,{color:"yellow",children:"No active configuration."})});if(m)return zt(y,{title:`File Executions (${a})`,paddingX:2,paddingY:1,children:zt($,{label:"Loading file executions..."})});if(u)return zt(y,{title:"File Executions",paddingX:2,paddingY:1,borderColor:"red",children:nr(Mi,{flexDirection:"column",gap:1,children:[nr(Ct,{color:"red",children:["Failed to load files: ",u]}),zt(Ct,{dimColor:!0,children:"Press Esc to go back"})]})});let w=c.filter(T=>T.status==="success").length,S=c.filter(T=>T.status==="failed").length,E=c.filter(T=>T.status==="skipped").length;return zt(y,{title:`File Executions (${a})`,paddingX:2,paddingY:1,children:nr(Mi,{flexDirection:"column",gap:1,children:[nr(Mi,{gap:2,flexWrap:"wrap",children:[nr(Ct,{children:["Total: ",zt(Ct,{bold:!0,children:c.length})]}),nr(Ct,{children:["Success: ",zt(Ct,{color:"green",children:w})]}),S>0&&nr(Ct,{children:["Failed: ",zt(Ct,{color:"red",children:S})]}),E>0&&nr(Ct,{children:["Skipped: ",zt(Ct,{color:"yellow",children:E})]})]}),c.length===0?zt(Mi,{marginTop:1,children:zt(Ct,{dimColor:!0,children:"No file executions recorded."})}):nr(Mi,{flexDirection:"column",marginTop:1,children:[c.slice(0,20).map((T,R)=>{let x=R===g,C=xv(T.status),b=T.durationMs?`(${(T.durationMs/1e3).toFixed(1)}s)`:"";return nr(Mi,{children:[zt(Ct,{color:x?"cyan":void 0,children:x?">":" "}),nr(Ct,{color:C.color,children:[" ",C.icon," "]}),zt(Ct,{color:x?"cyan":void 0,bold:x,children:bv(T.filepath)}),nr(Ct,{dimColor:!0,children:[" ",b]}),T.status==="skipped"&&T.skipReason&&nr(Ct,{dimColor:!0,children:[" - ",T.skipReason]})]},T.id)}),c.length>20&&nr(Ct,{dimColor:!0,children:["...and ",c.length-20," more"]})]}),f&&nr(Mi,{marginTop:1,flexDirection:"column",borderStyle:"single",borderColor:"gray",paddingX:1,children:[zt(Ct,{bold:!0,children:"File Details"}),nr(Ct,{dimColor:!0,children:["Path: ",f.filepath]}),nr(Ct,{dimColor:!0,children:["Checksum: ",f.checksum.slice(0,16),"..."]}),f.status==="skipped"&&f.skipReason&&nr(Ct,{color:"yellow",children:["Skip Reason: ",f.skipReason]}),f.status==="failed"&&f.errorMessage&&nr(Ct,{color:"red",children:["Error: ",f.errorMessage]})]}),zt(Mi,{marginTop:1,gap:2,children:zt(Ct,{dimColor:!0,children:"[Esc] Back"})})]})})}import{useState as Up,useEffect as Sv}from"react";import{Box as xn,Text as et,useInput as Cv}from"ink";import{attempt as wv}from"@logosdx/utils";import{Fragment as Tv,jsx as Fe,jsxs as pr}from"react/jsx-runtime";function Yp({params:t}){let{navigate:e,back:r}=I(),{isFocused:n}=A("DbList"),{activeConfig:o,activeConfigName:i}=L(),{showToast:s}=q(),[a,c]=Up(null),[l,m]=Up(!0),[d,u]=Up(null);return Sv(()=>{if(!o){m(!1);return}let p=!1;return(async()=>{m(!0),u(null);let h=await de(o.connection);if(!h.ok){p||(c({connected:!1,connectionError:h.error,tablesExist:!1,trackedCount:0}),m(!1));return}let[f,w]=await wv(async()=>{let S=await K(o.connection,i??void 0),E=S.db,T=await mo(E),R=0;if(T){let x=await E.selectFrom("__noorm_executions__").select(E.fn.countAll().as("count")).executeTakeFirst();R=Number(x?.count??0)}return await S.destroy(),{connected:!0,tablesExist:T,trackedCount:R}});p||(w?c({connected:!1,connectionError:w.message,tablesExist:!1,trackedCount:0}):f&&c(f),m(!1))})(),()=>{p=!0}},[o,i]),Cv((p,g)=>{if(n){if(g.escape){r();return}if(o){if(p==="c"){if(a?.connected&&a?.tablesExist){s({message:`Database "${o.connection.database}" already initialized`,variant:"info"});return}e("db/create");return}if(p==="d"){e("db/destroy");return}if(p==="x"){if(!a?.connected)return;e("db/explore");return}if(p==="w"){if(!a?.connected)return;e("db/truncate");return}if(p==="t"){if(!a?.connected)return;e("db/teardown");return}}}}),o?l?Fe(xn,{flexDirection:"column",gap:1,children:Fe(y,{title:"Database Operations",paddingX:1,paddingY:1,children:Fe($,{label:"Checking database status..."})})}):pr(xn,{flexDirection:"column",gap:1,children:[Fe(y,{title:"Database Operations",paddingX:1,paddingY:1,children:pr(xn,{flexDirection:"column",gap:1,children:[pr(xn,{gap:2,children:[Fe(et,{children:"Config:"}),Fe(et,{bold:!0,color:"cyan",children:i})]}),pr(xn,{gap:2,children:[Fe(et,{children:"Connection:"}),a?.connected?Fe(wc,{status:"connected"}):pr(xn,{flexDirection:"column",children:[Fe(wc,{status:"error"}),a?.connectionError&&pr(et,{color:"red",dimColor:!0,children:[" ",a.connectionError]})]})]}),a?.connected&&pr(Tv,{children:[pr(xn,{gap:2,children:[Fe(et,{children:"Tracking Tables:"}),a.tablesExist?Fe(et,{color:"green",children:"Initialized"}):Fe(et,{color:"yellow",children:"Not initialized"})]}),pr(xn,{gap:2,children:[Fe(et,{children:"Tracked Executions:"}),Fe(et,{bold:!0,children:a.trackedCount})]})]})]})}),Fe(y,{title:"Available Actions",paddingX:1,paddingY:1,children:pr(xn,{flexDirection:"column",gap:1,children:[pr(et,{children:[Fe(et,{color:"cyan",children:"[c]"})," Create - Build database from SQL files"]}),pr(et,{children:[Fe(et,{color:"cyan",children:"[d]"})," Destroy - Drop all managed objects"]}),pr(et,{color:a?.connected?void 0:"gray",children:[Fe(et,{color:a?.connected?"cyan":"gray",children:"[x]"})," Explore - Browse database schema"]}),pr(et,{color:a?.connected?void 0:"gray",children:[Fe(et,{color:a?.connected?"cyan":"gray",children:"[w]"})," Wipe - Truncate table data (keep schema)"]}),pr(et,{color:a?.connected?void 0:"gray",children:[Fe(et,{color:a?.connected?"cyan":"gray",children:"[t]"})," Teardown - Drop user objects (keep noorm)"]})]})}),Fe(xn,{paddingX:1,children:Fe(et,{color:"yellow",dimColor:!0,children:"Warning: These operations modify the database directly."})}),pr(xn,{flexWrap:"wrap",columnGap:2,children:[Fe(et,{dimColor:!0,children:"[c] Create"}),Fe(et,{dimColor:!0,children:"[d] Destroy"}),Fe(et,{dimColor:!0,children:"[x] Explore"}),Fe(et,{dimColor:!0,children:"[w] Wipe"}),Fe(et,{dimColor:!0,children:"[t] Teardown"}),Fe(et,{dimColor:!0,children:"[Esc] Back"})]})]}):pr(xn,{flexDirection:"column",gap:1,children:[Fe(y,{title:"Database Operations",borderColor:"yellow",paddingX:1,paddingY:1,children:pr(xn,{flexDirection:"column",gap:1,children:[Fe(et,{color:"yellow",children:"No active configuration selected."}),Fe(et,{dimColor:!0,children:"Select a configuration first using the config screen."})]})}),Fe(xn,{flexWrap:"wrap",columnGap:2,children:Fe(et,{dimColor:!0,children:"[Esc] Back"})})]})}import{useState as Wp,useEffect as Ev,useCallback as Vu}from"react";import{Box as Ic,Text as Ns,useInput as Rv}from"ink";import{Fragment as kv,jsx as fr,jsxs as Uu}from"react/jsx-runtime";function Gp({params:t}){let{back:e}=I(),{isFocused:r}=A("DbCreate"),{activeConfig:n,activeConfigName:o}=L(),{showToast:i}=q(),[s,a]=Wp("loading"),[c,l]=Wp(null),[m,d]=Wp(null);Ev(()=>{if(!n||!o){a("error"),l("No active configuration");return}let f=!1;return(async()=>{let S=await is(n.connection);if(!f){if(!S.serverOk){l(`Cannot connect to server: ${S.error}`),a("error");return}if(S.exists&&S.trackingInitialized){i({message:`Database "${n.connection.database}" already initialized`,variant:"info"}),e();return}d(S),a("confirm")}})(),()=>{f=!0}},[n,o,i,e]);let u=Vu(async()=>{if(!n||!o)return;a("running");let f=await Bl(n.connection,o);if(!f.ok){l(f.error??"Failed to create database"),a("error");return}a("done")},[n,o]),p=Vu(()=>{u()},[u]),g=Vu(()=>{e()},[e]),h=Vu(()=>{let f=m?.exists&&m?.trackingInitialized?"Database already initialized":m?.exists?"Tracking tables initialized":"Database created successfully";i({message:f,variant:"success"}),e()},[m,i,e]);if(Rv((f,w)=>{r&&(s==="done"||s==="error")&&(w.return||w.escape)&&(s==="done"?h():e())}),!n)return fr(y,{title:"Create Database",borderColor:"red",paddingX:1,paddingY:1,children:fr(Ns,{color:"red",children:"No active configuration selected."})});if(s==="loading")return fr(y,{title:"Create Database",paddingX:1,paddingY:1,children:fr($,{label:"Checking database status..."})});if(s==="confirm"&&m){let f=n.connection.database,w=!m.exists,S=w?`Create database "${f}" and initialize tracking tables?`:`Initialize tracking tables in "${f}"?`;return n.protected?fr(pt,{configName:o??"unknown",action:w?"create database for":"initialize tracking for",onConfirm:p,onCancel:g,focusLabel:"DbCreateConfirm"}):fr(ee,{title:"Create Database",message:S,onConfirm:p,onCancel:g,focusLabel:"DbCreateConfirm"})}if(s==="running"){let f=m&&!m.exists?"Creating database...":"Initializing tracking tables...";return fr(y,{title:"Create Database",paddingX:1,paddingY:1,children:fr($,{label:f})})}return s==="done"?Uu(Ic,{flexDirection:"column",gap:1,children:[fr(y,{title:"Database Created",borderColor:"green",paddingX:1,paddingY:1,children:Uu(Ic,{flexDirection:"column",gap:1,children:[Uu(Ns,{color:"green",children:["Database ",fr(Ns,{bold:!0,children:n.connection.database})," is ready."]}),fr(Ns,{dimColor:!0,children:"Tracking tables have been initialized."})]})}),fr(Ic,{flexWrap:"wrap",columnGap:2,children:fr(Ns,{dimColor:!0,children:"[Enter/Esc] Done"})})]}):s==="error"?Uu(Ic,{flexDirection:"column",gap:1,children:[fr(y,{title:"Create Database Failed",borderColor:"red",paddingX:1,paddingY:1,children:fr(Ns,{color:"red",children:c})}),fr(Ic,{flexWrap:"wrap",columnGap:2,children:fr(Ns,{dimColor:!0,children:"[Enter/Esc] Back"})})]}):fr(kv,{})}import{useState as Xp,useEffect as _v,useCallback as Yu}from"react";import{Box as Fn,Text as Ar,useInput as vv}from"ink";import{Fragment as Dv,jsx as st,jsxs as Bn}from"react/jsx-runtime";function zp({params:t}){let{back:e}=I(),{isFocused:r}=A("DbDestroy"),{activeConfig:n,activeConfigName:o}=L(),{showToast:i}=q(),[s,a]=Xp("loading"),[c,l]=Xp(null),[m,d]=Xp(null);_v(()=>{if(!n||!o){a("error"),l("No active configuration");return}if(n.protected){a("blocked");return}let f=!1;return(async()=>{let S=await is(n.connection);if(!f){if(!S.serverOk){l(`Cannot connect to server: ${S.error}`),a("error");return}d(S),a("confirm")}})(),()=>{f=!0}},[n,o]);let u=Yu(async()=>{if(!n||!o)return;a("running");let f=await Ll(n.connection,o);if(!f.ok){l(f.error??"Failed to drop database"),a("error");return}a("done")},[n,o]),p=Yu(()=>{u()},[u]),g=Yu(()=>{e()},[e]),h=Yu(()=>{i({message:"Database dropped",variant:"success"}),e()},[i,e]);return vv((f,w)=>{r&&(s==="blocked"&&(w.escape||w.return)&&e(),s==="confirm"&&m&&!m.exists&&w.escape&&e(),(s==="done"||s==="error")&&(w.return||w.escape)&&(s==="done"?h():e()))}),n?s==="blocked"?Bn(Fn,{flexDirection:"column",gap:1,children:[st(y,{title:"Destroy Database",borderColor:"red",paddingX:1,paddingY:1,children:Bn(Fn,{flexDirection:"column",gap:1,children:[Bn(Ar,{color:"red",children:["Cannot destroy protected configuration"," ",st(Ar,{bold:!0,children:o})]}),st(Ar,{dimColor:!0,children:"Protected configs cannot be dropped to prevent accidental data loss."})]})}),st(Fn,{flexWrap:"wrap",columnGap:2,children:st(Ar,{dimColor:!0,children:"[Enter/Esc] Back"})})]}):s==="loading"?st(y,{title:"Destroy Database",paddingX:1,paddingY:1,children:st($,{label:"Checking database status..."})}):s==="confirm"&&m?m.exists?Bn(Fn,{flexDirection:"column",gap:1,children:[st(y,{title:"Destroy Database",borderColor:"red",paddingX:1,paddingY:1,children:Bn(Fn,{flexDirection:"column",gap:1,children:[Bn(Ar,{children:["This will"," ",st(Ar,{bold:!0,color:"red",children:"permanently drop"})," ","the database"]}),Bn(Ar,{dimColor:!0,children:["Database: ",n.connection.database]})]})}),st(pt,{configName:o??"unknown",action:"drop database for",onConfirm:p,onCancel:g,focusLabel:"DbDestroyConfirm"})]}):Bn(Fn,{flexDirection:"column",gap:1,children:[st(y,{title:"Destroy Database",borderColor:"yellow",paddingX:1,paddingY:1,children:Bn(Fn,{flexDirection:"column",gap:1,children:[Bn(Ar,{color:"yellow",children:['Database "',n.connection.database,'" does not exist.']}),st(Ar,{dimColor:!0,children:"Nothing to destroy."})]})}),st(Fn,{flexWrap:"wrap",columnGap:2,children:st(Ar,{dimColor:!0,children:"[Esc] Back"})})]}):s==="running"?st(y,{title:"Destroy Database",paddingX:1,paddingY:1,children:st($,{label:"Dropping database..."})}):s==="done"?Bn(Fn,{flexDirection:"column",gap:1,children:[st(y,{title:"Database Destroyed",borderColor:"green",paddingX:1,paddingY:1,children:st(Fn,{flexDirection:"column",gap:1,children:Bn(Ar,{color:"green",children:["Database ",st(Ar,{bold:!0,children:n.connection.database})," has been dropped."]})})}),st(Fn,{flexWrap:"wrap",columnGap:2,children:st(Ar,{dimColor:!0,children:"[Enter/Esc] Done"})})]}):s==="error"?Bn(Fn,{flexDirection:"column",gap:1,children:[st(y,{title:"Destroy Database Failed",borderColor:"red",paddingX:1,paddingY:1,children:st(Ar,{color:"red",children:c})}),st(Fn,{flexWrap:"wrap",columnGap:2,children:st(Ar,{dimColor:!0,children:"[Enter/Esc] Back"})})]}):st(Dv,{}):st(y,{title:"Destroy Database",borderColor:"red",paddingX:1,paddingY:1,children:st(Ar,{color:"red",children:"No active configuration selected."})})}import{useState as Wu,useEffect as Pv,useCallback as Nv,useMemo as Fv,useRef as Bv}from"react";import{Box as to,Text as Vt,useInput as Lv}from"ink";import{attempt as gb}from"@logosdx/utils";import{Fragment as Iv,jsx as _t,jsxs as Jt}from"react/jsx-runtime";function Jp({params:t}){let{back:e}=I(),{isFocused:r}=A("DbTruncate"),{activeConfig:n,activeConfigName:o}=L(),{settings:i}=cr(),{showToast:s}=q(),[a,c]=Wu("loading"),[l,m]=Wu(null),[d,u]=Wu([]),[p,g]=Wu(null),h=Fv(()=>i?.teardown?.preserveTables??[],[i?.teardown?.preserveTables]),f=Bv(!1);Pv(()=>{if(!n||!o){m("No active configuration"),c("error");return}if(f.current)return;f.current=!0;let S=!1;return(async()=>{let[T,R]=await gb(()=>K(n.connection,o));if(R||!T){S||(m(`Connection failed: ${R?.message??"Unknown error"}`),c("error")),f.current=!1;return}try{let x=T.db,C=await Gr(x,n.connection.dialect,"tables");S||(u(C),c("preview"))}catch(x){S||(m(x instanceof Error?x.message:String(x)),c("error"))}finally{await T.destroy(),f.current=!1}})(),()=>{S=!0}},[n,o]);let w=Nv(async()=>{if(!n||!o)return;c("running");let[S,E]=await gb(()=>K(n.connection,o));if(E||!S){m(`Connection failed: ${E?.message??"Unknown error"}`),c("error");return}try{let T=S.db,R=await oa(T,n.connection.dialect,{preserve:h,restartIdentity:!0});g(R),c("done")}catch(T){m(T instanceof Error?T.message:String(T)),c("error")}finally{await S.destroy()}},[n,o,h]);if(Lv((S,E)=>{r&&(a==="preview"&&(E.escape&&e(),(E.return||S==="y")&&c("confirm")),(a==="done"||a==="error")&&(E.return||E.escape)&&(a==="done"&&s({message:`Truncated ${p?.truncated.length??0} tables`,variant:"success"}),e()))}),!n)return _t(y,{title:"Wipe Data",borderColor:"red",paddingX:1,paddingY:1,children:_t(Vt,{color:"red",children:"No active configuration selected."})});if(a==="loading")return _t(y,{title:"Wipe Data",paddingX:1,paddingY:1,children:_t($,{label:"Loading tables..."})});if(a==="error")return Jt(to,{flexDirection:"column",gap:1,children:[_t(y,{title:"Wipe Data Failed",borderColor:"red",paddingX:1,paddingY:1,children:_t(Vt,{color:"red",children:l})}),_t(to,{flexWrap:"wrap",columnGap:2,children:_t(Vt,{dimColor:!0,children:"[Enter/Esc] Back"})})]});if(a==="preview"){let S=new Set(h),E=d.filter(R=>!R.name.startsWith("__noorm_")&&!S.has(R.name)),T=d.filter(R=>R.name.startsWith("__noorm_")||S.has(R.name));return Jt(to,{flexDirection:"column",gap:1,children:[_t(y,{title:"Wipe Data - Preview",borderColor:"yellow",paddingX:1,paddingY:1,children:Jt(to,{flexDirection:"column",gap:1,children:[Jt(Vt,{children:["This will ",_t(Vt,{bold:!0,color:"yellow",children:"truncate all data"})," from the following tables:"]}),Jt(to,{flexDirection:"column",marginTop:1,children:[Jt(Vt,{bold:!0,children:["Tables to truncate (",E.length,"):"]}),E.length>0?E.slice(0,10).map(R=>Jt(Vt,{dimColor:!0,children:[" - ",R.name]},R.name)):_t(Vt,{dimColor:!0,children:" (none)"}),E.length>10&&Jt(Vt,{dimColor:!0,children:[" ... and ",E.length-10," more"]})]}),T.length>0&&Jt(to,{flexDirection:"column",marginTop:1,children:[Jt(Vt,{bold:!0,color:"green",children:["Preserved (",T.length,"):"]}),T.slice(0,5).map(R=>Jt(Vt,{color:"green",dimColor:!0,children:[" ","- ",R.name," ",R.name.startsWith("__noorm_")?"(system)":"(settings)"]},R.name)),T.length>5&&Jt(Vt,{dimColor:!0,children:[" ... and ",T.length-5," more"]})]})]})}),Jt(to,{flexWrap:"wrap",columnGap:2,children:[_t(Vt,{dimColor:!0,children:"[Enter/y] Continue"}),_t(Vt,{dimColor:!0,children:"[Esc] Cancel"})]})]})}return a==="confirm"?Jt(to,{flexDirection:"column",gap:1,children:[_t(y,{title:"Wipe Data",borderColor:"red",paddingX:1,paddingY:1,children:Jt(to,{flexDirection:"column",gap:1,children:[Jt(Vt,{children:["This will ",_t(Vt,{bold:!0,color:"red",children:"permanently delete"})," all data from tables."]}),_t(Vt,{dimColor:!0,children:"Schema and table structure will be preserved."})]})}),_t(pt,{configName:o??"unknown",action:"truncate data for",onConfirm:w,onCancel:()=>c("preview"),focusLabel:"DbTruncateConfirm"})]}):a==="running"?_t(y,{title:"Wipe Data",paddingX:1,paddingY:1,children:_t($,{label:"Truncating tables..."})}):a==="done"&&p?Jt(to,{flexDirection:"column",gap:1,children:[_t(y,{title:"Data Wiped",borderColor:"green",paddingX:1,paddingY:1,children:Jt(to,{flexDirection:"column",gap:1,children:[Jt(Vt,{color:"green",children:["Successfully truncated ",_t(Vt,{bold:!0,children:p.truncated.length})," tables."]}),Jt(Vt,{dimColor:!0,children:["Preserved ",p.preserved.length," tables. Duration: ",(p.durationMs/1e3).toFixed(2),"s"]})]})}),_t(to,{flexWrap:"wrap",columnGap:2,children:_t(Vt,{dimColor:!0,children:"[Enter/Esc] Done"})})]}):_t(Iv,{})}import{useState as Ba,useEffect as Ov,useCallback as Av,useMemo as Qp,useRef as Mv}from"react";import{Box as Ut,Text as he,useInput as $v}from"ink";import{attempt as yb}from"@logosdx/utils";import{Fragment as jv,jsx as ke,jsxs as we}from"react/jsx-runtime";var hb={tables:"Tables",views:"Views",functions:"Functions",types:"Types",foreignKeys:"Foreign Keys"};function Zp({params:t}){let{back:e}=I(),{isFocused:r}=A("DbTeardown"),{activeConfig:n,activeConfigName:o,identity:i}=L(),{settings:s}=cr(),{showToast:a}=q(),[c,l]=Ba("loading"),[m,d]=Ba(null),[u,p]=Ba(null),[g,h]=Ba(null),[f,w]=Ba("tables"),[S,E]=Ba(0),T=s?.teardown?.postScript,R=Qp(()=>s?.teardown?.preserveTables??[],[s?.teardown?.preserveTables]),x=Mv(!1);Ov(()=>{if(!n||!o){d("No active configuration"),l("error");return}if(x.current)return;x.current=!0;let P=!1;return(async()=>{let[O,N]=await yb(()=>K(n.connection,o));if(N||!O){P||(d(`Connection failed: ${N?.message??"Unknown error"}`),l("error")),x.current=!1;return}try{let B=O.db,D=await Wl(B,n.connection.dialect,{preserveTables:R,postScript:T});P||(p(D),l("preview"))}catch(B){P||(d(B instanceof Error?B.message:String(B)),l("error"))}finally{await O.destroy(),x.current=!1}})(),()=>{P=!0}},[n,o,R,T]);let C=Av(async()=>{if(!n||!o)return;l("running");let[P,_]=await yb(()=>K(n.connection,o));if(_||!P){d(`Connection failed: ${_?.message??"Unknown error"}`),l("error");return}try{let O=P.db,N=Zt({cryptoIdentity:i??null}),B=await us(O,n.connection.dialect,{preserveTables:R,postScript:T,configName:o,executedBy:Ft(N)});h(B),l("done")}catch(O){d(O instanceof Error?O.message:String(O)),l("error")}finally{await P.destroy()}},[n,o,R,T,i]),b=Qp(()=>{if(!u)return[];let P=[];return u.toDrop.tables.length>0&&P.push("tables"),u.toDrop.views.length>0&&P.push("views"),u.toDrop.functions.length>0&&P.push("functions"),u.toDrop.types.length>0&&P.push("types"),u.toDrop.foreignKeys.length>0&&P.push("foreignKeys"),P},[u]),v=Qp(()=>u?u.toDrop[f]??[]:[],[u,f]);if($v((P,_)=>{if(r){if(c==="preview"&&(_.escape&&e(),(_.return||P==="y")&&l("confirm"),P==="v"&&b.length>0&&(w(b[0]??"tables"),E(0),l("view"))),c==="view"){if(_.escape&&l("preview"),_.leftArrow||_.rightArrow){let N=b.indexOf(f),B;_.rightArrow?B=(N+1)%b.length:B=(N-1+b.length)%b.length,w(b[B]??"tables"),E(0)}let O=15;_.downArrow&&S<Math.max(0,v.length-O)&&E(N=>N+1),_.upArrow&&S>0&&E(N=>N-1),_.pageDown&&E(N=>Math.min(N+O,Math.max(0,v.length-O))),_.pageUp&&E(N=>Math.max(0,N-O))}if((c==="done"||c==="error")&&(_.return||_.escape)){if(c==="done"){let O=g?g.dropped.tables.length+g.dropped.views.length+g.dropped.functions.length+g.dropped.types.length:0;a({message:`Dropped ${O} objects`,variant:"success"})}e()}}}),!n)return ke(y,{title:"Schema Teardown",borderColor:"red",paddingX:1,paddingY:1,children:ke(he,{color:"red",children:"No active configuration selected."})});if(c==="loading")return ke(y,{title:"Schema Teardown",paddingX:1,paddingY:1,children:ke($,{label:"Analyzing schema..."})});if(c==="error")return we(Ut,{flexDirection:"column",gap:1,children:[ke(y,{title:"Schema Teardown Failed",borderColor:"red",paddingX:1,paddingY:1,children:ke(he,{color:"red",children:m})}),ke(Ut,{flexWrap:"wrap",columnGap:2,children:ke(he,{dimColor:!0,children:"[Enter/Esc] Back"})})]});if(c==="preview"&&u){let P=u.toDrop.tables.length+u.toDrop.views.length+u.toDrop.functions.length+u.toDrop.types.length+u.toDrop.foreignKeys.length;return we(Ut,{flexDirection:"column",gap:1,children:[ke(y,{title:"Schema Teardown - Preview",borderColor:"yellow",paddingX:1,paddingY:1,children:we(Ut,{flexDirection:"column",gap:1,children:[we(he,{children:["This will ",ke(he,{bold:!0,color:"yellow",children:"drop all user objects"})," from the database:"]}),we(Ut,{flexDirection:"column",marginTop:1,children:[we(he,{bold:!0,children:["Objects to drop (",P,"):"]}),u.toDrop.tables.length>0&&we(he,{dimColor:!0,children:[" ","Tables: ",u.toDrop.tables.length]}),u.toDrop.views.length>0&&we(he,{dimColor:!0,children:[" ","Views: ",u.toDrop.views.length]}),u.toDrop.functions.length>0&&we(he,{dimColor:!0,children:[" ","Functions: ",u.toDrop.functions.length]}),u.toDrop.types.length>0&&we(he,{dimColor:!0,children:[" ","Types: ",u.toDrop.types.length]}),u.toDrop.foreignKeys.length>0&&we(he,{dimColor:!0,children:[" ","Foreign Keys: ",u.toDrop.foreignKeys.length]}),P===0&&ke(he,{dimColor:!0,children:" (none)"})]}),u.toPreserve.length>0&&we(Ut,{flexDirection:"column",marginTop:1,children:[we(he,{bold:!0,color:"green",children:["Preserved (",u.toPreserve.length,"):"]}),u.toPreserve.slice(0,5).map(_=>we(he,{color:"green",dimColor:!0,children:[" ","- ",_," ",_.startsWith("__noorm_")?"(system)":"(settings)"]},_)),u.toPreserve.length>5&&we(he,{dimColor:!0,children:[" ... and ",u.toPreserve.length-5," more"]})]}),T&&ke(Ut,{marginTop:1,children:we(he,{dimColor:!0,children:["Post-script: ",T]})})]})}),we(Ut,{flexWrap:"wrap",columnGap:2,children:[b.length>0&&ke(he,{dimColor:!0,children:"[v] View details"}),ke(he,{dimColor:!0,children:"[Enter/y] Continue"}),ke(he,{dimColor:!0,children:"[Esc] Cancel"})]})]})}if(c==="view"&&u){let _=v.slice(S,S+15),O=v.length>15;return we(Ut,{flexDirection:"column",gap:1,children:[ke(y,{title:`Objects to Drop - ${hb[f]} (${v.length})`,borderColor:"yellow",paddingX:1,paddingY:1,children:we(Ut,{flexDirection:"column",children:[ke(Ut,{gap:2,marginBottom:1,children:b.map(N=>we(he,{bold:N===f,color:N===f?"yellow":void 0,dimColor:N!==f,children:[hb[N]," (",u.toDrop[N].length,")"]},N))}),we(Ut,{flexDirection:"column",children:[_.map((N,B)=>we(he,{dimColor:!0,children:[" ",N]},B)),v.length===0&&ke(he,{dimColor:!0,children:" (none)"})]}),O&&ke(Ut,{marginTop:1,children:we(he,{dimColor:!0,children:["Showing ",S+1,"-",Math.min(S+15,v.length)," of ",v.length]})})]})}),we(Ut,{flexWrap:"wrap",columnGap:2,children:[ke(he,{dimColor:!0,children:"[\u2190/\u2192] Category"}),O&&ke(he,{dimColor:!0,children:"[\u2191/\u2193] Scroll"}),ke(he,{dimColor:!0,children:"[Esc] Back"})]})]})}if(c==="confirm")return we(Ut,{flexDirection:"column",gap:1,children:[ke(y,{title:"Schema Teardown",borderColor:"red",paddingX:1,paddingY:1,children:we(Ut,{flexDirection:"column",gap:1,children:[we(he,{children:["This will ",ke(he,{bold:!0,color:"red",children:"permanently drop"})," all user-created objects."]}),ke(he,{dimColor:!0,children:"Only noorm tracking tables will be preserved."})]})}),ke(pt,{configName:o??"unknown",action:"drop schema for",onConfirm:C,onCancel:()=>l("preview"),focusLabel:"DbTeardownConfirm"})]});if(c==="running")return ke(y,{title:"Schema Teardown",paddingX:1,paddingY:1,children:ke($,{label:"Dropping objects..."})});if(c==="done"&&g){let P=g.dropped.tables.length+g.dropped.views.length+g.dropped.functions.length+g.dropped.types.length;return we(Ut,{flexDirection:"column",gap:1,children:[ke(y,{title:"Schema Teardown Complete",borderColor:"green",paddingX:1,paddingY:1,children:we(Ut,{flexDirection:"column",gap:1,children:[we(he,{color:"green",children:["Successfully dropped ",ke(he,{bold:!0,children:P})," objects."]}),we(Ut,{flexDirection:"column",children:[g.dropped.tables.length>0&&we(he,{dimColor:!0,children:[" Tables: ",g.dropped.tables.length]}),g.dropped.views.length>0&&we(he,{dimColor:!0,children:[" Views: ",g.dropped.views.length]}),g.dropped.functions.length>0&&we(he,{dimColor:!0,children:[" Functions: ",g.dropped.functions.length]}),g.dropped.types.length>0&&we(he,{dimColor:!0,children:[" Types: ",g.dropped.types.length]})]}),we(he,{dimColor:!0,children:["Preserved ",g.preserved.length," tables. Duration: ",(g.durationMs/1e3).toFixed(2),"s"]}),g.staleCount!==void 0&&g.staleCount>0&&we(he,{dimColor:!0,children:["Marked ",g.staleCount," changes as stale (will re-run on next apply)"]}),g.postScriptResult&&ke(Ut,{marginTop:1,children:g.postScriptResult.executed?ke(he,{color:"green",children:"Post-script executed successfully"}):we(he,{color:"red",children:["Post-script failed: ",g.postScriptResult.error]})})]})}),ke(Ut,{flexWrap:"wrap",columnGap:2,children:ke(he,{dimColor:!0,children:"[Enter/Esc] Done"})})]})}return ke(jv,{})}import{useState as tf,useEffect as Uv}from"react";import{Box as Mr,Text as gr,useInput as Yv}from"ink";import{attempt as Wv}from"@logosdx/utils";import{useEffect as Hv,useCallback as cX,useState as lX,useRef as xb,useMemo as qv}from"react";function si(t,e,r){let n=xb(e);n.current=e,Hv(()=>k.on(t,i=>{n.current(i)}),[t,...r])}function ef(t,e){let r=qv(()=>Array.isArray(t)?t:[t],[t]),n=xb(e);n.current=e,si("router:popped",o=>{r.some(s=>o.popped===s||o.popped.startsWith(s+"/"))&&n.current(o.popped,o.to)},[r])}import{useState as Kv,useCallback as Vv}from"react";var bb={phase:"idle",currentFile:null,filesTotal:0,filesRun:0,filesSkipped:0,filesFailed:0,filesDryRun:0,results:[],durationMs:0,status:null};function ai(){let[t,e]=Kv(bb),r=Vv(n=>{e({...bb,filesTotal:n})},[]);return si("build:start",n=>{e(o=>({...o,phase:"running",filesTotal:n.fileCount,currentFile:null}))},[]),si("file:before",n=>{e(o=>({...o,currentFile:n.filepath}))},[]),si("file:after",n=>{e(o=>{let i=n.status==="success",s={filepath:n.filepath,status:n.status,durationMs:n.durationMs,error:n.error};return{...o,filesRun:o.filesRun+(i?1:0),filesFailed:o.filesFailed+(i?0:1),results:[...o.results,s],currentFile:null}})},[]),si("file:skip",n=>{e(o=>{let i={filepath:n.filepath,status:"skipped",skipReason:n.reason};return{...o,filesSkipped:o.filesSkipped+1,results:[...o.results,i]}})},[]),si("file:dry-run",n=>{e(o=>{let i={filepath:n.filepath,status:"dry-run",outputPath:n.outputPath};return{...o,filesDryRun:o.filesDryRun+1,results:[...o.results,i],currentFile:null}})},[]),si("build:complete",n=>{e(o=>({...o,phase:"complete",status:n.status,durationMs:n.durationMs,currentFile:null}))},[]),{state:t,reset:r}}import{jsx as yt,jsxs as Ln}from"react/jsx-runtime";var Sb=[{key:"tables",label:"Tables",route:"db/explore/tables",hotkey:"t",numberKey:"1"},{key:"views",label:"Views",route:"db/explore/views",hotkey:"v",numberKey:"2"},{key:"procedures",label:"Procedures",route:"db/explore/procedures",hotkey:"p",numberKey:"3"},{key:"functions",label:"Functions",route:"db/explore/functions",hotkey:"f",numberKey:"4"},{key:"types",label:"Types",route:"db/explore/types",hotkey:"y",numberKey:"5"},{key:"indexes",label:"Indexes",route:"db/explore/indexes",hotkey:"i",numberKey:"6"},{key:"foreignKeys",label:"Foreign Keys",route:"db/explore/fks",hotkey:"k",numberKey:"7"}];function Gu({params:t}){let{navigate:e,back:r}=I(),{isFocused:n}=A("ExploreOverview"),{activeConfig:o,activeConfigName:i}=L(),{clearFilters:s}=tu(),{settings:a}=cr(),[c,l]=tf(null),[m,d]=tf(!0),[u,p]=tf(null),g={includeNoormTables:a?.logging?.level==="verbose"};if(ef("db/explore",()=>{s()}),Uv(()=>{if(!o){d(!1);return}let f=!1;return(async()=>{d(!0),p(null);let S=await de(o.connection);if(!S.ok){f||(p(S.error??"Connection failed"),d(!1));return}let[E,T]=await Wv(async()=>{let R=await K(o.connection,i??"__explore__"),x=await ac(R.db,o.connection.dialect,g);return await R.destroy(),x});f||(T?p(T.message):l(E),d(!1))})(),()=>{f=!0}},[o,i,a?.logging?.level]),Yv((f,w)=>{if(!n)return;if(w.escape){r();return}if(!c)return;let S=Sb.find(E=>E.hotkey===f||E.numberKey===f);S&&c[S.key]>0&&e(S.route)}),!o)return Ln(Mr,{flexDirection:"column",gap:1,children:[yt(y,{title:"DB Explore",borderColor:"yellow",paddingX:1,paddingY:1,children:Ln(Mr,{flexDirection:"column",gap:1,children:[yt(gr,{color:"yellow",children:"No active configuration selected."}),yt(gr,{dimColor:!0,children:"Select a configuration first using the config screen."})]})}),yt(Mr,{flexWrap:"wrap",columnGap:2,children:yt(gr,{dimColor:!0,children:"[Esc] Back"})})]});if(m)return yt(Mr,{flexDirection:"column",gap:1,children:yt(y,{title:"DB Explore",paddingX:1,paddingY:1,children:yt($,{label:"Loading schema overview..."})})});if(u)return Ln(Mr,{flexDirection:"column",gap:1,children:[yt(y,{title:"DB Explore",borderColor:"red",paddingX:1,paddingY:1,children:Ln(Mr,{flexDirection:"column",gap:1,children:[yt(gr,{color:"red",children:"Connection Error"}),yt(gr,{dimColor:!0,children:u})]})}),yt(Mr,{flexWrap:"wrap",columnGap:2,children:yt(gr,{dimColor:!0,children:"[Esc] Back"})})]});let h=c?Object.values(c).reduce((f,w)=>f+w,0):0;return Ln(Mr,{flexDirection:"column",gap:1,children:[yt(y,{title:"DB Explore",paddingX:1,paddingY:1,children:Ln(Mr,{flexDirection:"column",gap:1,children:[Ln(Mr,{gap:2,children:[yt(gr,{children:"Config:"}),yt(gr,{bold:!0,color:"cyan",children:i}),Ln(gr,{dimColor:!0,children:["(",o.connection.dialect,")"]})]}),Ln(Mr,{gap:2,children:[yt(gr,{children:"Database:"}),yt(gr,{children:o.connection.database})]}),Ln(Mr,{gap:2,children:[yt(gr,{children:"Total Objects:"}),yt(gr,{bold:!0,color:"green",children:h})]}),yt(Mr,{marginTop:1,flexDirection:"column",children:Sb.map(f=>{let w=c?.[f.key]??0,S=w>0;return Ln(Mr,{gap:2,children:[Ln(gr,{color:S?"cyan":"gray",children:["[",f.numberKey,"]"]}),yt(Mr,{width:14,children:yt(gr,{color:S?void 0:"gray",children:f.label})}),yt(gr,{bold:S,color:S?"green":"gray",children:w})]},f.key)})})]})}),Ln(Mr,{flexWrap:"wrap",columnGap:2,children:[yt(gr,{dimColor:!0,children:"[1-7] Navigate"}),yt(gr,{dimColor:!0,children:"[Esc] Back"})]})]})}import{useState as rf,useEffect as Gv,useMemo as Xv,useCallback as zv}from"react";import{Box as Oo,Text as ci,useInput as Jv}from"ink";import{attempt as Qv}from"@logosdx/utils";import{jsx as yr,jsxs as $i}from"react/jsx-runtime";var Zv={"db/explore/tables":{category:"tables",title:"Tables",detailRoute:"db/explore/tables/detail",hasDetail:!0},"db/explore/views":{category:"views",title:"Views",detailRoute:"db/explore/views/detail",hasDetail:!0},"db/explore/procedures":{category:"procedures",title:"Procedures",detailRoute:"db/explore/procedures/detail",hasDetail:!0},"db/explore/functions":{category:"functions",title:"Functions",detailRoute:"db/explore/functions/detail",hasDetail:!0},"db/explore/types":{category:"types",title:"Types",detailRoute:"db/explore/types/detail",hasDetail:!0},"db/explore/indexes":{category:"indexes",title:"Indexes",hasDetail:!1},"db/explore/fks":{category:"foreignKeys",title:"Foreign Keys",hasDetail:!1}};function Ao({params:t}){let{navigate:e,back:r,route:n}=I(),{isFocused:o}=A("ExploreList"),{activeConfig:i,activeConfigName:s}=L(),{getFilter:a,setFilter:c}=tu(),{settings:l}=cr(),[m,d]=rf([]),[u,p]=rf(!0),[g,h]=rf(null),f=Zv[n],w={includeNoormTables:l?.logging?.level==="verbose"},S=f?a(f.category):void 0;Gv(()=>{if(!i||!f){p(!1);return}let x=!1;return(async()=>{p(!0),h(null);let[b,v]=await Qv(async()=>{let P=await K(i.connection,s??"__explore__"),_=await Gr(P.db,i.connection.dialect,f.category,w);return await P.destroy(),_});x||(v?h(v.message):d(b),p(!1))})(),()=>{x=!0}},[i,s,f,l?.logging?.level]);let E=Xv(()=>f?m.map(x=>{let C=x.name,b="schema"in x?x.schema:void 0;return{key:b?`${b}.${C}`:C,label:b?`${b}.${C}`:C,value:x,description:cd(f.category,x)}}):[],[m,f]),T=x=>{if(!f?.hasDetail||!f.detailRoute)return;let C=x.value,b="schema"in C?C.schema:void 0;e(f.detailRoute,{name:C.name,schema:b})},R=zv(x=>{f&&c(f.category,{searchTerm:x.searchTerm,highlightedKey:x.highlightedKey})},[f,c]);return Jv((x,C)=>{o&&C.escape&&r()}),f?i?u?yr(Oo,{flexDirection:"column",gap:1,children:yr(y,{title:f.title,paddingX:1,paddingY:1,children:yr($,{label:`Loading ${f.title.toLowerCase()}...`})})}):g?$i(Oo,{flexDirection:"column",gap:1,children:[yr(y,{title:f.title,borderColor:"red",paddingX:1,paddingY:1,children:$i(Oo,{flexDirection:"column",gap:1,children:[$i(ci,{color:"red",children:["Error loading ",f.title.toLowerCase()]}),yr(ci,{dimColor:!0,children:g})]})}),yr(Oo,{flexWrap:"wrap",columnGap:2,children:yr(ci,{dimColor:!0,children:"[Esc] Back"})})]}):$i(Oo,{flexDirection:"column",gap:1,children:[yr(y,{title:`${f.title} (${m.length})`,paddingX:1,paddingY:1,children:yr(vi,{items:E,onSelect:f.hasDetail?T:void 0,searchPlaceholder:`Filter ${f.title.toLowerCase()}...`,emptyLabel:`No ${f.title.toLowerCase()} found`,noResultsLabel:"No matches",visibleCount:10,isFocused:o,numberNav:!0,initialSearchTerm:S?.searchTerm,initialHighlightedKey:S?.highlightedKey,onFilterChange:R})}),$i(Oo,{flexWrap:"wrap",columnGap:2,children:[f.hasDetail&&yr(ci,{dimColor:!0,children:"[Enter] View detail"}),yr(ci,{dimColor:!0,children:"[Esc] Back"})]})]}):$i(Oo,{flexDirection:"column",gap:1,children:[yr(y,{title:f.title,borderColor:"yellow",paddingX:1,paddingY:1,children:yr(ci,{color:"yellow",children:"No active configuration selected."})}),yr(Oo,{flexWrap:"wrap",columnGap:2,children:yr(ci,{dimColor:!0,children:"[Esc] Back"})})]}):$i(Oo,{flexDirection:"column",gap:1,children:[yr(y,{title:"Error",borderColor:"red",paddingX:1,paddingY:1,children:$i(ci,{color:"red",children:["Invalid explore route: ",n]})}),yr(Oo,{flexWrap:"wrap",columnGap:2,children:yr(ci,{dimColor:!0,children:"[Esc] Back"})})]})}import{useState as nf,useEffect as eD}from"react";import{Box as ce,Text as te,useInput as tD}from"ink";import{attempt as rD}from"@logosdx/utils";import{jsx as z,jsxs as J}from"react/jsx-runtime";var nD={"db/explore/tables/detail":"tables","db/explore/views/detail":"views","db/explore/procedures/detail":"procedures","db/explore/functions/detail":"functions","db/explore/types/detail":"types"};function of({columns:t}){return t.length===0?z(te,{dimColor:!0,children:"No columns"}):z(ce,{flexDirection:"column",children:t.map(e=>J(ce,{gap:2,children:[z(ce,{width:24,children:J(te,{color:e.isPrimaryKey?"yellow":void 0,children:[e.isPrimaryKey?"* ":" ",e.name]})}),z(ce,{width:20,children:z(te,{dimColor:!0,children:e.dataType})}),J(te,{dimColor:!0,children:[e.isNullable?"NULL":"NOT NULL",e.defaultValue?` DEFAULT ${e.defaultValue}`:""]})]},e.name))})}function Cb({parameters:t}){return t.length===0?z(te,{dimColor:!0,children:"No parameters"}):z(ce,{flexDirection:"column",children:t.map(e=>J(ce,{gap:2,children:[z(ce,{width:20,children:z(te,{children:e.name})}),z(ce,{width:16,children:z(te,{dimColor:!0,children:e.dataType})}),z(te,{dimColor:!0,children:e.mode})]},e.name))})}function oD({indexes:t}){return t.length===0?z(te,{dimColor:!0,children:"No indexes"}):z(ce,{flexDirection:"column",children:t.map(e=>J(ce,{gap:2,children:[z(ce,{width:30,children:J(te,{color:e.isPrimary?"yellow":void 0,children:[e.isPrimary?"* ":" ",e.name]})}),J(te,{dimColor:!0,children:["(",e.columns.join(", "),")",e.isUnique&&!e.isPrimary?" UNIQUE":""]})]},e.name))})}function iD({foreignKeys:t}){return t.length===0?z(te,{dimColor:!0,children:"No foreign keys"}):z(ce,{flexDirection:"column",children:t.map(e=>J(ce,{flexDirection:"column",children:[z(te,{children:e.name}),J(te,{dimColor:!0,children:[" ","(",e.columns.join(", "),") \u2192 ",e.referencedTable,"(",e.referencedColumns.join(", "),")"]})]},e.name))})}function sD({detail:t}){return J(ce,{flexDirection:"column",gap:1,children:[J(ce,{gap:2,children:[J(te,{bold:!0,children:[t.schema?`${t.schema}.`:"",t.name]}),t.rowCountEstimate!==void 0&&J(te,{dimColor:!0,children:["~",t.rowCountEstimate.toLocaleString()," rows"]})]}),J(ce,{flexDirection:"column",children:[J(te,{bold:!0,underline:!0,children:["Columns (",t.columns.length,")"]}),z(of,{columns:t.columns})]}),t.indexes.length>0&&J(ce,{flexDirection:"column",children:[J(te,{bold:!0,underline:!0,children:["Indexes (",t.indexes.length,")"]}),z(oD,{indexes:t.indexes})]}),t.foreignKeys.length>0&&J(ce,{flexDirection:"column",children:[J(te,{bold:!0,underline:!0,children:["Foreign Keys (",t.foreignKeys.length,")"]}),z(iD,{foreignKeys:t.foreignKeys})]})]})}function aD({detail:t}){return J(ce,{flexDirection:"column",gap:1,children:[J(ce,{gap:2,children:[J(te,{bold:!0,children:[t.schema?`${t.schema}.`:"",t.name]}),z(te,{dimColor:!0,children:t.isUpdatable?"UPDATABLE":"READ-ONLY"})]}),J(ce,{flexDirection:"column",children:[J(te,{bold:!0,underline:!0,children:["Columns (",t.columns.length,")"]}),z(of,{columns:t.columns})]}),t.definition&&J(ce,{flexDirection:"column",children:[z(te,{bold:!0,underline:!0,children:"Definition"}),J(te,{dimColor:!0,children:[t.definition.slice(0,500),t.definition.length>500?"...":""]})]})]})}function cD({detail:t}){return J(ce,{flexDirection:"column",gap:1,children:[J(te,{bold:!0,children:[t.schema?`${t.schema}.`:"",t.name]}),J(ce,{flexDirection:"column",children:[J(te,{bold:!0,underline:!0,children:["Parameters (",t.parameters.length,")"]}),z(Cb,{parameters:t.parameters})]}),t.definition&&J(ce,{flexDirection:"column",children:[z(te,{bold:!0,underline:!0,children:"Definition"}),J(te,{dimColor:!0,children:[t.definition.slice(0,500),t.definition.length>500?"...":""]})]})]})}function lD({detail:t}){return J(ce,{flexDirection:"column",gap:1,children:[J(ce,{gap:2,children:[J(te,{bold:!0,children:[t.schema?`${t.schema}.`:"",t.name]}),J(te,{dimColor:!0,children:["\u2192 ",t.returnType]})]}),J(ce,{flexDirection:"column",children:[J(te,{bold:!0,underline:!0,children:["Parameters (",t.parameters.length,")"]}),z(Cb,{parameters:t.parameters})]}),t.definition&&J(ce,{flexDirection:"column",children:[z(te,{bold:!0,underline:!0,children:"Definition"}),J(te,{dimColor:!0,children:[t.definition.slice(0,500),t.definition.length>500?"...":""]})]})]})}function uD({detail:t}){return J(ce,{flexDirection:"column",gap:1,children:[J(ce,{gap:2,children:[J(te,{bold:!0,children:[t.schema?`${t.schema}.`:"",t.name]}),z(te,{dimColor:!0,children:t.kind.toUpperCase()})]}),t.kind==="enum"&&t.values&&J(ce,{flexDirection:"column",children:[J(te,{bold:!0,underline:!0,children:["Values (",t.values.length,")"]}),z(ce,{flexDirection:"column",children:t.values.map((e,r)=>J(te,{children:[" ",e]},r))})]}),t.kind==="composite"&&t.attributes&&J(ce,{flexDirection:"column",children:[J(te,{bold:!0,underline:!0,children:["Attributes (",t.attributes.length,")"]}),z(of,{columns:t.attributes})]}),t.kind==="domain"&&t.baseType&&J(ce,{flexDirection:"column",children:[z(te,{bold:!0,underline:!0,children:"Base Type"}),J(te,{children:[" ",t.baseType]})]})]})}function ji({params:t}){let{back:e,route:r}=I(),{isFocused:n}=A("ExploreDetail"),{activeConfig:o,activeConfigName:i}=L(),[s,a]=nf(null),[c,l]=nf(!0),[m,d]=nf(null),u=nD[r],p=t.name,g=t.schema;eD(()=>{if(!o||!u||!p){l(!1);return}let w=!1;return(async()=>{l(!0),d(null);let[E,T]=await rD(async()=>{let R=await K(o.connection,i??"__explore__"),x=await cc(R.db,o.connection.dialect,u,p,g);return await R.destroy(),x});w||(T?d(T.message):E?a(E):d(`${p} not found`),l(!1))})(),()=>{w=!0}},[o,i,u,p,g]),tD((w,S)=>{n&&S.escape&&e()});let h=()=>{switch(u){case"tables":return"Table";case"views":return"View";case"procedures":return"Procedure";case"functions":return"Function";case"types":return"Type";default:return"Detail"}};if(!p)return J(ce,{flexDirection:"column",gap:1,children:[z(y,{title:"Error",borderColor:"red",paddingX:1,paddingY:1,children:z(te,{color:"red",children:"Missing object name"})}),z(ce,{flexWrap:"wrap",columnGap:2,children:z(te,{dimColor:!0,children:"[Esc] Back"})})]});if(!o)return J(ce,{flexDirection:"column",gap:1,children:[z(y,{title:h(),borderColor:"yellow",paddingX:1,paddingY:1,children:z(te,{color:"yellow",children:"No active configuration selected."})}),z(ce,{flexWrap:"wrap",columnGap:2,children:z(te,{dimColor:!0,children:"[Esc] Back"})})]});if(c)return z(ce,{flexDirection:"column",gap:1,children:z(y,{title:h(),paddingX:1,paddingY:1,children:z($,{label:`Loading ${p}...`})})});if(m||!s)return J(ce,{flexDirection:"column",gap:1,children:[z(y,{title:h(),borderColor:"red",paddingX:1,paddingY:1,children:J(ce,{flexDirection:"column",gap:1,children:[z(te,{color:"red",children:"Error"}),z(te,{dimColor:!0,children:m??"Object not found"})]})}),z(ce,{flexWrap:"wrap",columnGap:2,children:z(te,{dimColor:!0,children:"[Esc] Back"})})]});let f=()=>{switch(u){case"tables":return z(sD,{detail:s});case"views":return z(aD,{detail:s});case"procedures":return z(cD,{detail:s});case"functions":return z(lD,{detail:s});case"types":return z(uD,{detail:s});default:return z(te,{children:"Unknown category"})}};return J(ce,{flexDirection:"column",gap:1,children:[z(y,{title:h(),paddingX:1,paddingY:1,children:f()}),z(ce,{flexWrap:"wrap",columnGap:2,children:z(te,{dimColor:!0,children:"[Esc] Back"})})]})}import{useState as Hi,useEffect as sf,useCallback as af,useRef as cf,useMemo as mD}from"react";import{Box as ro,Text as vr,useInput as dD,useStdout as pD}from"ink";import{attempt as fD}from"@logosdx/utils";import{Fragment as wb,jsx as wt,jsxs as rn}from"react/jsx-runtime";function lf({params:t}){let{navigate:e,back:r}=I(),{isFocused:n}=A("SqlTerminal"),{activeConfig:o,activeConfigName:i,projectRoot:s,setHelpKeyEnabled:a}=L(),{showToast:c}=q(),{stdout:l}=pD(),m=mD(()=>{let V=(l.rows??24)-9,U=Math.floor(V*.75);return Math.max(5,Math.min(U,30))},[l.rows]),[d,u]=Hi(""),[p,g]=Hi(null),[h,f]=Hi(!1),[w,S]=Hi(!0),[E,T]=Hi(null),[R,x]=Hi("input"),[C,b]=Hi([]),[v,P]=Hi(-1),_=cf(null),O=cf(null),N=cf(null);sf(()=>{t.name&&u(t.name)},[t.name]),sf(()=>{let M=d.trim()!=="";return a(!M),()=>{a(!0)}},[d,a]),sf(()=>{if(!o||!i||!s){S(!1);return}let M=!1;return(async()=>{S(!0),T(null);let V=await de(o.connection);if(!V.ok){M||(T(V.error??"Connection failed"),S(!1));return}let[U,j]=await fD(()=>K(o.connection,i));if(j||!U){M||(T(j?.message??"Failed to connect"),S(!1));return}if(M){await U.destroy();return}O.current=U.db,N.current=U.destroy,_.current=new go(s,i);let Q=await _.current.load();M||(b(Q),S(!1))})(),()=>{M=!0,N.current&&(N.current(),O.current=null,N.current=null)}},[o,i,s]);let B=af(async M=>{if(!O.current||!_.current||!i)return;f(!0),g(null);let H=await Sd(O.current,M,i);await _.current.addEntry(M,H);let V=await _.current.load();b(V),P(-1),g(H),f(!1),H.success&&H.rowsAffected!==void 0?c({message:`${H.rowsAffected} row(s) affected`,variant:"success"}):H.success||c({message:H.errorMessage??"Query failed",variant:"error"}),H.success&&H.rows&&H.rows.length>0&&x("results")},[i,c]),D=af(M=>{if(C.length!==0)if(M==="up"){let H=v+1,V=C[H];H<C.length&&V&&(P(H),u(V.query))}else{let H=v-1,V=C[H];H>=0&&V?(P(H),u(V.query)):H===-1&&(P(-1),u(""))}},[C,v]),F=af(M=>{u(M),v>=0&&P(-1)},[v]);return dD((M,H)=>{if(!(!n||h)){if(H.tab&&!H.shift&&p?.rows&&p.rows.length>0){x(V=>V==="input"?"results":"input");return}if(M==="h"&&R==="input"&&d.trim()===""){e("db/sql/history");return}if(H.escape){R==="results"?x("input"):d.trim()!==""?(u(""),P(-1)):r();return}}}),!o||!i?rn(ro,{flexDirection:"column",gap:1,children:[wt(y,{title:"SQL Terminal",borderColor:"yellow",paddingX:1,paddingY:1,children:rn(ro,{flexDirection:"column",gap:1,children:[wt(vr,{color:"yellow",children:"No active configuration selected."}),wt(vr,{dimColor:!0,children:"Select a configuration first using the config screen."})]})}),wt(ro,{flexWrap:"wrap",columnGap:2,children:wt(vr,{dimColor:!0,children:"[Esc] Back"})})]}):w?wt(ro,{flexDirection:"column",gap:1,children:wt(y,{title:"SQL Terminal",paddingX:1,paddingY:1,children:wt($,{label:"Connecting to database..."})})}):E?rn(ro,{flexDirection:"column",gap:1,children:[wt(y,{title:"SQL Terminal",borderColor:"red",paddingX:1,paddingY:1,children:rn(ro,{flexDirection:"column",gap:1,children:[wt(vr,{color:"red",children:"Connection failed"}),wt(vr,{dimColor:!0,children:E})]})}),wt(ro,{flexWrap:"wrap",columnGap:2,children:wt(vr,{dimColor:!0,children:"[Esc] Back"})})]}):rn(ro,{flexDirection:"column",gap:1,children:[rn(ro,{gap:2,children:[wt(vr,{bold:!0,children:"SQL Terminal"}),wt(vr,{dimColor:!0,children:"-"}),wt(vr,{color:"cyan",children:i}),v>=0&&rn(wb,{children:[wt(vr,{dimColor:!0,children:"|"}),rn(vr,{dimColor:!0,children:["History [",v+1,"/",C.length,"]"]})]})]}),R==="results"&&p?.success&&p.columns&&p.rows&&p.rows.length>0&&wt(y,{title:"Results",borderColor:"cyan",paddingX:1,paddingY:1,children:wt(Ea,{columns:p.columns,rows:p.rows,maxVisibleRows:m,active:!0,onEscape:()=>x("input")})}),(R==="input"||!p?.rows||p.rows.length===0)&&rn(wb,{children:[p&&!h&&wt(ro,{children:p.success&&p.rowsAffected!==void 0?rn(vr,{color:"green",children:["\u2713 ",p.rowsAffected," row(s) affected (",p.durationMs.toFixed(0),"ms)"]}):p.success&&(!p.rows||p.rows.length===0)?rn(vr,{dimColor:!0,children:["\u2713 Query executed (",p.durationMs.toFixed(0),"ms)"]}):p.success?null:rn(vr,{color:"red",children:["\u2717 ",p.errorMessage]})}),h&&wt(ro,{children:wt($,{label:"Running query..."})}),wt(y,{title:"Query",borderColor:"cyan",paddingX:1,paddingY:1,children:wt(Du,{value:d,onChange:F,onSubmit:B,onHistoryNavigate:D,disabled:h,active:R==="input",historyBrowsing:v>=0})})]}),rn(ro,{flexWrap:"wrap",columnGap:2,children:[R==="input"&&wt(vr,{dimColor:!0,children:"[h] History"}),p?.rows&&p.rows.length>0&&rn(vr,{dimColor:!0,children:["[Tab] ",R==="input"?"View Results":"Edit Query"]}),rn(vr,{dimColor:!0,children:["[Esc] ",R==="results"?"Edit Query":d.trim()?"Clear":"Back"]})]})]})}import{useState as La,useEffect as gD,useMemo as yD}from"react";import{Box as nn,Text as at,useInput as hD}from"ink";import Tb from"dayjs";import xD from"dayjs/plugin/relativeTime.js";import{Fragment as CD,jsx as be,jsxs as on}from"react/jsx-runtime";Tb.extend(xD);function bD(t){return t<1e3?`${t.toFixed(0)}ms`:t<6e4?`${(t/1e3).toFixed(1)}s`:`${(t/6e4).toFixed(1)}m`}function SD(t,e){let r=t.replace(/\s+/g," ").trim();return r.length<=e?r:r.slice(0,e-3)+"..."}function uf({params:t}){let{navigate:e,back:r}=I(),{isFocused:n}=A("SqlHistory"),{activeConfigName:o,projectRoot:i}=L(),{showToast:s}=q(),[a,c]=La([]),[l,m]=La(!0),[d,u]=La(0),[p,g]=La(0),[h,f]=La(null),[w,S]=La(!1),E=10;gD(()=>{if(!o||!i){m(!1);return}(async()=>{m(!0);let b=await new go(i,o).load();c(b),m(!1)})()},[o,i]);let T=yD(()=>a.slice(p,p+E),[a,p]),R=async x=>{if(!x.resultsFile||!i||!o)return;S(!0);let b=await new go(i,o).loadResults(x.id);f(b),S(!1)};return hD((x,C)=>{if(n){if(h){C.escape&&f(null);return}if(C.upArrow){d>0&&(u(b=>b-1),d-1<p&&g(b=>Math.max(0,b-1)));return}if(C.downArrow){d<a.length-1&&(u(b=>b+1),d+1>=p+E&&g(b=>b+1));return}if(x==="r"){let b=a[d];b&&e("db/sql",{name:b.query});return}if(C.return){let b=a[d];b?.resultsFile?R(b):b&&!b.success?s({message:b.errorMessage??"Query failed",variant:"error"}):s({message:"No results stored for this query",variant:"info"});return}if(x==="c"){e("db/sql/clear");return}if(C.escape){r();return}}}),!o||!i?on(nn,{flexDirection:"column",gap:1,children:[be(y,{title:"SQL History",borderColor:"yellow",paddingX:1,paddingY:1,children:be(at,{color:"yellow",children:"No active configuration selected."})}),be(nn,{flexWrap:"wrap",columnGap:2,children:be(at,{dimColor:!0,children:"[Esc] Back"})})]}):l?be(nn,{flexDirection:"column",gap:1,children:be(y,{title:"SQL History",paddingX:1,paddingY:1,children:be($,{label:"Loading history..."})})}):h?on(nn,{flexDirection:"column",gap:1,children:[be(y,{title:"Query Result",paddingX:1,paddingY:1,children:h.columns&&h.rows?be(Ea,{columns:h.columns,rows:h.rows,active:!0}):be(at,{dimColor:!0,children:"No data"})}),be(nn,{flexWrap:"wrap",columnGap:2,children:be(at,{dimColor:!0,children:"[Esc] Close"})})]}):w?be(nn,{flexDirection:"column",gap:1,children:be(y,{title:"SQL History",paddingX:1,paddingY:1,children:be($,{label:"Loading result..."})})}):a.length===0?on(nn,{flexDirection:"column",gap:1,children:[be(y,{title:"SQL History",paddingX:1,paddingY:1,children:be(at,{dimColor:!0,children:"No query history yet."})}),be(nn,{flexWrap:"wrap",columnGap:2,children:be(at,{dimColor:!0,children:"[Esc] Back"})})]}):on(nn,{flexDirection:"column",gap:1,children:[on(nn,{gap:2,children:[be(at,{bold:!0,children:"SQL History"}),be(at,{dimColor:!0,children:"-"}),be(at,{color:"cyan",children:o}),be(at,{dimColor:!0,children:"|"}),on(at,{dimColor:!0,children:[a.length," queries"]})]}),be(y,{title:"Queries",paddingX:1,paddingY:1,children:on(nn,{flexDirection:"column",children:[p>0&&on(at,{dimColor:!0,children:["\u2191 ",p," more above"]}),T.map((x,C)=>{let v=p+C===d;return on(nn,{flexDirection:"column",paddingY:0,children:[on(nn,{children:[be(at,{inverse:v,children:v?"> ":" "}),be(at,{inverse:v,color:x.success?void 0:"red",children:SD(x.query,60)})]}),on(nn,{marginLeft:2,gap:1,children:[be(at,{dimColor:!0,children:Tb(x.executedAt).fromNow()}),be(at,{dimColor:!0,children:"|"}),be(at,{dimColor:!0,children:bD(x.durationMs)}),be(at,{dimColor:!0,children:"|"}),be(at,{color:x.success?"green":"red",children:x.success?"OK":"ERR"}),x.rowCount!==void 0&&on(CD,{children:[be(at,{dimColor:!0,children:"|"}),on(at,{dimColor:!0,children:[x.rowCount," rows"]})]})]})]},x.id)}),p+E<a.length&&on(at,{dimColor:!0,children:["\u2193 ",a.length-p-E," more below"]})]})}),a[d]&&be(y,{title:"Query",paddingX:1,paddingY:1,children:be(at,{wrap:"wrap",children:a[d].query})}),on(nn,{flexWrap:"wrap",columnGap:2,children:[be(at,{dimColor:!0,children:"[r] Re-run"}),be(at,{dimColor:!0,children:"[Enter] View result"}),be(at,{dimColor:!0,children:"[c] Clear"}),be(at,{dimColor:!0,children:"[\u2191/\u2193] Navigate"}),be(at,{dimColor:!0,children:"[Esc] Back"})]})]})}import{useState as Ia,useEffect as wD}from"react";import{Box as $r,Text as or,useInput as TD}from"ink";import{jsx as Ye,jsxs as In}from"react/jsx-runtime";function ED(t){return t<1024?`${t} B`:t<1024*1024?`${(t/1024).toFixed(1)} KB`:`${(t/(1024*1024)).toFixed(1)} MB`}function mf({params:t}){let{back:e}=I(),{isFocused:r}=A("SqlClear"),{activeConfigName:n,projectRoot:o}=L(),{showToast:i}=q(),[s,a]=Ia("select"),[c,l]=Ia("3months"),[m,d]=Ia(0),[u,p]=Ia(null),[g,h]=Ia(!0),[f,w]=Ia(null),S=[{key:"3months",label:"Clear last 3 months",description:"Remove queries older than 3 months"},{key:"all",label:"Clear all history",description:"Remove all queries and results"}];wD(()=>{if(!n||!o){h(!1);return}(async()=>{h(!0);let x=await new go(o,n).getStats();p(x),h(!1)})()},[n,o]);let E=async()=>{if(!n||!o)return;a("clearing");let T=new go(o,n),R;c==="3months"?R=await T.clearOlderThan(3):R=await T.clearAll(),w(R),a("done"),i({message:`Cleared ${R.entriesRemoved} entries, ${R.filesRemoved} files`,variant:"success"})};return TD((T,R)=>{if(r){if(s==="select"){if(R.upArrow){d(x=>x>0?x-1:S.length-1);return}if(R.downArrow){d(x=>x<S.length-1?x+1:0);return}if(R.return){let x=S[m];x&&(l(x.key),a("confirm"));return}if(R.escape){e();return}return}if(s==="done"){if(R.escape||R.return){e();return}return}}}),!n||!o?In($r,{flexDirection:"column",gap:1,children:[Ye(y,{title:"Clear History",borderColor:"yellow",paddingX:1,paddingY:1,children:Ye(or,{color:"yellow",children:"No active configuration selected."})}),Ye($r,{flexWrap:"wrap",columnGap:2,children:Ye(or,{dimColor:!0,children:"[Esc] Back"})})]}):s==="clearing"?Ye($r,{flexDirection:"column",gap:1,children:Ye(y,{title:"Clear History",paddingX:1,paddingY:1,children:Ye($,{label:"Clearing history..."})})}):s==="done"&&f?In($r,{flexDirection:"column",gap:1,children:[Ye(y,{title:"Clear History",borderColor:"green",paddingX:1,paddingY:1,children:In($r,{flexDirection:"column",gap:1,children:[Ye(or,{color:"green",children:"History cleared successfully!"}),In(or,{children:["Entries removed: ",f.entriesRemoved]}),In(or,{children:["Files removed: ",f.filesRemoved]})]})}),Ye($r,{flexWrap:"wrap",columnGap:2,children:Ye(or,{dimColor:!0,children:"[Enter/Esc] Back"})})]}):s==="confirm"?Ye(ee,{message:`Are you sure you want to ${c==="3months"?"clear queries older than 3 months":"clear ALL history"}?`,onConfirm:E,onCancel:()=>a("select")}):In($r,{flexDirection:"column",gap:1,children:[In($r,{gap:2,children:[Ye(or,{bold:!0,children:"Clear History"}),Ye(or,{dimColor:!0,children:"-"}),Ye(or,{color:"cyan",children:n})]}),Ye(y,{title:"Current History",paddingX:1,paddingY:1,children:g?Ye($,{label:"Loading stats..."}):u?In($r,{flexDirection:"column",children:[In($r,{gap:2,children:[Ye(or,{children:"Queries:"}),Ye(or,{bold:!0,children:u.entryCount})]}),In($r,{gap:2,children:[Ye(or,{children:"Results size:"}),Ye(or,{bold:!0,children:ED(u.resultsSize)})]})]}):Ye(or,{dimColor:!0,children:"No history"})}),Ye(y,{title:"Clear Options",paddingX:1,paddingY:1,children:Ye($r,{flexDirection:"column",children:S.map((T,R)=>{let x=R===m;return In($r,{flexDirection:"column",children:[Ye($r,{children:In(or,{inverse:x,color:T.key==="all"?"red":void 0,children:[x?"> ":" ",T.label]})}),Ye($r,{marginLeft:4,children:Ye(or,{dimColor:!0,children:T.description})})]},T.key)})})}),In($r,{flexWrap:"wrap",columnGap:2,children:[Ye(or,{dimColor:!0,children:"[Enter] Select"}),Ye(or,{dimColor:!0,children:"[\u2191/\u2193] Navigate"}),Ye(or,{dimColor:!0,children:"[Esc] Cancel"})]})]})}import{useState as RD,useCallback as Eb,useMemo as kD}from"react";import{Box as Rb,Text as df,useInput as _D}from"ink";import{jsx as Oc,jsxs as kb}from"react/jsx-runtime";function vD(t){if(!t)return"Not loaded";let e=t.build??{},r=e.include?.length??0,n=e.exclude?.length??0;return`include: ${r}, exclude: ${n}`}function DD(t){if(!t)return"Not loaded";let e=t.paths??{};return`schema: ${e.sql??"./sql"}, changes: ${e.changes??"./changes"}`}function PD(t){if(!t)return"Not loaded";let e=t.stages??{},r=Object.keys(e);return r.length===0?"none defined":r.length<=3?`${r.join(", ")} (${r.length})`:`${r.slice(0,3).join(", ")}... (${r.length})`}function ND(t){if(!t)return"Not loaded";let e=t.rules??[];return e.length===0?"none configured":`${e.length} configured`}function FD(t){if(!t)return"Not loaded";let e=t.strict??{};return e.enabled?`enabled (${e.stages?.length??0} required stages)`:"disabled"}function BD(t){if(!t)return"Not loaded";let e=t.logging??{};return e.enabled?`${e.level??"info"} \u2192 ${e.file??".noorm/noorm.log"}`:"disabled"}function LD(t){if(!t)return"Not loaded";let e=t.secrets??[];return e.length===0?"none defined":`${e.length} universal`}function pf({params:t}){let{navigate:e,back:r}=I(),{isFocused:n}=A("SettingsList"),{settings:o}=L(),[i,s]=RD("build"),a=kD(()=>[{key:"build",label:"Build",value:{key:"build",route:"settings/build"},description:vD(o)},{key:"paths",label:"Paths",value:{key:"paths",route:"settings/paths"},description:DD(o)},{key:"stages",label:"Stages",value:{key:"stages",route:"settings/stages"},description:PD(o)},{key:"rules",label:"Rules",value:{key:"rules",route:"settings/rules"},description:ND(o)},{key:"strict",label:"Strict",value:{key:"strict",route:"settings/strict"},description:FD(o)},{key:"logging",label:"Logging",value:{key:"logging",route:"settings/logging"},description:BD(o)},{key:"secrets",label:"Secrets",value:{key:"secrets",route:"settings/secrets"},description:LD(o)}],[o]),c=Eb(m=>{e(m.value.route)},[e]),l=Eb(m=>{s(m.value.key)},[]);return _D((m,d)=>{if(n){if(d.escape){r();return}if(m==="i"){e("settings/init");return}}}),kb(Rb,{flexDirection:"column",gap:1,children:[Oc(y,{title:"Settings",paddingX:1,paddingY:1,children:Oc(dt,{items:a,onSelect:c,onHighlight:l,isFocused:n,visibleCount:8,numberNav:!0})}),kb(Rb,{flexWrap:"wrap",columnGap:2,children:[Oc(df,{dimColor:!0,children:"[Enter] Edit"}),Oc(df,{dimColor:!0,children:"[i] Init"}),Oc(df,{dimColor:!0,children:"[Esc] Back"})]})]})}import{useState as _b,useCallback as Xu,useEffect as ID}from"react";import{Box as qi,Text as jr,useInput as OD}from"ink";import{attempt as AD}from"@logosdx/utils";import{jsx as ht,jsxs as Ki}from"react/jsx-runtime";function ff({params:t}){let{back:e}=I(),{isFocused:r}=A("SettingsInit"),{settingsManager:n,refresh:o}=L(),{showToast:i}=q(),s=t.force??!1,[a,c]=_b("checking"),[l,m]=_b(null);ID(()=>{if(!n){m("Settings manager not available"),c("error");return}(async()=>await n.exists()?s?(c("initializing"),await d(!0)):c("confirm-overwrite"):c("confirm-create"))()},[n,s]);let d=Xu(async h=>{if(!n){m("Settings manager not available"),c("error");return}c("initializing");let[f,w]=await AD(async()=>{await n.init(h),await o()});if(w){m(w instanceof Error?w.message:String(w)),c("error");return}i({message:h?"Settings file reset to defaults":"Settings file created",variant:"success"}),e()},[n,o,i,e]),u=Xu(()=>{d(!1)},[d]),p=Xu(()=>{d(!0)},[d]),g=Xu(()=>{e()},[e]);return OD((h,f)=>{r&&a==="error"&&(f.escape||f.return)&&e()}),a==="checking"?ht(y,{title:"Initialize Settings",paddingX:2,paddingY:1,children:ht($,{label:"Checking settings file..."})}):a==="initializing"?ht(y,{title:"Initialize Settings",paddingX:2,paddingY:1,children:ht($,{label:"Creating settings file..."})}):a==="error"?Ki(qi,{flexDirection:"column",gap:1,children:[ht(y,{title:"Initialize Settings",paddingX:2,paddingY:1,borderColor:"red",children:ht(jr,{color:"red",children:l??"An error occurred"})}),ht(qi,{flexWrap:"wrap",columnGap:2,children:ht(jr,{dimColor:!0,children:"[Enter/Esc] Back"})})]}):a==="confirm-create"?Ki(qi,{flexDirection:"column",gap:1,children:[ht(y,{title:"Initialize Settings",paddingX:2,paddingY:1,borderColor:"cyan",children:Ki(qi,{flexDirection:"column",gap:1,children:[Ki(jr,{children:["This will create ",ht(jr,{color:"cyan",children:".noorm/settings.yml"})," with default values:"]}),Ki(qi,{marginLeft:2,flexDirection:"column",children:[ht(jr,{dimColor:!0,children:"- build: include schema folder"}),ht(jr,{dimColor:!0,children:"- paths: ./sql, ./changes"}),ht(jr,{dimColor:!0,children:"- rules: none"}),ht(jr,{dimColor:!0,children:"- stages: none"}),ht(jr,{dimColor:!0,children:"- strict: disabled"}),ht(jr,{dimColor:!0,children:"- logging: info level"})]})]})}),ht(ee,{message:"Create settings file?",onConfirm:u,onCancel:g,isFocused:r})]}):a==="confirm-overwrite"?Ki(qi,{flexDirection:"column",gap:1,children:[ht(y,{title:"Initialize Settings",paddingX:2,paddingY:1,borderColor:"yellow",children:Ki(qi,{flexDirection:"column",gap:1,children:[ht(jr,{color:"yellow",children:"Settings file already exists."}),ht(jr,{children:"Overwriting will reset all settings to defaults:"}),Ki(qi,{marginLeft:2,flexDirection:"column",children:[ht(jr,{dimColor:!0,children:"- All stages will be removed"}),ht(jr,{dimColor:!0,children:"- All rules will be removed"}),ht(jr,{dimColor:!0,children:"- All custom paths will be reset"})]})]})}),ht(ee,{message:"Overwrite existing settings?",onConfirm:p,onCancel:g,variant:"warning",isFocused:r})]}):ht(y,{title:"Initialize Settings",paddingX:2,paddingY:1,children:ht(jr,{dimColor:!0,children:"Processing..."})})}import{useState as vb,useCallback as Db,useMemo as gf}from"react";import{Box as Pb,Text as Nb}from"ink";import{attempt as MD}from"@logosdx/utils";import{jsx as zu,jsxs as Lb}from"react/jsx-runtime";function Fb(t){return typeof t!="string"||!t.trim()?[]:t.split(",").map(e=>e.trim()).filter(Boolean)}function Bb(t){return!t||t.length===0?"":t.join(", ")}function yf({params:t}){let{back:e}=I(),{settingsManager:r,refresh:n}=L(),{showToast:o}=q(),[i,s]=vb(!1),[a,c]=vb(null),l=gf(()=>r?r.getBuild():{include:[],exclude:[]},[r]),m=gf(()=>r?r.getPaths().sql??Hs.sql??"./sql":Hs.sql??"./sql",[r]),d=gf(()=>[{key:"include",label:"Include Paths (comma-separated)",type:"text",defaultValue:Bb(l.include),placeholder:"tables, views, functions"},{key:"exclude",label:"Exclude Paths (comma-separated)",type:"text",defaultValue:Bb(l.exclude),placeholder:"archive, experiments"}],[l]),u=Db(async g=>{if(!r){c("Settings manager not available");return}s(!0),c(null);let h={include:Fb(g.include),exclude:Fb(g.exclude)},[f,w]=await MD(async()=>{await r.setBuild(h),await n()});if(w){c(w instanceof Error?w.message:String(w)),s(!1);return}o({message:"Build settings saved",variant:"success"}),e()},[r,n,o,e]),p=Db(()=>{e()},[e]);return zu(y,{title:"Build Settings",paddingX:2,paddingY:1,children:Lb(Pb,{flexDirection:"column",gap:1,children:[zu(Pb,{flexDirection:"column",children:Lb(Nb,{dimColor:!0,children:["Paths are relative to your SQL path: ",zu(Nb,{bold:!0,children:m})]})}),zu(Ke,{fields:d,onSubmit:u,onCancel:p,submitLabel:"Save",focusLabel:"SettingsBuildForm",busy:i,busyLabel:"Saving...",statusError:a??void 0})]})})}import{useState as Ib,useCallback as Ob,useMemo as Ab}from"react";import{attempt as $D}from"@logosdx/utils";import{jsx as Mb}from"react/jsx-runtime";function hf({params:t}){let{back:e}=I(),{settingsManager:r,refresh:n}=L(),{showToast:o}=q(),[i,s]=Ib(!1),[a,c]=Ib(null),l=Ab(()=>r?r.getPaths():{sql:"./sql",changes:"./changes"},[r]),m=Ab(()=>[{key:"sql",label:"SQL Path",type:"text",defaultValue:l.sql??"./sql",placeholder:"./sql"},{key:"changes",label:"Changes Path",type:"text",defaultValue:l.changes??"./changes",placeholder:"./changes"}],[l]),d=Ob(async p=>{if(!r){c("Settings manager not available");return}s(!0),c(null);let g={sql:String(p.sql||"./sql"),changes:String(p.changes||"./changes")},[h,f]=await $D(async()=>{await r.setPaths(g),await n()});if(f){c(f instanceof Error?f.message:String(f)),s(!1);return}o({message:"Path settings saved",variant:"success"}),e()},[r,n,o,e]),u=Ob(()=>{e()},[e]);return Mb(y,{title:"Path Settings",paddingX:2,paddingY:1,children:Mb(Ke,{fields:m,onSubmit:d,onCancel:u,submitLabel:"Save",focusLabel:"SettingsPathsForm",busy:i,busyLabel:"Saving...",statusError:a??void 0})})}import{useState as $b,useCallback as jb,useMemo as Hb}from"react";import{attempt as jD}from"@logosdx/utils";import{jsx as qb}from"react/jsx-runtime";function HD(t){return typeof t!="string"||!t.trim()?[]:t.split(",").map(e=>e.trim()).filter(Boolean)}function qD(t){return!t||t.length===0?"":t.join(", ")}function xf({params:t}){let{back:e}=I(),{settingsManager:r,refresh:n}=L(),{showToast:o}=q(),[i,s]=$b(!1),[a,c]=$b(null),l=Hb(()=>r?r.getStrict():{enabled:!1,stages:[]},[r]),m=Hb(()=>[{key:"enabled",label:"Enable Strict Mode",type:"checkbox",defaultValue:l.enabled??!1},{key:"stages",label:"Required Stages (comma-separated)",type:"text",defaultValue:qD(l.stages),placeholder:"dev, staging, prod"}],[l]),d=jb(async p=>{if(!r){c("Settings manager not available");return}s(!0),c(null);let g={enabled:!!p.enabled,stages:HD(p.stages)},[h,f]=await jD(async()=>{await r.setStrict(g),await n()});if(f){c(f instanceof Error?f.message:String(f)),s(!1);return}o({message:"Strict mode settings saved",variant:"success"}),e()},[r,n,o,e]),u=jb(()=>{e()},[e]);return qb(y,{title:"Strict Mode Settings",paddingX:2,paddingY:1,children:qb(Ke,{fields:m,onSubmit:d,onCancel:u,submitLabel:"Save",focusLabel:"SettingsStrictForm",busy:i,busyLabel:"Saving...",statusError:a??void 0})})}import{useState as Kb,useCallback as Vb,useMemo as Ub}from"react";import{attempt as KD}from"@logosdx/utils";import{jsx as Yb}from"react/jsx-runtime";function bf({params:t}){let{back:e}=I(),{settingsManager:r,refresh:n}=L(),{showToast:o}=q(),[i,s]=Kb(!1),[a,c]=Kb(null),l=Ub(()=>r?r.getLogging():{enabled:!0,level:"info",file:".noorm/noorm.log",maxSize:"10mb",maxFiles:5},[r]),m=Ub(()=>[{key:"enabled",label:"Enable File Logging",type:"checkbox",defaultValue:l.enabled??!0},{key:"level",label:"Log Level",type:"select",options:[{label:"Silent",value:"silent"},{label:"Error",value:"error"},{label:"Warn",value:"warn"},{label:"Info",value:"info"},{label:"Verbose",value:"verbose"}],defaultValue:l.level??"info"},{key:"file",label:"Log File Path",type:"text",defaultValue:l.file??".noorm/noorm.log",placeholder:".noorm/noorm.log"},{key:"maxSize",label:"Max File Size",type:"text",defaultValue:l.maxSize??"10mb",placeholder:"10mb"},{key:"maxFiles",label:"Max Rotated Files",type:"text",defaultValue:String(l.maxFiles??5),placeholder:"5",validate:p=>{if(typeof p!="string"||!p)return;let g=parseInt(p,10);if(isNaN(g)||g<1)return"Must be a positive number"}}],[l]),d=Vb(async p=>{if(!r){c("Settings manager not available");return}s(!0),c(null);let g={enabled:!!p.enabled,level:String(p.level||"info"),file:String(p.file||".noorm/noorm.log"),maxSize:String(p.maxSize||"10mb"),maxFiles:parseInt(String(p.maxFiles||"5"),10)},[h,f]=await KD(async()=>{await r.setLogging(g),await n()});if(f){c(f instanceof Error?f.message:String(f)),s(!1);return}o({message:"Logging settings saved",variant:"success"}),e()},[r,n,o,e]),u=Vb(()=>{e()},[e]);return Yb(y,{title:"Logging Settings",paddingX:2,paddingY:1,children:Yb(Ke,{fields:m,onSubmit:d,onCancel:u,submitLabel:"Save",focusLabel:"SettingsLoggingForm",busy:i,busyLabel:"Saving...",statusError:a??void 0})})}import{useState as Sf,useCallback as Ju,useMemo as Cf}from"react";import{Box as Ac,Text as Ro,useInput as VD}from"ink";import{attempt as UD}from"@logosdx/utils";import{jsx as bn,jsxs as Oa}from"react/jsx-runtime";function wf({params:t}){let{navigate:e,back:r}=I(),{isFocused:n}=A("SettingsStagesList"),{settingsManager:o,settings:i,refresh:s}=L(),{showToast:a}=q(),[c,l]=Sf(null),[m,d]=Sf(null),[u,p]=Sf(!1),g=Cf(()=>i?i.stages??{}:{},[i]),h=Cf(()=>{let T=Object.keys(g);return T.length===0?[]:T.map(R=>{let x=g[R];return{key:R,label:R,value:{name:R,description:x.description,locked:x.locked??!1},description:x.description??(x.locked?"[locked]":""),icon:x.locked?"\u{1F512}":"\u25CB"}})},[g]);Cf(()=>{h.length>0&&!c&&l(h[0].value.name)},[h,c]);let f=Ju(T=>{e("settings/stages/edit",{name:T.value.name})},[e]),w=Ju(T=>{l(T.value.name)},[]),S=Ju(async()=>{if(!o||!m)return;p(!0);let[T,R]=await UD(async()=>{await o.removeStage(m),await s()});if(p(!1),d(null),R){a({message:R instanceof Error?R.message:String(R),variant:"error"});return}a({message:`Stage "${m}" deleted`,variant:"success"})},[o,m,s,a]),E=Ju(()=>{d(null)},[]);return VD((T,R)=>{if(!(!n||m)){if(R.escape){r();return}if(T==="a"){e("settings/stages/add");return}if(c){if(T==="e"){e("settings/stages/edit",{name:c});return}if(T==="d"){if(g[c]?.locked){a({message:`Cannot delete locked stage "${c}"`,variant:"error"});return}d(c);return}if(T==="k"){e("settings/stages/secrets",{name:c});return}}}}),m?bn(Ac,{flexDirection:"column",gap:1,children:bn(y,{title:"Delete Stage",paddingX:2,paddingY:1,borderColor:"yellow",children:bn(ee,{message:`Are you sure you want to delete stage "${m}"?`,onConfirm:S,onCancel:E,variant:"warning",isFocused:n})})}):Oa(Ac,{flexDirection:"column",gap:1,children:[Oa(y,{title:"Stages",paddingX:1,paddingY:1,children:[Oa(Ac,{flexDirection:"column",marginBottom:1,children:[bn(Ro,{dimColor:!0,children:"Define required stages for your project. Stages with a dialect in their defaults"}),bn(Ro,{dimColor:!0,children:"are automatically created as configs in each user's local state on startup."})]}),h.length===0?Oa(Ac,{flexDirection:"column",gap:1,children:[bn(Ro,{dimColor:!0,children:"No stages defined."}),Oa(Ro,{children:["Press ",bn(Ro,{color:"cyan",children:"a"})," to add your first stage."]})]}):bn(dt,{items:h,onSelect:f,onHighlight:w,isFocused:n,visibleCount:8})]}),Oa(Ac,{flexWrap:"wrap",columnGap:2,children:[bn(Ro,{dimColor:!0,children:"[a] Add"}),bn(Ro,{dimColor:!0,children:"[e] Edit"}),bn(Ro,{dimColor:!0,children:"[k] Secrets"}),bn(Ro,{dimColor:!0,children:"[d] Delete"}),bn(Ro,{dimColor:!0,children:"[Enter] Edit"}),bn(Ro,{dimColor:!0,children:"[Esc] Back"})]})]})}import{useState as Wb,useCallback as Gb,useMemo as Tf}from"react";import{Text as YD}from"ink";import{attempt as WD}from"@logosdx/utils";import{jsx as Ef,jsxs as GD}from"react/jsx-runtime";function Qu({params:t}){let{back:e}=I(),{settingsManager:r,refresh:n}=L(),{showToast:o}=q(),i=t.name,s=!i,[a,c]=Wb(!1),[l,m]=Wb(null),d=Tf(()=>!r||!i?null:r.getStage(i),[r,i]),u=Tf(()=>r?Object.keys(r.getStages()):[],[r]),p=Tf(()=>{let f=d?.defaults??{};return[{key:"name",label:"Stage Name",type:"text",required:!0,defaultValue:i??"",placeholder:"e.g., dev, staging, prod",validate:w=>{if(typeof w!="string")return"Name is required";if(!/^[a-z0-9_-]+$/i.test(w))return"Only letters, numbers, hyphens, underscores";if(s&&u.includes(w))return"Stage already exists"}},{key:"description",label:"Description",type:"text",defaultValue:d?.description??"",placeholder:"e.g., Production database"},{key:"locked",label:"Locked (prevent config deletion)",type:"checkbox",defaultValue:d?.locked??!1},{key:"dialect",label:"Default Dialect",type:"select",options:[{label:"(none)",value:""},{label:"PostgreSQL",value:"postgres"},{label:"MySQL",value:"mysql"},{label:"SQLite",value:"sqlite"},{label:"MSSQL",value:"mssql"}],defaultValue:f.dialect??""},{key:"host",label:"Default Host",type:"text",defaultValue:f.host??"",placeholder:"localhost"},{key:"port",label:"Default Port",type:"text",defaultValue:f.port?String(f.port):"",placeholder:"5432",validate:w=>{if(typeof w!="string"||!w)return;let S=parseInt(w,10);if(isNaN(S)||S<1||S>65535)return"Port must be 1-65535"}},{key:"database",label:"Default Database",type:"text",defaultValue:f.database??"",placeholder:"myapp_dev"},{key:"user",label:"Default User",type:"text",defaultValue:f.user??"",placeholder:"postgres"},{key:"isTest",label:"Default: Test Database",type:"checkbox",defaultValue:f.isTest??!1},{key:"protected",label:"Default: Protected (enforce)",type:"checkbox",defaultValue:f.protected??!1}]},[d,i,s,u]),g=Gb(async f=>{if(!r){m("Settings manager not available");return}let w=String(f.name);if(!w){m("Stage name is required");return}c(!0),m(null);let S={};f.dialect&&(S.dialect=String(f.dialect)),f.host&&(S.host=String(f.host)),f.port&&(S.port=parseInt(String(f.port),10)),f.database&&(S.database=String(f.database)),f.user&&(S.user=String(f.user)),f.isTest&&(S.isTest=!0),f.protected&&(S.protected=!0);let E={description:f.description?String(f.description):void 0,locked:!!f.locked,defaults:Object.keys(S).length>0?S:void 0,secrets:d?.secrets},[T,R]=await WD(async()=>{i&&i!==w&&await r.removeStage(i),await r.setStage(w,E),await n()});if(R){m(R instanceof Error?R.message:String(R)),c(!1);return}o({message:s?`Stage "${w}" created`:`Stage "${w}" updated`,variant:"success"}),e()},[r,i,d,s,n,o,e]),h=Gb(()=>{e()},[e]);return!s&&!d?Ef(y,{title:"Edit Stage",paddingX:2,paddingY:1,borderColor:"red",children:GD(YD,{color:"red",children:['Stage "',i,'" not found.']})}):Ef(y,{title:s?"Add Stage":`Edit Stage: ${i}`,paddingX:2,paddingY:1,children:Ef(Ke,{fields:p,onSubmit:g,onCancel:h,submitLabel:s?"Create Stage":"Save Changes",focusLabel:"SettingsStageEditForm",busy:a,busyLabel:"Saving...",statusError:l??void 0})})}import{useState as Rf,useCallback as Zu,useMemo as kf}from"react";import{Box as em,Text as Vi,useInput as XD}from"ink";import{attempt as zD}from"@logosdx/utils";import JD from"voca";import{jsx as no,jsxs as tm}from"react/jsx-runtime";function QD(t){let e=[];return t.name!==void 0&&e.push(`name=${t.name}`),t.type!==void 0&&e.push(`type=${t.type}`),t.isTest!==void 0&&e.push(`isTest=${t.isTest}`),t.protected!==void 0&&e.push(`protected=${t.protected}`),e.length>0?e.join(", "):"(no conditions)"}function ZD(t){let e=[];return t.include&&t.include.length>0&&e.push(`+${t.include.length} include`),t.exclude&&t.exclude.length>0&&e.push(`-${t.exclude.length} exclude`),e.length>0?e.join(", "):"(no effect)"}function _f({params:t}){let{navigate:e,back:r}=I(),{isFocused:n}=A("SettingsRulesList"),{settingsManager:o,settings:i,refresh:s}=L(),{showToast:a}=q(),[c,l]=Rf(null),[m,d]=Rf(null),[u,p]=Rf(!1),g=kf(()=>i?i.rules??[]:[],[i]),h=kf(()=>g.map((T,R)=>({key:T.description?JD.kebabCase(T.description):String(R),label:T.description||`Rule ${R+1}`,value:{index:R,rule:T},description:`${QD(T.match)} \u2192 ${ZD(T)}`})),[g]);kf(()=>{h.length>0&&c===null&&l(0)},[h,c]);let f=Zu(T=>{e("settings/rules/edit",{name:String(T.value.index)})},[e]),w=Zu(T=>{l(T.value.index)},[]),S=Zu(async()=>{if(!o||m===null)return;p(!0);let[T,R]=await zD(async()=>{await o.removeRule(m),await s()});if(p(!1),d(null),R){a({message:R instanceof Error?R.message:String(R),variant:"error"});return}a({message:`Rule ${m+1} deleted`,variant:"success"}),c!==null&&c>=g.length-1&&l(Math.max(0,g.length-2))},[o,m,g.length,c,s,a]),E=Zu(()=>{d(null)},[]);return XD((T,R)=>{if(!(!n||m!==null)){if(R.escape){r();return}if(T==="a"){e("settings/rules/add");return}if(c!==null){if(T==="e"){e("settings/rules/edit",{name:String(c)});return}if(T==="d"){d(c);return}}}}),m!==null?no(em,{flexDirection:"column",gap:1,children:no(y,{title:"Delete Rule",paddingX:2,paddingY:1,borderColor:"yellow",children:no(ee,{message:`Are you sure you want to delete Rule ${m+1}?`,onConfirm:S,onCancel:E,variant:"warning",isFocused:n})})}):tm(em,{flexDirection:"column",gap:1,children:[no(y,{title:"Rules",paddingX:1,paddingY:1,children:h.length===0?tm(em,{flexDirection:"column",gap:1,children:[no(Vi,{dimColor:!0,children:"No rules defined."}),tm(Vi,{children:["Press ",no(Vi,{color:"cyan",children:"a"})," to add your first rule."]})]}):no(dt,{items:h,onSelect:f,onHighlight:w,isFocused:n,visibleCount:8})}),tm(em,{flexWrap:"wrap",columnGap:2,children:[no(Vi,{dimColor:!0,children:"[a] Add"}),no(Vi,{dimColor:!0,children:"[e] Edit"}),no(Vi,{dimColor:!0,children:"[d] Delete"}),no(Vi,{dimColor:!0,children:"[Enter] Edit"}),no(Vi,{dimColor:!0,children:"[Esc] Back"})]})]})}import{useState as Xb,useCallback as zb,useMemo as vf}from"react";import{Text as eP}from"ink";import{attempt as tP}from"@logosdx/utils";import{jsx as Df,jsxs as rP}from"react/jsx-runtime";function Jb(t){return typeof t!="string"||!t.trim()?[]:t.split(",").map(e=>e.trim()).filter(Boolean)}function Qb(t){return!t||t.length===0?"":t.join(", ")}function rm({params:t}){let{back:e}=I(),{settingsManager:r,refresh:n}=L(),{showToast:o}=q(),i=t.name,s=i!==void 0?parseInt(i,10):NaN,a=isNaN(s),[c,l]=Xb(!1),[m,d]=Xb(null),u=vf(()=>r?r.getRules():[],[r]),p=vf(()=>a||s<0||s>=u.length?null:u[s],[u,s,a]),g=vf(()=>{let S=p?.match??{};return[{key:"description",label:"Description",type:"text",defaultValue:p?.description??"",placeholder:"e.g., test seeds, prod config"},{key:"matchName",label:"Match: Config Name",type:"text",defaultValue:S.name??"",placeholder:"e.g., dev, prod (leave empty to match any)"},{key:"matchType",label:"Match: Connection Type",type:"select",options:[{label:"(any)",value:""},{label:"Local",value:"local"},{label:"Remote",value:"remote"}],defaultValue:S.type??""},{key:"matchIsTest",label:"Match: Is Test Database",type:"select",options:[{label:"(any)",value:""},{label:"Yes",value:"true"},{label:"No",value:"false"}],defaultValue:S.isTest!==void 0?String(S.isTest):""},{key:"matchProtected",label:"Match: Is Protected",type:"select",options:[{label:"(any)",value:""},{label:"Yes",value:"true"},{label:"No",value:"false"}],defaultValue:S.protected!==void 0?String(S.protected):""},{key:"include",label:"Include Paths (comma-separated)",type:"text",defaultValue:Qb(p?.include),placeholder:"sql/seeds, sql/fixtures"},{key:"exclude",label:"Exclude Paths (comma-separated)",type:"text",defaultValue:Qb(p?.exclude),placeholder:"sql/dangerous, sql/archive"}]},[p]),h=zb(async S=>{if(!r){d("Settings manager not available");return}l(!0),d(null);let E={};S.matchName&&(E.name=String(S.matchName)),S.matchType&&(E.type=String(S.matchType)),S.matchIsTest==="true"&&(E.isTest=!0),S.matchIsTest==="false"&&(E.isTest=!1),S.matchProtected==="true"&&(E.protected=!0),S.matchProtected==="false"&&(E.protected=!1);let T=Jb(S.include),R=Jb(S.exclude);if(T.length===0&&R.length===0){d("Rule must have at least one include or exclude path"),l(!1);return}let C={description:S.description?String(S.description):void 0,match:E,include:T.length>0?T:void 0,exclude:R.length>0?R:void 0},[b,v]=await tP(async()=>{a?await r.addRule(C):(await r.removeRule(s),await r.addRule(C)),await n()});if(v){d(v instanceof Error?v.message:String(v)),l(!1);return}o({message:a?"Rule created":"Rule updated",variant:"success"}),e()},[r,a,s,n,o,e]),f=zb(()=>{e()},[e]);if(!a&&!p)return Df(y,{title:"Edit Rule",paddingX:2,paddingY:1,borderColor:"red",children:rP(eP,{color:"red",children:["Rule ",s+1," not found."]})});let w=p?.description||`Rule ${s+1}`;return Df(y,{title:a?"Add Rule":`Edit: ${w}`,paddingX:2,paddingY:1,children:Df(Ke,{fields:g,onSubmit:h,onCancel:f,submitLabel:a?"Create Rule":"Save Changes",focusLabel:"SettingsRuleEditForm",busy:c,busyLabel:"Saving...",statusError:m??void 0})})}import{useCallback as Pf}from"react";import{Box as Nf,Text as nm}from"ink";import{attempt as nP,wait as oP}from"@logosdx/utils";import{jsx as Mc,jsxs as $c}from"react/jsx-runtime";function Ff({params:t}){let{navigate:e,back:r}=I(),{isFocused:n}=A("SettingsSecretsList"),{settingsManager:o,settings:i,refresh:s}=L(),{showToast:a}=q(),c=i?.secrets??[],l=Pf(()=>{e("settings/secrets/add")},[e]),m=Pf(u=>{e("settings/secrets/edit",{name:u})},[e]),d=Pf(async u=>{if(!o)return;let[p,g]=await nP(async()=>{await o.removeUniversalSecret(u)});if(g){a({message:g instanceof Error?g.message:String(g),variant:"error"});return}a({message:`Secret definition "${u}" deleted`,variant:"success"}),await oP(50),await s()},[o,s,a]);return $c(Nf,{flexDirection:"column",gap:1,children:[Mc(y,{title:"Universal Secrets",paddingX:1,paddingY:1,children:$c(Nf,{flexDirection:"column",gap:1,children:[$c(Nf,{flexDirection:"column",children:[$c(nm,{dimColor:!0,children:["Define which secrets are ",Mc(nm,{bold:!0,children:"required"})," for all configs, regardless of stage."]}),$c(nm,{dimColor:!0,children:["Actual values are set per-config via ",Mc(nm,{bold:!0,children:"Home \u203A Secrets"}),"."]})]}),Mc(xa,{secrets:c,scopeLabel:"universal",onAdd:l,onEdit:m,onDelete:d,deleteWarning:"This will remove the secret requirement from all stages.",isFocused:n,onBack:r})]})}),Mc(ba,{})]})}import{useState as Zb,useCallback as eS,useMemo as tS}from"react";import{Text as iP}from"ink";import{attempt as sP}from"@logosdx/utils";import{jsx as Bf,jsxs as aP}from"react/jsx-runtime";function om({params:t}){let{back:e}=I(),{settingsManager:r,settings:n,refresh:o}=L(),{showToast:i}=q(),s=t.name,a=!s,[c,l]=Zb(!1),[m,d]=Zb(null),u=tS(()=>!n?.secrets||!s?null:n.secrets.find(f=>f.key===s),[n,s]),p=tS(()=>n?.secrets?n.secrets.map(f=>f.key):[],[n]),g=eS(async f=>{if(!r){d("Settings manager not available");return}l(!0),d(null);let[w,S]=await sP(async()=>{a?await r.addUniversalSecret(f):s!==f.key?(await r.removeUniversalSecret(s),await r.addUniversalSecret(f)):await r.updateUniversalSecret(s,f)});if(S){d(S instanceof Error?S.message:String(S)),l(!1);return}i({message:a?`Secret definition "${f.key}" created`:`Secret definition "${f.key}" updated`,variant:"success"}),e()},[r,s,a,o,i,e]),h=eS(()=>e(),[e]);return!a&&!u?Bf(y,{title:"Edit Secret Definition",paddingX:2,paddingY:1,borderColor:"red",children:aP(iP,{color:"red",children:['Secret "',s,'" not found.']})}):Bf(y,{title:a?"Add Secret Definition":`Edit: ${s}`,paddingX:2,paddingY:1,children:Bf(ya,{existingSecret:u,existingKeys:p,isAddMode:a,onSubmit:g,onCancel:h,busy:c,error:m,focusLabel:"SettingsSecretEditForm"})})}import{useState as cP,useCallback as rS,useMemo as lP}from"react";import{Box as jc,Text as Fs,useInput as uP}from"ink";import{attempt as mP}from"@logosdx/utils";import{jsx as On,jsxs as Hc}from"react/jsx-runtime";function Lf({params:t}){let{back:e}=I(),{isFocused:r}=A("SettingsSecretRemove"),{settingsManager:n,settings:o,refresh:i}=L(),{showToast:s}=q(),a=t.name,[c,l]=cP(!1),m=lP(()=>!o?.secrets||!a?null:o.secrets.find(p=>p.key===a),[o,a]),d=rS(async()=>{if(!n||!a)return;l(!0);let[p,g]=await mP(async()=>{await n.removeUniversalSecret(a),await i()});if(g){s({message:g instanceof Error?g.message:String(g),variant:"error"}),l(!1);return}s({message:`Secret definition "${a}" removed`,variant:"success"}),e()},[n,a,i,s,e]),u=rS(()=>e(),[e]);return uP((p,g)=>{r&&(!a||!m)&&(g.escape||g.return)&&e()}),c?On(y,{title:`Delete: ${a}`,paddingX:2,paddingY:1,children:On($,{label:"Deleting secret definition..."})}):a?m?On(y,{title:`Remove: ${a}`,paddingX:2,paddingY:1,borderColor:"yellow",children:Hc(jc,{flexDirection:"column",gap:1,children:[m.description&&On(Fs,{dimColor:!0,children:m.description}),Hc(Fs,{dimColor:!0,children:["Type: ",m.type]}),On(Fs,{color:"yellow",children:"Warning: This will remove the secret requirement from all stages."}),On(ee,{message:`Delete secret definition "${a}"?`,onConfirm:d,onCancel:u,variant:"warning",isFocused:r})]})}):Hc(jc,{flexDirection:"column",gap:1,children:[On(y,{title:"Remove Secret Definition",paddingX:2,paddingY:1,borderColor:"red",children:Hc(Fs,{color:"red",children:['Secret "',a,'" not found.']})}),On(jc,{flexWrap:"wrap",columnGap:2,children:On(Fs,{dimColor:!0,children:"[Enter/Esc] Back"})})]}):Hc(jc,{flexDirection:"column",gap:1,children:[On(y,{title:"Remove Secret Definition",paddingX:2,paddingY:1,borderColor:"yellow",children:On(Fs,{color:"yellow",children:"No secret key provided."})}),On(jc,{flexWrap:"wrap",columnGap:2,children:On(Fs,{dimColor:!0,children:"[Enter/Esc] Back"})})]})}import{useCallback as If,useMemo as nS}from"react";import{Box as Bs,Text as Ui,useInput as dP}from"ink";import{attempt as pP}from"@logosdx/utils";import{jsx as oo,jsxs as Yi}from"react/jsx-runtime";function Of({params:t}){let{navigate:e,back:r}=I(),{isFocused:n}=A("SettingsStageSecretsList"),{settingsManager:o,settings:i,refresh:s}=L(),{showToast:a}=q(),c=t.name,l=nS(()=>!i?.stages||!c?null:i.stages[c],[i,c]),m=nS(()=>l?.secrets??[],[l]),d=If(()=>{e("settings/stages/secrets/add",{stage:c})},[e,c]),u=If(g=>{e("settings/stages/secrets/edit",{stage:c,name:g})},[e,c]),p=If(async g=>{if(!o||!c)return;let[h,f]=await pP(async()=>{await o.removeStageSecret(c,g),await s()});if(f){a({message:f instanceof Error?f.message:String(f),variant:"error"});return}a({message:`Secret definition "${g}" deleted from stage`,variant:"success"})},[o,c,s,a]);return dP((g,h)=>{n&&h.escape&&r()}),c?l?Yi(Bs,{flexDirection:"column",gap:1,children:[oo(y,{title:`Secrets for Stage: ${c}`,paddingX:1,paddingY:1,children:Yi(Bs,{flexDirection:"column",gap:1,children:[Yi(Bs,{flexDirection:"column",children:[Yi(Ui,{dimColor:!0,children:["Define which secrets are ",oo(Ui,{bold:!0,children:"required"})," for configs in this stage."]}),Yi(Ui,{dimColor:!0,children:["Actual values are set per-config via ",oo(Ui,{bold:!0,children:"Home \u203A Secrets"}),"."]})]}),oo(xa,{secrets:m,scopeLabel:`stage: ${c}`,onAdd:d,onEdit:u,onDelete:p,isFocused:n,onBack:r})]})}),oo(ba,{})]}):Yi(Bs,{flexDirection:"column",gap:1,children:[oo(y,{title:"Stage Secrets",paddingX:2,paddingY:1,borderColor:"red",children:Yi(Ui,{color:"red",children:['Stage "',c,'" not found.']})}),oo(Bs,{flexWrap:"wrap",columnGap:2,children:oo(Ui,{dimColor:!0,children:"[Esc] Back"})})]}):Yi(Bs,{flexDirection:"column",gap:1,children:[oo(y,{title:"Stage Secrets",paddingX:2,paddingY:1,borderColor:"yellow",children:oo(Ui,{color:"yellow",children:"No stage name provided."})}),oo(Bs,{flexWrap:"wrap",columnGap:2,children:oo(Ui,{dimColor:!0,children:"[Esc] Back"})})]})}import{useState as oS,useCallback as iS,useMemo as Af}from"react";import{Box as fP,Text as im}from"ink";import{attempt as gP}from"@logosdx/utils";import{jsx as Aa,jsxs as sm}from"react/jsx-runtime";function am({params:t}){let{back:e}=I(),{settingsManager:r,settings:n,refresh:o}=L(),{showToast:i}=q(),s=t.stage,a=t.name,c=!a,[l,m]=oS(!1),[d,u]=oS(null),p=Af(()=>!n?.stages||!s?null:n.stages[s],[n,s]),g=Af(()=>!p?.secrets||!a?null:p.secrets.find(S=>S.key===a),[p,a]),h=Af(()=>p?.secrets?p.secrets.map(S=>S.key):[],[p]),f=iS(async S=>{if(!r||!s){u("Settings manager not available");return}m(!0),u(null);let[E,T]=await gP(async()=>{c?await r.addStageSecret(s,S):a!==S.key?(await r.removeStageSecret(s,a),await r.addStageSecret(s,S)):await r.updateStageSecret(s,a,S),await o()});if(T){u(T instanceof Error?T.message:String(T)),m(!1);return}i({message:c?`Secret "${S.key}" added to stage "${s}"`:`Secret "${S.key}" updated in stage "${s}"`,variant:"success"}),e()},[r,s,a,c,o,i,e]),w=iS(()=>e(),[e]);return s?p?!c&&!g?Aa(y,{title:"Edit Stage Secret",paddingX:2,paddingY:1,borderColor:"red",children:sm(im,{color:"red",children:['Secret "',a,'" not found in stage "',s,'".']})}):Aa(y,{title:c?`Add Secret to ${s}`:`Edit: ${a} (${s})`,paddingX:2,paddingY:1,children:sm(fP,{flexDirection:"column",gap:1,children:[sm(im,{dimColor:!0,children:["Stage: ",s]}),Aa(ya,{existingSecret:g,existingKeys:h,isAddMode:c,onSubmit:f,onCancel:w,busy:l,error:d,focusLabel:"SettingsStageSecretEditForm"})]})}):Aa(y,{title:"Edit Stage Secret",paddingX:2,paddingY:1,borderColor:"red",children:sm(im,{color:"red",children:['Stage "',s,'" not found.']})}):Aa(y,{title:"Edit Stage Secret",paddingX:2,paddingY:1,borderColor:"yellow",children:Aa(im,{color:"yellow",children:"No stage name provided."})})}import{useState as yP,useCallback as sS,useMemo as aS}from"react";import{Box as li,Text as ko,useInput as hP}from"ink";import{attempt as xP}from"@logosdx/utils";import{jsx as ir,jsxs as ui}from"react/jsx-runtime";function Mf({params:t}){let{back:e}=I(),{isFocused:r}=A("SettingsStageSecretRemove"),{settingsManager:n,settings:o,refresh:i}=L(),{showToast:s}=q(),a=t.stage,c=t.name,[l,m]=yP(!1),d=aS(()=>!o?.stages||!a?null:o.stages[a],[o,a]),u=aS(()=>!d?.secrets||!c?null:d.secrets.find(h=>h.key===c),[d,c]),p=sS(async()=>{if(!n||!a||!c)return;m(!0);let[h,f]=await xP(async()=>{await n.removeStageSecret(a,c),await i()});if(f){s({message:f instanceof Error?f.message:String(f),variant:"error"}),m(!1);return}s({message:`Secret "${c}" removed from stage "${a}"`,variant:"success"}),e()},[n,a,c,i,s,e]),g=sS(()=>e(),[e]);return hP((h,f)=>{r&&(!a||!c||!d||!u)&&(f.escape||f.return)&&e()}),l?ir(y,{title:`Delete: ${c}`,paddingX:2,paddingY:1,children:ir($,{label:"Deleting secret from stage..."})}):a?d?c?u?ir(y,{title:`Remove: ${c}`,paddingX:2,paddingY:1,borderColor:"yellow",children:ui(li,{flexDirection:"column",gap:1,children:[ui(ko,{dimColor:!0,children:["Stage: ",a]}),u.description&&ir(ko,{dimColor:!0,children:u.description}),ui(ko,{dimColor:!0,children:["Type: ",u.type]}),ir(ee,{message:`Delete "${c}" from stage "${a}"?`,onConfirm:p,onCancel:g,variant:"warning",isFocused:r})]})}):ui(li,{flexDirection:"column",gap:1,children:[ir(y,{title:"Remove Stage Secret",paddingX:2,paddingY:1,borderColor:"red",children:ui(ko,{color:"red",children:['Secret "',c,'" not found in stage "',a,'".']})}),ir(li,{flexWrap:"wrap",columnGap:2,children:ir(ko,{dimColor:!0,children:"[Enter/Esc] Back"})})]}):ui(li,{flexDirection:"column",gap:1,children:[ir(y,{title:"Remove Stage Secret",paddingX:2,paddingY:1,borderColor:"yellow",children:ir(ko,{color:"yellow",children:"No secret key provided."})}),ir(li,{flexWrap:"wrap",columnGap:2,children:ir(ko,{dimColor:!0,children:"[Enter/Esc] Back"})})]}):ui(li,{flexDirection:"column",gap:1,children:[ir(y,{title:"Remove Stage Secret",paddingX:2,paddingY:1,borderColor:"red",children:ui(ko,{color:"red",children:['Stage "',a,'" not found.']})}),ir(li,{flexWrap:"wrap",columnGap:2,children:ir(ko,{dimColor:!0,children:"[Enter/Esc] Back"})})]}):ui(li,{flexDirection:"column",gap:1,children:[ir(y,{title:"Remove Stage Secret",paddingX:2,paddingY:1,borderColor:"yellow",children:ir(ko,{color:"yellow",children:"No stage name provided."})}),ir(li,{flexWrap:"wrap",columnGap:2,children:ir(ko,{dimColor:!0,children:"[Enter/Esc] Back"})})]})}import{useCallback as qc,useMemo as Kc}from"react";import{Box as Vc,Text as cm,useInput as bP}from"ink";import{jsx as Wi,jsxs as Uc}from"react/jsx-runtime";function $f({params:t}){let{navigate:e,back:r}=I(),{isFocused:n}=A("SecretList"),{activeConfig:o,activeConfigName:i,stateManager:s,settingsManager:a}=L(),{showToast:c}=q(),l=i,m=Kc(()=>!l||!a?[]:a.getRequiredSecrets(l),[l,a]),d=Kc(()=>!s||!i?[]:s.listSecrets(i),[s,i]),u=Kc(()=>{let T=[],R=new Set(m.map(C=>C.key)),x=C=>{if(!s||!i)return;let b=s.getSecret(i,C);return b?Jl(b,C,"verbose"):void 0};for(let C of m){let b=d.includes(C.key);T.push({key:C.key,isRequired:!0,isSet:b,type:C.type,description:C.description,maskedValue:b?x(C.key):void 0})}for(let C of d)R.has(C)||T.push({key:C,isRequired:!1,isSet:!0,maskedValue:x(C)});return T},[m,d,s,i]),p=Kc(()=>new Set(m.map(T=>T.key)),[m]),g=Kc(()=>{if(!a)return new Set;let T=a.getUniversalSecrets();return new Set(T.map(R=>R.key))},[a]),h=qc(()=>{e("secret/set")},[e]),f=qc(T=>{e("secret/set",{name:T})},[e]),w=qc(T=>{e("secret/rm",{name:T})},[e]),S=qc(T=>!p.has(T),[p]),E=qc(T=>{let x=g.has(T)?"universal":"stage";c({message:`"${T}" is a ${x} secret and cannot be deleted`,variant:"warning"})},[g,c]);return bP((T,R)=>{n&&R.escape&&(!i||!o)&&r()}),!i||!o?Uc(Vc,{flexDirection:"column",gap:1,children:[Wi(y,{title:"Secrets",paddingX:2,paddingY:1,borderColor:"yellow",children:Uc(Vc,{flexDirection:"column",gap:1,children:[Wi(cm,{color:"yellow",children:"No active configuration."}),Wi(cm,{children:"Set an active config first with: noorm config:use <name>"})]})}),Wi(Vc,{flexWrap:"wrap",columnGap:2,children:Wi(cm,{dimColor:!0,children:"[Esc] Back"})})]}):Uc(Vc,{flexDirection:"column",gap:1,children:[Wi(y,{title:`Secrets for "${i}"`,paddingX:1,paddingY:1,children:Uc(Vc,{flexDirection:"column",gap:1,children:[l&&Uc(cm,{dimColor:!0,children:["Stage: ",l]}),Wi(Eu,{secrets:u,onAdd:h,onEdit:f,onDelete:w,canDelete:S,onDeleteBlocked:E,isFocused:n,onBack:r})]})}),Wi(Ru,{})]})}import{useState as cS,useCallback as lS,useMemo as lm}from"react";import{Box as Yc,Text as um,useInput as SP}from"ink";import{attempt as CP}from"@logosdx/utils";import{jsx as mi,jsxs as mm}from"react/jsx-runtime";function wP({title:t,message:e}){let{back:r}=I(),{isFocused:n}=A("NoConfigError");return SP((o,i)=>{n&&(i.escape||i.return)&&r()}),mm(Yc,{flexDirection:"column",gap:1,children:[mi(y,{title:t,paddingX:2,paddingY:1,borderColor:"yellow",children:mm(Yc,{flexDirection:"column",gap:1,children:[mi(um,{color:"yellow",children:e}),mi(um,{dimColor:!0,children:"Use: noorm config:use <name>"})]})}),mi(Yc,{gap:2,children:mi(um,{color:n?"cyan":void 0,dimColor:!n,children:"[Esc] Back"})})]})}function jf({params:t}){let{back:e}=I(),{activeConfig:r,activeConfigName:n,stateManager:o,settingsManager:i,refresh:s}=L(),{showToast:a}=q(),[c,l]=cS(!1),[m,d]=cS(null),u=t.name,p=n,g=lm(()=>!p||!i?[]:i.getRequiredSecrets(p).map(R=>({key:R.key,type:R.type,description:R.description,required:!0})),[p,i]),h=lm(()=>u?g.find(R=>R.key===u)??null:null,[u,g]),f=lm(()=>!o||!n||!u?!1:o.getSecret(n,u)!==null,[o,n,u]),w=lm(()=>!o||!n?[]:g.filter(R=>o.getSecret(n,R.key)===null),[g,o,n]),S=lS(async(R,x)=>{if(!o||!n){d("No active configuration");return}l(!0),d(null);let[,C]=await CP(async()=>{await o.setSecret(n,R,x),await s()});if(C){d(C instanceof Error?C.message:String(C)),l(!1);return}a({message:`Secret "${R}" saved`,variant:"success"}),e()},[o,n,s,a,e]),E=lS(()=>{e()},[e]);if(!n||!r)return mi(wP,{title:"Set Secret",message:"No active configuration. Set an active config first."});let T=u?f?`Update Secret: ${u}`:`Set Secret: ${u}`:"Add Secret";return mi(Yc,{flexDirection:"column",gap:1,children:mi(y,{title:T,paddingX:2,paddingY:1,children:mm(Yc,{flexDirection:"column",gap:1,children:[mm(um,{dimColor:!0,children:["Config: ",n]}),mi(wu,{secretKey:u,secretDefinition:h,unsetRequired:w,secretExists:f,onSubmit:S,onCancel:E,busy:c,error:m,focusLabel:"SecretSetForm"})]})})})}import{useState as TP,useCallback as uS,useMemo as dm}from"react";import{Box as io,Text as Sn,useInput as EP}from"ink";import{attempt as RP}from"@logosdx/utils";import{jsx as $t,jsxs as so}from"react/jsx-runtime";function Hf({params:t}){let{back:e}=I(),{isFocused:r}=A("SecretRemove"),{activeConfig:n,activeConfigName:o,stateManager:i,settingsManager:s,refresh:a}=L(),{showToast:c}=q(),l=t.name,[m,d]=TP(!1),u=o,p=dm(()=>!u||!s?[]:s.getRequiredSecrets(u),[u,s]),g=dm(()=>l?p.find(E=>E.key===l):null,[l,p]),h=dm(()=>g!==void 0,[g]),f=dm(()=>!i||!o||!l?!1:i.getSecret(o,l)!==null,[i,o,l]),w=uS(async()=>{if(!i||!o||!l){c({message:"Secret not found",variant:"error"}),e();return}d(!0);let[,E]=await RP(async()=>{await i.deleteSecret(o,l),await a()});if(E){c({message:E instanceof Error?E.message:String(E),variant:"error"}),d(!1);return}c({message:`Secret "${l}" deleted`,variant:"success"}),e()},[i,o,l,a,c,e]),S=uS(()=>{e()},[e]);return EP((E,T)=>{r&&(!o||!l||!f||h)&&(T.escape||T.return)&&e()}),!o||!n?so(io,{flexDirection:"column",gap:1,children:[$t(y,{title:"Delete Secret",paddingX:2,paddingY:1,borderColor:"yellow",children:so(io,{flexDirection:"column",gap:1,children:[$t(Sn,{color:"yellow",children:"No active configuration."}),$t(Sn,{children:"Set an active config first with: noorm config:use <name>"})]})}),$t(io,{flexWrap:"wrap",columnGap:2,children:$t(Sn,{dimColor:!0,children:"[Enter/Esc] Back"})})]}):l?f?h?so(io,{flexDirection:"column",gap:1,children:[$t(y,{title:"Delete Secret",paddingX:2,paddingY:1,borderColor:"yellow",children:so(io,{flexDirection:"column",gap:1,children:[so(Sn,{color:"yellow",children:['Cannot delete required secret "',l,'".']}),$t(Sn,{children:"Required secrets are defined by the stage configuration."}),$t(Sn,{dimColor:!0,children:"To remove a required secret definition, edit settings.yml"})]})}),$t(io,{flexWrap:"wrap",columnGap:2,children:$t(Sn,{dimColor:!0,children:"[Enter/Esc] Back"})})]}):m?$t(y,{title:`Delete: ${l}`,paddingX:2,paddingY:1,children:$t($,{label:"Deleting secret..."})}):$t(y,{title:`Delete: ${l}`,paddingX:2,paddingY:1,borderColor:"yellow",children:so(io,{flexDirection:"column",gap:1,children:[so(Sn,{dimColor:!0,children:["Config: ",o]}),g?.description&&so(io,{flexDirection:"column",children:[$t(Sn,{dimColor:!0,children:"Description:"}),so(Sn,{dimColor:!0,children:[" ",g.description]})]}),$t(ee,{message:`Are you sure you want to delete secret "${l}"?`,onConfirm:w,onCancel:S,variant:"warning",isFocused:r})]})}):so(io,{flexDirection:"column",gap:1,children:[$t(y,{title:"Delete Secret",paddingX:2,paddingY:1,borderColor:"red",children:so(Sn,{color:"red",children:['Secret "',l,'" not found.']})}),$t(io,{flexWrap:"wrap",columnGap:2,children:$t(Sn,{dimColor:!0,children:"[Enter/Esc] Back"})})]}):so(io,{flexDirection:"column",gap:1,children:[$t(y,{title:"Delete Secret",paddingX:2,paddingY:1,borderColor:"yellow",children:$t(Sn,{color:"yellow",children:"No secret key provided. Use: noorm secret:rm <key>"})}),$t(io,{flexWrap:"wrap",columnGap:2,children:$t(Sn,{dimColor:!0,children:"[Enter/Esc] Back"})})]})}import{useState as pm,useEffect as kP}from"react";import{Box as Cn,Text as Ot,useInput as _P}from"ink";import{attempt as vP}from"@logosdx/utils";import{jsx as We,jsxs as wn}from"react/jsx-runtime";function qf({params:t}){let{navigate:e,back:r}=I(),{isFocused:n}=A("LockList"),{activeConfig:o,activeConfigName:i,identity:s}=L(),{showToast:a}=q(),[c,l]=pm(null),[m,d]=pm(!0),[u,p]=pm(null),[g,h]=pm("");if(kP(()=>{if(!o||!i){d(!1);return}let S=!1;return(async()=>{d(!0),p(null);let T=Zt({cryptoIdentity:s??null}),R=Ft(T);S||h(R);let x=await de(o.connection);if(!x.ok){S||(p(x.error??"Connection failed"),d(!1));return}let[C,b]=await vP(async()=>{let v=await K(o.connection,i??void 0),P=v.db,O=await mt().status(P,i??"");return await v.destroy(),O});S||(b?p(b.message):C&&l(C),d(!1))})(),()=>{S=!0}},[o,i,s]),_P((S,E)=>{if(n){if(E.escape){r();return}if(!(!o||u)){if(S==="s"||S==="1"){e("lock/status");return}if(S==="a"||S==="2"){if(c?.isLocked&&c.lock?.lockedBy===g){a({message:"You already hold this lock",variant:"info"});return}e("lock/acquire");return}if(S==="r"||S==="3"){if(!c?.isLocked){a({message:"No lock to release",variant:"info"});return}if(c.lock?.lockedBy!==g){a({message:`Lock held by ${c.lock?.lockedBy}`,variant:"warning"});return}e("lock/release");return}if(S==="f"||S==="4"){if(!c?.isLocked){a({message:"No lock to force-release",variant:"info"});return}e("lock/force");return}}}}),!o)return wn(Cn,{flexDirection:"column",gap:1,children:[We(y,{title:"Lock Management",borderColor:"yellow",paddingX:1,paddingY:1,children:wn(Cn,{flexDirection:"column",gap:1,children:[We(Ot,{color:"yellow",children:"No active configuration selected."}),We(Ot,{dimColor:!0,children:"Select a configuration first using the config screen."})]})}),We(Cn,{flexWrap:"wrap",columnGap:2,children:We(Ot,{dimColor:!0,children:"[Esc] Back"})})]});if(m)return We(Cn,{flexDirection:"column",gap:1,children:We(y,{title:"Lock Management",paddingX:1,paddingY:1,children:We($,{label:"Checking lock status..."})})});if(u)return wn(Cn,{flexDirection:"column",gap:1,children:[We(y,{title:"Lock Management",borderColor:"red",paddingX:1,paddingY:1,children:wn(Cn,{flexDirection:"column",gap:1,children:[We(Ot,{color:"red",children:"Cannot connect to database"}),We(Ot,{dimColor:!0,children:u})]})}),We(Cn,{flexWrap:"wrap",columnGap:2,children:We(Ot,{dimColor:!0,children:"[Esc] Back"})})]});let f=()=>c?.isLocked?c.lock?.lockedBy===g?"locked":"blocked":"free",w=c?.isLocked&&c.lock?.lockedBy===g;return wn(Cn,{flexDirection:"column",gap:1,children:[We(y,{title:"Lock Management",paddingX:1,paddingY:1,children:wn(Cn,{flexDirection:"column",gap:1,children:[wn(Cn,{gap:2,children:[We(Ot,{children:"Config:"}),We(Ot,{bold:!0,color:"cyan",children:i})]}),wn(Cn,{gap:2,children:[We(Ot,{children:"Your Identity:"}),We(Ot,{dimColor:!0,children:g})]}),We(Cn,{marginTop:1,children:We(pa,{status:f(),holder:c?.lock?.lockedBy,since:c?.lock?.lockedAt,expires:c?.lock?.expiresAt})})]})}),We(y,{title:"Available Actions",paddingX:1,paddingY:1,children:wn(Cn,{flexDirection:"column",gap:1,children:[wn(Ot,{children:[We(Ot,{color:"cyan",children:"[s]"})," Status - View detailed lock information"]}),wn(Ot,{children:[We(Ot,{color:"cyan",children:"[a]"})," Acquire - Obtain exclusive lock"]}),wn(Ot,{color:w?void 0:"gray",children:[We(Ot,{color:w?"cyan":"gray",children:"[r]"})," Release - Release your lock"]}),wn(Ot,{color:c?.isLocked?void 0:"gray",children:[We(Ot,{color:c?.isLocked?"cyan":"gray",children:"[f]"})," Force - Admin force-release"]})]})}),wn(Cn,{flexWrap:"wrap",columnGap:2,children:[We(Ot,{dimColor:!0,children:"[s] Status"}),We(Ot,{dimColor:!0,children:"[a] Acquire"}),We(Ot,{dimColor:!0,children:"[r] Release"}),We(Ot,{dimColor:!0,children:"[f] Force"}),We(Ot,{dimColor:!0,children:"[Esc] Back"})]})]})}import{useState as fm,useEffect as DP}from"react";import{Box as hr,Text as tt,useInput as PP}from"ink";import{attempt as NP}from"@logosdx/utils";import{Fragment as BP,jsx as Se,jsxs as xr}from"react/jsx-runtime";function FP(t){let e=Math.floor(t/6e4),r=Math.floor(e/60);return r>0?`${r}h ${e%60}m`:`${e}m`}function Kf({params:t}){let{navigate:e,back:r}=I(),{isFocused:n}=A("LockStatus"),{activeConfig:o,activeConfigName:i,identity:s}=L(),{showToast:a}=q(),[c,l]=fm(null),[m,d]=fm(!0),[u,p]=fm(null),[g,h]=fm("");if(DP(()=>{if(!o||!i){d(!1);return}let E=!1;return(async()=>{d(!0),p(null);let R=Zt({cryptoIdentity:s??null}),x=Ft(R);E||h(x);let C=await de(o.connection);if(!C.ok){E||(p(C.error??"Connection failed"),d(!1));return}let[b,v]=await NP(async()=>{let P=await K(o.connection,i??void 0),_=P.db,N=await mt().status(_,i??"");return await P.destroy(),N});E||(v?p(v.message):b&&l(b),d(!1))})(),()=>{E=!0}},[o,i,s]),PP((E,T)=>{if(n){if(T.escape){r();return}if(!(!o||u)){if(E==="a"){if(c?.isLocked&&c.lock?.lockedBy===g){a({message:"You already hold this lock",variant:"info"});return}e("lock/acquire");return}if(E==="r"){if(!c?.isLocked){a({message:"No lock to release",variant:"info"});return}if(c.lock?.lockedBy!==g){a({message:`Lock held by ${c.lock?.lockedBy}`,variant:"warning"});return}e("lock/release");return}if(E==="x"){if(!c?.isLocked){a({message:"No lock to extend",variant:"info"});return}if(c.lock?.lockedBy!==g){a({message:`Cannot extend - lock held by ${c.lock?.lockedBy}`,variant:"warning"});return}e("lock/acquire");return}if(E==="f"){if(!c?.isLocked){a({message:"No lock to force-release",variant:"info"});return}e("lock/force");return}}}}),!o)return xr(hr,{flexDirection:"column",gap:1,children:[Se(y,{title:"Lock Status",borderColor:"yellow",paddingX:1,paddingY:1,children:xr(hr,{flexDirection:"column",gap:1,children:[Se(tt,{color:"yellow",children:"No active configuration selected."}),Se(tt,{dimColor:!0,children:"Select a configuration first using the config screen."})]})}),Se(hr,{flexWrap:"wrap",columnGap:2,children:Se(tt,{dimColor:!0,children:"[Esc] Back"})})]});if(m)return Se(hr,{flexDirection:"column",gap:1,children:Se(y,{title:"Lock Status",paddingX:1,paddingY:1,children:Se($,{label:"Checking lock status..."})})});if(u)return xr(hr,{flexDirection:"column",gap:1,children:[Se(y,{title:"Lock Status",borderColor:"red",paddingX:1,paddingY:1,children:xr(hr,{flexDirection:"column",gap:1,children:[Se(tt,{color:"red",children:"Cannot connect to database"}),Se(tt,{dimColor:!0,children:u})]})}),Se(hr,{flexWrap:"wrap",columnGap:2,children:Se(tt,{dimColor:!0,children:"[Esc] Back"})})]});let f=c?.isLocked&&c.lock?.lockedBy===g,w=c?.isLocked?f?"locked":"blocked":"free",S=c?.lock?.expiresAt&&c.isLocked?c.lock.expiresAt.getTime()-Date.now():0;return xr(hr,{flexDirection:"column",gap:1,children:[Se(y,{title:"Lock Status",paddingX:1,paddingY:1,children:xr(hr,{flexDirection:"column",gap:1,children:[xr(hr,{gap:2,children:[Se(tt,{children:"Config:"}),Se(tt,{bold:!0,color:"cyan",children:i})]}),xr(hr,{gap:2,children:[Se(tt,{children:"Your Identity:"}),Se(tt,{dimColor:!0,children:g})]}),Se(hr,{marginTop:1,children:Se(pa,{status:w,holder:c?.lock?.lockedBy,since:c?.lock?.lockedAt,expires:c?.lock?.expiresAt})}),c?.isLocked&&c.lock?.reason&&xr(hr,{gap:2,marginTop:1,children:[Se(tt,{dimColor:!0,children:"Reason:"}),Se(tt,{children:c.lock.reason})]}),c?.isLocked&&S>0&&xr(hr,{gap:2,children:[Se(tt,{dimColor:!0,children:"Time Remaining:"}),Se(tt,{color:S<6e4?"yellow":void 0,children:FP(S)})]})]})}),!c?.isLocked&&Se(y,{title:"Actions",borderColor:"green",paddingX:1,paddingY:1,children:xr(hr,{flexDirection:"column",gap:1,children:[Se(tt,{color:"green",children:"Database is unlocked and available."}),xr(tt,{children:["Press ",Se(tt,{color:"cyan",children:"[a]"})," to acquire the lock."]})]})}),f&&Se(y,{title:"Actions",borderColor:"blue",paddingX:1,paddingY:1,children:xr(hr,{flexDirection:"column",gap:1,children:[Se(tt,{color:"blue",children:"You hold this lock."}),xr(tt,{children:["Press ",Se(tt,{color:"cyan",children:"[r]"})," to release or"," ",Se(tt,{color:"cyan",children:"[x]"})," to extend."]})]})}),c?.isLocked&&!f&&Se(y,{title:"Actions",borderColor:"yellow",paddingX:1,paddingY:1,children:xr(hr,{flexDirection:"column",gap:1,children:[Se(tt,{color:"yellow",children:"Blocked by another user."}),xr(tt,{dimColor:!0,children:["Wait for lock to be released, or use ",Se(tt,{color:"cyan",children:"[f]"})," for emergency force-release."]})]})}),xr(hr,{flexWrap:"wrap",columnGap:2,children:[!c?.isLocked&&Se(tt,{dimColor:!0,children:"[a] Acquire"}),f&&xr(BP,{children:[Se(tt,{dimColor:!0,children:"[r] Release"}),Se(tt,{dimColor:!0,children:"[x] Extend"})]}),c?.isLocked&&Se(tt,{dimColor:!0,children:"[f] Force"}),Se(tt,{dimColor:!0,children:"[Esc] Back"})]})]})}import{useState as gm,useEffect as LP,useCallback as Vf}from"react";import{Box as An,Text as Dr,useInput as IP}from"ink";import{attempt as mS}from"@logosdx/utils";import{Fragment as OP,jsx as Me,jsxs as Mo}from"react/jsx-runtime";function Uf({params:t}){let{back:e}=I(),{isFocused:r}=A("LockAcquire"),{activeConfig:n,activeConfigName:o,identity:i}=L(),{showToast:s}=q(),[a,c]=gm("loading"),[l,m]=gm(null),[d,u]=gm(null),[p,g]=gm("");LP(()=>{if(!n||!o){c("error"),m("No active configuration");return}let S=!1;return(async()=>{let T=Zt({cryptoIdentity:i??null}),R=Ft(T);S||g(R);let x=await de(n.connection);if(!x.ok){S||(m(`Cannot connect to database: ${x.error}`),c("error"));return}let[C,b]=await mS(async()=>{let v=await K(n.connection,o??void 0),P=v.db,O=await mt().status(P,o??"");return await v.destroy(),O});if(!S){if(b){m(b.message),c("error");return}if(u(C),C?.isLocked&&C.lock?.lockedBy!==R){c("blocked");return}c("form")}})(),()=>{S=!0}},[n,o,i]);let h=Vf(S=>{if(!n||!o)return;c("running");let E=parseInt(String(S.timeout??"5"),10)*60*1e3,T=S.reason?String(S.reason):void 0;(async()=>{let[,x]=await mS(async()=>{let C=await K(n.connection,o??void 0),b=C.db;await mt().acquire(b,o??"",p,{timeout:E,reason:T}),await C.destroy()});if(x){x instanceof Do?m(`Lock held by ${x.holder} since ${x.heldSince?.toLocaleString()}${x.reason?` (${x.reason})`:""}`):m(x.message),c("error");return}c("done")})()},[n,o,p]),f=Vf(()=>{e()},[e]),w=Vf(()=>{s({message:"Lock acquired",variant:"success"}),e()},[s,e]);if(IP((S,E)=>{r&&(a==="done"||a==="error"||a==="blocked")&&(E.return||E.escape)&&(a==="done"?w():e())}),!n)return Me(y,{title:"Acquire Lock",borderColor:"red",paddingX:1,paddingY:1,children:Me(Dr,{color:"red",children:"No active configuration selected."})});if(a==="loading")return Me(y,{title:"Acquire Lock",paddingX:1,paddingY:1,children:Me($,{label:"Checking lock status..."})});if(a==="blocked"&&d?.lock)return Mo(An,{flexDirection:"column",gap:1,children:[Me(y,{title:"Acquire Lock",borderColor:"yellow",paddingX:1,paddingY:1,children:Mo(An,{flexDirection:"column",gap:1,children:[Me(Dr,{color:"yellow",children:"Lock is currently held by another user."}),Mo(An,{gap:2,children:[Me(Dr,{dimColor:!0,children:"Holder:"}),Me(Dr,{children:d.lock.lockedBy})]}),Mo(An,{gap:2,children:[Me(Dr,{dimColor:!0,children:"Since:"}),Me(Dr,{children:d.lock.lockedAt?.toLocaleString()})]}),Mo(An,{gap:2,children:[Me(Dr,{dimColor:!0,children:"Expires:"}),Me(Dr,{children:d.lock.expiresAt?.toLocaleString()})]}),d.lock.reason&&Mo(An,{gap:2,children:[Me(Dr,{dimColor:!0,children:"Reason:"}),Me(Dr,{children:d.lock.reason})]})]})}),Me(An,{flexWrap:"wrap",columnGap:2,children:Me(Dr,{dimColor:!0,children:"[Enter/Esc] Back"})})]});if(a==="form"){let S=d?.isLocked&&d.lock?.lockedBy===p;return Mo(An,{flexDirection:"column",gap:1,children:[S&&Me(y,{title:"Extending Lock",borderColor:"blue",paddingX:1,paddingY:1,children:Me(Dr,{color:"blue",children:"You already hold this lock. Submitting will extend it."})}),Me(y,{title:S?"Extend Lock":"Acquire Lock",paddingX:1,paddingY:1,children:Me(Ke,{fields:[{key:"timeout",label:"Timeout (minutes)",type:"text",defaultValue:"5",placeholder:"5"},{key:"reason",label:"Reason (optional)",type:"text",placeholder:"Running migrations..."}],onSubmit:h,onCancel:f,focusLabel:"LockAcquireForm",submitLabel:S?"Extend":"Acquire"})})]})}return a==="running"?Me(y,{title:"Acquire Lock",paddingX:1,paddingY:1,children:Me($,{label:"Acquiring lock..."})}):a==="done"?Mo(An,{flexDirection:"column",gap:1,children:[Me(y,{title:"Lock Acquired",borderColor:"green",paddingX:1,paddingY:1,children:Mo(An,{flexDirection:"column",gap:1,children:[Me(Dr,{color:"green",children:"Lock successfully acquired."}),Me(Dr,{dimColor:!0,children:"You have exclusive access to this database."})]})}),Me(An,{flexWrap:"wrap",columnGap:2,children:Me(Dr,{dimColor:!0,children:"[Enter/Esc] Done"})})]}):a==="error"?Mo(An,{flexDirection:"column",gap:1,children:[Me(y,{title:"Acquire Lock Failed",borderColor:"red",paddingX:1,paddingY:1,children:Me(Dr,{color:"red",children:l})}),Me(An,{flexWrap:"wrap",columnGap:2,children:Me(Dr,{dimColor:!0,children:"[Enter/Esc] Back"})})]}):Me(OP,{})}import{useState as ym,useEffect as AP,useCallback as Yf}from"react";import{Box as ao,Text as Tn,useInput as MP}from"ink";import{attempt as dS}from"@logosdx/utils";import{Fragment as $P,jsx as rt,jsxs as Gi}from"react/jsx-runtime";function Wf({params:t}){let{back:e}=I(),{isFocused:r}=A("LockRelease"),{activeConfig:n,activeConfigName:o,identity:i}=L(),{showToast:s}=q(),[a,c]=ym("loading"),[l,m]=ym(null),[d,u]=ym(null),[p,g]=ym("");AP(()=>{if(!n||!o){c("error"),m("No active configuration");return}let S=!1;return(async()=>{let T=Zt({cryptoIdentity:i??null}),R=Ft(T);S||g(R);let x=await de(n.connection);if(!x.ok){S||(m(`Cannot connect to database: ${x.error}`),c("error"));return}let[C,b]=await dS(async()=>{let v=await K(n.connection,o??void 0),P=v.db,O=await mt().status(P,o??"");return await v.destroy(),O});if(!S){if(b){m(b.message),c("error");return}if(u(C),!C?.isLocked){c("no-lock");return}if(C.lock?.lockedBy!==R){c("not-yours");return}c("confirm")}})(),()=>{S=!0}},[n,o,i]);let h=Yf(async()=>{if(!n||!o)return;c("running");let[,S]=await dS(async()=>{let E=await K(n.connection,o??void 0),T=E.db;await mt().release(T,o??"",p),await E.destroy()});if(S){S instanceof Ho?m("Lock no longer exists"):S instanceof qo?m(`Lock is held by ${S.actualHolder}, not you`):m(S.message),c("error");return}c("done")},[n,o,p]),f=Yf(()=>{e()},[e]),w=Yf(()=>{s({message:"Lock released",variant:"success"}),e()},[s,e]);return MP((S,E)=>{r&&(a==="done"||a==="error"||a==="no-lock"||a==="not-yours")&&(E.return||E.escape)&&(a==="done"?w():(a==="no-lock"&&s({message:"No lock to release",variant:"info"}),e()))}),n?a==="loading"?rt(y,{title:"Release Lock",paddingX:1,paddingY:1,children:rt($,{label:"Checking lock status..."})}):a==="no-lock"?Gi(ao,{flexDirection:"column",gap:1,children:[rt(y,{title:"Release Lock",borderColor:"yellow",paddingX:1,paddingY:1,children:Gi(ao,{flexDirection:"column",gap:1,children:[rt(Tn,{color:"yellow",children:"No lock exists."}),rt(Tn,{dimColor:!0,children:"There is no lock to release for this configuration."})]})}),rt(ao,{flexWrap:"wrap",columnGap:2,children:rt(Tn,{dimColor:!0,children:"[Enter/Esc] Back"})})]}):a==="not-yours"&&d?.lock?Gi(ao,{flexDirection:"column",gap:1,children:[rt(y,{title:"Release Lock",borderColor:"red",paddingX:1,paddingY:1,children:Gi(ao,{flexDirection:"column",gap:1,children:[rt(Tn,{color:"red",children:"This lock is not yours."}),Gi(ao,{gap:2,children:[rt(Tn,{dimColor:!0,children:"Holder:"}),rt(Tn,{children:d.lock.lockedBy})]}),rt(Tn,{dimColor:!0,children:"You can only release locks you own. Use force-release for emergencies."})]})}),rt(ao,{flexWrap:"wrap",columnGap:2,children:rt(Tn,{dimColor:!0,children:"[Enter/Esc] Back"})})]}):a==="confirm"?rt(ee,{title:"Release Lock",message:"Are you sure you want to release your lock? Other users will be able to acquire it.",onConfirm:h,onCancel:f,focusLabel:"LockReleaseConfirm"}):a==="running"?rt(y,{title:"Release Lock",paddingX:1,paddingY:1,children:rt($,{label:"Releasing lock..."})}):a==="done"?Gi(ao,{flexDirection:"column",gap:1,children:[rt(y,{title:"Lock Released",borderColor:"green",paddingX:1,paddingY:1,children:Gi(ao,{flexDirection:"column",gap:1,children:[rt(Tn,{color:"green",children:"Lock successfully released."}),rt(Tn,{dimColor:!0,children:"Other users can now acquire the lock."})]})}),rt(ao,{flexWrap:"wrap",columnGap:2,children:rt(Tn,{dimColor:!0,children:"[Enter/Esc] Done"})})]}):a==="error"?Gi(ao,{flexDirection:"column",gap:1,children:[rt(y,{title:"Release Lock Failed",borderColor:"red",paddingX:1,paddingY:1,children:rt(Tn,{color:"red",children:l})}),rt(ao,{flexWrap:"wrap",columnGap:2,children:rt(Tn,{dimColor:!0,children:"[Enter/Esc] Back"})})]}):rt($P,{}):rt(y,{title:"Release Lock",borderColor:"red",paddingX:1,paddingY:1,children:rt(Tn,{color:"red",children:"No active configuration selected."})})}import{useState as Gf,useEffect as jP,useCallback as Xf}from"react";import{Box as Mn,Text as br,useInput as HP}from"ink";import{attempt as pS}from"@logosdx/utils";import{Fragment as qP,jsx as je,jsxs as _o}from"react/jsx-runtime";function zf({params:t}){let{back:e}=I(),{isFocused:r}=A("LockForce"),{activeConfig:n,activeConfigName:o}=L(),{showToast:i}=q(),[s,a]=Gf("loading"),[c,l]=Gf(null),[m,d]=Gf(null);jP(()=>{if(!n||!o){a("error"),l("No active configuration");return}let h=!1;return(async()=>{let w=await de(n.connection);if(!w.ok){h||(l(`Cannot connect to database: ${w.error}`),a("error"));return}let[S,E]=await pS(async()=>{let T=await K(n.connection,o??void 0),R=T.db,C=await mt().status(R,o??"");return await T.destroy(),C});if(!h){if(E){l(E.message),a("error");return}if(d(S),!S?.isLocked){a("no-lock");return}a("confirm")}})(),()=>{h=!0}},[n,o]);let u=Xf(async()=>{if(!n||!o)return;a("running");let[,h]=await pS(async()=>{let f=await K(n.connection,o??void 0),w=f.db;await mt().forceRelease(w,o??""),await f.destroy()});if(h){l(h.message),a("error");return}a("done")},[n,o]),p=Xf(()=>{e()},[e]),g=Xf(()=>{i({message:"Lock force-released",variant:"success"}),e()},[i,e]);return HP((h,f)=>{r&&(s==="done"||s==="error"||s==="no-lock")&&(f.return||f.escape)&&(s==="done"?g():(s==="no-lock"&&i({message:"No lock to release",variant:"info"}),e()))}),n?s==="loading"?je(y,{title:"Force Release Lock",paddingX:1,paddingY:1,children:je($,{label:"Checking lock status..."})}):s==="no-lock"?_o(Mn,{flexDirection:"column",gap:1,children:[je(y,{title:"Force Release Lock",borderColor:"yellow",paddingX:1,paddingY:1,children:_o(Mn,{flexDirection:"column",gap:1,children:[je(br,{color:"yellow",children:"No lock exists."}),je(br,{dimColor:!0,children:"There is no lock to release for this configuration."})]})}),je(Mn,{flexWrap:"wrap",columnGap:2,children:je(br,{dimColor:!0,children:"[Enter/Esc] Back"})})]}):s==="confirm"&&m?.lock?_o(Mn,{flexDirection:"column",gap:1,children:[je(y,{title:"Force Release Lock",borderColor:"red",paddingX:1,paddingY:1,children:_o(Mn,{flexDirection:"column",gap:1,children:[_o(br,{color:"red",children:[je(br,{bold:!0,children:"Warning:"})," This is an admin operation."]}),je(br,{dimColor:!0,children:"Force-releasing a lock may interrupt another user's work."}),_o(Mn,{gap:2,marginTop:1,children:[je(br,{dimColor:!0,children:"Current holder:"}),je(br,{children:m.lock.lockedBy})]}),_o(Mn,{gap:2,children:[je(br,{dimColor:!0,children:"Since:"}),je(br,{children:m.lock.lockedAt?.toLocaleString()})]}),m.lock.reason&&_o(Mn,{gap:2,children:[je(br,{dimColor:!0,children:"Reason:"}),je(br,{children:m.lock.reason})]})]})}),je(pt,{configName:o??"unknown",action:"force-release lock for",onConfirm:u,onCancel:p,focusLabel:"LockForceConfirm"})]}):s==="running"?je(y,{title:"Force Release Lock",paddingX:1,paddingY:1,children:je($,{label:"Force-releasing lock..."})}):s==="done"?_o(Mn,{flexDirection:"column",gap:1,children:[je(y,{title:"Lock Force-Released",borderColor:"green",paddingX:1,paddingY:1,children:_o(Mn,{flexDirection:"column",gap:1,children:[je(br,{color:"green",children:"Lock successfully force-released."}),je(br,{dimColor:!0,children:"The database is now unlocked."})]})}),je(Mn,{flexWrap:"wrap",columnGap:2,children:je(br,{dimColor:!0,children:"[Enter/Esc] Done"})})]}):s==="error"?_o(Mn,{flexDirection:"column",gap:1,children:[je(y,{title:"Force Release Failed",borderColor:"red",paddingX:1,paddingY:1,children:je(br,{color:"red",children:c})}),je(Mn,{flexWrap:"wrap",columnGap:2,children:je(br,{dimColor:!0,children:"[Enter/Esc] Back"})})]}):je(qP,{}):je(y,{title:"Force Release Lock",borderColor:"red",paddingX:1,paddingY:1,children:je(br,{color:"red",children:"No active configuration selected."})})}import{useMemo as KP}from"react";import{Box as vt,Text as Dt,useInput as VP}from"ink";import{jsx as Be,jsxs as Pr}from"react/jsx-runtime";function UP(t){return new Date(t).toLocaleDateString("en-US",{year:"numeric",month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"})}function Jf({params:t}){let{navigate:e,back:r}=I(),{isFocused:n}=A("IdentityScreen"),{identity:o,hasIdentity:i,stateManager:s}=L(),a=KP(()=>{let m=s?.getKnownUsers()??{};return Object.keys(m).length},[s]);if(VP((m,d)=>{if(n){if(d.escape){r();return}if(m==="e"){e("identity/edit");return}if(m==="x"){e("identity/export");return}if(m==="r"){e("identity/init");return}if(m==="u"){e("identity/list");return}}}),!i||!o)return Pr(vt,{flexDirection:"column",gap:1,children:[Be(y,{title:"Identity",borderColor:"yellow",paddingX:2,paddingY:1,children:Pr(vt,{flexDirection:"column",gap:1,children:[Be(Dt,{color:"yellow",children:"No identity configured."}),Pr(Dt,{dimColor:!0,children:["Run ",Be(Dt,{color:"cyan",children:"noorm init"})," to set up your identity."]})]})}),Be(vt,{flexWrap:"wrap",columnGap:2,children:Be(Dt,{dimColor:!0,children:"[Esc] Back"})})]});let c=fc(o.identityHash,12),l=o.publicKey.slice(0,24)+"...";return Pr(vt,{flexDirection:"column",gap:1,children:[Be(y,{title:"Identity",paddingX:2,paddingY:1,children:Pr(vt,{flexDirection:"column",gap:1,children:[Pr(vt,{flexDirection:"column",children:[Pr(vt,{children:[Be(vt,{width:12,children:Be(Dt,{dimColor:!0,children:"Name:"})}),Be(Dt,{bold:!0,children:o.name})]}),Pr(vt,{children:[Be(vt,{width:12,children:Be(Dt,{dimColor:!0,children:"Email:"})}),Be(Dt,{children:o.email})]})]}),Pr(vt,{flexDirection:"column",marginTop:1,children:[Pr(vt,{children:[Be(vt,{width:12,children:Be(Dt,{dimColor:!0,children:"Machine:"})}),Be(Dt,{children:o.machine})]}),Pr(vt,{children:[Be(vt,{width:12,children:Be(Dt,{dimColor:!0,children:"OS:"})}),Be(Dt,{children:o.os})]})]}),Pr(vt,{flexDirection:"column",marginTop:1,children:[Pr(vt,{children:[Be(vt,{width:12,children:Be(Dt,{dimColor:!0,children:"Hash:"})}),Be(Dt,{color:"gray",children:c})]}),Pr(vt,{children:[Be(vt,{width:12,children:Be(Dt,{dimColor:!0,children:"Public Key:"})}),Be(Dt,{color:"gray",children:l})]}),Pr(vt,{children:[Be(vt,{width:12,children:Be(Dt,{dimColor:!0,children:"Created:"})}),Be(Dt,{children:UP(o.createdAt)})]})]})]})}),a>0&&Be(vt,{paddingLeft:2,children:Pr(Dt,{dimColor:!0,children:[a," known user",a!==1?"s":""," discovered"]})}),Pr(vt,{flexWrap:"wrap",columnGap:2,children:[Be(Dt,{dimColor:!0,children:"[e] Edit"}),Be(Dt,{dimColor:!0,children:"[x] Export Key"}),Be(Dt,{dimColor:!0,children:"[r] Regenerate"}),Be(Dt,{dimColor:!0,children:"[u] Known Users"}),Be(Dt,{dimColor:!0,children:"[Esc] Back"})]})]})}import{useState as fS,useCallback as YP}from"react";import{Box as di,Text as pi}from"ink";import{attempt as WP}from"@logosdx/utils";import{jsx as Sr,jsxs as Ma}from"react/jsx-runtime";function Qf({params:t}){let{back:e}=I(),{identity:r,hasIdentity:n,refresh:o}=L(),{showToast:i}=q(),[s,a]=fS(!1),[c,l]=fS(null),m=r?[{key:"name",label:"Name",type:"text",defaultValue:r.name,required:!0,placeholder:"Your name"},{key:"email",label:"Email",type:"text",defaultValue:r.email,required:!0,placeholder:"your@email.com",validate:u=>{if(typeof u=="string"&&!u.includes("@"))return"Invalid email address"}},{key:"machine",label:"Machine",type:"text",defaultValue:r.machine,required:!0,placeholder:"Machine name"}]:[],d=YP(async u=>{a(!0),l(null);let[p,g]=await WP(()=>yc({name:u.name,email:u.email,machine:u.machine}));if(g){l(g instanceof Error?g.message:String(g)),a(!1),i({message:"Failed to update identity",variant:"error"});return}if(!p){l("Could not load existing keys. You may need to regenerate your identity."),a(!1);return}await o?.(),i({message:"Identity updated",variant:"success"}),e()},[o,i,e]);return!n||!r?Ma(di,{flexDirection:"column",gap:1,children:[Sr(y,{title:"Edit Identity",borderColor:"yellow",paddingX:2,paddingY:1,children:Ma(di,{flexDirection:"column",gap:1,children:[Sr(pi,{color:"yellow",children:"No identity configured."}),Ma(pi,{dimColor:!0,children:["Run ",Sr(pi,{color:"cyan",children:"noorm init"})," to set up your identity."]})]})}),Sr(di,{flexWrap:"wrap",columnGap:2,children:Sr(pi,{dimColor:!0,children:"[Esc] Back"})})]}):s?Sr(di,{flexDirection:"column",gap:1,children:Sr(y,{title:"Edit Identity",paddingX:2,paddingY:1,children:Sr($,{label:"Saving changes..."})})}):Ma(di,{flexDirection:"column",gap:1,children:[c&&Sr(y,{borderColor:"red",paddingX:2,paddingY:1,children:Sr(pi,{color:"red",children:c})}),Sr(y,{title:"Edit Identity",paddingX:2,paddingY:1,children:Ma(di,{flexDirection:"column",gap:1,children:[Sr(pi,{dimColor:!0,children:"Update your identity details. Your keypair will remain unchanged."}),Sr(di,{marginTop:1,children:Sr(Ke,{fields:m,onSubmit:d,onCancel:e,submitLabel:"Save"})}),Sr(di,{marginTop:1,children:Ma(pi,{dimColor:!0,children:["OS: ",r.os," ",Sr(pi,{dimColor:!0,children:"(auto-detected)"})]})}),Sr(di,{marginTop:1,children:Sr(pi,{dimColor:!0,children:"Note: If you change your details, your identity hash will change."})})]})})]})}import{useCallback as GP}from"react";import{Box as Xi,Text as vo,useInput as XP}from"ink";import{attemptSync as zP}from"@logosdx/utils";import{jsx as En,jsxs as Ls}from"react/jsx-runtime";function Zf({params:t}){let{back:e}=I(),{isFocused:r}=A("IdentityExport"),{identity:n,hasIdentity:o}=L(),{showToast:i}=q(),s=vp(),a=GP(()=>{if(!n?.publicKey)return;let[,c]=zP(()=>_p(n.publicKey));if(c){i({message:"Failed to copy to clipboard",variant:"error"});return}i({message:"Public key copied to clipboard",variant:"success"})},[n?.publicKey,i]);return XP((c,l)=>{if(r){if(l.escape){e();return}if(c==="c"&&s){a();return}}}),!o||!n?Ls(Xi,{flexDirection:"column",gap:1,children:[En(y,{title:"Export Public Key",borderColor:"yellow",paddingX:2,paddingY:1,children:Ls(Xi,{flexDirection:"column",gap:1,children:[En(vo,{color:"yellow",children:"No identity configured."}),Ls(vo,{dimColor:!0,children:["Run ",En(vo,{color:"cyan",children:"noorm init"})," to set up your identity."]})]})}),En(Xi,{flexWrap:"wrap",columnGap:2,children:En(vo,{dimColor:!0,children:"[Esc] Back"})})]}):Ls(Xi,{flexDirection:"column",gap:1,children:[En(y,{title:"Export Public Key",paddingX:2,paddingY:1,children:Ls(Xi,{flexDirection:"column",gap:1,children:[En(vo,{children:"Share this key with team members so they can send you encrypted configurations."}),En(Xi,{flexDirection:"column",marginTop:1,borderStyle:"single",borderColor:"gray",paddingX:1,paddingY:1,children:En(vo,{wrap:"wrap",children:n.publicKey})}),Ls(Xi,{marginTop:1,children:[En(vo,{dimColor:!0,children:"Identity Hash: "}),En(vo,{color:"gray",children:n.identityHash})]})]})}),Ls(Xi,{flexWrap:"wrap",columnGap:2,children:[s?En(vo,{dimColor:!0,children:"[c] Copy to Clipboard"}):En(vo,{dimColor:!0,color:"yellow",children:"Clipboard not available"}),En(vo,{dimColor:!0,children:"[Esc] Back"})]})]})}import{useState as gS,useMemo as yS}from"react";import{Box as Hr,Text as xt,useInput as JP}from"ink";import{jsx as Tt,jsxs as sr}from"react/jsx-runtime";function eg({params:t}){let{back:e}=I(),{isFocused:r}=A("KnownUsers"),{stateManager:n}=L(),[o,i]=gS(0),[s,a]=gS(null),c=yS(()=>{let m=n?.getKnownUsers()??{},d={};for(let u of Object.values(m))d[u.email]||(d[u.email]=[]),d[u.email].push(u);return Object.entries(d).map(([u,p])=>({email:u,users:p.sort((g,h)=>new Date(h.lastSeen).getTime()-new Date(g.lastSeen).getTime())})).sort((u,p)=>u.email.localeCompare(p.email))},[n]),l=yS(()=>c.reduce((m,d)=>m+d.users.length,0),[c]);return JP((m,d)=>{if(r){if(d.escape){e();return}if(d.upArrow){i(u=>Math.max(0,u-1));return}if(d.downArrow){i(u=>Math.min(c.length-1,u+1));return}if(d.return){let u=c[o];u&&a(p=>p===u.email?null:u.email);return}}}),c.length===0?sr(Hr,{flexDirection:"column",gap:1,children:[Tt(y,{title:"Known Users",borderColor:"gray",paddingX:2,paddingY:1,children:sr(Hr,{flexDirection:"column",gap:1,children:[Tt(xt,{dimColor:!0,children:"No known users discovered yet."}),Tt(xt,{dimColor:!0,children:"Users are discovered when you connect to shared databases."})]})}),Tt(Hr,{flexWrap:"wrap",columnGap:2,children:Tt(xt,{dimColor:!0,children:"[Esc] Back"})})]}):sr(Hr,{flexDirection:"column",gap:1,children:[Tt(y,{title:"Known Users",paddingX:2,paddingY:1,children:Tt(Hr,{flexDirection:"column",children:c.map((m,d)=>{let u=d===o,p=m.email===s,g=m.users.length;return sr(Hr,{flexDirection:"column",children:[sr(Hr,{children:[Tt(xt,{color:u?"cyan":void 0,children:u?">":" "}),sr(xt,{color:u?"cyan":void 0,children:[" ","[",p?"-":"+","]"," "]}),Tt(xt,{bold:u,children:m.email}),sr(xt,{dimColor:!0,children:[" ","(",g," machine",g!==1?"s":"",")"]})]}),p&&m.users.map((h,f)=>{let w=f===m.users.length-1,S=w?"\u2514\u2500":"\u251C\u2500",E=w?" ":"\u2502 ";return sr(Hr,{flexDirection:"column",marginLeft:4,children:[sr(Hr,{children:[sr(xt,{dimColor:!0,children:[S," "]}),Tt(xt,{children:h.name}),sr(xt,{dimColor:!0,children:[" ","(",h.machine,", ",h.os.split(" ")[0],")"]})]}),sr(Hr,{flexDirection:"column",marginLeft:3,children:[sr(Hr,{children:[Tt(xt,{dimColor:!0,children:E}),Tt(xt,{dimColor:!0,children:"Hash: "}),Tt(xt,{color:"gray",children:fc(h.identityHash)})]}),sr(Hr,{children:[Tt(xt,{dimColor:!0,children:E}),Tt(xt,{dimColor:!0,children:"Key: "}),sr(xt,{color:"gray",children:[h.publicKey.slice(0,20),"..."]})]}),sr(Hr,{children:[Tt(xt,{dimColor:!0,children:E}),Tt(xt,{dimColor:!0,children:"Source: "}),Tt(xt,{children:h.source})]}),sr(Hr,{children:[Tt(xt,{dimColor:!0,children:E}),Tt(xt,{dimColor:!0,children:"Last seen: "}),Tt(xt,{children:Bi(h.lastSeen)})]})]})]},h.identityHash)})]},m.email)})})}),Tt(Hr,{paddingLeft:2,children:sr(xt,{dimColor:!0,children:[c.length," user",c.length!==1?"s":"",", ",l," ",l!==1?"identities":"identity"]})}),sr(Hr,{flexWrap:"wrap",columnGap:2,children:[Tt(xt,{dimColor:!0,children:"[Enter] Expand/Collapse"}),Tt(xt,{dimColor:!0,children:"[Up/Down] Navigate"}),Tt(xt,{dimColor:!0,children:"[Esc] Back"})]})]})}import{useState as hS,useCallback as tg}from"react";import{Box as fi,Text as Rn,useInput as QP}from"ink";import{attempt as ZP}from"@logosdx/utils";import{jsx as sn,jsxs as $n}from"react/jsx-runtime";function rg({params:t}){let{back:e}=I(),{isFocused:r}=A("IdentityInit"),{identity:n,hasIdentity:o,refresh:i}=L(),{showToast:s}=q(),[a,c]=hS(o?"warning":"form"),[l,m]=hS(null),d=tg(()=>{c("form")},[]),u=tg(async g=>{c("processing"),m(null);let[,h]=await ZP(()=>gc({name:g.name,email:g.email,machine:g.machine}));if(h){m(h instanceof Error?h.message:String(h)),c("form"),s({message:"Failed to create identity",variant:"error"});return}await i?.(),s({message:o?"Identity regenerated":"Identity created",variant:"success"}),e()},[i,o,s,e]),p=tg(()=>{e()},[e]);return QP((g,h)=>{if(r&&a==="warning"){if(h.escape){e();return}if(h.return){d();return}}}),a==="warning"?$n(fi,{flexDirection:"column",gap:1,children:[sn(y,{title:"Regenerate Identity",borderColor:"yellow",paddingX:2,paddingY:1,children:$n(fi,{flexDirection:"column",gap:1,children:[sn(Rn,{color:"yellow",children:"This will generate a new keypair."}),$n(fi,{flexDirection:"column",marginTop:1,children:[sn(Rn,{dimColor:!0,children:"Current identity:"}),$n(fi,{marginLeft:2,flexDirection:"column",children:[$n(Rn,{children:[n?.name," ","<",n?.email,">"]}),$n(Rn,{dimColor:!0,children:[n?.machine," (",n?.os.split(" ")[0],")"]})]})]}),$n(fi,{flexDirection:"column",marginTop:1,children:[sn(Rn,{children:"Consequences:"}),$n(fi,{marginLeft:2,flexDirection:"column",children:[$n(Rn,{dimColor:!0,children:[sn(Rn,{color:"yellow",children:"\u2022"})," Existing encrypted configs will not decrypt"]}),$n(Rn,{dimColor:!0,children:[sn(Rn,{color:"yellow",children:"\u2022"})," Team members need your new public key"]}),$n(Rn,{dimColor:!0,children:[sn(Rn,{color:"yellow",children:"\u2022"})," Your identity hash may change"]})]})]})]})}),$n(fi,{flexWrap:"wrap",columnGap:2,children:[sn(Rn,{dimColor:!0,children:"[Enter] Continue"}),sn(Rn,{dimColor:!0,children:"[Esc] Cancel"})]})]}):a==="processing"?sn(fi,{flexDirection:"column",gap:1,children:sn(y,{title:"Regenerate Identity",paddingX:2,paddingY:1,children:sn($,{label:"Generating keypair..."})})}):$n(fi,{flexDirection:"column",gap:1,children:[l&&sn(y,{borderColor:"red",paddingX:2,paddingY:1,children:sn(Rn,{color:"red",children:l})}),sn(_c,{onComplete:u,onCancel:p,isRegeneration:o})]})}import{useState as xS,useEffect as eN}from"react";import{Box as jn,Text as Ge,useInput as tN}from"ink";import{jsx as Xe,jsxs as Cr}from"react/jsx-runtime";function ng({params:t}){let{navigate:e,back:r}=I(),{isFocused:n}=A("RunList"),{activeConfig:o,activeConfigName:i}=eu(),{settings:s}=cr(),a=_n(),[c,l]=xS(null),[m,d]=xS(!0);if(eN(()=>{if(!s||!o){d(!1);return}let p=s.build?.include??[],g=s.build?.exclude??[],h=s.rules??[],f={name:i??"",protected:o.protected??!1,isTest:o.isTest??!1,type:o.type},w=yi(p,g,h,f);l(w),d(!1)},[s,o,i]),tN((p,g)=>{if(n){if(g.escape){r();return}if(o){if(p==="b"||p==="1"){e("run/build");return}if(p==="e"||p==="2"){e("run/exec");return}if(p==="f"||p==="3"){e("run/file");return}if(p==="d"||p==="4"){e("run/dir");return}}}}),!o)return Cr(jn,{flexDirection:"column",gap:1,children:[Xe(y,{title:"Run SQL Files",borderColor:"yellow",paddingX:1,paddingY:1,children:Cr(jn,{flexDirection:"column",gap:1,children:[Xe(Ge,{color:"yellow",children:"No active configuration selected."}),Xe(Ge,{dimColor:!0,children:"Select a configuration first using the config screen."})]})}),Xe(jn,{flexWrap:"wrap",columnGap:2,children:Xe(Ge,{dimColor:!0,children:"[Esc] Back"})})]});if(m)return Xe(jn,{flexDirection:"column",gap:1,children:Xe(y,{title:"Run SQL Files",paddingX:1,paddingY:1,children:Xe($,{label:"Loading settings..."})})});let u=s?.paths?.sql??"sql";return Cr(jn,{flexDirection:"column",gap:1,children:[(a.dryRun||a.force)&&Cr(jn,{flexDirection:"column",children:[a.dryRun&&Xe(Ge,{color:"yellow",bold:!0,children:"DRY RUN MODE - Files will render to tmp/ without executing"}),a.force&&Xe(Ge,{color:"red",bold:!0,children:"FORCE MODE - All files will run regardless of checksum"})]}),Xe(y,{title:"Run SQL Files",paddingX:1,paddingY:1,children:Cr(jn,{flexDirection:"column",gap:1,children:[Cr(jn,{gap:2,children:[Xe(Ge,{children:"Config:"}),Xe(Ge,{bold:!0,color:"cyan",children:i}),Cr(Ge,{dimColor:!0,children:["(",o.type,")"]})]}),Cr(jn,{gap:2,children:[Xe(Ge,{children:"Schema Path:"}),Xe(Ge,{dimColor:!0,children:u})]}),c&&Cr(jn,{flexDirection:"column",marginTop:1,children:[Xe(Ge,{bold:!0,children:"Effective Build Paths:"}),Cr(jn,{flexDirection:"column",marginLeft:2,children:[Cr(Ge,{children:[Xe(Ge,{color:"green",children:"Include: "}),Xe(Ge,{dimColor:!0,children:c.include.length>0?c.include.join(", "):"(none)"})]}),c.exclude.length>0&&Cr(Ge,{children:[Xe(Ge,{color:"red",children:"Exclude: "}),Xe(Ge,{dimColor:!0,children:c.exclude.join(", ")})]})]})]})]})}),Xe(y,{title:"Available Actions",paddingX:1,paddingY:1,children:Cr(jn,{flexDirection:"column",gap:1,children:[Cr(Ge,{children:[Xe(Ge,{color:"cyan",children:"[b]"})," Build - Execute full schema build"]}),Cr(Ge,{children:[Xe(Ge,{color:"cyan",children:"[e]"})," Exec - Pick files to execute"]}),Cr(Ge,{children:[Xe(Ge,{color:"cyan",children:"[f]"})," File - Execute a single file"]}),Cr(Ge,{children:[Xe(Ge,{color:"cyan",children:"[d]"})," Dir - Execute all files in a directory"]})]})}),Cr(jn,{flexWrap:"wrap",columnGap:2,children:[Xe(Ge,{dimColor:!0,children:"[b] Build"}),Xe(Ge,{dimColor:!0,children:"[e] Exec"}),Xe(Ge,{dimColor:!0,children:"[f] File"}),Xe(Ge,{dimColor:!0,children:"[d] Dir"}),Xe(Ge,{dimColor:!0,children:"[Esc] Back"})]})]})}import{useState as hm,useEffect as rN,useCallback as nN}from"react";import{Box as ut,Text as le,useInput as oN}from"ink";import{ProgressBar as iN}from"@inkjs/ui";import{join as sN}from"path";import{attempt as bS}from"@logosdx/utils";import{jsx as re,jsxs as Le}from"react/jsx-runtime";function og({params:t}){let{back:e}=I(),{isFocused:r}=A("RunBuild"),{activeConfig:n,activeConfigName:o,stateManager:i,identity:s}=L(),{settings:a}=cr(),c=_n(),{showToast:l}=q(),{state:m,reset:d}=ai(),[u,p]=hm("loading"),[g,h]=hm([]),[f,w]=hm(""),[S,E]=hm(null);rN(()=>{if(!n||!o||!a)return;let R=!1;return(async()=>{p("loading"),E(null);let C=process.cwd(),b=a.paths?.sql??"sql";w(b);let v=a.build?.include??[],P=a.build?.exclude??[],_=a.rules??[],O={name:o,protected:n.protected??!1,isTest:n.isTest??!1,type:n.type},N=yi(v,P,_,O),B=sN(C,b),[D,F]=await bS(()=>Yn(B));if(R)return;if(F){E(`Failed to discover files: ${F.message}`),p("error");return}let M=bl(D??[],B,N.include,N.exclude);h(M),p("confirm")})(),()=>{R=!0}},[n,o,a]);let T=nN(async()=>{if(!n||!o||!i)return;p("running"),d(g.length);let R=process.cwd(),x=Zt({cryptoIdentity:s??null}),C=await de(n.connection);if(!C.ok){E(`Connection failed: ${C.error}`),p("error");return}let[b,v]=await bS(()=>K(n.connection,o));if(v||!b){E(`Connection failed: ${v?.message??"Unknown error"}`),p("error");return}try{let _={db:b.db,configName:o,identity:x,projectRoot:R,config:n,secrets:i.getAllSecrets(o),globalSecrets:i.getAllGlobalSecrets()},O={force:c.force,dryRun:c.dryRun,abortOnError:!0};await Ys(_,f,O),p("complete")}catch(P){E(P instanceof Error?P.message:String(P)),p("error")}finally{await b.destroy()}},[n,o,i,g,f,c,d]);if(oN((R,x)=>{if(r&&x.escape){if(u==="running"){l({message:"Cannot cancel running build",variant:"warning"});return}e();return}}),!n)return Le(ut,{flexDirection:"column",gap:1,children:[re(y,{title:"Run Build",borderColor:"yellow",paddingX:1,paddingY:1,children:Le(ut,{flexDirection:"column",gap:1,children:[re(le,{color:"yellow",children:"No active configuration selected."}),re(le,{dimColor:!0,children:"Select a configuration first."})]})}),re(ut,{flexWrap:"wrap",columnGap:2,children:re(le,{dimColor:!0,children:"[Esc] Back"})})]});if(u==="loading")return re(ut,{flexDirection:"column",gap:1,children:re(y,{title:"Run Build",paddingX:1,paddingY:1,children:re($,{label:"Discovering SQL files..."})})});if(u==="error")return Le(ut,{flexDirection:"column",gap:1,children:[re(y,{title:"Run Build",borderColor:"red",paddingX:1,paddingY:1,children:Le(ut,{flexDirection:"column",gap:1,children:[re(le,{color:"red",children:"Build Failed"}),re(le,{dimColor:!0,children:S})]})}),re(ut,{flexWrap:"wrap",columnGap:2,children:re(le,{dimColor:!0,children:"[Esc] Back"})})]});if(u==="confirm")return Le(ut,{flexDirection:"column",gap:1,children:[(c.dryRun||c.force)&&Le(ut,{flexDirection:"column",children:[c.dryRun&&re(le,{color:"yellow",bold:!0,children:"DRY RUN MODE - Files will render to tmp/ without executing"}),c.force&&re(le,{color:"red",bold:!0,children:"FORCE MODE - All files will run regardless of checksum"})]}),re(y,{title:"Run Build",paddingX:1,paddingY:1,children:Le(ut,{flexDirection:"column",gap:1,children:[Le(ut,{gap:2,children:[re(le,{children:"Config:"}),re(le,{bold:!0,color:"cyan",children:o})]}),Le(ut,{gap:2,children:[re(le,{children:"Schema Path:"}),re(le,{dimColor:!0,children:f})]}),Le(ut,{gap:2,children:[re(le,{children:"Files to run:"}),re(le,{bold:!0,color:"green",children:g.length})]})]})}),n.protected?re(pt,{focusLabel:"RunBuildConfirm",configName:o??"",action:"run build",onConfirm:T,onCancel:e}):re(ee,{focusLabel:"RunBuildConfirm",message:`Run ${g.length} SQL files on ${o}?`,onConfirm:T,onCancel:e})]});if(u==="running"){let R=m.filesRun+m.filesSkipped+m.filesFailed+m.filesDryRun,x=g.length>0?R/g.length:0;return Le(ut,{flexDirection:"column",gap:1,children:[(c.dryRun||c.force)&&Le(ut,{flexDirection:"column",children:[c.dryRun&&re(le,{color:"yellow",bold:!0,children:"DRY RUN MODE"}),c.force&&re(le,{color:"red",bold:!0,children:"FORCE MODE"})]}),re(y,{title:"Running Build",paddingX:1,paddingY:1,children:Le(ut,{flexDirection:"column",gap:1,children:[Le(ut,{gap:2,children:[re(le,{children:"Config:"}),re(le,{bold:!0,color:"cyan",children:o})]}),m.currentFile&&Le(ut,{gap:2,children:[re(le,{children:"Current:"}),re(le,{dimColor:!0,children:m.currentFile.split("/").pop()})]}),re(ut,{marginTop:1,width:50,children:re(iN,{value:x})}),Le(ut,{gap:3,children:[Le(le,{children:[re(le,{color:"green",children:m.filesRun})," run"]}),Le(le,{children:[re(le,{color:"yellow",children:m.filesSkipped})," skipped"]}),Le(le,{children:[re(le,{color:"red",children:m.filesFailed})," failed"]}),c.dryRun&&Le(le,{children:[re(le,{color:"cyan",children:m.filesDryRun})," rendered"]})]})]})})]})}if(u==="complete"){let R=m.status==="success"?"green":m.status==="failed"?"red":"yellow";return Le(ut,{flexDirection:"column",gap:1,children:[re(y,{title:"Build Complete",borderColor:R,paddingX:1,paddingY:1,children:Le(ut,{flexDirection:"column",gap:1,children:[Le(ut,{gap:2,children:[re(le,{children:"Status:"}),re(le,{bold:!0,color:R,children:m.status?.toUpperCase()})]}),Le(ut,{gap:2,children:[re(le,{children:"Duration:"}),Le(le,{dimColor:!0,children:[(m.durationMs/1e3).toFixed(2),"s"]})]}),Le(ut,{marginTop:1,gap:3,children:[Le(le,{children:[re(le,{color:"green",bold:!0,children:m.filesRun})," ","run"]}),Le(le,{children:[re(le,{color:"yellow",bold:!0,children:m.filesSkipped})," ","skipped"]}),Le(le,{children:[re(le,{color:"red",bold:!0,children:m.filesFailed})," ","failed"]}),m.filesDryRun>0&&Le(le,{children:[re(le,{color:"cyan",bold:!0,children:m.filesDryRun})," ","rendered"]})]}),m.filesFailed>0&&Le(ut,{flexDirection:"column",marginTop:1,children:[re(le,{bold:!0,color:"red",children:"Failed Files:"}),m.results.filter(x=>x.status==="failed").slice(0,5).map((x,C)=>Le(le,{dimColor:!0,children:[x.filepath.split("/").pop(),": ",x.error]},C)),m.results.filter(x=>x.status==="failed").length>5&&Le(le,{dimColor:!0,children:["...and"," ",m.results.filter(x=>x.status==="failed").length-5," ","more"]})]})]})}),re(ut,{flexWrap:"wrap",columnGap:2,children:re(le,{dimColor:!0,children:"[Esc] Back"})})]})}return re(le,{children:"Unknown phase"})}import{useState as xm,useEffect as aN,useCallback as bm}from"react";import{Box as jt,Text as ze,useInput as cN}from"ink";import{ProgressBar as lN}from"@inkjs/ui";import{join as uN,relative as mN}from"path";import{attempt as SS}from"@logosdx/utils";import{jsx as pe,jsxs as Pt}from"react/jsx-runtime";function Sm({onEscape:t,toastMessage:e,showToast:r}){let{isFocused:n}=A("EscapeHandler");return cN((o,i)=>{n&&i.escape&&(e&&r?r({message:e,variant:"warning"}):t&&t())}),null}function ig({params:t}){let{back:e}=I(),{activeConfig:r,activeConfigName:n,stateManager:o,identity:i}=L(),{settings:s}=cr(),a=_n(),{showToast:c}=q(),{state:l,reset:m}=ai(),[d,u]=xm("loading"),[p,g]=xm([]),[h,f]=xm(new Set),[w,S]=xm(null),E=process.cwd();aN(()=>{if(!r||!s)return;let v=!1;return(async()=>{u("loading");let _=s.paths?.sql??"sql",O=uN(E,_),[N,B]=await SS(()=>Yn(O));if(!v){if(B){S(`Failed to discover files: ${B.message}`),u("error");return}g(N??[]),u("picker")}})(),()=>{v=!0}},[r,s,E]);let T=bm(v=>{let P=v.value;f(_=>{let O=new Set(_);return O.has(P)?O.delete(P):O.add(P),O})},[]),R=bm(async()=>{if(!r||!n||!o)return;let v=Array.from(h);u("running"),m(v.length);let P=Zt({cryptoIdentity:i??null}),_=await de(r.connection);if(!_.ok){S(`Connection failed: ${_.error}`),u("error");return}let[O,N]=await SS(()=>K(r.connection,n));if(N||!O){S(`Connection failed: ${N?.message??"Unknown error"}`),u("error");return}try{let D={db:O.db,configName:n,identity:P,projectRoot:E,config:r,secrets:o.getAllSecrets(n),globalSecrets:o.getAllGlobalSecrets()},F={force:a.force,dryRun:a.dryRun};await os(D,v,F),u("complete")}catch(B){S(B instanceof Error?B.message:String(B)),u("error")}finally{await O.destroy()}},[r,n,o,h,a,m,E]),x=bm(()=>{h.size>0?u("confirm"):c({message:"Select at least one file",variant:"warning"})},[h.size,c]),C=bm(()=>{e()},[e]),b=p.map(v=>{let P=mN(E,v),_=h.has(v);return{key:v,label:`[${_?"x":" "}] ${P}`,value:v}});if(!r)return Pt(jt,{flexDirection:"column",gap:1,children:[pe(Sm,{onEscape:e}),pe(y,{title:"Execute Files",borderColor:"yellow",paddingX:1,paddingY:1,children:pe(ze,{color:"yellow",children:"No active configuration selected."})}),pe(jt,{flexWrap:"wrap",columnGap:2,children:pe(ze,{dimColor:!0,children:"[Esc] Back"})})]});if(d==="loading")return pe(jt,{flexDirection:"column",gap:1,children:pe(y,{title:"Execute Files",paddingX:1,paddingY:1,children:pe($,{label:"Discovering SQL files..."})})});if(d==="error")return Pt(jt,{flexDirection:"column",gap:1,children:[pe(Sm,{onEscape:e}),pe(y,{title:"Execute Files",borderColor:"red",paddingX:1,paddingY:1,children:Pt(jt,{flexDirection:"column",gap:1,children:[pe(ze,{color:"red",children:"Error"}),pe(ze,{dimColor:!0,children:w})]})}),pe(jt,{flexWrap:"wrap",columnGap:2,children:pe(ze,{dimColor:!0,children:"[Esc] Back"})})]});if(d==="picker")return Pt(jt,{flexDirection:"column",gap:1,children:[(a.dryRun||a.force)&&Pt(jt,{flexDirection:"column",children:[a.dryRun&&pe(ze,{color:"yellow",bold:!0,children:"DRY RUN MODE"}),a.force&&pe(ze,{color:"red",bold:!0,children:"FORCE MODE"})]}),pe(y,{title:"Select Files",paddingX:1,paddingY:1,children:Pt(jt,{flexDirection:"column",gap:1,children:[Pt(ze,{dimColor:!0,children:["Space to toggle, Enter to confirm (",h.size," selected)"]}),pe(jt,{flexDirection:"column",height:15,children:pe(dt,{focusLabel:"RunExecPicker",items:b,multiSelect:!0,onToggle:T,onSubmit:x,onCancel:C,visibleCount:10})})]})}),Pt(jt,{flexWrap:"wrap",columnGap:2,children:[pe(ze,{dimColor:!0,children:"[Space] Toggle"}),pe(ze,{dimColor:!0,children:"[Enter] Confirm"}),pe(ze,{dimColor:!0,children:"[Esc] Back"})]})]});if(d==="confirm")return Pt(jt,{flexDirection:"column",gap:1,children:[pe(y,{title:"Confirm Execution",paddingX:1,paddingY:1,children:pe(jt,{flexDirection:"column",gap:1,children:Pt(ze,{children:["Files to run: ",pe(ze,{bold:!0,color:"cyan",children:h.size})]})})}),pe(ee,{focusLabel:"RunExecConfirm",message:`Execute ${h.size} files on ${n}?`,onConfirm:R,onCancel:()=>u("picker")})]});if(d==="running"){let v=l.filesRun+l.filesSkipped+l.filesFailed+l.filesDryRun,P=h.size>0?v/h.size:0;return Pt(jt,{flexDirection:"column",gap:1,children:[pe(Sm,{toastMessage:"Cannot cancel running files",showToast:c}),pe(y,{title:"Running Files",paddingX:1,paddingY:1,children:Pt(jt,{flexDirection:"column",gap:1,children:[l.currentFile&&pe(ze,{dimColor:!0,children:l.currentFile.split("/").pop()}),pe(jt,{width:50,children:pe(lN,{value:P})}),Pt(jt,{gap:3,children:[Pt(ze,{children:[pe(ze,{color:"green",children:l.filesRun})," run"]}),Pt(ze,{children:[pe(ze,{color:"yellow",children:l.filesSkipped})," skipped"]}),Pt(ze,{children:[pe(ze,{color:"red",children:l.filesFailed})," failed"]})]})]})})]})}return d==="complete"?Pt(jt,{flexDirection:"column",gap:1,children:[pe(Sm,{onEscape:e}),pe(y,{title:"Execution Complete",borderColor:"green",paddingX:1,paddingY:1,children:Pt(jt,{flexDirection:"column",gap:1,children:[Pt(jt,{gap:2,children:[pe(ze,{children:"Duration:"}),Pt(ze,{dimColor:!0,children:[(l.durationMs/1e3).toFixed(2),"s"]})]}),Pt(jt,{gap:3,children:[Pt(ze,{children:[pe(ze,{color:"green",bold:!0,children:l.filesRun})," run"]}),Pt(ze,{children:[pe(ze,{color:"yellow",bold:!0,children:l.filesSkipped})," skipped"]}),Pt(ze,{children:[pe(ze,{color:"red",bold:!0,children:l.filesFailed})," failed"]})]})]})}),pe(jt,{flexWrap:"wrap",columnGap:2,children:pe(ze,{dimColor:!0,children:"[Esc] Back"})})]}):pe(ze,{children:"Unknown phase"})}import{useState as Cm,useCallback as sg,useEffect as dN}from"react";import{Box as Et,Text as nt,useInput as pN}from"ink";import{join as CS,relative as Wc}from"path";import{attempt as wS}from"@logosdx/utils";import{Fragment as ag,jsx as ne,jsxs as Nt}from"react/jsx-runtime";function Gc({onEscape:t,toastMessage:e,showToast:r}){let{isFocused:n}=A("EscapeHandler");return pN((o,i)=>{n&&i.escape&&(e&&r?r({message:e,variant:"warning"}):t&&t())}),null}function cg({params:t}){let{back:e}=I(),{activeConfig:r,activeConfigName:n,stateManager:o,identity:i}=L(),{settings:s}=cr(),a=_n(),{showToast:c}=q(),{state:l,reset:m}=ai(),[d,u]=Cm("loading"),[p,g]=Cm([]),[h,f]=Cm(t.path??null),[w,S]=Cm(null),E=process.cwd();dN(()=>{if(!r||!s)return;let b=!1;return(async()=>{u("loading");let P=s.paths?.sql??"sql",_=CS(E,P),[O,N]=await wS(()=>Yn(_));if(!b){if(N){S(`Failed to discover files: ${N.message}`),u("error");return}if(g(O??[]),t.path){let B=CS(E,t.path),D=O?.find(F=>F===B||Wc(E,F)===t.path);if(D){f(D),u("confirm");return}}u("picker")}})(),()=>{b=!0}},[r,s,E,t.path]);let T=sg(b=>{f(b.value),u("confirm")},[]),R=sg(()=>{e()},[e]),x=sg(async()=>{if(!r||!n||!o||!h)return;u("running"),m(1);let b=Zt({cryptoIdentity:i??null}),v=await de(r.connection);if(!v.ok){S(`Connection failed: ${v.error}`),u("error");return}let[P,_]=await wS(()=>K(r.connection,n));if(_||!P){S(`Connection failed: ${_?.message??"Unknown error"}`),u("error");return}try{let N={db:P.db,configName:n,identity:b,projectRoot:E,config:r,secrets:o.getAllSecrets(n),globalSecrets:o.getAllGlobalSecrets()},B={force:a.force,dryRun:a.dryRun};await Ws(N,h,B),u("complete")}catch(O){S(O instanceof Error?O.message:String(O)),u("error")}finally{await P.destroy()}},[r,n,o,h,a,m,E]),C=p.map(b=>{let v=Wc(E,b);return{key:b,label:v,value:b}});if(!r)return Nt(Et,{flexDirection:"column",gap:1,children:[ne(Gc,{onEscape:e}),ne(y,{title:"Run File",borderColor:"yellow",paddingX:1,paddingY:1,children:ne(nt,{color:"yellow",children:"No active configuration selected."})}),ne(Et,{flexWrap:"wrap",columnGap:2,children:ne(nt,{dimColor:!0,children:"[Esc] Back"})})]});if(d==="loading")return ne(Et,{flexDirection:"column",gap:1,children:ne(y,{title:"Run File",paddingX:1,paddingY:1,children:ne($,{label:"Discovering SQL files..."})})});if(d==="error")return Nt(Et,{flexDirection:"column",gap:1,children:[ne(Gc,{onEscape:e}),ne(y,{title:"Run File",borderColor:"red",paddingX:1,paddingY:1,children:Nt(Et,{flexDirection:"column",gap:1,children:[ne(nt,{color:"red",children:"Error"}),ne(nt,{dimColor:!0,children:w})]})}),ne(Et,{flexWrap:"wrap",columnGap:2,children:ne(nt,{dimColor:!0,children:"[Esc] Back"})})]});if(d==="picker"){let b=p.length>0,v=s?.paths?.sql??"sql";return Nt(Et,{flexDirection:"column",gap:1,children:[(a.dryRun||a.force)&&Nt(Et,{flexDirection:"column",children:[a.dryRun&&ne(nt,{color:"yellow",bold:!0,children:"DRY RUN MODE"}),a.force&&ne(nt,{color:"red",bold:!0,children:"FORCE MODE"})]}),ne(y,{title:"Select File",paddingX:1,paddingY:1,children:ne(Et,{flexDirection:"column",gap:1,children:b?Nt(ag,{children:[ne(nt,{dimColor:!0,children:"Select a SQL file to execute"}),ne(Et,{flexDirection:"column",height:15,children:ne(vi,{focusLabel:"RunFilePicker",items:C,onSelect:T,onCancel:R,visibleCount:10,searchPlaceholder:"Filter files...",emptyLabel:"No SQL files found"})})]}):Nt(ag,{children:[ne(Gc,{onEscape:R}),Nt(Et,{flexDirection:"column",gap:1,children:[Nt(nt,{color:"yellow",children:["No SQL files found in ",v,"/"]}),ne(nt,{dimColor:!0,children:"Make sure your schema path is configured correctly in settings."})]})]})})}),Nt(Et,{flexWrap:"wrap",columnGap:2,children:[b&&Nt(ag,{children:[ne(nt,{dimColor:!0,children:"[/] Search"}),ne(nt,{dimColor:!0,children:"[Enter] Select"})]}),ne(nt,{dimColor:!0,children:"[Esc] Back"})]})]})}if(d==="confirm"){let b=h?Wc(E,h):"";return Nt(Et,{flexDirection:"column",gap:1,children:[ne(y,{title:"Run File",paddingX:1,paddingY:1,children:Nt(Et,{flexDirection:"column",gap:1,children:[Nt(Et,{gap:2,children:[ne(nt,{children:"File:"}),ne(nt,{bold:!0,color:"cyan",children:b})]}),Nt(Et,{gap:2,children:[ne(nt,{children:"Config:"}),ne(nt,{dimColor:!0,children:n})]})]})}),ne(ee,{focusLabel:"RunFileConfirm",message:`Execute ${b}?`,onConfirm:x,onCancel:()=>u("picker")})]})}if(d==="running"){let b=h?Wc(E,h):"";return Nt(Et,{flexDirection:"column",gap:1,children:[ne(Gc,{toastMessage:"Cannot cancel running file",showToast:c}),ne(y,{title:"Running File",paddingX:1,paddingY:1,children:ne($,{label:`Executing ${b}...`})})]})}if(d==="complete"){let b=l.results[0],v=b?.status==="failed"?"red":"green",P=h?Wc(E,h):"";return Nt(Et,{flexDirection:"column",gap:1,children:[ne(Gc,{onEscape:e}),ne(y,{title:"File Complete",borderColor:v,paddingX:1,paddingY:1,children:Nt(Et,{flexDirection:"column",gap:1,children:[Nt(Et,{gap:2,children:[ne(nt,{children:"File:"}),ne(nt,{dimColor:!0,children:P})]}),Nt(Et,{gap:2,children:[ne(nt,{children:"Status:"}),ne(nt,{bold:!0,color:v,children:b?.status?.toUpperCase()??"COMPLETE"})]}),Nt(Et,{gap:2,children:[ne(nt,{children:"Duration:"}),Nt(nt,{dimColor:!0,children:[(l.durationMs/1e3).toFixed(2),"s"]})]}),b?.status==="skipped"&&Nt(Et,{gap:2,children:[ne(nt,{children:"Reason:"}),ne(nt,{dimColor:!0,children:b.skipReason})]}),b?.error&&Nt(Et,{flexDirection:"column",marginTop:1,children:[ne(nt,{color:"red",children:"Error:"}),ne(nt,{dimColor:!0,children:b.error})]})]})}),ne(Et,{flexWrap:"wrap",columnGap:2,children:ne(nt,{dimColor:!0,children:"[Esc] Back"})})]})}return ne(nt,{children:"Unknown phase"})}import{useState as zi,useEffect as fN,useCallback as Xc,useMemo as TS}from"react";import{Box as Ie,Text as ue,useInput as gN}from"ink";import{ProgressBar as yN}from"@inkjs/ui";import{join as ES,relative as Ji,dirname as zc}from"path";import{attempt as RS}from"@logosdx/utils";import{Fragment as kS,jsx as X,jsxs as Ee}from"react/jsx-runtime";function $a({onEscape:t,toastMessage:e,showToast:r}){let{isFocused:n}=A("EscapeHandler");return gN((o,i)=>{n&&i.escape&&(e&&r?r({message:e,variant:"warning"}):t&&t())}),null}function hN(t,e,r){let n=new Set;n.add(r);for(let o of t){let i=Ji(e,o),a=zc(i);for(;a&&a!==".";){n.add(a);let c=zc(a);if(c===a||c===".")break;a=c}}return Array.from(n).sort()}function lg({params:t}){let{back:e}=I(),{activeConfig:r,activeConfigName:n,stateManager:o,identity:i}=L(),{settings:s}=cr(),a=_n(),{showToast:c}=q(),{state:l,reset:m}=ai(),[d,u]=zi("loading"),[p,g]=zi([]),[h,f]=zi([]),[w,S]=zi(t.path??null),[E,T]=zi([]),[R,x]=zi(0),[C,b]=zi(null),[v,P]=zi(!1),_=process.cwd(),O=s?.paths?.sql??"sql";fN(()=>{if(!r||!s)return;let U=!1;return(async()=>{u("loading");let Q=ES(_,O),[fe,xe]=await RS(()=>Yn(Q));if(U)return;if(xe){b(`Failed to discover files: ${xe.message}`),u("error");return}g(fe??[]);let oe=hN(fe??[],_,O);if(f(oe),t.path&&oe.includes(t.path)){S(t.path);let Je=(fe??[]).filter(Vr=>Ji(_,Vr).startsWith(t.path+"/")||zc(Ji(_,Vr))===t.path);T(Je),x(Je.length),P(!1),u("confirm");return}u("picker")})(),()=>{U=!0}},[r,s,_,O,t.path]);let N=Xc(U=>{S(U.value);let j=p.filter(Q=>Ji(_,Q).startsWith(U.value+"/")||zc(Ji(_,Q))===U.value);T(j),x(j.length),P(!1),u("confirm")},[p,_]),B=Xc(()=>{e()},[e]),D=Xc(async()=>{if(!r||!n||!o||E.length===0)return;u("running"),m(E.length);let U=Zt({cryptoIdentity:i??null}),j=await de(r.connection);if(!j.ok){b(`Connection failed: ${j.error}`),u("error");return}let[Q,fe]=await RS(()=>K(r.connection,n));if(fe||!Q){b(`Connection failed: ${fe?.message??"Unknown error"}`),u("error");return}try{let oe={db:Q.db,configName:n,identity:U,projectRoot:_,config:r,secrets:o.getAllSecrets(n),globalSecrets:o.getAllGlobalSecrets()},Je={force:a.force,dryRun:a.dryRun,abortOnError:!0};await os(oe,E,Je),u("complete")}catch(xe){b(xe instanceof Error?xe.message:String(xe)),u("error")}finally{await Q.destroy()}},[r,n,o,E,a,m,_]),F=TS(()=>h.map(U=>{let j=p.filter(Q=>Ji(_,Q).startsWith(U+"/")||zc(Ji(_,Q))===U).length;return{key:U,label:U,description:`${j} files`,value:U}}),[h,p,_]),M=TS(()=>E.map(U=>Ji(_,U)),[E,_]),H=Xc(U=>{let j=U.map(Q=>ES(_,Q));T(j),x(j.length),P(!0)},[_]),V=Xc(()=>{P(!1)},[]);if(!r)return Ee(Ie,{flexDirection:"column",gap:1,children:[X($a,{onEscape:e}),X(y,{title:"Run Directory",borderColor:"yellow",paddingX:1,paddingY:1,children:X(ue,{color:"yellow",children:"No active configuration selected."})}),X(Ie,{flexWrap:"wrap",columnGap:2,children:X(ue,{dimColor:!0,children:"[Esc] Back"})})]});if(d==="loading")return X(Ie,{flexDirection:"column",gap:1,children:X(y,{title:"Run Directory",paddingX:1,paddingY:1,children:X($,{label:"Discovering directories..."})})});if(d==="error")return Ee(Ie,{flexDirection:"column",gap:1,children:[X($a,{onEscape:e}),X(y,{title:"Run Directory",borderColor:"red",paddingX:1,paddingY:1,children:Ee(Ie,{flexDirection:"column",gap:1,children:[X(ue,{color:"red",children:"Error"}),X(ue,{dimColor:!0,children:C})]})}),X(Ie,{flexWrap:"wrap",columnGap:2,children:X(ue,{dimColor:!0,children:"[Esc] Back"})})]});if(d==="picker"){let U=p.length>0;return Ee(Ie,{flexDirection:"column",gap:1,children:[(a.dryRun||a.force)&&Ee(Ie,{flexDirection:"column",children:[a.dryRun&&X(ue,{color:"yellow",bold:!0,children:"DRY RUN MODE"}),a.force&&X(ue,{color:"red",bold:!0,children:"FORCE MODE"})]}),X(y,{title:"Select Directory",paddingX:1,paddingY:1,children:X(Ie,{flexDirection:"column",gap:1,children:U?Ee(kS,{children:[X(ue,{dimColor:!0,children:"Select a directory to execute all SQL files within"}),X(Ie,{flexDirection:"column",height:15,children:X(dt,{focusLabel:"RunDirPicker",items:F,onSelect:N,onCancel:B,visibleCount:10,emptyLabel:"No directories found"})})]}):Ee(kS,{children:[X($a,{onEscape:B}),Ee(Ie,{flexDirection:"column",gap:1,children:[Ee(ue,{color:"yellow",children:["No SQL files found in ",O,"/"]}),X(ue,{dimColor:!0,children:"Make sure your schema path is configured correctly in settings."})]})]})})}),Ee(Ie,{flexWrap:"wrap",columnGap:2,children:[U&&X(ue,{dimColor:!0,children:"[Enter] Select"}),X(ue,{dimColor:!0,children:"[Esc] Back"})]})]})}if(d==="confirm")return v?Ee(Ie,{flexDirection:"column",gap:1,children:[X(y,{title:"Run Directory",paddingX:1,paddingY:1,children:Ee(Ie,{flexDirection:"column",gap:1,children:[Ee(Ie,{gap:2,children:[X(ue,{children:"Directory:"}),X(ue,{bold:!0,color:"cyan",children:w})]}),Ee(Ie,{gap:2,children:[X(ue,{children:"Files:"}),X(ue,{bold:!0,color:"green",children:R})]}),Ee(Ie,{gap:2,children:[X(ue,{children:"Config:"}),X(ue,{dimColor:!0,children:n})]})]})}),X(ee,{focusLabel:"RunDirConfirm",message:`Execute ${R} files from ${w}?`,onConfirm:D,onCancel:V})]}):R===0?Ee(Ie,{flexDirection:"column",gap:1,children:[X($a,{onEscape:()=>u("picker")}),X(y,{title:`Files in ${w}`,borderColor:"yellow",paddingX:1,paddingY:1,children:X(ue,{color:"yellow",children:"No SQL files found in this directory."})}),X(Ie,{flexWrap:"wrap",columnGap:2,children:X(ue,{dimColor:!0,children:"[Esc] Back"})})]}):Ee(Ie,{flexDirection:"column",gap:1,children:[(a.dryRun||a.force)&&Ee(Ie,{flexDirection:"column",children:[a.dryRun&&X(ue,{color:"yellow",bold:!0,children:"DRY RUN MODE"}),a.force&&X(ue,{color:"red",bold:!0,children:"FORCE MODE"})]}),X(fu,{focusLabel:"RunDirFilePicker",files:M,selected:M,onSelect:H,onCancel:()=>u("picker"),visibleCount:10})]});if(d==="running"){let U=l.filesRun+l.filesSkipped+l.filesFailed+l.filesDryRun,j=R>0?U/R:0;return Ee(Ie,{flexDirection:"column",gap:1,children:[X($a,{toastMessage:"Cannot cancel running directory",showToast:c}),X(y,{title:"Running Directory",paddingX:1,paddingY:1,children:Ee(Ie,{flexDirection:"column",gap:1,children:[l.currentFile&&X(ue,{dimColor:!0,children:l.currentFile.split("/").pop()}),X(Ie,{width:50,children:X(yN,{value:j})}),Ee(Ie,{gap:3,children:[Ee(ue,{children:[X(ue,{color:"green",children:l.filesRun})," run"]}),Ee(ue,{children:[X(ue,{color:"yellow",children:l.filesSkipped})," skipped"]}),Ee(ue,{children:[X(ue,{color:"red",children:l.filesFailed})," failed"]})]})]})})]})}if(d==="complete"){let U=l.status==="success"?"green":l.status==="failed"?"red":"yellow";return Ee(Ie,{flexDirection:"column",gap:1,children:[X($a,{onEscape:e}),X(y,{title:"Directory Complete",borderColor:U,paddingX:1,paddingY:1,children:Ee(Ie,{flexDirection:"column",gap:1,children:[Ee(Ie,{gap:2,children:[X(ue,{children:"Directory:"}),X(ue,{dimColor:!0,children:w})]}),Ee(Ie,{gap:2,children:[X(ue,{children:"Status:"}),X(ue,{bold:!0,color:U,children:l.status?.toUpperCase()??"COMPLETE"})]}),Ee(Ie,{gap:2,children:[X(ue,{children:"Duration:"}),Ee(ue,{dimColor:!0,children:[(l.durationMs/1e3).toFixed(2),"s"]})]}),Ee(Ie,{marginTop:1,gap:3,children:[Ee(ue,{children:[X(ue,{color:"green",bold:!0,children:l.filesRun})," run"]}),Ee(ue,{children:[X(ue,{color:"yellow",bold:!0,children:l.filesSkipped})," skipped"]}),Ee(ue,{children:[X(ue,{color:"red",bold:!0,children:l.filesFailed})," failed"]})]}),l.filesFailed>0&&Ee(Ie,{flexDirection:"column",marginTop:1,children:[X(ue,{bold:!0,color:"red",children:"Failed Files:"}),l.results.filter(j=>j.status==="failed").slice(0,5).map((j,Q)=>Ee(ue,{dimColor:!0,children:[j.filepath.split("/").pop(),": ",j.error]},Q))]})]})}),X(Ie,{flexWrap:"wrap",columnGap:2,children:X(ue,{dimColor:!0,children:"[Esc] Back"})})]})}return X(ue,{children:"Unknown phase"})}import{useState as ug,useEffect as xN}from"react";import{Box as qr,Text as wr,useInput as bN}from"ink";import{attempt as SN}from"@logosdx/utils";import{jsx as bt,jsxs as Hn}from"react/jsx-runtime";function mg({params:t}){let{navigate:e,back:r}=I(),{isFocused:n}=A("DebugOverview"),{activeConfig:o,activeConfigName:i}=L(),[s,a]=ug([]),[c,l]=ug(!0),[m,d]=ug(null);if(xN(()=>{if(!o){l(!1);return}let g=!1;return(async()=>{l(!0),d(null);let f=await de(o.connection);if(!f.ok){g||(d(f.error??"Connection failed"),l(!1));return}let[w,S]=await SN(async()=>{let E=await K(o.connection,i??"__debug__"),R=await Ri(E.db).getTableCounts();return await E.destroy(),R});g||(S?d(S.message):a(w),l(!1))})(),()=>{g=!0}},[o,i]),bN((g,h)=>{if(!n)return;if(h.escape){r();return}let f=parseInt(g)-1;if(f>=0&&f<Ei.length){let w=Ei[f];w&&e("debug/table",{table:w.name})}}),!o)return Hn(qr,{flexDirection:"column",gap:1,children:[bt(y,{title:"DEBUG MODE",borderColor:"red",paddingX:1,paddingY:1,children:Hn(qr,{flexDirection:"column",gap:1,children:[bt(wr,{color:"yellow",children:"No active configuration selected."}),bt(wr,{dimColor:!0,children:"Select a configuration first using the config screen."})]})}),bt(qr,{flexWrap:"wrap",columnGap:2,children:bt(wr,{dimColor:!0,children:"[Esc] Back"})})]});if(c)return bt(qr,{flexDirection:"column",gap:1,children:bt(y,{title:"DEBUG MODE",borderColor:"red",paddingX:1,paddingY:1,children:bt($,{label:"Loading internal tables..."})})});if(m)return Hn(qr,{flexDirection:"column",gap:1,children:[bt(y,{title:"DEBUG MODE",borderColor:"red",paddingX:1,paddingY:1,children:Hn(qr,{flexDirection:"column",gap:1,children:[bt(wr,{color:"red",children:"Connection Error"}),bt(wr,{dimColor:!0,children:m})]})}),bt(qr,{flexWrap:"wrap",columnGap:2,children:bt(wr,{dimColor:!0,children:"[Esc] Back"})})]});let u=g=>s.find(h=>h.table===g)?.count??0,p=s.reduce((g,h)=>g+h.count,0);return Hn(qr,{flexDirection:"column",gap:1,children:[bt(y,{title:"DEBUG MODE",borderColor:"red",paddingX:1,paddingY:1,children:Hn(qr,{flexDirection:"column",gap:1,children:[bt(wr,{color:"yellow",bold:!0,children:"Internal tables. Modifications may corrupt noorm state."}),Hn(qr,{gap:2,marginTop:1,children:[bt(wr,{children:"Config:"}),bt(wr,{bold:!0,color:"cyan",children:i}),Hn(wr,{dimColor:!0,children:["(",o.connection.dialect,")"]})]}),Hn(qr,{gap:2,children:[bt(wr,{children:"Total Rows:"}),bt(wr,{bold:!0,color:"green",children:p})]}),bt(qr,{marginTop:1,flexDirection:"column",children:Ei.map((g,h)=>{let f=u(g.name),w=f>0;return Hn(qr,{gap:2,children:[Hn(wr,{color:w?"cyan":"gray",children:["[",h+1,"]"]}),bt(qr,{width:14,children:bt(wr,{color:w?void 0:"gray",children:g.displayName})}),bt(qr,{width:20,children:bt(wr,{dimColor:!0,children:g.description})}),Hn(wr,{bold:w,color:w?"green":"gray",children:[f," ",f===1?"row":"rows"]})]},g.key)})})]})}),Hn(qr,{flexWrap:"wrap",columnGap:2,children:[bt(wr,{dimColor:!0,children:"[1-5] Select table"}),bt(wr,{dimColor:!0,children:"[Esc] Back"})]})]})}import{useState as $o,useEffect as CN,useMemo as _S,useCallback as Is}from"react";import{Box as qn,Text as Tr,useInput as wN}from"ink";import{attempt as TN}from"@logosdx/utils";import{jsx as ct,jsxs as co}from"react/jsx-runtime";function dg({params:t}){let e=t.table,r=e?aa(e):void 0,{navigate:n,back:o}=I(),{isFocused:i}=A("DebugList"),{activeConfig:s,activeConfigName:a}=L(),{showToast:c}=q(),[l,m]=$o([]),[d,u]=$o([]),[p,g]=$o(!0),[h,f]=$o(null),[w,S]=$o("id"),[E,T]=$o("desc"),[R,x]=$o(null),[C,b]=$o(null),[,v]=$o(""),[P,_]=$o(null);CN(()=>{if(!s||!e){g(!1);return}let j=!1;return(async()=>{g(!0),f(null);let fe=await de(s.connection);if(!fe.ok){j||(f(fe.error??"Connection failed"),g(!1));return}let[xe,oe]=await TN(async()=>{let Je=a??"__debug__",Vr=await K(s.connection,Je),ie=Ri(Vr.db),Ce=ie.getTableColumns(e),Qt=await ie.getTableRows(e,{sortColumn:w,sortDirection:E,limit:500});return b(ie),v(Je),{cols:Ce,data:Qt}});j||(oe?f(oe.message):xe&&(u(xe.cols),m(xe.data)),g(!1))})(),()=>{j=!0}},[s,a,e,w,E]);let O=_S(()=>[...l].sort((j,Q)=>{let fe=j[w],xe=Q[w];if(fe==null&&xe==null)return 0;if(fe==null)return E==="asc"?-1:1;if(xe==null)return E==="asc"?1:-1;let oe=0;return typeof fe=="number"&&typeof xe=="number"?oe=fe-xe:oe=String(fe).localeCompare(String(xe)),E==="asc"?oe:-oe}),[l,w,E]),N=_S(()=>O.map(j=>{let Q=j.id,fe=[`#${Q}`];j.name&&fe.push(String(j.name)),j.status&&fe.push(String(j.status)),j.config_name&&fe.push(`config=${j.config_name}`),j.email&&fe.push(String(j.email)),j.cli_version&&fe.push(`v${j.cli_version}`);let xe=[];return j.executed_at&&xe.push(EN(j.executed_at)),j.duration_ms&&xe.push(`${j.duration_ms}ms`),j.filepath&&xe.push(RN(String(j.filepath),40)),j.locked_by&&xe.push(`by ${j.locked_by}`),{key:String(Q),label:fe.join(" "),description:xe.join(" | "),value:j}}),[O]),B=Is(j=>{let Q=j.value.id;n("debug/table/detail",{table:e,rowId:Q})},[n,e]),D=Is(j=>{_(j.value.id)},[]),F=Is(()=>{let Q=(d.indexOf(w)+1)%d.length,fe=d[Q];fe&&S(fe)},[d,w]),M=Is(()=>{T(j=>j==="asc"?"desc":"asc")},[]),H=Is(()=>{P!=null&&x({mode:"single",ids:[P]})},[P]),V=Is(()=>{let j=O.map(Q=>Q.id);j.length!==0&&x({mode:"bulk",ids:j})},[O]),U=Is(async()=>{if(!R||!C||!e)return;let{mode:j,ids:Q}=R;if(x(null),j==="single"){let fe=Q[0];if(fe===void 0)return;await C.deleteRowById(e,fe)?(m(oe=>oe.filter(Je=>Je.id!==fe)),c({message:`Deleted row #${fe}`,variant:"success"})):c({message:"Delete failed",variant:"error"})}else{let fe=await C.deleteRowsByIds(e,Q);if(fe>0){let xe=new Set(Q);m(oe=>oe.filter(Je=>!xe.has(Je.id))),c({message:`Deleted ${fe} rows`,variant:"success"})}else c({message:"Delete failed",variant:"error"})}},[R,C,e,c]);if(wN((j,Q)=>{if(!(!i||R)){if(Q.escape){o();return}if(j==="s"){F();return}if(j==="S"){M();return}if(j==="d"){H();return}if(j==="D"){V();return}}}),!e||!r)return co(qn,{flexDirection:"column",gap:1,children:[ct(y,{title:"DEBUG MODE",borderColor:"red",paddingX:1,paddingY:1,children:ct(Tr,{color:"red",children:"No table specified"})}),ct(qn,{flexWrap:"wrap",columnGap:2,children:ct(Tr,{dimColor:!0,children:"[Esc] Back"})})]});if(!s)return co(qn,{flexDirection:"column",gap:1,children:[ct(y,{title:"DEBUG MODE",borderColor:"red",paddingX:1,paddingY:1,children:ct(Tr,{color:"yellow",children:"No active configuration selected."})}),ct(qn,{flexWrap:"wrap",columnGap:2,children:ct(Tr,{dimColor:!0,children:"[Esc] Back"})})]});if(p)return ct(qn,{flexDirection:"column",gap:1,children:ct(y,{title:`DEBUG: ${r.displayName}`,borderColor:"red",paddingX:1,paddingY:1,children:ct($,{label:`Loading ${e}...`})})});if(h)return co(qn,{flexDirection:"column",gap:1,children:[ct(y,{title:`DEBUG: ${r.displayName}`,borderColor:"red",paddingX:1,paddingY:1,children:co(qn,{flexDirection:"column",gap:1,children:[ct(Tr,{color:"red",children:"Error"}),ct(Tr,{dimColor:!0,children:h})]})}),ct(qn,{flexWrap:"wrap",columnGap:2,children:ct(Tr,{dimColor:!0,children:"[Esc] Back"})})]});if(R){let j=R.mode==="single"?`Delete row #${R.ids[0]} from ${e}?`:`Delete ${R.ids.length} rows from ${e}?`;return co(qn,{flexDirection:"column",gap:1,children:[ct(y,{title:`DEBUG: ${r.displayName}`,borderColor:"red",paddingX:1,paddingY:1,children:co(Tr,{dimColor:!0,children:[l.length," rows | Sorted by: ",w," ",E==="asc"?"\u2191":"\u2193"]})}),ct(ee,{title:"Delete Rows",message:j,variant:"danger",defaultChoice:"cancel",onConfirm:U,onCancel:()=>x(null)})]})}return co(qn,{flexDirection:"column",gap:1,children:[ct(y,{title:`DEBUG: ${r.displayName}`,borderColor:"red",paddingX:1,paddingY:1,children:co(qn,{flexDirection:"column",gap:1,children:[co(qn,{gap:2,children:[co(Tr,{children:[l.length," rows"]}),ct(Tr,{dimColor:!0,children:"|"}),co(Tr,{children:["Sorted by: ",ct(Tr,{bold:!0,color:"cyan",children:w})," ",E==="asc"?"\u2191":"\u2193"]})]}),ct(vi,{items:N,onSelect:B,onHighlight:D,searchPlaceholder:`Filter ${r.displayName.toLowerCase()}...`,emptyLabel:"No rows in table",noResultsLabel:"No matching rows",isFocused:i,numberNav:!0,visibleCount:10})]})}),co(qn,{flexWrap:"wrap",columnGap:2,children:[ct(Tr,{dimColor:!0,children:"[s] Sort column"}),ct(Tr,{dimColor:!0,children:"[S] Direction"}),ct(Tr,{dimColor:!0,children:"[d] Delete"}),ct(Tr,{dimColor:!0,children:"[D] Delete all"}),ct(Tr,{dimColor:!0,children:"[Enter] Detail"}),ct(Tr,{dimColor:!0,children:"[Esc] Back"})]})]})}function EN(t){if(!t)return"";if(t instanceof Date)return t.toISOString().replace("T"," ").slice(0,19);if(typeof t=="string"){let e=new Date(t);if(!isNaN(e.getTime()))return e.toISOString().replace("T"," ").slice(0,19)}return String(t)}function RN(t,e){return t.length<=e?t:t.slice(0,e-3)+"..."}import{useState as ja,useEffect as kN,useCallback as _N}from"react";import{Box as Er,Text as Kr,useInput as vN}from"ink";import{attempt as DN}from"@logosdx/utils";import{jsx as He,jsxs as lo}from"react/jsx-runtime";function pg({params:t}){let e=t.table,r=t.rowId,n=e?aa(e):void 0,{back:o}=I(),{isFocused:i}=A("DebugDetail"),{activeConfig:s,activeConfigName:a}=L(),{showToast:c}=q(),[l,m]=ja(null),[d,u]=ja([]),[p,g]=ja(!0),[h,f]=ja(null),[w,S]=ja(!1),[E,T]=ja(null);kN(()=>{if(!s||!e||r==null){g(!1);return}let x=!1;return(async()=>{g(!0),f(null);let b=await de(s.connection);if(!b.ok){x||(f(b.error??"Connection failed"),g(!1));return}let[v,P]=await DN(async()=>{let _=await K(s.connection,a??"__debug__"),O=Ri(_.db),N=O.getTableColumns(e),B=await O.getRowById(e,r);return T(O),{cols:N,data:B}});x||(P?f(P.message):v&&(u(v.cols),m(v.data)),g(!1))})(),()=>{x=!0}},[s,a,e,r]);let R=_N(async()=>{if(!E||!e||r==null)return;S(!1),await E.deleteRowById(e,r)?(c({message:`Deleted row #${r}`,variant:"success"}),o()):c({message:"Delete failed",variant:"error"})},[E,e,r,c,o]);return vN((x,C)=>{if(!(!i||w)){if(C.escape){o();return}if(x==="d"){S(!0);return}}}),!e||!n||r==null?lo(Er,{flexDirection:"column",gap:1,children:[He(y,{title:"DEBUG MODE",borderColor:"red",paddingX:1,paddingY:1,children:He(Kr,{color:"red",children:"No table or row specified"})}),He(Er,{flexWrap:"wrap",columnGap:2,children:He(Kr,{dimColor:!0,children:"[Esc] Back"})})]}):s?p?He(Er,{flexDirection:"column",gap:1,children:He(y,{title:`DEBUG: Row #${r}`,borderColor:"red",paddingX:1,paddingY:1,children:He($,{label:"Loading row..."})})}):h?lo(Er,{flexDirection:"column",gap:1,children:[He(y,{title:`DEBUG: Row #${r}`,borderColor:"red",paddingX:1,paddingY:1,children:lo(Er,{flexDirection:"column",gap:1,children:[He(Kr,{color:"red",children:"Error"}),He(Kr,{dimColor:!0,children:h})]})}),He(Er,{flexWrap:"wrap",columnGap:2,children:He(Kr,{dimColor:!0,children:"[Esc] Back"})})]}):l?w?lo(Er,{flexDirection:"column",gap:1,children:[He(y,{title:`DEBUG: Row #${r}`,borderColor:"red",paddingX:1,paddingY:1,children:lo(Kr,{dimColor:!0,children:[n.displayName," row"]})}),He(ee,{title:"Delete Row",message:`Delete row #${r} from ${e}?`,variant:"danger",defaultChoice:"cancel",onConfirm:R,onCancel:()=>S(!1)})]}):lo(Er,{flexDirection:"column",gap:1,children:[He(y,{title:`DEBUG: Row #${r}`,borderColor:"red",paddingX:1,paddingY:1,children:lo(Er,{flexDirection:"column",gap:1,children:[lo(Er,{gap:2,children:[He(Kr,{dimColor:!0,children:"Table:"}),He(Kr,{bold:!0,children:e})]}),He(Er,{flexDirection:"column",marginTop:1,children:d.map(x=>{let C=l[x];return lo(Er,{gap:2,children:[He(Er,{width:20,children:He(Kr,{bold:!0,color:"cyan",children:x})}),He(Kr,{children:PN(C)})]},x)})})]})}),lo(Er,{flexWrap:"wrap",columnGap:2,children:[He(Kr,{dimColor:!0,children:"[d] Delete"}),He(Kr,{dimColor:!0,children:"[Esc] Back"})]})]}):lo(Er,{flexDirection:"column",gap:1,children:[He(y,{title:`DEBUG: Row #${r}`,borderColor:"red",paddingX:1,paddingY:1,children:He(Kr,{color:"yellow",children:"Row not found"})}),He(Er,{flexWrap:"wrap",columnGap:2,children:He(Kr,{dimColor:!0,children:"[Esc] Back"})})]}):lo(Er,{flexDirection:"column",gap:1,children:[He(y,{title:"DEBUG MODE",borderColor:"red",paddingX:1,paddingY:1,children:He(Kr,{color:"yellow",children:"No active configuration selected."})}),He(Er,{flexWrap:"wrap",columnGap:2,children:He(Kr,{dimColor:!0,children:"[Esc] Back"})})]})}function PN(t){if(t==null)return"<null>";if(t instanceof Date)return t.toISOString().replace("T"," ").slice(0,19);if(typeof t=="string"){if(/^\d{4}-\d{2}-\d{2}/.test(t)){let e=new Date(t);if(!isNaN(e.getTime()))return e.toISOString().replace("T"," ").slice(0,19)}return t.length>80?t.slice(0,77)+"...":t||"<empty>"}return typeof t=="object"?JSON.stringify(t):String(t)}import{jsx as Ha}from"react/jsx-runtime";var vS={home:{component:Hx,label:"Home"},init:{component:cp,label:"Initialize"},config:{component:up,label:"Configurations"},"config/add":{component:dp,label:"Add Config"},"config/edit":{component:fp,label:"Edit Config"},"config/rm":{component:gp,label:"Delete Config"},"config/cp":{component:xp,label:"Copy Config"},"config/use":{component:Sp,label:"Use Config"},"config/validate":{component:wp,label:"Validate Config"},"config/export":{component:Ep,label:"Export Config"},"config/import":{component:Rp,label:"Import Config"},change:{component:kp,label:"Changes"},"change/add":{component:Pp,label:"Add Change"},"change/edit":{component:Fp,label:"Edit Change"},"change/rm":{component:Bp,label:"Delete Change"},"change/run":{component:Ip,label:"Run Change"},"change/revert":{component:Op,label:"Revert Change"},"change/next":{component:Mp,label:"Apply Next"},"change/ff":{component:jp,label:"Fast-Forward"},"change/rewind":{component:qp,label:"Rewind"},"change/history":{component:Kp,label:"Execution History"},"change/history/detail":{component:Vp,label:"File Executions"},db:{component:Yp,label:"Databases"},"db/create":{component:Gp,label:"Create Database"},"db/destroy":{component:zp,label:"Destroy Database"},"db/truncate":{component:Jp,label:"Wipe Data"},"db/teardown":{component:Zp,label:"Schema Teardown"},"db/explore":{component:Gu,label:"Explore Database"},"db/explore/tables":{component:Ao,label:"Tables"},"db/explore/tables/detail":{component:ji,label:"Table Detail"},"db/explore/views":{component:Ao,label:"Views"},"db/explore/views/detail":{component:ji,label:"View Detail"},"db/explore/procedures":{component:Ao,label:"Procedures"},"db/explore/procedures/detail":{component:ji,label:"Procedure Detail"},"db/explore/functions":{component:Ao,label:"Functions"},"db/explore/functions/detail":{component:ji,label:"Function Detail"},"db/explore/types":{component:Ao,label:"Types"},"db/explore/types/detail":{component:ji,label:"Type Detail"},"db/explore/indexes":{component:Ao,label:"Indexes"},"db/explore/fks":{component:Ao,label:"Foreign Keys"},"db/sql":{component:lf,label:"SQL Terminal"},"db/sql/history":{component:uf,label:"SQL History"},"db/sql/clear":{component:mf,label:"Clear History"},settings:{component:pf,label:"Settings"},"settings/init":{component:ff,label:"Initialize Settings"},"settings/build":{component:yf,label:"Build Settings"},"settings/paths":{component:hf,label:"Path Settings"},"settings/strict":{component:xf,label:"Strict Mode"},"settings/logging":{component:bf,label:"Logging Settings"},"settings/stages":{component:wf,label:"Stages"},"settings/stages/add":{component:Qu,label:"Add Stage"},"settings/stages/edit":{component:Qu,label:"Edit Stage"},"settings/rules":{component:_f,label:"Rules"},"settings/rules/add":{component:rm,label:"Add Rule"},"settings/rules/edit":{component:rm,label:"Edit Rule"},"settings/secrets":{component:Ff,label:"Universal Secrets"},"settings/secrets/add":{component:om,label:"Add Universal Secret"},"settings/secrets/edit":{component:om,label:"Edit Universal Secret"},"settings/secrets/rm":{component:Lf,label:"Remove Universal Secret"},"settings/stages/secrets":{component:Of,label:"Stage Secrets"},"settings/stages/secrets/add":{component:am,label:"Add Stage Secret"},"settings/stages/secrets/edit":{component:am,label:"Edit Stage Secret"},"settings/stages/secrets/rm":{component:Mf,label:"Remove Stage Secret"},secret:{component:$f,label:"Secrets"},"secret/set":{component:jf,label:"Set Secret"},"secret/rm":{component:Hf,label:"Delete Secret"},lock:{component:qf,label:"Lock Management"},"lock/status":{component:Kf,label:"Lock Status"},"lock/acquire":{component:Uf,label:"Acquire Lock"},"lock/release":{component:Wf,label:"Release Lock"},"lock/force":{component:zf,label:"Force Release"},identity:{component:Jf,label:"Identity"},"identity/edit":{component:Qf,label:"Edit Identity"},"identity/init":{component:rg,label:"Regenerate Identity"},"identity/export":{component:Zf,label:"Export Public Key"},"identity/list":{component:eg,label:"Known Users"},run:{component:ng,label:"Run SQL"},"run/build":{component:og,label:"Run Build"},"run/exec":{component:ig,label:"Execute Files"},"run/file":{component:cg,label:"Run File"},"run/dir":{component:lg,label:"Run Directory"},debug:{component:mg,label:"Debug"},"debug/table":{component:dg,label:"Debug Table"},"debug/table/detail":{component:pg,label:"Debug Row"}};function LN(){return Ha(FN,{children:Ha(BN,{dimColor:!0,children:"Loading..."})})}function fg(t){let e=vS[t];if(e?.label)return e.label;let r=t.split("/"),n=r[r.length-1]??t;return n.charAt(0).toUpperCase()+n.slice(1)}function DS(){let{route:t,params:e}=I(),r=vS[t];if(!r)return Ha(qx,{params:e});let n=r.component;return Ha(NN,{fallback:Ha(LN,{}),children:Ha(n,{params:e})})}import{Fragment as NS,jsx as me,jsxs as Kn}from"react/jsx-runtime";function AN({onClose:t}){let e=_n(),{isFocused:r}=A("HelpScreen");ON(()=>{r&&t()});let n=({k:o,desc:i})=>Kn(Nr,{children:[me(Nr,{color:"yellow",children:o.padEnd(12)}),me(Nr,{dimColor:!0,children:i})]});return Kn(an,{flexDirection:"column",children:[me(an,{borderStyle:"single",borderTop:!0,borderBottom:!1,borderLeft:!1,borderRight:!1,borderColor:"gray"}),Kn(an,{paddingX:1,paddingTop:1,children:[Kn(an,{flexDirection:"column",width:30,children:[me(n,{k:"esc",desc:"go back / cancel"}),me(n,{k:"enter",desc:"confirm / select"}),me(n,{k:"tab",desc:"next field"}),me(n,{k:"\u2191 / \u2193",desc:"navigate items"})]}),Kn(an,{flexDirection:"column",width:34,children:[me(n,{k:"D",desc:`toggle dry-run${e.dryRun?" (active)":""}`}),me(n,{k:"F",desc:`toggle force${e.force?" (active)":""}`}),me(n,{k:"shift + L",desc:"toggle log viewer"}),me(n,{k:"shift + Q",desc:"open SQL terminal"})]}),Kn(an,{flexDirection:"column",width:28,children:[me(n,{k:"?",desc:"show this help"}),me(n,{k:"ctrl + c",desc:"quit application"})]})]})]})}function MN(){let{route:t,history:e}=I(),r=e.slice(-2).map(n=>fg(n.route));return r.push(fg(t)),me(an,{children:r.map((n,o)=>Kn(Nr,{children:[o>0&&me(Nr,{dimColor:!0,children:" \u203A "}),me(Nr,{color:o===r.length-1?"white":"gray",children:n})]},o))})}function $N(){let{projectName:t}=lx(),{activeConfigName:e}=eu(),{connectionStatus:r}=ax(),{lockStatus:n}=cx(),o=_n(),i=e??"none",s=r==="connected",a=n.status==="free";return Kn(an,{paddingX:1,width:"100%",children:[me(an,{marginRight:1,children:me(Nr,{bold:!0,color:"cyan",children:t})}),Kn(an,{children:[me(Nr,{dimColor:!0,children:" \u2502 "}),me(Nr,{dimColor:!0,children:i}),me(Nr,{dimColor:!0,children:" \u2502 "}),me(Nr,{color:s?"green":"gray",children:s?"\u25CF":"\u25CB"}),me(Nr,{dimColor:!0,children:" \u2502 "}),me(Nr,{color:a?"green":"yellow",children:a?"\u{1F513}":"\u{1F512}"}),o.dryRun&&Kn(NS,{children:[me(Nr,{dimColor:!0,children:" \u2502 "}),me(Nr,{color:"yellow",bold:!0,children:"DRY"})]}),o.force&&Kn(NS,{children:[me(Nr,{dimColor:!0,children:" \u2502 "}),me(Nr,{color:"red",bold:!0,children:"FORCE"})]})]}),me(IN,{}),me(an,{justifyContent:"flex-end",children:me(mu,{})})]})}function jN(){let[t,e]=PS(!1),[r,n]=PS(!1),{toggleDryRun:o}=ux(),{toggleForce:i}=mx(),{navigate:s}=I(),a=Jc(()=>{e(!0)},[]),c=Jc(()=>{e(!1)},[]),l=Jc(()=>{n(u=>!u)},[]),m=Jc(()=>{s("db/sql")},[s]),d=Jc(()=>{s("debug")},[s]);return Kn(px,{onHelp:a,onToggleDryRun:o,onToggleForce:i,onToggleLogViewer:l,onOpenSqlTerminal:m,onDebugMode:d,children:[Kn(an,{flexDirection:"column",minHeight:20,children:[me(an,{borderStyle:"single",borderBottom:!0,borderTop:!1,borderLeft:!1,borderRight:!1,borderColor:"gray",paddingX:1,children:me(MN,{})}),me(an,{flexDirection:"column",flexGrow:1,children:me(DS,{})}),me(an,{borderStyle:"single",borderTop:!0,borderBottom:!1,borderLeft:!1,borderRight:!1,borderColor:"gray",children:me($N,{})})]}),t&&me(AN,{onClose:c}),r&&me(_u,{onClose:l})]})}function FS({initialRoute:t="home",initialParams:e={},projectRoot:r,autoLoad:n=!0}){let o=r??process.cwd();return me(Fh,{projectRoot:o,children:me(sx,{projectRoot:r,autoLoad:n,children:me(uu,{children:me(ay,{children:me(Dh,{initialRoute:t,initialParams:e,children:me(jN,{})})})})})})}import{createWriteStream as GF}from"fs";import{join as XF}from"path";import{attempt as WS,attemptSync as zF}from"@logosdx/utils";import{mkdir as fZ}from"fs/promises";import{createWriteStream as yZ}from"fs";import{dirname as xZ}from"path";import{attempt as qa}from"@logosdx/utils";import{merge as Os,clone as $S}from"@logosdx/utils";import{z as ge}from"zod";var Qc=ge.enum(["postgres","mysql","sqlite","mssql"]),BS=ge.string().min(1,"Config name is required").regex(/^[a-z0-9_-]+$/i,"Config name must contain only letters, numbers, hyphens, and underscores"),LS=ge.number().int().min(1,"Port must be at least 1").max(65535,"Port must be at most 65535"),IS=ge.object({min:ge.number().int().min(0).optional(),max:ge.number().int().min(1).optional()}),OS=ge.union([ge.boolean(),ge.object({rejectUnauthorized:ge.boolean().optional(),ca:ge.string().optional(),cert:ge.string().optional(),key:ge.string().optional()})]),AS=ge.object({dialect:Qc,host:ge.string().optional(),port:LS.optional(),database:ge.string().min(1,"Database name is required"),filename:ge.string().optional(),user:ge.string().optional(),password:ge.string().optional(),ssl:OS.optional(),pool:IS.optional()}).refine(t=>t.dialect==="sqlite"||t.host,{message:"Host is required for non-SQLite databases",path:["host"]}),HN=ge.object({sql:ge.string().min(1,"SQL path is required"),changes:ge.string().min(1,"Changes path is required")}),gg=ge.object({name:BS,type:ge.enum(["local","remote"]).default("local"),isTest:ge.boolean().default(!1),protected:ge.boolean().default(!1),connection:AS,paths:HN,identity:ge.string().optional()}),qN=ge.object({dialect:Qc.optional(),host:ge.string().optional(),port:LS.optional(),database:ge.string().optional(),filename:ge.string().optional(),user:ge.string().optional(),password:ge.string().optional(),ssl:OS.optional(),pool:IS.optional()}),KN=ge.object({sql:ge.string().optional(),changes:ge.string().optional()}),VN=ge.object({name:ge.string().regex(/^[a-z0-9_-]+$/i).optional(),type:ge.enum(["local","remote"]).optional(),isTest:ge.boolean().optional(),protected:ge.boolean().optional(),connection:qN.optional(),paths:KN.optional(),identity:ge.string().optional()}),UN=gg.extend({name:BS.optional()}),wm=class extends Error{constructor(r,n,o){super(r);this.field=n;this.issues=o;this.name="ConfigValidationError"}};function Tm(t){let e=gg.safeParse(t);if(!e.success){let r=e.error.issues[0];throw new wm(r?.message??"Validation failed",r?.path.join(".")||"unknown",e.error.issues)}return e.data}import{makeNestedConfig as YN}from"@logosdx/utils";var WN=new Set(["NOORM_CONFIG","NOORM_YES","NOORM_JSON"]),GN=["postgres","mysql","sqlite","mssql"],{allConfigs:XN,getConfig:MS}=YN(process.env,{filter:t=>t.startsWith("NOORM_")&&!WN.has(t),stripPrefix:"NOORM_",forceAllCapToLower:!0,memoizeOpts:!1,skipConversion:t=>t.toLowerCase().includes("password")});function yg(){let t=XN();if(t.connection?.dialect&&!Qc.safeParse(t.connection.dialect).success)throw new Error(`Invalid NOORM_CONNECTION_DIALECT: must be one of ${GN.join(", ")}`);return t}var Em=class{#t;constructor(e){this.#t=e}getStage(e){return this.#t.getStage(e)??null}findStageForConfig(e){return this.#t.getStage(e)??null}},jS={type:"local",isTest:!1,protected:!1,paths:{sql:"./sql",changes:"./changes"},connection:{host:"localhost",pool:{min:0,max:10}},log:{level:"info"}};function hg(t,e={}){let r=e.name??Oh()??t.getActiveConfigName();if(!r){let a=yg();return a.connection?.dialect&&a.connection?.database?zN(a,e.flags,e.stage,e.settings):null}let n=t.getConfig(r);if(!n)throw new Error(`Config "${r}" not found`);let o=HS(r,e.stage,e.settings),i=yg(),s=$S(jS);return o&&(s=Os(s,o)),s=Os(s,n),s=Os(s,i),s=Os(s,e.flags??{}),Tm(s)}function HS(t,e,r){return r?e?r.getStage(e)?.defaults??null:r.findStageForConfig(t)?.defaults??null:null}function zN(t,e,r,n){let o=t.name??e?.name??"__env__",i=HS(o,r,n),s=$S(jS);return i&&(s=Os(s,i)),s=Os(s,t),s=Os(s,e??{}),s.name||(s.name="__env__"),Tm(s)}import Vn from"path";import{sql as vm}from"kysely";var Rm=class extends Error{constructor(r){super(`Config "${r}" does not have isTest: true`);this.configName=r}name="RequireTestError"},km=class extends Error{constructor(r,n){super(`Cannot ${n} on protected config "${r}"`);this.configName=r;this.operation=n}name="ProtectedConfigError"};function qS(t,e){if(e.requireTest&&!t.isTest)throw new Rm(t.name)}function _m(t,e,r){if(t.protected&&!r.allowProtected)throw new km(t.name,e)}var Zc=class{#t=null;#e;#o;#r;#i;#n;#l=null;constructor(e,r,n,o,i){this.#e=e,this.#o=r,this.#r=n,this.#i=o,this.#n=i}get config(){return this.#e}get settings(){return this.#o}get identity(){return this.#r}get dialect(){return this.#e.connection.dialect}get connected(){return this.#t!==null}get observer(){return k}get kysely(){if(!this.#t)throw new Error("Not connected. Call connect() first.");return this.#t.db}async connect(){this.#t||(this.#t=await K(this.#e.connection,this.#e.name))}async disconnect(){this.#t&&(await this.#t.destroy(),this.#t=null,this.#l=null)}async query(e,r){let n=this.kysely;return(await vm.raw(e).execute(n)).rows??[]}async execute(e,r){let n=this.kysely,o=await vm.raw(e).execute(n);return{rowsAffected:o.numAffectedRows?Number(o.numAffectedRows):void 0}}async transaction(e){return this.kysely.transaction().execute(async n=>e({async query(i,s){return(await vm.raw(i).execute(n)).rows??[]},async execute(i,s){let a=await vm.raw(i).execute(n);return{rowsAffected:a.numAffectedRows?Number(a.numAffectedRows):void 0}}}))}async listTables(){return Gr(this.kysely,this.dialect,"tables")}async describeTable(e,r){return cc(this.kysely,this.dialect,"tables",e,r)}async overview(){return ac(this.kysely,this.dialect)}async truncate(){return _m(this.#e,"truncate",this.#i),oa(this.kysely,this.dialect)}async teardown(){return _m(this.#e,"teardown",this.#i),us(this.kysely,this.dialect,{configName:this.#e.name,executedBy:Ft(this.#r)})}async build(e){let r=this.#s(),n=Vn.join(this.#n,this.#e.paths.sql);return Ys(r,n,{force:e?.force})}async reset(){_m(this.#e,"reset",this.#i),await this.teardown(),await this.build({force:!0})}async runFile(e,r){let n=this.#s(),o=Vn.isAbsolute(e)?e:Vn.join(this.#n,e);return Ws(n,o,r)}async runFiles(e,r){let n=this.#s(),o=e.map(i=>Vn.isAbsolute(i)?i:Vn.join(this.#n,i));return os(n,o,r)}async runDir(e,r){let n=this.#s(),o=Vn.isAbsolute(e)?e:Vn.join(this.#n,e);return kl(n,o,r)}async applyChange(e,r){return this.#c().run(e,r)}async revertChange(e,r){return this.#c().revert(e,r)}async fastForward(){return this.#c().ff()}async getChangeStatus(){return this.#c().list()}async getPendingChanges(){return(await this.getChangeStatus()).filter(r=>!r.orphaned&&(r.status==="pending"||r.status==="reverted"))}getSecret(e){return Ur(this.#n).getSecret(this.#e.name,e)??void 0}async acquireLock(e){let r=mt(),n=Ft(this.#r);return r.acquire(this.kysely,this.#e.name,n,{...e,dialect:this.#e.connection.dialect})}async releaseLock(){let e=mt(),r=Ft(this.#r);await e.release(this.kysely,this.#e.name,r)}async getLockStatus(){return mt().status(this.kysely,this.#e.name,this.#e.connection.dialect)}async withLock(e,r){let n=mt(),o=Ft(this.#r);return n.withLock(this.kysely,this.#e.name,o,e,{...r,dialect:this.#e.connection.dialect})}async forceReleaseLock(){return mt().forceRelease(this.kysely,this.#e.name)}async renderTemplate(e){let r=Vn.isAbsolute(e)?e:Vn.join(this.#n,e),n=Ur(this.#n);return gi(r,{projectRoot:this.#n,config:this.#e,secrets:n.getAllSecrets(this.#e.name),globalSecrets:n.getAllGlobalSecrets()})}async getHistory(e){return this.#c().getHistory(void 0,e)}async computeChecksum(e){let r=Vn.isAbsolute(e)?e:Vn.join(this.#n,e);return cn(r)}async testConnection(){return de(this.#e.connection)}#s(){let e=Ur(this.#n);return{db:this.kysely,configName:this.#e.name,identity:this.#r,projectRoot:this.#n,config:this.#e,secrets:e.getAllSecrets(this.#e.name),globalSecrets:e.getAllGlobalSecrets()}}#a(){let e=Ur(this.#n);return{db:this.kysely,configName:this.#e.name,identity:this.#r,projectRoot:this.#n,changesDir:Vn.join(this.#n,this.#e.paths.changes),sqlDir:Vn.join(this.#n,this.#e.paths.sql),config:this.#e,secrets:e.getAllSecrets(this.#e.name),globalSecrets:e.getAllGlobalSecrets()}}#c(){return this.#l||(this.#l=new Gn(this.#a())),this.#l}};function JN(t){return new Em(t)}async function KS(t={}){let e=t.projectRoot??process.cwd();await Xa(e);let r=Ur(e),n=hi(e);await n.load();let o=n.settings,i=hg(r,{name:t.config,stage:t.stage,settings:JN(n)});if(!i)throw new Error(t.config?`Config "${t.config}" not found`:`No config available. Either:
|
|
1040
|
+
- Pass { config: "name" } to use a stored config
|
|
1041
|
+
- Set NOORM_CONFIG env var
|
|
1042
|
+
- Set NOORM_CONNECTION_DIALECT and NOORM_CONNECTION_DATABASE for env-only mode`);qS(i,t);let s=tx(i);return new Zc(i,o,s,t,e)}var QN="1.0.0",De=async t=>{let{flags:e,logger:r,fn:n}=t,[o,i]=await qa(()=>KS({config:e.config}));if(i)return r.error("Failed to create context",i),[null,i];let[,s]=await qa(()=>o.connect());if(s)return r.error("Failed to connect",s),[null,s];let[,a]=await qa(()=>wl(o.kysely,o.dialect,QN));if(a)return r.error("Failed to initialize database schema",a),await qa(()=>o.disconnect()),[null,a];let[c,l]=await qa(()=>n(o));return await qa(()=>o.disconnect()),l?(r.error(l.message),[null,l]):[c,null]};var xg={};ot(xg,{help:()=>ZN,run:()=>eF});var ZN=`
|
|
1043
|
+
# CHANGE FF
|
|
1044
|
+
|
|
1045
|
+
Fast-forward: apply all pending changes
|
|
1046
|
+
|
|
1047
|
+
## Usage
|
|
1048
|
+
|
|
1049
|
+
noorm change ff [options]
|
|
1050
|
+
noorm -H change ff
|
|
1051
|
+
|
|
1052
|
+
## Options
|
|
1053
|
+
|
|
1054
|
+
-c, --config NAME Use specific configuration
|
|
1055
|
+
-f, --force Skip checksum validation
|
|
1056
|
+
--dry-run Preview without executing
|
|
1057
|
+
|
|
1058
|
+
## Description
|
|
1059
|
+
|
|
1060
|
+
Applies all pending changes in order. This is the primary command
|
|
1061
|
+
for running migrations in CI/CD pipelines.
|
|
1062
|
+
|
|
1063
|
+
Changes are applied in alphabetical order by name. Each change
|
|
1064
|
+
is executed within a transaction when supported by the database.
|
|
1065
|
+
|
|
1066
|
+
> If a change fails, execution stops and subsequent changes are
|
|
1067
|
+
> not applied. The failed change is marked as 'failed' in the history.
|
|
1068
|
+
|
|
1069
|
+
## Examples
|
|
1070
|
+
|
|
1071
|
+
noorm -H change ff
|
|
1072
|
+
noorm -H -c prod change ff
|
|
1073
|
+
noorm -H --dry-run change ff
|
|
1074
|
+
noorm -H --force change ff
|
|
1075
|
+
|
|
1076
|
+
## Exit Codes
|
|
1077
|
+
|
|
1078
|
+
0 All changes applied successfully
|
|
1079
|
+
1 One or more changes failed
|
|
1080
|
+
|
|
1081
|
+
## JSON Output
|
|
1082
|
+
|
|
1083
|
+
\`\`\`json
|
|
1084
|
+
{
|
|
1085
|
+
"status": "success",
|
|
1086
|
+
"executed": 3,
|
|
1087
|
+
"skipped": 0,
|
|
1088
|
+
"failed": 0,
|
|
1089
|
+
"changes": [
|
|
1090
|
+
{ "name": "001_init", "status": "success", "durationMs": 45 }
|
|
1091
|
+
]
|
|
1092
|
+
}
|
|
1093
|
+
\`\`\`
|
|
1094
|
+
|
|
1095
|
+
See \`noorm help change\` or \`noorm help change run\`.
|
|
1096
|
+
`,eF=async(t,e,r)=>{let[n,o]=await De({flags:e,logger:r,fn:i=>i.fastForward()});if(o)return 1;r.info(`Fast-forward ${n.status}`,{executed:n.executed,skipped:n.skipped,failed:n.failed});for(let i of n.changes)r.info(` ${i.name} (${i.status})`);return n.status==="success"?0:1};var bg={};ot(bg,{help:()=>tF,run:()=>rF});var tF=`
|
|
1097
|
+
# CHANGE HISTORY
|
|
1098
|
+
|
|
1099
|
+
Show change execution history
|
|
1100
|
+
|
|
1101
|
+
## Usage
|
|
1102
|
+
|
|
1103
|
+
noorm change history [options]
|
|
1104
|
+
noorm -H change history
|
|
1105
|
+
|
|
1106
|
+
## Options
|
|
1107
|
+
|
|
1108
|
+
--count N Show last N records (default: 20)
|
|
1109
|
+
|
|
1110
|
+
## Description
|
|
1111
|
+
|
|
1112
|
+
Displays the history of change executions including timestamps,
|
|
1113
|
+
status, and duration. Useful for auditing and debugging.
|
|
1114
|
+
|
|
1115
|
+
## Examples
|
|
1116
|
+
|
|
1117
|
+
noorm -H change history
|
|
1118
|
+
noorm -H --count 50 change history
|
|
1119
|
+
|
|
1120
|
+
## JSON Output
|
|
1121
|
+
|
|
1122
|
+
\`\`\`json
|
|
1123
|
+
[
|
|
1124
|
+
{
|
|
1125
|
+
"name": "001_init",
|
|
1126
|
+
"status": "success",
|
|
1127
|
+
"direction": "forward",
|
|
1128
|
+
"executedAt": "2024-01-15T10:30:00Z",
|
|
1129
|
+
"durationMs": 45
|
|
1130
|
+
}
|
|
1131
|
+
]
|
|
1132
|
+
\`\`\`
|
|
1133
|
+
|
|
1134
|
+
See \`noorm help change\`.
|
|
1135
|
+
`,rF=async(t,e,r)=>{let[n,o]=await De({flags:e,logger:r,fn:i=>i.getHistory(t.count??20)});if(o)return 1;r.info(`Execution History: ${n.length} records`);for(let i of n){let s=new Date(i.executedAt).toLocaleString();r.info(` ${i.name} - ${i.status} (${s})`)}return 0};var Sg={};ot(Sg,{help:()=>nF,run:()=>oF});var nF=`
|
|
1136
|
+
# CHANGE REVERT
|
|
1137
|
+
|
|
1138
|
+
Revert a specific change
|
|
1139
|
+
|
|
1140
|
+
## Usage
|
|
1141
|
+
|
|
1142
|
+
noorm change revert NAME
|
|
1143
|
+
noorm -H change revert NAME
|
|
1144
|
+
|
|
1145
|
+
## Arguments
|
|
1146
|
+
|
|
1147
|
+
NAME Name of the change to revert
|
|
1148
|
+
|
|
1149
|
+
## Description
|
|
1150
|
+
|
|
1151
|
+
Reverts a single applied change by running its backward SQL.
|
|
1152
|
+
The change must have been previously applied.
|
|
1153
|
+
|
|
1154
|
+
## Examples
|
|
1155
|
+
|
|
1156
|
+
noorm -H change revert 002_users
|
|
1157
|
+
noorm -H change revert 001_init
|
|
1158
|
+
|
|
1159
|
+
See \`noorm help change\` or \`noorm help change run\`.
|
|
1160
|
+
`,oF=async(t,e,r)=>{if(!t.name)return r.error("Change name required. Use --name <change>"),1;let[n,o]=await De({flags:e,logger:r,fn:i=>i.revertChange(t.name)});return o?1:(r.info(`${n.name} reverted (${n.status})`),n.status==="success"?0:1)};var Cg={};ot(Cg,{help:()=>iF,run:()=>sF});var iF=`
|
|
1161
|
+
# CHANGE RUN
|
|
1162
|
+
|
|
1163
|
+
Apply a specific change
|
|
1164
|
+
|
|
1165
|
+
## Usage
|
|
1166
|
+
|
|
1167
|
+
noorm change run NAME
|
|
1168
|
+
noorm -H change run NAME
|
|
1169
|
+
|
|
1170
|
+
## Arguments
|
|
1171
|
+
|
|
1172
|
+
NAME Name of the change to apply
|
|
1173
|
+
|
|
1174
|
+
## Description
|
|
1175
|
+
|
|
1176
|
+
Applies a single change by name. Use this to apply changes
|
|
1177
|
+
out of order or to retry a failed change.
|
|
1178
|
+
|
|
1179
|
+
## Examples
|
|
1180
|
+
|
|
1181
|
+
noorm -H change run 001_init
|
|
1182
|
+
noorm -H change run 002_users
|
|
1183
|
+
|
|
1184
|
+
See \`noorm help change\`, \`noorm help change ff\`, or \`noorm help change revert\`.
|
|
1185
|
+
`,sF=async(t,e,r)=>{if(!t.name)return r.error("Change name required. Use --name <change>"),1;let[n,o]=await De({flags:e,logger:r,fn:i=>i.applyChange(t.name)});return o?1:(r.info(`${n.name} (${n.status})`),n.status==="success"?0:1)};var wg={};ot(wg,{help:()=>aF,run:()=>cF});var aF=`
|
|
1186
|
+
# CHANGE
|
|
1187
|
+
|
|
1188
|
+
Manage and apply changes
|
|
1189
|
+
|
|
1190
|
+
## Usage
|
|
1191
|
+
|
|
1192
|
+
noorm change [subcommand] [options]
|
|
1193
|
+
|
|
1194
|
+
## Subcommands
|
|
1195
|
+
|
|
1196
|
+
(none) List all changes and their status
|
|
1197
|
+
ff Fast-forward: apply all pending changes
|
|
1198
|
+
run NAME Apply a specific change
|
|
1199
|
+
revert NAME Revert a specific change
|
|
1200
|
+
history Show execution history
|
|
1201
|
+
|
|
1202
|
+
## Description
|
|
1203
|
+
|
|
1204
|
+
Changes are versioned SQL migrations stored in the \`changes/\`
|
|
1205
|
+
directory. Each change has forward (apply) and backward (revert)
|
|
1206
|
+
SQL files.
|
|
1207
|
+
|
|
1208
|
+
Change status:
|
|
1209
|
+
- **pending** - Not yet applied
|
|
1210
|
+
- **applied** - Successfully applied
|
|
1211
|
+
- **failed** - Execution failed
|
|
1212
|
+
|
|
1213
|
+
## Examples
|
|
1214
|
+
|
|
1215
|
+
noorm -H change
|
|
1216
|
+
noorm -H change ff
|
|
1217
|
+
noorm -H change run 001_users
|
|
1218
|
+
noorm -H change revert 001_users
|
|
1219
|
+
|
|
1220
|
+
## JSON Output
|
|
1221
|
+
|
|
1222
|
+
\`\`\`json
|
|
1223
|
+
[
|
|
1224
|
+
{ "name": "001_users", "status": "applied" },
|
|
1225
|
+
{ "name": "002_posts", "status": "pending" }
|
|
1226
|
+
]
|
|
1227
|
+
\`\`\`
|
|
1228
|
+
|
|
1229
|
+
See \`noorm help change ff\`, \`noorm help change run\`, or \`noorm help change history\`.
|
|
1230
|
+
`,cF=async(t,e,r)=>{let[n,o]=await De({flags:e,logger:r,fn:s=>s.getChangeStatus()});if(o)return 1;for(let s of n)r.info(`${s.name} (${s.status})`);let i=n.filter(s=>s.status==="pending").length;return i>0&&r.info(`${i} pending change(s)`),0};var Eg={};ot(Eg,{help:()=>Tg,run:()=>lF});var Tg=`
|
|
1231
|
+
# CONFIG ADD
|
|
1232
|
+
|
|
1233
|
+
Create a new configuration
|
|
1234
|
+
|
|
1235
|
+
## Usage
|
|
1236
|
+
|
|
1237
|
+
noorm config add
|
|
1238
|
+
|
|
1239
|
+
## Description
|
|
1240
|
+
|
|
1241
|
+
Opens an interactive wizard to create a new database configuration.
|
|
1242
|
+
Guides you through connection details, paths, and settings.
|
|
1243
|
+
|
|
1244
|
+
> TUI only - not available in headless mode.
|
|
1245
|
+
|
|
1246
|
+
See \`noorm help config\` or \`noorm help config edit\`.
|
|
1247
|
+
`,lF=async(t,e,r)=>{let n=e.json?Tg:Rt(Tg);return process.stdout.write(n+"\\n"),0};var kg={};ot(kg,{help:()=>Rg,run:()=>uF});var Rg=`
|
|
1248
|
+
# CONFIG EDIT
|
|
1249
|
+
|
|
1250
|
+
Edit an existing configuration
|
|
1251
|
+
|
|
1252
|
+
## Usage
|
|
1253
|
+
|
|
1254
|
+
noorm config edit NAME
|
|
1255
|
+
|
|
1256
|
+
## Arguments
|
|
1257
|
+
|
|
1258
|
+
NAME Name of the configuration to edit
|
|
1259
|
+
|
|
1260
|
+
## Description
|
|
1261
|
+
|
|
1262
|
+
Opens the configuration editor for the named config.
|
|
1263
|
+
Allows modifying connection details, paths, and settings.
|
|
1264
|
+
|
|
1265
|
+
> TUI only - not available in headless mode.
|
|
1266
|
+
|
|
1267
|
+
See \`noorm help config\` or \`noorm help config add\`.
|
|
1268
|
+
`,uF=async(t,e,r)=>{let n=e.json?Rg:Rt(Rg);return process.stdout.write(n+"\\n"),0};var vg={};ot(vg,{help:()=>_g,run:()=>mF});var _g=`
|
|
1269
|
+
# CONFIG RM
|
|
1270
|
+
|
|
1271
|
+
Remove a configuration
|
|
1272
|
+
|
|
1273
|
+
## Usage
|
|
1274
|
+
|
|
1275
|
+
noorm config rm NAME
|
|
1276
|
+
|
|
1277
|
+
## Arguments
|
|
1278
|
+
|
|
1279
|
+
NAME Name of the configuration to remove
|
|
1280
|
+
|
|
1281
|
+
## Description
|
|
1282
|
+
|
|
1283
|
+
Permanently deletes the named configuration and its secrets.
|
|
1284
|
+
Locked stage configs cannot be deleted.
|
|
1285
|
+
|
|
1286
|
+
> TUI only - not available in headless mode.
|
|
1287
|
+
|
|
1288
|
+
See \`noorm help config\`.
|
|
1289
|
+
`,mF=async(t,e,r)=>{let n=e.json?_g:Rt(_g);return process.stdout.write(n+"\\n"),0};var Dg={};ot(Dg,{help:()=>dF,run:()=>pF});import{attempt as VS}from"@logosdx/utils";var dF=`
|
|
1290
|
+
# CONFIG USE
|
|
1291
|
+
|
|
1292
|
+
Set the active configuration
|
|
1293
|
+
|
|
1294
|
+
## Usage
|
|
1295
|
+
|
|
1296
|
+
noorm config use NAME
|
|
1297
|
+
noorm -H config use NAME
|
|
1298
|
+
|
|
1299
|
+
## Arguments
|
|
1300
|
+
|
|
1301
|
+
NAME Name of the configuration to activate
|
|
1302
|
+
|
|
1303
|
+
## Description
|
|
1304
|
+
|
|
1305
|
+
Sets the specified configuration as the active default.
|
|
1306
|
+
Once set, commands will use this config unless overridden with \`--config\`.
|
|
1307
|
+
|
|
1308
|
+
> The active config is stored in \`.noorm/state.enc\` and persists across
|
|
1309
|
+
> sessions. Headless mode respects the active config, allowing you to
|
|
1310
|
+
> set it once and run CI commands without specifying \`--config\`.
|
|
1311
|
+
|
|
1312
|
+
## Examples
|
|
1313
|
+
|
|
1314
|
+
noorm config use dev
|
|
1315
|
+
noorm -H config use production
|
|
1316
|
+
|
|
1317
|
+
After setting active config, these are equivalent:
|
|
1318
|
+
|
|
1319
|
+
noorm -H change ff
|
|
1320
|
+
noorm -H --config production change ff
|
|
1321
|
+
|
|
1322
|
+
## JSON Output
|
|
1323
|
+
|
|
1324
|
+
\`\`\`json
|
|
1325
|
+
{
|
|
1326
|
+
"activeConfig": "production"
|
|
1327
|
+
}
|
|
1328
|
+
\`\`\`
|
|
1329
|
+
|
|
1330
|
+
See \`noorm help config\`.
|
|
1331
|
+
`,pF=async(t,e,r)=>{let n=t.name;if(!n)return r.error("Config name required. Usage: noorm -H config use <name>"),1;let o=process.cwd(),[,i]=await VS(()=>Xa(o));if(i)return r.error(`Failed to load state: ${i.message}`),1;let s=Ur(o),[,a]=await VS(()=>s.setActiveConfig(n));if(a)return r.error(a.message),1;let c=s.getConfig(n);if(c){let l=await fs(c);l.ok&&l.knownUsers?.length&&await s.addKnownUsers(l.knownUsers)}return r.info(`Active config set to: ${n}`),0};var Ng={};ot(Ng,{help:()=>Pg,run:()=>fF});var Pg=`
|
|
1332
|
+
# CONFIG
|
|
1333
|
+
|
|
1334
|
+
Manage database configurations
|
|
1335
|
+
|
|
1336
|
+
## Usage
|
|
1337
|
+
|
|
1338
|
+
noorm config [subcommand] [options]
|
|
1339
|
+
|
|
1340
|
+
## Subcommands
|
|
1341
|
+
|
|
1342
|
+
add Create a new configuration
|
|
1343
|
+
edit NAME Edit an existing configuration
|
|
1344
|
+
rm NAME Remove a configuration
|
|
1345
|
+
use NAME Set the active configuration
|
|
1346
|
+
validate Validate configuration settings
|
|
1347
|
+
|
|
1348
|
+
## Description
|
|
1349
|
+
|
|
1350
|
+
Configurations store database connection details, paths, and settings.
|
|
1351
|
+
Each config has a name and can be set as **active** for default use.
|
|
1352
|
+
|
|
1353
|
+
> Configs are stored encrypted in \`.noorm/state.enc\`
|
|
1354
|
+
|
|
1355
|
+
Config resolution order:
|
|
1356
|
+
1. \`--config\` flag
|
|
1357
|
+
2. \`NOORM_CONFIG\` env var
|
|
1358
|
+
3. Active config from state
|
|
1359
|
+
|
|
1360
|
+
## Examples
|
|
1361
|
+
|
|
1362
|
+
noorm config List all configurations (TUI)
|
|
1363
|
+
noorm -H config use dev Set 'dev' as active config
|
|
1364
|
+
noorm -H --config prod change ff Use 'prod' for this command
|
|
1365
|
+
|
|
1366
|
+
## Environment Variables
|
|
1367
|
+
|
|
1368
|
+
NOORM_CONFIG Default config name
|
|
1369
|
+
NOORM_CONNECTION_HOST Override connection host
|
|
1370
|
+
NOORM_CONNECTION_PORT Override connection port
|
|
1371
|
+
NOORM_CONNECTION_DATABASE Override database name
|
|
1372
|
+
NOORM_CONNECTION_USER Override username
|
|
1373
|
+
NOORM_CONNECTION_PASSWORD Override password
|
|
1374
|
+
NOORM_CONNECTION_DIALECT Override dialect (postgres|mysql|sqlite|mssql)
|
|
1375
|
+
|
|
1376
|
+
> Environment variables override config file values
|
|
1377
|
+
|
|
1378
|
+
See \`noorm help config use\` for setting the active config.
|
|
1379
|
+
`,fF=async(t,e,r)=>{let n=e.json?Pg:Rt(Pg);return process.stdout.write(n+`
|
|
1380
|
+
`),0};var Fg={};ot(Fg,{help:()=>gF,run:()=>yF});var gF=`
|
|
1381
|
+
# DB EXPLORE TABLES DETAIL
|
|
1382
|
+
|
|
1383
|
+
Describe a specific table
|
|
1384
|
+
|
|
1385
|
+
## Usage
|
|
1386
|
+
|
|
1387
|
+
noorm db explore tables detail NAME
|
|
1388
|
+
noorm -H db explore tables detail NAME
|
|
1389
|
+
noorm -H --name NAME db explore tables detail
|
|
1390
|
+
|
|
1391
|
+
## Arguments
|
|
1392
|
+
|
|
1393
|
+
NAME Name of the table to describe
|
|
1394
|
+
|
|
1395
|
+
## Description
|
|
1396
|
+
|
|
1397
|
+
Shows detailed schema information for a table including columns,
|
|
1398
|
+
data types, nullability, and primary key status.
|
|
1399
|
+
|
|
1400
|
+
## Examples
|
|
1401
|
+
|
|
1402
|
+
noorm -H db explore tables detail users
|
|
1403
|
+
noorm -H --json db explore tables detail posts
|
|
1404
|
+
|
|
1405
|
+
## JSON Output
|
|
1406
|
+
|
|
1407
|
+
\`\`\`json
|
|
1408
|
+
{
|
|
1409
|
+
"name": "users",
|
|
1410
|
+
"schema": "public",
|
|
1411
|
+
"columns": [
|
|
1412
|
+
{ "name": "id", "dataType": "integer", "nullable": false, "isPrimaryKey": true },
|
|
1413
|
+
{ "name": "email", "dataType": "varchar(255)", "nullable": false },
|
|
1414
|
+
{ "name": "created_at", "dataType": "timestamp", "nullable": false }
|
|
1415
|
+
]
|
|
1416
|
+
}
|
|
1417
|
+
\`\`\`
|
|
1418
|
+
|
|
1419
|
+
See \`noorm help db explore tables\`.
|
|
1420
|
+
`,yF=async(t,e,r)=>{if(!t.name)return r.error("Table name required. Use --name <table>"),1;let[n,o]=await De({flags:e,logger:r,fn:i=>i.describeTable(t.name,t.schema)});return o?1:n?(e.json?process.stdout.write(JSON.stringify(n)+`
|
|
1421
|
+
`):r.info(`Table: ${n.name}`,{columns:n.columns.map(i=>`${i.name}: ${i.dataType}`)}),0):(r.error(`Table not found: ${t.name}`),1)};var Bg={};ot(Bg,{help:()=>hF,run:()=>xF});var hF=`
|
|
1422
|
+
# DB EXPLORE TABLES
|
|
1423
|
+
|
|
1424
|
+
List all tables
|
|
1425
|
+
|
|
1426
|
+
## Usage
|
|
1427
|
+
|
|
1428
|
+
noorm db explore tables
|
|
1429
|
+
noorm -H db explore tables
|
|
1430
|
+
|
|
1431
|
+
## Description
|
|
1432
|
+
|
|
1433
|
+
Lists all tables in the database with their column counts.
|
|
1434
|
+
|
|
1435
|
+
## Examples
|
|
1436
|
+
|
|
1437
|
+
noorm -H db explore tables
|
|
1438
|
+
noorm -H --json db explore tables
|
|
1439
|
+
|
|
1440
|
+
## JSON Output
|
|
1441
|
+
|
|
1442
|
+
\`\`\`json
|
|
1443
|
+
[
|
|
1444
|
+
{ "name": "users", "columnCount": 8 },
|
|
1445
|
+
{ "name": "posts", "columnCount": 5 },
|
|
1446
|
+
{ "name": "comments", "columnCount": 4 }
|
|
1447
|
+
]
|
|
1448
|
+
\`\`\`
|
|
1449
|
+
|
|
1450
|
+
See \`noorm help db explore\` or \`noorm help db explore tables detail\`.
|
|
1451
|
+
`,xF=async(t,e,r)=>{let[n,o]=await De({flags:e,logger:r,fn:i=>i.listTables()});return o?1:(e.json?process.stdout.write(JSON.stringify(n)+`
|
|
1452
|
+
`):r.info(`Tables: ${n.length}`,{tables:n.map(i=>`${i.name} (${i.columnCount} cols)`)}),0)};var Lg={};ot(Lg,{help:()=>bF,run:()=>SF});var bF=`
|
|
1453
|
+
# DB EXPLORE
|
|
1454
|
+
|
|
1455
|
+
Explore database schema
|
|
1456
|
+
|
|
1457
|
+
## Usage
|
|
1458
|
+
|
|
1459
|
+
noorm db explore [subcommand] [options]
|
|
1460
|
+
|
|
1461
|
+
## Subcommands
|
|
1462
|
+
|
|
1463
|
+
(none) Get database overview with object counts
|
|
1464
|
+
tables List all tables
|
|
1465
|
+
tables detail Describe a specific table
|
|
1466
|
+
|
|
1467
|
+
## Description
|
|
1468
|
+
|
|
1469
|
+
Explore your database schema to understand its structure.
|
|
1470
|
+
Useful for debugging, documentation, and development.
|
|
1471
|
+
|
|
1472
|
+
## Examples
|
|
1473
|
+
|
|
1474
|
+
noorm -H db explore
|
|
1475
|
+
noorm -H db explore tables
|
|
1476
|
+
noorm -H db explore tables detail users
|
|
1477
|
+
noorm -H --json db explore > schema.json
|
|
1478
|
+
|
|
1479
|
+
## JSON Output
|
|
1480
|
+
|
|
1481
|
+
Overview:
|
|
1482
|
+
|
|
1483
|
+
\`\`\`json
|
|
1484
|
+
{
|
|
1485
|
+
"tables": 12,
|
|
1486
|
+
"views": 3,
|
|
1487
|
+
"functions": 5,
|
|
1488
|
+
"procedures": 0,
|
|
1489
|
+
"types": 2
|
|
1490
|
+
}
|
|
1491
|
+
\`\`\`
|
|
1492
|
+
|
|
1493
|
+
Tables list:
|
|
1494
|
+
|
|
1495
|
+
\`\`\`json
|
|
1496
|
+
[
|
|
1497
|
+
{ "name": "users", "columnCount": 8 },
|
|
1498
|
+
{ "name": "posts", "columnCount": 5 }
|
|
1499
|
+
]
|
|
1500
|
+
\`\`\`
|
|
1501
|
+
|
|
1502
|
+
See \`noorm help db explore tables detail\`.
|
|
1503
|
+
`,SF=async(t,e,r)=>{let[n,o]=await De({flags:e,logger:r,fn:i=>i.overview()});return o?1:(e.json?process.stdout.write(JSON.stringify(n)+`
|
|
1504
|
+
`):r.info("Database Overview",n),0)};var Ig={};ot(Ig,{help:()=>CF,run:()=>wF});var CF=`
|
|
1505
|
+
# DB TEARDOWN
|
|
1506
|
+
|
|
1507
|
+
Drop all database objects
|
|
1508
|
+
|
|
1509
|
+
## Usage
|
|
1510
|
+
|
|
1511
|
+
noorm db teardown
|
|
1512
|
+
noorm -H db teardown
|
|
1513
|
+
|
|
1514
|
+
## Description
|
|
1515
|
+
|
|
1516
|
+
Drops all database objects including tables, views, functions,
|
|
1517
|
+
and types. Keeps noorm tracking tables.
|
|
1518
|
+
|
|
1519
|
+
> **WARNING:** This is a destructive operation. Protected configs
|
|
1520
|
+
> require \`--force\` or confirmation.
|
|
1521
|
+
|
|
1522
|
+
## Examples
|
|
1523
|
+
|
|
1524
|
+
noorm -H db teardown
|
|
1525
|
+
noorm -H -y db teardown
|
|
1526
|
+
|
|
1527
|
+
## JSON Output
|
|
1528
|
+
|
|
1529
|
+
\`\`\`json
|
|
1530
|
+
{
|
|
1531
|
+
"dropped": {
|
|
1532
|
+
"tables": 5,
|
|
1533
|
+
"views": 2,
|
|
1534
|
+
"functions": 3,
|
|
1535
|
+
"types": 1
|
|
1536
|
+
},
|
|
1537
|
+
"count": 11
|
|
1538
|
+
}
|
|
1539
|
+
\`\`\`
|
|
1540
|
+
|
|
1541
|
+
See \`noorm help db\` or \`noorm help db truncate\`.
|
|
1542
|
+
`,wF=async(t,e,r)=>{let[n,o]=await De({flags:e,logger:r,fn:s=>s.teardown()});if(o)return 1;let i=n.dropped.tables.length+n.dropped.views.length+n.dropped.functions.length+n.dropped.types.length;if(e.json){let s={dropped:n.dropped,count:i};process.stdout.write(JSON.stringify(s)+`
|
|
1543
|
+
`)}else r.info(`Dropped ${i} objects`,{tables:n.dropped.tables.length,views:n.dropped.views.length,functions:n.dropped.functions.length,types:n.dropped.types.length});return 0};var Og={};ot(Og,{help:()=>TF,run:()=>EF});var TF=`
|
|
1544
|
+
# DB TRUNCATE
|
|
1545
|
+
|
|
1546
|
+
Wipe all data, keep schema
|
|
1547
|
+
|
|
1548
|
+
## Usage
|
|
1549
|
+
|
|
1550
|
+
noorm db truncate
|
|
1551
|
+
noorm -H db truncate
|
|
1552
|
+
|
|
1553
|
+
## Description
|
|
1554
|
+
|
|
1555
|
+
Truncates all tables in the database, removing all data while
|
|
1556
|
+
keeping the schema intact. Useful for resetting test databases.
|
|
1557
|
+
|
|
1558
|
+
> **WARNING:** This is a destructive operation. Protected configs
|
|
1559
|
+
> require \`--force\` or confirmation.
|
|
1560
|
+
|
|
1561
|
+
## Examples
|
|
1562
|
+
|
|
1563
|
+
noorm -H db truncate
|
|
1564
|
+
noorm -H -y db truncate
|
|
1565
|
+
|
|
1566
|
+
## JSON Output
|
|
1567
|
+
|
|
1568
|
+
\`\`\`json
|
|
1569
|
+
{
|
|
1570
|
+
"truncated": ["users", "posts", "comments"],
|
|
1571
|
+
"count": 3
|
|
1572
|
+
}
|
|
1573
|
+
\`\`\`
|
|
1574
|
+
|
|
1575
|
+
See \`noorm help db\` or \`noorm help db teardown\`.
|
|
1576
|
+
`,EF=async(t,e,r)=>{let[n,o]=await De({flags:e,logger:r,fn:i=>i.truncate()});if(o)return 1;if(e.json){let i={truncated:n.truncated,count:n.truncated.length};process.stdout.write(JSON.stringify(i)+`
|
|
1577
|
+
`)}else r.info(`Truncated ${n.truncated.length} tables`,{tables:n.truncated});return 0};var Mg={};ot(Mg,{help:()=>Ag,run:()=>RF});var Ag=`
|
|
1578
|
+
# DB
|
|
1579
|
+
|
|
1580
|
+
Database operations and exploration
|
|
1581
|
+
|
|
1582
|
+
## Usage
|
|
1583
|
+
|
|
1584
|
+
noorm db [subcommand] [options]
|
|
1585
|
+
|
|
1586
|
+
## Subcommands
|
|
1587
|
+
|
|
1588
|
+
explore Get database overview with object counts
|
|
1589
|
+
explore tables List all tables
|
|
1590
|
+
explore tables detail NAME
|
|
1591
|
+
Describe a specific table
|
|
1592
|
+
truncate Wipe all data, keep schema
|
|
1593
|
+
teardown Drop all database objects
|
|
1594
|
+
|
|
1595
|
+
## Description
|
|
1596
|
+
|
|
1597
|
+
Database commands for exploration and management. Use explore to
|
|
1598
|
+
understand your schema, truncate for test resets, and teardown
|
|
1599
|
+
for complete cleanup.
|
|
1600
|
+
|
|
1601
|
+
> **WARNING:** truncate and teardown are destructive operations.
|
|
1602
|
+
> Protected configs require \`--force\` or confirmation.
|
|
1603
|
+
|
|
1604
|
+
## Examples
|
|
1605
|
+
|
|
1606
|
+
noorm -H db explore
|
|
1607
|
+
noorm -H db explore tables
|
|
1608
|
+
noorm -H db explore tables detail users
|
|
1609
|
+
noorm -H db truncate
|
|
1610
|
+
noorm -H db teardown
|
|
1611
|
+
|
|
1612
|
+
See \`noorm help db explore\`, \`noorm help db truncate\`, or \`noorm help db teardown\`.
|
|
1613
|
+
`,RF=async(t,e,r)=>{let n=e.json?Ag:Rt(Ag);return process.stdout.write(n+"\\n"),0};var jg={};ot(jg,{help:()=>$g,run:()=>kF});var $g=`
|
|
1614
|
+
# IDENTITY
|
|
1615
|
+
|
|
1616
|
+
Manage identity
|
|
1617
|
+
|
|
1618
|
+
## Usage
|
|
1619
|
+
|
|
1620
|
+
noorm identity
|
|
1621
|
+
|
|
1622
|
+
## Description
|
|
1623
|
+
|
|
1624
|
+
Opens the identity management screen. Identity is used for:
|
|
1625
|
+
- Lock ownership
|
|
1626
|
+
- Audit logging
|
|
1627
|
+
- Change attribution
|
|
1628
|
+
|
|
1629
|
+
Identity can be derived from:
|
|
1630
|
+
- Git config (\`user.name\`, \`user.email\`)
|
|
1631
|
+
- Environment variables
|
|
1632
|
+
- Manual configuration
|
|
1633
|
+
|
|
1634
|
+
> TUI only - not available in headless mode.
|
|
1635
|
+
|
|
1636
|
+
See \`noorm help lock\`.
|
|
1637
|
+
`,kF=async(t,e,r)=>{let n=e.json?$g:Rt($g);return process.stdout.write(n+"\\n"),0};var Hg={};ot(Hg,{help:()=>_F,run:()=>vF});var _F=`
|
|
1638
|
+
# LOCK ACQUIRE
|
|
1639
|
+
|
|
1640
|
+
Acquire the database lock
|
|
1641
|
+
|
|
1642
|
+
## Usage
|
|
1643
|
+
|
|
1644
|
+
noorm lock acquire
|
|
1645
|
+
noorm -H lock acquire
|
|
1646
|
+
|
|
1647
|
+
## Description
|
|
1648
|
+
|
|
1649
|
+
Acquires an exclusive lock on the database. Fails if already locked.
|
|
1650
|
+
Use this to prevent concurrent migrations in multi-instance deployments.
|
|
1651
|
+
|
|
1652
|
+
> Locks expire automatically after a timeout period.
|
|
1653
|
+
|
|
1654
|
+
## Examples
|
|
1655
|
+
|
|
1656
|
+
noorm -H lock acquire
|
|
1657
|
+
|
|
1658
|
+
CI/CD pattern with cleanup:
|
|
1659
|
+
|
|
1660
|
+
noorm -H lock acquire
|
|
1661
|
+
trap "noorm -H lock release" EXIT
|
|
1662
|
+
noorm -H change ff
|
|
1663
|
+
|
|
1664
|
+
## Exit Codes
|
|
1665
|
+
|
|
1666
|
+
0 Lock acquired successfully
|
|
1667
|
+
1 Lock acquisition failed (already locked)
|
|
1668
|
+
|
|
1669
|
+
See \`noorm help lock\` or \`noorm help lock release\`.
|
|
1670
|
+
`,vF=async(t,e,r)=>{let[n,o]=await De({flags:e,logger:r,fn:i=>i.acquireLock()});if(o)return 1;if(e.json){let i={acquired:!0,lockedBy:n.lockedBy,expiresAt:n.expiresAt.toISOString()};process.stdout.write(JSON.stringify(i)+`
|
|
1671
|
+
`)}else r.info("Lock acquired",{lockedBy:n.lockedBy,expiresAt:n.expiresAt.toISOString()});return 0};var qg={};ot(qg,{help:()=>DF,run:()=>PF});var DF=`
|
|
1672
|
+
# LOCK FORCE
|
|
1673
|
+
|
|
1674
|
+
Force release any database lock
|
|
1675
|
+
|
|
1676
|
+
## Usage
|
|
1677
|
+
|
|
1678
|
+
noorm lock force
|
|
1679
|
+
noorm -H lock force
|
|
1680
|
+
|
|
1681
|
+
## Description
|
|
1682
|
+
|
|
1683
|
+
Force releases the database lock regardless of ownership.
|
|
1684
|
+
Use this when a lock holder crashed or when emergency intervention is needed.
|
|
1685
|
+
|
|
1686
|
+
> Warning: Force releasing a lock can cause data corruption if the original
|
|
1687
|
+
> holder is still running operations.
|
|
1688
|
+
|
|
1689
|
+
## Examples
|
|
1690
|
+
|
|
1691
|
+
noorm -H lock force
|
|
1692
|
+
|
|
1693
|
+
## Exit Codes
|
|
1694
|
+
|
|
1695
|
+
0 Lock force-released successfully
|
|
1696
|
+
1 No lock to release or operation failed
|
|
1697
|
+
|
|
1698
|
+
See \`noorm help lock\` or \`noorm help lock acquire\`.
|
|
1699
|
+
`,PF=async(t,e,r)=>{let[,n]=await De({flags:e,logger:r,fn:async o=>(await o.forceReleaseLock(),!0)});return n?1:(r.info("Lock force-released"),0)};var Kg={};ot(Kg,{help:()=>NF,run:()=>FF});var NF=`
|
|
1700
|
+
# LOCK RELEASE
|
|
1701
|
+
|
|
1702
|
+
Release the current lock
|
|
1703
|
+
|
|
1704
|
+
## Usage
|
|
1705
|
+
|
|
1706
|
+
noorm lock release
|
|
1707
|
+
noorm -H lock release
|
|
1708
|
+
|
|
1709
|
+
## Description
|
|
1710
|
+
|
|
1711
|
+
Releases the current database lock. Only the lock holder can release.
|
|
1712
|
+
Use \`lock force\` to override ownership.
|
|
1713
|
+
|
|
1714
|
+
## Examples
|
|
1715
|
+
|
|
1716
|
+
noorm -H lock release
|
|
1717
|
+
|
|
1718
|
+
## Exit Codes
|
|
1719
|
+
|
|
1720
|
+
0 Lock released successfully
|
|
1721
|
+
1 No lock to release or not owner
|
|
1722
|
+
|
|
1723
|
+
See \`noorm help lock\` or \`noorm help lock acquire\`.
|
|
1724
|
+
`,FF=async(t,e,r)=>{let[,n]=await De({flags:e,logger:r,fn:async o=>(await o.releaseLock(),!0)});return n?1:(e.json?process.stdout.write(JSON.stringify({released:!0})+`
|
|
1725
|
+
`):r.info("Lock released"),0)};var Vg={};ot(Vg,{help:()=>BF,run:()=>LF});var BF=`
|
|
1726
|
+
# LOCK STATUS
|
|
1727
|
+
|
|
1728
|
+
Check current lock status
|
|
1729
|
+
|
|
1730
|
+
## Usage
|
|
1731
|
+
|
|
1732
|
+
noorm lock status
|
|
1733
|
+
noorm -H lock status
|
|
1734
|
+
|
|
1735
|
+
## Description
|
|
1736
|
+
|
|
1737
|
+
Shows whether the database is currently locked and by whom.
|
|
1738
|
+
Use this to check before running migrations in a shared environment.
|
|
1739
|
+
|
|
1740
|
+
## Examples
|
|
1741
|
+
|
|
1742
|
+
noorm -H lock status
|
|
1743
|
+
|
|
1744
|
+
## JSON Output
|
|
1745
|
+
|
|
1746
|
+
When locked:
|
|
1747
|
+
|
|
1748
|
+
\`\`\`json
|
|
1749
|
+
{
|
|
1750
|
+
"isLocked": true,
|
|
1751
|
+
"lock": {
|
|
1752
|
+
"lockedBy": "deploy@ci-runner",
|
|
1753
|
+
"lockedAt": "2024-01-15T10:30:00Z",
|
|
1754
|
+
"expiresAt": "2024-01-15T10:35:00Z"
|
|
1755
|
+
}
|
|
1756
|
+
}
|
|
1757
|
+
\`\`\`
|
|
1758
|
+
|
|
1759
|
+
When not locked:
|
|
1760
|
+
|
|
1761
|
+
\`\`\`json
|
|
1762
|
+
{
|
|
1763
|
+
"isLocked": false
|
|
1764
|
+
}
|
|
1765
|
+
\`\`\`
|
|
1766
|
+
|
|
1767
|
+
See \`noorm help lock\` or \`noorm help lock acquire\`.
|
|
1768
|
+
`,LF=async(t,e,r)=>{let[n,o]=await De({flags:e,logger:r,fn:i=>i.getLockStatus()});if(o)return 1;if(e.json){let i=n.isLocked&&n.lock?{isLocked:!0,lock:{lockedBy:n.lock.lockedBy,lockedAt:n.lock.lockedAt.toISOString(),expiresAt:n.lock.expiresAt.toISOString()}}:{isLocked:!1,lock:null};process.stdout.write(JSON.stringify(i)+`
|
|
1769
|
+
`)}else n.isLocked&&n.lock?r.info(`Locked by ${n.lock.lockedBy}`,{since:n.lock.lockedAt.toISOString(),expires:n.lock.expiresAt.toISOString()}):r.info("No active lock");return 0};var Yg={};ot(Yg,{help:()=>Ug,run:()=>IF});var Ug=`
|
|
1770
|
+
# LOCK
|
|
1771
|
+
|
|
1772
|
+
Distributed lock management
|
|
1773
|
+
|
|
1774
|
+
## Usage
|
|
1775
|
+
|
|
1776
|
+
noorm lock [subcommand] [options]
|
|
1777
|
+
|
|
1778
|
+
## Subcommands
|
|
1779
|
+
|
|
1780
|
+
status Check current lock status
|
|
1781
|
+
acquire Acquire the database lock
|
|
1782
|
+
release Release the current lock
|
|
1783
|
+
force Force release (override ownership)
|
|
1784
|
+
|
|
1785
|
+
## Description
|
|
1786
|
+
|
|
1787
|
+
Distributed locking prevents concurrent migrations in multi-instance
|
|
1788
|
+
deployments. Use locks to coordinate CI/CD pipelines.
|
|
1789
|
+
|
|
1790
|
+
Locks are stored in the database and include:
|
|
1791
|
+
- Lock holder identity
|
|
1792
|
+
- Acquisition timestamp
|
|
1793
|
+
- Expiration time
|
|
1794
|
+
|
|
1795
|
+
## Examples
|
|
1796
|
+
|
|
1797
|
+
noorm -H lock status
|
|
1798
|
+
noorm -H lock acquire
|
|
1799
|
+
noorm -H lock release
|
|
1800
|
+
|
|
1801
|
+
CI/CD with lock protection:
|
|
1802
|
+
|
|
1803
|
+
noorm -H lock acquire
|
|
1804
|
+
trap "noorm -H lock release" EXIT
|
|
1805
|
+
noorm -H change ff
|
|
1806
|
+
|
|
1807
|
+
## JSON Output
|
|
1808
|
+
|
|
1809
|
+
\`\`\`json
|
|
1810
|
+
{
|
|
1811
|
+
"isLocked": true,
|
|
1812
|
+
"lock": {
|
|
1813
|
+
"lockedBy": "deploy@ci-runner",
|
|
1814
|
+
"lockedAt": "2024-01-15T10:30:00Z",
|
|
1815
|
+
"expiresAt": "2024-01-15T10:35:00Z"
|
|
1816
|
+
}
|
|
1817
|
+
}
|
|
1818
|
+
\`\`\`
|
|
1819
|
+
|
|
1820
|
+
See \`noorm help lock status\` or \`noorm help lock acquire\`.
|
|
1821
|
+
`,IF=async(t,e,r)=>{let n=e.json?Ug:Rt(Ug);return process.stdout.write(n+"\\n"),0};var Wg={};ot(Wg,{help:()=>OF,run:()=>AF});var OF=`
|
|
1822
|
+
# RUN BUILD
|
|
1823
|
+
|
|
1824
|
+
Execute all SQL files in schema directory
|
|
1825
|
+
|
|
1826
|
+
## Usage
|
|
1827
|
+
|
|
1828
|
+
noorm run build [options]
|
|
1829
|
+
noorm -H run build
|
|
1830
|
+
|
|
1831
|
+
## Options
|
|
1832
|
+
|
|
1833
|
+
-f, --force Force execution (skip checksum validation)
|
|
1834
|
+
--dry-run Preview without executing
|
|
1835
|
+
|
|
1836
|
+
## Description
|
|
1837
|
+
|
|
1838
|
+
Executes all SQL files in the \`sql/\` directory in alphabetical order.
|
|
1839
|
+
Tracks checksums to skip unchanged files on subsequent runs.
|
|
1840
|
+
|
|
1841
|
+
Use \`--force\` to rebuild everything regardless of checksums.
|
|
1842
|
+
|
|
1843
|
+
## Examples
|
|
1844
|
+
|
|
1845
|
+
noorm -H run build
|
|
1846
|
+
noorm -H --force run build
|
|
1847
|
+
noorm -H --dry-run run build
|
|
1848
|
+
|
|
1849
|
+
## JSON Output
|
|
1850
|
+
|
|
1851
|
+
\`\`\`json
|
|
1852
|
+
{
|
|
1853
|
+
"status": "success",
|
|
1854
|
+
"filesRun": 5,
|
|
1855
|
+
"filesSkipped": 2,
|
|
1856
|
+
"filesFailed": 0,
|
|
1857
|
+
"durationMs": 1234
|
|
1858
|
+
}
|
|
1859
|
+
\`\`\`
|
|
1860
|
+
|
|
1861
|
+
See \`noorm help run\` or \`noorm help run file\`.
|
|
1862
|
+
`,AF=async(t,e,r)=>{let[n,o]=await De({flags:e,logger:r,fn:i=>i.build({force:t.force??e.force})});return o?1:(r.info("Build completed successfully",{status:n.status,filesRun:n.filesRun,filesSkipped:n.filesSkipped,filesFailed:n.filesFailed,durationMs:n.durationMs}),n.status==="success"?0:2)};var Gg={};ot(Gg,{help:()=>MF,run:()=>$F});var MF=`
|
|
1863
|
+
# RUN DIR
|
|
1864
|
+
|
|
1865
|
+
Execute all SQL files in a directory
|
|
1866
|
+
|
|
1867
|
+
## Usage
|
|
1868
|
+
|
|
1869
|
+
noorm run dir PATH
|
|
1870
|
+
noorm -H run dir PATH
|
|
1871
|
+
|
|
1872
|
+
## Arguments
|
|
1873
|
+
|
|
1874
|
+
PATH Path to the directory containing SQL files
|
|
1875
|
+
|
|
1876
|
+
## Description
|
|
1877
|
+
|
|
1878
|
+
Executes all SQL files in the specified directory in alphabetical order.
|
|
1879
|
+
Supports \`.sql\` and \`.sql.eta\` (templated) files.
|
|
1880
|
+
|
|
1881
|
+
## Examples
|
|
1882
|
+
|
|
1883
|
+
noorm -H run dir migrations/
|
|
1884
|
+
noorm -H run dir seeds/
|
|
1885
|
+
|
|
1886
|
+
See \`noorm help run\` or \`noorm help run file\`.
|
|
1887
|
+
`,$F=async(t,e,r)=>{if(!t.path)return r.error("Directory path required. Use --path <dir>"),1;let[n,o]=await De({flags:e,logger:r,fn:i=>i.runDir(t.path)});return o?1:(r.info(`Run directory ${n.status}`,{filesRun:n.filesRun,filesSkipped:n.filesSkipped,filesFailed:n.filesFailed}),n.status==="success"?0:1)};var Xg={};ot(Xg,{help:()=>jF,run:()=>HF});var jF=`
|
|
1888
|
+
# RUN FILE
|
|
1889
|
+
|
|
1890
|
+
Execute a single SQL file
|
|
1891
|
+
|
|
1892
|
+
## Usage
|
|
1893
|
+
|
|
1894
|
+
noorm run file PATH
|
|
1895
|
+
noorm -H run file PATH
|
|
1896
|
+
|
|
1897
|
+
## Arguments
|
|
1898
|
+
|
|
1899
|
+
PATH Path to the SQL file to execute
|
|
1900
|
+
|
|
1901
|
+
## Description
|
|
1902
|
+
|
|
1903
|
+
Executes a single SQL file against the database.
|
|
1904
|
+
Supports \`.sql\` and \`.sql.eta\` (templated) files.
|
|
1905
|
+
|
|
1906
|
+
## Examples
|
|
1907
|
+
|
|
1908
|
+
noorm -H run file seed.sql
|
|
1909
|
+
noorm -H run file migrations/001_init.sql
|
|
1910
|
+
|
|
1911
|
+
## JSON Output
|
|
1912
|
+
|
|
1913
|
+
\`\`\`json
|
|
1914
|
+
{
|
|
1915
|
+
"filepath": "seed.sql",
|
|
1916
|
+
"status": "success",
|
|
1917
|
+
"durationMs": 45
|
|
1918
|
+
}
|
|
1919
|
+
\`\`\`
|
|
1920
|
+
|
|
1921
|
+
See \`noorm help run\` or \`noorm help run dir\`.
|
|
1922
|
+
`,HF=async(t,e,r)=>{if(!t.path)return r.error("File path required. Use --path <file.sql>"),1;let[n,o]=await De({flags:e,logger:r,fn:s=>s.runFile(t.path)});if(o)return 1;let i=n.status==="skipped";return r.info(`${n.filepath} (${n.status})`),n.status==="success"||i?0:1};var Jg={};ot(Jg,{help:()=>zg,run:()=>qF});var zg=`
|
|
1923
|
+
# RUN
|
|
1924
|
+
|
|
1925
|
+
Execute SQL files
|
|
1926
|
+
|
|
1927
|
+
## Usage
|
|
1928
|
+
|
|
1929
|
+
noorm run [subcommand] [options]
|
|
1930
|
+
|
|
1931
|
+
## Subcommands
|
|
1932
|
+
|
|
1933
|
+
build Execute all SQL files in schema directory
|
|
1934
|
+
file PATH Execute a single SQL file
|
|
1935
|
+
dir PATH Execute all SQL files in a directory
|
|
1936
|
+
|
|
1937
|
+
## Description
|
|
1938
|
+
|
|
1939
|
+
Run SQL files directly against the database. Unlike changes,
|
|
1940
|
+
these are not tracked for migration history.
|
|
1941
|
+
|
|
1942
|
+
Build mode executes files in the \`sql/\` directory in order,
|
|
1943
|
+
tracking checksums to skip unchanged files on subsequent runs.
|
|
1944
|
+
|
|
1945
|
+
## Options
|
|
1946
|
+
|
|
1947
|
+
-f, --force Force execution (skip checksum validation)
|
|
1948
|
+
--dry-run Preview without executing
|
|
1949
|
+
|
|
1950
|
+
## Examples
|
|
1951
|
+
|
|
1952
|
+
noorm -H run build
|
|
1953
|
+
noorm -H run file seed.sql
|
|
1954
|
+
noorm -H run dir migrations/
|
|
1955
|
+
noorm -H --force run build
|
|
1956
|
+
|
|
1957
|
+
## JSON Output
|
|
1958
|
+
|
|
1959
|
+
\`\`\`json
|
|
1960
|
+
{
|
|
1961
|
+
"status": "success",
|
|
1962
|
+
"filesRun": 5,
|
|
1963
|
+
"filesSkipped": 2,
|
|
1964
|
+
"filesFailed": 0,
|
|
1965
|
+
"durationMs": 1234
|
|
1966
|
+
}
|
|
1967
|
+
\`\`\`
|
|
1968
|
+
|
|
1969
|
+
See \`noorm help run build\` or \`noorm help change ff\`.
|
|
1970
|
+
`,qF=async(t,e,r)=>{let n=e.json?zg:Rt(zg);return process.stdout.write(n+"\\n"),0};var Zg={};ot(Zg,{help:()=>Qg,run:()=>KF});var Qg=`
|
|
1971
|
+
# SECRET
|
|
1972
|
+
|
|
1973
|
+
Manage secrets
|
|
1974
|
+
|
|
1975
|
+
## Usage
|
|
1976
|
+
|
|
1977
|
+
noorm secret
|
|
1978
|
+
|
|
1979
|
+
## Description
|
|
1980
|
+
|
|
1981
|
+
Opens the secrets management screen. Secrets are encrypted values
|
|
1982
|
+
stored per-config, used for sensitive connection parameters.
|
|
1983
|
+
|
|
1984
|
+
Common secrets:
|
|
1985
|
+
- \`DATABASE_PASSWORD\`
|
|
1986
|
+
- \`SSL_CERTIFICATE\`
|
|
1987
|
+
- \`API_KEY\`
|
|
1988
|
+
|
|
1989
|
+
> Secrets are stored encrypted in \`.noorm/state.enc\`.
|
|
1990
|
+
|
|
1991
|
+
> TUI only - not available in headless mode.
|
|
1992
|
+
|
|
1993
|
+
See \`noorm help config\`.
|
|
1994
|
+
`,KF=async(t,e,r)=>{let n=e.json?Qg:Rt(Qg);return process.stdout.write(n+"\\n"),0};var ty={};ot(ty,{help:()=>ey,run:()=>VF});var ey=`
|
|
1995
|
+
# SETTINGS
|
|
1996
|
+
|
|
1997
|
+
View/edit project settings
|
|
1998
|
+
|
|
1999
|
+
## Usage
|
|
2000
|
+
|
|
2001
|
+
noorm settings
|
|
2002
|
+
|
|
2003
|
+
## Description
|
|
2004
|
+
|
|
2005
|
+
Opens the settings screen to view and modify project configuration.
|
|
2006
|
+
Settings are stored in \`.noorm/settings.yml\`.
|
|
2007
|
+
|
|
2008
|
+
Settings include:
|
|
2009
|
+
- Stage definitions (dev, staging, production)
|
|
2010
|
+
- Build rules and paths
|
|
2011
|
+
- Logging configuration
|
|
2012
|
+
- Identity defaults
|
|
2013
|
+
|
|
2014
|
+
> TUI only - not available in headless mode.
|
|
2015
|
+
|
|
2016
|
+
See \`noorm help config\`.
|
|
2017
|
+
`,VF=async(t,e,r)=>{let n=e.json?ey:Rt(ey);return process.stdout.write(n+"\\n"),0};var Ka,US=`
|
|
2018
|
+
# HELP
|
|
2019
|
+
|
|
2020
|
+
Show help for commands
|
|
2021
|
+
|
|
2022
|
+
## Usage
|
|
2023
|
+
|
|
2024
|
+
noorm help [command] [subcommand]
|
|
2025
|
+
noorm -H help [command]
|
|
2026
|
+
|
|
2027
|
+
## Description
|
|
2028
|
+
|
|
2029
|
+
Displays help information for noorm commands.
|
|
2030
|
+
Without arguments, lists all available commands.
|
|
2031
|
+
|
|
2032
|
+
## Examples
|
|
2033
|
+
|
|
2034
|
+
noorm help
|
|
2035
|
+
noorm help config
|
|
2036
|
+
noorm help config use
|
|
2037
|
+
noorm -H help change ff
|
|
2038
|
+
|
|
2039
|
+
See \`noorm help config\`, \`noorm help change\`, or \`noorm help run\` for more.
|
|
2040
|
+
`;function UF(){if(!Ka)return"";let t=Object.keys(Ka).filter(n=>n!=="help").sort(),e={};for(let n of t){let o=n.split("/"),i=o[0];e[i]||(e[i]=[]),o.length>1&&e[i].push(o.slice(1).join(" "))}let r=["## Available Commands",""];for(let[n,o]of Object.entries(e))if(o.length===0)r.push(` ${n}`);else{let i=o.join(", ");r.push(` ${n.padEnd(12)} ${i}`)}return r.push(""),r.push("Run `noorm help <command>` for detailed help on any command."),r.join(`
|
|
2041
|
+
`)}var YF=async(t,e,r)=>{if(!Ka)throw new Error("Handlers not initialized");if(!t.name){let s=UF(),a=`${US}
|
|
2042
|
+
${s}`;if(e.json){let c=Object.keys(Ka).filter(l=>l!=="help").sort();process.stdout.write(JSON.stringify({topics:c})+`
|
|
2043
|
+
`)}else{let c=Rt(a);process.stdout.write(`${c}
|
|
2044
|
+
`)}return 0}let n=t.name.replace(" ","/"),o=Ka[n];if(!o)return r.error(`Unknown command: ${n.replace("/"," ")}`),1;let i=o.help||"No help available for this command.";if(e.json)process.stdout.write(JSON.stringify({topic:n,content:i})+`
|
|
2045
|
+
`);else{let s=Rt(i);process.stdout.write(`${s}
|
|
2046
|
+
`)}return 0},YS=t=>(Ka=t,{run:YF,help:US});var ry={change:wg,"change/ff":xg,"change/history":bg,"change/revert":Sg,"change/run":Cg,config:Ng,"config/add":Eg,"config/edit":kg,"config/rm":vg,"config/use":Dg,db:Mg,"db/explore":Lg,"db/explore/tables/detail":Fg,"db/explore/tables":Bg,"db/teardown":Ig,"db/truncate":Og,identity:jg,lock:Yg,"lock/acquire":Hg,"lock/force":qg,"lock/release":Kg,"lock/status":Vg,run:Jg,"run/build":Wg,"run/dir":Gg,"run/file":Xg,secret:Zg,settings:ty};ry.help=YS(ry);function GS(t){return t.tui?!1:t.headless?!0:ps()}async function JF(t,e){let r=hi(t),[,n]=await WS(()=>r.load()),o=n?{}:r.settings,i=XF(t,".noorm","noorm.log"),[s]=zF(()=>GF(i,{flags:"a"})),a="info";Ih()&&(a="verbose");let c={projectRoot:t,settings:o,config:{enabled:!0,level:MS("log.level",a)},console:process.stdout,file:s??void 0,json:e,color:!e};return new ki(c)}async function XS(t,e,r){let n=process.cwd(),o=await JF(n,r.json);await o.start();let i=ry[t],s=t.replace("/"," ");if(!i)return o.error(`Unknown command: ${s}`),await o.stop(),1;let{run:a}=i;if(!a)return o.error(`Command not implemented in headless mode: ${s}`),await o.stop(),1;let[c,l]=await WS(()=>a(e,r,o));if(l){let m=l instanceof Error?l:new Error(String(l));return o.error(m.message),await o.stop(),1}return await o.stop(),c}import{jsx as aB}from"react/jsx-runtime";var eB=`
|
|
2047
|
+
Usage
|
|
2048
|
+
$ noorm [command] [subcommand] [options]
|
|
2049
|
+
|
|
2050
|
+
Commands
|
|
2051
|
+
(none) Open home screen (TUI mode)
|
|
2052
|
+
config Manage database configurations
|
|
2053
|
+
config add Add a new configuration
|
|
2054
|
+
config edit <name> Edit a configuration
|
|
2055
|
+
config rm <name> Remove a configuration
|
|
2056
|
+
config use <name> Set active configuration
|
|
2057
|
+
|
|
2058
|
+
change Manage changes
|
|
2059
|
+
change add Create a new change
|
|
2060
|
+
change run <name> Apply a change
|
|
2061
|
+
change revert <name> Revert a change
|
|
2062
|
+
change next [count] Apply next N pending changes
|
|
2063
|
+
change ff Apply all pending changes
|
|
2064
|
+
change rewind [n] Revert recent changes
|
|
2065
|
+
|
|
2066
|
+
run build Build schema from SQL files
|
|
2067
|
+
run file <path> Execute a single SQL file
|
|
2068
|
+
run dir <path> Execute all SQL in a directory
|
|
2069
|
+
|
|
2070
|
+
db create Create database and tracking tables
|
|
2071
|
+
db destroy Drop all managed objects
|
|
2072
|
+
db explore Explore database schema
|
|
2073
|
+
|
|
2074
|
+
lock status Show lock status
|
|
2075
|
+
lock acquire Acquire lock
|
|
2076
|
+
lock release Release lock
|
|
2077
|
+
lock force Force release lock
|
|
2078
|
+
|
|
2079
|
+
settings View/edit project settings
|
|
2080
|
+
secret Manage secrets
|
|
2081
|
+
identity Manage identity
|
|
2082
|
+
|
|
2083
|
+
Options
|
|
2084
|
+
--headless, -H Force headless mode (no TUI)
|
|
2085
|
+
--tui, -T Force TUI mode (ignore TTY detection)
|
|
2086
|
+
--json Output JSON (headless mode only)
|
|
2087
|
+
--yes, -y Skip confirmation prompts
|
|
2088
|
+
--config, -c <name> Use specific configuration (defaults to active config)
|
|
2089
|
+
--force, -f Force operation
|
|
2090
|
+
--dry-run Preview without executing
|
|
2091
|
+
--help, -h Show this help
|
|
2092
|
+
--version Show version
|
|
2093
|
+
|
|
2094
|
+
Examples
|
|
2095
|
+
$ noorm # Start TUI
|
|
2096
|
+
$ noorm config # Go to config screen
|
|
2097
|
+
$ noorm -H run build # Build in CI
|
|
2098
|
+
$ noorm --json change ff # Fast-forward with JSON output
|
|
2099
|
+
$ noorm -c prod change run users # Run change on prod config
|
|
2100
|
+
`;function tB(){let t=QF(eB,{importMeta:import.meta,flags:{headless:{type:"boolean",shortFlag:"H",default:!1},tui:{type:"boolean",shortFlag:"T",default:!1},json:{type:"boolean",default:!1},yes:{type:"boolean",shortFlag:"y",default:!1},config:{type:"string",shortFlag:"c"},force:{type:"boolean",shortFlag:"f",default:!1},dryRun:{type:"boolean",default:!1}}}),e={headless:t.flags.headless,tui:t.flags.tui,json:t.flags.json,yes:t.flags.yes,config:t.flags.config,force:t.flags.force,dryRun:t.flags.dryRun},{route:r,params:n}=iB(t.input);return{mode:GS(e)?"headless":"tui",route:r,params:n,flags:e}}var rB=new Set(["help","use","edit","rm","add","revert","file","dir","detail"]);function nB(t,e){return!!(rB.has(t)||t==="run"&&e.length>0&&e[e.length-1]==="change")}function oB(t){return/^\d+$/.test(t)||t.includes("/")||t.endsWith(".sql")||t.endsWith(".eta")?!1:/^[a-z]+$/.test(t)}function iB(t){if(t.length===0)return{route:"home",params:{}};let e=t[0];if(e.includes(":")){let s=e.replace(/:/g,"/"),a=ny(t.slice(1));return{route:s,params:a}}if(e.includes("/")){let s=ny(t.slice(1));return{route:e,params:s}}let r=[],n=0;for(let s=0;s<t.length;s++){let a=t[s];if(oB(a)){if(r.push(a),n=s+1,nB(a,r.slice(0,-1)))break}else break}let o=r.join("/")||"home",i=ny(t.slice(n));return{route:o,params:i}}function ny(t){if(t.length===0)return{};let e={},r=[];for(let n of t){let o=parseInt(n,10);if(!isNaN(o)){e.count=o;continue}if(n.includes("/")||n.endsWith(".sql")||n.endsWith(".sql.eta")){e.path=n;continue}r.push(n)}return r.length>0&&(e.name=r[0]),r.length>1&&(e.topic=r.join("/")),e}async function sB(){let t=Td();qd(process.cwd());let{mode:e,route:r,params:n,flags:o}=tB(),i=await Wa()||!!process.env.NOORM_IDENTITY;if(e==="headless"){!i&&r!=="init"&&r!=="identity/init"&&(console.error("No identity configured. Run: noorm init"),process.exit(1));let l=await XS(r,n,o);process.exit(l)}let s=r;i?!t.hasProject&&r==="home"&&(s="init"):s="init";let a={...n,...o.force&&{force:!0}},{waitUntilExit:c}=ZF(aB(FS,{initialRoute:s,initialParams:a}),{exitOnCtrlC:!0,patchConsole:!0});await c()}sB().catch(t=>{console.error("Fatal error:",t),process.exit(1)});
|