@vaiftech/cli 1.9.7 → 1.9.9
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 +4 -2
- package/dist/{chunk-T7GOLIY4.js → chunk-KHEM3PLW.js} +20 -20
- package/dist/cli.cjs +199 -70
- package/dist/cli.js +157 -28
- package/dist/index.cjs +39 -39
- package/dist/index.js +1 -1
- package/package.json +10 -10
package/dist/index.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
'use strict';var b=require('fs'),R=require('path'),G=require('dotenv'),W=require('pg'),X=require('ora'),
|
|
1
|
+
'use strict';var b=require('fs'),R=require('path'),G=require('dotenv'),W=require('pg'),X=require('ora'),p=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 p__default=/*#__PURE__*/_interopDefault(p);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
|
|
@@ -44,9 +44,9 @@
|
|
|
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]),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(
|
|
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(d=>`"${d}"`).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 ie(n,a,t){let e=P(n),i=[],o=[],c=[];for(let
|
|
49
|
+
${e};`}function ie(n,a,t){let e=P(n),i=[],o=[],c=[];for(let d of a){let m=ae(d,t),u=d.column_name,f=d.column_default!==null||d.is_identity==="YES",h=d.is_nullable==="YES";i.push(` ${u}: ${m};`),f||d.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
50
|
${i.join(`
|
|
51
51
|
`)}
|
|
52
52
|
}`,r=`export interface ${e}Insert {
|
|
@@ -56,11 +56,11 @@ ${o.join(`
|
|
|
56
56
|
${c.join(`
|
|
57
57
|
`)}
|
|
58
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(
|
|
60
|
-
Either:`)),console.log(
|
|
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(
|
|
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(
|
|
63
|
-
Error: ${t.message}`)),t.message.includes("ECONNREFUSED")&&console.log(
|
|
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(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 f=t?.projectId||process.env.VAIF_PROJECT_ID||u.projectId;f||(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:c,foreignKeys:s}=await ee(u.token,f);}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 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(p__default.default.gray("\u2500".repeat(60))),console.log(l),console.log(p__default.default.gray("\u2500".repeat(60)));return}let d=R__default.default.resolve(n.output),m=R__default.default.dirname(d);b__default.default.existsSync(m)||b__default.default.mkdirSync(m,{recursive:!0}),b__default.default.writeFileSync(d,l,"utf-8"),a.succeed(`Generated types for ${o.size} tables \u2192 ${p__default.default.cyan(n.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: ${c.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 "${n.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
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,
|
|
@@ -171,7 +171,7 @@ export function createVaifServer() {
|
|
|
171
171
|
});
|
|
172
172
|
}
|
|
173
173
|
`},{path:".env.local.example",content:`# VAIF Configuration
|
|
174
|
-
# Get these values from https://vaif.studio/
|
|
174
|
+
# Get these values from https://console.vaif.studio/security/api-keys \u2192 Project Settings \u2192 API Keys
|
|
175
175
|
|
|
176
176
|
NEXT_PUBLIC_VAIF_API_URL=https://api.vaif.studio
|
|
177
177
|
NEXT_PUBLIC_VAIF_PROJECT_ID=your-project-id
|
|
@@ -212,7 +212,7 @@ A full-stack Next.js application powered by [VAIF Studio](https://vaif.studio),
|
|
|
212
212
|
cp .env.local.example .env.local
|
|
213
213
|
\\\`\\\`\\\`
|
|
214
214
|
|
|
215
|
-
Get your Project ID, API Key, and Secret Key from <https://vaif.studio/
|
|
215
|
+
Get your Project ID, API Key, and Secret Key from <https://console.vaif.studio/security/api-keys> under **Project Settings > API Keys**.
|
|
216
216
|
|
|
217
217
|
3. **Install and log in to the VAIF CLI**
|
|
218
218
|
|
|
@@ -686,7 +686,7 @@ interface ImportMeta {
|
|
|
686
686
|
readonly env: ImportMetaEnv;
|
|
687
687
|
}
|
|
688
688
|
`},{path:".env.example",content:`# VAIF Configuration
|
|
689
|
-
# Get these values from https://vaif.studio/
|
|
689
|
+
# Get these values from https://console.vaif.studio/security/api-keys
|
|
690
690
|
|
|
691
691
|
VITE_VAIF_API_URL=https://api.vaif.studio
|
|
692
692
|
VITE_VAIF_PROJECT_ID=your-project-id
|
|
@@ -720,7 +720,7 @@ A single-page React application built with [Vite](https://vite.dev/) and powered
|
|
|
720
720
|
cp .env.example .env
|
|
721
721
|
\\\`\\\`\\\`
|
|
722
722
|
|
|
723
|
-
Get your Project ID and API Key from <https://vaif.studio/
|
|
723
|
+
Get your Project ID and API Key from <https://console.vaif.studio/security/api-keys> under **Project Settings > API Keys**.
|
|
724
724
|
|
|
725
725
|
3. **Install and log in to the VAIF CLI**
|
|
726
726
|
|
|
@@ -1243,7 +1243,7 @@ An iOS/macOS application powered by [VAIF Studio](https://vaif.studio), using th
|
|
|
1243
1243
|
<string>your-anon-key</string>
|
|
1244
1244
|
\\\`\\\`\\\`
|
|
1245
1245
|
|
|
1246
|
-
Get your credentials from <https://vaif.studio/
|
|
1246
|
+
Get your credentials from <https://console.vaif.studio/security/api-keys> under **Project Settings > API Keys**.
|
|
1247
1247
|
|
|
1248
1248
|
3. **Install and log in to the VAIF CLI** (for type generation)
|
|
1249
1249
|
|
|
@@ -1372,7 +1372,7 @@ export const vaif = createExpoClient({
|
|
|
1372
1372
|
realtime: { enabled: true },
|
|
1373
1373
|
});
|
|
1374
1374
|
`},{path:".env.example",content:`# VAIF Configuration
|
|
1375
|
-
# Get these values from https://vaif.studio/
|
|
1375
|
+
# Get these values from https://console.vaif.studio/security/api-keys \u2192 Project Settings \u2192 API Keys
|
|
1376
1376
|
|
|
1377
1377
|
EXPO_PUBLIC_VAIF_PROJECT_ID=your-project-id
|
|
1378
1378
|
EXPO_PUBLIC_VAIF_API_KEY=your-anon-key
|
|
@@ -1409,7 +1409,7 @@ A React Native / Expo mobile application powered by [VAIF Studio](https://vaif.s
|
|
|
1409
1409
|
cp .env.example .env
|
|
1410
1410
|
\\\`\\\`\\\`
|
|
1411
1411
|
|
|
1412
|
-
Get your Project ID and API Key from <https://vaif.studio/
|
|
1412
|
+
Get your Project ID and API Key from <https://console.vaif.studio/security/api-keys> under **Project Settings > API Keys**.
|
|
1413
1413
|
|
|
1414
1414
|
3. **Install and log in to the VAIF CLI**
|
|
1415
1415
|
|
|
@@ -1844,7 +1844,7 @@ A Flutter application powered by [VAIF Studio](https://vaif.studio), with Dart c
|
|
|
1844
1844
|
cp .env.example .env
|
|
1845
1845
|
\\\`\\\`\\\`
|
|
1846
1846
|
|
|
1847
|
-
Get your Project ID and API Key from <https://vaif.studio/
|
|
1847
|
+
Get your Project ID and API Key from <https://console.vaif.studio/security/api-keys> under **Project Settings > API Keys**.
|
|
1848
1848
|
|
|
1849
1849
|
3. **Install and log in to the VAIF CLI** (for schema and type generation)
|
|
1850
1850
|
|
|
@@ -2102,7 +2102,7 @@ fastapi>=0.110.0
|
|
|
2102
2102
|
uvicorn[standard]>=0.27.0
|
|
2103
2103
|
python-dotenv>=1.0.0
|
|
2104
2104
|
`},{path:".env.example",content:`# VAIF Configuration
|
|
2105
|
-
# Get these values from https://vaif.studio/
|
|
2105
|
+
# Get these values from https://console.vaif.studio/security/api-keys \u2192 Project Settings \u2192 API Keys
|
|
2106
2106
|
|
|
2107
2107
|
VAIF_PROJECT_ID=your-project-id
|
|
2108
2108
|
VAIF_API_KEY=your-anon-key
|
|
@@ -2144,7 +2144,7 @@ A FastAPI backend application powered by [VAIF Studio](https://vaif.studio), wit
|
|
|
2144
2144
|
cp .env.example .env
|
|
2145
2145
|
\\\`\\\`\\\`
|
|
2146
2146
|
|
|
2147
|
-
Get your Project ID, API Key, and Secret Key from <https://vaif.studio/
|
|
2147
|
+
Get your Project ID, API Key, and Secret Key from <https://console.vaif.studio/security/api-keys> under **Project Settings > API Keys**.
|
|
2148
2148
|
|
|
2149
2149
|
4. **Install and log in to the VAIF CLI**
|
|
2150
2150
|
|
|
@@ -2467,7 +2467,7 @@ A Go backend API powered by [VAIF Studio](https://vaif.studio), with HTTP handle
|
|
|
2467
2467
|
cp .env.example .env
|
|
2468
2468
|
\\\`\\\`\\\`
|
|
2469
2469
|
|
|
2470
|
-
Get your Project ID, API Key, and Secret Key from <https://vaif.studio/
|
|
2470
|
+
Get your Project ID, API Key, and Secret Key from <https://console.vaif.studio/security/api-keys> under **Project Settings > API Keys**.
|
|
2471
2471
|
|
|
2472
2472
|
3. **Install and log in to the VAIF CLI**
|
|
2473
2473
|
|
|
@@ -2742,7 +2742,7 @@ export async function deleteTodo(id: string): Promise<void> {
|
|
|
2742
2742
|
if (error) throw error;
|
|
2743
2743
|
}
|
|
2744
2744
|
`},{path:".env.example",content:`# VAIF Configuration
|
|
2745
|
-
# Get these values from https://vaif.studio/
|
|
2745
|
+
# Get these values from https://console.vaif.studio/security/api-keys
|
|
2746
2746
|
|
|
2747
2747
|
VITE_VAIF_API_URL=https://api.vaif.studio
|
|
2748
2748
|
VITE_VAIF_PROJECT_ID=your-project-id
|
|
@@ -2771,7 +2771,7 @@ A simple React todo application for learning [VAIF Studio](https://vaif.studio)
|
|
|
2771
2771
|
cp .env.example .env
|
|
2772
2772
|
\\\`\\\`\\\`
|
|
2773
2773
|
|
|
2774
|
-
Get your Project ID and API Key from <https://vaif.studio/
|
|
2774
|
+
Get your Project ID and API Key from <https://console.vaif.studio/security/api-keys> under **Project Settings > API Keys**.
|
|
2775
2775
|
|
|
2776
2776
|
3. **Install and log in to the VAIF CLI**
|
|
2777
2777
|
|
|
@@ -3022,7 +3022,7 @@ export function useRealtimeMessages({
|
|
|
3022
3022
|
return { messages, isLoading, error, refresh };
|
|
3023
3023
|
}
|
|
3024
3024
|
`},{path:".env.example",content:`# VAIF Configuration
|
|
3025
|
-
# Get these values from https://vaif.studio/
|
|
3025
|
+
# Get these values from https://console.vaif.studio/security/api-keys
|
|
3026
3026
|
|
|
3027
3027
|
VITE_VAIF_API_URL=https://api.vaif.studio
|
|
3028
3028
|
VITE_VAIF_PROJECT_ID=your-project-id
|
|
@@ -3051,7 +3051,7 @@ A React chat application with live messaging powered by [VAIF Studio](https://va
|
|
|
3051
3051
|
cp .env.example .env
|
|
3052
3052
|
\\\`\\\`\\\`
|
|
3053
3053
|
|
|
3054
|
-
Get your Project ID and API Key from <https://vaif.studio/
|
|
3054
|
+
Get your Project ID and API Key from <https://console.vaif.studio/security/api-keys> under **Project Settings > API Keys**.
|
|
3055
3055
|
|
|
3056
3056
|
3. **Install and log in to the VAIF CLI**
|
|
3057
3057
|
|
|
@@ -3338,7 +3338,7 @@ export async function requireTeamRole(
|
|
|
3338
3338
|
return member as TeamMember;
|
|
3339
3339
|
}
|
|
3340
3340
|
`},{path:".env.example",content:`# VAIF Configuration
|
|
3341
|
-
# Get these values from https://vaif.studio/
|
|
3341
|
+
# Get these values from https://console.vaif.studio/security/api-keys \u2192 Project Settings \u2192 API Keys
|
|
3342
3342
|
|
|
3343
3343
|
NEXT_PUBLIC_VAIF_API_URL=https://api.vaif.studio
|
|
3344
3344
|
NEXT_PUBLIC_VAIF_PROJECT_ID=your-project-id
|
|
@@ -3371,7 +3371,7 @@ A full SaaS starter kit powered by [VAIF Studio](https://vaif.studio) with authe
|
|
|
3371
3371
|
cp .env.example .env.local
|
|
3372
3372
|
\\\`\\\`\\\`
|
|
3373
3373
|
|
|
3374
|
-
Get your Project ID, API Key, and Secret Key from <https://vaif.studio/
|
|
3374
|
+
Get your Project ID, API Key, and Secret Key from <https://console.vaif.studio/security/api-keys> under **Project Settings > API Keys**.
|
|
3375
3375
|
|
|
3376
3376
|
3. **Install and log in to the VAIF CLI**
|
|
3377
3377
|
|
|
@@ -3616,7 +3616,7 @@ function getContentType(fileName: string): string {
|
|
|
3616
3616
|
return mimeTypes[ext ?? ""] ?? "application/octet-stream";
|
|
3617
3617
|
}
|
|
3618
3618
|
`},{path:".env.example",content:`# VAIF Configuration
|
|
3619
|
-
# Get these values from https://vaif.studio/
|
|
3619
|
+
# Get these values from https://console.vaif.studio/security/api-keys \u2192 Project Settings \u2192 API Keys
|
|
3620
3620
|
|
|
3621
3621
|
NEXT_PUBLIC_VAIF_API_URL=https://api.vaif.studio
|
|
3622
3622
|
NEXT_PUBLIC_VAIF_PROJECT_ID=your-project-id
|
|
@@ -3649,7 +3649,7 @@ An API-first e-commerce setup powered by [VAIF Studio](https://vaif.studio) with
|
|
|
3649
3649
|
cp .env.example .env.local
|
|
3650
3650
|
\\\`\\\`\\\`
|
|
3651
3651
|
|
|
3652
|
-
Get your Project ID, API Key, and Secret Key from <https://vaif.studio/
|
|
3652
|
+
Get your Project ID, API Key, and Secret Key from <https://console.vaif.studio/security/api-keys> under **Project Settings > API Keys**.
|
|
3653
3653
|
|
|
3654
3654
|
3. **Install and log in to the VAIF CLI**
|
|
3655
3655
|
|
|
@@ -3765,18 +3765,18 @@ export const posts = pgTable("posts", {
|
|
|
3765
3765
|
|
|
3766
3766
|
return Response.json({ message: \`Hello, \${name}!\` });
|
|
3767
3767
|
}
|
|
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(
|
|
3769
|
-
? Which VAIF features do you want to include?`)),_.forEach((s,r)=>{let l=a.has(r)?
|
|
3770
|
-
Unknown template: ${n}`)),console.log(
|
|
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(
|
|
3772
|
-
No features specified.`)),console.log(
|
|
3773
|
-
`,"utf-8"),console.log(
|
|
3774
|
-
`,"utf-8");}catch{}(t.dependencies?.length||t.devDependencies?.length)&&(console.log(""),console.log(
|
|
3775
|
-
--add-features requires --template to know which template to use.`)),console.log(
|
|
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(p__default.default.bold(`
|
|
3769
|
+
? Which VAIF features do you want to include?`)),_.forEach((s,r)=>{let l=a.has(r)?p__default.default.green("[x]"):"[ ]",d=r===t?p__default.default.cyan("> "):" ";console.log(`${d}${l} ${s.label} ${p__default.default.gray(`(${s.description})`)}`);}),console.log(p__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(d=>_[d].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(p__default.default.red(`
|
|
3770
|
+
Unknown template: ${n}`)),console.log(p__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(p__default.default.red(`
|
|
3772
|
+
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 le(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 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(p__default.default.green(` merge ${u.path} (added dependencies)`)),r++;continue}catch{}if(b__default.default.existsSync(f)&&!a.force){console.log(p__default.default.yellow(` skip ${u.path} (already exists)`)),l++;continue}b__default.default.writeFileSync(f,u.content,"utf-8"),console.log(p__default.default.green(` create ${u.path}`)),r++;}console.log(""),r>0&&console.log(p__default.default.green(`Created ${r} file${r!==1?"s":""}.`)),l>0&&console.log(p__default.default.yellow(`Skipped ${l} file${l!==1?"s":""} (use --force to overwrite).`));let d={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=d[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(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(u=>{console.log(p__default.default.gray(` ${u}`));}),console.log(""),console.log(p__default.default.gray(" Get your project credentials at https://console.vaif.studio/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 de(n){if(n.addFeatures){n.template||(console.log(p__default.default.red(`
|
|
3775
|
+
--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=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(p__default.default.yellow(`
|
|
3776
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
|
|
3777
3777
|
DATABASE_URL=postgresql://user:password@localhost:5432/database
|
|
3778
3778
|
VAIF_API_KEY=your-api-key
|
|
3779
|
-
`,"utf-8"),console.log(
|
|
3779
|
+
`,"utf-8"),console.log(p__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(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(`
|
|
3780
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(`
|
|
3781
3781
|
SELECT table_name, table_type
|
|
3782
3782
|
FROM information_schema.tables
|
|
@@ -3807,9 +3807,9 @@ Error: ${e.message}`)),process.exit(1);}}async function at(n){let{connectionStri
|
|
|
3807
3807
|
JOIN pg_namespace n ON n.oid = t.typnamespace
|
|
3808
3808
|
WHERE n.nspname = $1
|
|
3809
3809
|
ORDER BY t.typname, e.enumsortorder
|
|
3810
|
-
`,[t]),s=new Map;for(let
|
|
3810
|
+
`,[t]),s=new Map;for(let d of i.rows)s.set(d.table_name,[]);for(let d of o.rows){let m=s.get(d.table_name);m&&m.push(d);}let r=new Map;for(let d of c.rows){let m=r.get(d.enum_name)||[];m.push(d.enum_value),r.set(d.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(d=>`"${d}"`).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
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
|
|
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 d of o){let m=fe(d,a),u=d.column_name,f=d.column_default!==null||d.is_identity==="YES",h=d.is_nullable==="YES";s.push(` ${u}: ${m};`),f||d.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
3813
|
${s.join(`
|
|
3814
3814
|
`)}
|
|
3815
3815
|
}`),t.push(""),t.push(`export interface ${c}Insert {
|
|
@@ -3819,4 +3819,4 @@ ${r.join(`
|
|
|
3819
3819
|
${l.join(`
|
|
3820
3820
|
`)}
|
|
3821
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=
|
|
3822
|
+
`)}exports.generateTypes=re;exports.generateTypesFromConnection=at;exports.initConfig=de;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-KHEM3PLW.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.9.
|
|
3
|
+
"version": "1.9.9",
|
|
4
4
|
"description": "VAIF CLI - Type generation and development tools",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -12,6 +12,12 @@
|
|
|
12
12
|
"files": [
|
|
13
13
|
"dist"
|
|
14
14
|
],
|
|
15
|
+
"scripts": {
|
|
16
|
+
"build": "tsup",
|
|
17
|
+
"dev": "tsup --watch",
|
|
18
|
+
"typecheck": "tsc --noEmit",
|
|
19
|
+
"clean": "rm -rf dist"
|
|
20
|
+
},
|
|
15
21
|
"dependencies": {
|
|
16
22
|
"commander": "^12.0.0",
|
|
17
23
|
"ora": "^8.0.1",
|
|
@@ -23,7 +29,7 @@
|
|
|
23
29
|
"devDependencies": {
|
|
24
30
|
"@types/node": "^22.14.0",
|
|
25
31
|
"@types/pg": "^8.11.0",
|
|
26
|
-
"typescript": "^5.
|
|
32
|
+
"typescript": "^5.8.3",
|
|
27
33
|
"tsup": "^8.5.1"
|
|
28
34
|
},
|
|
29
35
|
"peerDependencies": {
|
|
@@ -51,11 +57,5 @@
|
|
|
51
57
|
"bugs": {
|
|
52
58
|
"url": "https://github.com/vaif-technologies/vaif-studio/issues"
|
|
53
59
|
},
|
|
54
|
-
"homepage": "https://vaif.studio"
|
|
55
|
-
|
|
56
|
-
"build": "tsup",
|
|
57
|
-
"dev": "tsup --watch",
|
|
58
|
-
"typecheck": "tsc --noEmit",
|
|
59
|
-
"clean": "rm -rf dist"
|
|
60
|
-
}
|
|
61
|
-
}
|
|
60
|
+
"homepage": "https://vaif.studio"
|
|
61
|
+
}
|