pg2zod 2.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/CHANGELOG.md +131 -0
- package/README.md +404 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +180 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.ts +216 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/src-18pV45Fu.js +835 -0
- package/dist/src-18pV45Fu.js.map +1 -0
- package/package.json +73 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 2.0.0
|
|
4
|
+
|
|
5
|
+
### Major Changes
|
|
6
|
+
|
|
7
|
+
- 64f3673: Initial release of pg-to-zod - a comprehensive PostgreSQL to Zod v4 schema generator.
|
|
8
|
+
|
|
9
|
+
**Features:**
|
|
10
|
+
|
|
11
|
+
- Complete PostgreSQL database introspection
|
|
12
|
+
- Comprehensive type coverage (50+ PostgreSQL types)
|
|
13
|
+
- Strict Zod v4 schema generation
|
|
14
|
+
- CHECK constraint parsing and automatic enum generation
|
|
15
|
+
- CLI interface with comprehensive options
|
|
16
|
+
- Programmatic API for integration
|
|
17
|
+
- Support for enums, domains, composite types, and range types
|
|
18
|
+
- Multi-dimensional array support
|
|
19
|
+
- Smart Insert/Update schema generation (default behavior)
|
|
20
|
+
- Schema-prefixed naming to avoid collisions
|
|
21
|
+
- Dual CJS/ESM module support
|
|
22
|
+
- Composite types optional (use `--composite-types` flag)
|
|
23
|
+
|
|
24
|
+
**Type Mappings:**
|
|
25
|
+
|
|
26
|
+
- All PostgreSQL built-in types with proper Zod v4 validators
|
|
27
|
+
- Custom types: enums, domains, composite types, range types
|
|
28
|
+
- Network types with proper validation (inet, cidr, macaddr)
|
|
29
|
+
- Geometric types support
|
|
30
|
+
- Arrays including multi-dimensional
|
|
31
|
+
|
|
32
|
+
**Schema Generation:**
|
|
33
|
+
|
|
34
|
+
- Three schemas per table: Read, Insert, Update
|
|
35
|
+
- Read schema reflects actual database structure
|
|
36
|
+
- Insert schema with intelligent optional field detection
|
|
37
|
+
- Update schema with `.partial()` for flexible updates
|
|
38
|
+
- Schema-prefixed naming (e.g., `PublicUsersSchema`)
|
|
39
|
+
|
|
40
|
+
All notable changes to this project will be documented in this file.
|
|
41
|
+
|
|
42
|
+
## [1.0.0] - 2026-01-10
|
|
43
|
+
|
|
44
|
+
### Initial Release
|
|
45
|
+
|
|
46
|
+
**Features:**
|
|
47
|
+
|
|
48
|
+
- Complete PostgreSQL database introspection
|
|
49
|
+
- Comprehensive type coverage (50+ PostgreSQL types)
|
|
50
|
+
- Strict Zod v4 schema generation
|
|
51
|
+
- CHECK constraint parsing and automatic enum generation
|
|
52
|
+
- CLI interface with comprehensive options
|
|
53
|
+
- Programmatic API for integration
|
|
54
|
+
- Support for enums, domains, composite types, and range types
|
|
55
|
+
- Multi-dimensional array support
|
|
56
|
+
- Smart Insert/Update schema generation (default behavior)
|
|
57
|
+
- Schema-prefixed naming to avoid collisions (e.g., `PublicUsersSchema`)
|
|
58
|
+
- camelCase field name conversion
|
|
59
|
+
- Environment variable support
|
|
60
|
+
- Composite types optional (use `--composite-types` flag)
|
|
61
|
+
|
|
62
|
+
**Type Mappings (Zod v4):**
|
|
63
|
+
|
|
64
|
+
- Basic types: smallint, integer, bigint, numeric, real, double precision
|
|
65
|
+
- Text types: varchar, char, text, citext with length constraints
|
|
66
|
+
- Boolean
|
|
67
|
+
- Date/time: date, timestamp, time (using `z.iso.time()`), interval (using `z.iso.duration()`)
|
|
68
|
+
- UUID: `z.uuid()`
|
|
69
|
+
- JSON/JSONB
|
|
70
|
+
- Network types: inet (`z.union([z.ipv4(), z.ipv6()])`), cidr (`z.union([z.cidrv4(), z.cidrv6()])`), macaddr (`z.mac()`)
|
|
71
|
+
- Geometric types: point, box, circle, polygon, etc.
|
|
72
|
+
- Arrays including multi-dimensional
|
|
73
|
+
- Bit strings
|
|
74
|
+
- Full-text search: tsvector, tsquery
|
|
75
|
+
- Binary data: bytea
|
|
76
|
+
- Custom types: enums, domains, composite types, range types
|
|
77
|
+
|
|
78
|
+
**Constraint Support:**
|
|
79
|
+
|
|
80
|
+
- NOT NULL awareness
|
|
81
|
+
- Length constraints (varchar, char)
|
|
82
|
+
- Numeric precision/scale
|
|
83
|
+
- CHECK constraint parsing and implementation:
|
|
84
|
+
- Numeric comparisons: `>, <, >=, <=`
|
|
85
|
+
- BETWEEN: `value BETWEEN min AND max`
|
|
86
|
+
- IN/ANY(ARRAY): `value = ANY (ARRAY[...])` → `z.enum([...])`
|
|
87
|
+
- Regex: `value ~ 'pattern'` → `z.string().regex(/pattern/)`
|
|
88
|
+
- Length: `length(value) >= n` → `z.string().min(n)`
|
|
89
|
+
- Default value handling
|
|
90
|
+
- Auto-generated fields (SERIAL, IDENTITY)
|
|
91
|
+
|
|
92
|
+
**Documentation:**
|
|
93
|
+
|
|
94
|
+
- Comprehensive README
|
|
95
|
+
- Getting Started guide
|
|
96
|
+
- Project summary
|
|
97
|
+
- Example schema SQL
|
|
98
|
+
- Example usage code
|
|
99
|
+
- CLI help documentation
|
|
100
|
+
|
|
101
|
+
### Changed (Zod v4 Updates)
|
|
102
|
+
|
|
103
|
+
Updated type mappings to use correct Zod v4 APIs following the Zod 4 migration:
|
|
104
|
+
|
|
105
|
+
**String Format Validators → Top-Level Helpers:**
|
|
106
|
+
|
|
107
|
+
- `z.string().uuid()` → `z.uuid()` (stricter RFC 9562/4122 compliant)
|
|
108
|
+
- `z.string().ip()` → `z.union([z.ipv4(), z.ipv6()])` (separate validators for IPv4/IPv6)
|
|
109
|
+
- `z.string().email()` → `z.email()` (top-level helper)
|
|
110
|
+
- `z.string().url()` → `z.url()` (top-level helper)
|
|
111
|
+
|
|
112
|
+
**ISO Date/Time Validators:**
|
|
113
|
+
|
|
114
|
+
- Time types now use `z.iso.time()` instead of regex
|
|
115
|
+
- Interval types now use `z.iso.duration()` for ISO 8601 duration strings
|
|
116
|
+
- Date types continue to use `z.date()` for JavaScript Date objects
|
|
117
|
+
|
|
118
|
+
**Network Types:**
|
|
119
|
+
|
|
120
|
+
- `inet` → `z.union([z.ipv4(), z.ipv6()])` (supports both IPv4 and IPv6)
|
|
121
|
+
- `cidr` → `z.union([z.cidrv4(), z.cidrv6()])` (supports both CIDR notations)
|
|
122
|
+
- `macaddr` → `z.mac()` (supports configurable delimiters)
|
|
123
|
+
- `macaddr8` → continues to use regex (64-bit MAC addresses)
|
|
124
|
+
|
|
125
|
+
**Benefits:**
|
|
126
|
+
|
|
127
|
+
- More accurate type validation using native Zod v4 validators
|
|
128
|
+
- Better error messages from specialized validators
|
|
129
|
+
- Stricter UUID validation (RFC compliant)
|
|
130
|
+
- Proper ISO 8601 time and duration parsing
|
|
131
|
+
- Improved IP address validation with separate IPv4/IPv6 types
|
package/README.md
ADDED
|
@@ -0,0 +1,404 @@
|
|
|
1
|
+
# pg-to-zod
|
|
2
|
+
|
|
3
|
+
> **Introspect PostgreSQL databases and generate strict, comprehensive Zod v4 schemas**
|
|
4
|
+
|
|
5
|
+
A modern TypeScript package that automatically generates high-quality, strict Zod schemas from your PostgreSQL database schema. Supports all PostgreSQL types including advanced features like enums, composite types, domains, ranges, arrays, and geometric types.
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
✨ **Comprehensive Type Coverage**
|
|
10
|
+
- All built-in PostgreSQL types (numeric, text, date/time, boolean, JSON, UUID, etc.)
|
|
11
|
+
- Custom types: enums, domains, composite types, range types
|
|
12
|
+
- Arrays (including multi-dimensional)
|
|
13
|
+
- Geometric types (point, box, circle, polygon, etc.)
|
|
14
|
+
- Network types (inet, cidr, macaddr)
|
|
15
|
+
- Full-text search types (tsvector, tsquery)
|
|
16
|
+
- Bit strings, XML, and more
|
|
17
|
+
|
|
18
|
+
🔒 **Strict & Safe**
|
|
19
|
+
- Length constraints (`varchar(n)` → `.max(n)`)
|
|
20
|
+
- Precision/scale validation for numeric types
|
|
21
|
+
- Format validations (UUID, IP, MAC addresses, etc.)
|
|
22
|
+
- CHECK constraint parsing (comparisons, BETWEEN, IN, ANY/ARRAY, regex)
|
|
23
|
+
- Automatic enum generation from CHECK constraints
|
|
24
|
+
- NOT NULL awareness
|
|
25
|
+
|
|
26
|
+
🎯 **Smart Code Generation**
|
|
27
|
+
- Read schemas (reflect actual DB structure)
|
|
28
|
+
- Insert schemas (intelligent optional field detection based on defaults/auto-generation)
|
|
29
|
+
- Update schemas (all fields optional but maintain validation)
|
|
30
|
+
- TypeScript type inference support with `z.infer<>`
|
|
31
|
+
- Schema-prefixed naming to avoid collisions (e.g., `PublicUsersSchema`)
|
|
32
|
+
- Optional camelCase conversion
|
|
33
|
+
- CHECK constraint parsing and implementation
|
|
34
|
+
- Comprehensive comments
|
|
35
|
+
|
|
36
|
+
🚀 **Modern Stack**
|
|
37
|
+
- ESM-first
|
|
38
|
+
- TypeScript with strict mode
|
|
39
|
+
- Zod v4 (latest beta)
|
|
40
|
+
- CLI + Programmatic API
|
|
41
|
+
|
|
42
|
+
## Installation
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
npm install pg-to-zod
|
|
46
|
+
# or
|
|
47
|
+
pnpm add pg-to-zod
|
|
48
|
+
# or
|
|
49
|
+
yarn add pg-to-zod
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Quick Start
|
|
53
|
+
|
|
54
|
+
### CLI Usage
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
# Generate schemas from a local database (includes input schemas by default)
|
|
58
|
+
pg-to-zod --database mydb --output src/db/schema.ts
|
|
59
|
+
|
|
60
|
+
# Use a connection URL
|
|
61
|
+
pg-to-zod --url postgresql://user:pass@localhost:5432/mydb -o schema.ts
|
|
62
|
+
|
|
63
|
+
# Skip input schemas if you only need read schemas
|
|
64
|
+
pg-to-zod --database mydb --no-input-schemas --output schema.ts
|
|
65
|
+
|
|
66
|
+
# Include composite types (skipped by default)
|
|
67
|
+
pg-to-zod --database mydb --composite-types --output schema.ts
|
|
68
|
+
|
|
69
|
+
# Use camelCase for field names
|
|
70
|
+
pg-to-zod --database mydb --camel-case -o schema.ts
|
|
71
|
+
|
|
72
|
+
# Include specific tables only
|
|
73
|
+
pg-to-zod --database mydb --tables users,posts,comments -o schema.ts
|
|
74
|
+
|
|
75
|
+
# Multiple schemas
|
|
76
|
+
pg-to-zod --database mydb --schemas public,auth,api -o schema.ts
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Programmatic API
|
|
80
|
+
|
|
81
|
+
```typescript
|
|
82
|
+
import { generateZodSchemasString } from 'pg-to-zod';
|
|
83
|
+
|
|
84
|
+
const schemas = await generateZodSchemasString(
|
|
85
|
+
{
|
|
86
|
+
host: 'localhost',
|
|
87
|
+
port: 5432,
|
|
88
|
+
database: 'mydb',
|
|
89
|
+
user: 'postgres',
|
|
90
|
+
password: 'password',
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
schemas: ['public'],
|
|
94
|
+
generateInputSchemas: true,
|
|
95
|
+
includeComments: true,
|
|
96
|
+
strictMode: false,
|
|
97
|
+
}
|
|
98
|
+
);
|
|
99
|
+
|
|
100
|
+
console.log(schemas);
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Type Mapping
|
|
104
|
+
|
|
105
|
+
### Built-in Types
|
|
106
|
+
|
|
107
|
+
| PostgreSQL Type | Zod Schema |
|
|
108
|
+
|----------------|------------|
|
|
109
|
+
| `smallint`, `integer` | `z.number().int()` |
|
|
110
|
+
| `bigint` | `z.bigint()` |
|
|
111
|
+
| `numeric(p,s)`, `decimal` | `z.number()` with precision/scale comment |
|
|
112
|
+
| `real`, `double precision` | `z.number()` |
|
|
113
|
+
| `varchar(n)` | `z.string().max(n)` |
|
|
114
|
+
| `char(n)` | `z.string().length(n)` |
|
|
115
|
+
| `text` | `z.string()` |
|
|
116
|
+
| `boolean` | `z.boolean()` |
|
|
117
|
+
| `date`, `timestamp` | `z.date()` |
|
|
118
|
+
| `time` | `z.iso.time()` |
|
|
119
|
+
| `interval` | `z.iso.duration()` |
|
|
120
|
+
| `uuid` | `z.uuid()` |
|
|
121
|
+
| `json`, `jsonb` | `z.record(z.string(), z.unknown())` |
|
|
122
|
+
| `inet` | `z.union([z.ipv4(), z.ipv6()])` |
|
|
123
|
+
| `cidr` | `z.union([z.cidrv4(), z.cidrv6()])` |
|
|
124
|
+
| `macaddr` | `z.mac()` |
|
|
125
|
+
| `point` | `z.tuple([z.number(), z.number()])` |
|
|
126
|
+
| `circle` | `z.object({ center: ..., radius: ... })` |
|
|
127
|
+
| `polygon` | `z.array(z.tuple([z.number(), z.number()]))` |
|
|
128
|
+
| Arrays | `z.array(...)` (nested for multi-dimensional) |
|
|
129
|
+
|
|
130
|
+
### Custom Types
|
|
131
|
+
|
|
132
|
+
**Enums:**
|
|
133
|
+
```sql
|
|
134
|
+
CREATE TYPE status AS ENUM ('pending', 'active', 'inactive');
|
|
135
|
+
```
|
|
136
|
+
→
|
|
137
|
+
```typescript
|
|
138
|
+
export const StatusSchema = z.enum(['pending', 'active', 'inactive']);
|
|
139
|
+
export type Status = z.infer<typeof StatusSchema>;
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
**Domains:**
|
|
143
|
+
```sql
|
|
144
|
+
CREATE DOMAIN email AS TEXT CHECK (VALUE ~ '^[^@]+@[^@]+$');
|
|
145
|
+
```
|
|
146
|
+
→
|
|
147
|
+
```typescript
|
|
148
|
+
export const EmailSchema = z.string().regex(/^[^@]+@[^@]+$/);
|
|
149
|
+
export type Email = z.infer<typeof EmailSchema>;
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
**Composite Types:**
|
|
153
|
+
```sql
|
|
154
|
+
CREATE TYPE address AS (street TEXT, city TEXT, zip VARCHAR(10));
|
|
155
|
+
```
|
|
156
|
+
→
|
|
157
|
+
```typescript
|
|
158
|
+
export const AddressSchema = z.object({
|
|
159
|
+
street: z.string(),
|
|
160
|
+
city: z.string(),
|
|
161
|
+
zip: z.string().max(10),
|
|
162
|
+
});
|
|
163
|
+
export type Address = z.infer<typeof AddressSchema>;
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
**Range Types:**
|
|
167
|
+
```sql
|
|
168
|
+
-- int4range, daterange, tstzrange, etc.
|
|
169
|
+
```
|
|
170
|
+
→
|
|
171
|
+
```typescript
|
|
172
|
+
export const Int4rangeSchema = z.tuple([z.number().int().nullable(), z.number().int().nullable()]);
|
|
173
|
+
export type Int4range = z.infer<typeof Int4rangeSchema>;
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### Check Constraints
|
|
177
|
+
|
|
178
|
+
CHECK constraints are automatically parsed and translated to Zod validations:
|
|
179
|
+
|
|
180
|
+
```sql
|
|
181
|
+
CREATE TABLE products (
|
|
182
|
+
price NUMERIC CHECK (price > 0),
|
|
183
|
+
quantity INTEGER CHECK (quantity >= 0 AND quantity <= 1000),
|
|
184
|
+
code VARCHAR(20) CHECK (code ~ '^[A-Z]{3}-\d{4}$'),
|
|
185
|
+
status TEXT CHECK (status = ANY (ARRAY['draft', 'published', 'archived']))
|
|
186
|
+
);
|
|
187
|
+
```
|
|
188
|
+
→
|
|
189
|
+
```typescript
|
|
190
|
+
export const PublicProductsSchema = z.object({
|
|
191
|
+
price: z.number().min(0.00000000000001),
|
|
192
|
+
quantity: z.number().int().min(0).max(1000),
|
|
193
|
+
code: z.string().regex(/^[A-Z]{3}-\d{4}$/),
|
|
194
|
+
status: z.enum(['draft', 'published', 'archived']),
|
|
195
|
+
});
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
**Supported CHECK constraint patterns:**
|
|
199
|
+
- Numeric comparisons: `>, <, >=, <=`
|
|
200
|
+
- BETWEEN: `value BETWEEN min AND max`
|
|
201
|
+
- IN/ANY(ARRAY): `value = ANY (ARRAY['a', 'b'])` → `z.enum(['a', 'b'])`
|
|
202
|
+
- Regex: `value ~ 'pattern'` → `z.string().regex(/pattern/)`
|
|
203
|
+
- Length: `length(value) >= n` → `z.string().min(n)`
|
|
204
|
+
|
|
205
|
+
## CLI Options
|
|
206
|
+
|
|
207
|
+
### Connection Options
|
|
208
|
+
```
|
|
209
|
+
--url <url> PostgreSQL connection URL
|
|
210
|
+
--host <host> Database host (default: localhost)
|
|
211
|
+
--port <port> Database port (default: 5432)
|
|
212
|
+
--database <database> Database name (default: postgres)
|
|
213
|
+
--user <user> Database user (default: postgres)
|
|
214
|
+
--password <password> Database password
|
|
215
|
+
--ssl Use SSL connection
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
### Generation Options
|
|
219
|
+
```
|
|
220
|
+
--schemas <schemas> Comma-separated list of schemas (default: public)
|
|
221
|
+
--tables <tables> Include only these tables
|
|
222
|
+
--exclude-tables <tables> Exclude these tables
|
|
223
|
+
--no-input-schemas Skip input schemas (generated by default)
|
|
224
|
+
--composite-types Include composite types (skipped by default)
|
|
225
|
+
--branded-types Use branded types for IDs (future)
|
|
226
|
+
--strict Fail on unmapped types
|
|
227
|
+
--no-comments Don't include comments
|
|
228
|
+
--camel-case Convert field names to camelCase
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
### Output Options
|
|
232
|
+
```
|
|
233
|
+
--output <file> Output file path (default: schema.ts)
|
|
234
|
+
-o <file> Short form of --output
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
## Programmatic API
|
|
238
|
+
|
|
239
|
+
### Main Functions
|
|
240
|
+
|
|
241
|
+
```typescript
|
|
242
|
+
import {
|
|
243
|
+
generateZodSchemas,
|
|
244
|
+
generateZodSchemasString,
|
|
245
|
+
introspectDatabase,
|
|
246
|
+
generateSchemas,
|
|
247
|
+
formatOutput,
|
|
248
|
+
} from 'pg-to-zod';
|
|
249
|
+
|
|
250
|
+
// Complete flow: introspect + generate + format
|
|
251
|
+
const result = await generateZodSchemas(config, options);
|
|
252
|
+
|
|
253
|
+
// Get formatted string output
|
|
254
|
+
const schemaString = await generateZodSchemasString(config, options);
|
|
255
|
+
|
|
256
|
+
// Step-by-step
|
|
257
|
+
const metadata = await introspectDatabase(config, options);
|
|
258
|
+
const result = generateSchemas(metadata, options);
|
|
259
|
+
const output = formatOutput(result);
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
### Types
|
|
263
|
+
|
|
264
|
+
```typescript
|
|
265
|
+
interface DatabaseConfig {
|
|
266
|
+
host: string;
|
|
267
|
+
port: number;
|
|
268
|
+
database: string;
|
|
269
|
+
user: string;
|
|
270
|
+
password: string;
|
|
271
|
+
ssl?: boolean | { rejectUnauthorized: boolean };
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
interface SchemaGenerationOptions {
|
|
275
|
+
schemas?: string[]; // Default: ['public']
|
|
276
|
+
tables?: string[]; // Include only these
|
|
277
|
+
excludeTables?: string[]; // Exclude these
|
|
278
|
+
generateInputSchemas?: boolean; // Generate Insert/Update schemas (default: true)
|
|
279
|
+
includeCompositeTypes?: boolean; // Include composite types (default: false)
|
|
280
|
+
useBrandedTypes?: boolean; // Use branded types (future)
|
|
281
|
+
strictMode?: boolean; // Fail on unknown types
|
|
282
|
+
includeComments?: boolean; // Include comments (default: true)
|
|
283
|
+
useCamelCase?: boolean; // Convert to camelCase
|
|
284
|
+
customTypeMappings?: Record<string, string>; // Custom mappings
|
|
285
|
+
}
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
## Examples
|
|
289
|
+
|
|
290
|
+
### Example Database
|
|
291
|
+
|
|
292
|
+
```sql
|
|
293
|
+
-- Create enum
|
|
294
|
+
CREATE TYPE user_role AS ENUM ('admin', 'user', 'guest');
|
|
295
|
+
|
|
296
|
+
-- Create domain
|
|
297
|
+
CREATE DOMAIN email AS VARCHAR(255)
|
|
298
|
+
CHECK (VALUE ~ '^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$');
|
|
299
|
+
|
|
300
|
+
-- Create table
|
|
301
|
+
CREATE TABLE users (
|
|
302
|
+
id SERIAL PRIMARY KEY,
|
|
303
|
+
username VARCHAR(50) NOT NULL UNIQUE,
|
|
304
|
+
email email NOT NULL,
|
|
305
|
+
role user_role DEFAULT 'user',
|
|
306
|
+
age INTEGER CHECK (age >= 18 AND age <= 120),
|
|
307
|
+
tags TEXT[],
|
|
308
|
+
metadata JSONB,
|
|
309
|
+
created_at TIMESTAMPTZ DEFAULT NOW()
|
|
310
|
+
);
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
### Generated Output
|
|
314
|
+
|
|
315
|
+
```typescript
|
|
316
|
+
// Generated by pg-to-zod
|
|
317
|
+
// Do not edit manually
|
|
318
|
+
|
|
319
|
+
import { z } from 'zod';
|
|
320
|
+
|
|
321
|
+
// ============================================
|
|
322
|
+
// Enums
|
|
323
|
+
// ============================================
|
|
324
|
+
|
|
325
|
+
/** PostgreSQL enum: user_role */
|
|
326
|
+
export const PublicUserRoleSchema = z.enum(['admin', 'user', 'guest']);
|
|
327
|
+
export type PublicUserRole = z.infer<typeof PublicUserRoleSchema>;
|
|
328
|
+
|
|
329
|
+
// ============================================
|
|
330
|
+
// Domains
|
|
331
|
+
// ============================================
|
|
332
|
+
|
|
333
|
+
/** PostgreSQL domain: email (base: character varying) */
|
|
334
|
+
export const PublicEmailSchema = z.string().max(255).regex(/^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$/);
|
|
335
|
+
export type PublicEmail = z.infer<typeof PublicEmailSchema>;
|
|
336
|
+
|
|
337
|
+
// ============================================
|
|
338
|
+
// Tables
|
|
339
|
+
// ============================================
|
|
340
|
+
|
|
341
|
+
/** Table: public.users - Read schema */
|
|
342
|
+
export const PublicUsersSchema = z.object({
|
|
343
|
+
id: z.number().int(),
|
|
344
|
+
username: z.string().max(50),
|
|
345
|
+
email: PublicEmailSchema,
|
|
346
|
+
role: PublicUserRoleSchema,
|
|
347
|
+
age: z.number().int().min(18).max(120).nullable(),
|
|
348
|
+
tags: z.array(z.string()).nullable(),
|
|
349
|
+
metadata: z.record(z.string(), z.unknown()).nullable(),
|
|
350
|
+
created_at: z.date(),
|
|
351
|
+
});
|
|
352
|
+
export type PublicUsers = z.infer<typeof PublicUsersSchema>;
|
|
353
|
+
|
|
354
|
+
/** Insert schema for users - only auto-generated fields and fields with defaults are optional */
|
|
355
|
+
export const PublicUsersInsertSchema = z.object({
|
|
356
|
+
id: z.number().int().optional(), // auto-generated: SERIAL/identity
|
|
357
|
+
username: z.string().max(50), // required: no default
|
|
358
|
+
email: PublicEmailSchema, // required: no default
|
|
359
|
+
role: PublicUserRoleSchema.optional(), // optional: has DEFAULT 'user'
|
|
360
|
+
age: z.number().int().min(18).max(120).nullable(), // nullable but no default, so required
|
|
361
|
+
tags: z.array(z.string()).nullable(), // nullable but no default, so required
|
|
362
|
+
metadata: z.record(z.string(), z.unknown()).nullable(), // nullable but no default, so required
|
|
363
|
+
created_at: z.date().optional(), // optional: has DEFAULT NOW()
|
|
364
|
+
});
|
|
365
|
+
export type PublicUsersInsert = z.infer<typeof PublicUsersInsertSchema>;
|
|
366
|
+
|
|
367
|
+
/** Update schema for users - all fields optional, primary keys excluded, validation preserved */
|
|
368
|
+
export const PublicUsersUpdateSchema = z.object({
|
|
369
|
+
username: z.string().max(50).optional(),
|
|
370
|
+
email: PublicEmailSchema.optional(),
|
|
371
|
+
role: PublicUserRoleSchema.optional(),
|
|
372
|
+
age: z.number().int().min(18).max(120).optional().nullable(),
|
|
373
|
+
tags: z.array(z.string()).optional().nullable(),
|
|
374
|
+
metadata: z.record(z.string(), z.unknown()).optional().nullable(),
|
|
375
|
+
created_at: z.date().optional(),
|
|
376
|
+
});
|
|
377
|
+
export type PublicUsersUpdate = z.infer<typeof PublicUsersUpdateSchema>;
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
## Environment Variables
|
|
381
|
+
|
|
382
|
+
Set these to avoid passing credentials via CLI:
|
|
383
|
+
|
|
384
|
+
```bash
|
|
385
|
+
export PGHOST=localhost
|
|
386
|
+
export PGPORT=5432
|
|
387
|
+
export PGDATABASE=mydb
|
|
388
|
+
export PGUSER=postgres
|
|
389
|
+
export PGPASSWORD=password
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
## Contributing
|
|
393
|
+
|
|
394
|
+
Contributions welcome! Please open an issue or PR.
|
|
395
|
+
|
|
396
|
+
## License
|
|
397
|
+
|
|
398
|
+
MIT
|
|
399
|
+
|
|
400
|
+
## Credits
|
|
401
|
+
|
|
402
|
+
Built with:
|
|
403
|
+
- [pg](https://github.com/brianc/node-postgres) - PostgreSQL client
|
|
404
|
+
- [zod](https://github.com/colinhacks/zod) - TypeScript-first schema validation
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { };
|