pg2zod 2.1.0 → 2.1.2

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 CHANGED
@@ -1,5 +1,29 @@
1
1
  # Changelog
2
2
 
3
+ ## 2.1.2
4
+
5
+ ### Patch Changes
6
+
7
+ - 9cd667c: Filter internal PostgreSQL functions and handle duplicates
8
+
9
+ **Bug Fixes:**
10
+
11
+ - Fixed type errors in view column metadata generation
12
+ - Removed invalid fields (ordinalPosition, isIdentity, etc.) from ColumnMetadata
13
+
14
+ **Improvements:**
15
+
16
+ - Filter out internal PostgreSQL system functions (functions using internal, trigger, cstring, "char", and other low-level types)
17
+ - Skip functions with duplicate parameter names that would cause invalid TypeScript
18
+ - Skip overloaded functions - only keep first occurrence to avoid naming conflicts
19
+ - Significantly reduces generated function count (from 261 to ~50-60 for typical databases)
20
+ - Generated schemas now compile without TypeScript errors
21
+
22
+ **Quality:**
23
+
24
+ - Ensures only user-facing, application-relevant functions are included in generated schemas
25
+ - Cleaner output with fewer warnings about unmapped internal types
26
+
3
27
  ## 2.1.0
4
28
 
5
29
  ### Minor Changes
package/README.md CHANGED
@@ -1,12 +1,15 @@
1
- # pg-to-zod
1
+ # pg2zod
2
2
 
3
3
  > **Introspect PostgreSQL databases and generate strict, comprehensive Zod v4 schemas**
4
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.
5
+ A modern TypeScript package that automatically generates high-quality, strict Zod schemas from your PostgreSQL database
6
+ schema. Supports all PostgreSQL types including advanced features like enums, composite types, domains, ranges, arrays,
7
+ and geometric types.
6
8
 
7
9
  ## Features
8
10
 
9
11
  ✨ **Comprehensive Type Coverage**
12
+
10
13
  - All built-in PostgreSQL types (numeric, text, date/time, boolean, JSON, UUID, etc.)
11
14
  - Custom types: enums, domains, composite types, range types
12
15
  - Database views (read-only schemas)
@@ -18,6 +21,7 @@ A modern TypeScript package that automatically generates high-quality, strict Zo
18
21
  - Bit strings, XML, and more
19
22
 
20
23
  🔒 **Strict & Safe**
24
+
21
25
  - Length constraints (`varchar(n)` → `.max(n)`)
22
26
  - Precision/scale validation for numeric types
23
27
  - Format validations (UUID, IP, MAC addresses, etc.)
@@ -26,6 +30,7 @@ A modern TypeScript package that automatically generates high-quality, strict Zo
26
30
  - NOT NULL awareness
27
31
 
28
32
  🎯 **Smart Code Generation**
33
+
29
34
  - Read schemas (reflect actual DB structure)
30
35
  - Insert schemas (intelligent optional field detection based on defaults/auto-generation)
31
36
  - Update schemas (all fields optional but maintain validation)
@@ -36,6 +41,7 @@ A modern TypeScript package that automatically generates high-quality, strict Zo
36
41
  - Comprehensive comments
37
42
 
38
43
  🚀 **Modern Stack**
44
+
39
45
  - ESM-first
40
46
  - TypeScript with strict mode
41
47
  - Zod v4 (latest beta)
@@ -44,11 +50,11 @@ A modern TypeScript package that automatically generates high-quality, strict Zo
44
50
  ## Installation
45
51
 
46
52
  ```bash
47
- npm install pg-to-zod
53
+ npm install pg2zod
48
54
  # or
49
- pnpm add pg-to-zod
55
+ pnpm add pg2zod
50
56
  # or
51
- yarn add pg-to-zod
57
+ yarn add pg2zod
52
58
  ```
53
59
 
54
60
  ## Quick Start
@@ -57,55 +63,55 @@ yarn add pg-to-zod
57
63
 
58
64
  ```bash
59
65
  # Generate schemas from a local database (includes input schemas by default)
60
- pg-to-zod --database mydb --output src/db/schema.ts
66
+ pg2zod --database mydb --output src/db/schema.ts
61
67
 
62
68
  # Use a connection URL
63
- pg-to-zod --url postgresql://user:pass@localhost:5432/mydb -o schema.ts
69
+ pg2zod --url postgresql://user:pass@localhost:5432/mydb -o schema.ts
64
70
 
65
71
  # Skip input schemas if you only need read schemas
66
- pg-to-zod --database mydb --no-input-schemas --output schema.ts
72
+ pg2zod --database mydb --no-input-schemas --output schema.ts
67
73
 
68
74
  # Include composite types (skipped by default)
69
- pg-to-zod --database mydb --composite-types --output schema.ts
75
+ pg2zod --database mydb --composite-types --output schema.ts
70
76
 
71
77
  # Include database views
72
- pg-to-zod --database mydb --views --output schema.ts
78
+ pg2zod --database mydb --views --output schema.ts
73
79
 
74
80
  # Include functions/procedures (SECURITY DEFINER only by default)
75
- pg-to-zod --database mydb --routines --output schema.ts
81
+ pg2zod --database mydb --routines --output schema.ts
76
82
 
77
83
  # Include all functions including SECURITY INVOKER
78
- pg-to-zod --database mydb --routines --security-invoker --output schema.ts
84
+ pg2zod --database mydb --routines --security-invoker --output schema.ts
79
85
 
80
86
  # Use camelCase for field names
81
- pg-to-zod --database mydb --camel-case -o schema.ts
87
+ pg2zod --database mydb --camel-case -o schema.ts
82
88
 
83
89
  # Include specific tables only
84
- pg-to-zod --database mydb --tables users,posts,comments -o schema.ts
90
+ pg2zod --database mydb --tables users,posts,comments -o schema.ts
85
91
 
86
92
  # Multiple schemas
87
- pg-to-zod --database mydb --schemas public,auth,api -o schema.ts
93
+ pg2zod --database mydb --schemas public,auth,api -o schema.ts
88
94
  ```
89
95
 
90
96
  ### Programmatic API
91
97
 
92
98
  ```typescript
93
- import { generateZodSchemasString } from 'pg-to-zod';
99
+ import {generateZodSchemasString} from 'pg2zod';
94
100
 
95
101
  const schemas = await generateZodSchemasString(
96
- {
97
- host: 'localhost',
98
- port: 5432,
99
- database: 'mydb',
100
- user: 'postgres',
101
- password: 'password',
102
- },
103
- {
104
- schemas: ['public'],
105
- generateInputSchemas: true,
106
- includeComments: true,
107
- strictMode: false,
108
- }
102
+ {
103
+ host: 'localhost',
104
+ port: 5432,
105
+ database: 'mydb',
106
+ user: 'postgres',
107
+ password: 'password',
108
+ },
109
+ {
110
+ schemas: ['public'],
111
+ generateInputSchemas: true,
112
+ includeComments: true,
113
+ strictMode: false,
114
+ }
109
115
  );
110
116
 
111
117
  console.log(schemas);
@@ -115,120 +121,143 @@ console.log(schemas);
115
121
 
116
122
  ### Built-in Types
117
123
 
118
- | PostgreSQL Type | Zod Schema |
119
- |----------------|------------|
120
- | `smallint`, `integer` | `z.number().int()` |
121
- | `bigint` | `z.bigint()` |
122
- | `numeric(p,s)`, `decimal` | `z.number()` with precision/scale comment |
123
- | `real`, `double precision` | `z.number()` |
124
- | `varchar(n)` | `z.string().max(n)` |
125
- | `char(n)` | `z.string().length(n)` |
126
- | `text` | `z.string()` |
127
- | `boolean` | `z.boolean()` |
128
- | `date`, `timestamp` | `z.date()` |
129
- | `time` | `z.iso.time()` |
130
- | `interval` | `z.iso.duration()` |
131
- | `uuid` | `z.uuid()` |
132
- | `json`, `jsonb` | `z.record(z.string(), z.unknown())` |
133
- | `inet` | `z.union([z.ipv4(), z.ipv6()])` |
134
- | `cidr` | `z.union([z.cidrv4(), z.cidrv6()])` |
135
- | `macaddr` | `z.mac()` |
136
- | `point` | `z.tuple([z.number(), z.number()])` |
137
- | `circle` | `z.object({ center: ..., radius: ... })` |
138
- | `polygon` | `z.array(z.tuple([z.number(), z.number()]))` |
139
- | Arrays | `z.array(...)` (nested for multi-dimensional) |
124
+ | PostgreSQL Type | Zod Schema |
125
+ |----------------------------|-----------------------------------------------|
126
+ | `smallint`, `integer` | `z.number().int()` |
127
+ | `bigint` | `z.bigint()` |
128
+ | `numeric(p,s)`, `decimal` | `z.number()` with precision/scale comment |
129
+ | `real`, `double precision` | `z.number()` |
130
+ | `varchar(n)` | `z.string().max(n)` |
131
+ | `char(n)` | `z.string().length(n)` |
132
+ | `text` | `z.string()` |
133
+ | `boolean` | `z.boolean()` |
134
+ | `date`, `timestamp` | `z.date()` |
135
+ | `time` | `z.iso.time()` |
136
+ | `interval` | `z.iso.duration()` |
137
+ | `uuid` | `z.uuid()` |
138
+ | `json`, `jsonb` | `z.record(z.string(), z.unknown())` |
139
+ | `inet` | `z.union([z.ipv4(), z.ipv6()])` |
140
+ | `cidr` | `z.union([z.cidrv4(), z.cidrv6()])` |
141
+ | `macaddr` | `z.mac()` |
142
+ | `point` | `z.tuple([z.number(), z.number()])` |
143
+ | `circle` | `z.object({ center: ..., radius: ... })` |
144
+ | `polygon` | `z.array(z.tuple([z.number(), z.number()]))` |
145
+ | Arrays | `z.array(...)` (nested for multi-dimensional) |
140
146
 
141
147
  ### Custom Types
142
148
 
143
149
  **Enums:**
150
+
144
151
  ```sql
145
152
  CREATE TYPE status AS ENUM ('pending', 'active', 'inactive');
146
153
  ```
154
+
147
155
 
156
+
148
157
  ```typescript
149
158
  export const StatusSchema = z.enum(['pending', 'active', 'inactive']);
150
159
  export type Status = z.infer<typeof StatusSchema>;
151
160
  ```
152
161
 
153
162
  **Domains:**
163
+
154
164
  ```sql
155
165
  CREATE DOMAIN email AS TEXT CHECK (VALUE ~ '^[^@]+@[^@]+$');
156
166
  ```
167
+
157
168
 
169
+
158
170
  ```typescript
159
171
  export const EmailSchema = z.string().regex(/^[^@]+@[^@]+$/);
160
172
  export type Email = z.infer<typeof EmailSchema>;
161
173
  ```
162
174
 
163
175
  **Composite Types:**
176
+
164
177
  ```sql
165
178
  CREATE TYPE address AS (street TEXT, city TEXT, zip VARCHAR(10));
166
179
  ```
180
+
167
181
 
182
+
168
183
  ```typescript
169
184
  export const AddressSchema = z.object({
170
- street: z.string(),
171
- city: z.string(),
172
- zip: z.string().max(10),
185
+ street: z.string(),
186
+ city: z.string(),
187
+ zip: z.string().max(10),
173
188
  });
174
189
  export type Address = z.infer<typeof AddressSchema>;
175
190
  ```
176
191
 
177
192
  **Range Types:**
193
+
178
194
  ```sql
179
195
  -- int4range, daterange, tstzrange, etc.
180
196
  ```
197
+
181
198
 
199
+
182
200
  ```typescript
183
201
  export const Int4rangeSchema = z.tuple([z.number().int().nullable(), z.number().int().nullable()]);
184
202
  export type Int4range = z.infer<typeof Int4rangeSchema>;
185
203
  ```
186
204
 
187
205
  **Views:**
206
+
188
207
  ```sql
189
208
  CREATE VIEW user_stats AS
190
- SELECT
191
- u.id,
192
- u.username,
193
- COUNT(o.id) as order_count
209
+ SELECT u.id,
210
+ u.username,
211
+ COUNT(o.id) as order_count
194
212
  FROM users u
195
- LEFT JOIN orders o ON u.id = o.user_id
213
+ LEFT JOIN orders o ON u.id = o.user_id
196
214
  GROUP BY u.id, u.username;
197
215
  ```
216
+
198
217
 
218
+
199
219
  ```typescript
200
220
  /** View: public.user_stats (read-only) */
201
221
  export const PublicUserStatsSchema = z.object({
202
- id: z.number().int(),
203
- username: z.string(),
204
- order_count: z.number().int(),
205
- });
222
+ id: z.number().int(),
223
+ username: z.string(),
224
+ order_count: z.number().int(),
225
+ });
206
226
  export type PublicUserStats = z.infer<typeof PublicUserStatsSchema>;
207
227
  ```
208
228
 
209
229
  **Functions/Procedures:**
230
+
210
231
  ```sql
211
232
  CREATE FUNCTION get_user_by_id(user_id INTEGER)
212
- RETURNS TABLE(id INTEGER, username VARCHAR, email VARCHAR) AS $$
233
+ RETURNS TABLE
234
+ (
235
+ id INTEGER,
236
+ username VARCHAR,
237
+ email VARCHAR
238
+ ) AS $$
213
239
  BEGIN
214
- RETURN QUERY SELECT u.id, u.username, u.email FROM users u WHERE u.id = user_id;
240
+ RETURN QUERY SELECT u.id, u.username, u.email FROM users u WHERE u.id = user_id;
215
241
  END;
216
- $$ LANGUAGE plpgsql SECURITY DEFINER;
242
+ $$
243
+ LANGUAGE plpgsql SECURITY DEFINER;
217
244
  ```
245
+
218
246
 
247
+
219
248
  ```typescript
220
249
  /** FUNCTION: public.get_user_by_id */
221
250
  export const PublicGetUserByIdParamsSchema = z.object({
222
- /** integer (IN) */
223
- user_id: z.number().int(),
224
- });
251
+ /** integer (IN) */
252
+ user_id: z.number().int(),
253
+ });
225
254
  export type PublicGetUserByIdParams = z.infer<typeof PublicGetUserByIdParamsSchema>;
226
255
 
227
256
  /** Returns: record */
228
257
  export const PublicGetUserByIdReturnSchema = z.array(z.object({
229
- id: z.number().int(),
230
- username: z.string(),
231
- email: z.string(),
258
+ id: z.number().int(),
259
+ username: z.string(),
260
+ email: z.string(),
232
261
  }));
233
262
  export type PublicGetUserByIdReturn = z.infer<typeof PublicGetUserByIdReturnSchema>;
234
263
  ```
@@ -238,24 +267,29 @@ export type PublicGetUserByIdReturn = z.infer<typeof PublicGetUserByIdReturnSche
238
267
  CHECK constraints are automatically parsed and translated to Zod validations:
239
268
 
240
269
  ```sql
