pg2zod 2.2.0 → 2.2.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 +30 -0
- package/README.md +15 -0
- package/dist/cli.js +11 -4
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +12 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/{src-DrIY9N_Y.js → src-BNqNsMzC.js} +96 -41
- package/dist/src-BNqNsMzC.js.map +1 -0
- package/package.json +1 -1
- package/dist/src-DrIY9N_Y.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,35 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 2.2.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- **New Features:**
|
|
8
|
+
|
|
9
|
+
- Added foreign key relationship introspection and metadata to Database type interface
|
|
10
|
+
- Each table in the Database type now includes a `Relationships` array with foreign key information (foreignKeyName, columns, isOneToOne, referencedRelation, referencedColumns)
|
|
11
|
+
- Database type sections (Tables, Views, Functions, Enums, CompositeTypes) are now always present even when empty, using `[_ in never]: never` for empty sections
|
|
12
|
+
- Relationships array is always present for each table, showing `[]` if no foreign keys exist
|
|
13
|
+
|
|
14
|
+
**Improvements:**
|
|
15
|
+
|
|
16
|
+
- Database type structure now consistently matches Supabase's type generator format
|
|
17
|
+
- Better type safety with always-present sections in Database interface
|
|
18
|
+
- Fixed array parsing for relationship columns from PostgreSQL queries
|
|
19
|
+
|
|
20
|
+
## 2.2.1
|
|
21
|
+
|
|
22
|
+
### Patch Changes
|
|
23
|
+
|
|
24
|
+
- **Bug Fixes:**
|
|
25
|
+
|
|
26
|
+
- Fixed connection URL parser to properly handle query parameters (e.g., `?sslmode=verify-full&sslrootcert=system`)
|
|
27
|
+
- Database name is now correctly extracted before query string instead of including the entire query string
|
|
28
|
+
- SSL mode is now properly parsed from query parameters and configured appropriately
|
|
29
|
+
- Improved array and custom type detection in type mapper to handle both `_text` and `text[]` udtName formats
|
|
30
|
+
- Fixed enum, composite type, and range type lookups to check both base and original udtName for arrays
|
|
31
|
+
- Removed unused variable warning in Database type generation
|
|
32
|
+
|
|
3
33
|
## 2.2.0
|
|
4
34
|
|
|
5
35
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -307,11 +307,21 @@ export interface Database {
|
|
|
307
307
|
Row: PublicUsers;
|
|
308
308
|
Insert: PublicUsersInsert;
|
|
309
309
|
Update: PublicUsersUpdate;
|
|
310
|
+
Relationships: []; // No foreign keys
|
|
310
311
|
};
|
|
311
312
|
posts: {
|
|
312
313
|
Row: PublicPosts;
|
|
313
314
|
Insert: PublicPostsInsert;
|
|
314
315
|
Update: PublicPostsUpdate;
|
|
316
|
+
Relationships: [
|
|
317
|
+
{
|
|
318
|
+
foreignKeyName: "posts_user_id_fkey"
|
|
319
|
+
columns: ["user_id"]
|
|
320
|
+
isOneToOne: false
|
|
321
|
+
referencedRelation: "users"
|
|
322
|
+
referencedColumns: ["id"]
|
|
323
|
+
},
|
|
324
|
+
];
|
|
315
325
|
};
|
|
316
326
|
};
|
|
317
327
|
Views: {
|
|
@@ -345,6 +355,8 @@ export interface Database {
|
|
|
345
355
|
}
|
|
346
356
|
```
|
|
347
357
|
|
|
358
|
+
**Note:** All sections (Tables, Views, Functions, Enums, CompositeTypes) are always present in the Database interface, even if empty. Empty sections use `[_ in never]: never` type.
|
|
359
|
+
|
|
348
360
|
**Usage:**
|
|
349
361
|
|
|
350
362
|
```typescript
|
|
@@ -354,6 +366,9 @@ import { Database } from './schema';
|
|
|
354
366
|
type User = Database['public']['Tables']['users']['Row'];
|
|
355
367
|
type UserInsert = Database['public']['Tables']['users']['Insert'];
|
|
356
368
|
|
|
369
|
+
// Access relationships
|
|
370
|
+
type PostRelationships = Database['public']['Tables']['posts']['Relationships'];
|
|
371
|
+
|
|
357
372
|
// Access view types
|
|
358
373
|
type UserStats = Database['public']['Views']['user_stats']['Row'];
|
|
359
374
|
|
package/dist/cli.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { n as generateZodSchemasString } from "./src-
|
|
2
|
+
import { n as generateZodSchemasString } from "./src-BNqNsMzC.js";
|
|
3
3
|
import * as fs from "node:fs/promises";
|
|
4
4
|
import * as path from "node:path";
|
|
5
5
|
|
|
@@ -68,16 +68,23 @@ function getArgArray(args, flag) {
|
|
|
68
68
|
* Parse PostgreSQL connection URL
|
|
69
69
|
*/
|
|
70
70
|
function parseConnectionUrl(url) {
|
|
71
|
-
const match = url.match(/postgresql:\/\/([^:]+):([^@]+)@([^:\/]+):(\d+)\/(
|
|
71
|
+
const match = url.match(/postgresql:\/\/([^:]+):([^@]+)@([^:\/]+):(\d+)\/([^?]+)(\?.*)?/);
|
|
72
72
|
if (!match) throw new Error("Invalid connection URL format");
|
|
73
|
-
const [, user, password, host, port, database] = match;
|
|
73
|
+
const [, user, password, host, port, database, queryString] = match;
|
|
74
|
+
let ssl = false;
|
|
75
|
+
if (queryString) {
|
|
76
|
+
const sslmode = new URLSearchParams(queryString.substring(1)).get("sslmode");
|
|
77
|
+
if (sslmode) {
|
|
78
|
+
if (sslmode === "require" || sslmode === "verify-ca" || sslmode === "verify-full") ssl = sslmode === "require" ? true : { rejectUnauthorized: true };
|
|
79
|
+
}
|
|
80
|
+
}
|
|
74
81
|
return {
|
|
75
82
|
host,
|
|
76
83
|
port: parseInt(port),
|
|
77
84
|
database,
|
|
78
85
|
user,
|
|
79
86
|
password,
|
|
80
|
-
ssl
|
|
87
|
+
ssl
|
|
81
88
|
};
|
|
82
89
|
}
|
|
83
90
|
/**
|
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('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('--no-composite-types'), // Default: true\n includeViews: !args.includes('--no-views'), // Default: true\n includeRoutines: !args.includes('--no-routines'), // Default: true\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 --no-composite-types Skip composite types (generated by default)\n --no-views Skip database views (generated by default)\n --no-routines Skip functions/procedures (generated 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 (includes views, routines, composite types)\n pg2zod --database mydb --output src/schemas.ts\n\n # Use connection URL\n pg2zod --url postgresql://user:pass@localhost:5432/mydb\n\n # Skip views and routines\n pg2zod --database mydb --no-views --no-routines\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 with camelCase\n pg2zod --database mydb --schemas public,auth,api --camel-case\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('--no-composite-types'), // Default: true\n includeViews: !args.includes('--no-views'), // Default: true\n includeRoutines: !args.includes('--no-routines'), // Default: true\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, queryString] = match;\n\n // Parse query parameters\n let ssl: boolean | { rejectUnauthorized: boolean } = false;\n \n if (queryString) {\n const params = new URLSearchParams(queryString.substring(1)); // Remove leading '?'\n const sslmode = params.get('sslmode');\n \n if (sslmode) {\n if (sslmode === 'require' || sslmode === 'verify-ca' || sslmode === 'verify-full') {\n ssl = sslmode === 'require' ? true : { rejectUnauthorized: true };\n }\n }\n }\n\n return {\n host,\n port: parseInt(port),\n database,\n user,\n password,\n ssl,\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 --no-composite-types Skip composite types (generated by default)\n --no-views Skip database views (generated by default)\n --no-routines Skip functions/procedures (generated 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 (includes views, routines, composite types)\n pg2zod --database mydb --output src/schemas.ts\n\n # Use connection URL\n pg2zod --url postgresql://user:pass@localhost:5432/mydb\n\n # Skip views and routines\n pg2zod --database mydb --no-views --no-routines\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 with camelCase\n pg2zod --database mydb --schemas public,auth,api --camel-case\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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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -79,6 +79,16 @@ interface DomainMetadata {
|
|
|
79
79
|
domainDefault: string | null;
|
|
80
80
|
checkConstraints: CheckConstraintMetadata[];
|
|
81
81
|
}
|
|
82
|
+
/**
|
|
83
|
+
* Foreign key relationship metadata
|
|
84
|
+
*/
|
|
85
|
+
interface RelationshipMetadata {
|
|
86
|
+
foreignKeyName: string;
|
|
87
|
+
columns: string[];
|
|
88
|
+
isOneToOne: boolean;
|
|
89
|
+
referencedRelation: string;
|
|
90
|
+
referencedColumns: string[];
|
|
91
|
+
}
|
|
82
92
|
/**
|
|
83
93
|
* Table metadata
|
|
84
94
|
*/
|
|
@@ -92,6 +102,7 @@ interface TableMetadata {
|
|
|
92
102
|
constraintName: string;
|
|
93
103
|
columns: string[];
|
|
94
104
|
}>;
|
|
105
|
+
relationships: RelationshipMetadata[];
|
|
95
106
|
}
|
|
96
107
|
/**
|
|
97
108
|
* View metadata
|
|
@@ -263,5 +274,5 @@ declare const _default: {
|
|
|
263
274
|
formatOutput: typeof formatOutput;
|
|
264
275
|
};
|
|
265
276
|
//#endregion
|
|
266
|
-
export { type CheckConstraintMetadata, type ColumnMetadata, type CompositeTypeMetadata, type DatabaseConfig, type DatabaseMetadata, type DomainMetadata, type EnumMetadata, type GeneratedSchema, type GenerationResult, type RangeTypeMetadata, type SchemaGenerationOptions, type TableMetadata, _default as default, formatOutput, generateSchemas, generateZodSchemas, generateZodSchemasString, introspectDatabase, mapColumnToZod, toCamelCase, toPascalCase };
|
|
277
|
+
export { type CheckConstraintMetadata, type ColumnMetadata, type CompositeTypeMetadata, type DatabaseConfig, type DatabaseMetadata, type DomainMetadata, type EnumMetadata, type GeneratedSchema, type GenerationResult, type RangeTypeMetadata, type RelationshipMetadata, type SchemaGenerationOptions, type TableMetadata, _default as default, formatOutput, generateSchemas, generateZodSchemas, generateZodSchemasString, introspectDatabase, mapColumnToZod, toCamelCase, toPascalCase };
|
|
267
278
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -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":";;AAGA;AAYA;AAkBiB,UA9BA,cAAA,CA8BuB;EASvB,IAAA,EAAA,MAAA;EASA,IAAA,EAAA,MAAA;EAaA,QAAA,EAAA,MAAA;EASA,IAAA,EAAA,MAAA;EAeA,QAAA,EAAA,
|
|
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":";;AAGA;AAYA;AAkBiB,UA9BA,cAAA,CA8BuB;EASvB,IAAA,EAAA,MAAA;EASA,IAAA,EAAA,MAAA;EAaA,QAAA,EAAA,MAAA;EASA,IAAA,EAAA,MAAA;EAeA,QAAA,EAAA,MAAA;EAWA,GAAA,CAAA,EAAA,OAAA,GAAa;IAGnB,kBAAA,EAAA,OAAA;EACS,CAAA;;;;AAYpB;AAUiB,UA9GA,cAAA,CA8GwB;EAYxB,UAAA,EAAA,MAAe;EAcf,QAAA,EAAA,MAAA;EACP,UAAA,EAAA,OAAA;EACD,aAAA,EAAA,MAAA,GAAA,IAAA;EACG,sBAAA,EAAA,MAAA,GAAA,IAAA;EACH,gBAAA,EAAA,MAAA,GAAA,IAAA;EACS,YAAA,EAAA,MAAA,GAAA,IAAA;EACJ,iBAAA,EAAA,MAAA,GAAA,IAAA;EACH,OAAA,EAAA,MAAA;EAAc,UAAA,EAAA,MAAA,GAAA,IAAA;EAMR,eAAA,EAAA,MAAA;EA+CA,OAAA,EAAA,OAAA;AAWjB;;;;AAIS,UAjMQ,uBAAA,CAiMR;EACS,cAAA,EAAA,MAAA;EACP,WAAA,EAAA,MAAA;EACD,UAAA,EAAA,MAAA,GAAA,IAAA;;;;;AClNY,UDuBL,YAAA,CCvBuB;EAC9B,QAAA,EAAA,MAAA;EACC,UAAA,EAAA,MAAA,EAAA;EACA,UAAA,EAAA,MAAA;;;;;UD6BM,qBAAA;EEpCD,QAAA,EAAA,MAAA;EACF,UAAA,EAAA,MAAA;EACD,UAAA,EFqCC,KErCD,CAAA;IACV,aAAA,EAAA,MAAA;IAAgB,QAAA,EAAA,MAAA;IAg+BH,eAAY,EAAA,MAAS;;;;ACx+BrC;;AAEY,UHoDK,iBAAA,CGpDL;EACD,SAAA,EAAA,MAAA;EAAuB,OAAA,EAAA,MAAA;EA+alB,UAAA,EAAA,MAAY;AAU5B;;;;AC3asB,UJ8CL,cAAA,CI9CuB;EAC5B,UAAA,EAAA,MAAA;EACC,QAAA,EAAA,MAAA;EACF,UAAA,EAAA,MAAA;EAAR,sBAAA,EAAA,MAAA,GAAA,IAAA;EAAO,gBAAA,EAAA,MAAA,GAAA,IAAA;EAQY,YAAA,EAAA,MAAA,GAAA,IAAwB;EAClC,UAAA,EAAA,OAAA;EACC,aAAA,EAAA,MAAA,GAAA,IAAA;EACV,gBAAA,EJyCiB,uBIzCjB,EAAA;;AAIF;;;UJ2CgB,oBAAA;;;;;;;;;;UAWA,aAAA;;;WAGN;oBACS;;qBAEC;;;;iBAIJ;;;;;UAMA,YAAA;;;WAGN;;;;;;UAOM,wBAAA;;;;;;;;;;;UAYA,eAAA;;;;;cAKH;;;;;;;;UASG,gBAAA;UACP;SACD;YACG;SACH;kBACS;cACJ;WACH;;;;;UAMM,uBAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;uBAyCM;;;;;UAMN,eAAA;;;;;;;;;;UAWA,gBAAA;WACN;SACF;;;;YACG;;;;SACH;;;;kBACS;;;;WACP;;;;UACD;;;;;;;;AAlOV;AAYA;AAkBA;AASiB,iBCvBK,kBAAA,CDuBO,MAAA,ECtBnB,cDsBmB,EAAA,OAAA,CAAA,ECrBlB,uBDqBkB,CAAA,ECpB1B,ODoB0B,CCpBlB,gBDoBkB,CAAA;;;AAvC7B;AAYA;AAkBA;AASiB,iBE3BD,eAAA,CF2Ba,QAAA,EE1Bf,gBF0Be,EAAA,OAAA,CAAA,EEzBhB,uBFyBgB,CAAA,EExB1B,gBFwB0B;AAS7B;AAaA;AASA;AAeiB,iBE05BD,YAAA,CF15BqB,MAAA,EE05BA,gBF15BA,EAAA,QAAA,EE05B4B,gBF15B5B,CAAA,EAAA,MAAA;;;AArFrC;AAYA;AAkBA;AASiB,iBGhCD,cAAA,CHgCa,MAAA,EG/BnB,cH+BmB,EAAA,QAAA,EG9BjB,gBH8BiB,EAAA,OAAA,EG7BlB,uBH6BkB,EAAA,QAAA,EAAA,MAAA,EAAA,CAAA,EAAA,MAAA;AAyD7B;;;AAMqB,iBGmVL,YAAA,CHnVK,GAAA,EAAA,MAAA,CAAA,EAAA,MAAA;;;AAUrB;AAUiB,iBGyUD,WAAA,CHzUyB,GAAA,EAAA,MAAA,CAAA,EAAA,MAAA;;;AApDzC;AAeA;AAWA;AAGW,iBI3EW,kBAAA,CJ2EX,MAAA,EI1EC,cJ0ED,EAAA,OAAA,CAAA,EIzEE,uBJyEF,CAAA,EIxER,OJwEQ,CIxEA,gBJwEA,CAAA;;;;AAO0B,iBIvEf,wBAAA,CJuEe,MAAA,EItEzB,cJsEyB,EAAA,OAAA,CAAA,EIrExB,uBJqEwB,CAAA,EIpElC,OJoEkC,CAAA,MAAA,CAAA;AAMrC;AAUA;AAYA;AAcA,cI1GC,QJ0GgB,EAAgB;EACvB,kBAAA,EAAA,yBAAA;EACD,wBAAA,EAAA,+BAAA;EACG,kBAAA,EAAA,yBAAA;EACH,eAAA,EAAA,sBAAA;EACS,YAAA,EAAA,mBAAA;CACJ"}
|
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-
|
|
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-BNqNsMzC.js";
|
|
2
2
|
|
|
3
3
|
export { src_default as default, formatOutput, generateSchemas, generateZodSchemas, generateZodSchemasString, introspectDatabase, mapColumnToZod, toCamelCase, toPascalCase };
|
|
@@ -110,6 +110,38 @@ async function introspectTables(pool, schemas, options) {
|
|
|
110
110
|
GROUP BY tc.table_schema, tc.table_name, tc.constraint_name
|
|
111
111
|
`;
|
|
112
112
|
const uniqueConstraintsResult = await pool.query(uniqueConstraintsQuery, schemas);
|
|
113
|
+
const foreignKeysQuery = `
|
|
114
|
+
SELECT
|
|
115
|
+
tc.table_schema,
|
|
116
|
+
tc.table_name,
|
|
117
|
+
tc.constraint_name AS foreign_key_name,
|
|
118
|
+
array_agg(kcu.column_name ORDER BY kcu.ordinal_position) AS columns,
|
|
119
|
+
ccu.table_name AS referenced_table,
|
|
120
|
+
array_agg(ccu.column_name ORDER BY kcu.ordinal_position) AS referenced_columns,
|
|
121
|
+
-- Check if it's one-to-one (FK columns are also unique)
|
|
122
|
+
EXISTS(
|
|
123
|
+
SELECT 1
|
|
124
|
+
FROM information_schema.table_constraints uc
|
|
125
|
+
JOIN information_schema.key_column_usage ukcu
|
|
126
|
+
ON uc.constraint_name = ukcu.constraint_name
|
|
127
|
+
AND uc.table_schema = ukcu.table_schema
|
|
128
|
+
WHERE uc.constraint_type = 'UNIQUE'
|
|
129
|
+
AND uc.table_schema = tc.table_schema
|
|
130
|
+
AND uc.table_name = tc.table_name
|
|
131
|
+
AND ukcu.column_name = ANY(array_agg(kcu.column_name))
|
|
132
|
+
) AS is_one_to_one
|
|
133
|
+
FROM information_schema.table_constraints tc
|
|
134
|
+
JOIN information_schema.key_column_usage kcu
|
|
135
|
+
ON tc.constraint_name = kcu.constraint_name
|
|
136
|
+
AND tc.table_schema = kcu.table_schema
|
|
137
|
+
JOIN information_schema.constraint_column_usage ccu
|
|
138
|
+
ON tc.constraint_name = ccu.constraint_name
|
|
139
|
+
AND tc.table_schema = ccu.constraint_schema
|
|
140
|
+
WHERE tc.constraint_type = 'FOREIGN KEY'
|
|
141
|
+
AND tc.table_schema IN (${schemaFilter})
|
|
142
|
+
GROUP BY tc.table_schema, tc.table_name, tc.constraint_name, ccu.table_name
|
|
143
|
+
`;
|
|
144
|
+
const foreignKeysResult = await pool.query(foreignKeysQuery, schemas);
|
|
113
145
|
const tableMap = /* @__PURE__ */ new Map();
|
|
114
146
|
for (const row of columnsResult.rows) {
|
|
115
147
|
const tableKey = `${row.table_schema}.${row.table_name}`;
|
|
@@ -119,7 +151,8 @@ async function introspectTables(pool, schemas, options) {
|
|
|
119
151
|
columns: [],
|
|
120
152
|
checkConstraints: [],
|
|
121
153
|
primaryKeys: [],
|
|
122
|
-
uniqueConstraints: []
|
|
154
|
+
uniqueConstraints: [],
|
|
155
|
+
relationships: []
|
|
123
156
|
});
|
|
124
157
|
const table = tableMap.get(tableKey);
|
|
125
158
|
const isArray = row.data_type === "ARRAY";
|
|
@@ -160,6 +193,21 @@ async function introspectTables(pool, schemas, options) {
|
|
|
160
193
|
columns: row.columns
|
|
161
194
|
});
|
|
162
195
|
}
|
|
196
|
+
for (const row of foreignKeysResult.rows) {
|
|
197
|
+
const tableKey = `${row.table_schema}.${row.table_name}`;
|
|
198
|
+
const table = tableMap.get(tableKey);
|
|
199
|
+
if (table) {
|
|
200
|
+
const columns = Array.isArray(row.columns) ? row.columns : [];
|
|
201
|
+
const referencedColumns = Array.isArray(row.referenced_columns) ? row.referenced_columns : [];
|
|
202
|
+
table.relationships.push({
|
|
203
|
+
foreignKeyName: row.foreign_key_name,
|
|
204
|
+
columns,
|
|
205
|
+
isOneToOne: row.is_one_to_one,
|
|
206
|
+
referencedRelation: row.referenced_table,
|
|
207
|
+
referencedColumns
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
}
|
|
163
211
|
let tables = Array.from(tableMap.values());
|
|
164
212
|
if (options.tables) tables = tables.filter((t) => options.tables.includes(t.tableName));
|
|
165
213
|
if (options.excludeTables) tables = tables.filter((t) => !options.excludeTables.includes(t.tableName));
|
|
@@ -1228,49 +1276,56 @@ function generateDatabaseType(result, metadata) {
|
|
|
1228
1276
|
for (const schemaName of schemas) {
|
|
1229
1277
|
const entities = schemaMap.get(schemaName);
|
|
1230
1278
|
output += ` ${schemaName}: {\n`;
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
output += `
|
|
1246
|
-
output += `
|
|
1247
|
-
output += ` };\n`;
|
|
1248
|
-
}
|
|
1249
|
-
output += ` };\n`;
|
|
1250
|
-
}
|
|
1251
|
-
if (entities.routines.length > 0) {
|
|
1252
|
-
output += ` Functions: {\n`;
|
|
1253
|
-
for (const routine of entities.routines) {
|
|
1254
|
-
const routineName = routine.routineName.replace(/^[A-Z]/, (c) => c.toLowerCase());
|
|
1255
|
-
output += ` ${routineName}: {\n`;
|
|
1256
|
-
if (routine.hasParams) output += ` Args: ${routine.name}Params;\n`;
|
|
1257
|
-
else output += ` Args: Record<string, never>;\n`;
|
|
1258
|
-
if (routine.hasReturn) output += ` Returns: ${routine.name}Return;\n`;
|
|
1259
|
-
else output += ` Returns: void;\n`;
|
|
1260
|
-
output += ` };\n`;
|
|
1279
|
+
output += ` Tables: {\n`;
|
|
1280
|
+
if (entities.tables.length > 0) for (const table of entities.tables) {
|
|
1281
|
+
const relationships = metadata.tables.find((t) => t.tableName === table.tableName && t.schemaName === table.schemaName)?.relationships || [];
|
|
1282
|
+
output += ` ${table.tableName}: {\n`;
|
|
1283
|
+
output += ` Row: ${table.name};\n`;
|
|
1284
|
+
output += ` Insert: ${table.name}Insert;\n`;
|
|
1285
|
+
output += ` Update: ${table.name}Update;\n`;
|
|
1286
|
+
output += ` Relationships: [\n`;
|
|
1287
|
+
if (relationships.length > 0) for (const rel of relationships) {
|
|
1288
|
+
output += ` {\n`;
|
|
1289
|
+
output += ` foreignKeyName: "${rel.foreignKeyName}"\n`;
|
|
1290
|
+
output += ` columns: [${rel.columns.map((c) => `"${c}"`).join(", ")}]\n`;
|
|
1291
|
+
output += ` isOneToOne: ${rel.isOneToOne}\n`;
|
|
1292
|
+
output += ` referencedRelation: "${rel.referencedRelation}"\n`;
|
|
1293
|
+
output += ` referencedColumns: [${rel.referencedColumns.map((c) => `"${c}"`).join(", ")}]\n`;
|
|
1294
|
+
output += ` },\n`;
|
|
1261
1295
|
}
|
|
1262
|
-
output += `
|
|
1296
|
+
output += ` ];\n`;
|
|
1297
|
+
output += ` };\n`;
|
|
1263
1298
|
}
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1299
|
+
else output += ` [_ in never]: never\n`;
|
|
1300
|
+
output += ` };\n`;
|
|
1301
|
+
output += ` Views: {\n`;
|
|
1302
|
+
if (entities.views.length > 0) for (const view of entities.views) {
|
|
1303
|
+
output += ` ${view.viewName}: {\n`;
|
|
1304
|
+
output += ` Row: ${view.name};\n`;
|
|
1305
|
+
output += ` };\n`;
|
|
1268
1306
|
}
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1307
|
+
else output += ` [_ in never]: never\n`;
|
|
1308
|
+
output += ` };\n`;
|
|
1309
|
+
output += ` Functions: {\n`;
|
|
1310
|
+
if (entities.routines.length > 0) for (const routine of entities.routines) {
|
|
1311
|
+
const routineName = routine.routineName.replace(/^[A-Z]/, (c) => c.toLowerCase());
|
|
1312
|
+
output += ` ${routineName}: {\n`;
|
|
1313
|
+
if (routine.hasParams) output += ` Args: ${routine.name}Params;\n`;
|
|
1314
|
+
else output += ` Args: Record<string, never>;\n`;
|
|
1315
|
+
if (routine.hasReturn) output += ` Returns: ${routine.name}Return;\n`;
|
|
1316
|
+
else output += ` Returns: void;\n`;
|
|
1317
|
+
output += ` };\n`;
|
|
1273
1318
|
}
|
|
1319
|
+
else output += ` [_ in never]: never\n`;
|
|
1320
|
+
output += ` };\n`;
|
|
1321
|
+
output += ` Enums: {\n`;
|
|
1322
|
+
if (entities.enums.length > 0) for (const enumType of entities.enums) output += ` ${enumType.enumName.replace(/^[A-Z]/, (c) => c.toLowerCase())}: ${enumType.name};\n`;
|
|
1323
|
+
else output += ` [_ in never]: never\n`;
|
|
1324
|
+
output += ` };\n`;
|
|
1325
|
+
output += ` CompositeTypes: {\n`;
|
|
1326
|
+
if (entities.compositeTypes.length > 0) for (const compositeType of entities.compositeTypes) output += ` ${compositeType.typeName.replace(/^[A-Z]/, (c) => c.toLowerCase())}: ${compositeType.name};\n`;
|
|
1327
|
+
else output += ` [_ in never]: never\n`;
|
|
1328
|
+
output += ` };\n`;
|
|
1274
1329
|
output += ` };\n`;
|
|
1275
1330
|
}
|
|
1276
1331
|
output += `}\n`;
|
|
@@ -1379,4 +1434,4 @@ var src_default = {
|
|
|
1379
1434
|
|
|
1380
1435
|
//#endregion
|
|
1381
1436
|
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 };
|
|
1382
|
-
//# sourceMappingURL=src-
|
|
1437
|
+
//# sourceMappingURL=src-BNqNsMzC.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"src-BNqNsMzC.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 // Get foreign key relationships\n const foreignKeysQuery = `\n SELECT \n tc.table_schema,\n tc.table_name,\n tc.constraint_name AS foreign_key_name,\n array_agg(kcu.column_name ORDER BY kcu.ordinal_position) AS columns,\n ccu.table_name AS referenced_table,\n array_agg(ccu.column_name ORDER BY kcu.ordinal_position) AS referenced_columns,\n -- Check if it's one-to-one (FK columns are also unique)\n EXISTS(\n SELECT 1 \n FROM information_schema.table_constraints uc\n JOIN information_schema.key_column_usage ukcu \n ON uc.constraint_name = ukcu.constraint_name\n AND uc.table_schema = ukcu.table_schema\n WHERE uc.constraint_type = 'UNIQUE'\n AND uc.table_schema = tc.table_schema\n AND uc.table_name = tc.table_name\n AND ukcu.column_name = ANY(array_agg(kcu.column_name))\n ) AS is_one_to_one\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 JOIN information_schema.constraint_column_usage ccu\n ON tc.constraint_name = ccu.constraint_name\n AND tc.table_schema = ccu.constraint_schema\n WHERE tc.constraint_type = 'FOREIGN KEY'\n AND tc.table_schema IN (${schemaFilter})\n GROUP BY tc.table_schema, tc.table_name, tc.constraint_name, ccu.table_name\n `;\n\n const foreignKeysResult = await pool.query(foreignKeysQuery, 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 relationships: [],\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 // Add foreign key relationships\n for (const row of foreignKeysResult.rows) {\n const tableKey = `${row.table_schema}.${row.table_name}`;\n const table = tableMap.get(tableKey);\n if (table) {\n // Parse array columns (they come as PostgreSQL arrays)\n const columns = Array.isArray(row.columns) ? row.columns : [];\n const referencedColumns = Array.isArray(row.referenced_columns) ? row.referenced_columns : [];\n \n table.relationships.push({\n foreignKeyName: row.foreign_key_name,\n columns,\n isOneToOne: row.is_one_to_one,\n referencedRelation: row.referenced_table,\n referencedColumns,\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 // Custom type mappings (check original udtName first)\n if (options.customTypeMappings?.[udtName]) {\n return options.customTypeMappings[udtName];\n }\n\n // For arrays, extract the base type name\n // PostgreSQL array types have underscore prefix (e.g., _text for text[], _int4 for integer[])\n // But sometimes udtName comes as 'text[]' instead of '_text'\n let baseUdtName = udtName;\n if (column.isArray) {\n if (udtName.startsWith('_')) {\n baseUdtName = udtName.substring(1);\n } else if (udtName.endsWith('[]')) {\n // Handle 'text[]' format\n baseUdtName = udtName.replace(/\\[\\]$/, '');\n }\n }\n\n // Check if it's an enum (check both original and base name for arrays)\n const enumType = metadata.enums.find((e) => e.enumName === baseUdtName || 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 === baseUdtName || 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 === baseUdtName || 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 // Use the base name for type checking\n udtName = baseUdtName;\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}ViewSchema`;\n const typeName = `${schemaPrefix}${viewName}View`;\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 * Generate Database type that organizes all generated types by schema\n */\nfunction generateDatabaseType(result: GenerationResult, metadata: DatabaseMetadata): string {\n // Group all entities by schema\n const schemaMap = new Map<string, {\n tables: Array<{ name: string; schemaName: string; tableName: string }>;\n views: Array<{ name: string; schemaName: string; viewName: string }>;\n routines: Array<{ name: string; schemaName: string; routineName: string; hasParams: boolean; hasReturn: boolean }>;\n enums: Array<{ name: string; schemaName: string; enumName: string }>;\n compositeTypes: Array<{ name: string; schemaName: string; typeName: string }>;\n domains: Array<{ name: string; schemaName: string; domainName: string }>;\n ranges: Array<{ name: string; schemaName: string; rangeName: string }>;\n }>();\n\n // Collect tables\n for (const schema of result.schemas) {\n const schemaPrefix = toPascalCase(schema.schemaName);\n const tableName = toPascalCase(schema.tableName);\n const fullName = `${schemaPrefix}${tableName}`;\n\n if (!schemaMap.has(schema.schemaName)) {\n schemaMap.set(schema.schemaName, {\n tables: [],\n views: [],\n routines: [],\n enums: [],\n compositeTypes: [],\n domains: [],\n ranges: [],\n });\n }\n\n schemaMap.get(schema.schemaName)!.tables.push({\n name: fullName,\n schemaName: schema.schemaName,\n tableName: schema.tableName,\n });\n }\n\n // Collect views (views have 'View' suffix in their type names)\n for (const view of result.views) {\n const parts = view.name.match(/^([A-Z][a-z0-9]*)(.+)View$/);\n if (parts && parts.length >= 3) {\n const schemaName = parts[1].toLowerCase();\n if (!schemaMap.has(schemaName)) {\n schemaMap.set(schemaName, {\n tables: [],\n views: [],\n routines: [],\n enums: [],\n compositeTypes: [],\n domains: [],\n ranges: [],\n });\n }\n schemaMap.get(schemaName)!.views.push({\n name: view.name,\n schemaName,\n viewName: parts[2],\n });\n }\n }\n\n // Collect routines - need to check metadata to see if they have params/returns\n const routineMetadataMap = new Map<string, RoutineMetadata>();\n for (const routine of metadata.routines) {\n const schemaPrefix = toPascalCase(routine.schemaName);\n const routineName = toPascalCase(routine.routineName);\n const fullName = `${schemaPrefix}${routineName}`;\n routineMetadataMap.set(fullName, routine);\n }\n\n for (const routine of result.routines) {\n const parts = routine.name.match(/^([A-Z][a-z0-9]*)(.+)$/);\n if (parts && parts.length >= 3) {\n const schemaName = parts[1].toLowerCase();\n if (!schemaMap.has(schemaName)) {\n schemaMap.set(schemaName, {\n tables: [],\n views: [],\n routines: [],\n enums: [],\n compositeTypes: [],\n domains: [],\n ranges: [],\n });\n }\n\n const routineMeta = routineMetadataMap.get(routine.name);\n if (routineMeta) {\n const inParams = routineMeta.parameters.filter(\n (p) => p.parameterMode === 'IN' || p.parameterMode === 'INOUT'\n );\n const hasReturn = routineMeta.routineType === 'FUNCTION' && \n routineMeta.returnType && \n routineMeta.returnType !== 'void';\n const outParams = routineMeta.parameters.filter(\n (p) => p.parameterMode === 'OUT' || p.parameterMode === 'INOUT'\n );\n\n schemaMap.get(schemaName)!.routines.push({\n name: routine.name,\n schemaName,\n routineName: parts[2],\n hasParams: inParams.length > 0,\n hasReturn: hasReturn || outParams.length > 0,\n });\n }\n }\n }\n\n // Collect enums\n for (const enumType of result.enums) {\n const parts = enumType.name.match(/^([A-Z][a-z0-9]*)(.+)$/);\n if (parts && parts.length >= 3) {\n const schemaName = parts[1].toLowerCase();\n if (!schemaMap.has(schemaName)) {\n schemaMap.set(schemaName, {\n tables: [],\n views: [],\n routines: [],\n enums: [],\n compositeTypes: [],\n domains: [],\n ranges: [],\n });\n }\n schemaMap.get(schemaName)!.enums.push({\n name: enumType.name,\n schemaName,\n enumName: parts[2],\n });\n }\n }\n\n // Collect composite types\n for (const compositeType of result.compositeTypes) {\n const parts = compositeType.name.match(/^([A-Z][a-z0-9]*)(.+)Composite$/);\n if (parts && parts.length >= 3) {\n const schemaName = parts[1].toLowerCase();\n if (!schemaMap.has(schemaName)) {\n schemaMap.set(schemaName, {\n tables: [],\n views: [],\n routines: [],\n enums: [],\n compositeTypes: [],\n domains: [],\n ranges: [],\n });\n }\n schemaMap.get(schemaName)!.compositeTypes.push({\n name: compositeType.name,\n schemaName,\n typeName: parts[2],\n });\n }\n }\n\n // Collect domains\n for (const domain of result.domains) {\n const parts = domain.name.match(/^([A-Z][a-z0-9]*)(.+)$/);\n if (parts && parts.length >= 3) {\n const schemaName = parts[1].toLowerCase();\n if (!schemaMap.has(schemaName)) {\n schemaMap.set(schemaName, {\n tables: [],\n views: [],\n routines: [],\n enums: [],\n compositeTypes: [],\n domains: [],\n ranges: [],\n });\n }\n schemaMap.get(schemaName)!.domains.push({\n name: domain.name,\n schemaName,\n domainName: parts[2],\n });\n }\n }\n\n // Collect ranges\n for (const range of result.ranges) {\n const parts = range.name.match(/^([A-Z][a-z0-9]*)(.+)$/);\n if (parts && parts.length >= 3) {\n const schemaName = parts[1].toLowerCase();\n if (!schemaMap.has(schemaName)) {\n schemaMap.set(schemaName, {\n tables: [],\n views: [],\n routines: [],\n enums: [],\n compositeTypes: [],\n domains: [],\n ranges: [],\n });\n }\n schemaMap.get(schemaName)!.ranges.push({\n name: range.name,\n schemaName,\n rangeName: parts[2],\n });\n }\n }\n\n let output = '';\n output += `// ============================================\\n`;\n output += `// Database Types\\n`;\n output += `// ============================================\\n\\n`;\n\n output += `export interface Database {\\n`;\n\n // Generate schema sections\n const schemas = Array.from(schemaMap.keys()).sort();\n for (const schemaName of schemas) {\n const entities = schemaMap.get(schemaName)!;\n\n output += ` ${schemaName}: {\\n`;\n\n // Tables - always include\n output += ` Tables: {\\n`;\n if (entities.tables.length > 0) {\n for (const table of entities.tables) {\n // Get relationships for this table from metadata\n const tableMetadata = metadata.tables.find(\n t => t.tableName === table.tableName && t.schemaName === table.schemaName\n );\n const relationships = tableMetadata?.relationships || [];\n \n output += ` ${table.tableName}: {\\n`;\n output += ` Row: ${table.name};\\n`;\n output += ` Insert: ${table.name}Insert;\\n`;\n output += ` Update: ${table.name}Update;\\n`;\n output += ` Relationships: [\\n`;\n if (relationships.length > 0) {\n for (const rel of relationships) {\n output += ` {\\n`;\n output += ` foreignKeyName: \"${rel.foreignKeyName}\"\\n`;\n output += ` columns: [${rel.columns.map(c => `\"${c}\"`).join(\", \")}]\\n`;\n output += ` isOneToOne: ${rel.isOneToOne}\\n`;\n output += ` referencedRelation: \"${rel.referencedRelation}\"\\n`;\n output += ` referencedColumns: [${rel.referencedColumns.map(c => `\"${c}\"`).join(\", \")}]\\n`;\n output += ` },\\n`;\n }\n }\n output += ` ];\\n`;\n output += ` };\\n`;\n }\n } else {\n output += ` [_ in never]: never\\n`;\n }\n output += ` };\\n`;\n\n // Views - always include\n output += ` Views: {\\n`;\n if (entities.views.length > 0) {\n for (const view of entities.views) {\n output += ` ${view.viewName}: {\\n`;\n output += ` Row: ${view.name};\\n`;\n output += ` };\\n`;\n }\n } else {\n output += ` [_ in never]: never\\n`;\n }\n output += ` };\\n`;\n\n // Functions - always include\n output += ` Functions: {\\n`;\n if (entities.routines.length > 0) {\n for (const routine of entities.routines) {\n const routineName = routine.routineName.replace(/^[A-Z]/, (c) => c.toLowerCase());\n output += ` ${routineName}: {\\n`;\n \n // Only include Args if the function has parameters\n if (routine.hasParams) {\n output += ` Args: ${routine.name}Params;\\n`;\n } else {\n output += ` Args: Record<string, never>;\\n`;\n }\n \n // Only include Returns if the function has a return type\n if (routine.hasReturn) {\n output += ` Returns: ${routine.name}Return;\\n`;\n } else {\n output += ` Returns: void;\\n`;\n }\n \n output += ` };\\n`;\n }\n } else {\n output += ` [_ in never]: never\\n`;\n }\n output += ` };\\n`;\n\n // Enums - always include\n output += ` Enums: {\\n`;\n if (entities.enums.length > 0) {\n for (const enumType of entities.enums) {\n output += ` ${enumType.enumName.replace(/^[A-Z]/, (c) => c.toLowerCase())}: ${enumType.name};\\n`;\n }\n } else {\n output += ` [_ in never]: never\\n`;\n }\n output += ` };\\n`;\n\n // Composite Types - always include\n output += ` CompositeTypes: {\\n`;\n if (entities.compositeTypes.length > 0) {\n for (const compositeType of entities.compositeTypes) {\n output += ` ${compositeType.typeName.replace(/^[A-Z]/, (c) => c.toLowerCase())}: ${compositeType.name};\\n`;\n }\n } else {\n output += ` [_ in never]: never\\n`;\n }\n output += ` };\\n`;\n\n output += ` };\\n`;\n }\n\n output += `}\\n`;\n\n return output;\n}\n\n/**\n * Format the complete output file\n */\nexport function formatOutput(result: GenerationResult, metadata: DatabaseMetadata): 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 // Database Type\n output += generateDatabaseType(result, metadata) + '\\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 RelationshipMetadata,\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 metadata = await introspectDatabase(config, options);\n const result = generateSchemas(metadata, options);\n return formatOutput(result, metadata);\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
package/dist/src-DrIY9N_Y.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"src-DrIY9N_Y.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 // Custom type mappings (check original udtName first)\n if (options.customTypeMappings?.[udtName]) {\n return options.customTypeMappings[udtName];\n }\n\n // For arrays, extract the base type name\n // PostgreSQL array types have underscore prefix (e.g., _text for text[], _int4 for integer[])\n // But sometimes udtName comes as 'text[]' instead of '_text'\n let baseUdtName = udtName;\n if (column.isArray) {\n if (udtName.startsWith('_')) {\n baseUdtName = udtName.substring(1);\n } else if (udtName.endsWith('[]')) {\n // Handle 'text[]' format\n baseUdtName = udtName.replace(/\\[\\]$/, '');\n }\n }\n\n // Check if it's an enum (check both original and base name for arrays)\n const enumType = metadata.enums.find((e) => e.enumName === baseUdtName || 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 === baseUdtName || 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 === baseUdtName || 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 // Use the base name for type checking\n udtName = baseUdtName;\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}ViewSchema`;\n const typeName = `${schemaPrefix}${viewName}View`;\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 * Generate Database type that organizes all generated types by schema\n */\nfunction generateDatabaseType(result: GenerationResult, metadata: DatabaseMetadata): string {\n // Group all entities by schema\n const schemaMap = new Map<string, {\n tables: Array<{ name: string; schemaName: string; tableName: string }>;\n views: Array<{ name: string; schemaName: string; viewName: string }>;\n routines: Array<{ name: string; schemaName: string; routineName: string; hasParams: boolean; hasReturn: boolean }>;\n enums: Array<{ name: string; schemaName: string; enumName: string }>;\n compositeTypes: Array<{ name: string; schemaName: string; typeName: string }>;\n domains: Array<{ name: string; schemaName: string; domainName: string }>;\n ranges: Array<{ name: string; schemaName: string; rangeName: string }>;\n }>();\n\n // Collect tables\n for (const schema of result.schemas) {\n const schemaPrefix = toPascalCase(schema.schemaName);\n const tableName = toPascalCase(schema.tableName);\n const fullName = `${schemaPrefix}${tableName}`;\n\n if (!schemaMap.has(schema.schemaName)) {\n schemaMap.set(schema.schemaName, {\n tables: [],\n views: [],\n routines: [],\n enums: [],\n compositeTypes: [],\n domains: [],\n ranges: [],\n });\n }\n\n schemaMap.get(schema.schemaName)!.tables.push({\n name: fullName,\n schemaName: schema.schemaName,\n tableName: schema.tableName,\n });\n }\n\n // Collect views (views have 'View' suffix in their type names)\n for (const view of result.views) {\n const parts = view.name.match(/^([A-Z][a-z0-9]*)(.+)View$/);\n if (parts && parts.length >= 3) {\n const schemaName = parts[1].toLowerCase();\n if (!schemaMap.has(schemaName)) {\n schemaMap.set(schemaName, {\n tables: [],\n views: [],\n routines: [],\n enums: [],\n compositeTypes: [],\n domains: [],\n ranges: [],\n });\n }\n schemaMap.get(schemaName)!.views.push({\n name: view.name,\n schemaName,\n viewName: parts[2],\n });\n }\n }\n\n // Collect routines - need to check metadata to see if they have params/returns\n const routineMetadataMap = new Map<string, RoutineMetadata>();\n for (const routine of metadata.routines) {\n const schemaPrefix = toPascalCase(routine.schemaName);\n const routineName = toPascalCase(routine.routineName);\n const fullName = `${schemaPrefix}${routineName}`;\n routineMetadataMap.set(fullName, routine);\n }\n\n for (const routine of result.routines) {\n const parts = routine.name.match(/^([A-Z][a-z0-9]*)(.+)$/);\n if (parts && parts.length >= 3) {\n const schemaName = parts[1].toLowerCase();\n if (!schemaMap.has(schemaName)) {\n schemaMap.set(schemaName, {\n tables: [],\n views: [],\n routines: [],\n enums: [],\n compositeTypes: [],\n domains: [],\n ranges: [],\n });\n }\n\n const routineMeta = routineMetadataMap.get(routine.name);\n if (routineMeta) {\n const inParams = routineMeta.parameters.filter(\n (p) => p.parameterMode === 'IN' || p.parameterMode === 'INOUT'\n );\n const hasReturn = routineMeta.routineType === 'FUNCTION' && \n routineMeta.returnType && \n routineMeta.returnType !== 'void';\n const outParams = routineMeta.parameters.filter(\n (p) => p.parameterMode === 'OUT' || p.parameterMode === 'INOUT'\n );\n\n schemaMap.get(schemaName)!.routines.push({\n name: routine.name,\n schemaName,\n routineName: parts[2],\n hasParams: inParams.length > 0,\n hasReturn: hasReturn || outParams.length > 0,\n });\n }\n }\n }\n\n // Collect enums\n for (const enumType of result.enums) {\n const parts = enumType.name.match(/^([A-Z][a-z0-9]*)(.+)$/);\n if (parts && parts.length >= 3) {\n const schemaName = parts[1].toLowerCase();\n if (!schemaMap.has(schemaName)) {\n schemaMap.set(schemaName, {\n tables: [],\n views: [],\n routines: [],\n enums: [],\n compositeTypes: [],\n domains: [],\n ranges: [],\n });\n }\n schemaMap.get(schemaName)!.enums.push({\n name: enumType.name,\n schemaName,\n enumName: parts[2],\n });\n }\n }\n\n // Collect composite types\n for (const compositeType of result.compositeTypes) {\n const parts = compositeType.name.match(/^([A-Z][a-z0-9]*)(.+)Composite$/);\n if (parts && parts.length >= 3) {\n const schemaName = parts[1].toLowerCase();\n if (!schemaMap.has(schemaName)) {\n schemaMap.set(schemaName, {\n tables: [],\n views: [],\n routines: [],\n enums: [],\n compositeTypes: [],\n domains: [],\n ranges: [],\n });\n }\n schemaMap.get(schemaName)!.compositeTypes.push({\n name: compositeType.name,\n schemaName,\n typeName: parts[2],\n });\n }\n }\n\n // Collect domains\n for (const domain of result.domains) {\n const parts = domain.name.match(/^([A-Z][a-z0-9]*)(.+)$/);\n if (parts && parts.length >= 3) {\n const schemaName = parts[1].toLowerCase();\n if (!schemaMap.has(schemaName)) {\n schemaMap.set(schemaName, {\n tables: [],\n views: [],\n routines: [],\n enums: [],\n compositeTypes: [],\n domains: [],\n ranges: [],\n });\n }\n schemaMap.get(schemaName)!.domains.push({\n name: domain.name,\n schemaName,\n domainName: parts[2],\n });\n }\n }\n\n // Collect ranges\n for (const range of result.ranges) {\n const parts = range.name.match(/^([A-Z][a-z0-9]*)(.+)$/);\n if (parts && parts.length >= 3) {\n const schemaName = parts[1].toLowerCase();\n if (!schemaMap.has(schemaName)) {\n schemaMap.set(schemaName, {\n tables: [],\n views: [],\n routines: [],\n enums: [],\n compositeTypes: [],\n domains: [],\n ranges: [],\n });\n }\n schemaMap.get(schemaName)!.ranges.push({\n name: range.name,\n schemaName,\n rangeName: parts[2],\n });\n }\n }\n\n let output = '';\n output += `// ============================================\\n`;\n output += `// Database Types\\n`;\n output += `// ============================================\\n\\n`;\n\n output += `export interface Database {\\n`;\n\n // Generate schema sections\n const schemas = Array.from(schemaMap.keys()).sort();\n for (const schemaName of schemas) {\n const entities = schemaMap.get(schemaName)!;\n\n output += ` ${schemaName}: {\\n`;\n\n // Tables\n if (entities.tables.length > 0) {\n output += ` Tables: {\\n`;\n for (const table of entities.tables) {\n output += ` ${table.tableName}: {\\n`;\n output += ` Row: ${table.name};\\n`;\n output += ` Insert: ${table.name}Insert;\\n`;\n output += ` Update: ${table.name}Update;\\n`;\n output += ` };\\n`;\n }\n output += ` };\\n`;\n }\n\n // Views\n if (entities.views.length > 0) {\n output += ` Views: {\\n`;\n for (const view of entities.views) {\n output += ` ${view.viewName}: {\\n`;\n output += ` Row: ${view.name};\\n`;\n output += ` };\\n`;\n }\n output += ` };\\n`;\n }\n\n // Functions\n if (entities.routines.length > 0) {\n output += ` Functions: {\\n`;\n for (const routine of entities.routines) {\n const routineName = routine.routineName.replace(/^[A-Z]/, (c) => c.toLowerCase());\n output += ` ${routineName}: {\\n`;\n \n // Only include Args if the function has parameters\n if (routine.hasParams) {\n output += ` Args: ${routine.name}Params;\\n`;\n } else {\n output += ` Args: Record<string, never>;\\n`;\n }\n \n // Only include Returns if the function has a return type\n if (routine.hasReturn) {\n output += ` Returns: ${routine.name}Return;\\n`;\n } else {\n output += ` Returns: void;\\n`;\n }\n \n output += ` };\\n`;\n }\n output += ` };\\n`;\n }\n\n // Enums\n if (entities.enums.length > 0) {\n output += ` Enums: {\\n`;\n for (const enumType of entities.enums) {\n output += ` ${enumType.enumName.replace(/^[A-Z]/, (c) => c.toLowerCase())}: ${enumType.name};\\n`;\n }\n output += ` };\\n`;\n }\n\n // Composite Types\n if (entities.compositeTypes.length > 0) {\n output += ` CompositeTypes: {\\n`;\n for (const compositeType of entities.compositeTypes) {\n output += ` ${compositeType.typeName.replace(/^[A-Z]/, (c) => c.toLowerCase())}: ${compositeType.name};\\n`;\n }\n output += ` };\\n`;\n }\n\n output += ` };\\n`;\n }\n\n output += `}\\n`;\n\n return output;\n}\n\n/**\n * Format the complete output file\n */\nexport function formatOutput(result: GenerationResult, metadata: DatabaseMetadata): 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 // Database Type\n output += generateDatabaseType(result, metadata) + '\\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 metadata = await introspectDatabase(config, options);\n const result = generateSchemas(metadata, options);\n return formatOutput(result, metadata);\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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"}
|