@vaiftech/cli 1.9.9 → 1.10.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/cli.cjs CHANGED
@@ -1,20 +1,20 @@
1
1
  #!/usr/bin/env node
2
- 'use strict';require('dotenv/config');var module$1=require('module'),commander=require('commander'),f=require('chalk'),U=require('fs'),_=require('path'),Pt=require('pg'),Q=require('ora'),Ct=require('prettier'),yt=require('dotenv'),vt=require('os'),child_process=require('child_process'),Ee=require('readline');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var f__default=/*#__PURE__*/_interopDefault(f);var U__default=/*#__PURE__*/_interopDefault(U);var ___default=/*#__PURE__*/_interopDefault(_);var Pt__default=/*#__PURE__*/_interopDefault(Pt);var Q__default=/*#__PURE__*/_interopDefault(Q);var Ct__default=/*#__PURE__*/_interopDefault(Ct);var yt__default=/*#__PURE__*/_interopDefault(yt);var vt__default=/*#__PURE__*/_interopDefault(vt);var Ee__default=/*#__PURE__*/_interopDefault(Ee);var mt=()=>typeof document>"u"?new URL(`file:${__filename}`).href:document.currentScript&&document.currentScript.tagName.toUpperCase()==="SCRIPT"?document.currentScript.src:new URL("main.js",document.baseURI).href,j=mt();yt__default.default.config();async function A(t){let e=___default.default.resolve(t);if(!U__default.default.existsSync(e))return null;try{let n=U__default.default.readFileSync(e,"utf-8"),o=JSON.parse(n);return o.database?.url&&(o.database.url=Se(o.database.url)),o.api?.apiKey&&(o.api.apiKey=Se(o.api.apiKey)),o}catch{throw new Error(`Failed to parse config file: ${t}`)}}function Se(t){return t.replace(/\$\{([^}]+)\}/g,(e,n)=>process.env[n]||e)}var se=___default.default.join(vt__default.default.homedir(),".vaif"),K=___default.default.join(se,"auth.json"),H=process.env.VAIF_API_URL||"https://api.vaif.studio";function It(){U__default.default.existsSync(se)||U__default.default.mkdirSync(se,{recursive:true});}function Te(t){It(),U__default.default.writeFileSync(K,JSON.stringify(t,null,2),"utf-8"),U__default.default.chmodSync(K,384);}function I(){if(!U__default.default.existsSync(K))return null;try{let t=U__default.default.readFileSync(K,"utf-8");return JSON.parse(t)}catch{return null}}function At(t){let e=Ee__default.default.createInterface({input:process.stdin,output:process.stdout});return new Promise(n=>{e.question(t,o=>{e.close(),n(o);});})}function wt(t){return new Promise(e=>{let n=Ee__default.default.createInterface({input:process.stdin,output:process.stdout});process.stdin;let s=process.stdout.write.bind(process.stdout),i=false;process.stdout.write=((...r)=>i?true:s(...r)),n.question(t,r=>{i=false,process.stdout.write=s,console.log(""),n.close(),e(r);}),i=true;})}function St(t){let e=process.platform,n;e==="darwin"?n=`open "${t}"`:e==="win32"?n=`start "" "${t}"`:n=`xdg-open "${t}"`,child_process.exec(n,o=>{});}function _t(t){return new Promise(e=>setTimeout(e,t))}async function Et(t){try{let e=await fetch(`${H}/auth/me`,{headers:{Authorization:`Bearer ${t}`}});if(e.ok){let n=await e.json();return {valid:!0,email:n.user?.email||n.email}}return {valid:!1}}catch{return {valid:false}}}async function Tt(t){let e=Q__default.default();e.start("Setting up authentication...");let n,o;try{let a=await fetch(`${H}/auth/cli/authorize`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({})});a.ok||(e.fail("Failed to initiate authentication"),console.log(f__default.default.red(`
3
- Could not connect to VAIF API. Please try again later.`)),process.exit(1));let l=await a.json();n=l.code,o=l.url;}catch{e.fail("Failed to connect to VAIF API"),console.log(f__default.default.red(`
4
- Could not connect to VAIF API.`)),console.log(f__default.default.gray("Check your internet connection or try: vaif login --email")),process.exit(1);}e.stop(),console.log(f__default.default.cyan(" Opening browser for authentication...")),console.log(""),console.log(f__default.default.gray(" If the browser doesn't open, visit this URL:")),console.log(f__default.default.white(` ${o}`)),console.log(""),St(o),e.start("Waiting for browser authentication...");let s=12e4,i=2e3,r=Date.now();for(;Date.now()-r<s;){await _t(i);try{let a=await fetch(`${H}/auth/cli/token`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({code:n})});if(!a.ok){let d=await a.json();(d.error==="ExpiredCode"||d.error==="InvalidCode")&&(e.fail("Authentication expired"),console.log(f__default.default.red(`
5
- The authentication session expired. Please try again.`)),process.exit(1));continue}let l=await a.json();if(l.ok&&l.accessToken){let d={token:l.accessToken,email:l.user?.email,projectId:t,expiresAt:new Date(Date.now()+l.expiresIn*1e3).toISOString()};Te(d),e.succeed("Logged in successfully"),console.log(""),l.user?.email&&console.log(f__default.default.green(` Authenticated as: ${l.user.email}`)),console.log(f__default.default.gray(` Config saved to: ${K}`)),console.log("");return}}catch{}}e.fail("Authentication timed out"),console.log(f__default.default.red(`
6
- Timed out waiting for browser authentication.`)),console.log(f__default.default.gray("Try again or use: vaif login --email")),process.exit(1);}async function xt(t){console.log(""),console.log(f__default.default.bold("VAIF CLI Login")),console.log(f__default.default.gray("Enter your VAIF account credentials")),console.log("");let e=await At(f__default.default.cyan(" Email: "));(!e||e.trim()==="")&&(console.log(f__default.default.red(`
7
- No email provided. Login cancelled.`)),process.exit(1));let n=await wt(f__default.default.cyan(" Password: "));(!n||n.trim()==="")&&(console.log(f__default.default.red(`
8
- No password provided. Login cancelled.`)),process.exit(1));let o=Q__default.default("Authenticating...").start();try{let s=await fetch(`${H}/auth/cli/login`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({email:e.trim(),password:n})}),i=await s.json();(!s.ok||!i.ok)&&(o.fail("Login failed"),console.log(f__default.default.red(`
9
- ${i.message||"Invalid email or password."}`)),process.exit(1));let r={token:i.accessToken,email:i.user?.email,projectId:t,expiresAt:new Date(Date.now()+i.expiresIn*1e3).toISOString()};Te(r),o.succeed("Logged in successfully"),console.log(""),i.user?.email&&console.log(f__default.default.green(` Authenticated as: ${i.user.email}`)),console.log(f__default.default.gray(` Config saved to: ${K}`)),console.log("");}catch{o.fail("Failed to connect to VAIF API"),console.log(f__default.default.red(`
10
- Could not connect to VAIF API. Please try again later.`)),process.exit(1);}}async function xe(t){console.log(""),console.log(f__default.default.bold("Welcome to VAIF CLI")),console.log(f__default.default.gray("Authenticate to access your VAIF projects")),console.log(""),t.email?await xt(t.projectId):await Tt(t.projectId),console.log(f__default.default.gray("You can now use VAIF CLI commands like:")),console.log(f__default.default.gray(" vaif pull - Pull remote schema")),console.log(f__default.default.gray(" vaif push - Push schema changes")),console.log(f__default.default.gray(" vaif generate - Generate TypeScript types")),console.log("");}async function Pe(){U__default.default.existsSync(K)?(U__default.default.unlinkSync(K),console.log(f__default.default.green("Logged out successfully"))):console.log(f__default.default.yellow("Not currently logged in"));}async function Fe(){let t=I();(!t||!t.token)&&(console.log(f__default.default.yellow("Not logged in")),console.log(f__default.default.gray("Run `vaif login` to authenticate")),process.exit(1));let e=Q__default.default("Checking authentication...").start(),{valid:n,email:o}=await Et(t.token);n||(e.fail("Session expired"),console.log(f__default.default.yellow(`
11
- Your session has expired. Please login again.`)),process.exit(1)),e.succeed("Authenticated"),console.log(""),console.log(f__default.default.green(` Email: ${o||t.email||"Unknown"}`)),t.projectId&&console.log(f__default.default.green(` Project: ${t.projectId}`)),console.log("");}var jt=process.env.VAIF_API_URL||"https://api.vaif.studio";async function Rt(t,e){let n=await fetch(`${jt}/schema-engine/introspect/${e}`,{headers:{Authorization:`Bearer ${t}`,"Content-Type":"application/json"}});if(!n.ok){let a=await n.text();throw new Error(`API introspection failed: ${a}`)}let o=await n.json();if(!o.ok||!o.schemaExists)throw new Error("Project schema does not exist yet. Push a migration first with `vaif db push`.");let s=new Map,i=[];for(let a of o.tables){let l=a.columns.map(d=>({column_name:d.name,data_type:d.type,is_nullable:d.nullable?"YES":"NO",column_default:d.default,udt_name:d.type,is_identity:d.primaryKey&&d.default?.includes("gen_random_uuid")?"YES":"NO",character_maximum_length:null,numeric_precision:null,numeric_scale:null}));s.set(a.name,l);for(let d of a.foreignKeys)i.push({constraint_name:d.constraintName,table_name:a.name,column_name:d.columnName,foreign_table_name:d.refTable,foreign_column_name:d.refColumn});}return {tables:s,enums:new Map,foreignKeys:i}}async function kt(t,e){let n=await t.query(`
2
+ 'use strict';require('dotenv/config');var module$1=require('module'),commander=require('commander'),f=require('chalk'),A=require('fs'),S=require('path'),Vt=require('pg'),ie=require('ora'),Ot=require('prettier'),xt=require('dotenv'),Pt=require('os'),child_process=require('child_process'),Re=require('readline');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var f__default=/*#__PURE__*/_interopDefault(f);var A__default=/*#__PURE__*/_interopDefault(A);var S__default=/*#__PURE__*/_interopDefault(S);var Vt__default=/*#__PURE__*/_interopDefault(Vt);var ie__default=/*#__PURE__*/_interopDefault(ie);var Ot__default=/*#__PURE__*/_interopDefault(Ot);var xt__default=/*#__PURE__*/_interopDefault(xt);var Pt__default=/*#__PURE__*/_interopDefault(Pt);var Re__default=/*#__PURE__*/_interopDefault(Re);var St=()=>typeof document>"u"?new URL(`file:${__filename}`).href:document.currentScript&&document.currentScript.tagName.toUpperCase()==="SCRIPT"?document.currentScript.src:new URL("main.js",document.baseURI).href,N=St();xt__default.default.config();async function w(t){let e=S__default.default.resolve(t);if(!A__default.default.existsSync(e))return null;try{let o=A__default.default.readFileSync(e,"utf-8"),n=JSON.parse(o);return n.database?.url&&(n.database.url=Ce(n.database.url)),n.api?.apiKey&&(n.api.apiKey=Ce(n.api.apiKey)),n}catch{throw new Error(`Failed to parse config file: ${t}`)}}function Ce(t){return t.replace(/\$\{([^}]+)\}/g,(e,o)=>process.env[o]||e)}var fe=S__default.default.join(Pt__default.default.homedir(),".vaif"),J=S__default.default.join(fe,"auth.json"),te=process.env.VAIF_API_URL||"https://api.vaif.studio";function Ct(){A__default.default.existsSync(fe)||A__default.default.mkdirSync(fe,{recursive:true});}function Ue(t){Ct(),A__default.default.writeFileSync(J,JSON.stringify(t,null,2),"utf-8"),A__default.default.chmodSync(J,384);}function E(){if(!A__default.default.existsSync(J))return null;try{let t=A__default.default.readFileSync(J,"utf-8");return JSON.parse(t)}catch{return null}}function jt(t){let e=Re__default.default.createInterface({input:process.stdin,output:process.stdout});return new Promise(o=>{e.question(t,n=>{e.close(),o(n);});})}function Rt(t){return new Promise(e=>{let o=Re__default.default.createInterface({input:process.stdin,output:process.stdout});process.stdin;let i=process.stdout.write.bind(process.stdout),a=false;process.stdout.write=((...r)=>a?true:i(...r)),o.question(t,r=>{a=false,process.stdout.write=i,console.log(""),o.close(),e(r);}),a=true;})}function Ut(t){let e=process.platform,o;e==="darwin"?o=`open "${t}"`:e==="win32"?o=`start "" "${t}"`:o=`xdg-open "${t}"`,child_process.exec(o,n=>{});}function kt(t){return new Promise(e=>setTimeout(e,t))}async function Nt(t){try{let e=await fetch(`${te}/auth/me`,{headers:{Authorization:`Bearer ${t}`}});if(e.ok){let o=await e.json();return {valid:!0,email:o.user?.email||o.email}}return {valid:!1}}catch{return {valid:false}}}async function Lt(t){let e=ie__default.default();e.start("Setting up authentication...");let o,n;try{let s=await fetch(`${te}/auth/cli/authorize`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({})});s.ok||(e.fail("Failed to initiate authentication"),console.log(f__default.default.red(`
3
+ Could not connect to VAIF API. Please try again later.`)),process.exit(1));let c=await s.json();o=c.code,n=c.url;}catch{e.fail("Failed to connect to VAIF API"),console.log(f__default.default.red(`
4
+ Could not connect to VAIF API.`)),console.log(f__default.default.gray("Check your internet connection or try: vaif login --email")),process.exit(1);}e.stop(),console.log(f__default.default.cyan(" Opening browser for authentication...")),console.log(""),console.log(f__default.default.gray(" If the browser doesn't open, visit this URL:")),console.log(f__default.default.white(` ${n}`)),console.log(""),Ut(n),e.start("Waiting for browser authentication...");let i=12e4,a=2e3,r=Date.now();for(;Date.now()-r<i;){await kt(a);try{let s=await fetch(`${te}/auth/cli/token`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({code:o})});if(!s.ok){let l=await s.json();(l.error==="ExpiredCode"||l.error==="InvalidCode")&&(e.fail("Authentication expired"),console.log(f__default.default.red(`
5
+ The authentication session expired. Please try again.`)),process.exit(1));continue}let c=await s.json();if(c.ok&&c.accessToken){let l={token:c.accessToken,email:c.user?.email,projectId:t,expiresAt:new Date(Date.now()+c.expiresIn*1e3).toISOString()};Ue(l),e.succeed("Logged in successfully"),console.log(""),c.user?.email&&console.log(f__default.default.green(` Authenticated as: ${c.user.email}`)),console.log(f__default.default.gray(` Config saved to: ${J}`)),console.log("");return}}catch{}}e.fail("Authentication timed out"),console.log(f__default.default.red(`
6
+ Timed out waiting for browser authentication.`)),console.log(f__default.default.gray("Try again or use: vaif login --email")),process.exit(1);}async function Dt(t){console.log(""),console.log(f__default.default.bold("VAIF CLI Login")),console.log(f__default.default.gray("Enter your VAIF account credentials")),console.log("");let e=await jt(f__default.default.cyan(" Email: "));(!e||e.trim()==="")&&(console.log(f__default.default.red(`
7
+ No email provided. Login cancelled.`)),process.exit(1));let o=await Rt(f__default.default.cyan(" Password: "));(!o||o.trim()==="")&&(console.log(f__default.default.red(`
8
+ No password provided. Login cancelled.`)),process.exit(1));let n=ie__default.default("Authenticating...").start();try{let i=await fetch(`${te}/auth/cli/login`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({email:e.trim(),password:o})}),a=await i.json();(!i.ok||!a.ok)&&(n.fail("Login failed"),console.log(f__default.default.red(`
9
+ ${a.message||"Invalid email or password."}`)),process.exit(1));let r={token:a.accessToken,email:a.user?.email,projectId:t,expiresAt:new Date(Date.now()+a.expiresIn*1e3).toISOString()};Ue(r),n.succeed("Logged in successfully"),console.log(""),a.user?.email&&console.log(f__default.default.green(` Authenticated as: ${a.user.email}`)),console.log(f__default.default.gray(` Config saved to: ${J}`)),console.log("");}catch{n.fail("Failed to connect to VAIF API"),console.log(f__default.default.red(`
10
+ Could not connect to VAIF API. Please try again later.`)),process.exit(1);}}async function ke(t){console.log(""),console.log(f__default.default.bold("Welcome to VAIF CLI")),console.log(f__default.default.gray("Authenticate to access your VAIF projects")),console.log(""),t.email?await Dt(t.projectId):await Lt(t.projectId),console.log(f__default.default.gray("You can now use VAIF CLI commands like:")),console.log(f__default.default.gray(" vaif pull - Pull remote schema")),console.log(f__default.default.gray(" vaif push - Push schema changes")),console.log(f__default.default.gray(" vaif generate - Generate TypeScript types")),console.log("");}async function Ne(){A__default.default.existsSync(J)?(A__default.default.unlinkSync(J),console.log(f__default.default.green("Logged out successfully"))):console.log(f__default.default.yellow("Not currently logged in"));}async function Le(){let t=E();(!t||!t.token)&&(console.log(f__default.default.yellow("Not logged in")),console.log(f__default.default.gray("Run `vaif login` to authenticate")),process.exit(1));let e=ie__default.default("Checking authentication...").start(),{valid:o,email:n}=await Nt(t.token);o||(e.fail("Session expired"),console.log(f__default.default.yellow(`
11
+ Your session has expired. Please login again.`)),process.exit(1)),e.succeed("Authenticated"),console.log(""),console.log(f__default.default.green(` Email: ${n||t.email||"Unknown"}`)),t.projectId&&console.log(f__default.default.green(` Project: ${t.projectId}`)),console.log("");}var Mt=process.env.VAIF_API_URL||"https://api.vaif.studio";async function Kt(t,e){let o=await fetch(`${Mt}/schema-engine/introspect/${e}`,{headers:{Authorization:`Bearer ${t}`,"Content-Type":"application/json"}});if(!o.ok){let s=await o.text();throw new Error(`API introspection failed: ${s}`)}let n=await o.json();if(!n.ok||!n.schemaExists)throw new Error("Project schema does not exist yet. Push a migration first with `vaif db push`.");let i=new Map,a=[];for(let s of n.tables){let c=s.columns.map(l=>({column_name:l.name,data_type:l.type,is_nullable:l.nullable?"YES":"NO",column_default:l.default,udt_name:l.type,is_identity:l.primaryKey&&l.default?.includes("gen_random_uuid")?"YES":"NO",character_maximum_length:null,numeric_precision:null,numeric_scale:null}));i.set(s.name,c);for(let l of s.foreignKeys)a.push({constraint_name:l.constraintName,table_name:s.name,column_name:l.columnName,foreign_table_name:l.refTable,foreign_column_name:l.refColumn});}return {tables:i,enums:new Map,foreignKeys:a}}async function Bt(t,e){let o=await t.query(`
12
12
  SELECT table_name, table_type
13
13
  FROM information_schema.tables
14
14
  WHERE table_schema = $1
15
15
  AND table_type = 'BASE TABLE'
16
16
  ORDER BY table_name
17
- `,[e]),o=await t.query(`
17
+ `,[e]),n=await t.query(`
18
18
  SELECT
19
19
  table_name,
20
20
  column_name,
@@ -29,7 +29,7 @@ Your session has expired. Please login again.`)),process.exit(1)),e.succeed("Aut
29
29
  FROM information_schema.columns
30
30
  WHERE table_schema = $1
31
31
  ORDER BY table_name, ordinal_position
32
- `,[e]),s=await t.query(`
32
+ `,[e]),i=await t.query(`
33
33
  SELECT
34
34
  tc.constraint_name,
35
35
  tc.table_name,
@@ -45,7 +45,7 @@ Your session has expired. Please login again.`)),process.exit(1)),e.succeed("Aut
45
45
  AND ccu.table_schema = tc.table_schema
46
46
  WHERE tc.constraint_type = 'FOREIGN KEY'
47
47
  AND tc.table_schema = $1
48
- `,[e]),i=await t.query(`
48
+ `,[e]),a=await t.query(`
49
49
  SELECT
50
50
  t.typname as enum_name,
51
51
  e.enumlabel as enum_value
@@ -54,24 +54,24 @@ Your session has expired. Please login again.`)),process.exit(1)),e.succeed("Aut
54
54
  JOIN pg_namespace n ON n.oid = t.typnamespace
55
55
  WHERE n.nspname = $1
56
56
  ORDER BY t.typname, e.enumsortorder
57
- `,[e]),r=new Map;for(let l of n.rows)r.set(l.table_name,[]);for(let l of o.rows){let d=r.get(l.table_name);d&&d.push(l);}let a=new Map;for(let l of i.rows){let d=a.get(l.enum_name)||[];d.push(l.enum_value),a.set(l.enum_name,d);}return {tables:r,enums:a,foreignKeys:s.rows}}var ce={smallint:"number",integer:"number",bigint:"string",int2:"number",int4:"number",int8:"string",decimal:"string",numeric:"string",real:"number",float4:"number",float8:"number","double precision":"number",money:"string",boolean:"boolean",bool:"boolean",text:"string",varchar:"string",char:"string",character:"string","character varying":"string",name:"string",citext:"string",date:"string",time:"string",timetz:"string","time without time zone":"string","time with time zone":"string",timestamp:"string",timestamptz:"string","timestamp without time zone":"string","timestamp with time zone":"string",interval:"string",bytea:"Buffer",uuid:"string",json:"unknown",jsonb:"unknown",inet:"string",cidr:"string",macaddr:"string",macaddr8:"string",point:"{ x: number; y: number }",line:"string",lseg:"string",box:"string",path:"string",polygon:"string",circle:"string",ARRAY:"unknown[]"};function Nt(t,e){let{data_type:n,udt_name:o,is_nullable:s}=t;if(e.has(o)){let a=e.get(o).map(l=>`"${l}"`).join(" | ");return s==="YES"?`(${a}) | null`:a}if(n==="ARRAY"){let r=o.replace(/^_/,"");if(e.has(r)){let d=e.get(r).map(p=>`"${p}"`).join(" | ");return s==="YES"?`(${d})[] | null`:`(${d})[]`}let a=ce[r]||"unknown";return s==="YES"?`${a}[] | null`:`${a}[]`}let i=ce[n]||ce[o]||"unknown";return s==="YES"&&(i=`${i} | null`),i}function de(t){return t.split(/[_\-\s]+/).map(e=>e.charAt(0).toUpperCase()+e.slice(1).toLowerCase()).join("")}function Lt(t,e){let n=de(t),o=e.map(s=>` | "${s}"`).join(`
58
- `);return `export type ${n} =
59
- ${o};`}function Dt(t,e,n){let o=de(t),s=[],i=[],r=[];for(let p of e){let u=Nt(p,n),c=p.column_name,g=p.column_default!==null||p.is_identity==="YES",h=p.is_nullable==="YES";s.push(` ${c}: ${u};`),g||p.column_name==="id"?i.push(` ${c}?: ${u.replace(" | null","")} | null;`):h?i.push(` ${c}?: ${u};`):i.push(` ${c}: ${u.replace(" | null","")};`),r.push(` ${c}?: ${u.replace(" | null","")} | null;`);}let a=`export interface ${o} {
60
- ${s.join(`
61
- `)}
62
- }`,l=`export interface ${o}Insert {
57
+ `,[e]),r=new Map;for(let c of o.rows)r.set(c.table_name,[]);for(let c of n.rows){let l=r.get(c.table_name);l&&l.push(c);}let s=new Map;for(let c of a.rows){let l=s.get(c.enum_name)||[];l.push(c.enum_value),s.set(c.enum_name,l);}return {tables:r,enums:s,foreignKeys:i.rows}}var he={smallint:"number",integer:"number",bigint:"string",int2:"number",int4:"number",int8:"string",decimal:"string",numeric:"string",real:"number",float4:"number",float8:"number","double precision":"number",money:"string",boolean:"boolean",bool:"boolean",text:"string",varchar:"string",char:"string",character:"string","character varying":"string",name:"string",citext:"string",date:"string",time:"string",timetz:"string","time without time zone":"string","time with time zone":"string",timestamp:"string",timestamptz:"string","timestamp without time zone":"string","timestamp with time zone":"string",interval:"string",bytea:"Buffer",uuid:"string",json:"unknown",jsonb:"unknown",inet:"string",cidr:"string",macaddr:"string",macaddr8:"string",point:"{ x: number; y: number }",line:"string",lseg:"string",box:"string",path:"string",polygon:"string",circle:"string",ARRAY:"unknown[]"};function zt(t,e){let{data_type:o,udt_name:n,is_nullable:i}=t;if(e.has(n)){let s=e.get(n).map(c=>`"${c}"`).join(" | ");return i==="YES"?`(${s}) | null`:s}if(o==="ARRAY"){let r=n.replace(/^_/,"");if(e.has(r)){let l=e.get(r).map(p=>`"${p}"`).join(" | ");return i==="YES"?`(${l})[] | null`:`(${l})[]`}let s=he[r]||"unknown";return i==="YES"?`${s}[] | null`:`${s}[]`}let a=he[o]||he[n]||"unknown";return i==="YES"&&(a=`${a} | null`),a}function ye(t){return t.split(/[_\-\s]+/).map(e=>e.charAt(0).toUpperCase()+e.slice(1).toLowerCase()).join("")}function qt(t,e){let o=ye(t),n=e.map(i=>` | "${i}"`).join(`
58
+ `);return `export type ${o} =
59
+ ${n};`}function Yt(t,e,o){let n=ye(t),i=[],a=[],r=[];for(let p of e){let u=zt(p,o),d=p.column_name,g=p.column_default!==null||p.is_identity==="YES",y=p.is_nullable==="YES";i.push(` ${d}: ${u};`),g||p.column_name==="id"?a.push(` ${d}?: ${u.replace(" | null","")} | null;`):y?a.push(` ${d}?: ${u};`):a.push(` ${d}: ${u.replace(" | null","")};`),r.push(` ${d}?: ${u.replace(" | null","")} | null;`);}let s=`export interface ${n} {
63
60
  ${i.join(`
64
61
  `)}
65
- }`,d=`export interface ${o}Update {
62
+ }`,c=`export interface ${n}Insert {
63
+ ${a.join(`
64
+ `)}
65
+ }`,l=`export interface ${n}Update {
66
66
  ${r.join(`
67
67
  `)}
68
- }`;return {base:a,insert:l,update:d}}function Vt(t,e,n){let o=["/**"," * Auto-generated TypeScript types from database schema"," * Generated by @vaiftech/cli",` * Generated at: ${new Date().toISOString()}`," * "," * DO NOT EDIT MANUALLY - changes will be overwritten"," */",""];if(e.size>0){o.push("// ============ ENUMS ============"),o.push("");for(let[i,r]of e)o.push(Lt(i,r)),o.push("");}o.push("// ============ TABLES ============"),o.push("");let s=[];for(let[i,r]of t){let{base:a,insert:l,update:d}=Dt(i,r,e);s.push(i),o.push(a),o.push(""),o.push(l),o.push(""),o.push(d),o.push("");}o.push("// ============ DATABASE SCHEMA ============"),o.push(""),o.push("export interface Database {");for(let i of s){let r=de(i);o.push(` ${i}: {`),o.push(` Row: ${r};`),o.push(` Insert: ${r}Insert;`),o.push(` Update: ${r}Update;`),o.push(" };");}return o.push("}"),o.push(""),o.push("export type TableName = keyof Database;"),o.push(""),o.push("// ============ HELPER TYPES ============"),o.push(""),o.push('export type Row<T extends TableName> = Database[T]["Row"];'),o.push('export type Insert<T extends TableName> = Database[T]["Insert"];'),o.push('export type Update<T extends TableName> = Database[T]["Update"];'),o.push(""),o.join(`
69
- `)}async function je(t){let e=Q__default.default("Loading configuration...").start();try{let n=await A(t.config),o=t.connection||n?.database?.url||process.env.DATABASE_URL,s=o&&!o.includes("${"),i,r,a;if(s){e.text="Connecting to database...";let c=new Pt__default.default.Client({connectionString:o});await c.connect(),e.text="Introspecting schema...",{tables:i,enums:r,foreignKeys:a}=await kt(c,t.schema),await c.end();}else {let c=I();(!c||!c.token)&&(e.fail("No database connection and not logged in"),console.log(f__default.default.yellow(`
70
- Either:`)),console.log(f__default.default.gray(" 1. Run `vaif login` to authenticate (no DATABASE_URL needed)")),console.log(f__default.default.gray(" 2. Set DATABASE_URL in your .env file")),console.log(f__default.default.gray(" 3. Pass --connection postgresql://user:pass@host:5432/db")),process.exit(1));let g=n?.projectId||process.env.VAIF_PROJECT_ID||c.projectId;g||(e.fail("No project ID specified"),console.log(f__default.default.yellow(`
71
- Set projectId in vaif.config.json or use VAIF_PROJECT_ID env var.`)),process.exit(1)),e.text="Introspecting schema via API...",{tables:i,enums:r,foreignKeys:a}=await Rt(c.token,g);}if(i.size===0){e.warn("No tables found"),console.log(f__default.default.yellow(`
72
- Push a migration first: vaif db push`));return}e.text=`Generating types for ${i.size} tables...`;let l=Vt(i,r,a),d=await Ct__default.default.format(l,{parser:"typescript",semi:!0,singleQuote:!1,trailingComma:"es5",printWidth:100});if(t.dryRun){e.succeed("Generated types (dry run):"),console.log(""),console.log(f__default.default.gray("\u2500".repeat(60))),console.log(d),console.log(f__default.default.gray("\u2500".repeat(60)));return}let p=___default.default.resolve(t.output),u=___default.default.dirname(p);U__default.default.existsSync(u)||U__default.default.mkdirSync(u,{recursive:!0}),U__default.default.writeFileSync(p,d,"utf-8"),e.succeed(`Generated types for ${i.size} tables \u2192 ${f__default.default.cyan(t.output)}`),console.log(""),console.log(f__default.default.green("Generated:")),console.log(f__default.default.gray(` Tables: ${i.size}`)),console.log(f__default.default.gray(` Enums: ${r.size}`)),console.log(""),console.log(f__default.default.gray("Import in your code:")),console.log(f__default.default.cyan(` import type { Database, Row, Insert, Update } from "${t.output.replace(/\.ts$/,"")}";`));}catch(n){e.fail("Failed to generate types"),n instanceof Error&&(console.error(f__default.default.red(`
73
- Error: ${n.message}`)),n.message.includes("ECONNREFUSED")&&console.log(f__default.default.yellow(`
74
- Make sure your database is running and accessible.`))),process.exit(1);}}var q=[{name:"database",label:"Database",description:"CRUD queries, type-safe operations"},{name:"auth",label:"Authentication",description:"login, signup, OAuth, sessions"},{name:"realtime",label:"Realtime",description:"live subscriptions, presence"},{name:"storage",label:"Storage",description:"file uploads, signed URLs"},{name:"functions",label:"Functions",description:"serverless function calls"}],ke={"nextjs-fullstack":{name:"Next.js Full-Stack",description:"Next.js app with server/client VAIF client, auth middleware, and React hooks",tag:"Next.js",defaultFeatures:["database","auth"],files:[{path:"package.json",content:`{
68
+ }`;return {base:s,insert:c,update:l}}function Jt(t,e,o){let n=["/**"," * Auto-generated TypeScript types from database schema"," * Generated by @vaiftech/cli",` * Generated at: ${new Date().toISOString()}`," * "," * DO NOT EDIT MANUALLY - changes will be overwritten"," */",""];if(e.size>0){n.push("// ============ ENUMS ============"),n.push("");for(let[a,r]of e)n.push(qt(a,r)),n.push("");}n.push("// ============ TABLES ============"),n.push("");let i=[];for(let[a,r]of t){let{base:s,insert:c,update:l}=Yt(a,r,e);i.push(a),n.push(s),n.push(""),n.push(c),n.push(""),n.push(l),n.push("");}n.push("// ============ DATABASE SCHEMA ============"),n.push(""),n.push("export interface Database {");for(let a of i){let r=ye(a);n.push(` ${a}: {`),n.push(` Row: ${r};`),n.push(` Insert: ${r}Insert;`),n.push(` Update: ${r}Update;`),n.push(" };");}return n.push("}"),n.push(""),n.push("export type TableName = keyof Database;"),n.push(""),n.push("// ============ HELPER TYPES ============"),n.push(""),n.push('export type Row<T extends TableName> = Database[T]["Row"];'),n.push('export type Insert<T extends TableName> = Database[T]["Insert"];'),n.push('export type Update<T extends TableName> = Database[T]["Update"];'),n.push(""),n.join(`
69
+ `)}async function Ve(t){let e=ie__default.default("Loading configuration...").start();try{let o=await w(t.config),n=t.connection||o?.database?.url||process.env.DATABASE_URL,i=n&&!n.includes("${"),a,r,s;if(i){e.text="Connecting to database...";let d=new Vt__default.default.Client({connectionString:n});await d.connect(),e.text="Introspecting schema...",{tables:a,enums:r,foreignKeys:s}=await Bt(d,t.schema),await d.end();}else {let d=E();(!d||!d.token)&&(e.fail("No database connection and not logged in"),console.log(f__default.default.yellow(`
70
+ Either:`)),console.log(f__default.default.gray(" 1. Run `vaif login` to authenticate (no DATABASE_URL needed)")),console.log(f__default.default.gray(" 2. Set DATABASE_URL in your .env file")),console.log(f__default.default.gray(" 3. Pass --connection postgresql://user:pass@host:5432/db")),process.exit(1));let g=o?.projectId||process.env.VAIF_PROJECT_ID||d.projectId;g||(e.fail("No project ID specified"),console.log(f__default.default.yellow(`
71
+ Set projectId in vaif.config.json or use VAIF_PROJECT_ID env var.`)),process.exit(1)),e.text="Introspecting schema via API...",{tables:a,enums:r,foreignKeys:s}=await Kt(d.token,g);}if(a.size===0){e.warn("No tables found"),console.log(f__default.default.yellow(`
72
+ Push a migration first: vaif db push`));return}e.text=`Generating types for ${a.size} tables...`;let c=Jt(a,r,s),l=await Ot__default.default.format(c,{parser:"typescript",semi:!0,singleQuote:!1,trailingComma:"es5",printWidth:100});if(t.dryRun){e.succeed("Generated types (dry run):"),console.log(""),console.log(f__default.default.gray("\u2500".repeat(60))),console.log(l),console.log(f__default.default.gray("\u2500".repeat(60)));return}let p=S__default.default.resolve(t.output),u=S__default.default.dirname(p);A__default.default.existsSync(u)||A__default.default.mkdirSync(u,{recursive:!0}),A__default.default.writeFileSync(p,l,"utf-8"),e.succeed(`Generated types for ${a.size} tables \u2192 ${f__default.default.cyan(t.output)}`),console.log(""),console.log(f__default.default.green("Generated:")),console.log(f__default.default.gray(` Tables: ${a.size}`)),console.log(f__default.default.gray(` Enums: ${r.size}`)),console.log(""),console.log(f__default.default.gray("Import in your code:")),console.log(f__default.default.cyan(` import type { Database, Row, Insert, Update } from "${t.output.replace(/\.ts$/,"")}";`));}catch(o){e.fail("Failed to generate types"),o instanceof Error&&(console.error(f__default.default.red(`
73
+ Error: ${o.message}`)),o.message.includes("ECONNREFUSED")&&console.log(f__default.default.yellow(`
74
+ Make sure your database is running and accessible.`))),process.exit(1);}}var X=[{name:"database",label:"Database",description:"CRUD queries, type-safe operations"},{name:"auth",label:"Authentication",description:"login, signup, OAuth, sessions"},{name:"realtime",label:"Realtime",description:"live subscriptions, presence"},{name:"storage",label:"Storage",description:"file uploads, signed URLs"},{name:"functions",label:"Functions",description:"serverless function calls"}],Oe={"nextjs-fullstack":{name:"Next.js Full-Stack",description:"Next.js app with server/client VAIF client, auth middleware, and React hooks",tag:"Next.js",defaultFeatures:["database","auth"],files:[{path:"package.json",content:`{
75
75
  "name": "my-vaif-app",
76
76
  "private": true,
77
77
  "version": "0.1.0",
@@ -3775,94 +3775,57 @@ export const posts = pgTable("posts", {
3775
3775
 
3776
3776
  return Response.json({ message: \`Hello, \${name}!\` });
3777
3777
  }
3778
- `}]},dependencies:["@vaiftech/client","@vaiftech/auth"],postInstructions:["Copy .env.example to .env.local and fill in your project credentials","Create a 'product-images' storage bucket in your VAIF dashboard","Import storage helpers from '@/lib/storage' in your API routes","Use uploadProductImage() in your product creation flow","Run: npx vaif generate to generate TypeScript types"]}};function Ne(){console.log(""),console.log(f__default.default.bold("Available project templates")),console.log("");let t=26,e=22;console.log(` ${f__default.default.gray("Template".padEnd(t))}${f__default.default.gray("Stack".padEnd(e))}${f__default.default.gray("Description")}`),console.log(f__default.default.gray(" "+"-".repeat(t+e+40)));for(let[n,o]of Object.entries(ke))console.log(` ${f__default.default.cyan(n.padEnd(t))}${f__default.default.yellow(o.tag.padEnd(e))}${f__default.default.white(o.description)}`);console.log(""),console.log(f__default.default.gray("Usage:")),console.log(f__default.default.gray(" npx @vaiftech/cli init --template <name>")),console.log(f__default.default.gray(" npx @vaiftech/cli init -t nextjs-fullstack")),console.log(f__default.default.gray(" npx @vaiftech/cli init -t react-spa --features auth,database,realtime")),console.log(""),console.log(f__default.default.gray("Available features: auth, database, realtime, storage, functions")),console.log("");}async function Ut(t){if(!process.stdin.isTTY||!process.stdout.isTTY)return t;let e=new Set(t.map(o=>q.findIndex(s=>s.name===o)).filter(o=>o>=0)),n=0;return new Promise(o=>{let s=Ee__default.default.createInterface({input:process.stdin,output:process.stdout});Ee__default.default.emitKeypressEvents(process.stdin,s),process.stdin.setRawMode&&process.stdin.setRawMode(true);function i(){let a=q.length+2;process.stdout.write(`\x1B[${a}A`),r();}function r(){console.log(f__default.default.bold(`
3779
- ? Which VAIF features do you want to include?`)),q.forEach((a,l)=>{let d=e.has(l)?f__default.default.green("[x]"):"[ ]",p=l===n?f__default.default.cyan("> "):" ";console.log(`${p}${d} ${a.label} ${f__default.default.gray(`(${a.description})`)}`);}),console.log(f__default.default.gray(" (up/down to move, space to toggle, enter to confirm)"));}r(),process.stdin.on("keypress",(a,l)=>{if(l.name==="up"&&n>0)n--,i();else if(l.name==="down"&&n<q.length-1)n++,i();else if(l.name==="space")e.has(n)?e.delete(n):e.add(n),i();else if(l.name==="return"){process.stdin.setRawMode&&process.stdin.setRawMode(false),s.close();let d=[...e].sort().map(p=>q[p].name);o(d.length>0?d:t);}else l.name==="c"&&l.ctrl&&(process.stdin.setRawMode&&process.stdin.setRawMode(false),s.close(),process.exit(0));});})}async function pe(t,e={}){let n=ke[t];n||(console.log(f__default.default.red(`
3778
+ `}]},dependencies:["@vaiftech/client","@vaiftech/auth"],postInstructions:["Copy .env.example to .env.local and fill in your project credentials","Create a 'product-images' storage bucket in your VAIF dashboard","Import storage helpers from '@/lib/storage' in your API routes","Use uploadProductImage() in your product creation flow","Run: npx vaif generate to generate TypeScript types"]}};function Me(){console.log(""),console.log(f__default.default.bold("Available project templates")),console.log("");let t=26,e=22;console.log(` ${f__default.default.gray("Template".padEnd(t))}${f__default.default.gray("Stack".padEnd(e))}${f__default.default.gray("Description")}`),console.log(f__default.default.gray(" "+"-".repeat(t+e+40)));for(let[o,n]of Object.entries(Oe))console.log(` ${f__default.default.cyan(o.padEnd(t))}${f__default.default.yellow(n.tag.padEnd(e))}${f__default.default.white(n.description)}`);console.log(""),console.log(f__default.default.gray("Usage:")),console.log(f__default.default.gray(" npx @vaiftech/cli init --template <name>")),console.log(f__default.default.gray(" npx @vaiftech/cli init -t nextjs-fullstack")),console.log(f__default.default.gray(" npx @vaiftech/cli init -t react-spa --features auth,database,realtime")),console.log(""),console.log(f__default.default.gray("Available features: auth, database, realtime, storage, functions")),console.log("");}async function Gt(t){if(!process.stdin.isTTY||!process.stdout.isTTY)return t;let e=new Set(t.map(n=>X.findIndex(i=>i.name===n)).filter(n=>n>=0)),o=0;return new Promise(n=>{let i=Re__default.default.createInterface({input:process.stdin,output:process.stdout});Re__default.default.emitKeypressEvents(process.stdin,i),process.stdin.setRawMode&&process.stdin.setRawMode(true);function a(){let s=X.length+2;process.stdout.write(`\x1B[${s}A`),r();}function r(){console.log(f__default.default.bold(`
3779
+ ? Which VAIF features do you want to include?`)),X.forEach((s,c)=>{let l=e.has(c)?f__default.default.green("[x]"):"[ ]",p=c===o?f__default.default.cyan("> "):" ";console.log(`${p}${l} ${s.label} ${f__default.default.gray(`(${s.description})`)}`);}),console.log(f__default.default.gray(" (up/down to move, space to toggle, enter to confirm)"));}r(),process.stdin.on("keypress",(s,c)=>{if(c.name==="up"&&o>0)o--,a();else if(c.name==="down"&&o<X.length-1)o++,a();else if(c.name==="space")e.has(o)?e.delete(o):e.add(o),a();else if(c.name==="return"){process.stdin.setRawMode&&process.stdin.setRawMode(false),i.close();let l=[...e].sort().map(p=>X[p].name);n(l.length>0?l:t);}else c.name==="c"&&c.ctrl&&(process.stdin.setRawMode&&process.stdin.setRawMode(false),i.close(),process.exit(0));});})}async function be(t,e={}){let o=Oe[t];o||(console.log(f__default.default.red(`
3780
3780
  Unknown template: ${t}`)),console.log(f__default.default.yellow(`Run 'vaif templates' to see available templates.
3781
- `)),process.exit(1));let o;e.features&&e.features.length>0?o=e.features.filter(c=>q.some(g=>g.name===c)):e.addOnly?(console.log(f__default.default.red(`
3782
- No features specified.`)),console.log(f__default.default.yellow("Usage: vaif init --template <name> --add-features <features>")),console.log(f__default.default.gray("Available features: auth, database, realtime, storage, functions")),process.exit(1)):n.featureFiles&&Object.keys(n.featureFiles).length>0?o=await Ut(n.defaultFeatures??["database","auth"]):o=n.defaultFeatures??[],e.addOnly?(console.log(""),console.log(f__default.default.bold(`Adding features to ${f__default.default.cyan(n.name)} project...`)),console.log(f__default.default.gray(` Features: ${o.join(", ")}`)),console.log("")):(console.log(""),console.log(f__default.default.bold(`Scaffolding ${f__default.default.cyan(n.name)} template...`)),o.length>0&&console.log(f__default.default.gray(` Features: ${o.join(", ")}`)),console.log(""));let s=e.addOnly?[]:[...n.files],i=new Set,r=[];if(n.featureFiles)for(let c of o){let g=n.featureFiles[c];if(g)for(let h of g)i.add(h.path),r.push(h);}let a=s.filter(c=>!i.has(c.path)).concat(r),l=0,d=0;for(let c of a){let g=___default.default.resolve(c.path),h=___default.default.dirname(g);if(U__default.default.existsSync(h)||U__default.default.mkdirSync(h,{recursive:true}),c.path==="package.json"&&U__default.default.existsSync(g)&&!e.force)try{let T=JSON.parse(U__default.default.readFileSync(g,"utf-8")),D=JSON.parse(c.content),$=Ie=>{if(!Ie)return {};let Ae={};for(let[gt,W]of Object.entries(Ie))!W.startsWith("workspace:")&&!W.startsWith("link:")&&!W.startsWith("file:")&&(Ae[gt]=W);return Ae};T.dependencies={...$(T.dependencies),...D.dependencies||{}},T.devDependencies={...$(T.devDependencies),...D.devDependencies||{}},D.scripts&&(T.scripts={...T.scripts||{},...D.scripts}),U__default.default.writeFileSync(g,JSON.stringify(T,null,2)+`
3783
- `,"utf-8"),console.log(f__default.default.green(` merge ${c.path} (added dependencies)`)),l++;continue}catch{}if(U__default.default.existsSync(g)&&!e.force){console.log(f__default.default.yellow(` skip ${c.path} (already exists)`)),d++;continue}U__default.default.writeFileSync(g,c.content,"utf-8"),console.log(f__default.default.green(` create ${c.path}`)),l++;}console.log(""),l>0&&console.log(f__default.default.green(`Created ${l} file${l!==1?"s":""}.`)),d>0&&console.log(f__default.default.yellow(`Skipped ${d} file${d!==1?"s":""} (use --force to overwrite).`));let p={auth:{"@vaiftech/auth":"^1.0.0"},database:{},realtime:{},storage:{},functions:{}},u=___default.default.resolve("package.json");if(U__default.default.existsSync(u)&&o.length>0)try{let c=JSON.parse(U__default.default.readFileSync(u,"utf-8")),g=!1;for(let h of o){let T=p[h];if(T)for(let[D,$]of Object.entries(T))c.dependencies?.[D]||(c.dependencies=c.dependencies||{},c.dependencies[D]=$,g=!0);}g&&U__default.default.writeFileSync(u,JSON.stringify(c,null,2)+`
3784
- `,"utf-8");}catch{}(n.dependencies?.length||n.devDependencies?.length)&&(console.log(""),console.log(f__default.default.bold("Install dependencies:")),n.dependencies?.length&&console.log(f__default.default.cyan(` npm install ${n.dependencies.join(" ")}`)),n.devDependencies?.length&&console.log(f__default.default.cyan(` npm install -D ${n.devDependencies.join(" ")}`))),console.log(""),console.log(f__default.default.bold.green("Project scaffolded successfully!")),console.log(""),console.log(f__default.default.bold(" Next steps:")),n.postInstructions.forEach(c=>{console.log(f__default.default.gray(` ${c}`));}),console.log(""),console.log(f__default.default.gray(" Get your project credentials at https://console.vaif.studio/security/api-keys")),console.log("");}var Ot={$schema:"https://vaif.studio/schemas/config.json",projectId:"",database:{url:"${DATABASE_URL}",schema:"public"},types:{output:"./src/types/database.ts"},api:{baseUrl:"https://api.vaif.studio"}};async function Le(t){if(t.addFeatures){t.template||(console.log(f__default.default.red(`
3785
- --add-features requires --template to know which template to use.`)),console.log(f__default.default.gray("Example: vaif init --template react-spa --add-features functions,storage")),process.exit(1));let o=t.addFeatures.split(",").map(s=>s.trim());await pe(t.template,{force:t.force,features:o,addOnly:true});return}let e=Q__default.default("Initializing VAIF configuration...").start(),n=___default.default.resolve("vaif.config.json");U__default.default.existsSync(n)&&!t.force&&(e.fail("vaif.config.json already exists"),console.log(f__default.default.yellow(`
3786
- Use --force to overwrite existing configuration.`)),process.exit(1));try{if(U__default.default.writeFileSync(n,JSON.stringify(Ot,null,2),"utf-8"),e.succeed("Created vaif.config.json"),t.template){let o=t.features?t.features.split(",").map(s=>s.trim()):void 0;await pe(t.template,{force:t.force,features:o});}else {let o=___default.default.resolve(".env.example");if(U__default.default.existsSync(o)||(U__default.default.writeFileSync(o,`# VAIF Configuration
3787
- DATABASE_URL=postgresql://user:password@localhost:5432/database
3788
- VAIF_API_KEY=your-api-key
3789
- `,"utf-8"),console.log(f__default.default.gray("Created .env.example"))),t.typescript){let s=___default.default.resolve("src/types");U__default.default.existsSync(s)||(U__default.default.mkdirSync(s,{recursive:!0}),console.log(f__default.default.gray("Created src/types directory")));}console.log(""),console.log(f__default.default.green("VAIF initialized successfully!")),console.log(""),console.log(f__default.default.gray("Next steps:")),console.log(f__default.default.gray(" 1. Update vaif.config.json with your project ID")),console.log(f__default.default.gray(" 2. Set DATABASE_URL in your environment")),console.log(f__default.default.gray(" 3. Run: npx vaif generate")),console.log("");}}catch(o){e.fail("Failed to initialize"),o instanceof Error&&console.error(f__default.default.red(`
3790
- Error: ${o.message}`)),process.exit(1);}}var Bt=process.env.VAIF_API_URL||"https://api.vaif.studio";async function qt(t,e,n="public"){let o=await fetch(`${Bt}/projects/${e}/schema?schema=${n}`,{headers:{Authorization:`Bearer ${t}`,"Content-Type":"application/json"}});if(!o.ok){let s=await o.text();throw new Error(`Failed to fetch schema: ${s}`)}return o.json()}async function De(t){let e=Q__default.default(),n=I();(!n||!n.token)&&(console.log(f__default.default.red("Not logged in")),console.log(f__default.default.gray("Run `vaif login` first to authenticate")),process.exit(1));let o=t.config||"vaif.config.json",s=null;e.start("Loading configuration...");try{s=await A(o);}catch(r){e.fail("Failed to load config"),console.log(f__default.default.red(`
3791
- Error: ${r}`)),process.exit(1);}s||(e.fail("No configuration found"),console.log(f__default.default.yellow("\nRun `vaif init` to create a configuration file.")),process.exit(1));let i=t.projectId||s.projectId||process.env.VAIF_PROJECT_ID||n.projectId;i||(e.fail("No project ID specified"),console.log(f__default.default.yellow(`
3792
- Set projectId in vaif.config.json or use --project-id flag.`)),process.exit(1)),e.text="Fetching remote schema...";try{let r=t.schema||s.database?.schema||"public",a=await qt(n.token,i,r);e.succeed("Schema fetched successfully");let l=t.output||___default.default.resolve("vaif.schema.json"),d={$schema:"https://vaif.studio/schemas/schema.json",projectId:i,schema:r,pulledAt:new Date().toISOString(),...a};U__default.default.writeFileSync(l,JSON.stringify(d,null,2),"utf-8"),console.log(""),console.log(f__default.default.green(`Schema saved to: ${l}`)),console.log(""),console.log(f__default.default.gray("Schema summary:")),console.log(f__default.default.gray(` Tables: ${(a.tables||[]).length}`)),console.log(f__default.default.gray(` Enums: ${(a.enums||[]).length}`)),console.log(f__default.default.gray(` Functions: ${(a.functions||[]).length}`)),console.log(""),console.log(f__default.default.gray("Next steps:")),console.log(f__default.default.gray(" - Run `vaif generate` to generate TypeScript types")),console.log(f__default.default.gray(" - Edit the schema and run `vaif push` to deploy changes")),console.log("");}catch(r){e.fail("Failed to fetch schema"),r instanceof Error&&console.log(f__default.default.red(`
3793
- Error: ${r.message}`)),process.exit(1);}}var Ue=process.env.VAIF_API_URL||"https://api.vaif.studio";function Wt(t){let e=Ee__default.default.createInterface({input:process.stdin,output:process.stdout});return new Promise(n=>{e.question(t,o=>{e.close(),n(o);});})}async function Ht(t,e,n){let o=await fetch(`${Ue}/projects/${e}/schema/preview`,{method:"POST",headers:{Authorization:`Bearer ${t}`,"Content-Type":"application/json"},body:JSON.stringify({schema:n})});if(!o.ok){let s=await o.text();throw new Error(`Failed to preview changes: ${s}`)}return o.json()}async function Xt(t,e,n){let o=await fetch(`${Ue}/projects/${e}/schema/apply`,{method:"POST",headers:{Authorization:`Bearer ${t}`,"Content-Type":"application/json"},body:JSON.stringify({schema:n})});if(!o.ok){let s=await o.text();throw new Error(`Failed to apply changes: ${s}`)}return o.json()}function Qt(t){if(console.log(""),console.log(f__default.default.bold("Schema Changes:")),console.log(""),t.added.length===0&&t.modified.length===0&&t.removed.length===0){console.log(f__default.default.gray(" No changes detected. Schema is up to date."));return}if(t.added.length>0){console.log(f__default.default.green.bold(" + Added:"));for(let e of t.added)console.log(f__default.default.green(` + ${e.type}: ${e.name}`));console.log("");}if(t.modified.length>0){console.log(f__default.default.yellow.bold(" ~ Modified:"));for(let e of t.modified){console.log(f__default.default.yellow(` ~ ${e.type}: ${e.name}`));for(let n of e.changes)console.log(f__default.default.gray(` ${n}`));}console.log("");}if(t.removed.length>0){console.log(f__default.default.red.bold(" - Removed:"));for(let e of t.removed)console.log(f__default.default.red(` - ${e.type}: ${e.name}`));console.log("");}}async function $e(t){let e=Q__default.default(),n=I();(!n||!n.token)&&(console.log(f__default.default.red("Not logged in")),console.log(f__default.default.gray("Run `vaif login` first to authenticate")),process.exit(1));let o=t.config||"vaif.config.json",s=null;e.start("Loading configuration...");try{s=await A(o);}catch(l){e.fail("Failed to load config"),console.log(f__default.default.red(`
3794
- Error: ${l}`)),process.exit(1);}s||(e.fail("No configuration found"),console.log(f__default.default.yellow("\nRun `vaif init` to create a configuration file.")),process.exit(1));let i=t.projectId||s.projectId||process.env.VAIF_PROJECT_ID||n.projectId;i||(e.fail("No project ID specified"),console.log(f__default.default.yellow(`
3795
- Set projectId in vaif.config.json or use --project-id flag.`)),process.exit(1));let r=t.schema||___default.default.resolve("vaif.schema.json");U__default.default.existsSync(r)||(e.fail("No local schema found"),console.log(f__default.default.yellow(`
3796
- Expected schema file at: ${r}`)),console.log(f__default.default.gray("Run `vaif pull` first to fetch the current schema.")),process.exit(1));let a;try{let l=U__default.default.readFileSync(r,"utf-8");a=JSON.parse(l);}catch(l){e.fail("Failed to parse schema file"),l instanceof Error&&console.log(f__default.default.red(`
3797
- Error: ${l.message}`)),process.exit(1);}e.text="Calculating schema changes...";try{let{diff:l,sql:d}=await Ht(n.token,i,a);if(e.stop(),Qt(l),l.added.length===0&&l.modified.length===0&&l.removed.length===0){console.log("");return}if(d.length>0){console.log(f__default.default.bold("SQL Migrations:")),console.log("");for(let u of d)console.log(f__default.default.gray(` ${u}`));console.log("");}if(t.dryRun){console.log(f__default.default.yellow("Dry run mode - no changes applied.")),console.log(f__default.default.gray("Remove --dry-run to apply these changes."));return}if(!t.force){l.removed.length>0&&(console.log(f__default.default.red.bold("\u26A0\uFE0F Warning: This will remove tables/columns from your database.")),console.log(f__default.default.red(" This action cannot be undone!")),console.log(""));let c=await Wt(f__default.default.cyan("Apply these changes? [y/N] "));if(c.toLowerCase()!=="y"&&c.toLowerCase()!=="yes"){console.log(f__default.default.yellow(`
3798
- Cancelled. No changes applied.`));return}}e.start("Applying schema changes...");let p=await Xt(n.token,i,a);if(p.success){if(e.succeed("Schema changes applied successfully"),console.log(""),p.migrations.length>0){console.log(f__default.default.gray("Migrations applied:"));for(let u of p.migrations)console.log(f__default.default.gray(` - ${u}`));console.log("");}console.log(f__default.default.green("Your database schema is now up to date.")),console.log(f__default.default.gray("Run `vaif generate` to update your TypeScript types.")),console.log("");}else e.fail("Failed to apply some changes");}catch(l){e.fail("Failed to push schema changes"),l instanceof Error&&console.log(f__default.default.red(`
3799
- Error: ${l.message}`)),process.exit(1);}}var X=process.env.VAIF_API_URL||"https://api.vaif.studio";async function Zt(t,e,n,o){let s=new URL(`${X}/functions/project/${e}`);o&&s.searchParams.set("envId",o);let i=await fetch(s.toString(),{headers:{Authorization:`Bearer ${t}`}});if(!i.ok)return null;let r=await i.json(),a=r.functions||r;return Array.isArray(a)&&a.find(l=>l.name===n)||null}async function eo(t,e,n){let o=await fetch(`${X}/functions/`,{method:"POST",headers:{Authorization:`Bearer ${t}`,"Content-Type":"application/json"},body:JSON.stringify({projectId:e,name:n.name,runtime:n.runtime,entrypoint:n.entrypoint,envId:n.envId})});if(!o.ok){let s=await o.text();throw new Error(`Failed to create function: ${s}`)}return o.json()}async function to(t,e,n){let o=await fetch(`${X}/functions/${e}/source`,{method:"PUT",headers:{Authorization:`Bearer ${t}`,"Content-Type":"application/json"},body:JSON.stringify({sourceCode:n})});if(!o.ok){let s=await o.text();throw new Error(`Failed to deploy source: ${s}`)}}async function oo(t,e,n){let o=new URL(`${X}/functions/project/${e}`);n&&o.searchParams.set("envId",n);let s=await fetch(o.toString(),{headers:{Authorization:`Bearer ${t}`}});if(!s.ok){let r=await s.text();throw new Error(`Failed to list functions: ${r}`)}let i=await s.json();return i.functions||i}function Oe(t){switch(___default.default.extname(t).toLowerCase()){case ".ts":return "typescript";case ".js":case ".mjs":return "nodejs";case ".py":return "python";case ".go":return "go";case ".rs":return "rust";default:return "nodejs"}}function Me(t){let e=[],n=[".ts",".js",".mjs",".py",".go",".rs"],o=["drizzle.config.ts","tsconfig.json","package.json"];if(!U__default.default.existsSync(t))return e;let s=U__default.default.readdirSync(t,{withFileTypes:true});for(let i of s){let r=___default.default.join(t,i.name);if(i.isDirectory()){if(i.name!=="node_modules"&&!i.name.startsWith(".")){let a=U__default.default.readdirSync(r,{withFileTypes:true});for(let l of a)if(l.isFile()){let d=___default.default.extname(l.name).toLowerCase();if(n.includes(d)){e.push(___default.default.join(r,l.name));break}}}}else if(i.isFile()){let a=___default.default.extname(i.name).toLowerCase();n.includes(a)&&!o.includes(i.name)&&e.push(r);}}return e}async function ze(t){let e=Q__default.default(),n=I();(!n||!n.token)&&(console.log(f__default.default.red("Not logged in")),console.log(f__default.default.gray("Run `vaif login` first to authenticate")),process.exit(1));let o=t.config||"vaif.config.json",s=null;try{s=await A(o);}catch{}let i=t.projectId||s?.projectId||process.env.VAIF_PROJECT_ID||n.projectId;i||(console.log(f__default.default.red("No project ID specified")),console.log(f__default.default.yellow("Set projectId in vaif.config.json or use --project-id flag.")),process.exit(1)),console.log(""),console.log(f__default.default.bold("VAIF Functions Deploy")),console.log(""),e.start("Scanning for function files...");let r=___default.default.resolve("functions"),a=___default.default.resolve("src/functions"),l=[];if(t.entrypoint){let c=___default.default.resolve(t.entrypoint);U__default.default.existsSync(c)||(e.fail(`File not found: ${t.entrypoint}`),process.exit(1)),l=[c];}else l=[...Me(r),...Me(a)];l.length===0&&(e.fail("No function files found"),console.log(f__default.default.yellow(`
3800
- Place your functions in:`)),console.log(f__default.default.gray(" - ./functions/")),console.log(f__default.default.gray(" - ./src/functions/")),console.log(f__default.default.gray(`
3801
- Or specify an entrypoint with --entrypoint`)),process.exit(1)),e.succeed(`Found ${l.length} function(s)`),t.name&&(l=l.filter(c=>___default.default.basename(c,___default.default.extname(c)).includes(t.name)),l.length===0&&(console.log(f__default.default.yellow(`
3802
- No functions matching "${t.name}" found`)),process.exit(1))),console.log(""),console.log(f__default.default.gray("Functions to deploy:"));for(let c of l){let g=___default.default.basename(___default.default.dirname(c)),h=g==="functions"||g==="src"?___default.default.basename(c,___default.default.extname(c)):g,T=t.runtime||Oe(c);console.log(f__default.default.gray(` - ${h} (${T})`));}if(console.log(""),t.dryRun){console.log(f__default.default.yellow("Dry run mode - no functions deployed."));return}let d=[];for(let c of l){let g=___default.default.basename(___default.default.dirname(c)),h=g==="functions"||g==="src"?___default.default.basename(c,___default.default.extname(c)):g,T=t.runtime||Oe(c);e.start(`Deploying ${h}...`);try{let D=U__default.default.readFileSync(c,"utf-8"),$=await Zt(n.token,i,h,t.envId);$||(e.text=`Creating ${h}...`,$=await eo(n.token,i,{name:h,runtime:T,entrypoint:___default.default.basename(c),envId:t.envId})),e.text=`Deploying ${h}...`,await to(n.token,$.id,D),e.succeed(`Deployed ${h}`),d.push({name:h,success:!0});}catch(D){let $=D instanceof Error?D.message:"Unknown error";e.fail(`Failed to deploy ${h}`),d.push({name:h,success:false,error:$});}}console.log("");let p=d.filter(c=>c.success).length;if(d.filter(c=>!c.success).length===0)console.log(f__default.default.green(`\u2713 Successfully deployed ${p} function(s)`));else {console.log(f__default.default.yellow(`Deployed ${p}/${d.length} function(s)`)),console.log(""),console.log(f__default.default.red("Failed deployments:"));for(let c of d.filter(g=>!g.success))console.log(f__default.default.red(` - ${c.name}: ${c.error}`));}console.log("");}async function Be(t){let e=Q__default.default(),n=I();(!n||!n.token)&&(console.log(f__default.default.red("Not logged in")),console.log(f__default.default.gray("Run `vaif login` first to authenticate")),process.exit(1));let o=t.config||"vaif.config.json",s=null;try{s=await A(o);}catch{}let i=t.projectId||s?.projectId||process.env.VAIF_PROJECT_ID||n.projectId;i||(console.log(f__default.default.red("No project ID specified")),process.exit(1)),e.start("Fetching functions...");try{let r=await oo(n.token,i,t.envId);if(e.stop(),r.length===0){console.log(f__default.default.yellow(`
3803
- No functions found`)),console.log(f__default.default.gray("Deploy your first function with: vaif functions deploy"));return}console.log(""),console.log(f__default.default.bold(`Functions (${r.length}):`)),console.log(""),console.log(f__default.default.gray(" "+"NAME".padEnd(25)+"RUNTIME".padEnd(15)+"STATUS".padEnd(12)+"INVOCATIONS".padEnd(14)+"LAST DEPLOYED")),console.log(f__default.default.gray(" "+"-".repeat(80)));for(let a of r){let l=a.deployStatus==="deployed"?f__default.default.green:a.deployStatus==="deploying"?f__default.default.yellow:a.deployStatus==="failed"?f__default.default.red:f__default.default.gray;console.log(" "+a.name.padEnd(25)+a.runtime.padEnd(15)+l(a.deployStatus.padEnd(12))+String(a.invocationCount??0).padEnd(14)+(a.deployedAt?new Date(a.deployedAt).toLocaleDateString():"-"));}console.log("");}catch(r){e.fail("Failed to fetch functions"),r instanceof Error&&console.log(f__default.default.red(`
3804
- Error: ${r.message}`)),process.exit(1);}}var Z=process.env.VAIF_API_URL||"https://api.vaif.studio";async function no(t,e,n,o,s){let i=await fetch(`${Z}/projects/${e}/db/seed`,{method:"POST",headers:{Authorization:`Bearer ${t}`,"Content-Type":"application/json"},body:JSON.stringify({table:n,records:o,truncate:s?.truncate??false})});if(!i.ok){let r=await i.text();throw new Error(`Failed to seed ${n}: ${r}`)}return i.json()}async function ao(t,e){let n=await fetch(`${Z}/projects/${e}/db/reset`,{method:"POST",headers:{Authorization:`Bearer ${t}`,"Content-Type":"application/json"}});if(!n.ok){let o=await n.text();throw new Error(`Failed to reset database: ${o}`)}return n.json()}function ge(t){let e=[];if(!U__default.default.existsSync(t))return e;let n=U__default.default.readdirSync(t,{withFileTypes:true});for(let o of n)if(o.isFile()){let s=___default.default.extname(o.name).toLowerCase();(s===".json"||s===".ts"||s===".js")&&e.push(___default.default.join(t,o.name));}return e.sort()}async function qe(t){let e=___default.default.extname(t).toLowerCase();if(e===".json"){let n=U__default.default.readFileSync(t,"utf-8"),o=JSON.parse(n);return Array.isArray(o)?[{table:___default.default.basename(t,e),data:o}]:o.table&&o.data?[o]:Object.entries(o).map(([s,i])=>({table:s,data:i}))}else if(e===".ts"||e===".js"){let n=await import(t),o=n.default||n;return typeof o=="function"?o():o}throw new Error(`Unsupported file format: ${e}`)}async function Ye(t){let e=Q__default.default(),n=I();(!n||!n.token)&&(console.log(f__default.default.red("Not logged in")),console.log(f__default.default.gray("Run `vaif login` first to authenticate")),process.exit(1));let o=t.config||"vaif.config.json",s=null;try{s=await A(o);}catch{}let i=t.projectId||s?.projectId||process.env.VAIF_PROJECT_ID||n.projectId;i||(console.log(f__default.default.red("No project ID specified")),console.log(f__default.default.yellow("Set projectId in vaif.config.json or use --project-id flag.")),process.exit(1)),console.log(""),console.log(f__default.default.bold("VAIF Database Seed")),console.log("");let r=[];if(t.file){let p=___default.default.resolve(t.file);U__default.default.existsSync(p)||(console.log(f__default.default.red(`File not found: ${t.file}`)),process.exit(1)),r=[p];}else {let p=___default.default.resolve("seeds"),u=___default.default.resolve("prisma/seed"),c=___default.default.resolve("db/seeds");r=[...ge(p),...ge(u),...ge(c)];}r.length===0&&(console.log(f__default.default.yellow("No seed files found")),console.log(f__default.default.gray(`
3805
- Place your seed files in one of these directories:`)),console.log(f__default.default.gray(" - ./seeds/")),console.log(f__default.default.gray(" - ./prisma/seed/")),console.log(f__default.default.gray(" - ./db/seeds/")),console.log(f__default.default.gray(`
3806
- Or specify a file with --file`)),console.log(f__default.default.gray(`
3807
- Example seed file (seeds/users.json):`)),console.log(f__default.default.gray(" [")),console.log(f__default.default.gray(' { "name": "John Doe", "email": "john@example.com" },')),console.log(f__default.default.gray(' { "name": "Jane Doe", "email": "jane@example.com" }')),console.log(f__default.default.gray(" ]")),process.exit(1)),console.log(f__default.default.gray("Seed files found:"));for(let p of r)console.log(f__default.default.gray(` - ${___default.default.relative(process.cwd(),p)}`));if(console.log(""),t.truncate&&(console.log(f__default.default.yellow("\u26A0\uFE0F Tables will be truncated before seeding")),console.log("")),t.dryRun){console.log(f__default.default.yellow("Dry run mode - no data will be inserted.")),console.log("");for(let p of r){e.start(`Loading ${___default.default.basename(p)}...`);try{let u=await qe(p);e.stop();for(let c of u)t.table&&c.table!==t.table||(console.log(f__default.default.cyan(`Table: ${c.table}`)),console.log(f__default.default.gray(` Records: ${c.data.length}`)),c.data.length>0&&console.log(f__default.default.gray(` Sample: ${JSON.stringify(c.data[0],null,2).slice(0,100)}...`)),console.log(""));}catch(u){e.fail(`Failed to load ${___default.default.basename(p)}`),u instanceof Error&&console.log(f__default.default.red(` Error: ${u.message}`));}}return}let a=[];for(let p of r){e.start(`Processing ${___default.default.basename(p)}...`);try{let u=await qe(p);e.stop();for(let c of u)if(!(t.table&&c.table!==t.table)){if(c.data.length===0){console.log(f__default.default.gray(` Skipping ${c.table} (no records)`));continue}e.start(`Seeding ${c.table} (${c.data.length} records)...`);try{let g=await no(n.token,i,c.table,c.data,{truncate:t.truncate});e.succeed(`Seeded ${c.table}: ${g.inserted} records`),a.push({table:c.table,inserted:g.inserted});}catch(g){let h=g instanceof Error?g.message:"Unknown error";e.fail(`Failed to seed ${c.table}`),a.push({table:c.table,inserted:0,error:h});}}}catch(u){e.fail(`Failed to load ${___default.default.basename(p)}`),u instanceof Error&&console.log(f__default.default.red(` Error: ${u.message}`));}}console.log("");let l=a.reduce((p,u)=>p+u.inserted,0),d=a.filter(p=>p.error).length;if(d===0)console.log(f__default.default.green(`\u2713 Successfully seeded ${l} records across ${a.length} table(s)`));else {console.log(f__default.default.yellow(`Seeded ${l} records with ${d} error(s)`)),console.log(""),console.log(f__default.default.red("Errors:"));for(let p of a.filter(u=>u.error))console.log(f__default.default.red(` - ${p.table}: ${p.error}`));}console.log("");}async function Je(t){let e=Q__default.default(),n=I();(!n||!n.token)&&(console.log(f__default.default.red("Not logged in")),console.log(f__default.default.gray("Run `vaif login` first to authenticate")),process.exit(1));let o=t.config||"vaif.config.json",s=null;try{s=await A(o);}catch{}let i=t.projectId||s?.projectId||process.env.VAIF_PROJECT_ID||n.projectId;i||(console.log(f__default.default.red("No project ID specified")),console.log(f__default.default.yellow("Set projectId in vaif.config.json or use --project-id flag.")),process.exit(1));let r=___default.default.resolve(t.dir||"./drizzle");if(console.log(""),console.log(f__default.default.bold("VAIF Database Push")),console.log(""),!U__default.default.existsSync(r)){let u=___default.default.resolve("./migrations");U__default.default.existsSync(u)?console.log(f__default.default.gray(`Using migrations from: ${u}`)):(console.log(f__default.default.red(`Migrations directory not found: ${r}`)),console.log(f__default.default.gray(`
3808
- Expected one of:`)),console.log(f__default.default.gray(" - ./drizzle/")),console.log(f__default.default.gray(" - ./migrations/")),console.log(f__default.default.gray(`
3809
- Or specify with: vaif db push --dir <path>`)),process.exit(1));}let a=[],l=U__default.default.readdirSync(r,{withFileTypes:true});for(let u of l)if(u.isFile()&&u.name.endsWith(".sql"))a.push(___default.default.join(r,u.name));else if(u.isDirectory()){let c=U__default.default.readdirSync(___default.default.join(r,u.name),{withFileTypes:true});for(let g of c)g.isFile()&&g.name.endsWith(".sql")&&a.push(___default.default.join(r,u.name,g.name));}a.sort(),a.length===0&&(console.log(f__default.default.yellow("No SQL migration files found")),process.exit(1)),console.log(f__default.default.gray(`Found ${a.length} migration(s):`));for(let u of a)console.log(f__default.default.gray(` - ${___default.default.relative(process.cwd(),u)}`));if(console.log(""),t.dryRun){console.log(f__default.default.yellow("Dry run mode - no migrations will be applied.")),console.log("");for(let u of a){let c=U__default.default.readFileSync(u,"utf-8");console.log(f__default.default.cyan(`--- ${___default.default.basename(u)} ---`)),console.log(f__default.default.gray(c.slice(0,500))),c.length>500&&console.log(f__default.default.gray("...")),console.log("");}return}let d=0,p=0;for(let u of a){let c=U__default.default.readFileSync(u,"utf-8"),g=___default.default.relative(process.cwd(),u);e.start(`Applying ${g}...`);try{let h=await fetch(`${Z}/schema-engine/query/${i}`,{method:"POST",headers:{Authorization:`Bearer ${n.token}`,"Content-Type":"application/json"},body:JSON.stringify({sql:c})});if(!h.ok){let T=await h.text();throw new Error(T)}e.succeed(`Applied ${g}`),d++;}catch(h){let T=h instanceof Error?h.message:"Unknown error";e.fail(`Failed ${g}: ${T}`),p++;}}console.log(""),console.log(p===0?f__default.default.green(`Successfully applied ${d} migration(s)`):f__default.default.yellow(`Applied ${d}, failed ${p} migration(s)`)),console.log("");}async function Ge(t){let e=Q__default.default(),n=I();(!n||!n.token)&&(console.log(f__default.default.red("Not logged in")),console.log(f__default.default.gray("Run `vaif login` first to authenticate")),process.exit(1));let o=t.config||"vaif.config.json",s=null;try{s=await A(o);}catch{}let i=t.projectId||s?.projectId||process.env.VAIF_PROJECT_ID||n.projectId;i||(console.log(f__default.default.red("No project ID specified")),console.log(f__default.default.yellow("Set projectId in vaif.config.json or use --project-id flag.")),process.exit(1));let r=___default.default.resolve(t.output||"vaif.schema.json");console.log(""),console.log(f__default.default.bold("VAIF Database Pull")),console.log(""),e.start("Pulling schema from remote...");try{let a=await fetch(`${Z}/schema-engine/introspect/${i}`,{headers:{Authorization:`Bearer ${n.token}`}});if(!a.ok){let p=await a.text();throw new Error(`Failed to pull schema: ${p}`)}let l=await a.json();U__default.default.writeFileSync(r,JSON.stringify(l,null,2),"utf-8"),e.succeed(`Schema written to ${___default.default.relative(process.cwd(),r)}`);let d=l.tables?.length??Object.keys(l).length;console.log(f__default.default.gray(` ${d} table(s) pulled`)),console.log("");}catch(a){e.fail("Failed to pull schema"),a instanceof Error&&console.log(f__default.default.red(`
3810
- Error: ${a.message}`)),process.exit(1);}}async function We(t){let e=Q__default.default(),n=I();(!n||!n.token)&&(console.log(f__default.default.red("Not logged in")),console.log(f__default.default.gray("Run `vaif login` first to authenticate")),process.exit(1));let o=t.config||"vaif.config.json",s=null;try{s=await A(o);}catch{}let i=t.projectId||s?.projectId||process.env.VAIF_PROJECT_ID||n.projectId;i||(console.log(f__default.default.red("No project ID specified")),process.exit(1)),console.log(""),console.log(f__default.default.red.bold("\u26A0\uFE0F DATABASE RESET")),console.log(""),console.log(f__default.default.red("This will:")),console.log(f__default.default.red(" - Drop all tables")),console.log(f__default.default.red(" - Delete all data")),console.log(f__default.default.red(" - Reset migrations")),console.log(""),console.log(f__default.default.red.bold("This action cannot be undone!")),console.log(""),t.force||(console.log(f__default.default.yellow("Use --force to confirm this action.")),process.exit(1)),e.start("Resetting database...");try{await ao(n.token,i),e.succeed("Database reset complete"),console.log(""),console.log(f__default.default.gray("Your database is now empty.")),console.log(f__default.default.gray("Run `vaif push` to apply your schema, then `vaif db seed` to seed data.")),console.log("");}catch(r){e.fail("Failed to reset database"),r instanceof Error&&console.log(f__default.default.red(`
3811
- Error: ${r.message}`)),process.exit(1);}}var Xe=process.env.VAIF_API_URL||"https://api.vaif.studio";function Qe(t,e,n){return t.projectId||e?.projectId||process.env.VAIF_PROJECT_ID||n.projectId||null}async function Ze(t){let e=Q__default.default(),n=I();(!n||!n.token)&&(console.log(f__default.default.red("Not logged in")),console.log(f__default.default.gray("Run `vaif login` first to authenticate")),process.exit(1));let o=t.config||"vaif.config.json",s=null;try{s=await A(o);}catch{}let i=Qe(t,s,n);i||(console.log(f__default.default.red("No project ID specified")),console.log(f__default.default.yellow("Set projectId in vaif.config.json or use --project-id flag.")),process.exit(1));let r=t.name||`cli-key-${Date.now()}`;console.log(""),console.log(f__default.default.bold("VAIF Generate API Key")),console.log(""),e.start("Generating API key...");try{let a=await fetch(`${Xe}/projects/${i}/api-keys`,{method:"POST",headers:{Authorization:`Bearer ${n.token}`,"Content-Type":"application/json"},body:JSON.stringify({name:r})});if(!a.ok){let d=await a.text();throw new Error(`Failed to generate key: ${d}`)}let l=await a.json();e.succeed("API key generated"),console.log(""),console.log(f__default.default.green(` Name: ${l.name}`)),console.log(f__default.default.green(` Key: ${l.key}`)),console.log(""),console.log(f__default.default.yellow.bold(" Save this key now - it will not be shown again!")),console.log("");}catch(a){e.fail("Failed to generate API key"),a instanceof Error&&console.log(f__default.default.red(`
3812
- Error: ${a.message}`)),process.exit(1);}}async function et(t){let e=Q__default.default(),n=I();(!n||!n.token)&&(console.log(f__default.default.red("Not logged in")),console.log(f__default.default.gray("Run `vaif login` first to authenticate")),process.exit(1));let o=t.config||"vaif.config.json",s=null;try{s=await A(o);}catch{}let i=Qe(t,s,n);i||(console.log(f__default.default.red("No project ID specified")),console.log(f__default.default.yellow("Set projectId in vaif.config.json or use --project-id flag.")),process.exit(1)),console.log(""),console.log(f__default.default.bold("VAIF API Keys")),console.log(""),e.start("Fetching API keys...");try{let r=await fetch(`${Xe}/projects/${i}/api-keys`,{headers:{Authorization:`Bearer ${n.token}`}});if(!r.ok){let u=await r.text();throw new Error(`Failed to list keys: ${u}`)}let a=await r.json(),l=a.keys||a;if(e.stop(),!Array.isArray(l)||l.length===0){console.log(f__default.default.yellow("No API keys found")),console.log(f__default.default.gray(`
3813
- Generate one with: vaif keys generate`));return}let d=Math.max(8,...l.map(u=>(u.name||"").length)),p=` ${"Name".padEnd(d)} ${"Key".padEnd(24)} Created`;console.log(f__default.default.gray(p)),console.log(f__default.default.gray(" "+"-".repeat(p.length-2)));for(let u of l){let c=(u.name||"unnamed").padEnd(d),g=u.maskedKey||u.prefix||`${(u.key||"").slice(0,12)}...`,h=u.createdAt?new Date(u.createdAt).toLocaleDateString():"N/A";console.log(` ${c} ${g.padEnd(24)} ${h}`);}console.log(""),console.log(f__default.default.gray(` ${l.length} key(s) total`)),console.log("");}catch(r){e.fail("Failed to list API keys"),r instanceof Error&&console.log(f__default.default.red(`
3814
- Error: ${r.message}`)),process.exit(1);}}var z=process.env.VAIF_API_URL||"https://api.vaif.studio";function so(t,e,n){return t.projectId||e?.projectId||process.env.VAIF_PROJECT_ID||n.projectId||null}function te(){let t=I();return (!t||!t.token)&&(console.log(f__default.default.red("Not logged in")),console.log(f__default.default.gray("Run `vaif login` first to authenticate")),process.exit(1)),t}async function oe(t){try{return await A(t||"vaif.config.json")}catch{return null}}function ne(t,e,n){let o=so(t,e,n);return o||(console.log(f__default.default.red("No project ID specified")),console.log(f__default.default.yellow("Set projectId in vaif.config.json or use --project-id flag.")),process.exit(1)),o}async function tt(t,e,n){let o=Q__default.default(),s=te(),i=await oe(n.config),r=ne(n,i,s),a=e;if(n.fromFile)try{a=U__default.default.readFileSync(n.fromFile,"utf-8");}catch(l){console.log(f__default.default.red(`Failed to read file: ${n.fromFile}`)),l instanceof Error&&console.log(f__default.default.gray(l.message)),process.exit(1);}a||(console.log(f__default.default.red("No value provided")),console.log(f__default.default.gray("Provide a value as argument or use --from-file <path>")),process.exit(1)),console.log(""),console.log(f__default.default.bold("VAIF Set Secret")),console.log(""),o.start("Checking for existing secret...");try{let l=new URL(`${z}/functions/secrets/project/${r}`);n.envId&&l.searchParams.set("envId",n.envId);let d=await fetch(l.toString(),{headers:{Authorization:`Bearer ${s.token}`}});if(!d.ok)throw new Error(`Failed to check existing secrets: ${await d.text()}`);let u=(await d.json()).find(c=>c.key===t);if(u){o.text=`Updating secret "${t}"...`;let c=await fetch(`${z}/functions/secrets/${u.id}`,{method:"PUT",headers:{Authorization:`Bearer ${s.token}`,"Content-Type":"application/json"},body:JSON.stringify({value:a})});if(!c.ok)throw new Error(`Failed to update secret: ${await c.text()}`);o.succeed(`Updated secret "${t}"`);}else {o.text=`Creating secret "${t}"...`;let c=await fetch(`${z}/functions/secrets`,{method:"POST",headers:{Authorization:`Bearer ${s.token}`,"Content-Type":"application/json"},body:JSON.stringify({projectId:r,envId:n.envId,key:t,value:a})});if(!c.ok)throw new Error(`Failed to create secret: ${await c.text()}`);o.succeed(`Created secret "${t}"`);}console.log("");}catch(l){o.fail("Failed to set secret"),l instanceof Error&&console.log(f__default.default.red(`
3815
- Error: ${l.message}`)),process.exit(1);}}async function ot(t){let e=Q__default.default(),n=te(),o=await oe(t.config),s=ne(t,o,n);console.log(""),console.log(f__default.default.bold("VAIF Secrets")),console.log(""),e.start("Fetching secrets...");try{let i=new URL(`${z}/functions/secrets/project/${s}`);t.envId&&i.searchParams.set("envId",t.envId);let r=await fetch(i.toString(),{headers:{Authorization:`Bearer ${n.token}`}});if(!r.ok)throw new Error(`Failed to list secrets: ${await r.text()}`);let a=await r.json();if(e.stop(),a.length===0){console.log(f__default.default.yellow("No secrets found")),console.log(f__default.default.gray(`
3816
- Create one with: vaif secrets set <name> <value>`));return}let l=Math.max(8,...a.map(p=>p.key.length)),d=` ${"Name".padEnd(l)} Created`;console.log(f__default.default.gray(d)),console.log(f__default.default.gray(" "+"-".repeat(d.length-2)));for(let p of a){let u=p.key.padEnd(l),c=p.createdAt?new Date(p.createdAt).toLocaleDateString():"N/A";console.log(` ${u} ${c}`);}console.log(""),console.log(f__default.default.gray(` ${a.length} secret(s) total`)),console.log(f__default.default.gray(" Values are hidden. Use `vaif secrets get <name>` to reveal.")),console.log("");}catch(i){e.fail("Failed to list secrets"),i instanceof Error&&console.log(f__default.default.red(`
3817
- Error: ${i.message}`)),process.exit(1);}}async function nt(t,e){let n=Q__default.default(),o=te(),s=await oe(e.config),i=ne(e,s,o);console.log(""),n.start("Fetching secret...");try{let r=new URL(`${z}/functions/secrets/project/${i}`);e.envId&&r.searchParams.set("envId",e.envId);let a=await fetch(r.toString(),{headers:{Authorization:`Bearer ${o.token}`}});if(!a.ok)throw new Error(`Failed to fetch secrets: ${await a.text()}`);let d=(await a.json()).find(c=>c.key===t);d||(n.fail(`Secret "${t}" not found`),process.exit(1));let p=await fetch(`${z}/functions/secrets/${d.id}/value`,{headers:{Authorization:`Bearer ${o.token}`}});if(!p.ok)throw new Error(`Failed to get secret value: ${await p.text()}`);let u=await p.json();n.stop(),console.log(u.value);}catch(r){n.fail("Failed to get secret"),r instanceof Error&&console.log(f__default.default.red(`
3818
- Error: ${r.message}`)),process.exit(1);}}async function at(t,e){let n=Q__default.default(),o=te(),s=await oe(e.config),i=ne(e,s,o);console.log(""),console.log(f__default.default.bold("VAIF Delete Secret")),console.log(""),n.start("Finding secret...");try{let r=new URL(`${z}/functions/secrets/project/${i}`);e.envId&&r.searchParams.set("envId",e.envId);let a=await fetch(r.toString(),{headers:{Authorization:`Bearer ${o.token}`}});if(!a.ok)throw new Error(`Failed to fetch secrets: ${await a.text()}`);let d=(await a.json()).find(u=>u.key===t);d||(n.fail(`Secret "${t}" not found`),process.exit(1)),n.text=`Deleting secret "${t}"...`;let p=await fetch(`${z}/functions/secrets/${d.id}`,{method:"DELETE",headers:{Authorization:`Bearer ${o.token}`}});if(!p.ok)throw new Error(`Failed to delete secret: ${await p.text()}`);n.succeed(`Deleted secret "${t}"`),console.log("");}catch(r){n.fail("Failed to delete secret"),r instanceof Error&&console.log(f__default.default.red(`
3819
- Error: ${r.message}`)),process.exit(1);}}var it=process.env.VAIF_API_URL||"https://api.vaif.studio";function lo(t){try{let e=new URL(t);return e.password&&(e.password="****"),e.toString()}catch{return t.replace(/:[^@/]+@/,":****@")}}async function st(t){let e=Q__default.default(),n=I();(!n||!n.token)&&(console.log(f__default.default.red("Not logged in")),console.log(f__default.default.gray("Run `vaif login` first to authenticate")),process.exit(1));let o=t.config||"vaif.config.json",s=null;try{s=await A(o);}catch{}let i=t.projectId||s?.projectId||process.env.VAIF_PROJECT_ID||n.projectId;i||(console.log(f__default.default.red("No project ID specified")),console.log(f__default.default.yellow("Set projectId in vaif.config.json or use --project-id flag.")),process.exit(1)),e.start("Fetching project info...");try{let r=await fetch(`${it}/projects/${i}`,{headers:{Authorization:`Bearer ${n.token}`}});if(!r.ok){let p=await r.text();throw new Error(`Failed to fetch project: ${p}`)}let a=await r.json();e.stop(),console.log(""),console.log(f__default.default.bold("VAIF Project Info")),console.log("");let l=16,d=(p,u)=>{console.log(` ${f__default.default.gray(p.padEnd(l))} ${u}`);};d("Name:",f__default.default.white(a.name||"N/A")),d("Project ID:",f__default.default.white(i)),d("Region:",f__default.default.white(a.region||"us-east-1")),d("Plan:",f__default.default.white(a.plan||a.tier||"free")),d("Created:",f__default.default.white(a.createdAt?new Date(a.createdAt).toLocaleDateString():"N/A")),console.log(""),d("API URL:",f__default.default.cyan(a.apiUrl||`${it}/v1`)),d("WS URL:",f__default.default.cyan(a.wsUrl||a.realtimeUrl||"N/A")),d("DB URL:",f__default.default.cyan(a.databaseUrl?lo(a.databaseUrl):"N/A")),d("Storage URL:",f__default.default.cyan(a.storageUrl||"N/A")),console.log("");}catch(r){e.fail("Failed to fetch project info"),r instanceof Error&&console.log(f__default.default.red(`
3820
- Error: ${r.message}`)),process.exit(1);}}var uo=process.env.VAIF_API_URL||"https://api.vaif.studio";async function rt(t){let e=Q__default.default(),n=I();(!n||!n.token)&&(console.log(f__default.default.red("Not logged in")),console.log(f__default.default.gray("Run `vaif login` first to authenticate")),process.exit(1));let o=t.config||"vaif.config.json",s=null;try{s=await A(o);}catch{}let i=t.projectId||s?.projectId||process.env.VAIF_PROJECT_ID||n.projectId;i||(console.log(f__default.default.red("No project ID specified")),console.log(f__default.default.yellow("Set projectId in vaif.config.json or use --project-id flag.")),process.exit(1)),e.start("Fetching project status...");try{let r=await fetch(`${uo}/projects/${i}?include=tables,functions,storage,connections`,{headers:{Authorization:`Bearer ${n.token}`}});if(!r.ok){let h=await r.text();throw new Error(`Failed to fetch project status: ${h}`)}let a=await r.json();e.stop(),console.log(""),console.log(f__default.default.bold("VAIF Project Status")),console.log("");let l=22,d=(h,T)=>{console.log(` ${f__default.default.gray(h.padEnd(l))} ${T}`);};d("Project:",f__default.default.white(a.name||i)),d("Plan:",f__default.default.white(a.plan||a.tier||"free")),console.log(""),console.log(f__default.default.gray(" --- Resources ---")),console.log("");let p=a.tableCount??a.tables?.length??"N/A",u=a.functionCount??a.functions?.length??"N/A",c=a.bucketCount??a.storage?.buckets?.length??"N/A",g=a.activeConnections??a.connections??"N/A";d("Tables:",f__default.default.white(String(p))),d("Functions:",f__default.default.white(String(u))),d("Storage Buckets:",f__default.default.white(String(c))),d("Active Connections:",f__default.default.white(String(g))),a.usage&&(console.log(""),console.log(f__default.default.gray(" --- Usage ---")),console.log(""),a.usage.dbSize&&d("Database Size:",f__default.default.white(a.usage.dbSize)),a.usage.storageSize&&d("Storage Size:",f__default.default.white(a.usage.storageSize)),a.usage.bandwidth&&d("Bandwidth:",f__default.default.white(a.usage.bandwidth)),a.usage.functionInvocations!=null&&d("Function Invocations:",f__default.default.white(String(a.usage.functionInvocations)))),console.log("");}catch(r){e.fail("Failed to fetch project status"),r instanceof Error&&console.log(f__default.default.red(`
3821
- Error: ${r.message}`)),process.exit(1);}}var J=process.env.VAIF_API_URL||"https://api.vaif.studio";function fo(t){let e=Ee__default.default.createInterface({input:process.stdin,output:process.stdout});return new Promise(n=>{e.question(t,o=>{e.close(),n(o.trim());});})}function go(t,e,n){return t.projectId||e?.projectId||process.env.VAIF_PROJECT_ID||n.projectId||null}async function mo(t){let e=Q__default.default("Fetching your projects...").start();try{let n=await fetch(`${J}/projects`,{headers:{Authorization:`Bearer ${t}`}});if(!n.ok)return e.fail("Could not fetch projects"),null;let o=await n.json();if(!o||o.length===0)return e.fail("No projects found. Create a project at https://vaif.studio first."),null;if(o.length===1)return e.succeed(`Found project: ${f__default.default.cyan(o[0].name)} (${o[0].id})`),o[0].id;e.succeed(`Found ${o.length} projects
3822
- `);for(let r=0;r<o.length;r++)console.log(f__default.default.gray(` ${r+1}.`)+` ${f__default.default.white(o[r].name)} ${f__default.default.gray(`(${o[r].id})`)}`);console.log("");let s=await fo(f__default.default.cyan(` Select a project [1-${o.length}]: `)),i=parseInt(s,10)-1;return isNaN(i)||i<0||i>=o.length?(console.log(f__default.default.red(`
3823
- Invalid selection.`)),null):o[i].id}catch{return e.fail("Could not fetch projects"),null}}function ho(t){if(!t||t.length===0)return "*No tables found. Create tables in the VAIF Studio dashboard.*";let e="";for(let n of t){e+=`### \`${n.name}\`
3781
+ `)),process.exit(1));let n;e.features&&e.features.length>0?n=e.features.filter(d=>X.some(g=>g.name===d)):e.addOnly?(console.log(f__default.default.red(`
3782
+ No features specified.`)),console.log(f__default.default.yellow("Usage: vaif init --template <name> --add-features <features>")),console.log(f__default.default.gray("Available features: auth, database, realtime, storage, functions")),process.exit(1)):o.featureFiles&&Object.keys(o.featureFiles).length>0?n=await Gt(o.defaultFeatures??["database","auth"]):n=o.defaultFeatures??[],e.addOnly?(console.log(""),console.log(f__default.default.bold(`Adding features to ${f__default.default.cyan(o.name)} project...`)),console.log(f__default.default.gray(` Features: ${n.join(", ")}`)),console.log("")):(console.log(""),console.log(f__default.default.bold(`Scaffolding ${f__default.default.cyan(o.name)} template...`)),n.length>0&&console.log(f__default.default.gray(` Features: ${n.join(", ")}`)),console.log(""));let i=e.addOnly?[]:[...o.files],a=new Set,r=[];if(o.featureFiles)for(let d of n){let g=o.featureFiles[d];if(g)for(let y of g)a.add(y.path),r.push(y);}let s=i.filter(d=>!a.has(d.path)).concat(r),c=0,l=0;for(let d of s){let g=S__default.default.resolve(d.path),y=S__default.default.dirname(g);if(A__default.default.existsSync(y)||A__default.default.mkdirSync(y,{recursive:true}),d.path==="package.json"&&A__default.default.existsSync(g)&&!e.force)try{let P=JSON.parse(A__default.default.readFileSync(g,"utf-8")),O=JSON.parse(d.content),B=W=>{if(!W)return {};let Pe={};for(let[_t,ee]of Object.entries(W))!ee.startsWith("workspace:")&&!ee.startsWith("link:")&&!ee.startsWith("file:")&&(Pe[_t]=ee);return Pe};P.dependencies={...B(P.dependencies),...O.dependencies||{}},P.devDependencies={...B(P.devDependencies),...O.devDependencies||{}},O.scripts&&(P.scripts={...P.scripts||{},...O.scripts}),A__default.default.writeFileSync(g,JSON.stringify(P,null,2)+`
3783
+ `,"utf-8"),console.log(f__default.default.green(` merge ${d.path} (added dependencies)`)),c++;continue}catch{}if(A__default.default.existsSync(g)&&!e.force){console.log(f__default.default.yellow(` skip ${d.path} (already exists)`)),l++;continue}A__default.default.writeFileSync(g,d.content,"utf-8"),console.log(f__default.default.green(` create ${d.path}`)),c++;}console.log(""),c>0&&console.log(f__default.default.green(`Created ${c} file${c!==1?"s":""}.`)),l>0&&console.log(f__default.default.yellow(`Skipped ${l} file${l!==1?"s":""} (use --force to overwrite).`));let p={auth:{"@vaiftech/auth":"^1.0.0"},database:{},realtime:{},storage:{},functions:{}},u=S__default.default.resolve("package.json");if(A__default.default.existsSync(u)&&n.length>0)try{let d=JSON.parse(A__default.default.readFileSync(u,"utf-8")),g=!1;for(let y of n){let P=p[y];if(P)for(let[O,B]of Object.entries(P))d.dependencies?.[O]||(d.dependencies=d.dependencies||{},d.dependencies[O]=B,g=!0);}g&&A__default.default.writeFileSync(u,JSON.stringify(d,null,2)+`
3784
+ `,"utf-8");}catch{}(o.dependencies?.length||o.devDependencies?.length)&&(console.log(""),console.log(f__default.default.bold("Install dependencies:")),o.dependencies?.length&&console.log(f__default.default.cyan(` npm install ${o.dependencies.join(" ")}`)),o.devDependencies?.length&&console.log(f__default.default.cyan(` npm install -D ${o.devDependencies.join(" ")}`))),console.log(""),console.log(f__default.default.bold.green("Project scaffolded successfully!")),console.log(""),console.log(f__default.default.bold(" Next steps:")),o.postInstructions.forEach(d=>{console.log(f__default.default.gray(` ${d}`));}),console.log(""),console.log(f__default.default.gray(" Get your project credentials at https://console.vaif.studio/security/api-keys")),console.log("");}var Q=process.env.VAIF_API_URL||"https://api.vaif.studio";function Ht(t){let e=Re__default.default.createInterface({input:process.stdin,output:process.stdout});return new Promise(o=>{e.question(t,n=>{e.close(),o(n.trim());});})}function Xt(t,e,o){return t.projectId||e?.projectId||process.env.VAIF_PROJECT_ID||o.projectId||null}async function Qt(t){let e=ie__default.default("Fetching your projects...").start();try{let o=await fetch(`${Q}/projects`,{headers:{Authorization:`Bearer ${t}`}});if(!o.ok)return e.fail("Could not fetch projects"),null;let n=await o.json();if(!n||n.length===0)return e.fail("No projects found. Create a project at https://vaif.studio first."),null;if(n.length===1)return e.succeed(`Found project: ${f__default.default.cyan(n[0].name)} (${n[0].id})`),n[0].id;e.succeed(`Found ${n.length} projects
3785
+ `);for(let r=0;r<n.length;r++)console.log(f__default.default.gray(` ${r+1}.`)+` ${f__default.default.white(n[r].name)} ${f__default.default.gray(`(${n[r].id})`)}`);console.log("");let i=await Ht(f__default.default.cyan(` Select a project [1-${n.length}]: `)),a=parseInt(i,10)-1;return isNaN(a)||a<0||a>=n.length?(console.log(f__default.default.red(`
3786
+ Invalid selection.`)),null):n[a].id}catch{return e.fail("Could not fetch projects"),null}}function Zt(t){if(!t||t.length===0)return "*No tables found. Create tables in the VAIF Studio dashboard.*";let e="";for(let o of t){e+=`### \`${o.name}\`
3824
3787
 
3825
3788
  `,e+=`| Column | Type | Nullable | Default | Constraints |
3826
3789
  `,e+=`|--------|------|----------|---------|-------------|
3827
- `;for(let o of n.columns){let s=[];o.isPrimaryKey&&s.push("PK"),o.nullable||s.push("NOT NULL");let i=n.foreignKeys?.find(r=>r.column===o.name);i&&s.push(`FK \u2192 ${i.foreignTable}.${i.foreignColumn}`),e+=`| ${o.name} | ${o.type} | ${o.nullable?"yes":"no"} | ${o.defaultValue||"-"} | ${s.join(", ")||"-"} |
3790
+ `;for(let n of o.columns){let i=[];n.isPrimaryKey&&i.push("PK"),n.nullable||i.push("NOT NULL");let a=o.foreignKeys?.find(r=>r.column===n.name);a&&i.push(`FK \u2192 ${a.foreignTable}.${a.foreignColumn}`),e+=`| ${n.name} | ${n.type} | ${n.nullable?"yes":"no"} | ${n.defaultValue||"-"} | ${i.join(", ")||"-"} |
3828
3791
  `;}e+=`
3829
- `;}return e}function yo(t,e,n){let o=t.slice(0,3);if(o.length===0)return "";let s="";for(let i of o){let r=i.columns.filter(l=>!l.isPrimaryKey&&l.name!=="created_at"&&l.name!=="updated_at"),a=r.slice(0,3).map(l=>` ${l.name}: ${vo(l)}`).join(`,
3830
- `);s+=`### \`${i.name}\`
3792
+ `;}return e}function eo(t,e,o){let n=t.slice(0,3);if(n.length===0)return "";let i="";for(let a of n){let r=a.columns.filter(c=>!c.isPrimaryKey&&c.name!=="created_at"&&c.name!=="updated_at"),s=r.slice(0,3).map(c=>` ${c.name}: ${to(c)}`).join(`,
3793
+ `);i+=`### \`${a.name}\`
3831
3794
 
3832
- `,s+="```typescript\n",s+=`// Select all
3833
- const ${i.name} = await vaif.from("${i.name}").select();
3795
+ `,i+="```typescript\n",i+=`// Select all
3796
+ const ${a.name} = await vaif.from("${a.name}").select();
3834
3797
 
3835
- `,s+=`// Select with filter
3836
- const filtered = await vaif.from("${i.name}").select().eq("${r[0]?.name||"id"}", value);
3798
+ `,i+=`// Select with filter
3799
+ const filtered = await vaif.from("${a.name}").select().eq("${r[0]?.name||"id"}", value);
3837
3800
 
3838
- `,s+=`// Insert
3839
- const created = await vaif.from("${i.name}").insert({
3840
- ${a}
3801
+ `,i+=`// Insert
3802
+ const created = await vaif.from("${a.name}").insert({
3803
+ ${s}
3841
3804
  });
3842
3805
 
3843
- `,s+=`// Update
3844
- await vaif.from("${i.name}").update(recordId, {
3806
+ `,i+=`// Update
3807
+ await vaif.from("${a.name}").update(recordId, {
3845
3808
  ${r[0]?.name||"name"}: newValue
3846
3809
  });
3847
3810
 
3848
- `,s+=`// Delete
3849
- await vaif.from("${i.name}").delete(recordId);
3850
- `,s+="```\n\n",i===o[0]&&(s+=`#### Direct REST API (fetch)
3811
+ `,i+=`// Delete
3812
+ await vaif.from("${a.name}").delete(recordId);
3813
+ `,i+="```\n\n",a===n[0]&&(i+=`#### Direct REST API (fetch)
3851
3814
 
3852
- `,s+="```typescript\n",s+=`// GET all rows (returns { data: [...], count: N })
3853
- `,s+=`const res = await fetch("${e}/generated/${i.name}", {
3854
- `,s+=` headers: { "x-vaif-key": "${n}" },
3855
- `,s+=`});
3856
- `,s+=`const { data } = await res.json();
3815
+ `,i+="```typescript\n",i+=`// GET all rows (returns { data: [...], count: N })
3816
+ `,i+=`const res = await fetch("${e}/generated/${a.name}", {
3817
+ `,i+=` headers: { "x-vaif-key": "${o}" },
3818
+ `,i+=`});
3819
+ `,i+=`const { data } = await res.json();
3857
3820
 
3858
- `,s+=`// GET single row (returns { data: {...} })
3859
- `,s+=`const res2 = await fetch("${e}/generated/${i.name}/\${id}", {
3860
- `,s+=` headers: { "x-vaif-key": "${n}" },
3861
- `,s+=`});
3862
- `,s+=`const { data: record } = await res2.json();
3863
- `,s+="```\n\n");}return s}function vo(t){let e=t.type.toLowerCase();return e.includes("uuid")?'"crypto.randomUUID()"':e.includes("int")||e.includes("serial")?"42":e.includes("bool")?"true":e.includes("timestamp")||e.includes("date")?'"new Date().toISOString()"':e.includes("json")?"{}":e.includes("float")||e.includes("numeric")||e.includes("decimal")||e.includes("double")?"3.14":`"example_${t.name}"`}function bo(t){let{projectId:e,apiKey:n,apiUrl:o,projectName:s,schema:i}=t,r=ho(i.tables),a=yo(i.tables,o,n);return `# VAIF Studio Backend
3821
+ `,i+=`// GET single row (returns { data: {...} })
3822
+ `,i+=`const res2 = await fetch("${e}/generated/${a.name}/\${id}", {
3823
+ `,i+=` headers: { "x-vaif-key": "${o}" },
3824
+ `,i+=`});
3825
+ `,i+=`const { data: record } = await res2.json();
3826
+ `,i+="```\n\n");}return i}function to(t){let e=t.type.toLowerCase();return e.includes("uuid")?'"crypto.randomUUID()"':e.includes("int")||e.includes("serial")?"42":e.includes("bool")?"true":e.includes("timestamp")||e.includes("date")?'"new Date().toISOString()"':e.includes("json")?"{}":e.includes("float")||e.includes("numeric")||e.includes("decimal")||e.includes("double")?"3.14":`"example_${t.name}"`}function oo(t){let{projectId:e,apiKey:o,apiUrl:n,projectName:i,schema:a}=t,r=Zt(a.tables),s=eo(a.tables,n,o);return `# VAIF Studio Backend
3864
3827
 
3865
- This project uses **VAIF Studio** as its backend. Project: **${s}** (\`${e}\`).
3828
+ This project uses **VAIF Studio** as its backend. Project: **${i}** (\`${e}\`).
3866
3829
 
3867
3830
  ## SDK Setup
3868
3831
 
@@ -3874,9 +3837,9 @@ npm install @vaiftech/client
3874
3837
  import { createVaifClient } from "@vaiftech/client";
3875
3838
 
3876
3839
  const vaif = createVaifClient({
3877
- baseUrl: "${o}",
3840
+ baseUrl: "${n}",
3878
3841
  projectId: "${e}",
3879
- apiKey: "${n}",
3842
+ apiKey: "${o}",
3880
3843
  });
3881
3844
  \`\`\`
3882
3845
 
@@ -3886,7 +3849,7 @@ ${r}
3886
3849
 
3887
3850
  ## CRUD Examples
3888
3851
 
3889
- ${a}
3852
+ ${s}
3890
3853
 
3891
3854
  ## Authentication (End-User Auth)
3892
3855
 
@@ -3903,7 +3866,7 @@ VAIF provides **project-scoped** authentication for your app's end-users. All au
3903
3866
  ### Signup
3904
3867
 
3905
3868
  \`\`\`typescript
3906
- const res = await fetch("${o}/projects/${e}/auth/signup", {
3869
+ const res = await fetch("${n}/projects/${e}/auth/signup", {
3907
3870
  method: "POST",
3908
3871
  headers: { "Content-Type": "application/json" },
3909
3872
  body: JSON.stringify({
@@ -3919,7 +3882,7 @@ const { accessToken, expiresIn, user } = await res.json();
3919
3882
  ### Login
3920
3883
 
3921
3884
  \`\`\`typescript
3922
- const res = await fetch("${o}/projects/${e}/auth/login", {
3885
+ const res = await fetch("${n}/projects/${e}/auth/login", {
3923
3886
  method: "POST",
3924
3887
  headers: { "Content-Type": "application/json" },
3925
3888
  body: JSON.stringify({
@@ -3935,7 +3898,7 @@ const { accessToken, expiresIn, user } = await res.json();
3935
3898
  \`\`\`typescript
3936
3899
  // Refresh token is stored as httpOnly cookie (project_refresh_token)
3937
3900
  // and sent automatically with same-origin requests
3938
- const res = await fetch("${o}/projects/${e}/auth/refresh", {
3901
+ const res = await fetch("${n}/projects/${e}/auth/refresh", {
3939
3902
  method: "POST",
3940
3903
  credentials: "include", // sends the httpOnly cookie
3941
3904
  });
@@ -3948,7 +3911,7 @@ const { accessToken, expiresIn, user } = await res.json();
3948
3911
  // Store the access token and use it for authenticated requests
3949
3912
  const headers = {
3950
3913
  Authorization: \\\`Bearer \\\${accessToken}\\\`,
3951
- "x-vaif-key": "${n}",
3914
+ "x-vaif-key": "${o}",
3952
3915
  };
3953
3916
 
3954
3917
  // The JWT contains: { sub: userId, email, projectId, type: "project_user" }
@@ -4055,7 +4018,7 @@ Enable realtime on your tables, then subscribe to live changes:
4055
4018
 
4056
4019
  \`\`\`typescript
4057
4020
  // 1. Enable realtime on tables via API
4058
- await fetch("${o}/realtime/install", {
4021
+ await fetch("${n}/realtime/install", {
4059
4022
  method: "POST",
4060
4023
  headers: {
4061
4024
  Authorization: \`Bearer \${token}\`,
@@ -4104,7 +4067,7 @@ Control who can access storage buckets with RLS-style policies:
4104
4067
 
4105
4068
  \`\`\`typescript
4106
4069
  // Create a policy: only the uploader can read their own files
4107
- await fetch("${o}/storage/buckets/\${bucketId}/policies", {
4070
+ await fetch("${n}/storage/buckets/\${bucketId}/policies", {
4108
4071
  method: "POST",
4109
4072
  headers: {
4110
4073
  Authorization: \`Bearer \${token}\`,
@@ -4118,7 +4081,7 @@ await fetch("${o}/storage/buckets/\${bucketId}/policies", {
4118
4081
  });
4119
4082
 
4120
4083
  // Create a policy: authenticated users can upload
4121
- await fetch("${o}/storage/buckets/\${bucketId}/policies", {
4084
+ await fetch("${n}/storage/buckets/\${bucketId}/policies", {
4122
4085
  method: "POST",
4123
4086
  headers: {
4124
4087
  Authorization: \`Bearer \${token}\`,
@@ -4138,7 +4101,7 @@ Create and deploy serverless functions:
4138
4101
 
4139
4102
  \`\`\`typescript
4140
4103
  // 1. Create a function
4141
- const fn = await fetch("${o}/functions", {
4104
+ const fn = await fetch("${n}/functions", {
4142
4105
  method: "POST",
4143
4106
  headers: {
4144
4107
  Authorization: \`Bearer \${token}\`,
@@ -4154,7 +4117,7 @@ const fn = await fetch("${o}/functions", {
4154
4117
  });
4155
4118
 
4156
4119
  // 2. Deploy source code
4157
- await fetch(\`${o}/functions/\${fn.id}/source\`, {
4120
+ await fetch(\`${n}/functions/\${fn.id}/source\`, {
4158
4121
  method: "PUT",
4159
4122
  headers: {
4160
4123
  Authorization: \`Bearer \${token}\`,
@@ -4228,7 +4191,7 @@ API keys are project-scoped and used for data-plane authentication (CRUD, storag
4228
4191
 
4229
4192
  \`\`\`typescript
4230
4193
  // Create a new API key
4231
- const { key } = await fetch("${o}/projects/${e}/api-keys", {
4194
+ const { key } = await fetch("${n}/projects/${e}/api-keys", {
4232
4195
  method: "POST",
4233
4196
  headers: {
4234
4197
  Authorization: \`Bearer \${token}\`,
@@ -4238,18 +4201,18 @@ const { key } = await fetch("${o}/projects/${e}/api-keys", {
4238
4201
  }).then(r => r.json());
4239
4202
 
4240
4203
  // List keys
4241
- const keys = await fetch("${o}/projects/${e}/api-keys", {
4204
+ const keys = await fetch("${n}/projects/${e}/api-keys", {
4242
4205
  headers: { Authorization: \`Bearer \${token}\` },
4243
4206
  }).then(r => r.json());
4244
4207
 
4245
4208
  // Rotate a key (generates new secret, old key stops working)
4246
- await fetch(\`${o}/projects/${e}/api-keys/\${keyId}/rotate\`, {
4209
+ await fetch(\`${n}/projects/${e}/api-keys/\${keyId}/rotate\`, {
4247
4210
  method: "POST",
4248
4211
  headers: { Authorization: \`Bearer \${token}\` },
4249
4212
  });
4250
4213
 
4251
4214
  // Revoke a key
4252
- await fetch(\`${o}/projects/${e}/api-keys/\${keyId}/revoke\`, {
4215
+ await fetch(\`${n}/projects/${e}/api-keys/\${keyId}/revoke\`, {
4253
4216
  method: "POST",
4254
4217
  headers: { Authorization: \`Bearer \${token}\` },
4255
4218
  });
@@ -4261,7 +4224,7 @@ Secrets are encrypted at rest and injected into function invocations at runtime.
4261
4224
 
4262
4225
  \`\`\`typescript
4263
4226
  // Set a secret (via API)
4264
- await fetch("${o}/functions/secrets", {
4227
+ await fetch("${n}/functions/secrets", {
4265
4228
  method: "POST",
4266
4229
  headers: {
4267
4230
  Authorization: \`Bearer \${token}\`,
@@ -4333,9 +4296,9 @@ This generates: \\\`WHERE status = 'active' AND (role = 'admin' OR role = 'moder
4333
4296
  ### Full-Text Search
4334
4297
 
4335
4298
  \`\`\`typescript
4336
- const results = await fetch("${o}/generated/posts/search", {
4299
+ const results = await fetch("${n}/generated/posts/search", {
4337
4300
  method: "POST",
4338
- headers: { "x-vaif-key": "${n}", "Content-Type": "application/json" },
4301
+ headers: { "x-vaif-key": "${o}", "Content-Type": "application/json" },
4339
4302
  body: JSON.stringify({
4340
4303
  query: "search term",
4341
4304
  columns: ["title", "body"],
@@ -4348,9 +4311,9 @@ const results = await fetch("${o}/generated/posts/search", {
4348
4311
  ### Aggregation
4349
4312
 
4350
4313
  \`\`\`typescript
4351
- const stats = await fetch("${o}/generated/orders/aggregate", {
4314
+ const stats = await fetch("${n}/generated/orders/aggregate", {
4352
4315
  method: "POST",
4353
- headers: { "x-vaif-key": "${n}", "Content-Type": "application/json" },
4316
+ headers: { "x-vaif-key": "${o}", "Content-Type": "application/json" },
4354
4317
  body: JSON.stringify({
4355
4318
  aggregates: [
4356
4319
  { fn: "count", column: "*" },
@@ -4377,9 +4340,9 @@ Returns posts with \\\`author_id_included\\\` and \\\`category_id_included\\\` o
4377
4340
  Insert or update on conflict:
4378
4341
 
4379
4342
  \`\`\`typescript
4380
- const result = await fetch("${o}/generated/users", {
4343
+ const result = await fetch("${n}/generated/users", {
4381
4344
  method: "POST",
4382
- headers: { "x-vaif-key": "${n}", "Content-Type": "application/json" },
4345
+ headers: { "x-vaif-key": "${o}", "Content-Type": "application/json" },
4383
4346
  body: JSON.stringify({
4384
4347
  email: "alice@example.com",
4385
4348
  name: "Alice",
@@ -4464,7 +4427,787 @@ The \`.mcp.json\` file configures an MCP server that gives Claude Code direct ac
4464
4427
  | \`enable_realtime\`, \`realtime_status\` | Realtime subscriptions |
4465
4428
 
4466
4429
  > **Note**: MCP tools are only available to the main Claude Code session, not to spawned sub-agents (Task tool). The main session should handle all VAIF backend operations directly.
4467
- `}async function dt(t){let e=Q__default.default(),n=I();(!n||!n.token)&&(console.log(f__default.default.red("Not logged in")),console.log(f__default.default.gray("Run `vaif login` first to authenticate")),process.exit(1));let o=t.config||"vaif.config.json",s=null;try{s=await A(o);}catch{}let i=go(t,s,n);i||(console.log(f__default.default.yellow(`No project ID specified \u2014 fetching your projects...
4468
- `)),i=await mo(n.token),i||(console.log(f__default.default.gray(`
4469
- Tip: pass --project-id <id> or set projectId in vaif.config.json`)),process.exit(1)));let r=___default.default.resolve(t.outputDir||".");console.log(""),console.log(f__default.default.bold("VAIF Claude Code Setup")),console.log(f__default.default.gray(` Project: ${i}`)),console.log(""),e.start("Fetching database schema...");let a={tables:[]};try{let u=await fetch(`${J}/schema-engine/introspect/${i}`,{headers:{Authorization:`Bearer ${n.token}`}});u.ok?(a=await u.json(),e.succeed(`Fetched schema (${a.tables?.length||0} tables)`)):e.warn("Could not fetch schema \u2014 continuing without it");}catch{e.warn("Could not fetch schema \u2014 continuing without it");}e.start("Fetching project info...");let l=i,d=J;try{let u=await fetch(`${J}/projects/${i}`,{headers:{Authorization:`Bearer ${n.token}`}});if(u.ok){let c=await u.json(),g=c.project||c;l=g.name||i,d=g.apiUrl||J,e.succeed(`Project: ${l}`);}else e.warn("Could not fetch project info \u2014 using defaults");}catch{e.warn("Could not fetch project info \u2014 using defaults");}let p=t.apiKey||s?.api?.apiKey||"";if(!p){e.start("Generating API key for Claude Code...");try{let u=`claude-code-${Date.now()}`,c=await fetch(`${J}/projects/${i}/api-keys`,{method:"POST",headers:{Authorization:`Bearer ${n.token}`,"Content-Type":"application/json"},body:JSON.stringify({name:u,scopes:["crud","realtime","functions","storage"]})});if(c.ok){let g=await c.json();p=g.apiKey||g.key,e.succeed(`Generated API key: ${u}`);}else e.fail("Could not auto-generate API key"),console.log(f__default.default.yellow(" Pass one with --api-key or generate via `vaif keys generate`")),process.exit(1);}catch{e.fail("Could not auto-generate API key"),console.log(f__default.default.yellow(" Pass one with --api-key or generate via `vaif keys generate`")),process.exit(1);}}if(!t.skipMcp){e.start("Writing .mcp.json...");let u={mcpServers:{"vaif-studio":{command:"npx",args:["@vaiftech/mcp"],env:{VAIF_API_KEY:p,VAIF_PROJECT_ID:i,VAIF_API_URL:d,VAIF_AUTH_TOKEN:n.token}}}},c=___default.default.join(r,".mcp.json");U__default.default.writeFileSync(c,JSON.stringify(u,null,2)+`
4470
- `,"utf-8"),e.succeed(`Written ${f__default.default.cyan(".mcp.json")}`);}if(!t.skipClaudeMd){e.start("Writing CLAUDE.md...");let u=bo({projectId:i,apiKey:p,apiUrl:d,projectName:l,schema:a}),c=___default.default.join(r,"CLAUDE.md");U__default.default.writeFileSync(c,u,"utf-8"),e.succeed(`Written ${f__default.default.cyan("CLAUDE.md")}`);}console.log(""),console.log(f__default.default.green.bold(" Claude Code integration configured!")),console.log(""),t.skipMcp||console.log(f__default.default.gray(" MCP Server: ")+f__default.default.white(".mcp.json")),t.skipClaudeMd||console.log(f__default.default.gray(" Context: ")+f__default.default.white("CLAUDE.md")),console.log(""),console.log(f__default.default.bold(" Next steps:")),console.log(f__default.default.gray(" 1. Open this project in Claude Code")),console.log(f__default.default.gray(" 2. The MCP server auto-connects to your VAIF project")),console.log(f__default.default.gray(" 3. Ask Claude to query, modify, or build against your schema")),console.log("");}var Ao=module$1.createRequire(j),{version:ut}=Ao("../package.json"),he=f__default.default.hex("#00f0ff"),ye=f__default.default.hex("#7b61ff"),ve=f__default.default.hex("#ff3dff"),be=f__default.default.hex("#00ff9d"),S=f__default.default.hex("#555570"),B=f__default.default.hex("#00f0ff");function wo(){console.log(""),console.log(he(" \u2566 \u2566")+ye("\u2554\u2550\u2557\u2566")+ve("\u2554\u2550\u2557 ")+be("\u2554\u2550\u2557\u2566 \u2566")),console.log(he(" \u255A\u2557\u2554\u255D")+ye("\u2560\u2550\u2563\u2551")+ve("\u2560\u2563 ")+be("\u2551 \u2551 \u2551")),console.log(he(" \u255A\u255D ")+ye("\u2569 \u2569\u2569")+ve("\u255A ")+be("\u255A\u2550\u255D\u2569\u2550\u255D\u2569")),console.log(""),console.log(S(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500")),console.log(B(" VAIF Studio CLI")+S(` v${ut}`)),console.log(S(" Build full-stack apps at lightning speed")),console.log(S(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500")),console.log(""),console.log(f__default.default.bold(" Quick Start")),console.log(S(" $ ")+B("vaif login")+S(" Authenticate")),console.log(S(" $ ")+B("vaif init -t react-spa")+S(" Scaffold project")),console.log(S(" $ ")+B("vaif db push")+S(" Push migrations")),console.log(S(" $ ")+B("vaif generate")+S(" Generate types")),console.log(S(" $ ")+B("vaif functions deploy")+S(" Deploy functions")),console.log(""),console.log(f__default.default.bold(" Categories")),console.log(S(" auth ")+f__default.default.white("login, logout, whoami")),console.log(S(" project ")+f__default.default.white("init, templates, info, status")),console.log(S(" schema ")+f__default.default.white("pull, push, generate")),console.log(S(" database ")+f__default.default.white("db push, db pull, db seed, db reset")),console.log(S(" deploy ")+f__default.default.white("functions deploy, functions list")),console.log(S(" security ")+f__default.default.white("keys, secrets")),console.log(S(" ai ")+f__default.default.white("claude-setup")),console.log(""),console.log(S(" Run ")+B("vaif <command> --help")+S(" for details")),console.log(S(" Docs: ")+f__default.default.underline("https://docs.vaif.studio")),console.log("");}commander.program.name("vaif").description("VAIF CLI - Type generation and development tools").version(ut);commander.program.command("login").description("Authenticate with VAIF (opens browser)").option("-e, --email","Login with email/password instead of browser").option("-p, --project-id <id>","Default project ID").action(xe);commander.program.command("logout").description("Log out and remove stored credentials").action(Pe);commander.program.command("whoami").description("Show current authenticated user").action(Fe);commander.program.command("init").description("Initialize VAIF configuration in your project").option("--typescript","Setup for TypeScript project").option("-f, --force","Overwrite existing config").option("-t, --template <name>","Scaffold from a template (run vaif templates for list)").option("--features <features>","Comma-separated features to include: auth,database,realtime,storage,functions").option("--add-features <features>","Add features to an existing project (requires --template)").action(Le);commander.program.command("templates").alias("tpl").description("List available project templates").action(Ne);commander.program.command("info").description("Show project information (name, region, URLs)").option("-c, --config <path>","Config file path","vaif.config.json").option("-p, --project-id <id>","Project ID (overrides config)").action(st);commander.program.command("status").description("Show project status (tables, functions, storage, connections)").option("-c, --config <path>","Config file path","vaif.config.json").option("-p, --project-id <id>","Project ID (overrides config)").action(rt);commander.program.command("pull").description("Pull database schema from your VAIF project").option("-c, --config <path>","Config file path","vaif.config.json").option("-o, --output <path>","Output file path","vaif.schema.json").option("-s, --schema <name>","Schema name","public").option("-p, --project-id <id>","Project ID (overrides config)").action(De);commander.program.command("push").description("Push local schema changes to your VAIF project").option("-c, --config <path>","Config file path","vaif.config.json").option("-s, --schema <path>","Schema file path","vaif.schema.json").option("-p, --project-id <id>","Project ID (overrides config)").option("--dry-run","Preview changes without applying").option("-f, --force","Apply changes without confirmation").action($e);commander.program.command("generate").alias("gen").description("Generate TypeScript types from your database schema").option("-c, --connection <url>","Database connection string").option("-o, --output <path>","Output file path","./src/types/database.ts").option("--schema <name>","Schema name","public").option("--config <path>","Config file path","vaif.config.json").option("--dry-run","Preview generated types without writing").action(je);var pt=commander.program.command("functions").alias("fn").description("Manage serverless functions");pt.command("deploy").description("Deploy functions to your VAIF project").option("-c, --config <path>","Config file path","vaif.config.json").option("-p, --project-id <id>","Project ID (overrides config)").option("-e, --env-id <id>","Environment ID").option("-n, --name <name>","Function name filter").option("-r, --runtime <runtime>","Runtime (nodejs, typescript, python)").option("--entrypoint <file>","Specific entrypoint file").option("--dry-run","Preview deployment without deploying").action(ze);pt.command("list").alias("ls").description("List deployed functions").option("-c, --config <path>","Config file path","vaif.config.json").option("-p, --project-id <id>","Project ID (overrides config)").option("-e, --env-id <id>","Environment ID").action(Be);var ae=commander.program.command("db").description("Database management commands");ae.command("push").description("Push local Drizzle migrations to VAIF project").option("-c, --config <path>","Config file path","vaif.config.json").option("-p, --project-id <id>","Project ID (overrides config)").option("-d, --dir <path>","Migrations directory","./drizzle").option("--dry-run","Preview without applying").action(Je);ae.command("pull").description("Pull schema from VAIF project").option("-c, --config <path>","Config file path","vaif.config.json").option("-p, --project-id <id>","Project ID (overrides config)").option("-o, --output <path>","Output file","vaif.schema.json").action(Ge);ae.command("seed").description("Seed your database with test data").option("-c, --config <path>","Config file path","vaif.config.json").option("-p, --project-id <id>","Project ID (overrides config)").option("-f, --file <path>","Specific seed file").option("-t, --table <name>","Seed specific table only").option("--truncate","Truncate tables before seeding").option("--dry-run","Preview seeding without inserting data").action(Ye);ae.command("reset").description("Reset database (drop all tables and data)").option("-c, --config <path>","Config file path","vaif.config.json").option("-p, --project-id <id>","Project ID (overrides config)").option("-f, --force","Confirm reset (required)").action(We);var ft=commander.program.command("keys").description("Manage API keys");ft.command("generate").description("Generate a new API key").option("-c, --config <path>","Config file path","vaif.config.json").option("-p, --project-id <id>","Project ID (overrides config)").option("-n, --name <name>","Key name").action(Ze);ft.command("list").alias("ls").description("List API keys").option("-c, --config <path>","Config file path","vaif.config.json").option("-p, --project-id <id>","Project ID (overrides config)").action(et);var ie=commander.program.command("secrets").alias("sec").description("Manage function secrets");ie.command("set <name> [value]").description("Create or update a secret").option("-c, --config <path>","Config file path","vaif.config.json").option("-p, --project-id <id>","Project ID (overrides config)").option("-e, --env-id <id>","Environment ID or name").option("--from-file <path>","Read secret value from a file").action(tt);ie.command("list").alias("ls").description("List all secrets (names only)").option("-c, --config <path>","Config file path","vaif.config.json").option("-p, --project-id <id>","Project ID (overrides config)").option("-e, --env-id <id>","Environment ID or name").action(ot);ie.command("get <name>").description("Reveal a secret value").option("-c, --config <path>","Config file path","vaif.config.json").option("-p, --project-id <id>","Project ID (overrides config)").option("-e, --env-id <id>","Environment ID or name").action(nt);ie.command("delete <name>").description("Delete a secret").option("-c, --config <path>","Config file path","vaif.config.json").option("-p, --project-id <id>","Project ID (overrides config)").option("-e, --env-id <id>","Environment ID or name").action(at);commander.program.command("claude-setup").description("Configure Claude Code integration (MCP server + CLAUDE.md)").option("-c, --config <path>","Config file path","vaif.config.json").option("-p, --project-id <id>","Project ID").option("-k, --api-key <key>","API key for MCP server").option("--skip-mcp","Skip generating .mcp.json").option("--skip-claude-md","Skip generating CLAUDE.md").option("-o, --output-dir <dir>","Output directory",".").action(dt);process.argv.slice(2).length||(wo(),process.exit(0));commander.program.parse(process.argv);
4430
+ `}async function oe(t){let e=ie__default.default(),o=E();(!o||!o.token)&&(console.log(f__default.default.red("Not logged in")),console.log(f__default.default.gray("Run `vaif login` first to authenticate")),process.exit(1));let n=t.config||"vaif.config.json",i=null;try{i=await w(n);}catch{}let a=Xt(t,i,o);a||(console.log(f__default.default.yellow(`No project ID specified \u2014 fetching your projects...
4431
+ `)),a=await Qt(o.token),a||(console.log(f__default.default.gray(`
4432
+ Tip: pass --project-id <id> or set projectId in vaif.config.json`)),process.exit(1)));let r=S__default.default.resolve(t.outputDir||".");console.log(""),console.log(f__default.default.bold("VAIF Claude Code Setup")),console.log(f__default.default.gray(` Project: ${a}`)),console.log(""),e.start("Fetching database schema...");let s={tables:[]};try{let u=await fetch(`${Q}/schema-engine/introspect/${a}`,{headers:{Authorization:`Bearer ${o.token}`}});u.ok?(s=await u.json(),e.succeed(`Fetched schema (${s.tables?.length||0} tables)`)):e.warn("Could not fetch schema \u2014 continuing without it");}catch{e.warn("Could not fetch schema \u2014 continuing without it");}e.start("Fetching project info...");let c=a,l=Q;try{let u=await fetch(`${Q}/projects/${a}`,{headers:{Authorization:`Bearer ${o.token}`}});if(u.ok){let d=await u.json(),g=d.project||d;c=g.name||a,l=g.apiUrl||Q,e.succeed(`Project: ${c}`);}else e.warn("Could not fetch project info \u2014 using defaults");}catch{e.warn("Could not fetch project info \u2014 using defaults");}let p=t.apiKey||i?.api?.apiKey||"";if(!p){e.start("Generating API key for Claude Code...");try{let u=`claude-code-${Date.now()}`,d=await fetch(`${Q}/projects/${a}/api-keys`,{method:"POST",headers:{Authorization:`Bearer ${o.token}`,"Content-Type":"application/json"},body:JSON.stringify({name:u,scopes:["crud","realtime","functions","storage"]})});if(d.ok){let g=await d.json();p=g.apiKey||g.key,e.succeed(`Generated API key: ${u}`);}else e.fail("Could not auto-generate API key"),console.log(f__default.default.yellow(" Pass one with --api-key or generate via `vaif keys generate`")),process.exit(1);}catch{e.fail("Could not auto-generate API key"),console.log(f__default.default.yellow(" Pass one with --api-key or generate via `vaif keys generate`")),process.exit(1);}}if(!t.skipMcp){e.start("Writing .mcp.json...");let u={mcpServers:{"vaif-studio":{command:"npx",args:["@vaiftech/mcp"],env:{VAIF_API_KEY:p,VAIF_PROJECT_ID:a,VAIF_API_URL:l,VAIF_AUTH_TOKEN:o.token}}}},d=S__default.default.join(r,".mcp.json");A__default.default.writeFileSync(d,JSON.stringify(u,null,2)+`
4433
+ `,"utf-8"),e.succeed(`Written ${f__default.default.cyan(".mcp.json")}`);}if(!t.skipClaudeMd){e.start("Writing CLAUDE.md...");let u=oo({projectId:a,apiKey:p,apiUrl:l,projectName:c,schema:s}),d=S__default.default.join(r,"CLAUDE.md");A__default.default.writeFileSync(d,u,"utf-8"),e.succeed(`Written ${f__default.default.cyan("CLAUDE.md")}`);}console.log(""),console.log(f__default.default.green.bold(" Claude Code integration configured!")),console.log(""),t.skipMcp||console.log(f__default.default.gray(" MCP Server: ")+f__default.default.white(".mcp.json")),t.skipClaudeMd||console.log(f__default.default.gray(" Context: ")+f__default.default.white("CLAUDE.md")),console.log(""),console.log(f__default.default.bold(" Next steps:")),console.log(f__default.default.gray(" 1. Open this project in Claude Code")),console.log(f__default.default.gray(" 2. The MCP server auto-connects to your VAIF project")),console.log(f__default.default.gray(" 3. Ask Claude to query, modify, or build against your schema")),console.log("");}var ne={base:`# VAIF Studio Backend
4434
+
4435
+ This project uses **VAIF Studio** as its backend.
4436
+
4437
+ ## SDK Setup
4438
+
4439
+ \`\`\`bash
4440
+ npm install @vaiftech/client
4441
+ \`\`\`
4442
+
4443
+ \`\`\`typescript
4444
+ import { createVaifClient } from "@vaiftech/client";
4445
+
4446
+ const vaif = createVaifClient({
4447
+ baseUrl: "https://api.vaif.studio",
4448
+ projectId: process.env.VAIF_PROJECT_ID!,
4449
+ apiKey: process.env.VAIF_API_KEY!,
4450
+ });
4451
+ \`\`\`
4452
+
4453
+ ## MCP Server
4454
+
4455
+ This project includes an MCP server for Claude Code integration. Tools available:
4456
+
4457
+ - **Database**: list_tables, describe_table, query_rows, insert_row, update_row, delete_row
4458
+ - **Schema**: get_schema, create_tables
4459
+ - **Storage**: list_buckets, create_bucket, list_files, get_signed_url
4460
+ - **Functions**: list_functions, invoke_function, create_function, deploy_function
4461
+ - **Auth**: list_api_keys, create_api_key
4462
+ - **Realtime**: realtime_status, enable_realtime
4463
+
4464
+ ## Database
4465
+
4466
+ \`\`\`typescript
4467
+ // Query
4468
+ const { data } = await vaif.from("table_name").select().eq("column", value);
4469
+
4470
+ // Insert
4471
+ const { data } = await vaif.from("table_name").insert({ column: value });
4472
+
4473
+ // Update
4474
+ await vaif.from("table_name").update({ column: newValue }).eq("id", recordId);
4475
+
4476
+ // Delete
4477
+ await vaif.from("table_name").delete().eq("id", recordId);
4478
+ \`\`\`
4479
+
4480
+ ## Authentication
4481
+
4482
+ \`\`\`typescript
4483
+ // Sign up
4484
+ await vaif.auth.signUp({ email, password });
4485
+
4486
+ // Sign in
4487
+ const { data } = await vaif.auth.signIn({ email, password });
4488
+
4489
+ // OAuth
4490
+ await vaif.auth.signInWithOAuth({ provider: "google", redirectTo: callbackUrl });
4491
+
4492
+ // Get current user
4493
+ const user = await vaif.auth.getUser();
4494
+ \`\`\`
4495
+
4496
+ ## Storage
4497
+
4498
+ \`\`\`typescript
4499
+ // Upload
4500
+ await vaif.storage.from("bucket").upload("path/file.png", file);
4501
+
4502
+ // Signed URL
4503
+ const { url } = await vaif.storage.from("bucket").createSignedUrl("path/file.png", 3600);
4504
+
4505
+ // List files
4506
+ const { data } = await vaif.storage.from("bucket").list("path/");
4507
+ \`\`\`
4508
+
4509
+ ## Functions
4510
+
4511
+ \`\`\`typescript
4512
+ // Invoke
4513
+ const result = await vaif.functions.invoke("function_name", { body: { key: "value" } });
4514
+ \`\`\`
4515
+
4516
+ > Function names must be alphanumeric + underscores only (\`^[a-zA-Z0-9_]+$\`).
4517
+
4518
+ ## Realtime
4519
+
4520
+ \`\`\`typescript
4521
+ const subscription = vaif.realtime
4522
+ .channel("table_name")
4523
+ .on("INSERT", (payload) => console.log("New:", payload.new))
4524
+ .on("UPDATE", (payload) => console.log("Updated:", payload.new))
4525
+ .on("DELETE", (payload) => console.log("Removed:", payload.old))
4526
+ .subscribe();
4527
+ \`\`\`
4528
+
4529
+ ## Filter Operators
4530
+
4531
+ | Operator | Description | Example |
4532
+ |----------|-------------|---------|
4533
+ | eq | Equal | \`.eq("status", "active")\` |
4534
+ | neq | Not equal | \`.neq("status", "deleted")\` |
4535
+ | gt / gte | Greater than | \`.gt("age", 18)\` |
4536
+ | lt / lte | Less than | \`.lt("price", 100)\` |
4537
+ | in | In array | \`.in("role", ["admin", "editor"])\` |
4538
+ | like / ilike | Pattern match | \`.ilike("name", "%john%")\` |
4539
+ | is | IS NULL check | \`.is("deleted_at", null)\` |
4540
+
4541
+ ## Auth Headers
4542
+
4543
+ | Mode | Header | Used For |
4544
+ |------|--------|----------|
4545
+ | API Key | \`x-vaif-key: vk_xxx\` | Data-plane: CRUD, storage, functions |
4546
+ | JWT Token | \`Authorization: Bearer <jwt>\` | Control-plane: schema, project management |
4547
+
4548
+ ## Environment Variables
4549
+
4550
+ \`\`\`bash
4551
+ VAIF_API_URL=https://api.vaif.studio
4552
+ VAIF_PROJECT_ID=proj_xxx
4553
+ VAIF_API_KEY=vk_xxx
4554
+ \`\`\`
4555
+ `,saas:`# VAIF Studio \u2014 SaaS Backend
4556
+
4557
+ This project uses **VAIF Studio** as its backend for a SaaS application.
4558
+
4559
+ ## SDK Setup
4560
+
4561
+ \`\`\`bash
4562
+ npm install @vaiftech/client @vaiftech/react
4563
+ \`\`\`
4564
+
4565
+ \`\`\`typescript
4566
+ import { createVaifClient } from "@vaiftech/client";
4567
+
4568
+ const vaif = createVaifClient({
4569
+ baseUrl: "https://api.vaif.studio",
4570
+ projectId: process.env.VAIF_PROJECT_ID!,
4571
+ apiKey: process.env.VAIF_API_KEY!,
4572
+ });
4573
+ \`\`\`
4574
+
4575
+ ## Common SaaS Schema Patterns
4576
+
4577
+ ### Multi-Tenant with Organizations
4578
+
4579
+ \`\`\`sql
4580
+ -- Organizations (tenants)
4581
+ CREATE TABLE orgs (
4582
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
4583
+ name TEXT NOT NULL,
4584
+ slug TEXT UNIQUE NOT NULL,
4585
+ plan TEXT DEFAULT 'free',
4586
+ created_at TIMESTAMPTZ DEFAULT now()
4587
+ );
4588
+
4589
+ -- Organization members
4590
+ CREATE TABLE org_members (
4591
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
4592
+ org_id UUID REFERENCES orgs(id) ON DELETE CASCADE,
4593
+ user_id UUID NOT NULL,
4594
+ role TEXT DEFAULT 'member', -- owner, admin, member
4595
+ created_at TIMESTAMPTZ DEFAULT now(),
4596
+ UNIQUE(org_id, user_id)
4597
+ );
4598
+
4599
+ -- Tenant-scoped data
4600
+ CREATE TABLE projects (
4601
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
4602
+ org_id UUID REFERENCES orgs(id) ON DELETE CASCADE,
4603
+ name TEXT NOT NULL,
4604
+ settings JSONB DEFAULT '{}',
4605
+ created_at TIMESTAMPTZ DEFAULT now()
4606
+ );
4607
+ CREATE INDEX idx_projects_org ON projects(org_id);
4608
+ \`\`\`
4609
+
4610
+ ### Row-Level Security for Multi-Tenancy
4611
+
4612
+ \`\`\`typescript
4613
+ // Scope all queries to the current organization
4614
+ const projects = await vaif.from("projects").select().eq("org_id", currentOrgId);
4615
+
4616
+ // Or use RLS headers for automatic scoping
4617
+ const data = await vaif.from("projects").select({
4618
+ headers: { "x-vaif-rls": \\\`org_id:\${currentOrgId}\\\` },
4619
+ });
4620
+ \`\`\`
4621
+
4622
+ ### Auth Flows
4623
+
4624
+ \`\`\`typescript
4625
+ // Sign up \u2192 create org \u2192 add as owner
4626
+ const { data: user } = await vaif.auth.signUp({ email, password });
4627
+ const { data: org } = await vaif.from("orgs").insert({ name: orgName, slug });
4628
+ await vaif.from("org_members").insert({ org_id: org.id, user_id: user.id, role: "owner" });
4629
+ \`\`\`
4630
+
4631
+ ### Billing Integration
4632
+
4633
+ \`\`\`typescript
4634
+ // Store Stripe customer/subscription IDs
4635
+ CREATE TABLE billing_accounts (
4636
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
4637
+ org_id UUID UNIQUE REFERENCES orgs(id),
4638
+ stripe_customer_id TEXT,
4639
+ stripe_subscription_id TEXT,
4640
+ plan TEXT DEFAULT 'free',
4641
+ period_start TIMESTAMPTZ,
4642
+ period_end TIMESTAMPTZ
4643
+ );
4644
+
4645
+ // Webhook handler (VAIF Function)
4646
+ export default async function handler(req, ctx) {
4647
+ const event = req.body;
4648
+ if (event.type === "customer.subscription.updated") {
4649
+ const sub = event.data.object;
4650
+ await vaif.from("billing_accounts")
4651
+ .update({ plan: sub.metadata.plan, period_end: sub.current_period_end })
4652
+ .eq("stripe_subscription_id", sub.id);
4653
+ }
4654
+ return { received: true };
4655
+ }
4656
+ \`\`\`
4657
+
4658
+ ### Invite System
4659
+
4660
+ \`\`\`sql
4661
+ CREATE TABLE invites (
4662
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
4663
+ org_id UUID REFERENCES orgs(id) ON DELETE CASCADE,
4664
+ email TEXT NOT NULL,
4665
+ role TEXT DEFAULT 'member',
4666
+ token TEXT UNIQUE NOT NULL,
4667
+ expires_at TIMESTAMPTZ NOT NULL,
4668
+ accepted_at TIMESTAMPTZ
4669
+ );
4670
+ \`\`\`
4671
+
4672
+ ## API Key Scoping
4673
+
4674
+ \`\`\`
4675
+ x-vaif-key: vk_xxx \u2192 Data-plane (CRUD, storage, functions)
4676
+ Authorization: Bearer <jwt> \u2192 Control-plane (schema, project management)
4677
+ \`\`\`
4678
+
4679
+ ## Environment Variables
4680
+
4681
+ \`\`\`bash
4682
+ VAIF_API_URL=https://api.vaif.studio
4683
+ VAIF_PROJECT_ID=proj_xxx
4684
+ VAIF_API_KEY=vk_xxx
4685
+ STRIPE_SECRET_KEY=sk_live_xxx
4686
+ STRIPE_WEBHOOK_SECRET=whsec_xxx
4687
+ \`\`\`
4688
+ `,mobile:`# VAIF Studio \u2014 Mobile App Backend
4689
+
4690
+ This project uses **VAIF Studio** as its backend for a mobile application (React Native/Expo, Flutter, or Swift).
4691
+
4692
+ ## SDK Setup
4693
+
4694
+ ### React Native / Expo
4695
+ \`\`\`bash
4696
+ npm install @vaiftech/sdk-expo
4697
+ \`\`\`
4698
+
4699
+ \`\`\`typescript
4700
+ import { VaifProvider, useVaif } from "@vaiftech/sdk-expo";
4701
+
4702
+ export default function App() {
4703
+ return (
4704
+ <VaifProvider
4705
+ config={{
4706
+ baseUrl: "https://api.vaif.studio",
4707
+ projectId: "proj_xxx",
4708
+ apiKey: "vk_xxx",
4709
+ }}
4710
+ >
4711
+ <MainApp />
4712
+ </VaifProvider>
4713
+ );
4714
+ }
4715
+ \`\`\`
4716
+
4717
+ ### Flutter / Dart
4718
+ \`\`\`yaml
4719
+ # pubspec.yaml
4720
+ dependencies:
4721
+ vaif_client: ^1.0.0
4722
+ \`\`\`
4723
+
4724
+ \`\`\`dart
4725
+ import 'package:vaif_client/vaif_client.dart';
4726
+
4727
+ final vaif = VaifClient(
4728
+ baseUrl: 'https://api.vaif.studio',
4729
+ projectId: 'proj_xxx',
4730
+ apiKey: 'vk_xxx',
4731
+ );
4732
+ \`\`\`
4733
+
4734
+ ### Swift / iOS
4735
+ \`\`\`swift
4736
+ // Package.swift
4737
+ .package(url: "https://github.com/vaifllc/vaif-swift", from: "0.2.0")
4738
+
4739
+ import VaifClient
4740
+
4741
+ let vaif = VaifClient(
4742
+ baseUrl: "https://api.vaif.studio",
4743
+ projectId: "proj_xxx",
4744
+ apiKey: "vk_xxx"
4745
+ )
4746
+ \`\`\`
4747
+
4748
+ ## Common Mobile Patterns
4749
+
4750
+ ### User Profiles with Avatars
4751
+
4752
+ \`\`\`sql
4753
+ CREATE TABLE profiles (
4754
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
4755
+ user_id UUID UNIQUE NOT NULL,
4756
+ display_name TEXT,
4757
+ avatar_url TEXT,
4758
+ bio TEXT,
4759
+ push_token TEXT,
4760
+ device_type TEXT, -- ios, android
4761
+ last_seen TIMESTAMPTZ DEFAULT now()
4762
+ );
4763
+ \`\`\`
4764
+
4765
+ ### Push Notifications
4766
+
4767
+ \`\`\`typescript
4768
+ // Store push tokens
4769
+ await vaif.from("profiles").update({
4770
+ push_token: expoPushToken,
4771
+ device_type: Platform.OS,
4772
+ }).eq("user_id", userId);
4773
+
4774
+ // Send notification (VAIF Function)
4775
+ export default async function handler(req, ctx) {
4776
+ const { userId, title, body } = req.body;
4777
+ const { data: profile } = await vaif.from("profiles")
4778
+ .select("push_token, device_type")
4779
+ .eq("user_id", userId)
4780
+ .single();
4781
+
4782
+ // Send via Expo Push API or APNs/FCM
4783
+ await fetch("https://exp.host/--/api/v2/push/send", {
4784
+ method: "POST",
4785
+ headers: { "Content-Type": "application/json" },
4786
+ body: JSON.stringify({
4787
+ to: profile.push_token,
4788
+ title, body,
4789
+ }),
4790
+ });
4791
+ return { sent: true };
4792
+ }
4793
+ \`\`\`
4794
+
4795
+ ### Offline-First with Sync
4796
+
4797
+ \`\`\`typescript
4798
+ // Cache data locally, sync when online
4799
+ import AsyncStorage from "@react-native-async-storage/async-storage";
4800
+
4801
+ // Fetch and cache
4802
+ const { data } = await vaif.from("items").select();
4803
+ await AsyncStorage.setItem("items_cache", JSON.stringify(data));
4804
+
4805
+ // Read from cache when offline
4806
+ const cached = JSON.parse(await AsyncStorage.getItem("items_cache") || "[]");
4807
+ \`\`\`
4808
+
4809
+ ### Image Upload from Camera
4810
+
4811
+ \`\`\`typescript
4812
+ import * as ImagePicker from "expo-image-picker";
4813
+
4814
+ const result = await ImagePicker.launchCameraAsync({ quality: 0.8 });
4815
+ if (!result.canceled) {
4816
+ const uri = result.assets[0].uri;
4817
+ const response = await fetch(uri);
4818
+ const blob = await response.blob();
4819
+
4820
+ await vaif.storage.from("avatars").upload(
4821
+ \\\`\${userId}/avatar.jpg\\\`,
4822
+ blob,
4823
+ { contentType: "image/jpeg" }
4824
+ );
4825
+ }
4826
+ \`\`\`
4827
+
4828
+ ### Realtime Chat
4829
+
4830
+ \`\`\`typescript
4831
+ // Subscribe to new messages
4832
+ const subscription = vaif.realtime
4833
+ .channel("messages")
4834
+ .on("INSERT", (payload) => {
4835
+ setMessages(prev => [...prev, payload.new]);
4836
+ })
4837
+ .subscribe();
4838
+
4839
+ // Send a message
4840
+ await vaif.from("messages").insert({
4841
+ room_id: roomId,
4842
+ user_id: userId,
4843
+ content: messageText,
4844
+ });
4845
+ \`\`\`
4846
+
4847
+ ## Auth with Secure Token Storage
4848
+
4849
+ The Expo SDK automatically stores auth tokens in SecureStore (iOS Keychain / Android Keystore).
4850
+
4851
+ \`\`\`typescript
4852
+ const { useAuth } = require("@vaiftech/sdk-expo");
4853
+
4854
+ function LoginScreen() {
4855
+ const { signIn, signUp, user, loading } = useAuth();
4856
+
4857
+ const handleLogin = async () => {
4858
+ const { error } = await signIn({ email, password });
4859
+ if (error) Alert.alert("Error", error.message);
4860
+ };
4861
+ }
4862
+ \`\`\`
4863
+
4864
+ ## Environment Variables
4865
+
4866
+ \`\`\`bash
4867
+ VAIF_API_URL=https://api.vaif.studio
4868
+ VAIF_PROJECT_ID=proj_xxx
4869
+ VAIF_API_KEY=vk_xxx
4870
+ EXPO_PUBLIC_VAIF_PROJECT_ID=proj_xxx
4871
+ EXPO_PUBLIC_VAIF_API_KEY=vk_xxx
4872
+ \`\`\`
4873
+ `,ecommerce:`# VAIF Studio \u2014 E-Commerce Backend
4874
+
4875
+ This project uses **VAIF Studio** as its backend for an e-commerce application.
4876
+
4877
+ ## SDK Setup
4878
+
4879
+ \`\`\`bash
4880
+ npm install @vaiftech/client
4881
+ \`\`\`
4882
+
4883
+ \`\`\`typescript
4884
+ import { createVaifClient } from "@vaiftech/client";
4885
+
4886
+ const vaif = createVaifClient({
4887
+ baseUrl: "https://api.vaif.studio",
4888
+ projectId: process.env.VAIF_PROJECT_ID!,
4889
+ apiKey: process.env.VAIF_API_KEY!,
4890
+ });
4891
+ \`\`\`
4892
+
4893
+ ## E-Commerce Schema
4894
+
4895
+ \`\`\`sql
4896
+ -- Products
4897
+ CREATE TABLE products (
4898
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
4899
+ name TEXT NOT NULL,
4900
+ slug TEXT UNIQUE NOT NULL,
4901
+ description TEXT,
4902
+ price NUMERIC(10,2) NOT NULL,
4903
+ compare_at_price NUMERIC(10,2),
4904
+ currency TEXT DEFAULT 'USD',
4905
+ sku TEXT UNIQUE,
4906
+ inventory_count INTEGER DEFAULT 0,
4907
+ category_id UUID REFERENCES categories(id),
4908
+ images JSONB DEFAULT '[]', -- [{url, alt, position}]
4909
+ metadata JSONB DEFAULT '{}',
4910
+ status TEXT DEFAULT 'draft', -- draft, active, archived
4911
+ created_at TIMESTAMPTZ DEFAULT now(),
4912
+ updated_at TIMESTAMPTZ DEFAULT now()
4913
+ );
4914
+ CREATE INDEX idx_products_category ON products(category_id);
4915
+ CREATE INDEX idx_products_status ON products(status);
4916
+
4917
+ -- Categories
4918
+ CREATE TABLE categories (
4919
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
4920
+ name TEXT NOT NULL,
4921
+ slug TEXT UNIQUE NOT NULL,
4922
+ parent_id UUID REFERENCES categories(id),
4923
+ sort_order INTEGER DEFAULT 0
4924
+ );
4925
+
4926
+ -- Orders
4927
+ CREATE TABLE orders (
4928
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
4929
+ user_id UUID NOT NULL,
4930
+ status TEXT DEFAULT 'pending', -- pending, confirmed, shipped, delivered, cancelled
4931
+ subtotal NUMERIC(10,2) NOT NULL,
4932
+ tax NUMERIC(10,2) DEFAULT 0,
4933
+ shipping NUMERIC(10,2) DEFAULT 0,
4934
+ total NUMERIC(10,2) NOT NULL,
4935
+ currency TEXT DEFAULT 'USD',
4936
+ shipping_address JSONB,
4937
+ billing_address JSONB,
4938
+ stripe_payment_intent_id TEXT,
4939
+ notes TEXT,
4940
+ created_at TIMESTAMPTZ DEFAULT now(),
4941
+ updated_at TIMESTAMPTZ DEFAULT now()
4942
+ );
4943
+ CREATE INDEX idx_orders_user ON orders(user_id);
4944
+ CREATE INDEX idx_orders_status ON orders(status);
4945
+
4946
+ -- Order items
4947
+ CREATE TABLE order_items (
4948
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
4949
+ order_id UUID REFERENCES orders(id) ON DELETE CASCADE,
4950
+ product_id UUID REFERENCES products(id),
4951
+ quantity INTEGER NOT NULL,
4952
+ unit_price NUMERIC(10,2) NOT NULL,
4953
+ total NUMERIC(10,2) NOT NULL
4954
+ );
4955
+ CREATE INDEX idx_order_items_order ON order_items(order_id);
4956
+
4957
+ -- Cart (session-based)
4958
+ CREATE TABLE carts (
4959
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
4960
+ user_id UUID,
4961
+ session_id TEXT,
4962
+ items JSONB DEFAULT '[]', -- [{productId, quantity, price}]
4963
+ created_at TIMESTAMPTZ DEFAULT now(),
4964
+ updated_at TIMESTAMPTZ DEFAULT now()
4965
+ );
4966
+
4967
+ -- Reviews
4968
+ CREATE TABLE reviews (
4969
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
4970
+ product_id UUID REFERENCES products(id) ON DELETE CASCADE,
4971
+ user_id UUID NOT NULL,
4972
+ rating INTEGER CHECK (rating >= 1 AND rating <= 5),
4973
+ title TEXT,
4974
+ body TEXT,
4975
+ created_at TIMESTAMPTZ DEFAULT now()
4976
+ );
4977
+ CREATE INDEX idx_reviews_product ON reviews(product_id);
4978
+ \`\`\`
4979
+
4980
+ ## Common Patterns
4981
+
4982
+ ### Product Listing with Filters
4983
+
4984
+ \`\`\`typescript
4985
+ // Browse products with category filter and pagination
4986
+ const { data: products } = await vaif
4987
+ .from("products")
4988
+ .select("id, name, slug, price, compare_at_price, images, category:categories(name)")
4989
+ .eq("status", "active")
4990
+ .eq("category_id", categoryId)
4991
+ .order("created_at", { ascending: false })
4992
+ .limit(20)
4993
+ .offset(page * 20);
4994
+ \`\`\`
4995
+
4996
+ ### Cart Management
4997
+
4998
+ \`\`\`typescript
4999
+ // Add to cart
5000
+ const cart = await vaif.from("carts").select().eq("user_id", userId).single();
5001
+ const items = [...(cart.data?.items || [])];
5002
+ const existing = items.findIndex(i => i.productId === productId);
5003
+ if (existing >= 0) {
5004
+ items[existing].quantity += quantity;
5005
+ } else {
5006
+ items.push({ productId, quantity, price });
5007
+ }
5008
+ await vaif.from("carts").update({ items, updated_at: new Date().toISOString() }).eq("id", cart.data.id);
5009
+ \`\`\`
5010
+
5011
+ ### Order Creation
5012
+
5013
+ \`\`\`typescript
5014
+ // Create order from cart
5015
+ const { data: order } = await vaif.from("orders").insert({
5016
+ user_id: userId,
5017
+ subtotal, tax, shipping,
5018
+ total: subtotal + tax + shipping,
5019
+ shipping_address: addressData,
5020
+ });
5021
+
5022
+ // Create order items
5023
+ const orderItems = cartItems.map(item => ({
5024
+ order_id: order.id,
5025
+ product_id: item.productId,
5026
+ quantity: item.quantity,
5027
+ unit_price: item.price,
5028
+ total: item.price * item.quantity,
5029
+ }));
5030
+ await vaif.from("order_items").insert(orderItems);
5031
+ \`\`\`
5032
+
5033
+ ### Inventory Management
5034
+
5035
+ \`\`\`typescript
5036
+ // Decrement inventory on order (VAIF Function)
5037
+ export default async function handler(req, ctx) {
5038
+ const { items } = req.body; // [{productId, quantity}]
5039
+ for (const item of items) {
5040
+ const { data: product } = await vaif.from("products")
5041
+ .select("inventory_count")
5042
+ .eq("id", item.productId)
5043
+ .single();
5044
+
5045
+ if (product.inventory_count < item.quantity) {
5046
+ return { error: \\\`Insufficient stock for \${item.productId}\\\` };
5047
+ }
5048
+
5049
+ await vaif.from("products")
5050
+ .update({ inventory_count: product.inventory_count - item.quantity })
5051
+ .eq("id", item.productId);
5052
+ }
5053
+ return { success: true };
5054
+ }
5055
+ \`\`\`
5056
+
5057
+ ### Payment Webhooks
5058
+
5059
+ \`\`\`typescript
5060
+ // Stripe webhook handler (VAIF Function)
5061
+ export default async function handler(req, ctx) {
5062
+ const sig = req.headers["stripe-signature"];
5063
+ const event = stripe.webhooks.constructEvent(req.rawBody, sig, ctx.secrets.STRIPE_WEBHOOK_SECRET);
5064
+
5065
+ switch (event.type) {
5066
+ case "payment_intent.succeeded":
5067
+ await vaif.from("orders")
5068
+ .update({ status: "confirmed" })
5069
+ .eq("stripe_payment_intent_id", event.data.object.id);
5070
+ break;
5071
+ case "payment_intent.payment_failed":
5072
+ await vaif.from("orders")
5073
+ .update({ status: "cancelled" })
5074
+ .eq("stripe_payment_intent_id", event.data.object.id);
5075
+ break;
5076
+ }
5077
+ return { received: true };
5078
+ }
5079
+ \`\`\`
5080
+
5081
+ ### Product Image Upload
5082
+
5083
+ \`\`\`typescript
5084
+ // Upload product images to storage
5085
+ const { url } = await vaif.storage
5086
+ .from("product-images")
5087
+ .upload(\\\`\${productId}/\${fileName}\\\`, file, { contentType: "image/webp" });
5088
+
5089
+ // Update product images array
5090
+ const { data: product } = await vaif.from("products").select("images").eq("id", productId).single();
5091
+ const images = [...(product.images || []), { url, alt: altText, position: product.images.length }];
5092
+ await vaif.from("products").update({ images }).eq("id", productId);
5093
+ \`\`\`
5094
+
5095
+ ## Environment Variables
5096
+
5097
+ \`\`\`bash
5098
+ VAIF_API_URL=https://api.vaif.studio
5099
+ VAIF_PROJECT_ID=proj_xxx
5100
+ VAIF_API_KEY=vk_xxx
5101
+ STRIPE_SECRET_KEY=sk_live_xxx
5102
+ STRIPE_PUBLISHABLE_KEY=pk_live_xxx
5103
+ STRIPE_WEBHOOK_SECRET=whsec_xxx
5104
+ \`\`\`
5105
+
5106
+ > **Note**: \`numeric\` columns (like \`price\`) serialize to JSON strings to preserve precision. Parse with \`parseFloat()\` before arithmetic.
5107
+ `};var no={$schema:"https://vaif.studio/schemas/config.json",projectId:"",database:{url:"${DATABASE_URL}",schema:"public"},types:{output:"./src/types/database.ts"},api:{baseUrl:"https://api.vaif.studio"}};async function qe(t){if(t.claude!==void 0){let n=typeof t.claude=="string"?t.claude:null;if(n&&n in ne){let a=ie__default.default("Generating CLAUDE.md from template...").start(),r=ne[n],s=io();s&&(r+=`
5108
+ ## Team Conventions
5109
+
5110
+ ${s}
5111
+ `);let c=S__default.default.resolve("CLAUDE.md");A__default.default.existsSync(c)&&!t.force&&(a.fail("CLAUDE.md already exists"),console.log(f__default.default.yellow(`
5112
+ Use --force to overwrite.`)),process.exit(1)),A__default.default.writeFileSync(c,r,"utf-8"),a.succeed(`Created CLAUDE.md (${n} template)`),s&&console.log(f__default.default.gray(" Imported team conventions from existing config files.")),console.log(f__default.default.gray(`
5113
+ Customize the generated CLAUDE.md with your project details.`)),console.log(f__default.default.gray(` For a personalized version from live data, run: vaif claude-setup
5114
+ `));return}n&&!(n in ne)&&(console.log(f__default.default.red(`
5115
+ Unknown template type: "${n}"`)),console.log(f__default.default.gray(" Available types: base, saas, mobile, ecommerce")),console.log(f__default.default.gray(` Or omit the type to auto-generate from your live project: vaif init --claude
5116
+ `)),process.exit(1));let i=ao();i?(console.log(f__default.default.gray(`
5117
+ Detected project type: ${f__default.default.cyan(i)}`)),console.log(f__default.default.gray(` Generating from live project data with template context...
5118
+ `))):console.log(f__default.default.gray(`
5119
+ Generating from live project data...
5120
+ `)),await oe({skipMcp:false});return}if(t.addFeatures){t.template||(console.log(f__default.default.red(`
5121
+ --add-features requires --template to know which template to use.`)),console.log(f__default.default.gray("Example: vaif init --template react-spa --add-features functions,storage")),process.exit(1));let n=t.addFeatures.split(",").map(i=>i.trim());await be(t.template,{force:t.force,features:n,addOnly:true});return}let e=ie__default.default("Initializing VAIF configuration...").start(),o=S__default.default.resolve("vaif.config.json");A__default.default.existsSync(o)&&!t.force&&(e.fail("vaif.config.json already exists"),console.log(f__default.default.yellow(`
5122
+ Use --force to overwrite existing configuration.`)),process.exit(1));try{if(A__default.default.writeFileSync(o,JSON.stringify(no,null,2),"utf-8"),e.succeed("Created vaif.config.json"),t.template){let n=t.features?t.features.split(",").map(i=>i.trim()):void 0;await be(t.template,{force:t.force,features:n});}else {let n=S__default.default.resolve(".env.example");if(A__default.default.existsSync(n)||(A__default.default.writeFileSync(n,`# VAIF Configuration
5123
+ DATABASE_URL=postgresql://user:password@localhost:5432/database
5124
+ VAIF_API_KEY=your-api-key
5125
+ `,"utf-8"),console.log(f__default.default.gray("Created .env.example"))),t.typescript){let i=S__default.default.resolve("src/types");A__default.default.existsSync(i)||(A__default.default.mkdirSync(i,{recursive:!0}),console.log(f__default.default.gray("Created src/types directory")));}console.log(""),console.log(f__default.default.green("VAIF initialized successfully!")),console.log(""),console.log(f__default.default.gray("Next steps:")),console.log(f__default.default.gray(" 1. Update vaif.config.json with your project ID")),console.log(f__default.default.gray(" 2. Set DATABASE_URL in your environment")),console.log(f__default.default.gray(" 3. Run: npx vaif generate")),console.log("");}}catch(n){e.fail("Failed to initialize"),n instanceof Error&&console.error(f__default.default.red(`
5126
+ Error: ${n.message}`)),process.exit(1);}}function ao(){try{let t=S__default.default.resolve("package.json");if(!A__default.default.existsSync(t))return null;let e=JSON.parse(A__default.default.readFileSync(t,"utf-8")),o={...e.dependencies,...e.devDependencies};return o.expo||o["react-native"]||o["@vaiftech/sdk-expo"]||A__default.default.existsSync(S__default.default.resolve("pubspec.yaml"))||A__default.default.existsSync(S__default.default.resolve("Package.swift"))||A__default.default.existsSync(S__default.default.resolve("*.xcodeproj"))?"mobile":(o.stripe||o["@stripe/stripe-js"]||o["shopify-api-node"]||o["@shopify/shopify-api"])&&(A__default.default.existsSync(S__default.default.resolve("src/models/product.ts"))||A__default.default.existsSync(S__default.default.resolve("src/models/order.ts"))||A__default.default.existsSync(S__default.default.resolve("src/pages/products"))||A__default.default.existsSync(S__default.default.resolve("src/pages/cart")))?"ecommerce":o.stripe||o["@stripe/stripe-js"]||e.name?.includes("saas")||e.description?.toLowerCase().includes("saas")?"saas":"base"}catch{return null}}function io(){let t=[{path:".cursorrules",label:"Cursor Rules"},{path:".github/copilot-instructions.md",label:"GitHub Copilot Instructions"},{path:".windsurfrules",label:"Windsurf Rules"},{path:".clinerules",label:"Cline Rules"}],e=[];for(let o of t){let n=S__default.default.resolve(o.path);if(A__default.default.existsSync(n))try{let i=A__default.default.readFileSync(n,"utf-8").trim();i.length>0&&i.length<1e4&&e.push(`### From ${o.label} (\`${o.path}\`)
5127
+
5128
+ ${i}`);}catch{}}return e.length>0?e.join(`
5129
+
5130
+ `):null}var lo=process.env.VAIF_API_URL||"https://api.vaif.studio";async function uo(t,e,o="public"){let n=await fetch(`${lo}/projects/${e}/schema?schema=${o}`,{headers:{Authorization:`Bearer ${t}`,"Content-Type":"application/json"}});if(!n.ok){let i=await n.text();throw new Error(`Failed to fetch schema: ${i}`)}return n.json()}async function Ye(t){let e=ie__default.default(),o=E();(!o||!o.token)&&(console.log(f__default.default.red("Not logged in")),console.log(f__default.default.gray("Run `vaif login` first to authenticate")),process.exit(1));let n=t.config||"vaif.config.json",i=null;e.start("Loading configuration...");try{i=await w(n);}catch(r){e.fail("Failed to load config"),console.log(f__default.default.red(`
5131
+ Error: ${r}`)),process.exit(1);}i||(e.fail("No configuration found"),console.log(f__default.default.yellow("\nRun `vaif init` to create a configuration file.")),process.exit(1));let a=t.projectId||i.projectId||process.env.VAIF_PROJECT_ID||o.projectId;a||(e.fail("No project ID specified"),console.log(f__default.default.yellow(`
5132
+ Set projectId in vaif.config.json or use --project-id flag.`)),process.exit(1)),e.text="Fetching remote schema...";try{let r=t.schema||i.database?.schema||"public",s=await uo(o.token,a,r);e.succeed("Schema fetched successfully");let c=t.output||S__default.default.resolve("vaif.schema.json"),l={$schema:"https://vaif.studio/schemas/schema.json",projectId:a,schema:r,pulledAt:new Date().toISOString(),...s};A__default.default.writeFileSync(c,JSON.stringify(l,null,2),"utf-8"),console.log(""),console.log(f__default.default.green(`Schema saved to: ${c}`)),console.log(""),console.log(f__default.default.gray("Schema summary:")),console.log(f__default.default.gray(` Tables: ${(s.tables||[]).length}`)),console.log(f__default.default.gray(` Enums: ${(s.enums||[]).length}`)),console.log(f__default.default.gray(` Functions: ${(s.functions||[]).length}`)),console.log(""),console.log(f__default.default.gray("Next steps:")),console.log(f__default.default.gray(" - Run `vaif generate` to generate TypeScript types")),console.log(f__default.default.gray(" - Edit the schema and run `vaif push` to deploy changes")),console.log("");}catch(r){e.fail("Failed to fetch schema"),r instanceof Error&&console.log(f__default.default.red(`
5133
+ Error: ${r.message}`)),process.exit(1);}}var Ge=process.env.VAIF_API_URL||"https://api.vaif.studio";function mo(t){let e=Re__default.default.createInterface({input:process.stdin,output:process.stdout});return new Promise(o=>{e.question(t,n=>{e.close(),o(n);});})}async function ho(t,e,o){let n=await fetch(`${Ge}/projects/${e}/schema/preview`,{method:"POST",headers:{Authorization:`Bearer ${t}`,"Content-Type":"application/json"},body:JSON.stringify({schema:o})});if(!n.ok){let i=await n.text();throw new Error(`Failed to preview changes: ${i}`)}return n.json()}async function yo(t,e,o){let n=await fetch(`${Ge}/projects/${e}/schema/apply`,{method:"POST",headers:{Authorization:`Bearer ${t}`,"Content-Type":"application/json"},body:JSON.stringify({schema:o})});if(!n.ok){let i=await n.text();throw new Error(`Failed to apply changes: ${i}`)}return n.json()}function vo(t){if(console.log(""),console.log(f__default.default.bold("Schema Changes:")),console.log(""),t.added.length===0&&t.modified.length===0&&t.removed.length===0){console.log(f__default.default.gray(" No changes detected. Schema is up to date."));return}if(t.added.length>0){console.log(f__default.default.green.bold(" + Added:"));for(let e of t.added)console.log(f__default.default.green(` + ${e.type}: ${e.name}`));console.log("");}if(t.modified.length>0){console.log(f__default.default.yellow.bold(" ~ Modified:"));for(let e of t.modified){console.log(f__default.default.yellow(` ~ ${e.type}: ${e.name}`));for(let o of e.changes)console.log(f__default.default.gray(` ${o}`));}console.log("");}if(t.removed.length>0){console.log(f__default.default.red.bold(" - Removed:"));for(let e of t.removed)console.log(f__default.default.red(` - ${e.type}: ${e.name}`));console.log("");}}async function We(t){let e=ie__default.default(),o=E();(!o||!o.token)&&(console.log(f__default.default.red("Not logged in")),console.log(f__default.default.gray("Run `vaif login` first to authenticate")),process.exit(1));let n=t.config||"vaif.config.json",i=null;e.start("Loading configuration...");try{i=await w(n);}catch(c){e.fail("Failed to load config"),console.log(f__default.default.red(`
5134
+ Error: ${c}`)),process.exit(1);}i||(e.fail("No configuration found"),console.log(f__default.default.yellow("\nRun `vaif init` to create a configuration file.")),process.exit(1));let a=t.projectId||i.projectId||process.env.VAIF_PROJECT_ID||o.projectId;a||(e.fail("No project ID specified"),console.log(f__default.default.yellow(`
5135
+ Set projectId in vaif.config.json or use --project-id flag.`)),process.exit(1));let r=t.schema||S__default.default.resolve("vaif.schema.json");A__default.default.existsSync(r)||(e.fail("No local schema found"),console.log(f__default.default.yellow(`
5136
+ Expected schema file at: ${r}`)),console.log(f__default.default.gray("Run `vaif pull` first to fetch the current schema.")),process.exit(1));let s;try{let c=A__default.default.readFileSync(r,"utf-8");s=JSON.parse(c);}catch(c){e.fail("Failed to parse schema file"),c instanceof Error&&console.log(f__default.default.red(`
5137
+ Error: ${c.message}`)),process.exit(1);}e.text="Calculating schema changes...";try{let{diff:c,sql:l}=await ho(o.token,a,s);if(e.stop(),vo(c),c.added.length===0&&c.modified.length===0&&c.removed.length===0){console.log("");return}if(l.length>0){console.log(f__default.default.bold("SQL Migrations:")),console.log("");for(let u of l)console.log(f__default.default.gray(` ${u}`));console.log("");}if(t.dryRun){console.log(f__default.default.yellow("Dry run mode - no changes applied.")),console.log(f__default.default.gray("Remove --dry-run to apply these changes."));return}if(!t.force){c.removed.length>0&&(console.log(f__default.default.red.bold("\u26A0\uFE0F Warning: This will remove tables/columns from your database.")),console.log(f__default.default.red(" This action cannot be undone!")),console.log(""));let d=await mo(f__default.default.cyan("Apply these changes? [y/N] "));if(d.toLowerCase()!=="y"&&d.toLowerCase()!=="yes"){console.log(f__default.default.yellow(`
5138
+ Cancelled. No changes applied.`));return}}e.start("Applying schema changes...");let p=await yo(o.token,a,s);if(p.success){if(e.succeed("Schema changes applied successfully"),console.log(""),p.migrations.length>0){console.log(f__default.default.gray("Migrations applied:"));for(let u of p.migrations)console.log(f__default.default.gray(` - ${u}`));console.log("");}console.log(f__default.default.green("Your database schema is now up to date.")),console.log(f__default.default.gray("Run `vaif generate` to update your TypeScript types.")),console.log("");}else e.fail("Failed to apply some changes");}catch(c){e.fail("Failed to push schema changes"),c instanceof Error&&console.log(f__default.default.red(`
5139
+ Error: ${c.message}`)),process.exit(1);}}var ae=process.env.VAIF_API_URL||"https://api.vaif.studio";async function bo(t,e,o,n){let i=new URL(`${ae}/functions/project/${e}`);n&&i.searchParams.set("envId",n);let a=await fetch(i.toString(),{headers:{Authorization:`Bearer ${t}`}});if(!a.ok)return null;let r=await a.json(),s=r.functions||r;return Array.isArray(s)&&s.find(c=>c.name===o)||null}async function Io(t,e,o){let n=await fetch(`${ae}/functions/`,{method:"POST",headers:{Authorization:`Bearer ${t}`,"Content-Type":"application/json"},body:JSON.stringify({projectId:e,name:o.name,runtime:o.runtime,entrypoint:o.entrypoint,envId:o.envId})});if(!n.ok){let i=await n.text();throw new Error(`Failed to create function: ${i}`)}return n.json()}async function Ao(t,e,o){let n=await fetch(`${ae}/functions/${e}/source`,{method:"PUT",headers:{Authorization:`Bearer ${t}`,"Content-Type":"application/json"},body:JSON.stringify({sourceCode:o})});if(!n.ok){let i=await n.text();throw new Error(`Failed to deploy source: ${i}`)}}async function Eo(t,e,o){let n=new URL(`${ae}/functions/project/${e}`);o&&n.searchParams.set("envId",o);let i=await fetch(n.toString(),{headers:{Authorization:`Bearer ${t}`}});if(!i.ok){let r=await i.text();throw new Error(`Failed to list functions: ${r}`)}let a=await i.json();return a.functions||a}function He(t){switch(S__default.default.extname(t).toLowerCase()){case ".ts":return "typescript";case ".js":case ".mjs":return "nodejs";case ".py":return "python";case ".go":return "go";case ".rs":return "rust";default:return "nodejs"}}function Xe(t){let e=[],o=[".ts",".js",".mjs",".py",".go",".rs"],n=["drizzle.config.ts","tsconfig.json","package.json"];if(!A__default.default.existsSync(t))return e;let i=A__default.default.readdirSync(t,{withFileTypes:true});for(let a of i){let r=S__default.default.join(t,a.name);if(a.isDirectory()){if(a.name!=="node_modules"&&!a.name.startsWith(".")){let s=A__default.default.readdirSync(r,{withFileTypes:true});for(let c of s)if(c.isFile()){let l=S__default.default.extname(c.name).toLowerCase();if(o.includes(l)){e.push(S__default.default.join(r,c.name));break}}}}else if(a.isFile()){let s=S__default.default.extname(a.name).toLowerCase();o.includes(s)&&!n.includes(a.name)&&e.push(r);}}return e}async function Ze(t){let e=ie__default.default(),o=E();(!o||!o.token)&&(console.log(f__default.default.red("Not logged in")),console.log(f__default.default.gray("Run `vaif login` first to authenticate")),process.exit(1));let n=t.config||"vaif.config.json",i=null;try{i=await w(n);}catch{}let a=t.projectId||i?.projectId||process.env.VAIF_PROJECT_ID||o.projectId;a||(console.log(f__default.default.red("No project ID specified")),console.log(f__default.default.yellow("Set projectId in vaif.config.json or use --project-id flag.")),process.exit(1)),console.log(""),console.log(f__default.default.bold("VAIF Functions Deploy")),console.log(""),e.start("Scanning for function files...");let r=S__default.default.resolve("functions"),s=S__default.default.resolve("src/functions"),c=[];if(t.entrypoint){let d=S__default.default.resolve(t.entrypoint);A__default.default.existsSync(d)||(e.fail(`File not found: ${t.entrypoint}`),process.exit(1)),c=[d];}else c=[...Xe(r),...Xe(s)];c.length===0&&(e.fail("No function files found"),console.log(f__default.default.yellow(`
5140
+ Place your functions in:`)),console.log(f__default.default.gray(" - ./functions/")),console.log(f__default.default.gray(" - ./src/functions/")),console.log(f__default.default.gray(`
5141
+ Or specify an entrypoint with --entrypoint`)),process.exit(1)),e.succeed(`Found ${c.length} function(s)`),t.name&&(c=c.filter(d=>S__default.default.basename(d,S__default.default.extname(d)).includes(t.name)),c.length===0&&(console.log(f__default.default.yellow(`
5142
+ No functions matching "${t.name}" found`)),process.exit(1))),console.log(""),console.log(f__default.default.gray("Functions to deploy:"));for(let d of c){let g=S__default.default.basename(S__default.default.dirname(d)),y=g==="functions"||g==="src"?S__default.default.basename(d,S__default.default.extname(d)):g,P=t.runtime||He(d);console.log(f__default.default.gray(` - ${y} (${P})`));}if(console.log(""),t.dryRun){console.log(f__default.default.yellow("Dry run mode - no functions deployed."));return}let l=[];for(let d of c){let g=S__default.default.basename(S__default.default.dirname(d)),y=g==="functions"||g==="src"?S__default.default.basename(d,S__default.default.extname(d)):g,P=t.runtime||He(d);e.start(`Deploying ${y}...`);try{let O=A__default.default.readFileSync(d,"utf-8"),B=await bo(o.token,a,y,t.envId);B||(e.text=`Creating ${y}...`,B=await Io(o.token,a,{name:y,runtime:P,entrypoint:S__default.default.basename(d),envId:t.envId})),e.text=`Deploying ${y}...`,await Ao(o.token,B.id,O),e.succeed(`Deployed ${y}`),l.push({name:y,success:!0});}catch(O){let B=O instanceof Error?O.message:"Unknown error";e.fail(`Failed to deploy ${y}`),l.push({name:y,success:false,error:B});}}console.log("");let p=l.filter(d=>d.success).length;if(l.filter(d=>!d.success).length===0)console.log(f__default.default.green(`\u2713 Successfully deployed ${p} function(s)`));else {console.log(f__default.default.yellow(`Deployed ${p}/${l.length} function(s)`)),console.log(""),console.log(f__default.default.red("Failed deployments:"));for(let d of l.filter(g=>!g.success))console.log(f__default.default.red(` - ${d.name}: ${d.error}`));}console.log("");}async function et(t){let e=ie__default.default(),o=E();(!o||!o.token)&&(console.log(f__default.default.red("Not logged in")),console.log(f__default.default.gray("Run `vaif login` first to authenticate")),process.exit(1));let n=t.config||"vaif.config.json",i=null;try{i=await w(n);}catch{}let a=t.projectId||i?.projectId||process.env.VAIF_PROJECT_ID||o.projectId;a||(console.log(f__default.default.red("No project ID specified")),process.exit(1)),e.start("Fetching functions...");try{let r=await Eo(o.token,a,t.envId);if(e.stop(),r.length===0){console.log(f__default.default.yellow(`
5143
+ No functions found`)),console.log(f__default.default.gray("Deploy your first function with: vaif functions deploy"));return}console.log(""),console.log(f__default.default.bold(`Functions (${r.length}):`)),console.log(""),console.log(f__default.default.gray(" "+"NAME".padEnd(25)+"RUNTIME".padEnd(15)+"STATUS".padEnd(12)+"INVOCATIONS".padEnd(14)+"LAST DEPLOYED")),console.log(f__default.default.gray(" "+"-".repeat(80)));for(let s of r){let c=s.deployStatus==="deployed"?f__default.default.green:s.deployStatus==="deploying"?f__default.default.yellow:s.deployStatus==="failed"?f__default.default.red:f__default.default.gray;console.log(" "+s.name.padEnd(25)+s.runtime.padEnd(15)+c(s.deployStatus.padEnd(12))+String(s.invocationCount??0).padEnd(14)+(s.deployedAt?new Date(s.deployedAt).toLocaleDateString():"-"));}console.log("");}catch(r){e.fail("Failed to fetch functions"),r instanceof Error&&console.log(f__default.default.red(`
5144
+ Error: ${r.message}`)),process.exit(1);}}var se=process.env.VAIF_API_URL||"https://api.vaif.studio";async function wo(t,e,o,n,i){let a=await fetch(`${se}/projects/${e}/db/seed`,{method:"POST",headers:{Authorization:`Bearer ${t}`,"Content-Type":"application/json"},body:JSON.stringify({table:o,records:n,truncate:i?.truncate??false})});if(!a.ok){let r=await a.text();throw new Error(`Failed to seed ${o}: ${r}`)}return a.json()}async function _o(t,e){let o=await fetch(`${se}/projects/${e}/db/reset`,{method:"POST",headers:{Authorization:`Bearer ${t}`,"Content-Type":"application/json"}});if(!o.ok){let n=await o.text();throw new Error(`Failed to reset database: ${n}`)}return o.json()}function Ae(t){let e=[];if(!A__default.default.existsSync(t))return e;let o=A__default.default.readdirSync(t,{withFileTypes:true});for(let n of o)if(n.isFile()){let i=S__default.default.extname(n.name).toLowerCase();(i===".json"||i===".ts"||i===".js")&&e.push(S__default.default.join(t,n.name));}return e.sort()}async function tt(t){let e=S__default.default.extname(t).toLowerCase();if(e===".json"){let o=A__default.default.readFileSync(t,"utf-8"),n=JSON.parse(o);return Array.isArray(n)?[{table:S__default.default.basename(t,e),data:n}]:n.table&&n.data?[n]:Object.entries(n).map(([i,a])=>({table:i,data:a}))}else if(e===".ts"||e===".js"){let o=await import(t),n=o.default||o;return typeof n=="function"?n():n}throw new Error(`Unsupported file format: ${e}`)}async function ot(t){let e=ie__default.default(),o=E();(!o||!o.token)&&(console.log(f__default.default.red("Not logged in")),console.log(f__default.default.gray("Run `vaif login` first to authenticate")),process.exit(1));let n=t.config||"vaif.config.json",i=null;try{i=await w(n);}catch{}let a=t.projectId||i?.projectId||process.env.VAIF_PROJECT_ID||o.projectId;a||(console.log(f__default.default.red("No project ID specified")),console.log(f__default.default.yellow("Set projectId in vaif.config.json or use --project-id flag.")),process.exit(1)),console.log(""),console.log(f__default.default.bold("VAIF Database Seed")),console.log("");let r=[];if(t.file){let p=S__default.default.resolve(t.file);A__default.default.existsSync(p)||(console.log(f__default.default.red(`File not found: ${t.file}`)),process.exit(1)),r=[p];}else {let p=S__default.default.resolve("seeds"),u=S__default.default.resolve("prisma/seed"),d=S__default.default.resolve("db/seeds");r=[...Ae(p),...Ae(u),...Ae(d)];}r.length===0&&(console.log(f__default.default.yellow("No seed files found")),console.log(f__default.default.gray(`
5145
+ Place your seed files in one of these directories:`)),console.log(f__default.default.gray(" - ./seeds/")),console.log(f__default.default.gray(" - ./prisma/seed/")),console.log(f__default.default.gray(" - ./db/seeds/")),console.log(f__default.default.gray(`
5146
+ Or specify a file with --file`)),console.log(f__default.default.gray(`
5147
+ Example seed file (seeds/users.json):`)),console.log(f__default.default.gray(" [")),console.log(f__default.default.gray(' { "name": "John Doe", "email": "john@example.com" },')),console.log(f__default.default.gray(' { "name": "Jane Doe", "email": "jane@example.com" }')),console.log(f__default.default.gray(" ]")),process.exit(1)),console.log(f__default.default.gray("Seed files found:"));for(let p of r)console.log(f__default.default.gray(` - ${S__default.default.relative(process.cwd(),p)}`));if(console.log(""),t.truncate&&(console.log(f__default.default.yellow("\u26A0\uFE0F Tables will be truncated before seeding")),console.log("")),t.dryRun){console.log(f__default.default.yellow("Dry run mode - no data will be inserted.")),console.log("");for(let p of r){e.start(`Loading ${S__default.default.basename(p)}...`);try{let u=await tt(p);e.stop();for(let d of u)t.table&&d.table!==t.table||(console.log(f__default.default.cyan(`Table: ${d.table}`)),console.log(f__default.default.gray(` Records: ${d.data.length}`)),d.data.length>0&&console.log(f__default.default.gray(` Sample: ${JSON.stringify(d.data[0],null,2).slice(0,100)}...`)),console.log(""));}catch(u){e.fail(`Failed to load ${S__default.default.basename(p)}`),u instanceof Error&&console.log(f__default.default.red(` Error: ${u.message}`));}}return}let s=[];for(let p of r){e.start(`Processing ${S__default.default.basename(p)}...`);try{let u=await tt(p);e.stop();for(let d of u)if(!(t.table&&d.table!==t.table)){if(d.data.length===0){console.log(f__default.default.gray(` Skipping ${d.table} (no records)`));continue}e.start(`Seeding ${d.table} (${d.data.length} records)...`);try{let g=await wo(o.token,a,d.table,d.data,{truncate:t.truncate});e.succeed(`Seeded ${d.table}: ${g.inserted} records`),s.push({table:d.table,inserted:g.inserted});}catch(g){let y=g instanceof Error?g.message:"Unknown error";e.fail(`Failed to seed ${d.table}`),s.push({table:d.table,inserted:0,error:y});}}}catch(u){e.fail(`Failed to load ${S__default.default.basename(p)}`),u instanceof Error&&console.log(f__default.default.red(` Error: ${u.message}`));}}console.log("");let c=s.reduce((p,u)=>p+u.inserted,0),l=s.filter(p=>p.error).length;if(l===0)console.log(f__default.default.green(`\u2713 Successfully seeded ${c} records across ${s.length} table(s)`));else {console.log(f__default.default.yellow(`Seeded ${c} records with ${l} error(s)`)),console.log(""),console.log(f__default.default.red("Errors:"));for(let p of s.filter(u=>u.error))console.log(f__default.default.red(` - ${p.table}: ${p.error}`));}console.log("");}async function nt(t){let e=ie__default.default(),o=E();(!o||!o.token)&&(console.log(f__default.default.red("Not logged in")),console.log(f__default.default.gray("Run `vaif login` first to authenticate")),process.exit(1));let n=t.config||"vaif.config.json",i=null;try{i=await w(n);}catch{}let a=t.projectId||i?.projectId||process.env.VAIF_PROJECT_ID||o.projectId;a||(console.log(f__default.default.red("No project ID specified")),console.log(f__default.default.yellow("Set projectId in vaif.config.json or use --project-id flag.")),process.exit(1));let r=S__default.default.resolve(t.dir||"./drizzle");if(console.log(""),console.log(f__default.default.bold("VAIF Database Push")),console.log(""),!A__default.default.existsSync(r)){let u=S__default.default.resolve("./migrations");A__default.default.existsSync(u)?console.log(f__default.default.gray(`Using migrations from: ${u}`)):(console.log(f__default.default.red(`Migrations directory not found: ${r}`)),console.log(f__default.default.gray(`
5148
+ Expected one of:`)),console.log(f__default.default.gray(" - ./drizzle/")),console.log(f__default.default.gray(" - ./migrations/")),console.log(f__default.default.gray(`
5149
+ Or specify with: vaif db push --dir <path>`)),process.exit(1));}let s=[],c=A__default.default.readdirSync(r,{withFileTypes:true});for(let u of c)if(u.isFile()&&u.name.endsWith(".sql"))s.push(S__default.default.join(r,u.name));else if(u.isDirectory()){let d=A__default.default.readdirSync(S__default.default.join(r,u.name),{withFileTypes:true});for(let g of d)g.isFile()&&g.name.endsWith(".sql")&&s.push(S__default.default.join(r,u.name,g.name));}s.sort(),s.length===0&&(console.log(f__default.default.yellow("No SQL migration files found")),process.exit(1)),console.log(f__default.default.gray(`Found ${s.length} migration(s):`));for(let u of s)console.log(f__default.default.gray(` - ${S__default.default.relative(process.cwd(),u)}`));if(console.log(""),t.dryRun){console.log(f__default.default.yellow("Dry run mode - no migrations will be applied.")),console.log("");for(let u of s){let d=A__default.default.readFileSync(u,"utf-8");console.log(f__default.default.cyan(`--- ${S__default.default.basename(u)} ---`)),console.log(f__default.default.gray(d.slice(0,500))),d.length>500&&console.log(f__default.default.gray("...")),console.log("");}return}let l=0,p=0;for(let u of s){let d=A__default.default.readFileSync(u,"utf-8"),g=S__default.default.relative(process.cwd(),u);e.start(`Applying ${g}...`);try{let y=await fetch(`${se}/schema-engine/query/${a}`,{method:"POST",headers:{Authorization:`Bearer ${o.token}`,"Content-Type":"application/json"},body:JSON.stringify({sql:d})});if(!y.ok){let P=await y.text();throw new Error(P)}e.succeed(`Applied ${g}`),l++;}catch(y){let P=y instanceof Error?y.message:"Unknown error";e.fail(`Failed ${g}: ${P}`),p++;}}console.log(""),console.log(p===0?f__default.default.green(`Successfully applied ${l} migration(s)`):f__default.default.yellow(`Applied ${l}, failed ${p} migration(s)`)),console.log("");}async function at(t){let e=ie__default.default(),o=E();(!o||!o.token)&&(console.log(f__default.default.red("Not logged in")),console.log(f__default.default.gray("Run `vaif login` first to authenticate")),process.exit(1));let n=t.config||"vaif.config.json",i=null;try{i=await w(n);}catch{}let a=t.projectId||i?.projectId||process.env.VAIF_PROJECT_ID||o.projectId;a||(console.log(f__default.default.red("No project ID specified")),console.log(f__default.default.yellow("Set projectId in vaif.config.json or use --project-id flag.")),process.exit(1));let r=S__default.default.resolve(t.output||"vaif.schema.json");console.log(""),console.log(f__default.default.bold("VAIF Database Pull")),console.log(""),e.start("Pulling schema from remote...");try{let s=await fetch(`${se}/schema-engine/introspect/${a}`,{headers:{Authorization:`Bearer ${o.token}`}});if(!s.ok){let p=await s.text();throw new Error(`Failed to pull schema: ${p}`)}let c=await s.json();A__default.default.writeFileSync(r,JSON.stringify(c,null,2),"utf-8"),e.succeed(`Schema written to ${S__default.default.relative(process.cwd(),r)}`);let l=c.tables?.length??Object.keys(c).length;console.log(f__default.default.gray(` ${l} table(s) pulled`)),console.log("");}catch(s){e.fail("Failed to pull schema"),s instanceof Error&&console.log(f__default.default.red(`
5150
+ Error: ${s.message}`)),process.exit(1);}}async function it(t){let e=ie__default.default(),o=E();(!o||!o.token)&&(console.log(f__default.default.red("Not logged in")),console.log(f__default.default.gray("Run `vaif login` first to authenticate")),process.exit(1));let n=t.config||"vaif.config.json",i=null;try{i=await w(n);}catch{}let a=t.projectId||i?.projectId||process.env.VAIF_PROJECT_ID||o.projectId;a||(console.log(f__default.default.red("No project ID specified")),process.exit(1)),console.log(""),console.log(f__default.default.red.bold("\u26A0\uFE0F DATABASE RESET")),console.log(""),console.log(f__default.default.red("This will:")),console.log(f__default.default.red(" - Drop all tables")),console.log(f__default.default.red(" - Delete all data")),console.log(f__default.default.red(" - Reset migrations")),console.log(""),console.log(f__default.default.red.bold("This action cannot be undone!")),console.log(""),t.force||(console.log(f__default.default.yellow("Use --force to confirm this action.")),process.exit(1)),e.start("Resetting database...");try{await _o(o.token,a),e.succeed("Database reset complete"),console.log(""),console.log(f__default.default.gray("Your database is now empty.")),console.log(f__default.default.gray("Run `vaif push` to apply your schema, then `vaif db seed` to seed data.")),console.log("");}catch(r){e.fail("Failed to reset database"),r instanceof Error&&console.log(f__default.default.red(`
5151
+ Error: ${r.message}`)),process.exit(1);}}var rt=process.env.VAIF_API_URL||"https://api.vaif.studio";function ct(t,e,o){return t.projectId||e?.projectId||process.env.VAIF_PROJECT_ID||o.projectId||null}async function lt(t){let e=ie__default.default(),o=E();(!o||!o.token)&&(console.log(f__default.default.red("Not logged in")),console.log(f__default.default.gray("Run `vaif login` first to authenticate")),process.exit(1));let n=t.config||"vaif.config.json",i=null;try{i=await w(n);}catch{}let a=ct(t,i,o);a||(console.log(f__default.default.red("No project ID specified")),console.log(f__default.default.yellow("Set projectId in vaif.config.json or use --project-id flag.")),process.exit(1));let r=t.name||`cli-key-${Date.now()}`;console.log(""),console.log(f__default.default.bold("VAIF Generate API Key")),console.log(""),e.start("Generating API key...");try{let s=await fetch(`${rt}/projects/${a}/api-keys`,{method:"POST",headers:{Authorization:`Bearer ${o.token}`,"Content-Type":"application/json"},body:JSON.stringify({name:r})});if(!s.ok){let l=await s.text();throw new Error(`Failed to generate key: ${l}`)}let c=await s.json();e.succeed("API key generated"),console.log(""),console.log(f__default.default.green(` Name: ${c.name}`)),console.log(f__default.default.green(` Key: ${c.key}`)),console.log(""),console.log(f__default.default.yellow.bold(" Save this key now - it will not be shown again!")),console.log("");}catch(s){e.fail("Failed to generate API key"),s instanceof Error&&console.log(f__default.default.red(`
5152
+ Error: ${s.message}`)),process.exit(1);}}async function dt(t){let e=ie__default.default(),o=E();(!o||!o.token)&&(console.log(f__default.default.red("Not logged in")),console.log(f__default.default.gray("Run `vaif login` first to authenticate")),process.exit(1));let n=t.config||"vaif.config.json",i=null;try{i=await w(n);}catch{}let a=ct(t,i,o);a||(console.log(f__default.default.red("No project ID specified")),console.log(f__default.default.yellow("Set projectId in vaif.config.json or use --project-id flag.")),process.exit(1)),console.log(""),console.log(f__default.default.bold("VAIF API Keys")),console.log(""),e.start("Fetching API keys...");try{let r=await fetch(`${rt}/projects/${a}/api-keys`,{headers:{Authorization:`Bearer ${o.token}`}});if(!r.ok){let u=await r.text();throw new Error(`Failed to list keys: ${u}`)}let s=await r.json(),c=s.keys||s;if(e.stop(),!Array.isArray(c)||c.length===0){console.log(f__default.default.yellow("No API keys found")),console.log(f__default.default.gray(`
5153
+ Generate one with: vaif keys generate`));return}let l=Math.max(8,...c.map(u=>(u.name||"").length)),p=` ${"Name".padEnd(l)} ${"Key".padEnd(24)} Created`;console.log(f__default.default.gray(p)),console.log(f__default.default.gray(" "+"-".repeat(p.length-2)));for(let u of c){let d=(u.name||"unnamed").padEnd(l),g=u.maskedKey||u.prefix||`${(u.key||"").slice(0,12)}...`,y=u.createdAt?new Date(u.createdAt).toLocaleDateString():"N/A";console.log(` ${d} ${g.padEnd(24)} ${y}`);}console.log(""),console.log(f__default.default.gray(` ${c.length} key(s) total`)),console.log("");}catch(r){e.fail("Failed to list API keys"),r instanceof Error&&console.log(f__default.default.red(`
5154
+ Error: ${r.message}`)),process.exit(1);}}var G=process.env.VAIF_API_URL||"https://api.vaif.studio";function To(t,e,o){return t.projectId||e?.projectId||process.env.VAIF_PROJECT_ID||o.projectId||null}function ce(){let t=E();return (!t||!t.token)&&(console.log(f__default.default.red("Not logged in")),console.log(f__default.default.gray("Run `vaif login` first to authenticate")),process.exit(1)),t}async function le(t){try{return await w(t||"vaif.config.json")}catch{return null}}function de(t,e,o){let n=To(t,e,o);return n||(console.log(f__default.default.red("No project ID specified")),console.log(f__default.default.yellow("Set projectId in vaif.config.json or use --project-id flag.")),process.exit(1)),n}async function ut(t,e,o){let n=ie__default.default(),i=ce(),a=await le(o.config),r=de(o,a,i),s=e;if(o.fromFile)try{s=A__default.default.readFileSync(o.fromFile,"utf-8");}catch(c){console.log(f__default.default.red(`Failed to read file: ${o.fromFile}`)),c instanceof Error&&console.log(f__default.default.gray(c.message)),process.exit(1);}s||(console.log(f__default.default.red("No value provided")),console.log(f__default.default.gray("Provide a value as argument or use --from-file <path>")),process.exit(1)),console.log(""),console.log(f__default.default.bold("VAIF Set Secret")),console.log(""),n.start("Checking for existing secret...");try{let c=new URL(`${G}/functions/secrets/project/${r}`);o.envId&&c.searchParams.set("envId",o.envId);let l=await fetch(c.toString(),{headers:{Authorization:`Bearer ${i.token}`}});if(!l.ok)throw new Error(`Failed to check existing secrets: ${await l.text()}`);let u=(await l.json()).find(d=>d.key===t);if(u){n.text=`Updating secret "${t}"...`;let d=await fetch(`${G}/functions/secrets/${u.id}`,{method:"PUT",headers:{Authorization:`Bearer ${i.token}`,"Content-Type":"application/json"},body:JSON.stringify({value:s})});if(!d.ok)throw new Error(`Failed to update secret: ${await d.text()}`);n.succeed(`Updated secret "${t}"`);}else {n.text=`Creating secret "${t}"...`;let d=await fetch(`${G}/functions/secrets`,{method:"POST",headers:{Authorization:`Bearer ${i.token}`,"Content-Type":"application/json"},body:JSON.stringify({projectId:r,envId:o.envId,key:t,value:s})});if(!d.ok)throw new Error(`Failed to create secret: ${await d.text()}`);n.succeed(`Created secret "${t}"`);}console.log("");}catch(c){n.fail("Failed to set secret"),c instanceof Error&&console.log(f__default.default.red(`
5155
+ Error: ${c.message}`)),process.exit(1);}}async function pt(t){let e=ie__default.default(),o=ce(),n=await le(t.config),i=de(t,n,o);console.log(""),console.log(f__default.default.bold("VAIF Secrets")),console.log(""),e.start("Fetching secrets...");try{let a=new URL(`${G}/functions/secrets/project/${i}`);t.envId&&a.searchParams.set("envId",t.envId);let r=await fetch(a.toString(),{headers:{Authorization:`Bearer ${o.token}`}});if(!r.ok)throw new Error(`Failed to list secrets: ${await r.text()}`);let s=await r.json();if(e.stop(),s.length===0){console.log(f__default.default.yellow("No secrets found")),console.log(f__default.default.gray(`
5156
+ Create one with: vaif secrets set <name> <value>`));return}let c=Math.max(8,...s.map(p=>p.key.length)),l=` ${"Name".padEnd(c)} Created`;console.log(f__default.default.gray(l)),console.log(f__default.default.gray(" "+"-".repeat(l.length-2)));for(let p of s){let u=p.key.padEnd(c),d=p.createdAt?new Date(p.createdAt).toLocaleDateString():"N/A";console.log(` ${u} ${d}`);}console.log(""),console.log(f__default.default.gray(` ${s.length} secret(s) total`)),console.log(f__default.default.gray(" Values are hidden. Use `vaif secrets get <name>` to reveal.")),console.log("");}catch(a){e.fail("Failed to list secrets"),a instanceof Error&&console.log(f__default.default.red(`
5157
+ Error: ${a.message}`)),process.exit(1);}}async function ft(t,e){let o=ie__default.default(),n=ce(),i=await le(e.config),a=de(e,i,n);console.log(""),o.start("Fetching secret...");try{let r=new URL(`${G}/functions/secrets/project/${a}`);e.envId&&r.searchParams.set("envId",e.envId);let s=await fetch(r.toString(),{headers:{Authorization:`Bearer ${n.token}`}});if(!s.ok)throw new Error(`Failed to fetch secrets: ${await s.text()}`);let l=(await s.json()).find(d=>d.key===t);l||(o.fail(`Secret "${t}" not found`),process.exit(1));let p=await fetch(`${G}/functions/secrets/${l.id}/value`,{headers:{Authorization:`Bearer ${n.token}`}});if(!p.ok)throw new Error(`Failed to get secret value: ${await p.text()}`);let u=await p.json();o.stop(),console.log(u.value);}catch(r){o.fail("Failed to get secret"),r instanceof Error&&console.log(f__default.default.red(`
5158
+ Error: ${r.message}`)),process.exit(1);}}async function gt(t,e){let o=ie__default.default(),n=ce(),i=await le(e.config),a=de(e,i,n);console.log(""),console.log(f__default.default.bold("VAIF Delete Secret")),console.log(""),o.start("Finding secret...");try{let r=new URL(`${G}/functions/secrets/project/${a}`);e.envId&&r.searchParams.set("envId",e.envId);let s=await fetch(r.toString(),{headers:{Authorization:`Bearer ${n.token}`}});if(!s.ok)throw new Error(`Failed to fetch secrets: ${await s.text()}`);let l=(await s.json()).find(u=>u.key===t);l||(o.fail(`Secret "${t}" not found`),process.exit(1)),o.text=`Deleting secret "${t}"...`;let p=await fetch(`${G}/functions/secrets/${l.id}`,{method:"DELETE",headers:{Authorization:`Bearer ${n.token}`}});if(!p.ok)throw new Error(`Failed to delete secret: ${await p.text()}`);o.succeed(`Deleted secret "${t}"`),console.log("");}catch(r){o.fail("Failed to delete secret"),r instanceof Error&&console.log(f__default.default.red(`
5159
+ Error: ${r.message}`)),process.exit(1);}}var mt=process.env.VAIF_API_URL||"https://api.vaif.studio";function Po(t){try{let e=new URL(t);return e.password&&(e.password="****"),e.toString()}catch{return t.replace(/:[^@/]+@/,":****@")}}async function ht(t){let e=ie__default.default(),o=E();(!o||!o.token)&&(console.log(f__default.default.red("Not logged in")),console.log(f__default.default.gray("Run `vaif login` first to authenticate")),process.exit(1));let n=t.config||"vaif.config.json",i=null;try{i=await w(n);}catch{}let a=t.projectId||i?.projectId||process.env.VAIF_PROJECT_ID||o.projectId;a||(console.log(f__default.default.red("No project ID specified")),console.log(f__default.default.yellow("Set projectId in vaif.config.json or use --project-id flag.")),process.exit(1)),e.start("Fetching project info...");try{let r=await fetch(`${mt}/projects/${a}`,{headers:{Authorization:`Bearer ${o.token}`}});if(!r.ok){let p=await r.text();throw new Error(`Failed to fetch project: ${p}`)}let s=await r.json();e.stop(),console.log(""),console.log(f__default.default.bold("VAIF Project Info")),console.log("");let c=16,l=(p,u)=>{console.log(` ${f__default.default.gray(p.padEnd(c))} ${u}`);};l("Name:",f__default.default.white(s.name||"N/A")),l("Project ID:",f__default.default.white(a)),l("Region:",f__default.default.white(s.region||"us-east-1")),l("Plan:",f__default.default.white(s.plan||s.tier||"free")),l("Created:",f__default.default.white(s.createdAt?new Date(s.createdAt).toLocaleDateString():"N/A")),console.log(""),l("API URL:",f__default.default.cyan(s.apiUrl||`${mt}/v1`)),l("WS URL:",f__default.default.cyan(s.wsUrl||s.realtimeUrl||"N/A")),l("DB URL:",f__default.default.cyan(s.databaseUrl?Po(s.databaseUrl):"N/A")),l("Storage URL:",f__default.default.cyan(s.storageUrl||"N/A")),console.log("");}catch(r){e.fail("Failed to fetch project info"),r instanceof Error&&console.log(f__default.default.red(`
5160
+ Error: ${r.message}`)),process.exit(1);}}var Co=process.env.VAIF_API_URL||"https://api.vaif.studio";async function yt(t){let e=ie__default.default(),o=E();(!o||!o.token)&&(console.log(f__default.default.red("Not logged in")),console.log(f__default.default.gray("Run `vaif login` first to authenticate")),process.exit(1));let n=t.config||"vaif.config.json",i=null;try{i=await w(n);}catch{}let a=t.projectId||i?.projectId||process.env.VAIF_PROJECT_ID||o.projectId;a||(console.log(f__default.default.red("No project ID specified")),console.log(f__default.default.yellow("Set projectId in vaif.config.json or use --project-id flag.")),process.exit(1)),e.start("Fetching project status...");try{let r=await fetch(`${Co}/projects/${a}?include=tables,functions,storage,connections`,{headers:{Authorization:`Bearer ${o.token}`}});if(!r.ok){let y=await r.text();throw new Error(`Failed to fetch project status: ${y}`)}let s=await r.json();e.stop(),console.log(""),console.log(f__default.default.bold("VAIF Project Status")),console.log("");let c=22,l=(y,P)=>{console.log(` ${f__default.default.gray(y.padEnd(c))} ${P}`);};l("Project:",f__default.default.white(s.name||a)),l("Plan:",f__default.default.white(s.plan||s.tier||"free")),console.log(""),console.log(f__default.default.gray(" --- Resources ---")),console.log("");let p=s.tableCount??s.tables?.length??"N/A",u=s.functionCount??s.functions?.length??"N/A",d=s.bucketCount??s.storage?.buckets?.length??"N/A",g=s.activeConnections??s.connections??"N/A";l("Tables:",f__default.default.white(String(p))),l("Functions:",f__default.default.white(String(u))),l("Storage Buckets:",f__default.default.white(String(d))),l("Active Connections:",f__default.default.white(String(g))),s.usage&&(console.log(""),console.log(f__default.default.gray(" --- Usage ---")),console.log(""),s.usage.dbSize&&l("Database Size:",f__default.default.white(s.usage.dbSize)),s.usage.storageSize&&l("Storage Size:",f__default.default.white(s.usage.storageSize)),s.usage.bandwidth&&l("Bandwidth:",f__default.default.white(s.usage.bandwidth)),s.usage.functionInvocations!=null&&l("Function Invocations:",f__default.default.white(String(s.usage.functionInvocations)))),console.log("");}catch(r){e.fail("Failed to fetch project status"),r instanceof Error&&console.log(f__default.default.red(`
5161
+ Error: ${r.message}`)),process.exit(1);}}function jo(t){let e=[S__default.default.join(t,".env.local"),S__default.default.join(t,".env")],o={};for(let i of e)if(A__default.default.existsSync(i)){let a=A__default.default.readFileSync(i,"utf-8");for(let r of a.split(`
5162
+ `)){let s=r.match(/^([^#=]+)=(.*)$/);if(!s)continue;let[,c,l]=s,p=c.trim(),u=l.trim().replace(/^["']|["']$/g,"");if(p==="SUPABASE_URL"||p==="NEXT_PUBLIC_SUPABASE_URL"){o.api={...o.api,url:u};let d=u.match(/https:\/\/([^.]+)\.supabase\./);d&&(o.projectId=d[1]);}(p==="SUPABASE_ANON_KEY"||p==="NEXT_PUBLIC_SUPABASE_ANON_KEY")&&(o.api={...o.api,anonKey:u}),p==="SUPABASE_SERVICE_ROLE_KEY"&&(o.api={...o.api,serviceKey:u});}break}let n=S__default.default.join(t,"supabase","config.toml");if(A__default.default.existsSync(n)){let a=A__default.default.readFileSync(n,"utf-8").match(/project_id\s*=\s*"([^"]+)"/);a&&(o.projectId=a[1]);}return o.projectId||o.api?.url?o:null}function Ro(t){let e=S__default.default.join(t,"supabase","migrations"),o=new Map;if(!A__default.default.existsSync(e))return [];let n=A__default.default.readdirSync(e).filter(i=>i.endsWith(".sql")).sort();for(let i of n){let a=A__default.default.readFileSync(S__default.default.join(e,i),"utf-8");Uo(a,o),ko(a,o);}return Array.from(o.values())}function Uo(t,e){let o=/CREATE\s+TABLE\s+(?:IF\s+NOT\s+EXISTS\s+)?(?:public\.)?(\w+)\s*\(([\s\S]*?)\);/gi,n;for(;(n=o.exec(t))!==null;){let a=n[1],r=n[2];if(["schema_migrations","_prisma_migrations","supabase_migrations"].includes(a))continue;let s=[],c=r.split(`,
5163
+ `).map(l=>l.trim()).filter(Boolean);for(let l of c){if(/^\s*(PRIMARY\s+KEY|FOREIGN\s+KEY|UNIQUE|CHECK|CONSTRAINT)/i.test(l))continue;let p=l.match(/^(\w+)\s+(\w+(?:\([^)]*\))?(?:\[\])?)\s*(.*)/i);if(!p)continue;let[,u,d,g]=p,y=/PRIMARY\s+KEY/i.test(g),P=/UNIQUE/i.test(g),O=!/NOT\s+NULL/i.test(g)&&!y,B=g.match(/DEFAULT\s+(.+?)(?:\s+|$)/i),W=g.match(/REFERENCES\s+(?:public\.)?(\w+)\s*\((\w+)\)(?:\s+ON\s+DELETE\s+(\w+))?/i);s.push({name:u,type:No(d),nullable:O,isPrimaryKey:y,isUnique:P,defaultValue:B?.[1],references:W?{table:W[1],column:W[2],onDelete:W[3]?.toUpperCase()}:void 0});}s.length>0&&e.set(a,{name:a,columns:s,indexes:[],rlsPolicies:[]});}let i=/CREATE\s+(?:UNIQUE\s+)?INDEX\s+(?:IF\s+NOT\s+EXISTS\s+)?(\w+)\s+ON\s+(?:public\.)?(\w+)\s*\(([^)]+)\)/gi;for(;(n=i.exec(t))!==null;){let[,a,r,s]=n,c=e.get(r);c&&(c.indexes=c.indexes||[],c.indexes.push({name:a,columns:s.split(",").map(l=>l.trim()),unique:/UNIQUE/i.test(n[0])}));}}function ko(t,e){let o=/CREATE\s+POLICY\s+"([^"]+)"\s+ON\s+(?:public\.)?(\w+)\s+(?:FOR\s+(\w+)\s+)?(?:USING\s+\((.+?)\)|WITH\s+CHECK\s+\((.+?)\))/gi,n;for(;(n=o.exec(t))!==null;){let[,i,a,r,s,c]=n,l=e.get(a);l&&(l.rlsPolicies=l.rlsPolicies||[],l.rlsPolicies.push({name:i,command:r||"ALL",definition:(s||c||"").replace(/auth\.uid\(\)/g,"vaif.auth_uid()")}));}}function No(t){let e=t.toLowerCase();return e.includes("serial")?"integer":e.includes("bigserial")?"bigint":t}function Lo(t){let e=S__default.default.join(t,"supabase","config.toml"),o=[];if(A__default.default.existsSync(e)){let n=A__default.default.readFileSync(e,"utf-8"),i=/\[storage\.buckets\.(\w+)\]/g,a;for(;(a=i.exec(n))!==null;){let r=a[1],s=n.slice(a.index),c=/public\s*=\s*true/i.test(s.split(/\[/)[0]);o.push({name:r,public:c});}}return o}function Do(t){let e=S__default.default.join(t,"supabase","functions"),o=[];if(!A__default.default.existsSync(e))return [];let n=A__default.default.readdirSync(e,{withFileTypes:true});for(let i of n){if(!i.isDirectory()||i.name.startsWith("_"))continue;let a=S__default.default.join(e,i.name,"index.ts"),r=A__default.default.existsSync(a);o.push({name:i.name.replace(/-/g,"_"),runtime:"nodejs20",entrypoint:"index.ts",sourceHint:r?`Source found at supabase/functions/${i.name}/index.ts \u2014 convert Deno imports to Node.js`:void 0});}return o}function Vo(t){let e=[],o=Ro(t);o.length===0&&e.push("No migration files found in supabase/migrations/. Add your schema SQL files or export with: supabase db dump --schema public > supabase/migrations/schema.sql");let n=Lo(t),i=Do(t);i.length>0&&e.push("Supabase Edge Functions use Deno runtime. VAIF functions use Node.js by default. You will need to convert Deno-specific imports (e.g., std/http/server) to Node.js equivalents.");let a=[],r=S__default.default.join(t,"supabase","config.toml");if(A__default.default.existsSync(r)){let s=A__default.default.readFileSync(r,"utf-8");s.includes("[auth.external.google]")&&a.push("google"),s.includes("[auth.external.github]")&&a.push("github"),s.includes("[auth.external.apple]")&&a.push("apple"),s.includes("[auth.external.azure]")&&a.push("microsoft"),(s.includes("[auth.sms]")||s.includes("[auth.external.phone]"))&&a.push("phone");}return {source:"supabase",tables:o,buckets:n,functions:i,authProviders:a,warnings:e}}function bt(t){let e=S__default.default.join(t,"firebase.json"),o={};if(A__default.default.existsSync(e))try{let a=JSON.parse(A__default.default.readFileSync(e,"utf-8"));a.projectId&&(o.projectId=a.projectId);}catch{}let n=S__default.default.join(t,".firebaserc");if(A__default.default.existsSync(n))try{let r=JSON.parse(A__default.default.readFileSync(n,"utf-8")).projects?.default;r&&(o.projectId=r);}catch{}let i=S__default.default.join(t,".env");if(A__default.default.existsSync(i)){let a=A__default.default.readFileSync(i,"utf-8");for(let r of a.split(`
5164
+ `)){let s=r.match(/^([^#=]+)=(.*)$/);if(!s)continue;let[,c,l]=s;c.trim().includes("STORAGE_BUCKET")&&(o.storageBucket=l.trim().replace(/^["']|["']$/g,""));}}return o.projectId?o:null}function $o(t){let e=S__default.default.join(t,"firestore.rules"),o=[];if(!A__default.default.existsSync(e))return [];let n=A__default.default.readFileSync(e,"utf-8"),i=/match\s+\/([a-zA-Z_]\w*)\s*\/\{(\w+)\}/g,a,r=new Set;for(;(a=i.exec(n))!==null;){let s=a[1];r.has(s)||(r.add(s),!s.startsWith("_")&&o.push({name:s,columns:[{name:"id",type:"uuid",nullable:false,isPrimaryKey:true,defaultValue:"gen_random_uuid()"},{name:"created_at",type:"timestamptz",nullable:false,defaultValue:"now()"},{name:"updated_at",type:"timestamptz",nullable:false,defaultValue:"now()"},{name:"data",type:"jsonb",nullable:true,defaultValue:"'{}'"}],indexes:[],rlsPolicies:[]}));}return o}function Oo(t){let e=S__default.default.join(t,"functions"),o=[];if(!A__default.default.existsSync(e))return [];let i=[S__default.default.join(e,"src","index.ts"),S__default.default.join(e,"index.ts"),S__default.default.join(e,"src","index.js"),S__default.default.join(e,"index.js")].find(c=>A__default.default.existsSync(c));if(!i)return [];let a=A__default.default.readFileSync(i,"utf-8"),r=/(?:exports\.(\w+)\s*=|export\s+(?:const|function)\s+(\w+))/g,s;for(;(s=r.exec(a))!==null;){let c=(s[1]||s[2]).replace(/-/g,"_");o.push({name:c,runtime:"nodejs20",entrypoint:"index.ts",sourceHint:`Exported from ${S__default.default.relative(t,i)} \u2014 needs manual conversion from Firebase Functions SDK to VAIF handler format`});}return o}function Mo(t,e){let o=[];e.storageBucket&&o.push({name:"default",public:false});let n=S__default.default.join(t,"storage.rules");if(A__default.default.existsSync(n)){let i=A__default.default.readFileSync(n,"utf-8"),a=/match\s+\/([a-zA-Z]\w*)\s*\/\{/g,r;for(;(r=a.exec(i))!==null;){let s=r[1];s!=="b"&&!o.find(c=>c.name===s)&&o.push({name:s,public:false});}}return o}function Ko(t){let e=[],o=bt(t)||{},n=$o(t);n.length===0?e.push("No firestore.rules found. Add your Firestore rules file or manually specify your collection structure."):e.push("Firestore collections were detected from firestore.rules. Each collection is mapped to a table with a JSONB 'data' column. You should replace the 'data' column with specific typed columns matching your document structure. See docs/migration/from-firebase.md for schema design patterns.");let i=Oo(t);i.length>0&&e.push("Firebase Cloud Functions use the Firebase Admin SDK and trigger patterns (auth.user().onCreate, firestore.document().onWrite). VAIF functions use a simpler handler(req, ctx) pattern. Each function needs manual conversion.");let a=Mo(t,o),r=["email"],s=S__default.default.join(t,"firebase.json");if(A__default.default.existsSync(s))try{let c=JSON.parse(A__default.default.readFileSync(s,"utf-8"));c.auth?.providers&&r.push(...c.auth.providers.filter(l=>l!=="email"));}catch{}return {source:"firebase",tables:n,buckets:a,functions:i,authProviders:r,warnings:e}}function Bo(t){if(console.log(""),console.log(f__default.default.bold.cyan(` Migration Plan (from ${t.source})`)),console.log(f__default.default.gray(" \u2500".repeat(30))),console.log(""),t.tables.length>0){console.log(f__default.default.bold(` \u{1F4E6} Tables (${t.tables.length})`));for(let e of t.tables){let o=e.columns.length,n=e.columns.filter(r=>r.references).length,i=e.rlsPolicies?.length||0,a=[`${o} columns`];n>0&&a.push(`${n} foreign keys`),i>0&&a.push(`${i} RLS policies`),console.log(f__default.default.white(` ${e.name}`)+f__default.default.gray(` \u2014 ${a.join(", ")}`));}console.log("");}if(t.buckets.length>0){console.log(f__default.default.bold(` \u{1F5C4}\uFE0F Storage Buckets (${t.buckets.length})`));for(let e of t.buckets)console.log(f__default.default.white(` ${e.name}`)+f__default.default.gray(` \u2014 ${e.public?"public":"private"}`));console.log("");}if(t.functions.length>0){console.log(f__default.default.bold(` \u26A1 Functions (${t.functions.length})`));for(let e of t.functions)console.log(f__default.default.white(` ${e.name}`)+f__default.default.gray(` \u2014 ${e.runtime}`)),e.sourceHint&&console.log(f__default.default.yellow(` \u26A0 ${e.sourceHint}`));console.log("");}if(t.authProviders.length>0&&(console.log(f__default.default.bold(` \u{1F510} Auth Providers (${t.authProviders.length})`)),console.log(f__default.default.white(` ${t.authProviders.join(", ")}`)),console.log("")),t.warnings.length>0){console.log(f__default.default.bold.yellow(" \u26A0 Warnings"));for(let e of t.warnings)console.log(f__default.default.yellow(` \u2022 ${e}`));console.log("");}}function vt(t,e){let o=`# VAIF Migration Plan
5165
+
5166
+ `;if(o+=`**Source:** ${t.source}
5167
+ `,o+=`**Generated:** ${new Date().toISOString()}
5168
+
5169
+ `,t.tables.length>0){o+=`## Tables (${t.tables.length})
5170
+
5171
+ `;for(let i of t.tables){o+=`### ${i.name}
5172
+
5173
+ `,o+=`| Column | Type | Nullable | Default | Constraints |
5174
+ `,o+=`|--------|------|----------|---------|-------------|
5175
+ `;for(let a of i.columns){let r=[];a.isPrimaryKey&&r.push("PK"),a.isUnique&&r.push("UNIQUE"),a.references&&r.push(`FK \u2192 ${a.references.table}.${a.references.column}`),o+=`| ${a.name} | ${a.type} | ${a.nullable?"yes":"no"} | ${a.defaultValue||"-"} | ${r.join(", ")||"-"} |
5176
+ `;}if(o+=`
5177
+ `,i.rlsPolicies&&i.rlsPolicies.length>0){o+=`**RLS Policies:**
5178
+ `;for(let a of i.rlsPolicies)o+=`- \`${a.name}\` (${a.command}): \`${a.definition}\`
5179
+ `;o+=`
5180
+ `;}}}if(t.buckets.length>0){o+=`## Storage Buckets (${t.buckets.length})
5181
+
5182
+ `;for(let i of t.buckets)o+=`- **${i.name}** \u2014 ${i.public?"public":"private"}
5183
+ `;o+=`
5184
+ `;}if(t.functions.length>0){o+=`## Functions (${t.functions.length})
5185
+
5186
+ `;for(let i of t.functions)o+=`- **${i.name}** \u2014 ${i.runtime}
5187
+ `,i.sourceHint&&(o+=` - \u26A0 ${i.sourceHint}
5188
+ `);o+=`
5189
+ `;}if(t.authProviders.length>0&&(o+=`## Auth Providers
5190
+
5191
+ `,o+=t.authProviders.map(i=>`- ${i}`).join(`
5192
+ `)+`
5193
+
5194
+ `),t.warnings.length>0){o+=`## Warnings
5195
+
5196
+ `;for(let i of t.warnings)o+=`- \u26A0 ${i}
5197
+ `;o+=`
5198
+ `;}o+=`## Next Steps
5199
+
5200
+ `,o+=`1. Review the tables above and adjust column types as needed
5201
+ `,o+=`2. Run \`vaif migrate --from ${t.source}\` without \`--dry-run\` to execute
5202
+ `,o+=`3. Verify tables were created in the VAIF dashboard
5203
+ `,o+=`4. Migrate your data using the export/import scripts in docs/migration/from-${t.source}.md
5204
+ `,o+="5. Update your application code to use `@vaiftech/client`\n";let n=S__default.default.join(e,"vaif-migration-plan.md");return A__default.default.writeFileSync(n,o,"utf-8"),n}var we=process.env.VAIF_API_URL||"https://api.vaif.studio";async function zo(t,e,o){if(t.tables.length>0){let n=ie__default.default(`Creating ${t.tables.length} tables...`).start();try{let i=t.tables.map(r=>({name:r.name,columns:r.columns.map(s=>({name:s.name,type:s.type,nullable:s.nullable,primaryKey:s.isPrimaryKey||!1,unique:s.isUnique||!1,default:s.defaultValue,references:s.references?{table:s.references.table,column:s.references.column,onDelete:s.references.onDelete||"SET NULL"}:void 0})),indexes:r.indexes})),a=await fetch(`${we}/schema-engine/${e}/tables`,{method:"POST",headers:{Authorization:`Bearer ${o}`,"Content-Type":"application/json"},body:JSON.stringify({tables:i})});if(a.ok)n.succeed(`Created ${t.tables.length} tables`);else {let r=await a.text();n.fail(`Failed to create tables: ${r}`);}}catch(i){n.fail(`Failed to create tables: ${i instanceof Error?i.message:String(i)}`);}}for(let n of t.buckets){let i=ie__default.default(`Creating bucket: ${n.name}...`).start();try{let a=await fetch(`${we}/storage/buckets`,{method:"POST",headers:{Authorization:`Bearer ${o}`,"Content-Type":"application/json","x-project-id":e},body:JSON.stringify({name:n.name,public:n.public,fileSizeLimit:n.fileSizeLimit,allowedMimeTypes:n.allowedMimeTypes})});if(a.ok)i.succeed(`Created bucket: ${n.name}`);else {let r=await a.text();i.warn(`Bucket ${n.name}: ${r}`);}}catch(a){i.warn(`Bucket ${n.name}: ${a instanceof Error?a.message:String(a)}`);}}for(let n of t.functions){let i=ie__default.default(`Creating function: ${n.name}...`).start();try{let a=await fetch(`${we}/functions`,{method:"POST",headers:{Authorization:`Bearer ${o}`,"Content-Type":"application/json"},body:JSON.stringify({projectId:e,name:n.name,runtime:n.runtime,entrypoint:n.entrypoint})});if(a.ok)i.succeed(`Created function stub: ${n.name}`);else {let r=await a.text();i.warn(`Function ${n.name}: ${r}`);}}catch(a){i.warn(`Function ${n.name}: ${a instanceof Error?a.message:String(a)}`);}}}async function It(t){let e=t.outputDir?S__default.default.resolve(t.outputDir):process.cwd(),o=t.from;console.log(""),console.log(f__default.default.bold(` Analyzing ${o} project...`));let n;if(o==="supabase"?(jo(e)||(console.log(f__default.default.yellow(`
5205
+ No Supabase configuration found.`)),console.log(f__default.default.gray(" Expected: .env with SUPABASE_URL, or supabase/config.toml")),console.log(f__default.default.gray(` Make sure you're in a Supabase project directory.
5206
+ `)),process.exit(1)),n=Vo(e)):o==="firebase"?(bt(e)||(console.log(f__default.default.yellow(`
5207
+ No Firebase configuration found.`)),console.log(f__default.default.gray(" Expected: firebase.json or .firebaserc in project root")),console.log(f__default.default.gray(` Make sure you're in a Firebase project directory.
5208
+ `)),process.exit(1)),n=Ko(e)):(console.log(f__default.default.red(`
5209
+ Unknown source: "${o}"`)),console.log(f__default.default.gray(` Supported: supabase, firebase
5210
+ `)),process.exit(1)),Bo(n),t.dryRun){let s=vt(n,e);console.log(f__default.default.green(` \u2713 Migration plan written to ${f__default.default.cyan(S__default.default.relative(process.cwd(),s))}`)),console.log(f__default.default.gray(` Review the plan, then run without --dry-run to execute.
5211
+ `));return}let i=E();(!i||!i.token)&&(console.log(f__default.default.red(" Not logged in. Run `vaif login` first.")),process.exit(1));let a=t.projectId;if(!a)try{a=(await w(t.config||"vaif.config.json")).projectId;}catch{}a||(a=process.env.VAIF_PROJECT_ID),a||(console.log(f__default.default.red(" No VAIF project ID specified.")),console.log(f__default.default.gray(` Pass --project-id <id>, set in vaif.config.json, or set VAIF_PROJECT_ID env var.
5212
+ `)),process.exit(1)),console.log(f__default.default.bold(` Executing migration to VAIF project: ${a}
5213
+ `)),await zo(n,a,i.token);let r=vt(n,e);console.log(""),console.log(f__default.default.green.bold(" \u2713 Migration complete!")),console.log(f__default.default.gray(` Plan saved to ${S__default.default.relative(process.cwd(),r)}`)),console.log(""),console.log(f__default.default.bold(" Next steps:")),console.log(f__default.default.gray(" 1. Verify tables in the VAIF dashboard")),console.log(f__default.default.gray(" 2. Migrate data using scripts in docs/migration/from-"+o+".md")),console.log(f__default.default.gray(" 3. Update your app code to use @vaiftech/client")),console.log(f__default.default.gray(" 4. Run `vaif claude-setup` to configure AI tools for your project\n"));}var Yo=module$1.createRequire(N),{version:At}=Yo("../package.json"),_e=f__default.default.hex("#00f0ff"),Se=f__default.default.hex("#7b61ff"),Te=f__default.default.hex("#ff3dff"),xe=f__default.default.hex("#00ff9d"),T=f__default.default.hex("#555570"),H=f__default.default.hex("#00f0ff");function Jo(){console.log(""),console.log(_e(" \u2566 \u2566")+Se("\u2554\u2550\u2557\u2566")+Te("\u2554\u2550\u2557 ")+xe("\u2554\u2550\u2557\u2566 \u2566")),console.log(_e(" \u255A\u2557\u2554\u255D")+Se("\u2560\u2550\u2563\u2551")+Te("\u2560\u2563 ")+xe("\u2551 \u2551 \u2551")),console.log(_e(" \u255A\u255D ")+Se("\u2569 \u2569\u2569")+Te("\u255A ")+xe("\u255A\u2550\u255D\u2569\u2550\u255D\u2569")),console.log(""),console.log(T(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500")),console.log(H(" VAIF Studio CLI")+T(` v${At}`)),console.log(T(" Build full-stack apps at lightning speed")),console.log(T(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500")),console.log(""),console.log(f__default.default.bold(" Quick Start")),console.log(T(" $ ")+H("vaif login")+T(" Authenticate")),console.log(T(" $ ")+H("vaif init -t react-spa")+T(" Scaffold project")),console.log(T(" $ ")+H("vaif db push")+T(" Push migrations")),console.log(T(" $ ")+H("vaif generate")+T(" Generate types")),console.log(T(" $ ")+H("vaif functions deploy")+T(" Deploy functions")),console.log(""),console.log(f__default.default.bold(" Categories")),console.log(T(" auth ")+f__default.default.white("login, logout, whoami")),console.log(T(" project ")+f__default.default.white("init, templates, info, status")),console.log(T(" schema ")+f__default.default.white("pull, push, generate")),console.log(T(" database ")+f__default.default.white("db push, db pull, db seed, db reset")),console.log(T(" deploy ")+f__default.default.white("functions deploy, functions list")),console.log(T(" security ")+f__default.default.white("keys, secrets")),console.log(T(" migrate ")+f__default.default.white("migrate --from supabase|firebase")),console.log(T(" ai ")+f__default.default.white("claude-setup, init --claude")),console.log(""),console.log(T(" Run ")+H("vaif <command> --help")+T(" for details")),console.log(T(" Docs: ")+f__default.default.underline("https://docs.vaif.studio")),console.log("");}commander.program.name("vaif").description("VAIF CLI - Type generation and development tools").version(At);commander.program.command("login").description("Authenticate with VAIF (opens browser)").option("-e, --email","Login with email/password instead of browser").option("-p, --project-id <id>","Default project ID").action(ke);commander.program.command("logout").description("Log out and remove stored credentials").action(Ne);commander.program.command("whoami").description("Show current authenticated user").action(Le);commander.program.command("init").description("Initialize VAIF configuration in your project").option("--typescript","Setup for TypeScript project").option("-f, --force","Overwrite existing config").option("-t, --template <name>","Scaffold from a template (run vaif templates for list)").option("--features <features>","Comma-separated features to include: auth,database,realtime,storage,functions").option("--add-features <features>","Add features to an existing project (requires --template)").option("--claude [type]","Generate CLAUDE.md for AI assistants (types: base, saas, mobile, ecommerce). Omit type to auto-detect or use live project data.").action(qe);commander.program.command("templates").alias("tpl").description("List available project templates").action(Me);commander.program.command("info").description("Show project information (name, region, URLs)").option("-c, --config <path>","Config file path","vaif.config.json").option("-p, --project-id <id>","Project ID (overrides config)").action(ht);commander.program.command("status").description("Show project status (tables, functions, storage, connections)").option("-c, --config <path>","Config file path","vaif.config.json").option("-p, --project-id <id>","Project ID (overrides config)").action(yt);commander.program.command("pull").description("Pull database schema from your VAIF project").option("-c, --config <path>","Config file path","vaif.config.json").option("-o, --output <path>","Output file path","vaif.schema.json").option("-s, --schema <name>","Schema name","public").option("-p, --project-id <id>","Project ID (overrides config)").action(Ye);commander.program.command("push").description("Push local schema changes to your VAIF project").option("-c, --config <path>","Config file path","vaif.config.json").option("-s, --schema <path>","Schema file path","vaif.schema.json").option("-p, --project-id <id>","Project ID (overrides config)").option("--dry-run","Preview changes without applying").option("-f, --force","Apply changes without confirmation").action(We);commander.program.command("generate").alias("gen").description("Generate TypeScript types from your database schema").option("-c, --connection <url>","Database connection string").option("-o, --output <path>","Output file path","./src/types/database.ts").option("--schema <name>","Schema name","public").option("--config <path>","Config file path","vaif.config.json").option("--dry-run","Preview generated types without writing").action(Ve);var Et=commander.program.command("functions").alias("fn").description("Manage serverless functions");Et.command("deploy").description("Deploy functions to your VAIF project").option("-c, --config <path>","Config file path","vaif.config.json").option("-p, --project-id <id>","Project ID (overrides config)").option("-e, --env-id <id>","Environment ID").option("-n, --name <name>","Function name filter").option("-r, --runtime <runtime>","Runtime (nodejs, typescript, python)").option("--entrypoint <file>","Specific entrypoint file").option("--dry-run","Preview deployment without deploying").action(Ze);Et.command("list").alias("ls").description("List deployed functions").option("-c, --config <path>","Config file path","vaif.config.json").option("-p, --project-id <id>","Project ID (overrides config)").option("-e, --env-id <id>","Environment ID").action(et);var ue=commander.program.command("db").description("Database management commands");ue.command("push").description("Push local Drizzle migrations to VAIF project").option("-c, --config <path>","Config file path","vaif.config.json").option("-p, --project-id <id>","Project ID (overrides config)").option("-d, --dir <path>","Migrations directory","./drizzle").option("--dry-run","Preview without applying").action(nt);ue.command("pull").description("Pull schema from VAIF project").option("-c, --config <path>","Config file path","vaif.config.json").option("-p, --project-id <id>","Project ID (overrides config)").option("-o, --output <path>","Output file","vaif.schema.json").action(at);ue.command("seed").description("Seed your database with test data").option("-c, --config <path>","Config file path","vaif.config.json").option("-p, --project-id <id>","Project ID (overrides config)").option("-f, --file <path>","Specific seed file").option("-t, --table <name>","Seed specific table only").option("--truncate","Truncate tables before seeding").option("--dry-run","Preview seeding without inserting data").action(ot);ue.command("reset").description("Reset database (drop all tables and data)").option("-c, --config <path>","Config file path","vaif.config.json").option("-p, --project-id <id>","Project ID (overrides config)").option("-f, --force","Confirm reset (required)").action(it);var wt=commander.program.command("keys").description("Manage API keys");wt.command("generate").description("Generate a new API key").option("-c, --config <path>","Config file path","vaif.config.json").option("-p, --project-id <id>","Project ID (overrides config)").option("-n, --name <name>","Key name").action(lt);wt.command("list").alias("ls").description("List API keys").option("-c, --config <path>","Config file path","vaif.config.json").option("-p, --project-id <id>","Project ID (overrides config)").action(dt);var pe=commander.program.command("secrets").alias("sec").description("Manage function secrets");pe.command("set <name> [value]").description("Create or update a secret").option("-c, --config <path>","Config file path","vaif.config.json").option("-p, --project-id <id>","Project ID (overrides config)").option("-e, --env-id <id>","Environment ID or name").option("--from-file <path>","Read secret value from a file").action(ut);pe.command("list").alias("ls").description("List all secrets (names only)").option("-c, --config <path>","Config file path","vaif.config.json").option("-p, --project-id <id>","Project ID (overrides config)").option("-e, --env-id <id>","Environment ID or name").action(pt);pe.command("get <name>").description("Reveal a secret value").option("-c, --config <path>","Config file path","vaif.config.json").option("-p, --project-id <id>","Project ID (overrides config)").option("-e, --env-id <id>","Environment ID or name").action(ft);pe.command("delete <name>").description("Delete a secret").option("-c, --config <path>","Config file path","vaif.config.json").option("-p, --project-id <id>","Project ID (overrides config)").option("-e, --env-id <id>","Environment ID or name").action(gt);commander.program.command("migrate").description("Migrate from Supabase or Firebase to VAIF Studio").requiredOption("--from <platform>","Source platform: supabase or firebase").option("--dry-run","Show migration plan without executing").option("-c, --config <path>","VAIF config file path","vaif.config.json").option("-p, --project-id <id>","Target VAIF project ID").option("-o, --output-dir <dir>","Source project directory to analyze",".").action(It);commander.program.command("claude-setup").description("Configure Claude Code integration (MCP server + CLAUDE.md)").option("-c, --config <path>","Config file path","vaif.config.json").option("-p, --project-id <id>","Project ID").option("-k, --api-key <key>","API key for MCP server").option("--skip-mcp","Skip generating .mcp.json").option("--skip-claude-md","Skip generating CLAUDE.md").option("-o, --output-dir <dir>","Output directory",".").action(oe);process.argv.slice(2).length||(Jo(),process.exit(0));commander.program.parse(process.argv);