@vaiftech/cli 1.7.1 → 1.7.3
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/README.md +1 -1
- package/dist/{chunk-N7OY2COL.js → chunk-M2UHM7B7.js} +39 -46
- package/dist/cli.cjs +64 -80
- package/dist/cli.js +28 -37
- package/dist/index.cjs +44 -60
- package/dist/index.js +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
'use strict';var v=require('fs'),w=require('path'),
|
|
1
|
+
'use strict';var v=require('fs'),w=require('path'),q=require('dotenv'),G=require('pg'),H=require('ora'),p=require('chalk'),W=require('prettier'),B=require('os'),K=require('readline');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var v__default=/*#__PURE__*/_interopDefault(v);var w__default=/*#__PURE__*/_interopDefault(w);var q__default=/*#__PURE__*/_interopDefault(q);var G__default=/*#__PURE__*/_interopDefault(G);var H__default=/*#__PURE__*/_interopDefault(H);var p__default=/*#__PURE__*/_interopDefault(p);var W__default=/*#__PURE__*/_interopDefault(W);var B__default=/*#__PURE__*/_interopDefault(B);var K__default=/*#__PURE__*/_interopDefault(K);q__default.default.config();async function E(i){let a=w__default.default.resolve(i);if(!v__default.default.existsSync(a))return null;try{let t=v__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(B__default.default.homedir(),".vaif"),k=w__default.default.join(Y,"auth.json");process.env.VAIF_API_URL||"https://api.vaif.studio";function O(){if(!v__default.default.existsSync(k))return null;try{let i=v__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(`
|
|
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
|
|
7
|
+
`,[a]),e=await i.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]),
|
|
22
|
+
`,[a]),r=await i.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]),
|
|
38
|
+
`,[a]),o=await i.query(`
|
|
39
39
|
SELECT
|
|
40
40
|
t.typname as enum_name,
|
|
41
41
|
e.enumlabel as enum_value
|
|
@@ -44,22 +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]),
|
|
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 S={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=S[u]||"unknown";return r==="YES"?`${l}[] | null`:`${l}[]`}let o=S[t]||S[e]||"unknown";return r==="YES"&&(o=`${o} | null`),o}function x(i){return i.split(/[_\-\s]+/).map(a=>a.charAt(0).toUpperCase()+a.slice(1).toLowerCase()).join("")}function ee(i,a){let t=x(i),e=a.map(r=>` | "${r}"`).join(`
|
|
48
48
|
`);return `export type ${t} =
|
|
49
|
-
${e};`}function
|
|
50
|
-
${i.join(`
|
|
51
|
-
`)}
|
|
52
|
-
}`,l=`export interface ${e}Insert {
|
|
49
|
+
${e};`}function te(i,a,t){let e=x(i),r=[],o=[],u=[];for(let s of a){let m=Z(s,t),d=s.column_name,g=s.column_default!==null||s.is_identity==="YES",y=s.is_nullable==="YES";r.push(` ${d}: ${m};`),g||s.column_name==="id"?o.push(` ${d}?: ${m.replace(" | null","")} | null;`):y?o.push(` ${d}?: ${m};`):o.push(` ${d}: ${m.replace(" | null","")};`),u.push(` ${d}?: ${m.replace(" | null","")} | null;`);}let l=`export interface ${e} {
|
|
53
50
|
${r.join(`
|
|
54
51
|
`)}
|
|
55
|
-
}`,
|
|
56
|
-
${
|
|
52
|
+
}`,c=`export interface ${e}Insert {
|
|
53
|
+
${o.join(`
|
|
57
54
|
`)}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
55
|
+
}`,n=`export interface ${e}Update {
|
|
56
|
+
${u.join(`
|
|
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=x(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 d=new G__default.default.Client({connectionString:e});await d.connect(),a.text="Introspecting schema...",{tables:o,enums:u,foreignKeys:l}=await Q(d,i.schema),await d.end();}else {let d=O();(!d||!d.token)&&(a.fail("No database connection and not logged in"),console.log(p__default.default.yellow(`
|
|
60
|
+
Either:`)),console.log(p__default.default.gray(" 1. Run `vaif login` to authenticate (no DATABASE_URL needed)")),console.log(p__default.default.gray(" 2. Set DATABASE_URL in your .env file")),console.log(p__default.default.gray(" 3. Pass --connection postgresql://user:pass@host:5432/db")),process.exit(1));let g=t?.projectId||process.env.VAIF_PROJECT_ID||d.projectId;g||(a.fail("No project ID specified"),console.log(p__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(d.token,g);}if(o.size===0){a.warn("No tables found"),console.log(p__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(p__default.default.gray("\u2500".repeat(60))),console.log(n),console.log(p__default.default.gray("\u2500".repeat(60)));return}let s=w__default.default.resolve(i.output),m=w__default.default.dirname(s);v__default.default.existsSync(m)||v__default.default.mkdirSync(m,{recursive:!0}),v__default.default.writeFileSync(s,n,"utf-8"),a.succeed(`Generated types for ${o.size} tables \u2192 ${p__default.default.cyan(i.output)}`),console.log(""),console.log(p__default.default.green("Generated:")),console.log(p__default.default.gray(` Tables: ${o.size}`)),console.log(p__default.default.gray(` Enums: ${u.size}`)),console.log(""),console.log(p__default.default.gray("Import in your code:")),console.log(p__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(p__default.default.red(`
|
|
63
|
+
Error: ${t.message}`)),t.message.includes("ECONNREFUSED")&&console.log(p__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:`{
|
|
63
65
|
"name": "my-vaif-app",
|
|
64
66
|
"private": true,
|
|
65
67
|
"version": "0.1.0",
|
|
@@ -173,10 +175,7 @@ NEXT_PUBLIC_VAIF_API_URL=https://api.vaif.studio
|
|
|
173
175
|
NEXT_PUBLIC_VAIF_API_KEY=your-api-key
|
|
174
176
|
VAIF_SECRET_KEY=your-secret-key
|
|
175
177
|
|
|
176
|
-
#
|
|
177
|
-
# DATABASE_URL=postgresql://user:password@host:5432/dbname
|
|
178
|
-
|
|
179
|
-
# CLI uses these (non-prefixed) for vaif db push, vaif secrets, etc.
|
|
178
|
+
# CLI project ID (for vaif generate, vaif pull, vaif secrets, etc.)
|
|
180
179
|
VAIF_PROJECT_ID=your-project-id
|
|
181
180
|
`},{path:".gitignore",content:`node_modules
|
|
182
181
|
.next
|
|
@@ -671,9 +670,6 @@ interface ImportMeta {
|
|
|
671
670
|
|
|
672
671
|
VITE_VAIF_API_URL=https://api.vaif.studio
|
|
673
672
|
VITE_VAIF_API_KEY=your-api-key
|
|
674
|
-
|
|
675
|
-
# Database connection (for vaif generate, vaif db push)
|
|
676
|
-
# DATABASE_URL=postgresql://user:password@host:5432/dbname
|
|
677
673
|
`},{path:".gitignore",content:`node_modules
|
|
678
674
|
dist
|
|
679
675
|
.env
|
|
@@ -2668,9 +2664,6 @@ export async function deleteTodo(id: string): Promise<void> {
|
|
|
2668
2664
|
|
|
2669
2665
|
VITE_VAIF_API_URL=https://api.vaif.studio
|
|
2670
2666
|
VITE_VAIF_API_KEY=your-api-key
|
|
2671
|
-
|
|
2672
|
-
# Database connection (for vaif generate, vaif db push)
|
|
2673
|
-
# DATABASE_URL=postgresql://user:password@host:5432/dbname
|
|
2674
2667
|
`},{path:"README.md",content:`# Todo App \u2014 VAIF Starter
|
|
2675
2668
|
|
|
2676
2669
|
A simple React todo application for learning [VAIF Studio](https://vaif.studio) basics, including typed database queries and CRUD operations.
|
|
@@ -2949,9 +2942,6 @@ export function useRealtimeMessages({
|
|
|
2949
2942
|
|
|
2950
2943
|
VITE_VAIF_API_URL=https://api.vaif.studio
|
|
2951
2944
|
VITE_VAIF_API_KEY=your-api-key
|
|
2952
|
-
|
|
2953
|
-
# Database connection (for vaif generate, vaif db push)
|
|
2954
|
-
# DATABASE_URL=postgresql://user:password@host:5432/dbname
|
|
2955
2945
|
`},{path:"README.md",content:`# Realtime Chat \u2014 VAIF Starter
|
|
2956
2946
|
|
|
2957
2947
|
A React chat application with live messaging powered by [VAIF Studio](https://vaif.studio) realtime subscriptions.
|
|
@@ -3267,10 +3257,7 @@ NEXT_PUBLIC_VAIF_API_URL=https://api.vaif.studio
|
|
|
3267
3257
|
NEXT_PUBLIC_VAIF_API_KEY=your-api-key
|
|
3268
3258
|
VAIF_SECRET_KEY=your-secret-key
|
|
3269
3259
|
|
|
3270
|
-
#
|
|
3271
|
-
# DATABASE_URL=postgresql://user:password@host:5432/dbname
|
|
3272
|
-
|
|
3273
|
-
# CLI uses these (non-prefixed) for vaif db push, vaif secrets, etc.
|
|
3260
|
+
# CLI project ID (for vaif generate, vaif pull, vaif secrets, etc.)
|
|
3274
3261
|
VAIF_PROJECT_ID=your-project-id
|
|
3275
3262
|
`},{path:"README.md",content:`# SaaS Starter \u2014 VAIF Studio
|
|
3276
3263
|
|
|
@@ -3545,10 +3532,7 @@ NEXT_PUBLIC_VAIF_API_URL=https://api.vaif.studio
|
|
|
3545
3532
|
NEXT_PUBLIC_VAIF_API_KEY=your-api-key
|
|
3546
3533
|
VAIF_SECRET_KEY=your-secret-key
|
|
3547
3534
|
|
|
3548
|
-
#
|
|
3549
|
-
# DATABASE_URL=postgresql://user:password@host:5432/dbname
|
|
3550
|
-
|
|
3551
|
-
# CLI uses these (non-prefixed) for vaif db push, vaif secrets, etc.
|
|
3535
|
+
# CLI project ID (for vaif generate, vaif pull, vaif secrets, etc.)
|
|
3552
3536
|
VAIF_PROJECT_ID=your-project-id
|
|
3553
3537
|
`},{path:"README.md",content:`# E-commerce API \u2014 VAIF Studio
|
|
3554
3538
|
|
|
@@ -3690,25 +3674,25 @@ export const posts = pgTable("posts", {
|
|
|
3690
3674
|
|
|
3691
3675
|
return Response.json({ message: \`Hello, \${name}!\` });
|
|
3692
3676
|
}
|
|
3693
|
-
`}]},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
|
|
3694
|
-
? Which VAIF features do you want to include?`)),
|
|
3695
|
-
Unknown template: ${
|
|
3696
|
-
`)),process.exit(1));let e;a.features&&a.features.length>0?e=a.features.filter(
|
|
3697
|
-
No features specified.`)),console.log(
|
|
3698
|
-
`,"utf-8"),console.log(
|
|
3699
|
-
`,"utf-8");}catch{}(t.dependencies?.length||t.devDependencies?.length)&&(console.log(""),console.log(
|
|
3700
|
-
--add-features requires --template to know which template to use.`)),console.log(
|
|
3701
|
-
Use --force to overwrite existing configuration.`)),process.exit(1));try{if(v__default.default.writeFileSync(t,JSON.stringify(
|
|
3677
|
+
`}]},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(p__default.default.bold(`
|
|
3678
|
+
? Which VAIF features do you want to include?`)),b.forEach((l,c)=>{let n=a.has(c)?p__default.default.green("[x]"):"[ ]",s=c===t?p__default.default.cyan("> "):" ";console.log(`${s}${n} ${l.label} ${p__default.default.gray(`(${l.description})`)}`);}),console.log(p__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(p__default.default.red(`
|
|
3679
|
+
Unknown template: ${i}`)),console.log(p__default.default.yellow(`Run 'vaif templates' to see available templates.
|
|
3680
|
+
`)),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(p__default.default.red(`
|
|
3681
|
+
No features specified.`)),console.log(p__default.default.yellow("Usage: vaif init --template <name> --add-features <features>")),console.log(p__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(p__default.default.bold(`Adding features to ${p__default.default.cyan(t.name)} project...`)),console.log(p__default.default.gray(` Features: ${e.join(", ")}`)),console.log("")):(console.log(""),console.log(p__default.default.bold(`Scaffolding ${p__default.default.cyan(t.name)} template...`)),e.length>0&&console.log(p__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(v__default.default.existsSync(m)||v__default.default.mkdirSync(m,{recursive:true}),n.path==="package.json"&&v__default.default.existsSync(s)&&!a.force)try{let d=JSON.parse(v__default.default.readFileSync(s,"utf-8")),g=JSON.parse(n.content),y=N=>{if(!N)return {};let L={};for(let[z,_]of Object.entries(N))!_.startsWith("workspace:")&&!_.startsWith("link:")&&!_.startsWith("file:")&&(L[z]=_);return L};d.dependencies={...y(d.dependencies),...g.dependencies||{}},d.devDependencies={...y(d.devDependencies),...g.devDependencies||{}},g.scripts&&(d.scripts={...d.scripts||{},...g.scripts}),v__default.default.writeFileSync(s,JSON.stringify(d,null,2)+`
|
|
3682
|
+
`,"utf-8"),console.log(p__default.default.green(` merge ${n.path} (added dependencies)`)),o++;continue}catch{}if(v__default.default.existsSync(s)&&!a.force){console.log(p__default.default.yellow(` skip ${n.path} (already exists)`)),u++;continue}v__default.default.writeFileSync(s,n.content,"utf-8"),console.log(p__default.default.green(` create ${n.path}`)),o++;}console.log(""),o>0&&console.log(p__default.default.green(`Created ${o} file${o!==1?"s":""}.`)),u>0&&console.log(p__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(v__default.default.existsSync(c)&&e.length>0)try{let n=JSON.parse(v__default.default.readFileSync(c,"utf-8")),s=!1;for(let m of e){let d=l[m];if(d)for(let[g,y]of Object.entries(d))n.dependencies?.[g]||(n.dependencies=n.dependencies||{},n.dependencies[g]=y,s=!0);}s&&v__default.default.writeFileSync(c,JSON.stringify(n,null,2)+`
|
|
3683
|
+
`,"utf-8");}catch{}(t.dependencies?.length||t.devDependencies?.length)&&(console.log(""),console.log(p__default.default.bold("Install dependencies:")),t.dependencies?.length&&console.log(p__default.default.cyan(` npm install ${t.dependencies.join(" ")}`)),t.devDependencies?.length&&console.log(p__default.default.cyan(` npm install -D ${t.devDependencies.join(" ")}`))),console.log(""),console.log(p__default.default.bold.green("Project scaffolded successfully!")),console.log(""),console.log(p__default.default.bold(" Next steps:")),t.postInstructions.forEach(n=>{console.log(p__default.default.gray(` ${n}`));}),console.log(""),console.log(p__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(p__default.default.red(`
|
|
3684
|
+
--add-features requires --template to know which template to use.`)),console.log(p__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");v__default.default.existsSync(t)&&!i.force&&(a.fail("vaif.config.json already exists"),console.log(p__default.default.yellow(`
|
|
3685
|
+
Use --force to overwrite existing configuration.`)),process.exit(1));try{if(v__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(v__default.default.existsSync(e)||(v__default.default.writeFileSync(e,`# VAIF Configuration
|
|
3702
3686
|
DATABASE_URL=postgresql://user:password@localhost:5432/database
|
|
3703
3687
|
VAIF_API_KEY=your-api-key
|
|
3704
|
-
`,"utf-8"),console.log(
|
|
3705
|
-
Error: ${e.message}`)),process.exit(1);}}async function
|
|
3688
|
+
`,"utf-8"),console.log(p__default.default.gray("Created .env.example"))),i.typescript){let r=w__default.default.resolve("src/types");v__default.default.existsSync(r)||(v__default.default.mkdirSync(r,{recursive:!0}),console.log(p__default.default.gray("Created src/types directory")));}console.log(""),console.log(p__default.default.green("VAIF initialized successfully!")),console.log(""),console.log(p__default.default.gray("Next steps:")),console.log(p__default.default.gray(" 1. Update vaif.config.json with your project ID")),console.log(p__default.default.gray(" 2. Set DATABASE_URL in your environment")),console.log(p__default.default.gray(" 3. Run: npx vaif generate")),console.log("");}}catch(e){a.fail("Failed to initialize"),e instanceof Error&&console.error(p__default.default.red(`
|
|
3689
|
+
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(`
|
|
3706
3690
|
SELECT table_name, table_type
|
|
3707
3691
|
FROM information_schema.tables
|
|
3708
3692
|
WHERE table_schema = $1
|
|
3709
3693
|
AND table_type = 'BASE TABLE'
|
|
3710
3694
|
ORDER BY table_name
|
|
3711
|
-
`,[t]),
|
|
3695
|
+
`,[t]),o=await e.query(`
|
|
3712
3696
|
SELECT
|
|
3713
3697
|
table_name,
|
|
3714
3698
|
column_name,
|
|
@@ -3723,7 +3707,7 @@ Error: ${e.message}`)),process.exit(1);}}async function Le(n){let{connectionStri
|
|
|
3723
3707
|
FROM information_schema.columns
|
|
3724
3708
|
WHERE table_schema = $1
|
|
3725
3709
|
ORDER BY table_name, ordinal_position
|
|
3726
|
-
`,[t]),
|
|
3710
|
+
`,[t]),u=await e.query(`
|
|
3727
3711
|
SELECT
|
|
3728
3712
|
t.typname as enum_name,
|
|
3729
3713
|
e.enumlabel as enum_value
|
|
@@ -3732,16 +3716,16 @@ Error: ${e.message}`)),process.exit(1);}}async function Le(n){let{connectionStri
|
|
|
3732
3716
|
JOIN pg_namespace n ON n.oid = t.typnamespace
|
|
3733
3717
|
WHERE n.nspname = $1
|
|
3734
3718
|
ORDER BY t.typname, e.enumsortorder
|
|
3735
|
-
`,[t]),
|
|
3736
|
-
`);t.push(`export type ${
|
|
3737
|
-
${
|
|
3738
|
-
${u.join(`
|
|
3739
|
-
`)}
|
|
3740
|
-
}`),t.push(""),t.push(`export interface ${c}Insert {
|
|
3719
|
+
`,[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=pe(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 de(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 pe(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(`
|
|
3720
|
+
`);t.push(`export type ${u} =
|
|
3721
|
+
${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=de(s,a),d=s.column_name,g=s.column_default!==null||s.is_identity==="YES",y=s.is_nullable==="YES";l.push(` ${d}: ${m};`),g||s.column_name==="id"?c.push(` ${d}?: ${m.replace(" | null","")} | null;`):y?c.push(` ${d}?: ${m};`):c.push(` ${d}: ${m.replace(" | null","")};`),n.push(` ${d}?: ${m.replace(" | null","")} | null;`);}t.push(`export interface ${u} {
|
|
3741
3722
|
${l.join(`
|
|
3742
3723
|
`)}
|
|
3743
|
-
}`),t.push(""),t.push(`export interface ${
|
|
3744
|
-
${
|
|
3724
|
+
}`),t.push(""),t.push(`export interface ${u}Insert {
|
|
3725
|
+
${c.join(`
|
|
3726
|
+
`)}
|
|
3727
|
+
}`),t.push(""),t.push(`export interface ${u}Update {
|
|
3728
|
+
${n.join(`
|
|
3745
3729
|
`)}
|
|
3746
|
-
}`),t.push("");}t.push("// ============ DATABASE SCHEMA ============"),t.push(""),t.push("export interface Database {");for(let
|
|
3747
|
-
`)}exports.generateTypes=
|
|
3730
|
+
}`),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(`
|
|
3731
|
+
`)}exports.generateTypes=ne;exports.generateTypesFromConnection=Ze;exports.initConfig=le;exports.loadConfig=E;
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export{
|
|
1
|
+
export{f as generateTypes,h as initConfig,a as loadConfig}from'./chunk-M2UHM7B7.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
|