@vaiftech/cli 1.7.5 → 1.8.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/index.cjs CHANGED
@@ -1,10 +1,10 @@
1
- 'use strict';var y=require('fs'),w=require('path'),B=require('dotenv'),G=require('pg'),H=require('ora'),d=require('chalk'),W=require('prettier'),q=require('os'),K=require('readline');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var y__default=/*#__PURE__*/_interopDefault(y);var w__default=/*#__PURE__*/_interopDefault(w);var B__default=/*#__PURE__*/_interopDefault(B);var G__default=/*#__PURE__*/_interopDefault(G);var H__default=/*#__PURE__*/_interopDefault(H);var d__default=/*#__PURE__*/_interopDefault(d);var W__default=/*#__PURE__*/_interopDefault(W);var q__default=/*#__PURE__*/_interopDefault(q);var K__default=/*#__PURE__*/_interopDefault(K);B__default.default.config();async function E(i){let a=w__default.default.resolve(i);if(!y__default.default.existsSync(a))return null;try{let t=y__default.default.readFileSync(a,"utf-8"),e=JSON.parse(t);return e.database?.url&&(e.database.url=V(e.database.url)),e.api?.apiKey&&(e.api.apiKey=V(e.api.apiKey)),e}catch{throw new Error(`Failed to parse config file: ${i}`)}}function V(i){return i.replace(/\$\{([^}]+)\}/g,(a,t)=>process.env[t]||a)}var Y=w__default.default.join(q__default.default.homedir(),".vaif"),k=w__default.default.join(Y,"auth.json");process.env.VAIF_API_URL||"https://api.vaif.studio";function O(){if(!y__default.default.existsSync(k))return null;try{let i=y__default.default.readFileSync(k,"utf-8");return JSON.parse(i)}catch{return null}}var J=process.env.VAIF_API_URL||"https://api.vaif.studio";async function X(i,a){let t=await fetch(`${J}/schema-engine/introspect/${a}`,{headers:{Authorization:`Bearer ${i}`,"Content-Type":"application/json"}});if(!t.ok){let l=await t.text();throw new Error(`API introspection failed: ${l}`)}let e=await t.json();if(!e.ok||!e.schemaExists)throw new Error("Project schema does not exist yet. Push a migration first with `vaif db push`.");let r=new Map,o=[];for(let l of e.tables){let c=l.columns.map(n=>({column_name:n.name,data_type:n.type,is_nullable:n.nullable?"YES":"NO",column_default:n.default,udt_name:n.type,is_identity:n.primaryKey&&n.default?.includes("gen_random_uuid")?"YES":"NO",character_maximum_length:null,numeric_precision:null,numeric_scale:null}));r.set(l.name,c);for(let n of l.foreignKeys)o.push({constraint_name:n.constraintName,table_name:l.name,column_name:n.columnName,foreign_table_name:n.refTable,foreign_column_name:n.refColumn});}return {tables:r,enums:new Map,foreignKeys:o}}async function Q(i,a){let t=await i.query(`
1
+ 'use strict';var b=require('fs'),R=require('path'),G=require('dotenv'),W=require('pg'),X=require('ora'),d=require('chalk'),Q=require('prettier'),H=require('os'),B=require('readline');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var b__default=/*#__PURE__*/_interopDefault(b);var R__default=/*#__PURE__*/_interopDefault(R);var G__default=/*#__PURE__*/_interopDefault(G);var W__default=/*#__PURE__*/_interopDefault(W);var X__default=/*#__PURE__*/_interopDefault(X);var d__default=/*#__PURE__*/_interopDefault(d);var Q__default=/*#__PURE__*/_interopDefault(Q);var H__default=/*#__PURE__*/_interopDefault(H);var B__default=/*#__PURE__*/_interopDefault(B);G__default.default.config();async function S(n){let a=R__default.default.resolve(n);if(!b__default.default.existsSync(a))return null;try{let t=b__default.default.readFileSync(a,"utf-8"),e=JSON.parse(t);return e.database?.url&&(e.database.url=j(e.database.url)),e.api?.apiKey&&(e.api.apiKey=j(e.api.apiKey)),e}catch{throw new Error(`Failed to parse config file: ${n}`)}}function j(n){return n.replace(/\$\{([^}]+)\}/g,(a,t)=>process.env[t]||a)}var J=R__default.default.join(H__default.default.homedir(),".vaif"),M=R__default.default.join(J,"auth.json");process.env.VAIF_API_URL||"https://api.vaif.studio";function z(){if(!b__default.default.existsSync(M))return null;try{let n=b__default.default.readFileSync(M,"utf-8");return JSON.parse(n)}catch{return null}}var Z=process.env.VAIF_API_URL||"https://api.vaif.studio";async function ee(n,a){let t=await fetch(`${Z}/schema-engine/introspect/${a}`,{headers:{Authorization:`Bearer ${n}`,"Content-Type":"application/json"}});if(!t.ok){let s=await t.text();throw new Error(`API introspection failed: ${s}`)}let e=await t.json();if(!e.ok||!e.schemaExists)throw new Error("Project schema does not exist yet. Push a migration first with `vaif db push`.");let i=new Map,o=[];for(let s of e.tables){let r=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,r);for(let l of s.foreignKeys)o.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:o}}async function te(n,a){let t=await n.query(`
2
2
  SELECT table_name, table_type
3
3
  FROM information_schema.tables
4
4
  WHERE table_schema = $1
5
5
  AND table_type = 'BASE TABLE'
6
6
  ORDER BY table_name
7
- `,[a]),e=await i.query(`
7
+ `,[a]),e=await n.query(`
8
8
  SELECT
9
9
  table_name,
10
10
  column_name,
@@ -19,7 +19,7 @@
19
19
  FROM information_schema.columns
20
20
  WHERE table_schema = $1
21
21
  ORDER BY table_name, ordinal_position
22
- `,[a]),r=await i.query(`
22
+ `,[a]),i=await n.query(`
23
23
  SELECT
24
24
  tc.constraint_name,
25
25
  tc.table_name,
@@ -35,7 +35,7 @@
35
35
  AND ccu.table_schema = tc.table_schema
36
36
  WHERE tc.constraint_type = 'FOREIGN KEY'
37
37
  AND tc.table_schema = $1
38
- `,[a]),o=await i.query(`
38
+ `,[a]),o=await n.query(`
39
39
  SELECT
40
40
  t.typname as enum_name,
41
41
  e.enumlabel as enum_value
@@ -44,24 +44,24 @@
44
44
  JOIN pg_namespace n ON n.oid = t.typnamespace
45
45
  WHERE n.nspname = $1
46
46
  ORDER BY t.typname, e.enumsortorder
47
- `,[a]),u=new Map;for(let c of t.rows)u.set(c.table_name,[]);for(let c of e.rows){let n=u.get(c.table_name);n&&n.push(c);}let l=new Map;for(let c of o.rows){let n=l.get(c.enum_name)||[];n.push(c.enum_value),l.set(c.enum_name,n);}return {tables:u,enums:l,foreignKeys:r.rows}}var x={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 Z(i,a){let{data_type:t,udt_name:e,is_nullable:r}=i;if(a.has(e)){let l=a.get(e).map(c=>`"${c}"`).join(" | ");return r==="YES"?`(${l}) | null`:l}if(t==="ARRAY"){let u=e.replace(/^_/,"");if(a.has(u)){let n=a.get(u).map(s=>`"${s}"`).join(" | ");return r==="YES"?`(${n})[] | null`:`(${n})[]`}let l=x[u]||"unknown";return r==="YES"?`${l}[] | null`:`${l}[]`}let o=x[t]||x[e]||"unknown";return r==="YES"&&(o=`${o} | null`),o}function S(i){return i.split(/[_\-\s]+/).map(a=>a.charAt(0).toUpperCase()+a.slice(1).toLowerCase()).join("")}function ee(i,a){let t=S(i),e=a.map(r=>` | "${r}"`).join(`
47
+ `,[a]),c=new Map;for(let r of t.rows)c.set(r.table_name,[]);for(let r of e.rows){let l=c.get(r.table_name);l&&l.push(r);}let s=new Map;for(let r of o.rows){let l=s.get(r.enum_name)||[];l.push(r.enum_value),s.set(r.enum_name,l);}return {tables:c,enums:s,foreignKeys:i.rows}}var F={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 ae(n,a){let{data_type:t,udt_name:e,is_nullable:i}=n;if(a.has(e)){let s=a.get(e).map(r=>`"${r}"`).join(" | ");return i==="YES"?`(${s}) | null`:s}if(t==="ARRAY"){let c=e.replace(/^_/,"");if(a.has(c)){let l=a.get(c).map(p=>`"${p}"`).join(" | ");return i==="YES"?`(${l})[] | null`:`(${l})[]`}let s=F[c]||"unknown";return i==="YES"?`${s}[] | null`:`${s}[]`}let o=F[t]||F[e]||"unknown";return i==="YES"&&(o=`${o} | null`),o}function P(n){return n.split(/[_\-\s]+/).map(a=>a.charAt(0).toUpperCase()+a.slice(1).toLowerCase()).join("")}function ne(n,a){let t=P(n),e=a.map(i=>` | "${i}"`).join(`
48
48
  `);return `export type ${t} =
49
- ${e};`}function te(i,a,t){let e=S(i),r=[],o=[],u=[];for(let s of a){let m=Z(s,t),p=s.column_name,g=s.column_default!==null||s.is_identity==="YES",v=s.is_nullable==="YES";r.push(` ${p}: ${m};`),g||s.column_name==="id"?o.push(` ${p}?: ${m.replace(" | null","")} | null;`):v?o.push(` ${p}?: ${m};`):o.push(` ${p}: ${m.replace(" | null","")};`),u.push(` ${p}?: ${m.replace(" | null","")} | null;`);}let l=`export interface ${e} {
50
- ${r.join(`
49
+ ${e};`}function ie(n,a,t){let e=P(n),i=[],o=[],c=[];for(let p of a){let m=ae(p,t),u=p.column_name,f=p.column_default!==null||p.is_identity==="YES",h=p.is_nullable==="YES";i.push(` ${u}: ${m};`),f||p.column_name==="id"?o.push(` ${u}?: ${m.replace(" | null","")} | null;`):h?o.push(` ${u}?: ${m};`):o.push(` ${u}: ${m.replace(" | null","")};`),c.push(` ${u}?: ${m.replace(" | null","")} | null;`);}let s=`export interface ${e} {
50
+ ${i.join(`
51
51
  `)}
52
- }`,c=`export interface ${e}Insert {
52
+ }`,r=`export interface ${e}Insert {
53
53
  ${o.join(`
54
54
  `)}
55
- }`,n=`export interface ${e}Update {
56
- ${u.join(`
55
+ }`,l=`export interface ${e}Update {
56
+ ${c.join(`
57
57
  `)}
58
- }`;return {base:l,insert:c,update:n}}function ae(i,a,t){let e=["/**"," * 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(a.size>0){e.push("// ============ ENUMS ============"),e.push("");for(let[o,u]of a)e.push(ee(o,u)),e.push("");}e.push("// ============ TABLES ============"),e.push("");let r=[];for(let[o,u]of i){let{base:l,insert:c,update:n}=te(o,u,a);r.push(o),e.push(l),e.push(""),e.push(c),e.push(""),e.push(n),e.push("");}e.push("// ============ DATABASE SCHEMA ============"),e.push(""),e.push("export interface Database {");for(let o of r){let u=S(o);e.push(` ${o}: {`),e.push(` Row: ${u};`),e.push(` Insert: ${u}Insert;`),e.push(` Update: ${u}Update;`),e.push(" };");}return e.push("}"),e.push(""),e.push("export type TableName = keyof Database;"),e.push(""),e.push("// ============ HELPER TYPES ============"),e.push(""),e.push('export type Row<T extends TableName> = Database[T]["Row"];'),e.push('export type Insert<T extends TableName> = Database[T]["Insert"];'),e.push('export type Update<T extends TableName> = Database[T]["Update"];'),e.push(""),e.join(`
59
- `)}async function ne(i){let a=H__default.default("Loading configuration...").start();try{let t=await E(i.config),e=i.connection||t?.database?.url||process.env.DATABASE_URL,r=e&&!e.includes("${"),o,u,l;if(r){a.text="Connecting to database...";let p=new G__default.default.Client({connectionString:e});await p.connect(),a.text="Introspecting schema...",{tables:o,enums:u,foreignKeys:l}=await Q(p,i.schema),await p.end();}else {let p=O();(!p||!p.token)&&(a.fail("No database connection and not logged in"),console.log(d__default.default.yellow(`
60
- Either:`)),console.log(d__default.default.gray(" 1. Run `vaif login` to authenticate (no DATABASE_URL needed)")),console.log(d__default.default.gray(" 2. Set DATABASE_URL in your .env file")),console.log(d__default.default.gray(" 3. Pass --connection postgresql://user:pass@host:5432/db")),process.exit(1));let g=t?.projectId||process.env.VAIF_PROJECT_ID||p.projectId;g||(a.fail("No project ID specified"),console.log(d__default.default.yellow(`
61
- Set projectId in vaif.config.json or use VAIF_PROJECT_ID env var.`)),process.exit(1)),a.text="Introspecting schema via API...",{tables:o,enums:u,foreignKeys:l}=await X(p.token,g);}if(o.size===0){a.warn("No tables found"),console.log(d__default.default.yellow(`
62
- Push a migration first: vaif db push`));return}a.text=`Generating types for ${o.size} tables...`;let c=ae(o,u,l),n=await W__default.default.format(c,{parser:"typescript",semi:!0,singleQuote:!1,trailingComma:"es5",printWidth:100});if(i.dryRun){a.succeed("Generated types (dry run):"),console.log(""),console.log(d__default.default.gray("\u2500".repeat(60))),console.log(n),console.log(d__default.default.gray("\u2500".repeat(60)));return}let s=w__default.default.resolve(i.output),m=w__default.default.dirname(s);y__default.default.existsSync(m)||y__default.default.mkdirSync(m,{recursive:!0}),y__default.default.writeFileSync(s,n,"utf-8"),a.succeed(`Generated types for ${o.size} tables \u2192 ${d__default.default.cyan(i.output)}`),console.log(""),console.log(d__default.default.green("Generated:")),console.log(d__default.default.gray(` Tables: ${o.size}`)),console.log(d__default.default.gray(` Enums: ${u.size}`)),console.log(""),console.log(d__default.default.gray("Import in your code:")),console.log(d__default.default.cyan(` import type { Database, Row, Insert, Update } from "${i.output.replace(/\.ts$/,"")}";`));}catch(t){a.fail("Failed to generate types"),t instanceof Error&&(console.error(d__default.default.red(`
58
+ }`;return {base:s,insert:r,update:l}}function oe(n,a,t){let e=["/**"," * 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(a.size>0){e.push("// ============ ENUMS ============"),e.push("");for(let[o,c]of a)e.push(ne(o,c)),e.push("");}e.push("// ============ TABLES ============"),e.push("");let i=[];for(let[o,c]of n){let{base:s,insert:r,update:l}=ie(o,c,a);i.push(o),e.push(s),e.push(""),e.push(r),e.push(""),e.push(l),e.push("");}e.push("// ============ DATABASE SCHEMA ============"),e.push(""),e.push("export interface Database {");for(let o of i){let c=P(o);e.push(` ${o}: {`),e.push(` Row: ${c};`),e.push(` Insert: ${c}Insert;`),e.push(` Update: ${c}Update;`),e.push(" };");}return e.push("}"),e.push(""),e.push("export type TableName = keyof Database;"),e.push(""),e.push("// ============ HELPER TYPES ============"),e.push(""),e.push('export type Row<T extends TableName> = Database[T]["Row"];'),e.push('export type Insert<T extends TableName> = Database[T]["Insert"];'),e.push('export type Update<T extends TableName> = Database[T]["Update"];'),e.push(""),e.join(`
59
+ `)}async function re(n){let a=X__default.default("Loading configuration...").start();try{let t=await S(n.config),e=n.connection||t?.database?.url||process.env.DATABASE_URL,i=e&&!e.includes("${"),o,c,s;if(i){a.text="Connecting to database...";let u=new W__default.default.Client({connectionString:e});await u.connect(),a.text="Introspecting schema...",{tables:o,enums:c,foreignKeys:s}=await te(u,n.schema),await u.end();}else {let u=z();(!u||!u.token)&&(a.fail("No database connection and not logged in"),console.log(d__default.default.yellow(`
60
+ Either:`)),console.log(d__default.default.gray(" 1. Run `vaif login` to authenticate (no DATABASE_URL needed)")),console.log(d__default.default.gray(" 2. Set DATABASE_URL in your .env file")),console.log(d__default.default.gray(" 3. Pass --connection postgresql://user:pass@host:5432/db")),process.exit(1));let f=t?.projectId||process.env.VAIF_PROJECT_ID||u.projectId;f||(a.fail("No project ID specified"),console.log(d__default.default.yellow(`
61
+ Set projectId in vaif.config.json or use VAIF_PROJECT_ID env var.`)),process.exit(1)),a.text="Introspecting schema via API...",{tables:o,enums:c,foreignKeys:s}=await ee(u.token,f);}if(o.size===0){a.warn("No tables found"),console.log(d__default.default.yellow(`
62
+ Push a migration first: vaif db push`));return}a.text=`Generating types for ${o.size} tables...`;let r=oe(o,c,s),l=await Q__default.default.format(r,{parser:"typescript",semi:!0,singleQuote:!1,trailingComma:"es5",printWidth:100});if(n.dryRun){a.succeed("Generated types (dry run):"),console.log(""),console.log(d__default.default.gray("\u2500".repeat(60))),console.log(l),console.log(d__default.default.gray("\u2500".repeat(60)));return}let p=R__default.default.resolve(n.output),m=R__default.default.dirname(p);b__default.default.existsSync(m)||b__default.default.mkdirSync(m,{recursive:!0}),b__default.default.writeFileSync(p,l,"utf-8"),a.succeed(`Generated types for ${o.size} tables \u2192 ${d__default.default.cyan(n.output)}`),console.log(""),console.log(d__default.default.green("Generated:")),console.log(d__default.default.gray(` Tables: ${o.size}`)),console.log(d__default.default.gray(` Enums: ${c.size}`)),console.log(""),console.log(d__default.default.gray("Import in your code:")),console.log(d__default.default.cyan(` import type { Database, Row, Insert, Update } from "${n.output.replace(/\.ts$/,"")}";`));}catch(t){a.fail("Failed to generate types"),t instanceof Error&&(console.error(d__default.default.red(`
63
63
  Error: ${t.message}`)),t.message.includes("ECONNREFUSED")&&console.log(d__default.default.yellow(`
64
- Make sure your database is running and accessible.`))),process.exit(1);}}var b=[{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"}],ie={"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:`{
64
+ Make sure your database is running and accessible.`))),process.exit(1);}}var _=[{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"}],se={"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:`{
65
65
  "name": "my-vaif-app",
66
66
  "private": true,
67
67
  "version": "0.1.0",
@@ -158,6 +158,7 @@ body {
158
158
  // Browser client \u2013 safe to use in Client Components
159
159
  export const vaif = createVaifClient({
160
160
  baseUrl: process.env.NEXT_PUBLIC_VAIF_API_URL || 'https://api.vaif.studio',
161
+ projectId: process.env.NEXT_PUBLIC_VAIF_PROJECT_ID,
161
162
  apiKey: process.env.NEXT_PUBLIC_VAIF_API_KEY!,
162
163
  });
163
164
 
@@ -165,6 +166,7 @@ export const vaif = createVaifClient({
165
166
  export function createVaifServer() {
166
167
  return createVaifClient({
167
168
  baseUrl: process.env.NEXT_PUBLIC_VAIF_API_URL || 'https://api.vaif.studio',
169
+ projectId: process.env.VAIF_PROJECT_ID,
168
170
  apiKey: process.env.VAIF_SECRET_KEY!,
169
171
  });
170
172
  }
@@ -172,6 +174,7 @@ export function createVaifServer() {
172
174
  # Get these values from https://vaif.studio/app/security/api-keys \u2192 Project Settings \u2192 API Keys
173
175
 
174
176
  NEXT_PUBLIC_VAIF_API_URL=https://api.vaif.studio
177
+ NEXT_PUBLIC_VAIF_PROJECT_ID=your-project-id
175
178
  NEXT_PUBLIC_VAIF_API_KEY=your-api-key
176
179
  VAIF_SECRET_KEY=your-secret-key
177
180
 
@@ -305,6 +308,7 @@ export async function middleware(request: NextRequest) {
305
308
 
306
309
  const vaif = createVaifClient({
307
310
  baseUrl: process.env.NEXT_PUBLIC_VAIF_API_URL || 'https://api.vaif.studio',
311
+ projectId: process.env.VAIF_PROJECT_ID,
308
312
  apiKey: process.env.VAIF_SECRET_KEY!,
309
313
  });
310
314
 
@@ -667,12 +671,14 @@ function Home() {
667
671
 
668
672
  export const vaif = createVaifClient({
669
673
  baseUrl: import.meta.env.VITE_VAIF_API_URL || 'https://api.vaif.studio',
674
+ projectId: import.meta.env.VITE_VAIF_PROJECT_ID,
670
675
  apiKey: import.meta.env.VITE_VAIF_API_KEY,
671
676
  });
672
677
  `},{path:"src/vite-env.d.ts",content:`/// <reference types="vite/client" />
673
678
 
674
679
  interface ImportMetaEnv {
675
680
  readonly VITE_VAIF_API_URL: string;
681
+ readonly VITE_VAIF_PROJECT_ID: string;
676
682
  readonly VITE_VAIF_API_KEY: string;
677
683
  }
678
684
 
@@ -683,6 +689,7 @@ interface ImportMeta {
683
689
  # Get these values from https://vaif.studio/app/security/api-keys
684
690
 
685
691
  VITE_VAIF_API_URL=https://api.vaif.studio
692
+ VITE_VAIF_PROJECT_ID=your-project-id
686
693
  VITE_VAIF_API_KEY=your-api-key
687
694
  `},{path:".gitignore",content:`node_modules
688
695
  dist
@@ -2683,6 +2690,7 @@ func HelloHandler(w http.ResponseWriter, r *http.Request) {
2683
2690
 
2684
2691
  export const vaif = createVaifClient({
2685
2692
  baseUrl: import.meta.env.VITE_VAIF_API_URL || 'https://api.vaif.studio',
2693
+ projectId: import.meta.env.VITE_VAIF_PROJECT_ID,
2686
2694
  apiKey: import.meta.env.VITE_VAIF_API_KEY,
2687
2695
  });
2688
2696
 
@@ -2737,6 +2745,7 @@ export async function deleteTodo(id: string): Promise<void> {
2737
2745
  # Get these values from https://vaif.studio/app/security/api-keys
2738
2746
 
2739
2747
  VITE_VAIF_API_URL=https://api.vaif.studio
2748
+ VITE_VAIF_PROJECT_ID=your-project-id
2740
2749
  VITE_VAIF_API_KEY=your-api-key
2741
2750
  `},{path:"README.md",content:`# Todo App \u2014 VAIF Starter
2742
2751
 
@@ -2874,6 +2883,7 @@ export const posts = pgTable("posts", {
2874
2883
 
2875
2884
  export const vaif = createVaifClient({
2876
2885
  baseUrl: import.meta.env.VITE_VAIF_API_URL || 'https://api.vaif.studio',
2886
+ projectId: import.meta.env.VITE_VAIF_PROJECT_ID,
2877
2887
  apiKey: import.meta.env.VITE_VAIF_API_KEY,
2878
2888
  });
2879
2889
 
@@ -3015,6 +3025,7 @@ export function useRealtimeMessages({
3015
3025
  # Get these values from https://vaif.studio/app/security/api-keys
3016
3026
 
3017
3027
  VITE_VAIF_API_URL=https://api.vaif.studio
3028
+ VITE_VAIF_PROJECT_ID=your-project-id
3018
3029
  VITE_VAIF_API_KEY=your-api-key
3019
3030
  `},{path:"README.md",content:`# Realtime Chat \u2014 VAIF Starter
3020
3031
 
@@ -3167,6 +3178,7 @@ export const posts = pgTable("posts", {
3167
3178
  // Browser client \u2013 use in Client Components
3168
3179
  export const vaif = createVaifClient({
3169
3180
  baseUrl: process.env.NEXT_PUBLIC_VAIF_API_URL || 'https://api.vaif.studio',
3181
+ projectId: process.env.NEXT_PUBLIC_VAIF_PROJECT_ID,
3170
3182
  apiKey: process.env.NEXT_PUBLIC_VAIF_API_KEY!,
3171
3183
  });
3172
3184
 
@@ -3174,6 +3186,7 @@ export const vaif = createVaifClient({
3174
3186
  export function createVaifServer() {
3175
3187
  return createVaifClient({
3176
3188
  baseUrl: process.env.NEXT_PUBLIC_VAIF_API_URL || 'https://api.vaif.studio',
3189
+ projectId: process.env.VAIF_PROJECT_ID,
3177
3190
  apiKey: process.env.VAIF_SECRET_KEY!,
3178
3191
  });
3179
3192
  }
@@ -3328,6 +3341,7 @@ export async function requireTeamRole(
3328
3341
  # Get these values from https://vaif.studio/app/security/api-keys \u2192 Project Settings \u2192 API Keys
3329
3342
 
3330
3343
  NEXT_PUBLIC_VAIF_API_URL=https://api.vaif.studio
3344
+ NEXT_PUBLIC_VAIF_PROJECT_ID=your-project-id
3331
3345
  NEXT_PUBLIC_VAIF_API_KEY=your-api-key
3332
3346
  VAIF_SECRET_KEY=your-secret-key
3333
3347
 
@@ -3480,6 +3494,7 @@ export const posts = pgTable("posts", {
3480
3494
  // Browser client
3481
3495
  export const vaif = createVaifClient({
3482
3496
  baseUrl: process.env.NEXT_PUBLIC_VAIF_API_URL || 'https://api.vaif.studio',
3497
+ projectId: process.env.NEXT_PUBLIC_VAIF_PROJECT_ID,
3483
3498
  apiKey: process.env.NEXT_PUBLIC_VAIF_API_KEY!,
3484
3499
  });
3485
3500
 
@@ -3487,6 +3502,7 @@ export const vaif = createVaifClient({
3487
3502
  export function createVaifServer() {
3488
3503
  return createVaifClient({
3489
3504
  baseUrl: process.env.NEXT_PUBLIC_VAIF_API_URL || 'https://api.vaif.studio',
3505
+ projectId: process.env.VAIF_PROJECT_ID,
3490
3506
  apiKey: process.env.VAIF_SECRET_KEY!,
3491
3507
  });
3492
3508
  }
@@ -3603,6 +3619,7 @@ function getContentType(fileName: string): string {
3603
3619
  # Get these values from https://vaif.studio/app/security/api-keys \u2192 Project Settings \u2192 API Keys
3604
3620
 
3605
3621
  NEXT_PUBLIC_VAIF_API_URL=https://api.vaif.studio
3622
+ NEXT_PUBLIC_VAIF_PROJECT_ID=your-project-id
3606
3623
  NEXT_PUBLIC_VAIF_API_KEY=your-api-key
3607
3624
  VAIF_SECRET_KEY=your-secret-key
3608
3625
 
@@ -3748,19 +3765,19 @@ export const posts = pgTable("posts", {
3748
3765
 
3749
3766
  return Response.json({ message: \`Hello, \${name}!\` });
3750
3767
  }
3751
- `}]},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"]}};async function oe(i){if(!process.stdin.isTTY||!process.stdout.isTTY)return i;let a=new Set(i.map(e=>b.findIndex(r=>r.name===e)).filter(e=>e>=0)),t=0;return new Promise(e=>{let r=K__default.default.createInterface({input:process.stdin,output:process.stdout});K__default.default.emitKeypressEvents(process.stdin,r),process.stdin.setRawMode&&process.stdin.setRawMode(true);function o(){let l=b.length+2;process.stdout.write(`\x1B[${l}A`),u();}function u(){console.log(d__default.default.bold(`
3752
- ? Which VAIF features do you want to include?`)),b.forEach((l,c)=>{let n=a.has(c)?d__default.default.green("[x]"):"[ ]",s=c===t?d__default.default.cyan("> "):" ";console.log(`${s}${n} ${l.label} ${d__default.default.gray(`(${l.description})`)}`);}),console.log(d__default.default.gray(" (up/down to move, space to toggle, enter to confirm)"));}u(),process.stdin.on("keypress",(l,c)=>{if(c.name==="up"&&t>0)t--,o();else if(c.name==="down"&&t<b.length-1)t++,o();else if(c.name==="space")a.has(t)?a.delete(t):a.add(t),o();else if(c.name==="return"){process.stdin.setRawMode&&process.stdin.setRawMode(false),r.close();let n=[...a].sort().map(s=>b[s].name);e(n.length>0?n:i);}else c.name==="c"&&c.ctrl&&(process.stdin.setRawMode&&process.stdin.setRawMode(false),r.close(),process.exit(0));});})}async function F(i,a={}){let t=ie[i];t||(console.log(d__default.default.red(`
3753
- Unknown template: ${i}`)),console.log(d__default.default.yellow(`Run 'vaif templates' to see available templates.
3754
- `)),process.exit(1));let e;a.features&&a.features.length>0?e=a.features.filter(n=>b.some(s=>s.name===n)):a.addOnly?(console.log(d__default.default.red(`
3755
- No features specified.`)),console.log(d__default.default.yellow("Usage: vaif init --template <name> --add-features <features>")),console.log(d__default.default.gray("Available features: auth, database, realtime, storage, functions")),process.exit(1)):t.featureFiles&&Object.keys(t.featureFiles).length>0?e=await oe(t.defaultFeatures??["database","auth"]):e=t.defaultFeatures??[],a.addOnly?(console.log(""),console.log(d__default.default.bold(`Adding features to ${d__default.default.cyan(t.name)} project...`)),console.log(d__default.default.gray(` Features: ${e.join(", ")}`)),console.log("")):(console.log(""),console.log(d__default.default.bold(`Scaffolding ${d__default.default.cyan(t.name)} template...`)),e.length>0&&console.log(d__default.default.gray(` Features: ${e.join(", ")}`)),console.log(""));let r=a.addOnly?[]:[...t.files];if(t.featureFiles)for(let n of e){let s=t.featureFiles[n];s&&r.push(...s);}let o=0,u=0;for(let n of r){let s=w__default.default.resolve(n.path),m=w__default.default.dirname(s);if(y__default.default.existsSync(m)||y__default.default.mkdirSync(m,{recursive:true}),n.path==="package.json"&&y__default.default.existsSync(s)&&!a.force)try{let p=JSON.parse(y__default.default.readFileSync(s,"utf-8")),g=JSON.parse(n.content),v=L=>{if(!L)return {};let N={};for(let[z,_]of Object.entries(L))!_.startsWith("workspace:")&&!_.startsWith("link:")&&!_.startsWith("file:")&&(N[z]=_);return N};p.dependencies={...v(p.dependencies),...g.dependencies||{}},p.devDependencies={...v(p.devDependencies),...g.devDependencies||{}},g.scripts&&(p.scripts={...p.scripts||{},...g.scripts}),y__default.default.writeFileSync(s,JSON.stringify(p,null,2)+`
3756
- `,"utf-8"),console.log(d__default.default.green(` merge ${n.path} (added dependencies)`)),o++;continue}catch{}if(y__default.default.existsSync(s)&&!a.force){console.log(d__default.default.yellow(` skip ${n.path} (already exists)`)),u++;continue}y__default.default.writeFileSync(s,n.content,"utf-8"),console.log(d__default.default.green(` create ${n.path}`)),o++;}console.log(""),o>0&&console.log(d__default.default.green(`Created ${o} file${o!==1?"s":""}.`)),u>0&&console.log(d__default.default.yellow(`Skipped ${u} file${u!==1?"s":""} (use --force to overwrite).`));let l={auth:{"@vaiftech/auth":"^1.0.0"},database:{},realtime:{},storage:{},functions:{}},c=w__default.default.resolve("package.json");if(y__default.default.existsSync(c)&&e.length>0)try{let n=JSON.parse(y__default.default.readFileSync(c,"utf-8")),s=!1;for(let m of e){let p=l[m];if(p)for(let[g,v]of Object.entries(p))n.dependencies?.[g]||(n.dependencies=n.dependencies||{},n.dependencies[g]=v,s=!0);}s&&y__default.default.writeFileSync(c,JSON.stringify(n,null,2)+`
3757
- `,"utf-8");}catch{}(t.dependencies?.length||t.devDependencies?.length)&&(console.log(""),console.log(d__default.default.bold("Install dependencies:")),t.dependencies?.length&&console.log(d__default.default.cyan(` npm install ${t.dependencies.join(" ")}`)),t.devDependencies?.length&&console.log(d__default.default.cyan(` npm install -D ${t.devDependencies.join(" ")}`))),console.log(""),console.log(d__default.default.bold.green("Project scaffolded successfully!")),console.log(""),console.log(d__default.default.bold(" Next steps:")),t.postInstructions.forEach(n=>{console.log(d__default.default.gray(` ${n}`));}),console.log(""),console.log(d__default.default.gray(" Get your project credentials at https://vaif.studio/app/security/api-keys")),console.log("");}var se={$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(i){if(i.addFeatures){i.template||(console.log(d__default.default.red(`
3758
- --add-features requires --template to know which template to use.`)),console.log(d__default.default.gray("Example: vaif init --template react-spa --add-features functions,storage")),process.exit(1));let e=i.addFeatures.split(",").map(r=>r.trim());await F(i.template,{force:i.force,features:e,addOnly:true});return}let a=H__default.default("Initializing VAIF configuration...").start(),t=w__default.default.resolve("vaif.config.json");y__default.default.existsSync(t)&&!i.force&&(a.fail("vaif.config.json already exists"),console.log(d__default.default.yellow(`
3759
- Use --force to overwrite existing configuration.`)),process.exit(1));try{if(y__default.default.writeFileSync(t,JSON.stringify(se,null,2),"utf-8"),a.succeed("Created vaif.config.json"),i.template){let e=i.features?i.features.split(",").map(r=>r.trim()):void 0;await F(i.template,{force:i.force,features:e});}else {let e=w__default.default.resolve(".env.example");if(y__default.default.existsSync(e)||(y__default.default.writeFileSync(e,`# VAIF Configuration
3768
+ `}]},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"]}};async function le(n){if(!process.stdin.isTTY||!process.stdout.isTTY)return n;let a=new Set(n.map(e=>_.findIndex(i=>i.name===e)).filter(e=>e>=0)),t=0;return new Promise(e=>{let i=B__default.default.createInterface({input:process.stdin,output:process.stdout});B__default.default.emitKeypressEvents(process.stdin,i),process.stdin.setRawMode&&process.stdin.setRawMode(true);function o(){let s=_.length+2;process.stdout.write(`\x1B[${s}A`),c();}function c(){console.log(d__default.default.bold(`
3769
+ ? Which VAIF features do you want to include?`)),_.forEach((s,r)=>{let l=a.has(r)?d__default.default.green("[x]"):"[ ]",p=r===t?d__default.default.cyan("> "):" ";console.log(`${p}${l} ${s.label} ${d__default.default.gray(`(${s.description})`)}`);}),console.log(d__default.default.gray(" (up/down to move, space to toggle, enter to confirm)"));}c(),process.stdin.on("keypress",(s,r)=>{if(r.name==="up"&&t>0)t--,o();else if(r.name==="down"&&t<_.length-1)t++,o();else if(r.name==="space")a.has(t)?a.delete(t):a.add(t),o();else if(r.name==="return"){process.stdin.setRawMode&&process.stdin.setRawMode(false),i.close();let l=[...a].sort().map(p=>_[p].name);e(l.length>0?l:n);}else r.name==="c"&&r.ctrl&&(process.stdin.setRawMode&&process.stdin.setRawMode(false),i.close(),process.exit(0));});})}async function C(n,a={}){let t=se[n];t||(console.log(d__default.default.red(`
3770
+ Unknown template: ${n}`)),console.log(d__default.default.yellow(`Run 'vaif templates' to see available templates.
3771
+ `)),process.exit(1));let e;a.features&&a.features.length>0?e=a.features.filter(u=>_.some(f=>f.name===u)):a.addOnly?(console.log(d__default.default.red(`
3772
+ No features specified.`)),console.log(d__default.default.yellow("Usage: vaif init --template <name> --add-features <features>")),console.log(d__default.default.gray("Available features: auth, database, realtime, storage, functions")),process.exit(1)):t.featureFiles&&Object.keys(t.featureFiles).length>0?e=await le(t.defaultFeatures??["database","auth"]):e=t.defaultFeatures??[],a.addOnly?(console.log(""),console.log(d__default.default.bold(`Adding features to ${d__default.default.cyan(t.name)} project...`)),console.log(d__default.default.gray(` Features: ${e.join(", ")}`)),console.log("")):(console.log(""),console.log(d__default.default.bold(`Scaffolding ${d__default.default.cyan(t.name)} template...`)),e.length>0&&console.log(d__default.default.gray(` Features: ${e.join(", ")}`)),console.log(""));let i=a.addOnly?[]:[...t.files],o=new Set,c=[];if(t.featureFiles)for(let u of e){let f=t.featureFiles[u];if(f)for(let h of f)o.add(h.path),c.push(h);}let s=i.filter(u=>!o.has(u.path)).concat(c),r=0,l=0;for(let u of s){let f=R__default.default.resolve(u.path),h=R__default.default.dirname(f);if(b__default.default.existsSync(h)||b__default.default.mkdirSync(h,{recursive:true}),u.path==="package.json"&&b__default.default.existsSync(f)&&!a.force)try{let v=JSON.parse(b__default.default.readFileSync(f,"utf-8")),I=JSON.parse(u.content),T=U=>{if(!U)return {};let D={};for(let[q,x]of Object.entries(U))!x.startsWith("workspace:")&&!x.startsWith("link:")&&!x.startsWith("file:")&&(D[q]=x);return D};v.dependencies={...T(v.dependencies),...I.dependencies||{}},v.devDependencies={...T(v.devDependencies),...I.devDependencies||{}},I.scripts&&(v.scripts={...v.scripts||{},...I.scripts}),b__default.default.writeFileSync(f,JSON.stringify(v,null,2)+`
3773
+ `,"utf-8"),console.log(d__default.default.green(` merge ${u.path} (added dependencies)`)),r++;continue}catch{}if(b__default.default.existsSync(f)&&!a.force){console.log(d__default.default.yellow(` skip ${u.path} (already exists)`)),l++;continue}b__default.default.writeFileSync(f,u.content,"utf-8"),console.log(d__default.default.green(` create ${u.path}`)),r++;}console.log(""),r>0&&console.log(d__default.default.green(`Created ${r} file${r!==1?"s":""}.`)),l>0&&console.log(d__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:{}},m=R__default.default.resolve("package.json");if(b__default.default.existsSync(m)&&e.length>0)try{let u=JSON.parse(b__default.default.readFileSync(m,"utf-8")),f=!1;for(let h of e){let v=p[h];if(v)for(let[I,T]of Object.entries(v))u.dependencies?.[I]||(u.dependencies=u.dependencies||{},u.dependencies[I]=T,f=!0);}f&&b__default.default.writeFileSync(m,JSON.stringify(u,null,2)+`
3774
+ `,"utf-8");}catch{}(t.dependencies?.length||t.devDependencies?.length)&&(console.log(""),console.log(d__default.default.bold("Install dependencies:")),t.dependencies?.length&&console.log(d__default.default.cyan(` npm install ${t.dependencies.join(" ")}`)),t.devDependencies?.length&&console.log(d__default.default.cyan(` npm install -D ${t.devDependencies.join(" ")}`))),console.log(""),console.log(d__default.default.bold.green("Project scaffolded successfully!")),console.log(""),console.log(d__default.default.bold(" Next steps:")),t.postInstructions.forEach(u=>{console.log(d__default.default.gray(` ${u}`));}),console.log(""),console.log(d__default.default.gray(" Get your project credentials at https://vaif.studio/app/security/api-keys")),console.log("");}var ue={$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 pe(n){if(n.addFeatures){n.template||(console.log(d__default.default.red(`
3775
+ --add-features requires --template to know which template to use.`)),console.log(d__default.default.gray("Example: vaif init --template react-spa --add-features functions,storage")),process.exit(1));let e=n.addFeatures.split(",").map(i=>i.trim());await C(n.template,{force:n.force,features:e,addOnly:true});return}let a=X__default.default("Initializing VAIF configuration...").start(),t=R__default.default.resolve("vaif.config.json");b__default.default.existsSync(t)&&!n.force&&(a.fail("vaif.config.json already exists"),console.log(d__default.default.yellow(`
3776
+ Use --force to overwrite existing configuration.`)),process.exit(1));try{if(b__default.default.writeFileSync(t,JSON.stringify(ue,null,2),"utf-8"),a.succeed("Created vaif.config.json"),n.template){let e=n.features?n.features.split(",").map(i=>i.trim()):void 0;await C(n.template,{force:n.force,features:e});}else {let e=R__default.default.resolve(".env.example");if(b__default.default.existsSync(e)||(b__default.default.writeFileSync(e,`# VAIF Configuration
3760
3777
  DATABASE_URL=postgresql://user:password@localhost:5432/database
3761
3778
  VAIF_API_KEY=your-api-key
3762
- `,"utf-8"),console.log(d__default.default.gray("Created .env.example"))),i.typescript){let r=w__default.default.resolve("src/types");y__default.default.existsSync(r)||(y__default.default.mkdirSync(r,{recursive:!0}),console.log(d__default.default.gray("Created src/types directory")));}console.log(""),console.log(d__default.default.green("VAIF initialized successfully!")),console.log(""),console.log(d__default.default.gray("Next steps:")),console.log(d__default.default.gray(" 1. Update vaif.config.json with your project ID")),console.log(d__default.default.gray(" 2. Set DATABASE_URL in your environment")),console.log(d__default.default.gray(" 3. Run: npx vaif generate")),console.log("");}}catch(e){a.fail("Failed to initialize"),e instanceof Error&&console.error(d__default.default.red(`
3763
- Error: ${e.message}`)),process.exit(1);}}async function Ze(i){let{connectionString:a,schema:t="public"}=i,e=new G__default.default.Client({connectionString:a});await e.connect();try{let r=await e.query(`
3779
+ `,"utf-8"),console.log(d__default.default.gray("Created .env.example"))),n.typescript){let i=R__default.default.resolve("src/types");b__default.default.existsSync(i)||(b__default.default.mkdirSync(i,{recursive:!0}),console.log(d__default.default.gray("Created src/types directory")));}console.log(""),console.log(d__default.default.green("VAIF initialized successfully!")),console.log(""),console.log(d__default.default.gray("Next steps:")),console.log(d__default.default.gray(" 1. Update vaif.config.json with your project ID")),console.log(d__default.default.gray(" 2. Set DATABASE_URL in your environment")),console.log(d__default.default.gray(" 3. Run: npx vaif generate")),console.log("");}}catch(e){a.fail("Failed to initialize"),e instanceof Error&&console.error(d__default.default.red(`
3780
+ Error: ${e.message}`)),process.exit(1);}}async function at(n){let{connectionString:a,schema:t="public"}=n,e=new W__default.default.Client({connectionString:a});await e.connect();try{let i=await e.query(`
3764
3781
  SELECT table_name, table_type
3765
3782
  FROM information_schema.tables
3766
3783
  WHERE table_schema = $1
@@ -3781,7 +3798,7 @@ Error: ${e.message}`)),process.exit(1);}}async function Ze(i){let{connectionStri
3781
3798
  FROM information_schema.columns
3782
3799
  WHERE table_schema = $1
3783
3800
  ORDER BY table_name, ordinal_position
3784
- `,[t]),u=await e.query(`
3801
+ `,[t]),c=await e.query(`
3785
3802
  SELECT
3786
3803
  t.typname as enum_name,
3787
3804
  e.enumlabel as enum_value
@@ -3790,16 +3807,16 @@ Error: ${e.message}`)),process.exit(1);}}async function Ze(i){let{connectionStri
3790
3807
  JOIN pg_namespace n ON n.oid = t.typnamespace
3791
3808
  WHERE n.nspname = $1
3792
3809
  ORDER BY t.typname, e.enumsortorder
3793
- `,[t]),l=new Map;for(let s of r.rows)l.set(s.table_name,[]);for(let s of o.rows){let m=l.get(s.table_name);m&&m.push(s);}let c=new Map;for(let s of u.rows){let m=c.get(s.enum_name)||[];m.push(s.enum_value),c.set(s.enum_name,m);}let n=de(l,c);return W__default.default.format(n,{parser:"typescript",semi:!0,singleQuote:!1,trailingComma:"es5",printWidth:100})}finally{await e.end();}}var R={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",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",point:"{ x: number; y: number }",ARRAY:"unknown[]"};function pe(i,a){let{data_type:t,udt_name:e,is_nullable:r}=i;if(a.has(e)){let l=a.get(e).map(c=>`"${c}"`).join(" | ");return r==="YES"?`(${l}) | null`:l}if(t==="ARRAY"){let u=e.replace(/^_/,"");if(a.has(u)){let n=a.get(u).map(s=>`"${s}"`).join(" | ");return r==="YES"?`(${n})[] | null`:`(${n})[]`}let l=R[u]||"unknown";return r==="YES"?`${l}[] | null`:`${l}[]`}let o=R[t]||R[e]||"unknown";return r==="YES"&&(o=`${o} | null`),o}function C(i){return i.split(/[_\-\s]+/).map(a=>a.charAt(0).toUpperCase()+a.slice(1).toLowerCase()).join("")}function de(i,a){let t=["/**"," * 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(a.size>0){t.push("// ============ ENUMS ============"),t.push("");for(let[r,o]of a){let u=C(r),l=o.map(c=>` | "${c}"`).join(`
3794
- `);t.push(`export type ${u} =
3795
- ${l};`),t.push("");}}t.push("// ============ TABLES ============"),t.push("");let e=[];for(let[r,o]of i){e.push(r);let u=C(r),l=[],c=[],n=[];for(let s of o){let m=pe(s,a),p=s.column_name,g=s.column_default!==null||s.is_identity==="YES",v=s.is_nullable==="YES";l.push(` ${p}: ${m};`),g||s.column_name==="id"?c.push(` ${p}?: ${m.replace(" | null","")} | null;`):v?c.push(` ${p}?: ${m};`):c.push(` ${p}: ${m.replace(" | null","")};`),n.push(` ${p}?: ${m.replace(" | null","")} | null;`);}t.push(`export interface ${u} {
3796
- ${l.join(`
3810
+ `,[t]),s=new Map;for(let p of i.rows)s.set(p.table_name,[]);for(let p of o.rows){let m=s.get(p.table_name);m&&m.push(p);}let r=new Map;for(let p of c.rows){let m=r.get(p.enum_name)||[];m.push(p.enum_value),r.set(p.enum_name,m);}let l=ge(s,r);return Q__default.default.format(l,{parser:"typescript",semi:!0,singleQuote:!1,trailingComma:"es5",printWidth:100})}finally{await e.end();}}var N={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",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",point:"{ x: number; y: number }",ARRAY:"unknown[]"};function fe(n,a){let{data_type:t,udt_name:e,is_nullable:i}=n;if(a.has(e)){let s=a.get(e).map(r=>`"${r}"`).join(" | ");return i==="YES"?`(${s}) | null`:s}if(t==="ARRAY"){let c=e.replace(/^_/,"");if(a.has(c)){let l=a.get(c).map(p=>`"${p}"`).join(" | ");return i==="YES"?`(${l})[] | null`:`(${l})[]`}let s=N[c]||"unknown";return i==="YES"?`${s}[] | null`:`${s}[]`}let o=N[t]||N[e]||"unknown";return i==="YES"&&(o=`${o} | null`),o}function V(n){return n.split(/[_\-\s]+/).map(a=>a.charAt(0).toUpperCase()+a.slice(1).toLowerCase()).join("")}function ge(n,a){let t=["/**"," * 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(a.size>0){t.push("// ============ ENUMS ============"),t.push("");for(let[i,o]of a){let c=V(i),s=o.map(r=>` | "${r}"`).join(`
3811
+ `);t.push(`export type ${c} =
3812
+ ${s};`),t.push("");}}t.push("// ============ TABLES ============"),t.push("");let e=[];for(let[i,o]of n){e.push(i);let c=V(i),s=[],r=[],l=[];for(let p of o){let m=fe(p,a),u=p.column_name,f=p.column_default!==null||p.is_identity==="YES",h=p.is_nullable==="YES";s.push(` ${u}: ${m};`),f||p.column_name==="id"?r.push(` ${u}?: ${m.replace(" | null","")} | null;`):h?r.push(` ${u}?: ${m};`):r.push(` ${u}: ${m.replace(" | null","")};`),l.push(` ${u}?: ${m.replace(" | null","")} | null;`);}t.push(`export interface ${c} {
3813
+ ${s.join(`
3797
3814
  `)}
3798
- }`),t.push(""),t.push(`export interface ${u}Insert {
3799
- ${c.join(`
3815
+ }`),t.push(""),t.push(`export interface ${c}Insert {
3816
+ ${r.join(`
3800
3817
  `)}
3801
- }`),t.push(""),t.push(`export interface ${u}Update {
3802
- ${n.join(`
3818
+ }`),t.push(""),t.push(`export interface ${c}Update {
3819
+ ${l.join(`
3803
3820
  `)}
3804
- }`),t.push("");}t.push("// ============ DATABASE SCHEMA ============"),t.push(""),t.push("export interface Database {");for(let r of e){let o=C(r);t.push(` ${r}: {`),t.push(` Row: ${o};`),t.push(` Insert: ${o}Insert;`),t.push(` Update: ${o}Update;`),t.push(" };");}return t.push("}"),t.push(""),t.push("export type TableName = keyof Database;"),t.push(""),t.push("// ============ HELPER TYPES ============"),t.push(""),t.push('export type Row<T extends TableName> = Database[T]["Row"];'),t.push('export type Insert<T extends TableName> = Database[T]["Insert"];'),t.push('export type Update<T extends TableName> = Database[T]["Update"];'),t.push(""),t.join(`
3805
- `)}exports.generateTypes=ne;exports.generateTypesFromConnection=Ze;exports.initConfig=le;exports.loadConfig=E;
3821
+ }`),t.push("");}t.push("// ============ DATABASE SCHEMA ============"),t.push(""),t.push("export interface Database {");for(let i of e){let o=V(i);t.push(` ${i}: {`),t.push(` Row: ${o};`),t.push(` Insert: ${o}Insert;`),t.push(` Update: ${o}Update;`),t.push(" };");}return t.push("}"),t.push(""),t.push("export type TableName = keyof Database;"),t.push(""),t.push("// ============ HELPER TYPES ============"),t.push(""),t.push('export type Row<T extends TableName> = Database[T]["Row"];'),t.push('export type Insert<T extends TableName> = Database[T]["Insert"];'),t.push('export type Update<T extends TableName> = Database[T]["Update"];'),t.push(""),t.join(`
3822
+ `)}exports.generateTypes=re;exports.generateTypesFromConnection=at;exports.initConfig=pe;exports.loadConfig=S;
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- export{f as generateTypes,h as initConfig,a as loadConfig}from'./chunk-WYTLXCHQ.js';import T from'pg';import $ from'prettier';async function S(p){let{connectionString:a,schema:e="public"}=p,r=new T.Client({connectionString:a});await r.connect();try{let t=await r.query(`
1
+ export{f as generateTypes,h as initConfig,a as loadConfig}from'./chunk-T7GOLIY4.js';import T from'pg';import $ from'prettier';async function S(p){let{connectionString:a,schema:e="public"}=p,r=new T.Client({connectionString:a});await r.connect();try{let t=await r.query(`
2
2
  SELECT table_name, table_type
3
3
  FROM information_schema.tables
4
4
  WHERE table_schema = $1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vaiftech/cli",
3
- "version": "1.7.5",
3
+ "version": "1.8.0",
4
4
  "description": "VAIF CLI - Type generation and development tools",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",