@vaiftech/cli 1.0.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024-2026 VAIF Technologies
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,121 @@
1
+ # @vaif/cli
2
+
3
+ Command-line tools for VAIF Studio - a Backend-as-a-Service platform.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install -D @vaif/cli
9
+ # or
10
+ pnpm add -D @vaif/cli
11
+ # or
12
+ yarn add -D @vaif/cli
13
+ ```
14
+
15
+ ## Features
16
+
17
+ ### Type Generation
18
+
19
+ Generate TypeScript types from your VAIF database schema.
20
+
21
+ ```bash
22
+ npx vaif types generate --project <project-id> --output ./src/types/database.ts
23
+ ```
24
+
25
+ #### Options
26
+
27
+ | Flag | Description | Default |
28
+ |------|-------------|---------|
29
+ | `--project` | Project ID | Required |
30
+ | `--output` | Output file path | `./vaif.types.ts` |
31
+ | `--env` | Environment (development, staging, production) | `development` |
32
+
33
+ #### Example Output
34
+
35
+ ```typescript
36
+ // Generated by @vaif/cli
37
+
38
+ export interface User {
39
+ id: string;
40
+ email: string;
41
+ name: string | null;
42
+ avatar_url: string | null;
43
+ created_at: string;
44
+ updated_at: string;
45
+ }
46
+
47
+ export interface Post {
48
+ id: string;
49
+ title: string;
50
+ content: string;
51
+ author_id: string;
52
+ published: boolean;
53
+ created_at: string;
54
+ updated_at: string;
55
+ }
56
+
57
+ export interface Database {
58
+ users: User;
59
+ posts: Post;
60
+ }
61
+ ```
62
+
63
+ ### Programmatic Usage
64
+
65
+ ```typescript
66
+ import { generateTypes } from '@vaif/cli';
67
+
68
+ const types = await generateTypes({
69
+ projectId: 'proj-123',
70
+ apiKey: 'vaif_sk_xxx',
71
+ baseUrl: 'https://api.vaif.io',
72
+ });
73
+
74
+ // types is a string containing TypeScript definitions
75
+ console.log(types);
76
+ ```
77
+
78
+ ## Configuration
79
+
80
+ Create a `vaif.config.js` file in your project root:
81
+
82
+ ```javascript
83
+ module.exports = {
84
+ projectId: 'proj-123',
85
+ output: './src/types/vaif.ts',
86
+ };
87
+ ```
88
+
89
+ Then run without flags:
90
+
91
+ ```bash
92
+ npx vaif types generate
93
+ ```
94
+
95
+ ## Usage with @vaif/client
96
+
97
+ Use generated types with the client SDK:
98
+
99
+ ```typescript
100
+ import { createVaifClient } from '@vaif/client';
101
+ import type { User, Post, Database } from './types/vaif';
102
+
103
+ const vaif = createVaifClient({
104
+ baseUrl: 'https://api.myproject.vaif.io',
105
+ apiKey: 'vaif_pk_xxx',
106
+ });
107
+
108
+ // Fully typed queries
109
+ const users = await vaif.from<User>('users').list();
110
+ const post = await vaif.from<Post>('posts').eq('id', 'post-123').single();
111
+ ```
112
+
113
+ ## Related Packages
114
+
115
+ - [@vaif/client](https://www.npmjs.com/package/@vaif/client) - Core client SDK
116
+ - [@vaif/react](https://www.npmjs.com/package/@vaif/react) - React hooks
117
+ - [@vaif/sdk-expo](https://www.npmjs.com/package/@vaif/sdk-expo) - React Native/Expo SDK
118
+
119
+ ## License
120
+
121
+ MIT
@@ -0,0 +1,67 @@
1
+ import f from'fs';import h from'path';import R from'dotenv';import N from'pg';import C from'ora';import u from'chalk';import D from'prettier';R.config();async function x(t){let n=h.resolve(t);if(!f.existsSync(n))return null;try{let o=f.readFileSync(n,"utf-8"),e=JSON.parse(o);return e.database?.url&&(e.database.url=$(e.database.url)),e.api?.apiKey&&(e.api.apiKey=$(e.api.apiKey)),e}catch{throw new Error(`Failed to parse config file: ${t}`)}}function $(t){return t.replace(/\$\{([^}]+)\}/g,(n,o)=>process.env[o]||n)}async function O(t,n){let o=await t.query(`
2
+ SELECT table_name, table_type
3
+ FROM information_schema.tables
4
+ WHERE table_schema = $1
5
+ AND table_type = 'BASE TABLE'
6
+ ORDER BY table_name
7
+ `,[n]),e=await t.query(`
8
+ SELECT
9
+ table_name,
10
+ column_name,
11
+ data_type,
12
+ is_nullable,
13
+ column_default,
14
+ udt_name,
15
+ is_identity,
16
+ character_maximum_length,
17
+ numeric_precision,
18
+ numeric_scale
19
+ FROM information_schema.columns
20
+ WHERE table_schema = $1
21
+ ORDER BY table_name, ordinal_position
22
+ `,[n]),r=await t.query(`
23
+ SELECT
24
+ tc.constraint_name,
25
+ tc.table_name,
26
+ kcu.column_name,
27
+ ccu.table_name AS foreign_table_name,
28
+ ccu.column_name AS foreign_column_name
29
+ FROM information_schema.table_constraints AS tc
30
+ JOIN information_schema.key_column_usage AS kcu
31
+ ON tc.constraint_name = kcu.constraint_name
32
+ AND tc.table_schema = kcu.table_schema
33
+ JOIN information_schema.constraint_column_usage AS ccu
34
+ ON ccu.constraint_name = tc.constraint_name
35
+ AND ccu.table_schema = tc.table_schema
36
+ WHERE tc.constraint_type = 'FOREIGN KEY'
37
+ AND tc.table_schema = $1
38
+ `,[n]),s=await t.query(`
39
+ SELECT
40
+ t.typname as enum_name,
41
+ e.enumlabel as enum_value
42
+ FROM pg_type t
43
+ JOIN pg_enum e ON t.oid = e.enumtypid
44
+ JOIN pg_namespace n ON n.oid = t.typnamespace
45
+ WHERE n.nspname = $1
46
+ ORDER BY t.typname, e.enumsortorder
47
+ `,[n]),a=new Map;for(let i of o.rows)a.set(i.table_name,[]);for(let i of e.rows){let l=a.get(i.table_name);l&&l.push(i);}let c=new Map;for(let i of s.rows){let l=c.get(i.enum_name)||[];l.push(i.enum_value),c.set(i.enum_name,l);}return {tables:a,enums:c,foreignKeys:r.rows}}var b={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 F(t,n){let{data_type:o,udt_name:e,is_nullable:r}=t;if(n.has(e)){let c=n.get(e).map(i=>`"${i}"`).join(" | ");return r==="YES"?`(${c}) | null`:c}if(o==="ARRAY"){let a=e.replace(/^_/,"");if(n.has(a)){let l=n.get(a).map(m=>`"${m}"`).join(" | ");return r==="YES"?`(${l})[] | null`:`(${l})[]`}let c=b[a]||"unknown";return r==="YES"?`${c}[] | null`:`${c}[]`}let s=b[o]||b[e]||"unknown";return r==="YES"&&(s=`${s} | null`),s}function _(t){return t.split(/[_\-\s]+/).map(n=>n.charAt(0).toUpperCase()+n.slice(1).toLowerCase()).join("")}function j(t,n){let o=_(t),e=n.map(r=>` | "${r}"`).join(`
48
+ `);return `export type ${o} =
49
+ ${e};`}function k(t,n,o){let e=_(t),r=[],s=[],a=[];for(let m of n){let g=F(m,o),y=m.column_name,v=m.column_default!==null||m.is_identity==="YES",A=m.is_nullable==="YES";r.push(` ${y}: ${g};`),v||m.column_name==="id"?s.push(` ${y}?: ${g.replace(" | null","")} | null;`):A?s.push(` ${y}?: ${g};`):s.push(` ${y}: ${g.replace(" | null","")};`),a.push(` ${y}?: ${g.replace(" | null","")} | null;`);}let c=`export interface ${e} {
50
+ ${r.join(`
51
+ `)}
52
+ }`,i=`export interface ${e}Insert {
53
+ ${s.join(`
54
+ `)}
55
+ }`,l=`export interface ${e}Update {
56
+ ${a.join(`
57
+ `)}
58
+ }`;return {base:c,insert:i,update:l}}function U(t,n,o){let e=["/**"," * Auto-generated TypeScript types from database schema"," * Generated by @vaif/cli",` * Generated at: ${new Date().toISOString()}`," * "," * DO NOT EDIT MANUALLY - changes will be overwritten"," */",""];if(n.size>0){e.push("// ============ ENUMS ============"),e.push("");for(let[s,a]of n)e.push(j(s,a)),e.push("");}e.push("// ============ TABLES ============"),e.push("");let r=[];for(let[s,a]of t){let{base:c,insert:i,update:l}=k(s,a,n);r.push(s),e.push(c),e.push(""),e.push(i),e.push(""),e.push(l),e.push("");}e.push("// ============ DATABASE SCHEMA ============"),e.push(""),e.push("export interface Database {");for(let s of r){let a=_(s);e.push(` ${s}: {`),e.push(` Row: ${a};`),e.push(` Insert: ${a}Insert;`),e.push(` Update: ${a}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 X(t){let n=C("Loading configuration...").start();try{let o=await x(t.config),e=t.connection||o?.database?.url||process.env.DATABASE_URL;e||(n.fail("No database connection string provided"),console.log(u.yellow(`
60
+ Provide a connection string via:`)),console.log(u.gray(" --connection <url>")),console.log(u.gray(" DATABASE_URL environment variable")),console.log(u.gray(" vaif.config.json database.url")),process.exit(1)),n.text="Connecting to database...";let r=new N.Client({connectionString:e});await r.connect(),n.text="Introspecting schema...";let{tables:s,enums:a,foreignKeys:c}=await O(r,t.schema);if(await r.end(),s.size===0){n.warn(`No tables found in schema "${t.schema}"`);return}n.text=`Generating types for ${s.size} tables...`;let i=U(s,a,c),l=await D.format(i,{parser:"typescript",semi:!0,singleQuote:!1,trailingComma:"es5",printWidth:100});if(t.dryRun){n.succeed("Generated types (dry run):"),console.log(""),console.log(u.gray("\u2500".repeat(60))),console.log(l),console.log(u.gray("\u2500".repeat(60)));return}let m=h.resolve(t.output),g=h.dirname(m);f.existsSync(g)||f.mkdirSync(g,{recursive:!0}),f.writeFileSync(m,l,"utf-8"),n.succeed(`Generated types for ${s.size} tables \u2192 ${u.cyan(t.output)}`),console.log(""),console.log(u.green("Generated:")),console.log(u.gray(` Tables: ${s.size}`)),console.log(u.gray(` Enums: ${a.size}`)),console.log(""),console.log(u.gray("Import in your code:")),console.log(u.cyan(` import type { Database, Row, Insert, Update } from "${t.output.replace(/\.ts$/,"")}";`));}catch(o){n.fail("Failed to generate types"),o instanceof Error&&(console.error(u.red(`
61
+ Error: ${o.message}`)),o.message.includes("ECONNREFUSED")&&console.log(u.yellow(`
62
+ Make sure your database is running and accessible.`))),process.exit(1);}}var L={$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 re(t){let n=C("Initializing VAIF configuration...").start(),o=h.resolve("vaif.config.json");f.existsSync(o)&&!t.force&&(n.fail("vaif.config.json already exists"),console.log(u.yellow(`
63
+ Use --force to overwrite existing configuration.`)),process.exit(1));try{f.writeFileSync(o,JSON.stringify(L,null,2),"utf-8"),n.succeed("Created vaif.config.json");let e=h.resolve(".env.example");if(f.existsSync(e)||(f.writeFileSync(e,`# VAIF Configuration
64
+ DATABASE_URL=postgresql://user:password@localhost:5432/database
65
+ VAIF_API_KEY=your-api-key
66
+ `,"utf-8"),console.log(u.gray("Created .env.example"))),t.typescript){let r=h.resolve("src/types");f.existsSync(r)||(f.mkdirSync(r,{recursive:!0}),console.log(u.gray("Created src/types directory")));}console.log(""),console.log(u.green("VAIF initialized successfully!")),console.log(""),console.log(u.gray("Next steps:")),console.log(u.gray(" 1. Update vaif.config.json with your project ID")),console.log(u.gray(" 2. Set DATABASE_URL in your environment")),console.log(u.gray(" 3. Run: npx vaif generate")),console.log("");}catch(e){n.fail("Failed to initialize"),e instanceof Error&&console.error(u.red(`
67
+ Error: ${e.message}`)),process.exit(1);}}export{x as a,X as b,re as c};
package/dist/cli.cjs ADDED
@@ -0,0 +1,68 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';var commander=require('commander'),f=require('fs'),v=require('path'),D=require('pg'),O=require('ora'),u=require('chalk'),F=require('prettier'),N=require('dotenv');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var f__default=/*#__PURE__*/_interopDefault(f);var v__default=/*#__PURE__*/_interopDefault(v);var D__default=/*#__PURE__*/_interopDefault(D);var O__default=/*#__PURE__*/_interopDefault(O);var u__default=/*#__PURE__*/_interopDefault(u);var F__default=/*#__PURE__*/_interopDefault(F);var N__default=/*#__PURE__*/_interopDefault(N);N__default.default.config();async function $(t){let n=v__default.default.resolve(t);if(!f__default.default.existsSync(n))return null;try{let s=f__default.default.readFileSync(n,"utf-8"),e=JSON.parse(s);return e.database?.url&&(e.database.url=S(e.database.url)),e.api?.apiKey&&(e.api.apiKey=S(e.api.apiKey)),e}catch{throw new Error(`Failed to parse config file: ${t}`)}}function S(t){return t.replace(/\$\{([^}]+)\}/g,(n,s)=>process.env[s]||n)}async function j(t,n){let s=await t.query(`
3
+ SELECT table_name, table_type
4
+ FROM information_schema.tables
5
+ WHERE table_schema = $1
6
+ AND table_type = 'BASE TABLE'
7
+ ORDER BY table_name
8
+ `,[n]),e=await t.query(`
9
+ SELECT
10
+ table_name,
11
+ column_name,
12
+ data_type,
13
+ is_nullable,
14
+ column_default,
15
+ udt_name,
16
+ is_identity,
17
+ character_maximum_length,
18
+ numeric_precision,
19
+ numeric_scale
20
+ FROM information_schema.columns
21
+ WHERE table_schema = $1
22
+ ORDER BY table_name, ordinal_position
23
+ `,[n]),r=await t.query(`
24
+ SELECT
25
+ tc.constraint_name,
26
+ tc.table_name,
27
+ kcu.column_name,
28
+ ccu.table_name AS foreign_table_name,
29
+ ccu.column_name AS foreign_column_name
30
+ FROM information_schema.table_constraints AS tc
31
+ JOIN information_schema.key_column_usage AS kcu
32
+ ON tc.constraint_name = kcu.constraint_name
33
+ AND tc.table_schema = kcu.table_schema
34
+ JOIN information_schema.constraint_column_usage AS ccu
35
+ ON ccu.constraint_name = tc.constraint_name
36
+ AND ccu.table_schema = tc.table_schema
37
+ WHERE tc.constraint_type = 'FOREIGN KEY'
38
+ AND tc.table_schema = $1
39
+ `,[n]),o=await t.query(`
40
+ SELECT
41
+ t.typname as enum_name,
42
+ e.enumlabel as enum_value
43
+ FROM pg_type t
44
+ JOIN pg_enum e ON t.oid = e.enumtypid
45
+ JOIN pg_namespace n ON n.oid = t.typnamespace
46
+ WHERE n.nspname = $1
47
+ ORDER BY t.typname, e.enumsortorder
48
+ `,[n]),a=new Map;for(let i of s.rows)a.set(i.table_name,[]);for(let i of e.rows){let l=a.get(i.table_name);l&&l.push(i);}let c=new Map;for(let i of o.rows){let l=c.get(i.enum_name)||[];l.push(i.enum_value),c.set(i.enum_name,l);}return {tables:a,enums:c,foreignKeys:r.rows}}var _={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 k(t,n){let{data_type:s,udt_name:e,is_nullable:r}=t;if(n.has(e)){let c=n.get(e).map(i=>`"${i}"`).join(" | ");return r==="YES"?`(${c}) | null`:c}if(s==="ARRAY"){let a=e.replace(/^_/,"");if(n.has(a)){let l=n.get(a).map(p=>`"${p}"`).join(" | ");return r==="YES"?`(${l})[] | null`:`(${l})[]`}let c=_[a]||"unknown";return r==="YES"?`${c}[] | null`:`${c}[]`}let o=_[s]||_[e]||"unknown";return r==="YES"&&(o=`${o} | null`),o}function E(t){return t.split(/[_\-\s]+/).map(n=>n.charAt(0).toUpperCase()+n.slice(1).toLowerCase()).join("")}function U(t,n){let s=E(t),e=n.map(r=>` | "${r}"`).join(`
49
+ `);return `export type ${s} =
50
+ ${e};`}function L(t,n,s){let e=E(t),r=[],o=[],a=[];for(let p of n){let g=k(p,s),y=p.column_name,I=p.column_default!==null||p.is_identity==="YES",R=p.is_nullable==="YES";r.push(` ${y}: ${g};`),I||p.column_name==="id"?o.push(` ${y}?: ${g.replace(" | null","")} | null;`):R?o.push(` ${y}?: ${g};`):o.push(` ${y}: ${g.replace(" | null","")};`),a.push(` ${y}?: ${g.replace(" | null","")} | null;`);}let c=`export interface ${e} {
51
+ ${r.join(`
52
+ `)}
53
+ }`,i=`export interface ${e}Insert {
54
+ ${o.join(`
55
+ `)}
56
+ }`,l=`export interface ${e}Update {
57
+ ${a.join(`
58
+ `)}
59
+ }`;return {base:c,insert:i,update:l}}function M(t,n,s){let e=["/**"," * Auto-generated TypeScript types from database schema"," * Generated by @vaif/cli",` * Generated at: ${new Date().toISOString()}`," * "," * DO NOT EDIT MANUALLY - changes will be overwritten"," */",""];if(n.size>0){e.push("// ============ ENUMS ============"),e.push("");for(let[o,a]of n)e.push(U(o,a)),e.push("");}e.push("// ============ TABLES ============"),e.push("");let r=[];for(let[o,a]of t){let{base:c,insert:i,update:l}=L(o,a,n);r.push(o),e.push(c),e.push(""),e.push(i),e.push(""),e.push(l),e.push("");}e.push("// ============ DATABASE SCHEMA ============"),e.push(""),e.push("export interface Database {");for(let o of r){let a=E(o);e.push(` ${o}: {`),e.push(` Row: ${a};`),e.push(` Insert: ${a}Insert;`),e.push(` Update: ${a}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(`
60
+ `)}async function x(t){let n=O__default.default("Loading configuration...").start();try{let s=await $(t.config),e=t.connection||s?.database?.url||process.env.DATABASE_URL;e||(n.fail("No database connection string provided"),console.log(u__default.default.yellow(`
61
+ Provide a connection string via:`)),console.log(u__default.default.gray(" --connection <url>")),console.log(u__default.default.gray(" DATABASE_URL environment variable")),console.log(u__default.default.gray(" vaif.config.json database.url")),process.exit(1)),n.text="Connecting to database...";let r=new D__default.default.Client({connectionString:e});await r.connect(),n.text="Introspecting schema...";let{tables:o,enums:a,foreignKeys:c}=await j(r,t.schema);if(await r.end(),o.size===0){n.warn(`No tables found in schema "${t.schema}"`);return}n.text=`Generating types for ${o.size} tables...`;let i=M(o,a,c),l=await F__default.default.format(i,{parser:"typescript",semi:!0,singleQuote:!1,trailingComma:"es5",printWidth:100});if(t.dryRun){n.succeed("Generated types (dry run):"),console.log(""),console.log(u__default.default.gray("\u2500".repeat(60))),console.log(l),console.log(u__default.default.gray("\u2500".repeat(60)));return}let p=v__default.default.resolve(t.output),g=v__default.default.dirname(p);f__default.default.existsSync(g)||f__default.default.mkdirSync(g,{recursive:!0}),f__default.default.writeFileSync(p,l,"utf-8"),n.succeed(`Generated types for ${o.size} tables \u2192 ${u__default.default.cyan(t.output)}`),console.log(""),console.log(u__default.default.green("Generated:")),console.log(u__default.default.gray(` Tables: ${o.size}`)),console.log(u__default.default.gray(` Enums: ${a.size}`)),console.log(""),console.log(u__default.default.gray("Import in your code:")),console.log(u__default.default.cyan(` import type { Database, Row, Insert, Update } from "${t.output.replace(/\.ts$/,"")}";`));}catch(s){n.fail("Failed to generate types"),s instanceof Error&&(console.error(u__default.default.red(`
62
+ Error: ${s.message}`)),s.message.includes("ECONNREFUSED")&&console.log(u__default.default.yellow(`
63
+ Make sure your database is running and accessible.`))),process.exit(1);}}var V={$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 A(t){let n=O__default.default("Initializing VAIF configuration...").start(),s=v__default.default.resolve("vaif.config.json");f__default.default.existsSync(s)&&!t.force&&(n.fail("vaif.config.json already exists"),console.log(u__default.default.yellow(`
64
+ Use --force to overwrite existing configuration.`)),process.exit(1));try{f__default.default.writeFileSync(s,JSON.stringify(V,null,2),"utf-8"),n.succeed("Created vaif.config.json");let e=v__default.default.resolve(".env.example");if(f__default.default.existsSync(e)||(f__default.default.writeFileSync(e,`# VAIF Configuration
65
+ DATABASE_URL=postgresql://user:password@localhost:5432/database
66
+ VAIF_API_KEY=your-api-key
67
+ `,"utf-8"),console.log(u__default.default.gray("Created .env.example"))),t.typescript){let r=v__default.default.resolve("src/types");f__default.default.existsSync(r)||(f__default.default.mkdirSync(r,{recursive:!0}),console.log(u__default.default.gray("Created src/types directory")));}console.log(""),console.log(u__default.default.green("VAIF initialized successfully!")),console.log(""),console.log(u__default.default.gray("Next steps:")),console.log(u__default.default.gray(" 1. Update vaif.config.json with your project ID")),console.log(u__default.default.gray(" 2. Set DATABASE_URL in your environment")),console.log(u__default.default.gray(" 3. Run: npx vaif generate")),console.log("");}catch(e){n.fail("Failed to initialize"),e instanceof Error&&console.error(u__default.default.red(`
68
+ Error: ${e.message}`)),process.exit(1);}}commander.program.name("vaif").description("VAIF CLI - Type generation and development tools").version("0.1.0");commander.program.command("generate").alias("gen").description("Generate TypeScript types from your database schema").option("-c, --connection <url>","Database connection string").option("-o, --output <path>","Output file path","./src/types/database.ts").option("--schema <name>","Schema name","public").option("--config <path>","Config file path","vaif.config.json").option("--dry-run","Preview generated types without writing").action(x);commander.program.command("init").description("Initialize VAIF configuration in your project").option("--typescript","Setup for TypeScript project").option("-f, --force","Overwrite existing config").action(A);commander.program.parse(process.argv);process.argv.slice(2).length||commander.program.outputHelp();
package/dist/cli.d.cts ADDED
@@ -0,0 +1 @@
1
+ #!/usr/bin/env node
package/dist/cli.d.ts ADDED
@@ -0,0 +1 @@
1
+ #!/usr/bin/env node
package/dist/cli.js ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ import {b,c}from'./chunk-IQB6LKJ7.js';import {program}from'commander';program.name("vaif").description("VAIF CLI - Type generation and development tools").version("0.1.0");program.command("generate").alias("gen").description("Generate TypeScript types from your database schema").option("-c, --connection <url>","Database connection string").option("-o, --output <path>","Output file path","./src/types/database.ts").option("--schema <name>","Schema name","public").option("--config <path>","Config file path","vaif.config.json").option("--dry-run","Preview generated types without writing").action(b);program.command("init").description("Initialize VAIF configuration in your project").option("--typescript","Setup for TypeScript project").option("-f, --force","Overwrite existing config").action(c);program.parse(process.argv);process.argv.slice(2).length||program.outputHelp();
package/dist/index.cjs ADDED
@@ -0,0 +1,109 @@
1
+ 'use strict';var b=require('fs'),w=require('path'),v=require('dotenv'),C=require('pg'),D=require('ora'),m=require('chalk'),O=require('prettier');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var b__default=/*#__PURE__*/_interopDefault(b);var w__default=/*#__PURE__*/_interopDefault(w);var v__default=/*#__PURE__*/_interopDefault(v);var C__default=/*#__PURE__*/_interopDefault(C);var D__default=/*#__PURE__*/_interopDefault(D);var m__default=/*#__PURE__*/_interopDefault(m);var O__default=/*#__PURE__*/_interopDefault(O);v__default.default.config();async function _(s){let t=w__default.default.resolve(s);if(!b__default.default.existsSync(t))return null;try{let n=b__default.default.readFileSync(t,"utf-8"),e=JSON.parse(n);return e.database?.url&&(e.database.url=A(e.database.url)),e.api?.apiKey&&(e.api.apiKey=A(e.api.apiKey)),e}catch{throw new Error(`Failed to parse config file: ${s}`)}}function A(s){return s.replace(/\$\{([^}]+)\}/g,(t,n)=>process.env[n]||t)}async function F(s,t){let n=await s.query(`
2
+ SELECT table_name, table_type
3
+ FROM information_schema.tables
4
+ WHERE table_schema = $1
5
+ AND table_type = 'BASE TABLE'
6
+ ORDER BY table_name
7
+ `,[t]),e=await s.query(`
8
+ SELECT
9
+ table_name,
10
+ column_name,
11
+ data_type,
12
+ is_nullable,
13
+ column_default,
14
+ udt_name,
15
+ is_identity,
16
+ character_maximum_length,
17
+ numeric_precision,
18
+ numeric_scale
19
+ FROM information_schema.columns
20
+ WHERE table_schema = $1
21
+ ORDER BY table_name, ordinal_position
22
+ `,[t]),r=await s.query(`
23
+ SELECT
24
+ tc.constraint_name,
25
+ tc.table_name,
26
+ kcu.column_name,
27
+ ccu.table_name AS foreign_table_name,
28
+ ccu.column_name AS foreign_column_name
29
+ FROM information_schema.table_constraints AS tc
30
+ JOIN information_schema.key_column_usage AS kcu
31
+ ON tc.constraint_name = kcu.constraint_name
32
+ AND tc.table_schema = kcu.table_schema
33
+ JOIN information_schema.constraint_column_usage AS ccu
34
+ ON ccu.constraint_name = tc.constraint_name
35
+ AND ccu.table_schema = tc.table_schema
36
+ WHERE tc.constraint_type = 'FOREIGN KEY'
37
+ AND tc.table_schema = $1
38
+ `,[t]),a=await s.query(`
39
+ SELECT
40
+ t.typname as enum_name,
41
+ e.enumlabel as enum_value
42
+ FROM pg_type t
43
+ JOIN pg_enum e ON t.oid = e.enumtypid
44
+ JOIN pg_namespace n ON n.oid = t.typnamespace
45
+ WHERE n.nspname = $1
46
+ ORDER BY t.typname, e.enumsortorder
47
+ `,[t]),o=new Map;for(let i of n.rows)o.set(i.table_name,[]);for(let i of e.rows){let u=o.get(i.table_name);u&&u.push(i);}let l=new Map;for(let i of a.rows){let u=l.get(i.enum_name)||[];u.push(i.enum_value),l.set(i.enum_name,u);}return {tables:o,enums:l,foreignKeys:r.rows}}var $={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 j(s,t){let{data_type:n,udt_name:e,is_nullable:r}=s;if(t.has(e)){let l=t.get(e).map(i=>`"${i}"`).join(" | ");return r==="YES"?`(${l}) | null`:l}if(n==="ARRAY"){let o=e.replace(/^_/,"");if(t.has(o)){let u=t.get(o).map(c=>`"${c}"`).join(" | ");return r==="YES"?`(${u})[] | null`:`(${u})[]`}let l=$[o]||"unknown";return r==="YES"?`${l}[] | null`:`${l}[]`}let a=$[n]||$[e]||"unknown";return r==="YES"&&(a=`${a} | null`),a}function T(s){return s.split(/[_\-\s]+/).map(t=>t.charAt(0).toUpperCase()+t.slice(1).toLowerCase()).join("")}function M(s,t){let n=T(s),e=t.map(r=>` | "${r}"`).join(`
48
+ `);return `export type ${n} =
49
+ ${e};`}function Y(s,t,n){let e=T(s),r=[],a=[],o=[];for(let c of t){let p=j(c,n),g=c.column_name,y=c.column_default!==null||c.is_identity==="YES",d=c.is_nullable==="YES";r.push(` ${g}: ${p};`),y||c.column_name==="id"?a.push(` ${g}?: ${p.replace(" | null","")} | null;`):d?a.push(` ${g}?: ${p};`):a.push(` ${g}: ${p.replace(" | null","")};`),o.push(` ${g}?: ${p.replace(" | null","")} | null;`);}let l=`export interface ${e} {
50
+ ${r.join(`
51
+ `)}
52
+ }`,i=`export interface ${e}Insert {
53
+ ${a.join(`
54
+ `)}
55
+ }`,u=`export interface ${e}Update {
56
+ ${o.join(`
57
+ `)}
58
+ }`;return {base:l,insert:i,update:u}}function U(s,t,n){let e=["/**"," * Auto-generated TypeScript types from database schema"," * Generated by @vaif/cli",` * Generated at: ${new Date().toISOString()}`," * "," * DO NOT EDIT MANUALLY - changes will be overwritten"," */",""];if(t.size>0){e.push("// ============ ENUMS ============"),e.push("");for(let[a,o]of t)e.push(M(a,o)),e.push("");}e.push("// ============ TABLES ============"),e.push("");let r=[];for(let[a,o]of s){let{base:l,insert:i,update:u}=Y(a,o,t);r.push(a),e.push(l),e.push(""),e.push(i),e.push(""),e.push(u),e.push("");}e.push("// ============ DATABASE SCHEMA ============"),e.push(""),e.push("export interface Database {");for(let a of r){let o=T(a);e.push(` ${a}: {`),e.push(` Row: ${o};`),e.push(` Insert: ${o}Insert;`),e.push(` Update: ${o}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 k(s){let t=D__default.default("Loading configuration...").start();try{let n=await _(s.config),e=s.connection||n?.database?.url||process.env.DATABASE_URL;e||(t.fail("No database connection string provided"),console.log(m__default.default.yellow(`
60
+ Provide a connection string via:`)),console.log(m__default.default.gray(" --connection <url>")),console.log(m__default.default.gray(" DATABASE_URL environment variable")),console.log(m__default.default.gray(" vaif.config.json database.url")),process.exit(1)),t.text="Connecting to database...";let r=new C__default.default.Client({connectionString:e});await r.connect(),t.text="Introspecting schema...";let{tables:a,enums:o,foreignKeys:l}=await F(r,s.schema);if(await r.end(),a.size===0){t.warn(`No tables found in schema "${s.schema}"`);return}t.text=`Generating types for ${a.size} tables...`;let i=U(a,o,l),u=await O__default.default.format(i,{parser:"typescript",semi:!0,singleQuote:!1,trailingComma:"es5",printWidth:100});if(s.dryRun){t.succeed("Generated types (dry run):"),console.log(""),console.log(m__default.default.gray("\u2500".repeat(60))),console.log(u),console.log(m__default.default.gray("\u2500".repeat(60)));return}let c=w__default.default.resolve(s.output),p=w__default.default.dirname(c);b__default.default.existsSync(p)||b__default.default.mkdirSync(p,{recursive:!0}),b__default.default.writeFileSync(c,u,"utf-8"),t.succeed(`Generated types for ${a.size} tables \u2192 ${m__default.default.cyan(s.output)}`),console.log(""),console.log(m__default.default.green("Generated:")),console.log(m__default.default.gray(` Tables: ${a.size}`)),console.log(m__default.default.gray(` Enums: ${o.size}`)),console.log(""),console.log(m__default.default.gray("Import in your code:")),console.log(m__default.default.cyan(` import type { Database, Row, Insert, Update } from "${s.output.replace(/\.ts$/,"")}";`));}catch(n){t.fail("Failed to generate types"),n instanceof Error&&(console.error(m__default.default.red(`
61
+ Error: ${n.message}`)),n.message.includes("ECONNREFUSED")&&console.log(m__default.default.yellow(`
62
+ Make sure your database is running and accessible.`))),process.exit(1);}}var B={$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 z(s){let t=D__default.default("Initializing VAIF configuration...").start(),n=w__default.default.resolve("vaif.config.json");b__default.default.existsSync(n)&&!s.force&&(t.fail("vaif.config.json already exists"),console.log(m__default.default.yellow(`
63
+ Use --force to overwrite existing configuration.`)),process.exit(1));try{b__default.default.writeFileSync(n,JSON.stringify(B,null,2),"utf-8"),t.succeed("Created vaif.config.json");let e=w__default.default.resolve(".env.example");if(b__default.default.existsSync(e)||(b__default.default.writeFileSync(e,`# VAIF Configuration
64
+ DATABASE_URL=postgresql://user:password@localhost:5432/database
65
+ VAIF_API_KEY=your-api-key
66
+ `,"utf-8"),console.log(m__default.default.gray("Created .env.example"))),s.typescript){let r=w__default.default.resolve("src/types");b__default.default.existsSync(r)||(b__default.default.mkdirSync(r,{recursive:!0}),console.log(m__default.default.gray("Created src/types directory")));}console.log(""),console.log(m__default.default.green("VAIF initialized successfully!")),console.log(""),console.log(m__default.default.gray("Next steps:")),console.log(m__default.default.gray(" 1. Update vaif.config.json with your project ID")),console.log(m__default.default.gray(" 2. Set DATABASE_URL in your environment")),console.log(m__default.default.gray(" 3. Run: npx vaif generate")),console.log("");}catch(e){t.fail("Failed to initialize"),e instanceof Error&&console.error(m__default.default.red(`
67
+ Error: ${e.message}`)),process.exit(1);}}async function be(s){let{connectionString:t,schema:n="public"}=s,e=new C__default.default.Client({connectionString:t});await e.connect();try{let r=await e.query(`
68
+ SELECT table_name, table_type
69
+ FROM information_schema.tables
70
+ WHERE table_schema = $1
71
+ AND table_type = 'BASE TABLE'
72
+ ORDER BY table_name
73
+ `,[n]),a=await e.query(`
74
+ SELECT
75
+ table_name,
76
+ column_name,
77
+ data_type,
78
+ is_nullable,
79
+ column_default,
80
+ udt_name,
81
+ is_identity,
82
+ character_maximum_length,
83
+ numeric_precision,
84
+ numeric_scale
85
+ FROM information_schema.columns
86
+ WHERE table_schema = $1
87
+ ORDER BY table_name, ordinal_position
88
+ `,[n]),o=await e.query(`
89
+ SELECT
90
+ t.typname as enum_name,
91
+ e.enumlabel as enum_value
92
+ FROM pg_type t
93
+ JOIN pg_enum e ON t.oid = e.enumtypid
94
+ JOIN pg_namespace n ON n.oid = t.typnamespace
95
+ WHERE n.nspname = $1
96
+ ORDER BY t.typname, e.enumsortorder
97
+ `,[n]),l=new Map;for(let c of r.rows)l.set(c.table_name,[]);for(let c of a.rows){let p=l.get(c.table_name);p&&p.push(c);}let i=new Map;for(let c of o.rows){let p=i.get(c.enum_name)||[];p.push(c.enum_value),i.set(c.enum_name,p);}let u=G(l,i);return O__default.default.format(u,{parser:"typescript",semi:!0,singleQuote:!1,trailingComma:"es5",printWidth:100})}finally{await e.end();}}var x={smallint:"number",integer:"number",bigint:"string",int2:"number",int4:"number",int8:"string",decimal:"string",numeric:"string",real:"number",float4:"number",float8:"number","double precision":"number",money:"string",boolean:"boolean",bool:"boolean",text:"string",varchar:"string",char:"string",character:"string","character varying":"string",name:"string",citext:"string",date:"string",time:"string",timetz:"string",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 K(s,t){let{data_type:n,udt_name:e,is_nullable:r}=s;if(t.has(e)){let l=t.get(e).map(i=>`"${i}"`).join(" | ");return r==="YES"?`(${l}) | null`:l}if(n==="ARRAY"){let o=e.replace(/^_/,"");if(t.has(o)){let u=t.get(o).map(c=>`"${c}"`).join(" | ");return r==="YES"?`(${u})[] | null`:`(${u})[]`}let l=x[o]||"unknown";return r==="YES"?`${l}[] | null`:`${l}[]`}let a=x[n]||x[e]||"unknown";return r==="YES"&&(a=`${a} | null`),a}function S(s){return s.split(/[_\-\s]+/).map(t=>t.charAt(0).toUpperCase()+t.slice(1).toLowerCase()).join("")}function G(s,t){let n=["/**"," * Auto-generated TypeScript types from database schema"," * Generated by @vaif/cli",` * Generated at: ${new Date().toISOString()}`," * "," * DO NOT EDIT MANUALLY - changes will be overwritten"," */",""];if(t.size>0){n.push("// ============ ENUMS ============"),n.push("");for(let[r,a]of t){let o=S(r),l=a.map(i=>` | "${i}"`).join(`
98
+ `);n.push(`export type ${o} =
99
+ ${l};`),n.push("");}}n.push("// ============ TABLES ============"),n.push("");let e=[];for(let[r,a]of s){e.push(r);let o=S(r),l=[],i=[],u=[];for(let c of a){let p=K(c,t),g=c.column_name,y=c.column_default!==null||c.is_identity==="YES",d=c.is_nullable==="YES";l.push(` ${g}: ${p};`),y||c.column_name==="id"?i.push(` ${g}?: ${p.replace(" | null","")} | null;`):d?i.push(` ${g}?: ${p};`):i.push(` ${g}: ${p.replace(" | null","")};`),u.push(` ${g}?: ${p.replace(" | null","")} | null;`);}n.push(`export interface ${o} {
100
+ ${l.join(`
101
+ `)}
102
+ }`),n.push(""),n.push(`export interface ${o}Insert {
103
+ ${i.join(`
104
+ `)}
105
+ }`),n.push(""),n.push(`export interface ${o}Update {
106
+ ${u.join(`
107
+ `)}
108
+ }`),n.push("");}n.push("// ============ DATABASE SCHEMA ============"),n.push(""),n.push("export interface Database {");for(let r of e){let a=S(r);n.push(` ${r}: {`),n.push(` Row: ${a};`),n.push(` Insert: ${a}Insert;`),n.push(` Update: ${a}Update;`),n.push(" };");}return n.push("}"),n.push(""),n.push("export type TableName = keyof Database;"),n.push(""),n.push("// ============ HELPER TYPES ============"),n.push(""),n.push('export type Row<T extends TableName> = Database[T]["Row"];'),n.push('export type Insert<T extends TableName> = Database[T]["Insert"];'),n.push('export type Update<T extends TableName> = Database[T]["Update"];'),n.push(""),n.join(`
109
+ `)}exports.generateTypes=k;exports.generateTypesFromConnection=be;exports.initConfig=z;exports.loadConfig=_;
@@ -0,0 +1,99 @@
1
+ interface VaifConfig {
2
+ projectId?: string;
3
+ database?: {
4
+ url?: string;
5
+ schema?: string;
6
+ };
7
+ types?: {
8
+ output?: string;
9
+ };
10
+ api?: {
11
+ baseUrl?: string;
12
+ apiKey?: string;
13
+ };
14
+ }
15
+ declare function loadConfig(configPath: string): Promise<VaifConfig | null>;
16
+
17
+ interface GenerateOptions {
18
+ connection?: string;
19
+ output: string;
20
+ schema: string;
21
+ config: string;
22
+ dryRun?: boolean;
23
+ }
24
+ declare function generateTypes(options: GenerateOptions): Promise<void>;
25
+
26
+ interface InitOptions {
27
+ typescript?: boolean;
28
+ force?: boolean;
29
+ }
30
+ declare function initConfig(options: InitOptions): Promise<void>;
31
+
32
+ /**
33
+ * @vaif/cli - VAIF CLI and Type Generation
34
+ *
35
+ * CLI tool for generating TypeScript types from database schemas.
36
+ *
37
+ * @example CLI Usage
38
+ * ```bash
39
+ * # Initialize VAIF config
40
+ * npx vaif init --typescript
41
+ *
42
+ * # Generate types from database
43
+ * npx vaif generate --connection postgres://... --output ./src/types/db.ts
44
+ *
45
+ * # Generate types using config file
46
+ * npx vaif generate
47
+ *
48
+ * # Preview generated types without writing
49
+ * npx vaif generate --dry-run
50
+ * ```
51
+ *
52
+ * @example Programmatic Usage
53
+ * ```typescript
54
+ * import { generateTypesFromConnection } from '@vaif/cli';
55
+ *
56
+ * const types = await generateTypesFromConnection({
57
+ * connectionString: process.env.DATABASE_URL,
58
+ * schema: 'public',
59
+ * });
60
+ *
61
+ * fs.writeFileSync('./src/types/db.ts', types);
62
+ * ```
63
+ *
64
+ * @packageDocumentation
65
+ */
66
+
67
+ interface GenerateTypesOptions {
68
+ connectionString: string;
69
+ schema?: string;
70
+ }
71
+ interface ColumnInfo {
72
+ column_name: string;
73
+ data_type: string;
74
+ is_nullable: string;
75
+ column_default: string | null;
76
+ udt_name: string;
77
+ is_identity: string;
78
+ character_maximum_length: number | null;
79
+ numeric_precision: number | null;
80
+ numeric_scale: number | null;
81
+ }
82
+ /**
83
+ * Generate TypeScript types from a database connection
84
+ *
85
+ * @example
86
+ * ```typescript
87
+ * import { generateTypesFromConnection } from '@vaif/cli';
88
+ *
89
+ * const types = await generateTypesFromConnection({
90
+ * connectionString: 'postgres://user:pass@localhost:5432/mydb',
91
+ * schema: 'public',
92
+ * });
93
+ *
94
+ * console.log(types);
95
+ * ```
96
+ */
97
+ declare function generateTypesFromConnection(options: GenerateTypesOptions): Promise<string>;
98
+
99
+ export { type ColumnInfo, type GenerateTypesOptions, type VaifConfig, generateTypes, generateTypesFromConnection, initConfig, loadConfig };
@@ -0,0 +1,99 @@
1
+ interface VaifConfig {
2
+ projectId?: string;
3
+ database?: {
4
+ url?: string;
5
+ schema?: string;
6
+ };
7
+ types?: {
8
+ output?: string;
9
+ };
10
+ api?: {
11
+ baseUrl?: string;
12
+ apiKey?: string;
13
+ };
14
+ }
15
+ declare function loadConfig(configPath: string): Promise<VaifConfig | null>;
16
+
17
+ interface GenerateOptions {
18
+ connection?: string;
19
+ output: string;
20
+ schema: string;
21
+ config: string;
22
+ dryRun?: boolean;
23
+ }
24
+ declare function generateTypes(options: GenerateOptions): Promise<void>;
25
+
26
+ interface InitOptions {
27
+ typescript?: boolean;
28
+ force?: boolean;
29
+ }
30
+ declare function initConfig(options: InitOptions): Promise<void>;
31
+
32
+ /**
33
+ * @vaif/cli - VAIF CLI and Type Generation
34
+ *
35
+ * CLI tool for generating TypeScript types from database schemas.
36
+ *
37
+ * @example CLI Usage
38
+ * ```bash
39
+ * # Initialize VAIF config
40
+ * npx vaif init --typescript
41
+ *
42
+ * # Generate types from database
43
+ * npx vaif generate --connection postgres://... --output ./src/types/db.ts
44
+ *
45
+ * # Generate types using config file
46
+ * npx vaif generate
47
+ *
48
+ * # Preview generated types without writing
49
+ * npx vaif generate --dry-run
50
+ * ```
51
+ *
52
+ * @example Programmatic Usage
53
+ * ```typescript
54
+ * import { generateTypesFromConnection } from '@vaif/cli';
55
+ *
56
+ * const types = await generateTypesFromConnection({
57
+ * connectionString: process.env.DATABASE_URL,
58
+ * schema: 'public',
59
+ * });
60
+ *
61
+ * fs.writeFileSync('./src/types/db.ts', types);
62
+ * ```
63
+ *
64
+ * @packageDocumentation
65
+ */
66
+
67
+ interface GenerateTypesOptions {
68
+ connectionString: string;
69
+ schema?: string;
70
+ }
71
+ interface ColumnInfo {
72
+ column_name: string;
73
+ data_type: string;
74
+ is_nullable: string;
75
+ column_default: string | null;
76
+ udt_name: string;
77
+ is_identity: string;
78
+ character_maximum_length: number | null;
79
+ numeric_precision: number | null;
80
+ numeric_scale: number | null;
81
+ }
82
+ /**
83
+ * Generate TypeScript types from a database connection
84
+ *
85
+ * @example
86
+ * ```typescript
87
+ * import { generateTypesFromConnection } from '@vaif/cli';
88
+ *
89
+ * const types = await generateTypesFromConnection({
90
+ * connectionString: 'postgres://user:pass@localhost:5432/mydb',
91
+ * schema: 'public',
92
+ * });
93
+ *
94
+ * console.log(types);
95
+ * ```
96
+ */
97
+ declare function generateTypesFromConnection(options: GenerateTypesOptions): Promise<string>;
98
+
99
+ export { type ColumnInfo, type GenerateTypesOptions, type VaifConfig, generateTypes, generateTypesFromConnection, initConfig, loadConfig };
package/dist/index.js ADDED
@@ -0,0 +1,43 @@
1
+ export{b as generateTypes,c as initConfig,a as loadConfig}from'./chunk-IQB6LKJ7.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
+ SELECT table_name, table_type
3
+ FROM information_schema.tables
4
+ WHERE table_schema = $1
5
+ AND table_type = 'BASE TABLE'
6
+ ORDER BY table_name
7
+ `,[e]),i=await r.query(`
8
+ SELECT
9
+ table_name,
10
+ column_name,
11
+ data_type,
12
+ is_nullable,
13
+ column_default,
14
+ udt_name,
15
+ is_identity,
16
+ character_maximum_length,
17
+ numeric_precision,
18
+ numeric_scale
19
+ FROM information_schema.columns
20
+ WHERE table_schema = $1
21
+ ORDER BY table_name, ordinal_position
22
+ `,[e]),u=await r.query(`
23
+ SELECT
24
+ t.typname as enum_name,
25
+ e.enumlabel as enum_value
26
+ FROM pg_type t
27
+ JOIN pg_enum e ON t.oid = e.enumtypid
28
+ JOIN pg_namespace n ON n.oid = t.typnamespace
29
+ WHERE n.nspname = $1
30
+ ORDER BY t.typname, e.enumsortorder
31
+ `,[e]),s=new Map;for(let n of t.rows)s.set(n.table_name,[]);for(let n of i.rows){let l=s.get(n.table_name);l&&l.push(n);}let o=new Map;for(let n of u.rows){let l=o.get(n.enum_name)||[];l.push(n.enum_value),o.set(n.enum_name,l);}let m=w(s,o);return $.format(m,{parser:"typescript",semi:!0,singleQuote:!1,trailingComma:"es5",printWidth:100})}finally{await r.end();}}var g={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 E(p,a){let{data_type:e,udt_name:r,is_nullable:t}=p;if(a.has(r)){let s=a.get(r).map(o=>`"${o}"`).join(" | ");return t==="YES"?`(${s}) | null`:s}if(e==="ARRAY"){let u=r.replace(/^_/,"");if(a.has(u)){let m=a.get(u).map(n=>`"${n}"`).join(" | ");return t==="YES"?`(${m})[] | null`:`(${m})[]`}let s=g[u]||"unknown";return t==="YES"?`${s}[] | null`:`${s}[]`}let i=g[e]||g[r]||"unknown";return t==="YES"&&(i=`${i} | null`),i}function f(p){return p.split(/[_\-\s]+/).map(a=>a.charAt(0).toUpperCase()+a.slice(1).toLowerCase()).join("")}function w(p,a){let e=["/**"," * Auto-generated TypeScript types from database schema"," * Generated by @vaif/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[t,i]of a){let u=f(t),s=i.map(o=>` | "${o}"`).join(`
32
+ `);e.push(`export type ${u} =
33
+ ${s};`),e.push("");}}e.push("// ============ TABLES ============"),e.push("");let r=[];for(let[t,i]of p){r.push(t);let u=f(t),s=[],o=[],m=[];for(let n of i){let l=E(n,a),c=n.column_name,b=n.column_default!==null||n.is_identity==="YES",h=n.is_nullable==="YES";s.push(` ${c}: ${l};`),b||n.column_name==="id"?o.push(` ${c}?: ${l.replace(" | null","")} | null;`):h?o.push(` ${c}?: ${l};`):o.push(` ${c}: ${l.replace(" | null","")};`),m.push(` ${c}?: ${l.replace(" | null","")} | null;`);}e.push(`export interface ${u} {
34
+ ${s.join(`
35
+ `)}
36
+ }`),e.push(""),e.push(`export interface ${u}Insert {
37
+ ${o.join(`
38
+ `)}
39
+ }`),e.push(""),e.push(`export interface ${u}Update {
40
+ ${m.join(`
41
+ `)}
42
+ }`),e.push("");}e.push("// ============ DATABASE SCHEMA ============"),e.push(""),e.push("export interface Database {");for(let t of r){let i=f(t);e.push(` ${t}: {`),e.push(` Row: ${i};`),e.push(` Insert: ${i}Insert;`),e.push(` Update: ${i}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(`
43
+ `)}export{S as generateTypesFromConnection};
package/package.json ADDED
@@ -0,0 +1,61 @@
1
+ {
2
+ "name": "@vaiftech/cli",
3
+ "version": "1.0.0",
4
+ "description": "VAIF CLI - Type generation and development tools",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "module": "dist/index.mjs",
8
+ "types": "dist/index.d.ts",
9
+ "bin": {
10
+ "vaif": "./dist/cli.js"
11
+ },
12
+ "files": [
13
+ "dist"
14
+ ],
15
+ "scripts": {
16
+ "build": "tsup",
17
+ "dev": "tsup --watch",
18
+ "typecheck": "tsc --noEmit",
19
+ "clean": "rm -rf dist"
20
+ },
21
+ "dependencies": {
22
+ "commander": "^12.0.0",
23
+ "ora": "^8.0.1",
24
+ "chalk": "^5.3.0",
25
+ "prettier": "^3.2.0",
26
+ "pg": "^8.11.0",
27
+ "dotenv": "^16.4.0"
28
+ },
29
+ "devDependencies": {
30
+ "@types/node": "^22.14.0",
31
+ "@types/pg": "^8.11.0",
32
+ "typescript": "^5.9.3",
33
+ "tsup": "^8.5.1"
34
+ },
35
+ "peerDependencies": {
36
+ "typescript": ">=5.0.0"
37
+ },
38
+ "engines": {
39
+ "node": ">=18.0.0"
40
+ },
41
+ "keywords": [
42
+ "vaif",
43
+ "cli",
44
+ "codegen",
45
+ "typescript",
46
+ "types",
47
+ "database",
48
+ "schema"
49
+ ],
50
+ "author": "VAIF Technologies",
51
+ "license": "MIT",
52
+ "repository": {
53
+ "type": "git",
54
+ "url": "https://github.com/vaif-technologies/vaif-studio",
55
+ "directory": "packages/cli"
56
+ },
57
+ "bugs": {
58
+ "url": "https://github.com/vaif-technologies/vaif-studio/issues"
59
+ },
60
+ "homepage": "https://vaif.studio"
61
+ }