@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/README.md +29 -1
- package/dist/{chunk-WYTLXCHQ.js → chunk-T7GOLIY4.js} +52 -35
- package/dist/cli.cjs +271 -61
- package/dist/cli.js +225 -32
- package/dist/index.cjs +55 -38
- package/dist/index.js +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
'use strict';var
|
|
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
|
|
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]),
|
|
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
|
|
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]),
|
|
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
|
|
50
|
-
${
|
|
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
|
-
}`,
|
|
52
|
+
}`,r=`export interface ${e}Insert {
|
|
53
53
|
${o.join(`
|
|
54
54
|
`)}
|
|
55
|
-
}`,
|
|
56
|
-
${
|
|
55
|
+
}`,l=`export interface ${e}Update {
|
|
56
|
+
${c.join(`
|
|
57
57
|
`)}
|
|
58
|
-
}`;return {base:
|
|
59
|
-
`)}async function
|
|
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
|
|
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:
|
|
62
|
-
Push a migration first: vaif db push`));return}a.text=`Generating types for ${o.size} tables...`;let
|
|
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
|
|
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
|
|
3752
|
-
? Which VAIF features do you want to include?`)),
|
|
3753
|
-
Unknown template: ${
|
|
3754
|
-
`)),process.exit(1));let e;a.features&&a.features.length>0?e=a.features.filter(
|
|
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
|
|
3756
|
-
`,"utf-8"),console.log(d__default.default.green(` merge ${
|
|
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(
|
|
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=
|
|
3759
|
-
Use --force to overwrite existing configuration.`)),process.exit(1));try{if(
|
|
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"))),
|
|
3763
|
-
Error: ${e.message}`)),process.exit(1);}}async function
|
|
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]),
|
|
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]),
|
|
3794
|
-
`);t.push(`export type ${
|
|
3795
|
-
${
|
|
3796
|
-
${
|
|
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 ${
|
|
3799
|
-
${
|
|
3815
|
+
}`),t.push(""),t.push(`export interface ${c}Insert {
|
|
3816
|
+
${r.join(`
|
|
3800
3817
|
`)}
|
|
3801
|
-
}`),t.push(""),t.push(`export interface ${
|
|
3802
|
-
${
|
|
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
|
|
3805
|
-
`)}exports.generateTypes=
|
|
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-
|
|
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
|