241
- CREATE TABLE products (
242
- price NUMERIC CHECK (price > 0),
243
- quantity INTEGER CHECK (quantity >= 0 AND quantity <= 1000),
244
- code VARCHAR(20) CHECK (code ~ '^[A-Z]{3}-\d{4}$'),
270
+ CREATE TABLE products
271
+ (
272
+ price NUMERIC CHECK (price > 0),
273
+ quantity INTEGER CHECK (quantity >= 0 AND quantity <= 1000),
274
+ code VARCHAR(20) CHECK (code ~ '^[A-Z]{3}-\d{4}$'
275
+ ) ,
245
276
  status TEXT CHECK (status = ANY (ARRAY['draft', 'published', 'archived']))
246
277
  );
247
278
  ```
279
+
248
280
 
281
+
249
282
  ```typescript
250
283
  export const PublicProductsSchema = z.object({
251
- price: z.number().min(0.00000000000001),
252
- quantity: z.number().int().min(0).max(1000),
253
- code: z.string().regex(/^[A-Z]{3}-\d{4}$/),
254
- status: z.enum(['draft', 'published', 'archived']),
284
+ price: z.number().min(0.00000000000001),
285
+ quantity: z.number().int().min(0).max(1000),
286
+ code: z.string().regex(/^[A-Z]{3}-\d{4}$/),
287
+ status: z.enum(['draft', 'published', 'archived']),
255
288
  });
256
289
  ```
257
290
 
258
291
  **Supported CHECK constraint patterns:**
292
+
259
293
  - Numeric comparisons: `>, <, >=, <=`
260
294
  - BETWEEN: `value BETWEEN min AND max`
261
295
  - IN/ANY(ARRAY): `value = ANY (ARRAY['a', 'b'])` → `z.enum(['a', 'b'])`
@@ -265,6 +299,7 @@ export const PublicProductsSchema = z.object({
265
299
  ## CLI Options
266
300
 
267
301
  ### Connection Options
302
+
268
303
  ```
269
304
  --url <url> PostgreSQL connection URL
270
305
  --host <host> Database host (default: localhost)
@@ -276,6 +311,7 @@ export const PublicProductsSchema = z.object({
276
311
  ```
277
312
 
278
313
  ### Generation Options
314
+
279
315
  ```
280
316
  --schemas <schemas> Comma-separated list of schemas (default: public)
281
317
  --tables <tables> Include only these tables
@@ -292,6 +328,7 @@ export const PublicProductsSchema = z.object({
292
328
  ```
293
329
 
294
330
  ### Output Options
331
+
295
332
  ```
296
333
  --output <file> Output file path (default: schema.ts)
297
334
  -o <file> Short form of --output
@@ -303,12 +340,12 @@ export const PublicProductsSchema = z.object({
303
340
 
304
341
  ```typescript
305
342
  import {
306
- generateZodSchemas,
307
- generateZodSchemasString,
308
- introspectDatabase,
309
- generateSchemas,
310
- formatOutput,
311
- } from 'pg-to-zod';
343
+ generateZodSchemas,
344
+ generateZodSchemasString,
345
+ introspectDatabase,
346
+ generateSchemas,
347
+ formatOutput,
348
+ } from 'pg2zod';
312
349
 
313
350
  // Complete flow: introspect + generate + format
314
351
  const result = await generateZodSchemas(config, options);
@@ -318,36 +355,36 @@ const schemaString = await generateZodSchemasString(config, options);
318
355
 
319
356
  // Step-by-step
320
357
  const metadata = await introspectDatabase(config, options);
321
- const result = generateSchemas(metadata, options);
322
- const output = formatOutput(result);
358
+ const result2 = generateSchemas(metadata, options);
359
+ const output = formatOutput(result2);
323
360
  ```
324
361
 
325
362
  ### Types
326
363
 
327
364
  ```typescript
328
365
  interface DatabaseConfig {
329
- host: string;
330
- port: number;
331
- database: string;
332
- user: string;
333
- password: string;
334
- ssl?: boolean | { rejectUnauthorized: boolean };
366
+ host: string;
367
+ port: number;
368
+ database: string;
369
+ user: string;
370
+ password: string;
371
+ ssl?: boolean | { rejectUnauthorized: boolean };
335
372
  }
336
373
 
337
374
  interface SchemaGenerationOptions {
338
- schemas?: string[]; // Default: ['public']
339
- tables?: string[]; // Include only these
340
- excludeTables?: string[]; // Exclude these
341
- generateInputSchemas?: boolean; // Generate Insert/Update schemas (default: true)
342
- includeCompositeTypes?: boolean; // Include composite types (default: false)
343
- includeViews?: boolean; // Include database views (default: false)
344
- includeRoutines?: boolean; // Include functions/procedures (default: false)
345
- includeSecurityInvoker?: boolean; // Include SECURITY INVOKER routines (default: false)
346
- useBrandedTypes?: boolean; // Use branded types (future)
347
- strictMode?: boolean; // Fail on unknown types
348
- includeComments?: boolean; // Include comments (default: true)
349
- useCamelCase?: boolean; // Convert to camelCase
350
- customTypeMappings?: Record<string, string>; // Custom mappings
375
+ schemas?: string[]; // Default: ['public']
376
+ tables?: string[]; // Include only these
377
+ excludeTables?: string[]; // Exclude these
378
+ generateInputSchemas?: boolean; // Generate Insert/Update schemas (default: true)
379
+ includeCompositeTypes?: boolean; // Include composite types (default: false)
380
+ includeViews?: boolean; // Include database views (default: false)
381
+ includeRoutines?: boolean; // Include functions/procedures (default: false)
382
+ includeSecurityInvoker?: boolean; // Include SECURITY INVOKER routines (default: false)
383
+ useBrandedTypes?: boolean; // Use branded types (future)
384
+ strictMode?: boolean; // Fail on unknown types
385
+ includeComments?: boolean; // Include comments (default: true)
386
+ useCamelCase?: boolean; // Convert to camelCase
387
+ customTypeMappings?: Record<string, string>; // Custom mappings
351
388
  }
352
389
  ```
353
390
 
@@ -360,29 +397,30 @@ interface SchemaGenerationOptions {
360
397
  CREATE TYPE user_role AS ENUM ('admin', 'user', 'guest');
361
398
 
362
399
  -- Create domain
363
- CREATE DOMAIN email AS VARCHAR(255)
364
- CHECK (VALUE ~ '^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$');
400
+ CREATE DOMAIN email AS VARCHAR(255)
401
+ CHECK (VALUE ~ '^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$');
365
402
 
366
403
  -- Create table
367
- CREATE TABLE users (
368
- id SERIAL PRIMARY KEY,
369
- username VARCHAR(50) NOT NULL UNIQUE,
370
- email email NOT NULL,
371
- role user_role DEFAULT 'user',
372
- age INTEGER CHECK (age >= 18 AND age <= 120),
373
- tags TEXT[],
374
- metadata JSONB,
375
- created_at TIMESTAMPTZ DEFAULT NOW()
404
+ CREATE TABLE users
405
+ (
406
+ id SERIAL PRIMARY KEY,
407
+ username VARCHAR(50) NOT NULL UNIQUE,
408
+ email email NOT NULL,
409
+ role user_role DEFAULT 'user',
410
+ age INTEGER CHECK (age >= 18 AND age <= 120),
411
+ tags TEXT[],
412
+ metadata JSONB,
413
+ created_at TIMESTAMPTZ DEFAULT NOW()
376
414
  );
377
415
  ```
378
416
 
379
417
  ### Generated Output
380
418
 
381
419
  ```typescript
382
- // Generated by pg-to-zod
420
+ // Generated by pg2zod
383
421
  // Do not edit manually
384
422
 
385
- import { z } from 'zod';
423
+ import {z} from 'zod';
386
424
 
387
425
  // ============================================
388
426
  // Enums
@@ -406,39 +444,39 @@ export type PublicEmail = z.infer<typeof PublicEmailSchema>;
406
444
 
407
445
  /** Table: public.users - Read schema */
408
446
  export const PublicUsersSchema = z.object({
409
- id: z.number().int(),
410
- username: z.string().max(50),
411
- email: PublicEmailSchema,
412
- role: PublicUserRoleSchema,
413
- age: z.number().int().min(18).max(120).nullable(),
414
- tags: z.array(z.string()).nullable(),
415
- metadata: z.record(z.string(), z.unknown()).nullable(),
416
- created_at: z.date(),
447
+ id: z.number().int(),
448
+ username: z.string().max(50),
449
+ email: PublicEmailSchema,
450
+ role: PublicUserRoleSchema,
451
+ age: z.number().int().min(18).max(120).nullable(),
452
+ tags: z.array(z.string()).nullable(),
453
+ metadata: z.record(z.string(), z.unknown()).nullable(),
454
+ created_at: z.date(),
417
455
  });
418
456
  export type PublicUsers = z.infer<typeof PublicUsersSchema>;
419
457
 
420
458
  /** Insert schema for users - only auto-generated fields and fields with defaults are optional */
421
459
  export const PublicUsersInsertSchema = z.object({
422
- id: z.number().int().optional(), // auto-generated: SERIAL/identity
423
- username: z.string().max(50), // required: no default
424
- email: PublicEmailSchema, // required: no default
425
- role: PublicUserRoleSchema.optional(), // optional: has DEFAULT 'user'
426
- age: z.number().int().min(18).max(120).nullable(), // nullable but no default, so required
427
- tags: z.array(z.string()).nullable(), // nullable but no default, so required
428
- metadata: z.record(z.string(), z.unknown()).nullable(), // nullable but no default, so required
429
- created_at: z.date().optional(), // optional: has DEFAULT NOW()
460
+ id: z.number().int().optional(), // auto-generated: SERIAL/identity
461
+ username: z.string().max(50), // required: no default
462
+ email: PublicEmailSchema, // required: no default
463
+ role: PublicUserRoleSchema.optional(), // optional: has DEFAULT 'user'
464
+ age: z.number().int().min(18).max(120).nullable(), // nullable but no default, so required
465
+ tags: z.array(z.string()).nullable(), // nullable but no default, so required
466
+ metadata: z.record(z.string(), z.unknown()).nullable(), // nullable but no default, so required
467
+ created_at: z.date().optional(), // optional: has DEFAULT NOW()
430
468
  });
431
469
  export type PublicUsersInsert = z.infer<typeof PublicUsersInsertSchema>;
432
470
 
433
471
  /** Update schema for users - all fields optional, primary keys excluded, validation preserved */
434
472
  export const PublicUsersUpdateSchema = z.object({
435
- username: z.string().max(50).optional(),
436
- email: PublicEmailSchema.optional(),
437
- role: PublicUserRoleSchema.optional(),
438
- age: z.number().int().min(18).max(120).optional().nullable(),
439
- tags: z.array(z.string()).optional().nullable(),
440
- metadata: z.record(z.string(), z.unknown()).optional().nullable(),
441
- created_at: z.date().optional(),
473
+ username: z.string().max(50).optional(),
474
+ email: PublicEmailSchema.optional(),
475
+ role: PublicUserRoleSchema.optional(),
476
+ age: z.number().int().min(18).max(120).optional().nullable(),
477
+ tags: z.array(z.string()).optional().nullable(),
478
+ metadata: z.record(z.string(), z.unknown()).optional().nullable(),
479
+ created_at: z.date().optional(),
442
480
  });
443
481
  export type PublicUsersUpdate = z.infer<typeof PublicUsersUpdateSchema>;
444
482
  ```
@@ -466,5 +504,6 @@ MIT
466
504
  ## Credits
467
505
 
468
506
  Built with:
507
+
469
508
  - [pg](https://github.com/brianc/node-postgres) - PostgreSQL client
470
509
  - [zod](https://github.com/colinhacks/zod) - TypeScript-first schema validation
package/dist/cli.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { n as generateZodSchemasString } from "./src-CEkWBxDB.js";
2
+ import { n as generateZodSchemasString } from "./src-BTbLgtTh.js";
3
3
  import * as fs from "node:fs/promises";
4
4
  import * as path from "node:path";
5
5
 
@@ -15,7 +15,7 @@ function parseArgs() {
15
15
  process.exit(0);
16
16
  }
17
17
  if (args.includes("--version") || args.includes("-v")) {
18
- console.log("pg-to-zod 1.0.0");
18
+ console.log("pg2zod 2.1.0");
19
19
  process.exit(0);
20
20
  }
21
21
  const connectionUrl = getArg(args, "--url");
@@ -85,10 +85,10 @@ function parseConnectionUrl(url) {
85
85
  */
86
86
  function printHelp() {
87
87
  console.log(`
88
- pg-to-zod - Generate strict Zod v4 schemas from PostgreSQL database
88
+ pg2zod - Generate strict Zod v4 schemas from PostgreSQL database
89
89
 
90
90
  USAGE:
91
- pg-to-zod [OPTIONS]
91
+ pg2zod [OPTIONS]
92
92
 
93
93
  CONNECTION OPTIONS:
94
94
  --url <url> PostgreSQL connection URL
@@ -131,22 +131,22 @@ ENVIRONMENT VARIABLES:
131
131
 
132
132
  EXAMPLES:
133
133
  # Generate schemas from local database
134
- pg-to-zod --database mydb --output src/schemas.ts
134
+ pg2zod --database mydb --output src/schemas.ts
135
135
 
136
136
  # Use connection URL
137
- pg-to-zod --url postgresql://user:pass@localhost:5432/mydb
137
+ pg2zod --url postgresql://user:pass@localhost:5432/mydb
138
138
 
139
139
  # Generate with input schemas and camelCase
140
- pg-to-zod --database mydb --input-schemas --camel-case
140
+ pg2zod --database mydb --input-schemas --camel-case
141
141
 
142
142
  # Include specific tables only
143
- pg-to-zod --database mydb --tables users,posts,comments
143
+ pg2zod --database mydb --tables users,posts,comments
144
144
 
145
145
  # Exclude specific tables
146
- pg-to-zod --database mydb --exclude-tables migrations,internal
146
+ pg2zod --database mydb --exclude-tables migrations,internal
147
147
 
148
148
  # Multiple schemas
149
- pg-to-zod --database mydb --schemas public,auth,api
149
+ pg2zod --database mydb --schemas public,auth,api
150
150
  `);
151
151
  }
152
152
  /**
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","names":[],"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport {generateZodSchemasString} from './index.js';\nimport type {DatabaseConfig, SchemaGenerationOptions} from './types.js';\n\nconst DEFAULT_OUTPUT = 'schema.ts';\n\n/**\n * Parse command line arguments\n */\nfunction parseArgs(): {\n config: DatabaseConfig;\n options: SchemaGenerationOptions;\n output: string;\n} {\n const args = process.argv.slice(2);\n\n if (args.includes('--help') || args.includes('-h')) {\n printHelp();\n process.exit(0);\n }\n\n if (args.includes('--version') || args.includes('-v')) {\n console.log('pg-to-zod 1.0.0');\n process.exit(0);\n }\n\n // Parse connection string or individual params\n const connectionUrl = getArg(args, '--url');\n let config: DatabaseConfig;\n\n if (connectionUrl) {\n config = parseConnectionUrl(connectionUrl);\n } else {\n config = {\n host: getArg(args, '--host') || process.env.PGHOST || 'localhost',\n port: parseInt(getArg(args, '--port') || process.env.PGPORT || '5432'),\n database: getArg(args, '--database') || process.env.PGDATABASE || 'postgres',\n user: getArg(args, '--user') || process.env.PGUSER || 'postgres',\n password: getArg(args, '--password') || process.env.PGPASSWORD || '',\n ssl: args.includes('--ssl'),\n };\n }\n\n const options: SchemaGenerationOptions = {\n schemas: getArgArray(args, '--schemas') || ['public'],\n tables: getArgArray(args, '--tables'),\n excludeTables: getArgArray(args, '--exclude-tables'),\n generateInputSchemas: !args.includes('--no-input-schemas'), // Default: true\n includeCompositeTypes: args.includes('--composite-types'), // Default: false\n includeViews: args.includes('--views'), // Default: false\n includeRoutines: args.includes('--routines'), // Default: false\n includeSecurityInvoker: args.includes('--security-invoker'), // Default: false\n useBrandedTypes: args.includes('--branded-types'),\n strictMode: args.includes('--strict'),\n includeComments: !args.includes('--no-comments'),\n useCamelCase: args.includes('--camel-case'),\n };\n\n const output = getArg(args, '--output') || getArg(args, '-o') || DEFAULT_OUTPUT;\n\n return {config, options, output};\n}\n\n/**\n * Get argument value\n */\nfunction getArg(args: string[], flag: string): string | undefined {\n const index = args.indexOf(flag);\n if (index !== -1 && index + 1 < args.length) {\n return args[index + 1];\n }\n return undefined;\n}\n\n/**\n * Get argument array value (comma-separated)\n */\nfunction getArgArray(args: string[], flag: string): string[] | undefined {\n const value = getArg(args, flag);\n if (value) {\n return value.split(',').map((s) => s.trim());\n }\n return undefined;\n}\n\n/**\n * Parse PostgreSQL connection URL\n */\nfunction parseConnectionUrl(url: string): DatabaseConfig {\n const match = url.match(\n /postgresql:\\/\\/([^:]+):([^@]+)@([^:\\/]+):(\\d+)\\/(.+)/\n );\n\n if (!match) {\n throw new Error('Invalid connection URL format');\n }\n\n const [, user, password, host, port, database] = match;\n\n return {\n host,\n port: parseInt(port),\n database,\n user,\n password,\n ssl: url.includes('sslmode=require'),\n };\n}\n\n/**\n * Print help message\n */\nfunction printHelp(): void {\n console.log(`\npg-to-zod - Generate strict Zod v4 schemas from PostgreSQL database\n\nUSAGE:\n pg-to-zod [OPTIONS]\n\nCONNECTION OPTIONS:\n --url <url> PostgreSQL connection URL\n (postgresql://user:pass@host:port/db)\n --host <host> Database host (default: localhost)\n --port <port> Database port (default: 5432)\n --database <database> Database name (default: postgres)\n --user <user> Database user (default: postgres)\n --password <password> Database password\n --ssl Use SSL connection\n\nGENERATION OPTIONS:\n --schemas <schemas> Comma-separated list of schemas (default: public)\n --tables <tables> Comma-separated list of tables to include\n --exclude-tables <tables> Comma-separated list of tables to exclude\n --no-input-schemas Skip generating input schemas (generated by default)\n --composite-types Include composite types (skipped by default)\n --views Include database views (skipped by default)\n --routines Include functions/procedures (skipped by default)\n --security-invoker Include SECURITY INVOKER routines (default: DEFINER only)\n --branded-types Use branded types for IDs\n --strict Fail on unmapped types instead of using z.unknown()\n --no-comments Don't include comments in generated code\n --camel-case Use camelCase for field names\n\nOUTPUT OPTIONS:\n --output <file> Output file path (default: schema.ts)\n -o <file> Short form of --output\n\nOTHER OPTIONS:\n --help, -h Show this help message\n --version, -v Show version\n\nENVIRONMENT VARIABLES:\n PGHOST Database host\n PGPORT Database port\n PGDATABASE Database name\n PGUSER Database user\n PGPASSWORD Database password\n\nEXAMPLES:\n # Generate schemas from local database\n pg-to-zod --database mydb --output src/schemas.ts\n\n # Use connection URL\n pg-to-zod --url postgresql://user:pass@localhost:5432/mydb\n\n # Generate with input schemas and camelCase\n pg-to-zod --database mydb --input-schemas --camel-case\n\n # Include specific tables only\n pg-to-zod --database mydb --tables users,posts,comments\n\n # Exclude specific tables\n pg-to-zod --database mydb --exclude-tables migrations,internal\n\n # Multiple schemas\n pg-to-zod --database mydb --schemas public,auth,api\n`);\n}\n\n/**\n * Main CLI function\n */\nasync function main(): Promise<void> {\n try {\n const {config, options, output} = parseArgs();\n\n console.log('🔍 Introspecting database...');\n console.log(` Database: ${config.database}`);\n console.log(` Schemas: ${options.schemas?.join(', ') || 'public'}`);\n\n const schema = await generateZodSchemasString(config, options);\n\n // Write to file\n const outputPath = path.resolve(process.cwd(), output);\n await fs.writeFile(outputPath, schema, 'utf-8');\n\n console.log('✅ Schema generated successfully!');\n console.log(` Output: ${outputPath}`);\n\n // Count generated items\n const enumCount = (schema.match(/export const \\w+Schema = z\\.enum\\(/g) || []).length;\n const tableCount = (schema.match(/export const \\w+Schema = z\\.object\\({/g) || []).length - enumCount;\n\n console.log(` Tables: ${tableCount}`);\n console.log(` Enums: ${enumCount}`);\n\n // Show warnings if any\n if (schema.includes('// Warnings')) {\n const warningLines = schema\n .split('\\n')\n .filter((line) => line.startsWith('// - '))\n .map((line) => line.slice(5));\n\n if (warningLines.length > 0) {\n console.log('\\n⚠️ Warnings:');\n for (const warning of warningLines) {\n console.log(` ${warning}`);\n }\n }\n }\n\n } catch (error) {\n console.error('❌ Error:', error instanceof Error ? error.message : error);\n process.exit(1);\n }\n}\n\nmain();\n"],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","names":[],"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport {generateZodSchemasString} from './index.js';\nimport type {DatabaseConfig, SchemaGenerationOptions} from './types.js';\n\nconst DEFAULT_OUTPUT = 'schema.ts';\n\n/**\n * Parse command line arguments\n */\nfunction parseArgs(): {\n config: DatabaseConfig;\n options: SchemaGenerationOptions;\n output: string;\n} {\n const args = process.argv.slice(2);\n\n if (args.includes('--help') || args.includes('-h')) {\n printHelp();\n process.exit(0);\n }\n\n if (args.includes('--version') || args.includes('-v')) {\n console.log('pg2zod 2.1.0');\n process.exit(0);\n }\n\n // Parse connection string or individual params\n const connectionUrl = getArg(args, '--url');\n let config: DatabaseConfig;\n\n if (connectionUrl) {\n config = parseConnectionUrl(connectionUrl);\n } else {\n config = {\n host: getArg(args, '--host') || process.env.PGHOST || 'localhost',\n port: parseInt(getArg(args, '--port') || process.env.PGPORT || '5432'),\n database: getArg(args, '--database') || process.env.PGDATABASE || 'postgres',\n user: getArg(args, '--user') || process.env.PGUSER || 'postgres',\n password: getArg(args, '--password') || process.env.PGPASSWORD || '',\n ssl: args.includes('--ssl'),\n };\n }\n\n const options: SchemaGenerationOptions = {\n schemas: getArgArray(args, '--schemas') || ['public'],\n tables: getArgArray(args, '--tables'),\n excludeTables: getArgArray(args, '--exclude-tables'),\n generateInputSchemas: !args.includes('--no-input-schemas'), // Default: true\n includeCompositeTypes: args.includes('--composite-types'), // Default: false\n includeViews: args.includes('--views'), // Default: false\n includeRoutines: args.includes('--routines'), // Default: false\n includeSecurityInvoker: args.includes('--security-invoker'), // Default: false\n useBrandedTypes: args.includes('--branded-types'),\n strictMode: args.includes('--strict'),\n includeComments: !args.includes('--no-comments'),\n useCamelCase: args.includes('--camel-case'),\n };\n\n const output = getArg(args, '--output') || getArg(args, '-o') || DEFAULT_OUTPUT;\n\n return {config, options, output};\n}\n\n/**\n * Get argument value\n */\nfunction getArg(args: string[], flag: string): string | undefined {\n const index = args.indexOf(flag);\n if (index !== -1 && index + 1 < args.length) {\n return args[index + 1];\n }\n return undefined;\n}\n\n/**\n * Get argument array value (comma-separated)\n */\nfunction getArgArray(args: string[], flag: string): string[] | undefined {\n const value = getArg(args, flag);\n if (value) {\n return value.split(',').map((s) => s.trim());\n }\n return undefined;\n}\n\n/**\n * Parse PostgreSQL connection URL\n */\nfunction parseConnectionUrl(url: string): DatabaseConfig {\n const match = url.match(\n /postgresql:\\/\\/([^:]+):([^@]+)@([^:\\/]+):(\\d+)\\/(.+)/\n );\n\n if (!match) {\n throw new Error('Invalid connection URL format');\n }\n\n const [, user, password, host, port, database] = match;\n\n return {\n host,\n port: parseInt(port),\n database,\n user,\n password,\n ssl: url.includes('sslmode=require'),\n };\n}\n\n/**\n * Print help message\n */\nfunction printHelp(): void {\n console.log(`\npg2zod - Generate strict Zod v4 schemas from PostgreSQL database\n\nUSAGE:\n pg2zod [OPTIONS]\n\nCONNECTION OPTIONS:\n --url <url> PostgreSQL connection URL\n (postgresql://user:pass@host:port/db)\n --host <host> Database host (default: localhost)\n --port <port> Database port (default: 5432)\n --database <database> Database name (default: postgres)\n --user <user> Database user (default: postgres)\n --password <password> Database password\n --ssl Use SSL connection\n\nGENERATION OPTIONS:\n --schemas <schemas> Comma-separated list of schemas (default: public)\n --tables <tables> Comma-separated list of tables to include\n --exclude-tables <tables> Comma-separated list of tables to exclude\n --no-input-schemas Skip generating input schemas (generated by default)\n --composite-types Include composite types (skipped by default)\n --views Include database views (skipped by default)\n --routines Include functions/procedures (skipped by default)\n --security-invoker Include SECURITY INVOKER routines (default: DEFINER only)\n --branded-types Use branded types for IDs\n --strict Fail on unmapped types instead of using z.unknown()\n --no-comments Don't include comments in generated code\n --camel-case Use camelCase for field names\n\nOUTPUT OPTIONS:\n --output <file> Output file path (default: schema.ts)\n -o <file> Short form of --output\n\nOTHER OPTIONS:\n --help, -h Show this help message\n --version, -v Show version\n\nENVIRONMENT VARIABLES:\n PGHOST Database host\n PGPORT Database port\n PGDATABASE Database name\n PGUSER Database user\n PGPASSWORD Database password\n\nEXAMPLES:\n # Generate schemas from local database\n pg2zod --database mydb --output src/schemas.ts\n\n # Use connection URL\n pg2zod --url postgresql://user:pass@localhost:5432/mydb\n\n # Generate with input schemas and camelCase\n pg2zod --database mydb --input-schemas --camel-case\n\n # Include specific tables only\n pg2zod --database mydb --tables users,posts,comments\n\n # Exclude specific tables\n pg2zod --database mydb --exclude-tables migrations,internal\n\n # Multiple schemas\n pg2zod --database mydb --schemas public,auth,api\n`);\n}\n\n/**\n * Main CLI function\n */\nasync function main(): Promise<void> {\n try {\n const {config, options, output} = parseArgs();\n\n console.log('🔍 Introspecting database...');\n console.log(` Database: ${config.database}`);\n console.log(` Schemas: ${options.schemas?.join(', ') || 'public'}`);\n\n const schema = await generateZodSchemasString(config, options);\n\n // Write to file\n const outputPath = path.resolve(process.cwd(), output);\n await fs.writeFile(outputPath, schema, 'utf-8');\n\n console.log('✅ Schema generated successfully!');\n console.log(` Output: ${outputPath}`);\n\n // Count generated items\n const enumCount = (schema.match(/export const \\w+Schema = z\\.enum\\(/g) || []).length;\n const tableCount = (schema.match(/export const \\w+Schema = z\\.object\\({/g) || []).length - enumCount;\n\n console.log(` Tables: ${tableCount}`);\n console.log(` Enums: ${enumCount}`);\n\n // Show warnings if any\n if (schema.includes('// Warnings')) {\n const warningLines = schema\n .split('\\n')\n .filter((line) => line.startsWith('// - '))\n .map((line) => line.slice(5));\n\n if (warningLines.length > 0) {\n console.log('\\n⚠️ Warnings:');\n for (const warning of warningLines) {\n console.log(` ${warning}`);\n }\n }\n }\n\n } catch (error) {\n console.error('❌ Error:', error instanceof Error ? error.message : error);\n process.exit(1);\n }\n}\n\nmain();\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../src/types.ts","../src/introspect.ts","../src/generator.ts","../src/type-mapper.ts","../src/index.ts"],"sourcesContent":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../src/types.ts","../src/introspect.ts","../src/generator.ts","../src/type-mapper.ts","../src/index.ts"],"sourcesContent":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -1,3 +1,3 @@
1
- import { a as generateSchemas, c as toPascalCase, i as formatOutput, l as introspectDatabase, n as generateZodSchemasString, o as mapColumnToZod, r as src_default, s as toCamelCase, t as generateZodSchemas } from "./src-CEkWBxDB.js";
1
+ import { a as generateSchemas, c as toPascalCase, i as formatOutput, l as introspectDatabase, n as generateZodSchemasString, o as mapColumnToZod, r as src_default, s as toCamelCase, t as generateZodSchemas } from "./src-BTbLgtTh.js";
2
2
 
3
3
  export { src_default as default, formatOutput, generateSchemas, generateZodSchemas, generateZodSchemasString, introspectDatabase, mapColumnToZod, toCamelCase, toPascalCase };
@@ -372,17 +372,13 @@ async function introspectViews(pool, schemas) {
372
372
  udtName: row.udt_name,
373
373
  isNullable: row.is_nullable === "YES",
374
374
  columnDefault: row.column_default,
375
- ordinalPosition: row.ordinal_position,
376
375
  characterMaximumLength: row.character_maximum_length,
377
376
  numericPrecision: row.numeric_precision,
378
377
  numericScale: row.numeric_scale,
379
378
  datetimePrecision: row.datetime_precision,
380
379
  arrayDimensions: row.array_dimensions,
381
- isIdentity: false,
382
- identityGeneration: null,
383
- isGenerated: false,
384
- generationExpression: null,
385
- checkConstraints: []
380
+ domainName: null,
381
+ isArray: row.array_dimensions > 0
386
382
  });
387
383
  }
388
384
  return views;
@@ -696,20 +692,46 @@ function generateSchemas(metadata, options = {}) {
696
692
  const schema = generateTableSchema(table, metadata, options, warnings);
697
693
  schemas.push(schema);
698
694
  }
695
+ const views = metadata.views?.map((view) => ({
696
+ name: toPascalCase(view.schemaName) + toPascalCase(view.viewName),
697
+ code: generateViewSchema(view, metadata, options, warnings)
698
+ })) || [];
699
+ const filteredRoutines = metadata.routines?.filter((routine) => {
700
+ if (routine.securityType === "INVOKER" && !options.includeSecurityInvoker) return false;
701
+ const internalTypes = [
702
+ "internal",
703
+ "trigger",
704
+ "event_trigger",
705
+ "cstring",
706
+ "opaque",
707
+ "\"char\"",
708
+ "language_handler",
709
+ "fdw_handler",
710
+ "index_am_handler",
711
+ "tsm_handler",
712
+ "table_am_handler"
713
+ ];
714
+ const hasInternalParam = routine.parameters.some((param) => internalTypes.includes(param.dataType.toLowerCase()) || internalTypes.includes(param.udtName.toLowerCase()));
715
+ const hasInternalReturn = routine.returnType && (internalTypes.includes(routine.returnType.toLowerCase()) || routine.returnUdtName && internalTypes.includes(routine.returnUdtName.toLowerCase()));
716
+ if (hasInternalParam || hasInternalReturn) return false;
717
+ const paramNames = routine.parameters.map((p) => p.parameterName.toLowerCase());
718
+ if (new Set(paramNames).size !== paramNames.length) return false;
719
+ return true;
720
+ }) || [];
721
+ const seenRoutineNames = /* @__PURE__ */ new Set();
699
722
  return {
700
723
  schemas,
701
724
  enums,
702
725
  compositeTypes,
703
726
  domains,
704
727
  ranges,
705
- views: metadata.views?.map((view) => ({
706
- name: toPascalCase(view.schemaName) + toPascalCase(view.viewName),
707
- code: generateViewSchema(view, metadata, options, warnings)
708
- })) || [],
709
- routines: (metadata.routines?.filter((routine) => {
710
- if (routine.securityType === "INVOKER" && !options.includeSecurityInvoker) return false;
728
+ views,
729
+ routines: filteredRoutines.filter((routine) => {
730
+ const baseName = toPascalCase(routine.schemaName) + toPascalCase(routine.routineName);
731
+ if (seenRoutineNames.has(baseName)) return false;
732
+ seenRoutineNames.add(baseName);
711
733
  return true;
712
- }) || []).map((routine) => ({
734
+ }).map((routine) => ({
713
735
  name: toPascalCase(routine.schemaName) + toPascalCase(routine.routineName),
714
736
  code: generateRoutineSchema(routine, metadata, options, warnings)
715
737
  })),
@@ -1043,7 +1065,7 @@ function generateTableSchema(table, metadata, options, warnings) {
1043
1065
  function formatOutput(result) {
1044
1066
  let output = `/**\n`;
1045
1067
  output += ` * ==========================================\n`;
1046
- output += ` * | GENERATED BY PG-TO-ZOD (TBP) |\n`;
1068
+ output += ` * | GENERATED BY PG2ZOD |\n`;
1047
1069
  output += ` * ==========================================\n`;
1048
1070
  output += ` *\n`;
1049
1071
  output += ` * ⚠️ DO NOT EDIT THIS FILE MANUALLY!\n`;
@@ -1052,7 +1074,7 @@ function formatOutput(result) {
1052
1074
  output += ` * your PostgreSQL database schema.\n`;
1053
1075
  output += ` *\n`;
1054
1076
  output += ` * To regenerate, run:\n`;
1055
- output += ` * pg-to-zod --url <connection-url> -o <file>\n`;
1077
+ output += ` * pg2zod --url <connection-url> -o <file>\n`;
1056
1078
  output += ` *\n`;
1057
1079
  output += ` * Any manual changes will be overwritten when\n`;
1058
1080
  output += ` * the code is regenerated.\n`;
@@ -1138,4 +1160,4 @@ var src_default = {
1138
1160
 
1139
1161
  //#endregion
1140
1162
  export { generateSchemas as a, toPascalCase as c, formatOutput as i, introspectDatabase as l, generateZodSchemasString as n, mapColumnToZod as o, src_default as r, toCamelCase as s, generateZodSchemas as t };
1141
- //# sourceMappingURL=src-CEkWBxDB.js.map
1163
+ //# sourceMappingURL=src-BTbLgtTh.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"src-BTbLgtTh.js","names":[],"sources":["../src/introspect.ts","../src/type-mapper.ts","../src/generator.ts","../src/index.ts"],"sourcesContent":["import pg from 'pg';\nimport type {\n DatabaseConfig,\n DatabaseMetadata,\n TableMetadata,\n ViewMetadata,\n RoutineMetadata,\n EnumMetadata,\n CompositeTypeMetadata,\n RangeTypeMetadata,\n DomainMetadata,\n SchemaGenerationOptions,\n} from './types.js';\n\nconst { Pool } = pg;\n\n/**\n * Introspect a PostgreSQL database and return complete metadata\n */\nexport async function introspectDatabase(\n config: DatabaseConfig,\n options: SchemaGenerationOptions = {}\n): Promise<DatabaseMetadata> {\n const pool = new Pool(config);\n\n try {\n const schemas = options.schemas ?? ['public'];\n\n const [\n tables,\n views,\n routines,\n enums,\n compositeTypes,\n rangeTypes,\n domains,\n ] = await Promise.all([\n introspectTables(pool, schemas, options),\n options.includeViews ? introspectViews(pool, schemas) : Promise.resolve([]),\n options.includeRoutines ? introspectRoutines(pool, schemas) : Promise.resolve([]),\n introspectEnums(pool, schemas),\n introspectCompositeTypes(pool, schemas),\n introspectRangeTypes(pool, schemas),\n introspectDomains(pool, schemas),\n ]);\n\n return {\n tables,\n views,\n routines,\n enums,\n compositeTypes,\n rangeTypes,\n domains,\n };\n } finally {\n await pool.end();\n }\n}\n\n/**\n * Introspect tables and their columns\n */\nasync function introspectTables(\n pool: pg.Pool,\n schemas: string[],\n options: SchemaGenerationOptions\n): Promise<TableMetadata[]> {\n const schemaFilter = schemas.map((_, i) => `$${i + 1}`).join(', ');\n\n // Get all columns\n const columnsQuery = `\n SELECT \n c.table_schema,\n c.table_name,\n c.column_name,\n c.data_type,\n c.is_nullable,\n c.column_default,\n c.character_maximum_length,\n c.numeric_precision,\n c.numeric_scale,\n c.datetime_precision,\n c.udt_name,\n c.domain_name,\n COALESCE(\n (SELECT array_ndims(ARRAY[]::text[]) FROM information_schema.element_types e \n WHERE e.object_schema = c.table_schema \n AND e.object_name = c.table_name \n AND e.object_type = 'TABLE'\n AND e.collection_type_identifier = c.dtd_identifier\n ), 0\n ) as array_dimensions\n FROM information_schema.columns c\n WHERE c.table_schema IN (${schemaFilter})\n ORDER BY c.table_schema, c.table_name, c.ordinal_position\n `;\n\n const columnsResult = await pool.query(columnsQuery, schemas);\n\n // Get check constraints\n const constraintsQuery = `\n SELECT \n tc.table_schema,\n tc.table_name,\n tc.constraint_name,\n cc.check_clause,\n ccu.column_name\n FROM information_schema.table_constraints tc\n JOIN information_schema.check_constraints cc \n ON tc.constraint_name = cc.constraint_name \n AND tc.constraint_schema = cc.constraint_schema\n LEFT JOIN information_schema.constraint_column_usage ccu\n ON tc.constraint_name = ccu.constraint_name\n AND tc.constraint_schema = ccu.constraint_schema\n WHERE tc.constraint_type = 'CHECK'\n AND tc.table_schema IN (${schemaFilter})\n `;\n\n const constraintsResult = await pool.query(constraintsQuery, schemas);\n\n // Get primary keys\n const primaryKeysQuery = `\n SELECT \n tc.table_schema,\n tc.table_name,\n kcu.column_name\n FROM information_schema.table_constraints tc\n JOIN information_schema.key_column_usage kcu\n ON tc.constraint_name = kcu.constraint_name\n AND tc.table_schema = kcu.table_schema\n WHERE tc.constraint_type = 'PRIMARY KEY'\n AND tc.table_schema IN (${schemaFilter})\n ORDER BY kcu.ordinal_position\n `;\n\n const primaryKeysResult = await pool.query(primaryKeysQuery, schemas);\n\n // Get unique constraints\n const uniqueConstraintsQuery = `\n SELECT \n tc.table_schema,\n tc.table_name,\n tc.constraint_name,\n array_agg(kcu.column_name ORDER BY kcu.ordinal_position) as columns\n FROM information_schema.table_constraints tc\n JOIN information_schema.key_column_usage kcu\n ON tc.constraint_name = kcu.constraint_name\n AND tc.table_schema = kcu.table_schema\n WHERE tc.constraint_type = 'UNIQUE'\n AND tc.table_schema IN (${schemaFilter})\n GROUP BY tc.table_schema, tc.table_name, tc.constraint_name\n `;\n\n const uniqueConstraintsResult = await pool.query(uniqueConstraintsQuery, schemas);\n\n // Group by table\n const tableMap = new Map<string, TableMetadata>();\n\n for (const row of columnsResult.rows) {\n const tableKey = `${row.table_schema}.${row.table_name}`;\n\n if (!tableMap.has(tableKey)) {\n tableMap.set(tableKey, {\n tableName: row.table_name,\n schemaName: row.table_schema,\n columns: [],\n checkConstraints: [],\n primaryKeys: [],\n uniqueConstraints: [],\n });\n }\n\n const table = tableMap.get(tableKey)!;\n const isArray = row.data_type === 'ARRAY';\n\n table.columns.push({\n columnName: row.column_name,\n dataType: row.data_type,\n isNullable: row.is_nullable === 'YES',\n columnDefault: row.column_default,\n characterMaximumLength: row.character_maximum_length,\n numericPrecision: row.numeric_precision,\n numericScale: row.numeric_scale,\n datetimePrecision: row.datetime_precision,\n udtName: row.udt_name,\n domainName: row.domain_name,\n arrayDimensions: row.array_dimensions || 0,\n isArray,\n });\n }\n\n // Add check constraints\n for (const row of constraintsResult.rows) {\n const tableKey = `${row.table_schema}.${row.table_name}`;\n const table = tableMap.get(tableKey);\n if (table) {\n table.checkConstraints.push({\n constraintName: row.constraint_name,\n checkClause: row.check_clause,\n columnName: row.column_name,\n });\n }\n }\n\n // Add primary keys\n for (const row of primaryKeysResult.rows) {\n const tableKey = `${row.table_schema}.${row.table_name}`;\n const table = tableMap.get(tableKey);\n if (table) {\n table.primaryKeys.push(row.column_name);\n }\n }\n\n // Add unique constraints\n for (const row of uniqueConstraintsResult.rows) {\n const tableKey = `${row.table_schema}.${row.table_name}`;\n const table = tableMap.get(tableKey);\n if (table) {\n table.uniqueConstraints.push({\n constraintName: row.constraint_name,\n columns: row.columns,\n });\n }\n }\n\n // Filter tables based on options\n let tables = Array.from(tableMap.values());\n\n if (options.tables) {\n tables = tables.filter((t) => options.tables!.includes(t.tableName));\n }\n\n if (options.excludeTables) {\n tables = tables.filter((t) => !options.excludeTables!.includes(t.tableName));\n }\n\n return tables;\n}\n\n/**\n * Introspect enum types\n */\nasync function introspectEnums(\n pool: pg.Pool,\n schemas: string[]\n): Promise<EnumMetadata[]> {\n const schemaFilter = schemas.map((_, i) => `$${i + 1}`).join(', ');\n\n const query = `\n SELECT \n t.typname as enum_name,\n n.nspname as schema_name,\n array_agg(e.enumlabel ORDER BY e.enumsortorder) as enum_values\n FROM pg_type t\n JOIN pg_enum e ON t.oid = e.enumtypid\n JOIN pg_namespace n ON t.typnamespace = n.oid\n WHERE n.nspname IN (${schemaFilter})\n GROUP BY t.typname, n.nspname\n ORDER BY t.typname\n `;\n\n const result = await pool.query(query, schemas);\n\n return result.rows.map((row) => {\n // Handle PostgreSQL array format: {value1,value2,value3}\n let enumValues: string[];\n \n if (Array.isArray(row.enum_values)) {\n enumValues = row.enum_values;\n } else if (typeof row.enum_values === 'string') {\n // Parse PostgreSQL array format\n if (row.enum_values.startsWith('{') && row.enum_values.endsWith('}')) {\n enumValues = row.enum_values\n .slice(1, -1) // Remove { and }\n .split(',')\n .map((v: string) => v.trim());\n } else {\n enumValues = [row.enum_values];\n }\n } else {\n enumValues = [row.enum_values];\n }\n \n return {\n enumName: row.enum_name,\n enumValues,\n schemaName: row.schema_name,\n };\n });\n}\n\n/**\n * Introspect composite types\n */\nasync function introspectCompositeTypes(\n pool: pg.Pool,\n schemas: string[]\n): Promise<CompositeTypeMetadata[]> {\n const schemaFilter = schemas.map((_, i) => `$${i + 1}`).join(', ');\n\n const query = `\n SELECT \n t.typname as type_name,\n n.nspname as schema_name,\n a.attname as attribute_name,\n a.attnum as attribute_number,\n format_type(a.atttypid, a.atttypmod) as data_type\n FROM pg_type t\n JOIN pg_namespace n ON t.typnamespace = n.oid\n JOIN pg_class c ON t.typrelid = c.oid\n JOIN pg_attribute a ON c.oid = a.attrelid\n WHERE t.typtype = 'c'\n AND n.nspname IN (${schemaFilter})\n AND a.attnum > 0\n AND NOT a.attisdropped\n ORDER BY t.typname, a.attnum\n `;\n\n const result = await pool.query(query, schemas);\n\n const typeMap = new Map<string, CompositeTypeMetadata>();\n\n for (const row of result.rows) {\n const typeKey = `${row.schema_name}.${row.type_name}`;\n\n if (!typeMap.has(typeKey)) {\n typeMap.set(typeKey, {\n typeName: row.type_name,\n schemaName: row.schema_name,\n attributes: [],\n });\n }\n\n const type = typeMap.get(typeKey)!;\n type.attributes.push({\n attributeName: row.attribute_name,\n dataType: row.data_type,\n attributeNumber: row.attribute_number,\n });\n }\n\n return Array.from(typeMap.values());\n}\n\n/**\n * Introspect range types\n */\nasync function introspectRangeTypes(\n pool: pg.Pool,\n schemas: string[]\n): Promise<RangeTypeMetadata[]> {\n const schemaFilter = schemas.map((_, i) => `$${i + 1}`).join(', ');\n\n const query = `\n SELECT \n t.typname as range_name,\n n.nspname as schema_name,\n format_type(r.rngsubtype, NULL) as subtype\n FROM pg_type t\n JOIN pg_namespace n ON t.typnamespace = n.oid\n JOIN pg_range r ON t.oid = r.rngtypid\n WHERE n.nspname IN (${schemaFilter})\n ORDER BY t.typname\n `;\n\n const result = await pool.query(query, schemas);\n\n return result.rows.map((row) => ({\n rangeName: row.range_name,\n subtype: row.subtype,\n schemaName: row.schema_name,\n }));\n}\n\n/**\n * Introspect domain types\n */\nasync function introspectDomains(\n pool: pg.Pool,\n schemas: string[]\n): Promise<DomainMetadata[]> {\n const schemaFilter = schemas.map((_, i) => `$${i + 1}`).join(', ');\n\n // Get domain information\n const domainsQuery = `\n SELECT \n t.typname as domain_name,\n n.nspname as schema_name,\n format_type(t.typbasetype, t.typtypmod) as data_type,\n t.typnotnull as is_not_null,\n t.typdefault as domain_default,\n information_schema._pg_char_max_length(t.typbasetype, t.typtypmod) as character_maximum_length,\n information_schema._pg_numeric_precision(t.typbasetype, t.typtypmod) as numeric_precision,\n information_schema._pg_numeric_scale(t.typbasetype, t.typtypmod) as numeric_scale\n FROM pg_type t\n JOIN pg_namespace n ON t.typnamespace = n.oid\n WHERE t.typtype = 'd'\n AND n.nspname IN (${schemaFilter})\n ORDER BY t.typname\n `;\n\n const domainsResult = await pool.query(domainsQuery, schemas);\n\n // Get domain constraints\n const constraintsQuery = `\n SELECT \n t.typname as domain_name,\n n.nspname as schema_name,\n c.conname as constraint_name,\n pg_get_constraintdef(c.oid) as check_clause\n FROM pg_constraint c\n JOIN pg_type t ON c.contypid = t.oid\n JOIN pg_namespace n ON t.typnamespace = n.oid\n WHERE c.contype = 'c'\n AND n.nspname IN (${schemaFilter})\n `;\n\n const constraintsResult = await pool.query(constraintsQuery, schemas);\n\n const domains: DomainMetadata[] = domainsResult.rows.map((row) => ({\n domainName: row.domain_name,\n dataType: row.data_type,\n schemaName: row.schema_name,\n characterMaximumLength: row.character_maximum_length,\n numericPrecision: row.numeric_precision,\n numericScale: row.numeric_scale,\n isNullable: !row.is_not_null,\n domainDefault: row.domain_default,\n checkConstraints: [],\n }));\n\n // Add check constraints to domains\n for (const row of constraintsResult.rows) {\n const domain = domains.find(\n (d) => d.domainName === row.domain_name && d.schemaName === row.schema_name\n );\n if (domain) {\n domain.checkConstraints.push({\n constraintName: row.constraint_name,\n checkClause: row.check_clause,\n columnName: null,\n });\n }\n }\n\n return domains;\n}\n\n/**\n * Introspect database views\n */\nasync function introspectViews(\n pool: pg.Pool,\n schemas: string[]\n): Promise<ViewMetadata[]> {\n const schemaFilter = schemas.map((_, i) => `$${i + 1}`).join(', ');\n\n // Get view definitions\n const viewsQuery = `\n SELECT \n table_name as view_name,\n table_schema as schema_name,\n view_definition\n FROM information_schema.views\n WHERE table_schema IN (${schemaFilter})\n ORDER BY table_schema, table_name\n `;\n\n const viewsResult = await pool.query(viewsQuery, schemas);\n\n // Get columns for each view\n const columnsQuery = `\n SELECT \n c.table_name as view_name,\n c.table_schema as schema_name,\n c.column_name,\n c.ordinal_position,\n c.data_type,\n c.udt_name,\n c.character_maximum_length,\n c.numeric_precision,\n c.numeric_scale,\n c.datetime_precision,\n c.is_nullable,\n c.column_default,\n COALESCE(\n (\n SELECT array_length(string_to_array(udt_name, '_'), 1) - 1\n FROM information_schema.element_types e\n WHERE e.object_schema = c.table_schema\n AND e.object_name = c.table_name\n AND e.collection_type_identifier = c.dtd_identifier\n ),\n 0\n ) as array_dimensions\n FROM information_schema.columns c\n WHERE c.table_schema IN (${schemaFilter})\n AND c.table_name IN (\n SELECT table_name \n FROM information_schema.views \n WHERE table_schema IN (${schemaFilter})\n )\n ORDER BY c.table_schema, c.table_name, c.ordinal_position\n `;\n\n const columnsResult = await pool.query(columnsQuery, schemas);\n\n const views: ViewMetadata[] = viewsResult.rows.map((row) => ({\n viewName: row.view_name,\n schemaName: row.schema_name,\n viewDefinition: row.view_definition,\n columns: [],\n }));\n\n // Add columns to views\n for (const row of columnsResult.rows) {\n const view = views.find(\n (v) => v.viewName === row.view_name && v.schemaName === row.schema_name\n );\n if (view) {\n view.columns.push({\n columnName: row.column_name,\n dataType: row.data_type,\n udtName: row.udt_name,\n isNullable: row.is_nullable === 'YES',\n columnDefault: row.column_default,\n characterMaximumLength: row.character_maximum_length,\n numericPrecision: row.numeric_precision,\n numericScale: row.numeric_scale,\n datetimePrecision: row.datetime_precision,\n arrayDimensions: row.array_dimensions,\n domainName: null,\n isArray: row.array_dimensions > 0,\n });\n }\n }\n\n return views;\n}\n\n/**\n * Introspect database routines (functions and procedures)\n */\nasync function introspectRoutines(\n pool: pg.Pool,\n schemas: string[]\n): Promise<RoutineMetadata[]> {\n const schemaFilter = schemas.map((_, i) => `$${i + 1}`).join(', ');\n\n // Get routine definitions\n const routinesQuery = `\n SELECT \n r.routine_name,\n r.routine_schema as schema_name,\n r.routine_type,\n r.security_type,\n r.data_type as return_type,\n CASE \n WHEN r.data_type = 'USER-DEFINED' THEN r.type_udt_name\n ELSE r.data_type\n END as return_udt_name,\n CASE\n WHEN r.data_type = 'ARRAY' THEN true\n ELSE false\n END as returns_set\n FROM information_schema.routines r\n WHERE r.routine_schema IN (${schemaFilter})\n ORDER BY r.routine_schema, r.routine_name\n `;\n\n const routinesResult = await pool.query(routinesQuery, schemas);\n\n // Get parameters for each routine\n const parametersQuery = `\n SELECT \n p.specific_name,\n r.routine_name,\n r.routine_schema as schema_name,\n p.parameter_name,\n p.parameter_mode,\n p.ordinal_position,\n p.data_type,\n CASE \n WHEN p.data_type = 'ARRAY' THEN p.udt_name\n WHEN p.data_type = 'USER-DEFINED' THEN p.udt_name\n ELSE p.data_type\n END as udt_name,\n CASE\n WHEN p.parameter_mode = 'OUT' OR p.parameter_mode = 'INOUT' THEN 'YES'\n ELSE 'NO'\n END as is_nullable\n FROM information_schema.parameters p\n JOIN information_schema.routines r ON p.specific_name = r.specific_name\n WHERE r.routine_schema IN (${schemaFilter})\n AND p.parameter_mode IS NOT NULL\n ORDER BY r.routine_schema, r.routine_name, p.ordinal_position\n `;\n\n const parametersResult = await pool.query(parametersQuery, schemas);\n\n const routines: RoutineMetadata[] = routinesResult.rows.map((row) => ({\n routineName: row.routine_name,\n schemaName: row.schema_name,\n routineType: row.routine_type as 'FUNCTION' | 'PROCEDURE',\n securityType: row.security_type as 'DEFINER' | 'INVOKER',\n returnType: row.return_type,\n returnUdtName: row.return_udt_name,\n returnsSet: row.returns_set,\n parameters: [],\n }));\n\n // Add parameters to routines\n for (const row of parametersResult.rows) {\n const routine = routines.find(\n (r) => r.routineName === row.routine_name && r.schemaName === row.schema_name\n );\n if (routine) {\n routine.parameters.push({\n parameterName: row.parameter_name || `param${row.ordinal_position}`,\n dataType: row.data_type,\n udtName: row.udt_name,\n parameterMode: row.parameter_mode,\n ordinalPosition: row.ordinal_position,\n isNullable: row.is_nullable === 'YES',\n });\n }\n }\n\n return routines;\n}\n","import type {\n ColumnMetadata,\n DatabaseMetadata,\n SchemaGenerationOptions,\n CheckConstraintMetadata,\n} from './types.js';\n\n/**\n * Map PostgreSQL column to Zod schema string with strict validation\n */\nexport function mapColumnToZod(\n column: ColumnMetadata,\n metadata: DatabaseMetadata,\n options: SchemaGenerationOptions,\n warnings: string[]\n): string {\n // Handle domains first\n if (column.domainName) {\n const domain = metadata.domains.find((d) => d.domainName === column.domainName);\n if (domain) {\n const schemaPrefix = toPascalCase(domain.schemaName);\n const domainName = toPascalCase(domain.domainName);\n let schema = `${schemaPrefix}${domainName}Schema`;\n return column.isNullable ? `${schema}.nullable()` : schema;\n }\n }\n\n // Handle arrays\n if (column.isArray) {\n const baseType = mapBaseTypeToZod(column, metadata, options, warnings);\n let arraySchema = `z.array(${baseType})`;\n \n // Multi-dimensional arrays\n if (column.arrayDimensions > 1) {\n for (let i = 1; i < column.arrayDimensions; i++) {\n arraySchema = `z.array(${arraySchema})`;\n }\n }\n \n return column.isNullable ? `${arraySchema}.nullable()` : arraySchema;\n }\n\n // Handle base types\n const baseSchema = mapBaseTypeToZod(column, metadata, options, warnings);\n return column.isNullable ? `${baseSchema}.nullable()` : baseSchema;\n}\n\n/**\n * Map base PostgreSQL type to Zod\n */\nfunction mapBaseTypeToZod(\n column: ColumnMetadata,\n metadata: DatabaseMetadata,\n options: SchemaGenerationOptions,\n warnings: string[]\n): string {\n let udtName = column.udtName;\n const dataType = column.dataType.toLowerCase();\n\n // PostgreSQL array types have underscore prefix (e.g., _text for text[], _int4 for integer[])\n // Strip the underscore to get the actual base type name\n if (column.isArray && udtName.startsWith('_')) {\n udtName = udtName.substring(1);\n }\n\n // Custom type mappings\n if (options.customTypeMappings?.[udtName]) {\n return options.customTypeMappings[udtName];\n }\n\n // Check if it's an enum\n const enumType = metadata.enums.find((e) => e.enumName === udtName);\n if (enumType) {\n const schemaPrefix = toPascalCase(enumType.schemaName);\n const enumName = toPascalCase(enumType.enumName);\n return `${schemaPrefix}${enumName}Schema`;\n }\n\n // Check if it's a composite type\n const compositeType = metadata.compositeTypes.find((t) => t.typeName === udtName);\n if (compositeType) {\n const schemaPrefix = toPascalCase(compositeType.schemaName);\n const typeName = toPascalCase(compositeType.typeName);\n // Add 'Composite' suffix to match generator\n return `${schemaPrefix}${typeName}CompositeSchema`;\n }\n\n // Check if it's a range type\n const rangeType = metadata.rangeTypes.find((r) => r.rangeName === udtName);\n if (rangeType) {\n const schemaPrefix = toPascalCase(rangeType.schemaName);\n const rangeName = toPascalCase(rangeType.rangeName);\n return `${schemaPrefix}${rangeName}Schema`;\n }\n\n // Map by data type or by udtName for arrays\n // For arrays, dataType will be 'ARRAY' so we need to check the udtName\n const typeToCheck = dataType === 'array' ? udtName : dataType;\n \n switch (typeToCheck) {\n // Numeric types\n case 'smallint':\n case 'integer':\n case 'int':\n case 'int2':\n case 'int4':\n return 'z.number().int()';\n \n case 'bigint':\n case 'int8':\n return 'z.bigint()';\n \n case 'decimal':\n case 'numeric':\n if (column.numericPrecision !== null && column.numericScale !== null) {\n return `z.number() /* precision: ${column.numericPrecision}, scale: ${column.numericScale} */`;\n }\n return 'z.number()';\n \n case 'real':\n case 'float4':\n return 'z.number()';\n \n case 'double precision':\n case 'float8':\n return 'z.number()';\n \n case 'money':\n return 'z.string().regex(/^\\\\$?[0-9,]+(\\\\.\\\\d{2})?$/)';\n\n // Text types\n case 'character varying':\n case 'varchar':\n if (column.characterMaximumLength) {\n return `z.string().max(${column.characterMaximumLength})`;\n }\n return 'z.string()';\n \n case 'character':\n case 'char':\n if (column.characterMaximumLength) {\n return `z.string().length(${column.characterMaximumLength})`;\n }\n return 'z.string()';\n \n case 'text':\n return 'z.string()';\n \n case 'citext':\n return 'z.string()';\n\n // Boolean\n case 'boolean':\n case 'bool':\n return 'z.boolean()';\n\n // Date/Time types\n case 'timestamp':\n case 'timestamp without time zone':\n return 'z.date()';\n \n case 'timestamp with time zone':\n case 'timestamptz':\n return 'z.date()';\n \n case 'date':\n return 'z.date()';\n \n case 'time':\n case 'time without time zone':\n return 'z.iso.time()';\n \n case 'time with time zone':\n case 'timetz':\n // PostgreSQL time with timezone, no direct Zod v4 equivalent\n return 'z.string().regex(/^\\\\d{2}:\\\\d{2}:\\\\d{2}(\\\\.\\\\d+)?[+-]\\\\d{2}:\\\\d{2}$/)';\n \n case 'interval':\n return 'z.iso.duration()';\n\n // UUID\n case 'uuid':\n return 'z.uuid()';\n\n // JSON types\n case 'json':\n return 'z.record(z.string(), z.unknown())';\n \n case 'jsonb':\n return 'z.record(z.string(), z.unknown())';\n\n // Network types\n case 'inet':\n // In Zod v4, use z.ipv4() or z.ipv6() but inet accepts both, so we use a union\n return 'z.union([z.ipv4(), z.ipv6()])';\n \n case 'cidr':\n // PostgreSQL cidr accepts both IPv4 and IPv6 CIDR notation\n return 'z.union([z.cidrv4(), z.cidrv6()])';\n \n case 'macaddr':\n return 'z.mac()';\n \n case 'macaddr8':\n // macaddr8 is 64-bit (8 bytes), standard z.mac() is 48-bit, use regex\n return 'z.string().regex(/^([0-9A-Fa-f]{2}[:-]){7}([0-9A-Fa-f]{2})$/)';\n\n // Bit string types\n case 'bit':\n if (column.characterMaximumLength) {\n return `z.string().regex(/^[01]{${column.characterMaximumLength}}$/)`;\n }\n return 'z.string().regex(/^[01]+$/)';\n \n case 'bit varying':\n case 'varbit':\n if (column.characterMaximumLength) {\n return `z.string().regex(/^[01]{0,${column.characterMaximumLength}}$/)`;\n }\n return 'z.string().regex(/^[01]*$/)';\n\n // Geometric types\n case 'point':\n return 'z.tuple([z.number(), z.number()])';\n \n case 'line':\n return 'z.object({ a: z.number(), b: z.number(), c: z.number() })';\n \n case 'lseg':\n return 'z.tuple([z.tuple([z.number(), z.number()]), z.tuple([z.number(), z.number()])])';\n \n case 'box':\n return 'z.tuple([z.tuple([z.number(), z.number()]), z.tuple([z.number(), z.number()])])';\n \n case 'path':\n return 'z.array(z.tuple([z.number(), z.number()]))';\n \n case 'polygon':\n return 'z.array(z.tuple([z.number(), z.number()]))';\n \n case 'circle':\n return 'z.object({ center: z.tuple([z.number(), z.number()]), radius: z.number() })';\n\n // Text search types\n case 'tsvector':\n return 'z.string() /* tsvector */';\n \n case 'tsquery':\n return 'z.string() /* tsquery */';\n\n // XML\n case 'xml':\n return 'z.string() /* XML */';\n\n // Binary data\n case 'bytea':\n return 'z.instanceof(Buffer)';\n\n // Other types\n case 'oid':\n return 'z.number().int().positive()';\n \n case 'regproc':\n case 'regprocedure':\n case 'regoper':\n case 'regoperator':\n case 'regclass':\n case 'regtype':\n case 'regrole':\n case 'regnamespace':\n case 'regconfig':\n case 'regdictionary':\n return 'z.string() /* PostgreSQL OID reference */';\n\n // pg_lsn\n case 'pg_lsn':\n return 'z.string().regex(/^[0-9A-F]+\\\\/[0-9A-F]+$/)';\n\n // User-defined base types or unknown\n default:\n const warning = `Unknown type: ${dataType} (udt: ${udtName}) in column ${column.columnName}`;\n warnings.push(warning);\n \n if (options.strictMode) {\n throw new Error(warning);\n }\n \n return 'z.unknown() /* unmapped type */';\n }\n}\n\n/**\n * Apply check constraints as Zod refinements\n */\nexport function applyCheckConstraints(\n columnName: string,\n baseSchema: string,\n constraints: CheckConstraintMetadata[]\n): string {\n let schema = baseSchema;\n\n for (const constraint of constraints) {\n // Try to parse simple check constraints\n const checkClause = constraint.checkClause.toLowerCase();\n\n // >= pattern\n const geMatch = checkClause.match(new RegExp(`${columnName}\\\\s*>=\\\\s*([\\\\d.]+)`));\n if (geMatch) {\n const value = geMatch[1];\n if (schema.includes('z.number()')) {\n schema = schema.replace('z.number()', `z.number().min(${value})`);\n } else if (schema.includes('z.bigint()')) {\n schema = schema.replace('z.bigint()', `z.bigint().min(${value}n)`);\n }\n continue;\n }\n\n // > pattern\n const gtMatch = checkClause.match(new RegExp(`${columnName}\\\\s*>\\\\s*([\\\\d.]+)`));\n if (gtMatch) {\n const value = parseFloat(gtMatch[1]);\n if (schema.includes('z.number()')) {\n schema = schema.replace('z.number()', `z.number().min(${value + Number.EPSILON})`);\n }\n continue;\n }\n\n // <= pattern\n const leMatch = checkClause.match(new RegExp(`${columnName}\\\\s*<=\\\\s*([\\\\d.]+)`));\n if (leMatch) {\n const value = leMatch[1];\n if (schema.includes('z.number()')) {\n schema = schema.replace('z.number()', `z.number().max(${value})`);\n } else if (schema.includes('z.bigint()')) {\n schema = schema.replace('z.bigint()', `z.bigint().max(${value}n)`);\n }\n continue;\n }\n\n // < pattern\n const ltMatch = checkClause.match(new RegExp(`${columnName}\\\\s*<\\\\s*([\\\\d.]+)`));\n if (ltMatch) {\n const value = parseFloat(ltMatch[1]);\n if (schema.includes('z.number()')) {\n schema = schema.replace('z.number()', `z.number().max(${value - Number.EPSILON})`);\n }\n continue;\n }\n\n // BETWEEN pattern\n const betweenMatch = checkClause.match(\n new RegExp(`${columnName}\\\\s*between\\\\s*([\\\\d.]+)\\\\s*and\\\\s*([\\\\d.]+)`)\n );\n if (betweenMatch) {\n const [, min, max] = betweenMatch;\n if (schema.includes('z.number()')) {\n schema = schema.replace('z.number()', `z.number().min(${min}).max(${max})`);\n }\n continue;\n }\n\n // IN pattern (standard SQL)\n const inMatch = checkClause.match(\n new RegExp(`${columnName}\\\\s*in\\\\s*\\\\(([^)]+)\\\\)`)\n );\n if (inMatch) {\n const values = inMatch[1].split(',').map((v: string) => v.trim().replace(/'/g, ''));\n if (schema.includes('z.string()')) {\n const enumValues = values.map((v: string) => `'${v}'`).join(', ');\n schema = `z.enum([${enumValues}])`;\n }\n continue;\n }\n\n // PostgreSQL ANY (ARRAY[...]) pattern\n const anyArrayMatch = checkClause.match(\n new RegExp(`\\\\(?${columnName}\\\\s*=\\\\s*any\\\\s*\\\\(array\\\\[([^\\\\]]+)\\\\]`)\n );\n if (anyArrayMatch) {\n // Extract values from ARRAY['val1'::text, 'val2'::text]\n const valuesStr = anyArrayMatch[1];\n const values = valuesStr\n .split(',')\n .map((v: string) => {\n const match = v.trim().match(/'([^']+)'/);\n return match ? match[1] : null;\n })\n .filter((v: string | null): v is string => v !== null);\n \n if (values.length > 0 && schema.includes('z.string()')) {\n const enumValues = values.map((v: string) => `'${v}'`).join(', ');\n schema = `z.enum([${enumValues}])`;\n continue;\n }\n }\n\n // REGEX/~ pattern\n const regexMatch = checkClause.match(\n new RegExp(`${columnName}\\\\s*~\\\\s*'([^']+)'`)\n );\n if (regexMatch) {\n const pattern = regexMatch[1];\n if (schema.includes('z.string()')) {\n schema = schema.replace('z.string()', `z.string().regex(/${pattern}/)`);\n }\n continue;\n }\n\n // LENGTH pattern\n const lengthMatch = checkClause.match(\n new RegExp(`length\\\\(${columnName}\\\\)\\\\s*([><=]+)\\\\s*([\\\\d]+)`)\n );\n if (lengthMatch) {\n const [, operator, value] = lengthMatch;\n if (schema.includes('z.string()')) {\n if (operator === '>=' || operator === '>') {\n schema = schema.replace('z.string()', `z.string().min(${value})`);\n } else if (operator === '<=' || operator === '<') {\n schema = schema.replace('z.string()', `z.string().max(${value})`);\n }\n }\n continue;\n }\n\n // If we can't parse it, add as a comment\n schema += ` /* CHECK: ${constraint.checkClause} */`;\n }\n\n return schema;\n}\n\n/**\n * Convert snake_case to PascalCase\n */\nexport function toPascalCase(str: string): string {\n return str\n .split('_')\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join('');\n}\n\n/**\n * Convert snake_case to camelCase\n */\nexport function toCamelCase(str: string): string {\n const pascal = toPascalCase(str);\n return pascal.charAt(0).toLowerCase() + pascal.slice(1);\n}\n","import type {\n ColumnMetadata,\n DatabaseMetadata,\n GeneratedSchema,\n GenerationResult,\n SchemaGenerationOptions,\n TableMetadata,\n ViewMetadata,\n RoutineMetadata,\n} from './types.js';\nimport {applyCheckConstraints, mapColumnToZod, toCamelCase, toPascalCase,} from './type-mapper.js';\n\n/**\n * Generate Zod schemas from database metadata\n */\nexport function generateSchemas(\n metadata: DatabaseMetadata,\n options: SchemaGenerationOptions = {}\n): GenerationResult {\n const warnings: string[] = [];\n const schemas: GeneratedSchema[] = [];\n\n // Generate enum schemas\n const enums = metadata.enums.map((enumType) => ({\n name: toPascalCase(enumType.schemaName) + toPascalCase(enumType.enumName),\n code: generateEnumSchema(enumType.enumName, enumType.enumValues, options, enumType.schemaName),\n }));\n\n // Generate range type schemas\n const ranges = metadata.rangeTypes.map((rangeType) => ({\n name: toPascalCase(rangeType.schemaName) + toPascalCase(rangeType.rangeName),\n code: generateRangeSchema(rangeType.rangeName, rangeType.subtype, metadata, options, warnings, rangeType.schemaName),\n }));\n\n // Generate composite type schemas (only if flag is set)\n const compositeTypes = options.includeCompositeTypes\n ? metadata.compositeTypes.map((compositeType) => ({\n name: toPascalCase(compositeType.schemaName) + toPascalCase(compositeType.typeName) + 'Composite',\n code: generateCompositeTypeSchema(compositeType, metadata, options, warnings),\n }))\n : [];\n\n // Generate domain schemas\n const domains = metadata.domains.map((domain) => ({\n name: toPascalCase(domain.schemaName) + toPascalCase(domain.domainName),\n code: generateDomainSchema(domain, metadata, options, warnings),\n }));\n\n // Generate table schemas\n for (const table of metadata.tables) {\n const schema = generateTableSchema(table, metadata, options, warnings);\n schemas.push(schema);\n }\n\n // Generate view schemas\n const views = metadata.views?.map((view) => ({\n name: toPascalCase(view.schemaName) + toPascalCase(view.viewName),\n code: generateViewSchema(view, metadata, options, warnings),\n })) || [];\n\n // Generate routine schemas (filter by security type and internal types)\n const filteredRoutines = metadata.routines?.filter((routine) => {\n // By default, only include SECURITY DEFINER functions\n // Include SECURITY INVOKER only if explicitly requested\n if (routine.securityType === 'INVOKER' && !options.includeSecurityInvoker) {\n return false;\n }\n \n // Skip routines with internal PostgreSQL types\n // These are low-level system functions not meant for application use\n const internalTypes = ['internal', 'trigger', 'event_trigger', 'cstring', 'opaque', '\"char\"', 'language_handler', 'fdw_handler', 'index_am_handler', 'tsm_handler', 'table_am_handler'];\n \n // Check parameters for internal types\n const hasInternalParam = routine.parameters.some(param => \n internalTypes.includes(param.dataType.toLowerCase()) || \n internalTypes.includes(param.udtName.toLowerCase())\n );\n \n // Check return type for internal types\n const hasInternalReturn = routine.returnType && (\n internalTypes.includes(routine.returnType.toLowerCase()) ||\n (routine.returnUdtName && internalTypes.includes(routine.returnUdtName.toLowerCase()))\n );\n \n if (hasInternalParam || hasInternalReturn) {\n return false;\n }\n \n // Skip functions with duplicate parameter names (would cause invalid TypeScript)\n const paramNames = routine.parameters.map(p => p.parameterName.toLowerCase());\n const hasDuplicateParams = new Set(paramNames).size !== paramNames.length;\n if (hasDuplicateParams) {\n return false;\n }\n \n return true;\n }) || [];\n\n // Handle function overloading by skipping duplicates - only keep first occurrence\n const seenRoutineNames = new Set<string>();\n const uniqueRoutines = filteredRoutines.filter((routine) => {\n const baseName = toPascalCase(routine.schemaName) + toPascalCase(routine.routineName);\n \n if (seenRoutineNames.has(baseName)) {\n // Skip duplicates (overloaded functions)\n return false;\n }\n \n seenRoutineNames.add(baseName);\n return true;\n });\n \n const routines = uniqueRoutines.map((routine) => ({\n name: toPascalCase(routine.schemaName) + toPascalCase(routine.routineName),\n code: generateRoutineSchema(routine, metadata, options, warnings),\n }));\n\n return {\n schemas,\n enums,\n compositeTypes,\n domains,\n ranges,\n views,\n routines,\n warnings,\n };\n}\n\n/**\n * Generate enum schema\n */\nfunction generateEnumSchema(\n enumName: string,\n values: string[],\n options: SchemaGenerationOptions,\n schemaPrefix?: string\n): string {\n const baseName = toPascalCase(enumName);\n const fullName = schemaPrefix ? `${toPascalCase(schemaPrefix)}${baseName}` : baseName;\n const schemaName = `${fullName}Schema`;\n const typeName = fullName;\n\n const valuesStr = values.map((v) => `'${v}'`).join(', ');\n\n let code = '';\n\n if (options.includeComments) {\n code += `/** PostgreSQL enum: ${enumName} */\\n`;\n }\n\n code += `export const ${schemaName} = z.enum([${valuesStr}]);\\n`;\n code += `export type ${typeName} = z.infer<typeof ${schemaName}>;\\n`;\n\n return code;\n}\n\n/**\n * Generate range type schema\n */\nfunction generateRangeSchema(\n rangeName: string,\n subtype: string,\n _metadata: DatabaseMetadata,\n options: SchemaGenerationOptions,\n _warnings: string[],\n schemaPrefix?: string\n): string {\n const baseName = toPascalCase(rangeName);\n const fullName = schemaPrefix ? `${toPascalCase(schemaPrefix)}${baseName}` : baseName;\n const schemaName = `${fullName}Schema`;\n const typeName = fullName;\n\n // Map subtype to Zod schema\n const subtypeSchema = mapSubtypeToZod(subtype, _metadata);\n\n let code = '';\n\n if (options.includeComments) {\n code += `/** PostgreSQL range type: ${rangeName}<${subtype}> */\\n`;\n }\n\n // Ranges represented as [lower, upper] tuple with nullable bounds\n code += `export const ${schemaName} = z.tuple([${subtypeSchema}.nullable(), ${subtypeSchema}.nullable()]);\\n`;\n code += `export type ${typeName} = z.infer<typeof ${schemaName}>;\\n`;\n\n return code;\n}\n\n/**\n * Map PostgreSQL subtype to Zod for range types\n */\nfunction mapSubtypeToZod(subtype: string, _metadata: DatabaseMetadata): string {\n const normalized = subtype.toLowerCase();\n\n switch (normalized) {\n case 'integer':\n case 'int':\n case 'int4':\n return 'z.number().int()';\n case 'bigint':\n case 'int8':\n return 'z.bigint()';\n case 'numeric':\n case 'decimal':\n return 'z.number()';\n case 'date':\n return 'z.date()';\n case 'timestamp':\n case 'timestamp without time zone':\n case 'timestamp with time zone':\n case 'timestamptz':\n return 'z.date()';\n default:\n return 'z.unknown()';\n }\n}\n\n/**\n * Generate composite type schema\n */\nfunction generateCompositeTypeSchema(\n compositeType: any,\n metadata: DatabaseMetadata,\n options: SchemaGenerationOptions,\n warnings: string[]\n): string {\n const baseName = toPascalCase(compositeType.typeName);\n const schemaPrefix = toPascalCase(compositeType.schemaName);\n // Add 'Composite' suffix to distinguish from tables with same name\n const fullName = `${schemaPrefix}${baseName}Composite`;\n const schemaName = `${fullName}Schema`;\n const typeName = fullName;\n\n let code = '';\n\n if (options.includeComments) {\n code += `/** PostgreSQL composite type: ${compositeType.typeName} */\\n`;\n }\n\n code += `export const ${schemaName} = z.object({\\n`;\n\n for (const attr of compositeType.attributes) {\n const fieldName = options.useCamelCase ? toCamelCase(attr.attributeName) : attr.attributeName;\n\n // Create a mock column for type mapping\n const mockColumn: ColumnMetadata = {\n columnName: attr.attributeName,\n dataType: attr.dataType,\n isNullable: true, // Composite type attributes can be null\n columnDefault: null,\n characterMaximumLength: null,\n numericPrecision: null,\n numericScale: null,\n datetimePrecision: null,\n udtName: attr.dataType,\n domainName: null,\n arrayDimensions: 0,\n isArray: false,\n };\n\n const zodType = mapColumnToZod(mockColumn, metadata, options, warnings);\n\n if (options.includeComments) {\n code += ` /** ${attr.dataType} */\\n`;\n }\n code += ` ${fieldName}: ${zodType},\\n`;\n }\n\n code += `});\\n`;\n code += `export type ${typeName} = z.infer<typeof ${schemaName}>;\\n`;\n\n return code;\n}\n\n/**\n * Generate domain schema\n */\nfunction generateDomainSchema(\n domain: any,\n metadata: DatabaseMetadata,\n options: SchemaGenerationOptions,\n warnings: string[]\n): string {\n const baseName = toPascalCase(domain.domainName);\n const schemaPrefix = toPascalCase(domain.schemaName);\n const fullName = `${schemaPrefix}${baseName}`;\n const schemaName = `${fullName}Schema`;\n const typeName = fullName;\n\n // Create a mock column for type mapping\n const mockColumn: ColumnMetadata = {\n columnName: domain.domainName,\n dataType: domain.dataType,\n isNullable: domain.isNullable,\n columnDefault: domain.domainDefault,\n characterMaximumLength: domain.characterMaximumLength,\n numericPrecision: domain.numericPrecision,\n numericScale: domain.numericScale,\n datetimePrecision: null,\n udtName: domain.dataType,\n domainName: null,\n arrayDimensions: 0,\n isArray: false,\n };\n\n let zodType = mapColumnToZod(mockColumn, metadata, options, warnings);\n\n // Apply domain check constraints\n if (domain.checkConstraints.length > 0) {\n zodType = applyCheckConstraints(domain.domainName, zodType, domain.checkConstraints);\n }\n\n let code = '';\n\n if (options.includeComments) {\n code += `/** PostgreSQL domain: ${domain.domainName} (base: ${domain.dataType}) */\\n`;\n }\n\n code += `export const ${schemaName} = ${zodType};\\n`;\n code += `export type ${typeName} = z.infer<typeof ${schemaName}>;\\n`;\n\n return code;\n}\n\n/**\n * Generate view schema (read-only)\n */\nfunction generateViewSchema(\n view: ViewMetadata,\n metadata: DatabaseMetadata,\n options: SchemaGenerationOptions,\n warnings: string[]\n): string {\n const schemaPrefix = toPascalCase(view.schemaName);\n const viewName = toPascalCase(view.viewName);\n const schemaName = `${schemaPrefix}${viewName}Schema`;\n const typeName = `${schemaPrefix}${viewName}`;\n\n let code = '';\n\n if (options.includeComments) {\n code += `/** View: ${view.schemaName}.${view.viewName} (read-only) */\\n`;\n }\n\n code += `export const ${schemaName} = z.object({\\n`;\n\n for (const column of view.columns) {\n const fieldName = options.useCamelCase ? toCamelCase(column.columnName) : column.columnName;\n const zodType = mapColumnToZod(column, metadata, options, warnings);\n\n if (options.includeComments) {\n code += ` /** ${column.dataType} */\\n`;\n }\n code += ` ${fieldName}: ${zodType},\\n`;\n }\n\n code += `});\\n`;\n code += `export type ${typeName} = z.infer<typeof ${schemaName}>;\\n`;\n\n return code;\n}\n\n/**\n * Generate routine schema (function/procedure)\n */\nfunction generateRoutineSchema(\n routine: RoutineMetadata,\n metadata: DatabaseMetadata,\n options: SchemaGenerationOptions,\n warnings: string[]\n): string {\n const schemaPrefix = toPascalCase(routine.schemaName);\n const routineName = toPascalCase(routine.routineName);\n const paramsSchemaName = `${schemaPrefix}${routineName}ParamsSchema`;\n const returnSchemaName = `${schemaPrefix}${routineName}ReturnSchema`;\n const paramsTypeName = `${schemaPrefix}${routineName}Params`;\n const returnTypeName = `${schemaPrefix}${routineName}Return`;\n\n let code = '';\n\n if (options.includeComments) {\n code += `/** ${routine.routineType}: ${routine.schemaName}.${routine.routineName} */\\n`;\n }\n\n // Generate parameters schema (input)\n const inParams = routine.parameters.filter(\n (p) => p.parameterMode === 'IN' || p.parameterMode === 'INOUT'\n );\n\n if (inParams.length > 0) {\n code += `export const ${paramsSchemaName} = z.object({\\n`;\n\n for (const param of inParams) {\n const fieldName = options.useCamelCase ? toCamelCase(param.parameterName) : param.parameterName;\n\n // Create a mock column for type mapping\n const mockColumn: ColumnMetadata = {\n columnName: param.parameterName,\n dataType: param.dataType,\n isNullable: param.isNullable,\n columnDefault: null,\n characterMaximumLength: null,\n numericPrecision: null,\n numericScale: null,\n datetimePrecision: null,\n udtName: param.udtName,\n domainName: null,\n arrayDimensions: 0,\n isArray: param.dataType === 'ARRAY',\n };\n\n const zodType = mapColumnToZod(mockColumn, metadata, options, warnings);\n\n if (options.includeComments) {\n code += ` /** ${param.dataType} (${param.parameterMode}) */\\n`;\n }\n code += ` ${fieldName}: ${zodType},\\n`;\n }\n\n code += `});\\n`;\n code += `export type ${paramsTypeName} = z.infer<typeof ${paramsSchemaName}>;\\n\\n`;\n }\n\n // Generate return type schema (output)\n const outParams = routine.parameters.filter(\n (p) => p.parameterMode === 'OUT' || p.parameterMode === 'INOUT'\n );\n\n if (routine.routineType === 'FUNCTION' && routine.returnType && routine.returnType !== 'void') {\n // For functions with return values\n if (outParams.length > 0) {\n // Multiple output parameters - return object\n code += `export const ${returnSchemaName} = z.object({\\n`;\n\n for (const param of outParams) {\n const fieldName = options.useCamelCase ? toCamelCase(param.parameterName) : param.parameterName;\n\n const mockColumn: ColumnMetadata = {\n columnName: param.parameterName,\n dataType: param.dataType,\n isNullable: param.isNullable,\n columnDefault: null,\n characterMaximumLength: null,\n numericPrecision: null,\n numericScale: null,\n datetimePrecision: null,\n udtName: param.udtName,\n domainName: null,\n arrayDimensions: 0,\n isArray: param.dataType === 'ARRAY',\n };\n\n const zodType = mapColumnToZod(mockColumn, metadata, options, warnings);\n\n if (options.includeComments) {\n code += ` /** ${param.dataType} (${param.parameterMode}) */\\n`;\n }\n code += ` ${fieldName}: ${zodType},\\n`;\n }\n\n code += `});\\n`;\n } else {\n // Single return value\n const mockColumn: ColumnMetadata = {\n columnName: 'return_value',\n dataType: routine.returnType,\n isNullable: false,\n columnDefault: null,\n characterMaximumLength: null,\n numericPrecision: null,\n numericScale: null,\n datetimePrecision: null,\n udtName: routine.returnUdtName || routine.returnType,\n domainName: null,\n arrayDimensions: 0,\n isArray: routine.returnType === 'ARRAY' || routine.returnsSet,\n };\n\n const zodType = mapColumnToZod(mockColumn, metadata, options, warnings);\n \n if (options.includeComments) {\n code += `/** Returns: ${routine.returnType} */\\n`;\n }\n \n if (routine.returnsSet) {\n code += `export const ${returnSchemaName} = z.array(${zodType});\\n`;\n } else {\n code += `export const ${returnSchemaName} = ${zodType};\\n`;\n }\n }\n\n code += `export type ${returnTypeName} = z.infer<typeof ${returnSchemaName}>;\\n`;\n } else if (outParams.length > 0) {\n // Procedures with OUT parameters\n code += `export const ${returnSchemaName} = z.object({\\n`;\n\n for (const param of outParams) {\n const fieldName = options.useCamelCase ? toCamelCase(param.parameterName) : param.parameterName;\n\n const mockColumn: ColumnMetadata = {\n columnName: param.parameterName,\n dataType: param.dataType,\n isNullable: param.isNullable,\n columnDefault: null,\n characterMaximumLength: null,\n numericPrecision: null,\n numericScale: null,\n datetimePrecision: null,\n udtName: param.udtName,\n domainName: null,\n arrayDimensions: 0,\n isArray: param.dataType === 'ARRAY',\n };\n\n const zodType = mapColumnToZod(mockColumn, metadata, options, warnings);\n\n if (options.includeComments) {\n code += ` /** ${param.dataType} (${param.parameterMode}) */\\n`;\n }\n code += ` ${fieldName}: ${zodType},\\n`;\n }\n\n code += `});\\n`;\n code += `export type ${returnTypeName} = z.infer<typeof ${returnSchemaName}>;\\n`;\n }\n\n return code;\n}\n\n/**\n * Generate table schema\n */\nfunction generateTableSchema(\n table: TableMetadata,\n metadata: DatabaseMetadata,\n options: SchemaGenerationOptions,\n warnings: string[]\n): GeneratedSchema {\n // Include schema name to avoid collisions (e.g., PublicCommentThreadsSchema)\n const schemaPrefix = toPascalCase(table.schemaName);\n const tableName = toPascalCase(table.tableName);\n const schemaName = `${schemaPrefix}${tableName}`;\n const readSchemaName = `${schemaName}Schema`;\n const insertSchemaName = `${schemaName}InsertSchema`;\n const updateSchemaName = `${schemaName}UpdateSchema`;\n const typeName = schemaName;\n const insertTypeName = `${schemaName}Insert`;\n const updateTypeName = `${schemaName}Update`;\n\n // Generate read schema (complete)\n let readCode = '';\n\n if (options.includeComments) {\n readCode += `/** Table: ${table.schemaName}.${table.tableName} */\\n`;\n }\n\n readCode += `export const ${readSchemaName} = z.object({\\n`;\n\n for (const column of table.columns) {\n const fieldName = options.useCamelCase ? toCamelCase(column.columnName) : column.columnName;\n\n let zodType = mapColumnToZod(column, metadata, options, warnings);\n\n // Apply column-specific check constraints\n const columnConstraints = table.checkConstraints.filter(\n (c) => c.columnName === column.columnName\n );\n if (columnConstraints.length > 0) {\n zodType = applyCheckConstraints(column.columnName, zodType, columnConstraints);\n }\n\n if (options.includeComments) {\n const commentParts = [column.dataType];\n if (column.columnDefault) {\n commentParts.push(`default: ${column.columnDefault}`);\n }\n readCode += ` /** ${commentParts.join(', ')} */\\n`;\n }\n\n readCode += ` ${fieldName}: ${zodType},\\n`;\n }\n\n readCode += `});\\n`;\n readCode += `export type ${typeName} = z.infer<typeof ${readSchemaName}>;\\n`;\n\n // Generate insert and update schemas\n // Default to true if not specified\n let insertCode: string | undefined;\n let updateCode: string | undefined;\n\n if (options.generateInputSchemas !== false) {\n // Collect fields that should be optional for insert\n const optionalFields: Array<{ fieldName: string; zodType: string; comment?: string }> = [];\n\n for (const column of table.columns) {\n const fieldName = options.useCamelCase ? toCamelCase(column.columnName) : column.columnName;\n\n // Determine if field should be optional in insert\n const hasDefault = column.columnDefault !== null;\n const isSerial = column.columnDefault?.includes('nextval') ?? false;\n const isAutoGenerated = isSerial || column.columnDefault?.includes('gen_random_uuid()') || false;\n\n if (isAutoGenerated || hasDefault) {\n // Get the base type\n let zodType = mapColumnToZod(column, metadata, options, warnings);\n\n // Apply column-specific check constraints\n const columnConstraints = table.checkConstraints.filter(\n (c) => c.columnName === column.columnName\n );\n if (columnConstraints.length > 0) {\n zodType = applyCheckConstraints(column.columnName, zodType, columnConstraints);\n }\n\n // Make it optional\n zodType = `${zodType}.optional()`;\n\n let comment: string | undefined;\n if (options.includeComments) {\n const commentParts = [column.dataType];\n if (hasDefault) {\n commentParts.push(`default: ${column.columnDefault}`);\n }\n if (isSerial) {\n commentParts.push('auto-generated');\n }\n comment = commentParts.join(', ');\n }\n\n optionalFields.push({fieldName, zodType, comment});\n }\n }\n\n // Generate INSERT schema using .extend() if there are optional fields\n insertCode = '';\n\n if (options.includeComments) {\n insertCode += `/** Insert schema for ${table.tableName} */\\n`;\n }\n\n if (optionalFields.length === 0) {\n // No optional fields - just use the read schema directly\n insertCode += `export const ${insertSchemaName} = ${readSchemaName};\\n`;\n } else {\n // Use .extend() to override optional fields\n insertCode += `export const ${insertSchemaName} = ${readSchemaName}.extend({\\n`;\n\n for (const field of optionalFields) {\n if (field.comment) {\n insertCode += ` /** ${field.comment} */\\n`;\n }\n insertCode += ` ${field.fieldName}: ${field.zodType},\\n`;\n }\n\n insertCode += `});\\n`;\n }\n\n insertCode += `export type ${insertTypeName} = z.infer<typeof ${insertSchemaName}>;\\n`;\n\n // Generate UPDATE schema using .partial() - all fields optional\n updateCode = '';\n\n if (options.includeComments) {\n updateCode += `/** Update schema for ${table.tableName} (all fields optional) */\\n`;\n }\n\n updateCode += `export const ${updateSchemaName} = ${readSchemaName}.partial();\\n`;\n updateCode += `export type ${updateTypeName} = z.infer<typeof ${updateSchemaName}>;\\n`;\n }\n\n return {\n tableName: table.tableName,\n schemaName: table.schemaName,\n readSchema: readCode,\n inputSchema: insertCode,\n typeDefinitions: `${readCode}${insertCode ? '\\n' + insertCode : ''}${updateCode ? '\\n' + updateCode : ''}`,\n };\n}\n\n/**\n * Format the complete output file\n */\nexport function formatOutput(result: GenerationResult): string {\n let output = `/**\\n`;\n output += ` * ==========================================\\n`;\n output += ` * | GENERATED BY PG2ZOD |\\n`;\n output += ` * ==========================================\\n`;\n output += ` *\\n`;\n output += ` * ⚠️ DO NOT EDIT THIS FILE MANUALLY!\\n`;\n output += ` *\\n`;\n output += ` * This file was automatically generated from\\n`;\n output += ` * your PostgreSQL database schema.\\n`;\n output += ` *\\n`;\n output += ` * To regenerate, run:\\n`;\n output += ` * pg2zod --url <connection-url> -o <file>\\n`;\n output += ` *\\n`;\n output += ` * Any manual changes will be overwritten when\\n`;\n output += ` * the code is regenerated.\\n`;\n output += ` * ==========================================\\n`;\n output += ` */\\n\\n`;\n output += `import { z } from 'zod';\\n\\n`;\n\n // Enums\n if (result.enums.length > 0) {\n output += `// ============================================\\n`;\n output += `// Enums\\n`;\n output += `// ============================================\\n\\n`;\n\n for (const enumSchema of result.enums) {\n output += enumSchema.code + '\\n';\n }\n }\n\n // Domains\n if (result.domains.length > 0) {\n output += `// ============================================\\n`;\n output += `// Domains\\n`;\n output += `// ============================================\\n\\n`;\n\n for (const domain of result.domains) {\n output += domain.code + '\\n';\n }\n }\n\n // Ranges\n if (result.ranges.length > 0) {\n output += `// ============================================\\n`;\n output += `// Range Types\\n`;\n output += `// ============================================\\n\\n`;\n\n for (const range of result.ranges) {\n output += range.code + '\\n';\n }\n }\n\n // Composite types\n if (result.compositeTypes.length > 0) {\n output += `// ============================================\\n`;\n output += `// Composite Types\\n`;\n output += `// ============================================\\n\\n`;\n\n for (const compositeType of result.compositeTypes) {\n output += compositeType.code + '\\n';\n }\n }\n\n // Tables\n if (result.schemas.length > 0) {\n output += `// ============================================\\n`;\n output += `// Tables\\n`;\n output += `// ============================================\\n\\n`;\n\n for (const schema of result.schemas) {\n output += schema.typeDefinitions + '\\n';\n }\n }\n\n // Views\n if (result.views && result.views.length > 0) {\n output += `// ============================================\\n`;\n output += `// Views\\n`;\n output += `// ============================================\\n\\n`;\n\n for (const view of result.views) {\n output += view.code + '\\n';\n }\n }\n\n // Routines\n if (result.routines && result.routines.length > 0) {\n output += `// ============================================\\n`;\n output += `// Routines (Functions/Procedures)\\n`;\n output += `// ============================================\\n\\n`;\n\n for (const routine of result.routines) {\n output += routine.code + '\\n';\n }\n }\n\n // Warnings\n if (result.warnings.length > 0) {\n output += `// ============================================\\n`;\n output += `// Warnings\\n`;\n output += `// ============================================\\n`;\n output += `// The following warnings were generated:\\n`;\n\n for (const warning of result.warnings) {\n output += `// - ${warning}\\n`;\n }\n }\n\n return output;\n}\n","import {introspectDatabase} from './introspect.js';\nimport {formatOutput, generateSchemas} from './generator.js';\nimport type {DatabaseConfig, GenerationResult, SchemaGenerationOptions,} from './types.js';\n\nexport type {\n DatabaseConfig,\n SchemaGenerationOptions,\n GenerationResult,\n DatabaseMetadata,\n TableMetadata,\n ColumnMetadata,\n EnumMetadata,\n CompositeTypeMetadata,\n RangeTypeMetadata,\n DomainMetadata,\n CheckConstraintMetadata,\n GeneratedSchema,\n} from './types.js';\n\nexport {introspectDatabase} from './introspect.js';\nexport {generateSchemas, formatOutput} from './generator.js';\nexport {mapColumnToZod, toPascalCase, toCamelCase} from './type-mapper.js';\n\n/**\n * Main function: introspect database and generate Zod schemas\n */\nexport async function generateZodSchemas(\n config: DatabaseConfig,\n options: SchemaGenerationOptions = {}\n): Promise<GenerationResult> {\n const metadata = await introspectDatabase(config, options);\n return generateSchemas(metadata, options);\n}\n\n/**\n * Convenience function: generate schemas and return formatted output string\n */\nexport async function generateZodSchemasString(\n config: DatabaseConfig,\n options: SchemaGenerationOptions = {}\n): Promise<string> {\n const result = await generateZodSchemas(config, options);\n return formatOutput(result);\n}\n\n/**\n * Default export\n */\nexport default {\n generateZodSchemas,\n generateZodSchemasString,\n introspectDatabase,\n generateSchemas,\n formatOutput,\n};\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pg2zod",
3
- "version": "2.1.0",
3
+ "version": "2.1.2",
4
4
  "type": "module",
5
5
  "description": "Introspect PostgreSQL databases and generate strict, comprehensive Zod v4 schemas with full type coverage",
6
6
  "main": "./dist/index.js",
@@ -38,12 +38,12 @@
38
38
  "license": "MIT",
39
39
  "repository": {
40
40
  "type": "git",
41
- "url": "https://github.com/theNkennaAmadi/pg-to-zod.git"
41
+ "url": "https://github.com/theNkennaAmadi/pg2zod.git"
42
42
  },
43
43
  "bugs": {
44
- "url": "https://github.com/theNkennaAmadi/pg-to-zod/issues"
44
+ "url": "https://github.com/theNkennaAmadi/pg2zod/issues"
45
45
  },
46
- "homepage": "https://github.com/theNkennaAmadi/pg-to-zod#readme",
46
+ "homepage": "https://github.com/theNkennaAmadi/pg2zod#readme",
47
47
  "publishConfig": {
48
48
  "access": "public",
49
49
  "registry": "https://registry.npmjs.org/"
@@ -1 +0,0 @@
1
- {"version":3,"file":"src-CEkWBxDB.js","names":[],"sources":["../src/introspect.ts","../src/type-mapper.ts","../src/generator.ts","../src/index.ts"],"sourcesContent":["import pg from 'pg';\nimport type {\n DatabaseConfig,\n DatabaseMetadata,\n TableMetadata,\n ViewMetadata,\n RoutineMetadata,\n EnumMetadata,\n CompositeTypeMetadata,\n RangeTypeMetadata,\n DomainMetadata,\n SchemaGenerationOptions,\n} from './types.js';\n\nconst { Pool } = pg;\n\n/**\n * Introspect a PostgreSQL database and return complete metadata\n */\nexport async function introspectDatabase(\n config: DatabaseConfig,\n options: SchemaGenerationOptions = {}\n): Promise<DatabaseMetadata> {\n const pool = new Pool(config);\n\n try {\n const schemas = options.schemas ?? ['public'];\n\n const [\n tables,\n views,\n routines,\n enums,\n compositeTypes,\n rangeTypes,\n domains,\n ] = await Promise.all([\n introspectTables(pool, schemas, options),\n options.includeViews ? introspectViews(pool, schemas) : Promise.resolve([]),\n options.includeRoutines ? introspectRoutines(pool, schemas) : Promise.resolve([]),\n introspectEnums(pool, schemas),\n introspectCompositeTypes(pool, schemas),\n introspectRangeTypes(pool, schemas),\n introspectDomains(pool, schemas),\n ]);\n\n return {\n tables,\n views,\n routines,\n enums,\n compositeTypes,\n rangeTypes,\n domains,\n };\n } finally {\n await pool.end();\n }\n}\n\n/**\n * Introspect tables and their columns\n */\nasync function introspectTables(\n pool: pg.Pool,\n schemas: string[],\n options: SchemaGenerationOptions\n): Promise<TableMetadata[]> {\n const schemaFilter = schemas.map((_, i) => `$${i + 1}`).join(', ');\n\n // Get all columns\n const columnsQuery = `\n SELECT \n c.table_schema,\n c.table_name,\n c.column_name,\n c.data_type,\n c.is_nullable,\n c.column_default,\n c.character_maximum_length,\n c.numeric_precision,\n c.numeric_scale,\n c.datetime_precision,\n c.udt_name,\n c.domain_name,\n COALESCE(\n (SELECT array_ndims(ARRAY[]::text[]) FROM information_schema.element_types e \n WHERE e.object_schema = c.table_schema \n AND e.object_name = c.table_name \n AND e.object_type = 'TABLE'\n AND e.collection_type_identifier = c.dtd_identifier\n ), 0\n ) as array_dimensions\n FROM information_schema.columns c\n WHERE c.table_schema IN (${schemaFilter})\n ORDER BY c.table_schema, c.table_name, c.ordinal_position\n `;\n\n const columnsResult = await pool.query(columnsQuery, schemas);\n\n // Get check constraints\n const constraintsQuery = `\n SELECT \n tc.table_schema,\n tc.table_name,\n tc.constraint_name,\n cc.check_clause,\n ccu.column_name\n FROM information_schema.table_constraints tc\n JOIN information_schema.check_constraints cc \n ON tc.constraint_name = cc.constraint_name \n AND tc.constraint_schema = cc.constraint_schema\n LEFT JOIN information_schema.constraint_column_usage ccu\n ON tc.constraint_name = ccu.constraint_name\n AND tc.constraint_schema = ccu.constraint_schema\n WHERE tc.constraint_type = 'CHECK'\n AND tc.table_schema IN (${schemaFilter})\n `;\n\n const constraintsResult = await pool.query(constraintsQuery, schemas);\n\n // Get primary keys\n const primaryKeysQuery = `\n SELECT \n tc.table_schema,\n tc.table_name,\n kcu.column_name\n FROM information_schema.table_constraints tc\n JOIN information_schema.key_column_usage kcu\n ON tc.constraint_name = kcu.constraint_name\n AND tc.table_schema = kcu.table_schema\n WHERE tc.constraint_type = 'PRIMARY KEY'\n AND tc.table_schema IN (${schemaFilter})\n ORDER BY kcu.ordinal_position\n `;\n\n const primaryKeysResult = await pool.query(primaryKeysQuery, schemas);\n\n // Get unique constraints\n const uniqueConstraintsQuery = `\n SELECT \n tc.table_schema,\n tc.table_name,\n tc.constraint_name,\n array_agg(kcu.column_name ORDER BY kcu.ordinal_position) as columns\n FROM information_schema.table_constraints tc\n JOIN information_schema.key_column_usage kcu\n ON tc.constraint_name = kcu.constraint_name\n AND tc.table_schema = kcu.table_schema\n WHERE tc.constraint_type = 'UNIQUE'\n AND tc.table_schema IN (${schemaFilter})\n GROUP BY tc.table_schema, tc.table_name, tc.constraint_name\n `;\n\n const uniqueConstraintsResult = await pool.query(uniqueConstraintsQuery, schemas);\n\n // Group by table\n const tableMap = new Map<string, TableMetadata>();\n\n for (const row of columnsResult.rows) {\n const tableKey = `${row.table_schema}.${row.table_name}`;\n\n if (!tableMap.has(tableKey)) {\n tableMap.set(tableKey, {\n tableName: row.table_name,\n schemaName: row.table_schema,\n columns: [],\n checkConstraints: [],\n primaryKeys: [],\n uniqueConstraints: [],\n });\n }\n\n const table = tableMap.get(tableKey)!;\n const isArray = row.data_type === 'ARRAY';\n\n table.columns.push({\n columnName: row.column_name,\n dataType: row.data_type,\n isNullable: row.is_nullable === 'YES',\n columnDefault: row.column_default,\n characterMaximumLength: row.character_maximum_length,\n numericPrecision: row.numeric_precision,\n numericScale: row.numeric_scale,\n datetimePrecision: row.datetime_precision,\n udtName: row.udt_name,\n domainName: row.domain_name,\n arrayDimensions: row.array_dimensions || 0,\n isArray,\n });\n }\n\n // Add check constraints\n for (const row of constraintsResult.rows) {\n const tableKey = `${row.table_schema}.${row.table_name}`;\n const table = tableMap.get(tableKey);\n if (table) {\n table.checkConstraints.push({\n constraintName: row.constraint_name,\n checkClause: row.check_clause,\n columnName: row.column_name,\n });\n }\n }\n\n // Add primary keys\n for (const row of primaryKeysResult.rows) {\n const tableKey = `${row.table_schema}.${row.table_name}`;\n const table = tableMap.get(tableKey);\n if (table) {\n table.primaryKeys.push(row.column_name);\n }\n }\n\n // Add unique constraints\n for (const row of uniqueConstraintsResult.rows) {\n const tableKey = `${row.table_schema}.${row.table_name}`;\n const table = tableMap.get(tableKey);\n if (table) {\n table.uniqueConstraints.push({\n constraintName: row.constraint_name,\n columns: row.columns,\n });\n }\n }\n\n // Filter tables based on options\n let tables = Array.from(tableMap.values());\n\n if (options.tables) {\n tables = tables.filter((t) => options.tables!.includes(t.tableName));\n }\n\n if (options.excludeTables) {\n tables = tables.filter((t) => !options.excludeTables!.includes(t.tableName));\n }\n\n return tables;\n}\n\n/**\n * Introspect enum types\n */\nasync function introspectEnums(\n pool: pg.Pool,\n schemas: string[]\n): Promise<EnumMetadata[]> {\n const schemaFilter = schemas.map((_, i) => `$${i + 1}`).join(', ');\n\n const query = `\n SELECT \n t.typname as enum_name,\n n.nspname as schema_name,\n array_agg(e.enumlabel ORDER BY e.enumsortorder) as enum_values\n FROM pg_type t\n JOIN pg_enum e ON t.oid = e.enumtypid\n JOIN pg_namespace n ON t.typnamespace = n.oid\n WHERE n.nspname IN (${schemaFilter})\n GROUP BY t.typname, n.nspname\n ORDER BY t.typname\n `;\n\n const result = await pool.query(query, schemas);\n\n return result.rows.map((row) => {\n // Handle PostgreSQL array format: {value1,value2,value3}\n let enumValues: string[];\n \n if (Array.isArray(row.enum_values)) {\n enumValues = row.enum_values;\n } else if (typeof row.enum_values === 'string') {\n // Parse PostgreSQL array format\n if (row.enum_values.startsWith('{') && row.enum_values.endsWith('}')) {\n enumValues = row.enum_values\n .slice(1, -1) // Remove { and }\n .split(',')\n .map((v: string) => v.trim());\n } else {\n enumValues = [row.enum_values];\n }\n } else {\n enumValues = [row.enum_values];\n }\n \n return {\n enumName: row.enum_name,\n enumValues,\n schemaName: row.schema_name,\n };\n });\n}\n\n/**\n * Introspect composite types\n */\nasync function introspectCompositeTypes(\n pool: pg.Pool,\n schemas: string[]\n): Promise<CompositeTypeMetadata[]> {\n const schemaFilter = schemas.map((_, i) => `$${i + 1}`).join(', ');\n\n const query = `\n SELECT \n t.typname as type_name,\n n.nspname as schema_name,\n a.attname as attribute_name,\n a.attnum as attribute_number,\n format_type(a.atttypid, a.atttypmod) as data_type\n FROM pg_type t\n JOIN pg_namespace n ON t.typnamespace = n.oid\n JOIN pg_class c ON t.typrelid = c.oid\n JOIN pg_attribute a ON c.oid = a.attrelid\n WHERE t.typtype = 'c'\n AND n.nspname IN (${schemaFilter})\n AND a.attnum > 0\n AND NOT a.attisdropped\n ORDER BY t.typname, a.attnum\n `;\n\n const result = await pool.query(query, schemas);\n\n const typeMap = new Map<string, CompositeTypeMetadata>();\n\n for (const row of result.rows) {\n const typeKey = `${row.schema_name}.${row.type_name}`;\n\n if (!typeMap.has(typeKey)) {\n typeMap.set(typeKey, {\n typeName: row.type_name,\n schemaName: row.schema_name,\n attributes: [],\n });\n }\n\n const type = typeMap.get(typeKey)!;\n type.attributes.push({\n attributeName: row.attribute_name,\n dataType: row.data_type,\n attributeNumber: row.attribute_number,\n });\n }\n\n return Array.from(typeMap.values());\n}\n\n/**\n * Introspect range types\n */\nasync function introspectRangeTypes(\n pool: pg.Pool,\n schemas: string[]\n): Promise<RangeTypeMetadata[]> {\n const schemaFilter = schemas.map((_, i) => `$${i + 1}`).join(', ');\n\n const query = `\n SELECT \n t.typname as range_name,\n n.nspname as schema_name,\n format_type(r.rngsubtype, NULL) as subtype\n FROM pg_type t\n JOIN pg_namespace n ON t.typnamespace = n.oid\n JOIN pg_range r ON t.oid = r.rngtypid\n WHERE n.nspname IN (${schemaFilter})\n ORDER BY t.typname\n `;\n\n const result = await pool.query(query, schemas);\n\n return result.rows.map((row) => ({\n rangeName: row.range_name,\n subtype: row.subtype,\n schemaName: row.schema_name,\n }));\n}\n\n/**\n * Introspect domain types\n */\nasync function introspectDomains(\n pool: pg.Pool,\n schemas: string[]\n): Promise<DomainMetadata[]> {\n const schemaFilter = schemas.map((_, i) => `$${i + 1}`).join(', ');\n\n // Get domain information\n const domainsQuery = `\n SELECT \n t.typname as domain_name,\n n.nspname as schema_name,\n format_type(t.typbasetype, t.typtypmod) as data_type,\n t.typnotnull as is_not_null,\n t.typdefault as domain_default,\n information_schema._pg_char_max_length(t.typbasetype, t.typtypmod) as character_maximum_length,\n information_schema._pg_numeric_precision(t.typbasetype, t.typtypmod) as numeric_precision,\n information_schema._pg_numeric_scale(t.typbasetype, t.typtypmod) as numeric_scale\n FROM pg_type t\n JOIN pg_namespace n ON t.typnamespace = n.oid\n WHERE t.typtype = 'd'\n AND n.nspname IN (${schemaFilter})\n ORDER BY t.typname\n `;\n\n const domainsResult = await pool.query(domainsQuery, schemas);\n\n // Get domain constraints\n const constraintsQuery = `\n SELECT \n t.typname as domain_name,\n n.nspname as schema_name,\n c.conname as constraint_name,\n pg_get_constraintdef(c.oid) as check_clause\n FROM pg_constraint c\n JOIN pg_type t ON c.contypid = t.oid\n JOIN pg_namespace n ON t.typnamespace = n.oid\n WHERE c.contype = 'c'\n AND n.nspname IN (${schemaFilter})\n `;\n\n const constraintsResult = await pool.query(constraintsQuery, schemas);\n\n const domains: DomainMetadata[] = domainsResult.rows.map((row) => ({\n domainName: row.domain_name,\n dataType: row.data_type,\n schemaName: row.schema_name,\n characterMaximumLength: row.character_maximum_length,\n numericPrecision: row.numeric_precision,\n numericScale: row.numeric_scale,\n isNullable: !row.is_not_null,\n domainDefault: row.domain_default,\n checkConstraints: [],\n }));\n\n // Add check constraints to domains\n for (const row of constraintsResult.rows) {\n const domain = domains.find(\n (d) => d.domainName === row.domain_name && d.schemaName === row.schema_name\n );\n if (domain) {\n domain.checkConstraints.push({\n constraintName: row.constraint_name,\n checkClause: row.check_clause,\n columnName: null,\n });\n }\n }\n\n return domains;\n}\n\n/**\n * Introspect database views\n */\nasync function introspectViews(\n pool: pg.Pool,\n schemas: string[]\n): Promise<ViewMetadata[]> {\n const schemaFilter = schemas.map((_, i) => `$${i + 1}`).join(', ');\n\n // Get view definitions\n const viewsQuery = `\n SELECT \n table_name as view_name,\n table_schema as schema_name,\n view_definition\n FROM information_schema.views\n WHERE table_schema IN (${schemaFilter})\n ORDER BY table_schema, table_name\n `;\n\n const viewsResult = await pool.query(viewsQuery, schemas);\n\n // Get columns for each view\n const columnsQuery = `\n SELECT \n c.table_name as view_name,\n c.table_schema as schema_name,\n c.column_name,\n c.ordinal_position,\n c.data_type,\n c.udt_name,\n c.character_maximum_length,\n c.numeric_precision,\n c.numeric_scale,\n c.datetime_precision,\n c.is_nullable,\n c.column_default,\n COALESCE(\n (\n SELECT array_length(string_to_array(udt_name, '_'), 1) - 1\n FROM information_schema.element_types e\n WHERE e.object_schema = c.table_schema\n AND e.object_name = c.table_name\n AND e.collection_type_identifier = c.dtd_identifier\n ),\n 0\n ) as array_dimensions\n FROM information_schema.columns c\n WHERE c.table_schema IN (${schemaFilter})\n AND c.table_name IN (\n SELECT table_name \n FROM information_schema.views \n WHERE table_schema IN (${schemaFilter})\n )\n ORDER BY c.table_schema, c.table_name, c.ordinal_position\n `;\n\n const columnsResult = await pool.query(columnsQuery, schemas);\n\n const views: ViewMetadata[] = viewsResult.rows.map((row) => ({\n viewName: row.view_name,\n schemaName: row.schema_name,\n viewDefinition: row.view_definition,\n columns: [],\n }));\n\n // Add columns to views\n for (const row of columnsResult.rows) {\n const view = views.find(\n (v) => v.viewName === row.view_name && v.schemaName === row.schema_name\n );\n if (view) {\n view.columns.push({\n columnName: row.column_name,\n dataType: row.data_type,\n udtName: row.udt_name,\n isNullable: row.is_nullable === 'YES',\n columnDefault: row.column_default,\n ordinalPosition: row.ordinal_position,\n characterMaximumLength: row.character_maximum_length,\n numericPrecision: row.numeric_precision,\n numericScale: row.numeric_scale,\n datetimePrecision: row.datetime_precision,\n arrayDimensions: row.array_dimensions,\n isIdentity: false,\n identityGeneration: null,\n isGenerated: false,\n generationExpression: null,\n checkConstraints: [],\n });\n }\n }\n\n return views;\n}\n\n/**\n * Introspect database routines (functions and procedures)\n */\nasync function introspectRoutines(\n pool: pg.Pool,\n schemas: string[]\n): Promise<RoutineMetadata[]> {\n const schemaFilter = schemas.map((_, i) => `$${i + 1}`).join(', ');\n\n // Get routine definitions\n const routinesQuery = `\n SELECT \n r.routine_name,\n r.routine_schema as schema_name,\n r.routine_type,\n r.security_type,\n r.data_type as return_type,\n CASE \n WHEN r.data_type = 'USER-DEFINED' THEN r.type_udt_name\n ELSE r.data_type\n END as return_udt_name,\n CASE\n WHEN r.data_type = 'ARRAY' THEN true\n ELSE false\n END as returns_set\n FROM information_schema.routines r\n WHERE r.routine_schema IN (${schemaFilter})\n ORDER BY r.routine_schema, r.routine_name\n `;\n\n const routinesResult = await pool.query(routinesQuery, schemas);\n\n // Get parameters for each routine\n const parametersQuery = `\n SELECT \n p.specific_name,\n r.routine_name,\n r.routine_schema as schema_name,\n p.parameter_name,\n p.parameter_mode,\n p.ordinal_position,\n p.data_type,\n CASE \n WHEN p.data_type = 'ARRAY' THEN p.udt_name\n WHEN p.data_type = 'USER-DEFINED' THEN p.udt_name\n ELSE p.data_type\n END as udt_name,\n CASE\n WHEN p.parameter_mode = 'OUT' OR p.parameter_mode = 'INOUT' THEN 'YES'\n ELSE 'NO'\n END as is_nullable\n FROM information_schema.parameters p\n JOIN information_schema.routines r ON p.specific_name = r.specific_name\n WHERE r.routine_schema IN (${schemaFilter})\n AND p.parameter_mode IS NOT NULL\n ORDER BY r.routine_schema, r.routine_name, p.ordinal_position\n `;\n\n const parametersResult = await pool.query(parametersQuery, schemas);\n\n const routines: RoutineMetadata[] = routinesResult.rows.map((row) => ({\n routineName: row.routine_name,\n schemaName: row.schema_name,\n routineType: row.routine_type as 'FUNCTION' | 'PROCEDURE',\n securityType: row.security_type as 'DEFINER' | 'INVOKER',\n returnType: row.return_type,\n returnUdtName: row.return_udt_name,\n returnsSet: row.returns_set,\n parameters: [],\n }));\n\n // Add parameters to routines\n for (const row of parametersResult.rows) {\n const routine = routines.find(\n (r) => r.routineName === row.routine_name && r.schemaName === row.schema_name\n );\n if (routine) {\n routine.parameters.push({\n parameterName: row.parameter_name || `param${row.ordinal_position}`,\n dataType: row.data_type,\n udtName: row.udt_name,\n parameterMode: row.parameter_mode,\n ordinalPosition: row.ordinal_position,\n isNullable: row.is_nullable === 'YES',\n });\n }\n }\n\n return routines;\n}\n","import type {\n ColumnMetadata,\n DatabaseMetadata,\n SchemaGenerationOptions,\n CheckConstraintMetadata,\n} from './types.js';\n\n/**\n * Map PostgreSQL column to Zod schema string with strict validation\n */\nexport function mapColumnToZod(\n column: ColumnMetadata,\n metadata: DatabaseMetadata,\n options: SchemaGenerationOptions,\n warnings: string[]\n): string {\n // Handle domains first\n if (column.domainName) {\n const domain = metadata.domains.find((d) => d.domainName === column.domainName);\n if (domain) {\n const schemaPrefix = toPascalCase(domain.schemaName);\n const domainName = toPascalCase(domain.domainName);\n let schema = `${schemaPrefix}${domainName}Schema`;\n return column.isNullable ? `${schema}.nullable()` : schema;\n }\n }\n\n // Handle arrays\n if (column.isArray) {\n const baseType = mapBaseTypeToZod(column, metadata, options, warnings);\n let arraySchema = `z.array(${baseType})`;\n \n // Multi-dimensional arrays\n if (column.arrayDimensions > 1) {\n for (let i = 1; i < column.arrayDimensions; i++) {\n arraySchema = `z.array(${arraySchema})`;\n }\n }\n \n return column.isNullable ? `${arraySchema}.nullable()` : arraySchema;\n }\n\n // Handle base types\n const baseSchema = mapBaseTypeToZod(column, metadata, options, warnings);\n return column.isNullable ? `${baseSchema}.nullable()` : baseSchema;\n}\n\n/**\n * Map base PostgreSQL type to Zod\n */\nfunction mapBaseTypeToZod(\n column: ColumnMetadata,\n metadata: DatabaseMetadata,\n options: SchemaGenerationOptions,\n warnings: string[]\n): string {\n let udtName = column.udtName;\n const dataType = column.dataType.toLowerCase();\n\n // PostgreSQL array types have underscore prefix (e.g., _text for text[], _int4 for integer[])\n // Strip the underscore to get the actual base type name\n if (column.isArray && udtName.startsWith('_')) {\n udtName = udtName.substring(1);\n }\n\n // Custom type mappings\n if (options.customTypeMappings?.[udtName]) {\n return options.customTypeMappings[udtName];\n }\n\n // Check if it's an enum\n const enumType = metadata.enums.find((e) => e.enumName === udtName);\n if (enumType) {\n const schemaPrefix = toPascalCase(enumType.schemaName);\n const enumName = toPascalCase(enumType.enumName);\n return `${schemaPrefix}${enumName}Schema`;\n }\n\n // Check if it's a composite type\n const compositeType = metadata.compositeTypes.find((t) => t.typeName === udtName);\n if (compositeType) {\n const schemaPrefix = toPascalCase(compositeType.schemaName);\n const typeName = toPascalCase(compositeType.typeName);\n // Add 'Composite' suffix to match generator\n return `${schemaPrefix}${typeName}CompositeSchema`;\n }\n\n // Check if it's a range type\n const rangeType = metadata.rangeTypes.find((r) => r.rangeName === udtName);\n if (rangeType) {\n const schemaPrefix = toPascalCase(rangeType.schemaName);\n const rangeName = toPascalCase(rangeType.rangeName);\n return `${schemaPrefix}${rangeName}Schema`;\n }\n\n // Map by data type or by udtName for arrays\n // For arrays, dataType will be 'ARRAY' so we need to check the udtName\n const typeToCheck = dataType === 'array' ? udtName : dataType;\n \n switch (typeToCheck) {\n // Numeric types\n case 'smallint':\n case 'integer':\n case 'int':\n case 'int2':\n case 'int4':\n return 'z.number().int()';\n \n case 'bigint':\n case 'int8':\n return 'z.bigint()';\n \n case 'decimal':\n case 'numeric':\n if (column.numericPrecision !== null && column.numericScale !== null) {\n return `z.number() /* precision: ${column.numericPrecision}, scale: ${column.numericScale} */`;\n }\n return 'z.number()';\n \n case 'real':\n case 'float4':\n return 'z.number()';\n \n case 'double precision':\n case 'float8':\n return 'z.number()';\n \n case 'money':\n return 'z.string().regex(/^\\\\$?[0-9,]+(\\\\.\\\\d{2})?$/)';\n\n // Text types\n case 'character varying':\n case 'varchar':\n if (column.characterMaximumLength) {\n return `z.string().max(${column.characterMaximumLength})`;\n }\n return 'z.string()';\n \n case 'character':\n case 'char':\n if (column.characterMaximumLength) {\n return `z.string().length(${column.characterMaximumLength})`;\n }\n return 'z.string()';\n \n case 'text':\n return 'z.string()';\n \n case 'citext':\n return 'z.string()';\n\n // Boolean\n case 'boolean':\n case 'bool':\n return 'z.boolean()';\n\n // Date/Time types\n case 'timestamp':\n case 'timestamp without time zone':\n return 'z.date()';\n \n case 'timestamp with time zone':\n case 'timestamptz':\n return 'z.date()';\n \n case 'date':\n return 'z.date()';\n \n case 'time':\n case 'time without time zone':\n return 'z.iso.time()';\n \n case 'time with time zone':\n case 'timetz':\n // PostgreSQL time with timezone, no direct Zod v4 equivalent\n return 'z.string().regex(/^\\\\d{2}:\\\\d{2}:\\\\d{2}(\\\\.\\\\d+)?[+-]\\\\d{2}:\\\\d{2}$/)';\n \n case 'interval':\n return 'z.iso.duration()';\n\n // UUID\n case 'uuid':\n return 'z.uuid()';\n\n // JSON types\n case 'json':\n return 'z.record(z.string(), z.unknown())';\n \n case 'jsonb':\n return 'z.record(z.string(), z.unknown())';\n\n // Network types\n case 'inet':\n // In Zod v4, use z.ipv4() or z.ipv6() but inet accepts both, so we use a union\n return 'z.union([z.ipv4(), z.ipv6()])';\n \n case 'cidr':\n // PostgreSQL cidr accepts both IPv4 and IPv6 CIDR notation\n return 'z.union([z.cidrv4(), z.cidrv6()])';\n \n case 'macaddr':\n return 'z.mac()';\n \n case 'macaddr8':\n // macaddr8 is 64-bit (8 bytes), standard z.mac() is 48-bit, use regex\n return 'z.string().regex(/^([0-9A-Fa-f]{2}[:-]){7}([0-9A-Fa-f]{2})$/)';\n\n // Bit string types\n case 'bit':\n if (column.characterMaximumLength) {\n return `z.string().regex(/^[01]{${column.characterMaximumLength}}$/)`;\n }\n return 'z.string().regex(/^[01]+$/)';\n \n case 'bit varying':\n case 'varbit':\n if (column.characterMaximumLength) {\n return `z.string().regex(/^[01]{0,${column.characterMaximumLength}}$/)`;\n }\n return 'z.string().regex(/^[01]*$/)';\n\n // Geometric types\n case 'point':\n return 'z.tuple([z.number(), z.number()])';\n \n case 'line':\n return 'z.object({ a: z.number(), b: z.number(), c: z.number() })';\n \n case 'lseg':\n return 'z.tuple([z.tuple([z.number(), z.number()]), z.tuple([z.number(), z.number()])])';\n \n case 'box':\n return 'z.tuple([z.tuple([z.number(), z.number()]), z.tuple([z.number(), z.number()])])';\n \n case 'path':\n return 'z.array(z.tuple([z.number(), z.number()]))';\n \n case 'polygon':\n return 'z.array(z.tuple([z.number(), z.number()]))';\n \n case 'circle':\n return 'z.object({ center: z.tuple([z.number(), z.number()]), radius: z.number() })';\n\n // Text search types\n case 'tsvector':\n return 'z.string() /* tsvector */';\n \n case 'tsquery':\n return 'z.string() /* tsquery */';\n\n // XML\n case 'xml':\n return 'z.string() /* XML */';\n\n // Binary data\n case 'bytea':\n return 'z.instanceof(Buffer)';\n\n // Other types\n case 'oid':\n return 'z.number().int().positive()';\n \n case 'regproc':\n case 'regprocedure':\n case 'regoper':\n case 'regoperator':\n case 'regclass':\n case 'regtype':\n case 'regrole':\n case 'regnamespace':\n case 'regconfig':\n case 'regdictionary':\n return 'z.string() /* PostgreSQL OID reference */';\n\n // pg_lsn\n case 'pg_lsn':\n return 'z.string().regex(/^[0-9A-F]+\\\\/[0-9A-F]+$/)';\n\n // User-defined base types or unknown\n default:\n const warning = `Unknown type: ${dataType} (udt: ${udtName}) in column ${column.columnName}`;\n warnings.push(warning);\n \n if (options.strictMode) {\n throw new Error(warning);\n }\n \n return 'z.unknown() /* unmapped type */';\n }\n}\n\n/**\n * Apply check constraints as Zod refinements\n */\nexport function applyCheckConstraints(\n columnName: string,\n baseSchema: string,\n constraints: CheckConstraintMetadata[]\n): string {\n let schema = baseSchema;\n\n for (const constraint of constraints) {\n // Try to parse simple check constraints\n const checkClause = constraint.checkClause.toLowerCase();\n\n // >= pattern\n const geMatch = checkClause.match(new RegExp(`${columnName}\\\\s*>=\\\\s*([\\\\d.]+)`));\n if (geMatch) {\n const value = geMatch[1];\n if (schema.includes('z.number()')) {\n schema = schema.replace('z.number()', `z.number().min(${value})`);\n } else if (schema.includes('z.bigint()')) {\n schema = schema.replace('z.bigint()', `z.bigint().min(${value}n)`);\n }\n continue;\n }\n\n // > pattern\n const gtMatch = checkClause.match(new RegExp(`${columnName}\\\\s*>\\\\s*([\\\\d.]+)`));\n if (gtMatch) {\n const value = parseFloat(gtMatch[1]);\n if (schema.includes('z.number()')) {\n schema = schema.replace('z.number()', `z.number().min(${value + Number.EPSILON})`);\n }\n continue;\n }\n\n // <= pattern\n const leMatch = checkClause.match(new RegExp(`${columnName}\\\\s*<=\\\\s*([\\\\d.]+)`));\n if (leMatch) {\n const value = leMatch[1];\n if (schema.includes('z.number()')) {\n schema = schema.replace('z.number()', `z.number().max(${value})`);\n } else if (schema.includes('z.bigint()')) {\n schema = schema.replace('z.bigint()', `z.bigint().max(${value}n)`);\n }\n continue;\n }\n\n // < pattern\n const ltMatch = checkClause.match(new RegExp(`${columnName}\\\\s*<\\\\s*([\\\\d.]+)`));\n if (ltMatch) {\n const value = parseFloat(ltMatch[1]);\n if (schema.includes('z.number()')) {\n schema = schema.replace('z.number()', `z.number().max(${value - Number.EPSILON})`);\n }\n continue;\n }\n\n // BETWEEN pattern\n const betweenMatch = checkClause.match(\n new RegExp(`${columnName}\\\\s*between\\\\s*([\\\\d.]+)\\\\s*and\\\\s*([\\\\d.]+)`)\n );\n if (betweenMatch) {\n const [, min, max] = betweenMatch;\n if (schema.includes('z.number()')) {\n schema = schema.replace('z.number()', `z.number().min(${min}).max(${max})`);\n }\n continue;\n }\n\n // IN pattern (standard SQL)\n const inMatch = checkClause.match(\n new RegExp(`${columnName}\\\\s*in\\\\s*\\\\(([^)]+)\\\\)`)\n );\n if (inMatch) {\n const values = inMatch[1].split(',').map((v: string) => v.trim().replace(/'/g, ''));\n if (schema.includes('z.string()')) {\n const enumValues = values.map((v: string) => `'${v}'`).join(', ');\n schema = `z.enum([${enumValues}])`;\n }\n continue;\n }\n\n // PostgreSQL ANY (ARRAY[...]) pattern\n const anyArrayMatch = checkClause.match(\n new RegExp(`\\\\(?${columnName}\\\\s*=\\\\s*any\\\\s*\\\\(array\\\\[([^\\\\]]+)\\\\]`)\n );\n if (anyArrayMatch) {\n // Extract values from ARRAY['val1'::text, 'val2'::text]\n const valuesStr = anyArrayMatch[1];\n const values = valuesStr\n .split(',')\n .map((v: string) => {\n const match = v.trim().match(/'([^']+)'/);\n return match ? match[1] : null;\n })\n .filter((v: string | null): v is string => v !== null);\n \n if (values.length > 0 && schema.includes('z.string()')) {\n const enumValues = values.map((v: string) => `'${v}'`).join(', ');\n schema = `z.enum([${enumValues}])`;\n continue;\n }\n }\n\n // REGEX/~ pattern\n const regexMatch = checkClause.match(\n new RegExp(`${columnName}\\\\s*~\\\\s*'([^']+)'`)\n );\n if (regexMatch) {\n const pattern = regexMatch[1];\n if (schema.includes('z.string()')) {\n schema = schema.replace('z.string()', `z.string().regex(/${pattern}/)`);\n }\n continue;\n }\n\n // LENGTH pattern\n const lengthMatch = checkClause.match(\n new RegExp(`length\\\\(${columnName}\\\\)\\\\s*([><=]+)\\\\s*([\\\\d]+)`)\n );\n if (lengthMatch) {\n const [, operator, value] = lengthMatch;\n if (schema.includes('z.string()')) {\n if (operator === '>=' || operator === '>') {\n schema = schema.replace('z.string()', `z.string().min(${value})`);\n } else if (operator === '<=' || operator === '<') {\n schema = schema.replace('z.string()', `z.string().max(${value})`);\n }\n }\n continue;\n }\n\n // If we can't parse it, add as a comment\n schema += ` /* CHECK: ${constraint.checkClause} */`;\n }\n\n return schema;\n}\n\n/**\n * Convert snake_case to PascalCase\n */\nexport function toPascalCase(str: string): string {\n return str\n .split('_')\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join('');\n}\n\n/**\n * Convert snake_case to camelCase\n */\nexport function toCamelCase(str: string): string {\n const pascal = toPascalCase(str);\n return pascal.charAt(0).toLowerCase() + pascal.slice(1);\n}\n","import type {\n ColumnMetadata,\n DatabaseMetadata,\n GeneratedSchema,\n GenerationResult,\n SchemaGenerationOptions,\n TableMetadata,\n ViewMetadata,\n RoutineMetadata,\n} from './types.js';\nimport {applyCheckConstraints, mapColumnToZod, toCamelCase, toPascalCase,} from './type-mapper.js';\n\n/**\n * Generate Zod schemas from database metadata\n */\nexport function generateSchemas(\n metadata: DatabaseMetadata,\n options: SchemaGenerationOptions = {}\n): GenerationResult {\n const warnings: string[] = [];\n const schemas: GeneratedSchema[] = [];\n\n // Generate enum schemas\n const enums = metadata.enums.map((enumType) => ({\n name: toPascalCase(enumType.schemaName) + toPascalCase(enumType.enumName),\n code: generateEnumSchema(enumType.enumName, enumType.enumValues, options, enumType.schemaName),\n }));\n\n // Generate range type schemas\n const ranges = metadata.rangeTypes.map((rangeType) => ({\n name: toPascalCase(rangeType.schemaName) + toPascalCase(rangeType.rangeName),\n code: generateRangeSchema(rangeType.rangeName, rangeType.subtype, metadata, options, warnings, rangeType.schemaName),\n }));\n\n // Generate composite type schemas (only if flag is set)\n const compositeTypes = options.includeCompositeTypes\n ? metadata.compositeTypes.map((compositeType) => ({\n name: toPascalCase(compositeType.schemaName) + toPascalCase(compositeType.typeName) + 'Composite',\n code: generateCompositeTypeSchema(compositeType, metadata, options, warnings),\n }))\n : [];\n\n // Generate domain schemas\n const domains = metadata.domains.map((domain) => ({\n name: toPascalCase(domain.schemaName) + toPascalCase(domain.domainName),\n code: generateDomainSchema(domain, metadata, options, warnings),\n }));\n\n // Generate table schemas\n for (const table of metadata.tables) {\n const schema = generateTableSchema(table, metadata, options, warnings);\n schemas.push(schema);\n }\n\n // Generate view schemas\n const views = metadata.views?.map((view) => ({\n name: toPascalCase(view.schemaName) + toPascalCase(view.viewName),\n code: generateViewSchema(view, metadata, options, warnings),\n })) || [];\n\n // Generate routine schemas (filter by security type)\n const filteredRoutines = metadata.routines?.filter((routine) => {\n // By default, only include SECURITY DEFINER functions\n // Include SECURITY INVOKER only if explicitly requested\n if (routine.securityType === 'INVOKER' && !options.includeSecurityInvoker) {\n return false;\n }\n return true;\n }) || [];\n\n const routines = filteredRoutines.map((routine) => ({\n name: toPascalCase(routine.schemaName) + toPascalCase(routine.routineName),\n code: generateRoutineSchema(routine, metadata, options, warnings),\n }));\n\n return {\n schemas,\n enums,\n compositeTypes,\n domains,\n ranges,\n views,\n routines,\n warnings,\n };\n}\n\n/**\n * Generate enum schema\n */\nfunction generateEnumSchema(\n enumName: string,\n values: string[],\n options: SchemaGenerationOptions,\n schemaPrefix?: string\n): string {\n const baseName = toPascalCase(enumName);\n const fullName = schemaPrefix ? `${toPascalCase(schemaPrefix)}${baseName}` : baseName;\n const schemaName = `${fullName}Schema`;\n const typeName = fullName;\n\n const valuesStr = values.map((v) => `'${v}'`).join(', ');\n\n let code = '';\n\n if (options.includeComments) {\n code += `/** PostgreSQL enum: ${enumName} */\\n`;\n }\n\n code += `export const ${schemaName} = z.enum([${valuesStr}]);\\n`;\n code += `export type ${typeName} = z.infer<typeof ${schemaName}>;\\n`;\n\n return code;\n}\n\n/**\n * Generate range type schema\n */\nfunction generateRangeSchema(\n rangeName: string,\n subtype: string,\n _metadata: DatabaseMetadata,\n options: SchemaGenerationOptions,\n _warnings: string[],\n schemaPrefix?: string\n): string {\n const baseName = toPascalCase(rangeName);\n const fullName = schemaPrefix ? `${toPascalCase(schemaPrefix)}${baseName}` : baseName;\n const schemaName = `${fullName}Schema`;\n const typeName = fullName;\n\n // Map subtype to Zod schema\n const subtypeSchema = mapSubtypeToZod(subtype, _metadata);\n\n let code = '';\n\n if (options.includeComments) {\n code += `/** PostgreSQL range type: ${rangeName}<${subtype}> */\\n`;\n }\n\n // Ranges represented as [lower, upper] tuple with nullable bounds\n code += `export const ${schemaName} = z.tuple([${subtypeSchema}.nullable(), ${subtypeSchema}.nullable()]);\\n`;\n code += `export type ${typeName} = z.infer<typeof ${schemaName}>;\\n`;\n\n return code;\n}\n\n/**\n * Map PostgreSQL subtype to Zod for range types\n */\nfunction mapSubtypeToZod(subtype: string, _metadata: DatabaseMetadata): string {\n const normalized = subtype.toLowerCase();\n\n switch (normalized) {\n case 'integer':\n case 'int':\n case 'int4':\n return 'z.number().int()';\n case 'bigint':\n case 'int8':\n return 'z.bigint()';\n case 'numeric':\n case 'decimal':\n return 'z.number()';\n case 'date':\n return 'z.date()';\n case 'timestamp':\n case 'timestamp without time zone':\n case 'timestamp with time zone':\n case 'timestamptz':\n return 'z.date()';\n default:\n return 'z.unknown()';\n }\n}\n\n/**\n * Generate composite type schema\n */\nfunction generateCompositeTypeSchema(\n compositeType: any,\n metadata: DatabaseMetadata,\n options: SchemaGenerationOptions,\n warnings: string[]\n): string {\n const baseName = toPascalCase(compositeType.typeName);\n const schemaPrefix = toPascalCase(compositeType.schemaName);\n // Add 'Composite' suffix to distinguish from tables with same name\n const fullName = `${schemaPrefix}${baseName}Composite`;\n const schemaName = `${fullName}Schema`;\n const typeName = fullName;\n\n let code = '';\n\n if (options.includeComments) {\n code += `/** PostgreSQL composite type: ${compositeType.typeName} */\\n`;\n }\n\n code += `export const ${schemaName} = z.object({\\n`;\n\n for (const attr of compositeType.attributes) {\n const fieldName = options.useCamelCase ? toCamelCase(attr.attributeName) : attr.attributeName;\n\n // Create a mock column for type mapping\n const mockColumn: ColumnMetadata = {\n columnName: attr.attributeName,\n dataType: attr.dataType,\n isNullable: true, // Composite type attributes can be null\n columnDefault: null,\n characterMaximumLength: null,\n numericPrecision: null,\n numericScale: null,\n datetimePrecision: null,\n udtName: attr.dataType,\n domainName: null,\n arrayDimensions: 0,\n isArray: false,\n };\n\n const zodType = mapColumnToZod(mockColumn, metadata, options, warnings);\n\n if (options.includeComments) {\n code += ` /** ${attr.dataType} */\\n`;\n }\n code += ` ${fieldName}: ${zodType},\\n`;\n }\n\n code += `});\\n`;\n code += `export type ${typeName} = z.infer<typeof ${schemaName}>;\\n`;\n\n return code;\n}\n\n/**\n * Generate domain schema\n */\nfunction generateDomainSchema(\n domain: any,\n metadata: DatabaseMetadata,\n options: SchemaGenerationOptions,\n warnings: string[]\n): string {\n const baseName = toPascalCase(domain.domainName);\n const schemaPrefix = toPascalCase(domain.schemaName);\n const fullName = `${schemaPrefix}${baseName}`;\n const schemaName = `${fullName}Schema`;\n const typeName = fullName;\n\n // Create a mock column for type mapping\n const mockColumn: ColumnMetadata = {\n columnName: domain.domainName,\n dataType: domain.dataType,\n isNullable: domain.isNullable,\n columnDefault: domain.domainDefault,\n characterMaximumLength: domain.characterMaximumLength,\n numericPrecision: domain.numericPrecision,\n numericScale: domain.numericScale,\n datetimePrecision: null,\n udtName: domain.dataType,\n domainName: null,\n arrayDimensions: 0,\n isArray: false,\n };\n\n let zodType = mapColumnToZod(mockColumn, metadata, options, warnings);\n\n // Apply domain check constraints\n if (domain.checkConstraints.length > 0) {\n zodType = applyCheckConstraints(domain.domainName, zodType, domain.checkConstraints);\n }\n\n let code = '';\n\n if (options.includeComments) {\n code += `/** PostgreSQL domain: ${domain.domainName} (base: ${domain.dataType}) */\\n`;\n }\n\n code += `export const ${schemaName} = ${zodType};\\n`;\n code += `export type ${typeName} = z.infer<typeof ${schemaName}>;\\n`;\n\n return code;\n}\n\n/**\n * Generate view schema (read-only)\n */\nfunction generateViewSchema(\n view: ViewMetadata,\n metadata: DatabaseMetadata,\n options: SchemaGenerationOptions,\n warnings: string[]\n): string {\n const schemaPrefix = toPascalCase(view.schemaName);\n const viewName = toPascalCase(view.viewName);\n const schemaName = `${schemaPrefix}${viewName}Schema`;\n const typeName = `${schemaPrefix}${viewName}`;\n\n let code = '';\n\n if (options.includeComments) {\n code += `/** View: ${view.schemaName}.${view.viewName} (read-only) */\\n`;\n }\n\n code += `export const ${schemaName} = z.object({\\n`;\n\n for (const column of view.columns) {\n const fieldName = options.useCamelCase ? toCamelCase(column.columnName) : column.columnName;\n const zodType = mapColumnToZod(column, metadata, options, warnings);\n\n if (options.includeComments) {\n code += ` /** ${column.dataType} */\\n`;\n }\n code += ` ${fieldName}: ${zodType},\\n`;\n }\n\n code += `});\\n`;\n code += `export type ${typeName} = z.infer<typeof ${schemaName}>;\\n`;\n\n return code;\n}\n\n/**\n * Generate routine schema (function/procedure)\n */\nfunction generateRoutineSchema(\n routine: RoutineMetadata,\n metadata: DatabaseMetadata,\n options: SchemaGenerationOptions,\n warnings: string[]\n): string {\n const schemaPrefix = toPascalCase(routine.schemaName);\n const routineName = toPascalCase(routine.routineName);\n const paramsSchemaName = `${schemaPrefix}${routineName}ParamsSchema`;\n const returnSchemaName = `${schemaPrefix}${routineName}ReturnSchema`;\n const paramsTypeName = `${schemaPrefix}${routineName}Params`;\n const returnTypeName = `${schemaPrefix}${routineName}Return`;\n\n let code = '';\n\n if (options.includeComments) {\n code += `/** ${routine.routineType}: ${routine.schemaName}.${routine.routineName} */\\n`;\n }\n\n // Generate parameters schema (input)\n const inParams = routine.parameters.filter(\n (p) => p.parameterMode === 'IN' || p.parameterMode === 'INOUT'\n );\n\n if (inParams.length > 0) {\n code += `export const ${paramsSchemaName} = z.object({\\n`;\n\n for (const param of inParams) {\n const fieldName = options.useCamelCase ? toCamelCase(param.parameterName) : param.parameterName;\n\n // Create a mock column for type mapping\n const mockColumn: ColumnMetadata = {\n columnName: param.parameterName,\n dataType: param.dataType,\n isNullable: param.isNullable,\n columnDefault: null,\n characterMaximumLength: null,\n numericPrecision: null,\n numericScale: null,\n datetimePrecision: null,\n udtName: param.udtName,\n domainName: null,\n arrayDimensions: 0,\n isArray: param.dataType === 'ARRAY',\n };\n\n const zodType = mapColumnToZod(mockColumn, metadata, options, warnings);\n\n if (options.includeComments) {\n code += ` /** ${param.dataType} (${param.parameterMode}) */\\n`;\n }\n code += ` ${fieldName}: ${zodType},\\n`;\n }\n\n code += `});\\n`;\n code += `export type ${paramsTypeName} = z.infer<typeof ${paramsSchemaName}>;\\n\\n`;\n }\n\n // Generate return type schema (output)\n const outParams = routine.parameters.filter(\n (p) => p.parameterMode === 'OUT' || p.parameterMode === 'INOUT'\n );\n\n if (routine.routineType === 'FUNCTION' && routine.returnType && routine.returnType !== 'void') {\n // For functions with return values\n if (outParams.length > 0) {\n // Multiple output parameters - return object\n code += `export const ${returnSchemaName} = z.object({\\n`;\n\n for (const param of outParams) {\n const fieldName = options.useCamelCase ? toCamelCase(param.parameterName) : param.parameterName;\n\n const mockColumn: ColumnMetadata = {\n columnName: param.parameterName,\n dataType: param.dataType,\n isNullable: param.isNullable,\n columnDefault: null,\n characterMaximumLength: null,\n numericPrecision: null,\n numericScale: null,\n datetimePrecision: null,\n udtName: param.udtName,\n domainName: null,\n arrayDimensions: 0,\n isArray: param.dataType === 'ARRAY',\n };\n\n const zodType = mapColumnToZod(mockColumn, metadata, options, warnings);\n\n if (options.includeComments) {\n code += ` /** ${param.dataType} (${param.parameterMode}) */\\n`;\n }\n code += ` ${fieldName}: ${zodType},\\n`;\n }\n\n code += `});\\n`;\n } else {\n // Single return value\n const mockColumn: ColumnMetadata = {\n columnName: 'return_value',\n dataType: routine.returnType,\n isNullable: false,\n columnDefault: null,\n characterMaximumLength: null,\n numericPrecision: null,\n numericScale: null,\n datetimePrecision: null,\n udtName: routine.returnUdtName || routine.returnType,\n domainName: null,\n arrayDimensions: 0,\n isArray: routine.returnType === 'ARRAY' || routine.returnsSet,\n };\n\n const zodType = mapColumnToZod(mockColumn, metadata, options, warnings);\n \n if (options.includeComments) {\n code += `/** Returns: ${routine.returnType} */\\n`;\n }\n \n if (routine.returnsSet) {\n code += `export const ${returnSchemaName} = z.array(${zodType});\\n`;\n } else {\n code += `export const ${returnSchemaName} = ${zodType};\\n`;\n }\n }\n\n code += `export type ${returnTypeName} = z.infer<typeof ${returnSchemaName}>;\\n`;\n } else if (outParams.length > 0) {\n // Procedures with OUT parameters\n code += `export const ${returnSchemaName} = z.object({\\n`;\n\n for (const param of outParams) {\n const fieldName = options.useCamelCase ? toCamelCase(param.parameterName) : param.parameterName;\n\n const mockColumn: ColumnMetadata = {\n columnName: param.parameterName,\n dataType: param.dataType,\n isNullable: param.isNullable,\n columnDefault: null,\n characterMaximumLength: null,\n numericPrecision: null,\n numericScale: null,\n datetimePrecision: null,\n udtName: param.udtName,\n domainName: null,\n arrayDimensions: 0,\n isArray: param.dataType === 'ARRAY',\n };\n\n const zodType = mapColumnToZod(mockColumn, metadata, options, warnings);\n\n if (options.includeComments) {\n code += ` /** ${param.dataType} (${param.parameterMode}) */\\n`;\n }\n code += ` ${fieldName}: ${zodType},\\n`;\n }\n\n code += `});\\n`;\n code += `export type ${returnTypeName} = z.infer<typeof ${returnSchemaName}>;\\n`;\n }\n\n return code;\n}\n\n/**\n * Generate table schema\n */\nfunction generateTableSchema(\n table: TableMetadata,\n metadata: DatabaseMetadata,\n options: SchemaGenerationOptions,\n warnings: string[]\n): GeneratedSchema {\n // Include schema name to avoid collisions (e.g., PublicCommentThreadsSchema)\n const schemaPrefix = toPascalCase(table.schemaName);\n const tableName = toPascalCase(table.tableName);\n const schemaName = `${schemaPrefix}${tableName}`;\n const readSchemaName = `${schemaName}Schema`;\n const insertSchemaName = `${schemaName}InsertSchema`;\n const updateSchemaName = `${schemaName}UpdateSchema`;\n const typeName = schemaName;\n const insertTypeName = `${schemaName}Insert`;\n const updateTypeName = `${schemaName}Update`;\n\n // Generate read schema (complete)\n let readCode = '';\n\n if (options.includeComments) {\n readCode += `/** Table: ${table.schemaName}.${table.tableName} */\\n`;\n }\n\n readCode += `export const ${readSchemaName} = z.object({\\n`;\n\n for (const column of table.columns) {\n const fieldName = options.useCamelCase ? toCamelCase(column.columnName) : column.columnName;\n\n let zodType = mapColumnToZod(column, metadata, options, warnings);\n\n // Apply column-specific check constraints\n const columnConstraints = table.checkConstraints.filter(\n (c) => c.columnName === column.columnName\n );\n if (columnConstraints.length > 0) {\n zodType = applyCheckConstraints(column.columnName, zodType, columnConstraints);\n }\n\n if (options.includeComments) {\n const commentParts = [column.dataType];\n if (column.columnDefault) {\n commentParts.push(`default: ${column.columnDefault}`);\n }\n readCode += ` /** ${commentParts.join(', ')} */\\n`;\n }\n\n readCode += ` ${fieldName}: ${zodType},\\n`;\n }\n\n readCode += `});\\n`;\n readCode += `export type ${typeName} = z.infer<typeof ${readSchemaName}>;\\n`;\n\n // Generate insert and update schemas\n // Default to true if not specified\n let insertCode: string | undefined;\n let updateCode: string | undefined;\n\n if (options.generateInputSchemas !== false) {\n // Collect fields that should be optional for insert\n const optionalFields: Array<{ fieldName: string; zodType: string; comment?: string }> = [];\n\n for (const column of table.columns) {\n const fieldName = options.useCamelCase ? toCamelCase(column.columnName) : column.columnName;\n\n // Determine if field should be optional in insert\n const hasDefault = column.columnDefault !== null;\n const isSerial = column.columnDefault?.includes('nextval') ?? false;\n const isAutoGenerated = isSerial || column.columnDefault?.includes('gen_random_uuid()') || false;\n\n if (isAutoGenerated || hasDefault) {\n // Get the base type\n let zodType = mapColumnToZod(column, metadata, options, warnings);\n\n // Apply column-specific check constraints\n const columnConstraints = table.checkConstraints.filter(\n (c) => c.columnName === column.columnName\n );\n if (columnConstraints.length > 0) {\n zodType = applyCheckConstraints(column.columnName, zodType, columnConstraints);\n }\n\n // Make it optional\n zodType = `${zodType}.optional()`;\n\n let comment: string | undefined;\n if (options.includeComments) {\n const commentParts = [column.dataType];\n if (hasDefault) {\n commentParts.push(`default: ${column.columnDefault}`);\n }\n if (isSerial) {\n commentParts.push('auto-generated');\n }\n comment = commentParts.join(', ');\n }\n\n optionalFields.push({fieldName, zodType, comment});\n }\n }\n\n // Generate INSERT schema using .extend() if there are optional fields\n insertCode = '';\n\n if (options.includeComments) {\n insertCode += `/** Insert schema for ${table.tableName} */\\n`;\n }\n\n if (optionalFields.length === 0) {\n // No optional fields - just use the read schema directly\n insertCode += `export const ${insertSchemaName} = ${readSchemaName};\\n`;\n } else {\n // Use .extend() to override optional fields\n insertCode += `export const ${insertSchemaName} = ${readSchemaName}.extend({\\n`;\n\n for (const field of optionalFields) {\n if (field.comment) {\n insertCode += ` /** ${field.comment} */\\n`;\n }\n insertCode += ` ${field.fieldName}: ${field.zodType},\\n`;\n }\n\n insertCode += `});\\n`;\n }\n\n insertCode += `export type ${insertTypeName} = z.infer<typeof ${insertSchemaName}>;\\n`;\n\n // Generate UPDATE schema using .partial() - all fields optional\n updateCode = '';\n\n if (options.includeComments) {\n updateCode += `/** Update schema for ${table.tableName} (all fields optional) */\\n`;\n }\n\n updateCode += `export const ${updateSchemaName} = ${readSchemaName}.partial();\\n`;\n updateCode += `export type ${updateTypeName} = z.infer<typeof ${updateSchemaName}>;\\n`;\n }\n\n return {\n tableName: table.tableName,\n schemaName: table.schemaName,\n readSchema: readCode,\n inputSchema: insertCode,\n typeDefinitions: `${readCode}${insertCode ? '\\n' + insertCode : ''}${updateCode ? '\\n' + updateCode : ''}`,\n };\n}\n\n/**\n * Format the complete output file\n */\nexport function formatOutput(result: GenerationResult): string {\n let output = `/**\\n`;\n output += ` * ==========================================\\n`;\n output += ` * | GENERATED BY PG-TO-ZOD (TBP) |\\n`;\n output += ` * ==========================================\\n`;\n output += ` *\\n`;\n output += ` * ⚠️ DO NOT EDIT THIS FILE MANUALLY!\\n`;\n output += ` *\\n`;\n output += ` * This file was automatically generated from\\n`;\n output += ` * your PostgreSQL database schema.\\n`;\n output += ` *\\n`;\n output += ` * To regenerate, run:\\n`;\n output += ` * pg-to-zod --url <connection-url> -o <file>\\n`;\n output += ` *\\n`;\n output += ` * Any manual changes will be overwritten when\\n`;\n output += ` * the code is regenerated.\\n`;\n output += ` * ==========================================\\n`;\n output += ` */\\n\\n`;\n output += `import { z } from 'zod';\\n\\n`;\n\n // Enums\n if (result.enums.length > 0) {\n output += `// ============================================\\n`;\n output += `// Enums\\n`;\n output += `// ============================================\\n\\n`;\n\n for (const enumSchema of result.enums) {\n output += enumSchema.code + '\\n';\n }\n }\n\n // Domains\n if (result.domains.length > 0) {\n output += `// ============================================\\n`;\n output += `// Domains\\n`;\n output += `// ============================================\\n\\n`;\n\n for (const domain of result.domains) {\n output += domain.code + '\\n';\n }\n }\n\n // Ranges\n if (result.ranges.length > 0) {\n output += `// ============================================\\n`;\n output += `// Range Types\\n`;\n output += `// ============================================\\n\\n`;\n\n for (const range of result.ranges) {\n output += range.code + '\\n';\n }\n }\n\n // Composite types\n if (result.compositeTypes.length > 0) {\n output += `// ============================================\\n`;\n output += `// Composite Types\\n`;\n output += `// ============================================\\n\\n`;\n\n for (const compositeType of result.compositeTypes) {\n output += compositeType.code + '\\n';\n }\n }\n\n // Tables\n if (result.schemas.length > 0) {\n output += `// ============================================\\n`;\n output += `// Tables\\n`;\n output += `// ============================================\\n\\n`;\n\n for (const schema of result.schemas) {\n output += schema.typeDefinitions + '\\n';\n }\n }\n\n // Views\n if (result.views && result.views.length > 0) {\n output += `// ============================================\\n`;\n output += `// Views\\n`;\n output += `// ============================================\\n\\n`;\n\n for (const view of result.views) {\n output += view.code + '\\n';\n }\n }\n\n // Routines\n if (result.routines && result.routines.length > 0) {\n output += `// ============================================\\n`;\n output += `// Routines (Functions/Procedures)\\n`;\n output += `// ============================================\\n\\n`;\n\n for (const routine of result.routines) {\n output += routine.code + '\\n';\n }\n }\n\n // Warnings\n if (result.warnings.length > 0) {\n output += `// ============================================\\n`;\n output += `// Warnings\\n`;\n output += `// ============================================\\n`;\n output += `// The following warnings were generated:\\n`;\n\n for (const warning of result.warnings) {\n output += `// - ${warning}\\n`;\n }\n }\n\n return output;\n}\n","import {introspectDatabase} from './introspect.js';\nimport {formatOutput, generateSchemas} from './generator.js';\nimport type {DatabaseConfig, GenerationResult, SchemaGenerationOptions,} from './types.js';\n\nexport type {\n DatabaseConfig,\n SchemaGenerationOptions,\n GenerationResult,\n DatabaseMetadata,\n TableMetadata,\n ColumnMetadata,\n EnumMetadata,\n CompositeTypeMetadata,\n RangeTypeMetadata,\n DomainMetadata,\n CheckConstraintMetadata,\n GeneratedSchema,\n} from './types.js';\n\nexport {introspectDatabase} from './introspect.js';\nexport {generateSchemas, formatOutput} from './generator.js';\nexport {mapColumnToZod, toPascalCase, toCamelCase} from './type-mapper.js';\n\n/**\n * Main function: introspect database and generate Zod schemas\n */\nexport async function generateZodSchemas(\n config: DatabaseConfig,\n options: SchemaGenerationOptions = {}\n): Promise<GenerationResult> {\n const metadata = await introspectDatabase(config, options);\n return generateSchemas(metadata, options);\n}\n\n/**\n * Convenience function: generate schemas and return formatted output string\n */\nexport async function generateZodSchemasString(\n config: DatabaseConfig,\n options: SchemaGenerationOptions = {}\n): Promise<string> {\n const result = await generateZodSchemas(config, options);\n return formatOutput(result);\n}\n\n/**\n * Default export\n */\nexport default {\n generateZodSchemas,\n generateZodSchemasString,\n introspectDatabase,\n generateSchemas,\n formatOutput,\n};\n"],"mappings":"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"}