drizzle-multitenant 1.2.0 → 1.3.1

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.
@@ -0,0 +1,395 @@
1
+ /**
2
+ * Types for schema export/import functionality
3
+ */
4
+ /**
5
+ * Supported export formats
6
+ */
7
+ type ExportFormat = 'json' | 'typescript' | 'mermaid';
8
+ /**
9
+ * Column reference (foreign key)
10
+ */
11
+ interface ColumnReference {
12
+ table: string;
13
+ column: string;
14
+ onDelete?: 'CASCADE' | 'SET NULL' | 'SET DEFAULT' | 'RESTRICT' | 'NO ACTION';
15
+ onUpdate?: 'CASCADE' | 'SET NULL' | 'SET DEFAULT' | 'RESTRICT' | 'NO ACTION';
16
+ }
17
+ /**
18
+ * Exported column definition
19
+ */
20
+ interface ExportedColumn {
21
+ name: string;
22
+ dataType: string;
23
+ isPrimaryKey: boolean;
24
+ isNullable: boolean;
25
+ hasDefault: boolean;
26
+ defaultValue?: string | null;
27
+ references?: ColumnReference;
28
+ }
29
+ /**
30
+ * Exported index definition
31
+ */
32
+ interface ExportedIndex {
33
+ name: string;
34
+ columns: string[];
35
+ isUnique: boolean;
36
+ }
37
+ /**
38
+ * Exported table definition
39
+ */
40
+ interface ExportedTable {
41
+ name: string;
42
+ schemaType: 'tenant' | 'shared';
43
+ columns: ExportedColumn[];
44
+ indexes: ExportedIndex[];
45
+ filePath?: string;
46
+ }
47
+ /**
48
+ * Complete schema export structure
49
+ */
50
+ interface SchemaExport {
51
+ version: string;
52
+ exportedAt: string;
53
+ projectName?: string;
54
+ tables: ExportedTable[];
55
+ metadata?: {
56
+ tenantCount: number;
57
+ sharedCount: number;
58
+ totalColumns: number;
59
+ totalIndexes: number;
60
+ totalRelations: number;
61
+ };
62
+ }
63
+ /**
64
+ * JSON Schema format output
65
+ */
66
+ interface JsonSchemaOutput {
67
+ $schema: string;
68
+ $id?: string;
69
+ title: string;
70
+ description?: string;
71
+ definitions: Record<string, JsonSchemaDefinition>;
72
+ }
73
+ /**
74
+ * JSON Schema definition for a table
75
+ */
76
+ interface JsonSchemaDefinition {
77
+ type: 'object';
78
+ description?: string;
79
+ properties: Record<string, JsonSchemaProperty>;
80
+ required: string[];
81
+ additionalProperties: boolean;
82
+ }
83
+ /**
84
+ * JSON Schema property for a column
85
+ */
86
+ interface JsonSchemaProperty {
87
+ type: string | string[];
88
+ format?: string;
89
+ description?: string;
90
+ default?: unknown;
91
+ $ref?: string;
92
+ maxLength?: number;
93
+ minimum?: number;
94
+ maximum?: number;
95
+ }
96
+ /**
97
+ * TypeScript export options
98
+ */
99
+ interface TypeScriptExportOptions {
100
+ /**
101
+ * Include Zod schema generation
102
+ */
103
+ includeZod?: boolean;
104
+ /**
105
+ * Include insert types (NewTableName)
106
+ */
107
+ includeInsertTypes?: boolean;
108
+ /**
109
+ * Include select types (TableName)
110
+ */
111
+ includeSelectTypes?: boolean;
112
+ /**
113
+ * Generate barrel export file
114
+ */
115
+ generateBarrel?: boolean;
116
+ }
117
+ /**
118
+ * Mermaid ERD export options
119
+ */
120
+ interface MermaidExportOptions {
121
+ /**
122
+ * Include column data types
123
+ */
124
+ includeDataTypes?: boolean;
125
+ /**
126
+ * Include indexes as notes
127
+ */
128
+ includeIndexes?: boolean;
129
+ /**
130
+ * Show primary keys
131
+ */
132
+ showPrimaryKeys?: boolean;
133
+ /**
134
+ * Show foreign keys
135
+ */
136
+ showForeignKeys?: boolean;
137
+ /**
138
+ * Theme for the ERD
139
+ */
140
+ theme?: 'default' | 'dark' | 'forest' | 'neutral';
141
+ }
142
+ /**
143
+ * Export options
144
+ */
145
+ interface ExportOptions {
146
+ /**
147
+ * Export format
148
+ */
149
+ format: ExportFormat;
150
+ /**
151
+ * Project name for the export
152
+ */
153
+ projectName?: string;
154
+ /**
155
+ * Include metadata in export
156
+ */
157
+ includeMetadata?: boolean;
158
+ /**
159
+ * TypeScript-specific options
160
+ */
161
+ typescript?: TypeScriptExportOptions;
162
+ /**
163
+ * Mermaid-specific options
164
+ */
165
+ mermaid?: MermaidExportOptions;
166
+ }
167
+ /**
168
+ * Import options
169
+ */
170
+ interface ImportOptions {
171
+ /**
172
+ * Output directory for generated files
173
+ */
174
+ outputDir: string;
175
+ /**
176
+ * Overwrite existing files
177
+ */
178
+ overwrite?: boolean;
179
+ /**
180
+ * Generate tenant schemas
181
+ */
182
+ generateTenant?: boolean;
183
+ /**
184
+ * Generate shared schemas
185
+ */
186
+ generateShared?: boolean;
187
+ /**
188
+ * Include Zod validation schemas
189
+ */
190
+ includeZod?: boolean;
191
+ /**
192
+ * Include TypeScript types
193
+ */
194
+ includeTypes?: boolean;
195
+ /**
196
+ * Dry run - don't write files
197
+ */
198
+ dryRun?: boolean;
199
+ }
200
+ /**
201
+ * Import result
202
+ */
203
+ interface ImportResult {
204
+ success: boolean;
205
+ filesCreated: string[];
206
+ filesSkipped: string[];
207
+ errors: Array<{
208
+ file: string;
209
+ error: string;
210
+ }>;
211
+ }
212
+ /**
213
+ * Exporter interface
214
+ */
215
+ interface ISchemaExporter {
216
+ /**
217
+ * Export schemas to the specified format
218
+ */
219
+ export(tables: ExportedTable[], options: ExportOptions): string;
220
+ }
221
+ /**
222
+ * Importer interface
223
+ */
224
+ interface ISchemaImporter {
225
+ /**
226
+ * Import schemas from JSON and generate Drizzle schema files
227
+ */
228
+ import(schema: SchemaExport, options: ImportOptions): Promise<ImportResult>;
229
+ }
230
+
231
+ /**
232
+ * Schema Exporter
233
+ *
234
+ * Main exporter class that coordinates all export formats.
235
+ * Provides a unified interface for exporting Drizzle schemas
236
+ * to JSON Schema, TypeScript, or Mermaid ERD formats.
237
+ */
238
+
239
+ /**
240
+ * Schema Exporter Configuration
241
+ */
242
+ interface SchemaExporterConfig {
243
+ /**
244
+ * Directory containing tenant schemas
245
+ */
246
+ tenantSchemaDir?: string;
247
+ /**
248
+ * Directory containing shared schemas
249
+ */
250
+ sharedSchemaDir?: string;
251
+ /**
252
+ * Schema modules to export (alternative to directories)
253
+ */
254
+ schemas?: {
255
+ tenant?: Record<string, unknown>;
256
+ shared?: Record<string, unknown>;
257
+ };
258
+ }
259
+ /**
260
+ * Main Schema Exporter class
261
+ */
262
+ declare class SchemaExporter {
263
+ private jsonExporter;
264
+ private tsExporter;
265
+ private mermaidExporter;
266
+ /**
267
+ * Export schemas from directories
268
+ */
269
+ exportFromDirectories(config: {
270
+ tenantDir?: string;
271
+ sharedDir?: string;
272
+ }, options: ExportOptions): Promise<string>;
273
+ /**
274
+ * Export schemas from module objects
275
+ */
276
+ exportFromModules(schemas: {
277
+ tenant?: Record<string, unknown>;
278
+ shared?: Record<string, unknown>;
279
+ }, options: ExportOptions): string;
280
+ /**
281
+ * Export tables to the specified format
282
+ */
283
+ export(tables: ExportedTable[], options: ExportOptions): string;
284
+ /**
285
+ * Export to JSON format (internal schema format, not JSON Schema)
286
+ */
287
+ private exportToJson;
288
+ /**
289
+ * Export to JSON Schema format
290
+ */
291
+ exportToJsonSchema(tables: ExportedTable[], options: ExportOptions): string;
292
+ /**
293
+ * Export to TypeScript types
294
+ */
295
+ exportToTypeScript(tables: ExportedTable[], options: ExportOptions): string;
296
+ /**
297
+ * Export to Mermaid ERD
298
+ */
299
+ exportToMermaid(tables: ExportedTable[], options: ExportOptions): string;
300
+ /**
301
+ * Get supported export formats
302
+ */
303
+ getSupportedFormats(): ExportFormat[];
304
+ }
305
+ /**
306
+ * Create a schema exporter instance
307
+ */
308
+ declare function createSchemaExporter(): SchemaExporter;
309
+
310
+ /**
311
+ * JSON Schema Exporter
312
+ *
313
+ * Exports Drizzle schemas to JSON Schema format for documentation
314
+ * and cross-platform interoperability.
315
+ */
316
+
317
+ /**
318
+ * JSON Schema Exporter
319
+ */
320
+ declare class JsonSchemaExporter implements ISchemaExporter {
321
+ export(tables: ExportedTable[], options: ExportOptions): string;
322
+ }
323
+ /**
324
+ * Create a JSON Schema exporter instance
325
+ */
326
+ declare function createJsonSchemaExporter(): JsonSchemaExporter;
327
+
328
+ /**
329
+ * TypeScript Exporter
330
+ *
331
+ * Exports Drizzle schemas to TypeScript type definitions
332
+ * for use in other projects or for documentation.
333
+ */
334
+
335
+ /**
336
+ * TypeScript Exporter
337
+ */
338
+ declare class TypeScriptExporter implements ISchemaExporter {
339
+ export(tables: ExportedTable[], options: ExportOptions): string;
340
+ }
341
+ /**
342
+ * Create a TypeScript exporter instance
343
+ */
344
+ declare function createTypeScriptExporter(): TypeScriptExporter;
345
+
346
+ /**
347
+ * Mermaid ERD Exporter
348
+ *
349
+ * Exports Drizzle schemas to Mermaid ERD (Entity-Relationship Diagram)
350
+ * format for documentation and visualization.
351
+ */
352
+
353
+ /**
354
+ * Mermaid ERD Exporter
355
+ */
356
+ declare class MermaidExporter implements ISchemaExporter {
357
+ export(tables: ExportedTable[], options: ExportOptions): string;
358
+ /**
359
+ * Generate table definition in Mermaid ERD format
360
+ */
361
+ private generateTableDefinition;
362
+ /**
363
+ * Generate relationship lines
364
+ */
365
+ private generateRelationships;
366
+ }
367
+ /**
368
+ * Create a Mermaid exporter instance
369
+ */
370
+ declare function createMermaidExporter(): MermaidExporter;
371
+
372
+ /**
373
+ * Schema Importer
374
+ *
375
+ * Imports schema definitions from JSON and generates Drizzle ORM
376
+ * schema files. Useful for sharing schemas between projects or
377
+ * reconstructing schemas from documentation.
378
+ */
379
+
380
+ /**
381
+ * Schema Importer
382
+ */
383
+ declare class SchemaImporter implements ISchemaImporter {
384
+ import(schema: SchemaExport, options: ImportOptions): Promise<ImportResult>;
385
+ }
386
+ /**
387
+ * Create a schema importer instance
388
+ */
389
+ declare function createSchemaImporter(): SchemaImporter;
390
+ /**
391
+ * Load schema export from a JSON file
392
+ */
393
+ declare function loadSchemaExport(filePath: string): Promise<SchemaExport>;
394
+
395
+ export { type ColumnReference, type ExportFormat, type ExportOptions, type ExportedColumn, type ExportedIndex, type ExportedTable, type ISchemaExporter, type ISchemaImporter, type ImportOptions, type ImportResult, type JsonSchemaDefinition, JsonSchemaExporter, type JsonSchemaOutput, type JsonSchemaProperty, type MermaidExportOptions, MermaidExporter, type SchemaExport, SchemaExporter, type SchemaExporterConfig, SchemaImporter, type TypeScriptExportOptions, TypeScriptExporter, createJsonSchemaExporter, createMermaidExporter, createSchemaExporter, createSchemaImporter, createTypeScriptExporter, loadSchemaExport };
@@ -0,0 +1,9 @@
1
+ import {mkdir,writeFile,readFile,access}from'fs/promises';import {resolve,join}from'path';var F=Symbol.for("drizzle:Table"),_=Symbol.for("drizzle:Column");function A(n){if(!n||typeof n!="object")return false;let e=n;if(e._&&typeof e._=="object"){let t=e._;return typeof t.name=="string"&&(t.schema===void 0||typeof t.schema=="string")}return !!Object.getOwnPropertySymbols(e).some(t=>t===F)}function U(n){if(!n||typeof n!="object")return false;let e=n;return typeof e.name=="string"||typeof e.columnType=="string"||typeof e.dataType=="string"||Object.getOwnPropertySymbols(e).some(t=>t===_)}function q(n,e){let t=e.name??n,r="unknown";if(typeof e.dataType=="string")r=e.dataType;else if(typeof e.columnType=="string")r=e.columnType;else if(typeof e.getSQLType=="function")try{r=e.getSQLType();}catch{}let s=e.primary===true||e.isPrimaryKey===true||typeof e.primaryKey=="function"&&e._isPrimaryKey===true,i=e.notNull!==true&&e.isNotNull!==true,o=e.hasDefault===true||e.default!==void 0,a=e.default!==void 0?String(e.default):null,p;if(e.references&&typeof e.references=="object"){let u=e.references;p={table:u.table??"unknown",column:u.column??"unknown",onDelete:u.onDelete,onUpdate:u.onUpdate};}return {name:t,dataType:r,isPrimaryKey:s,isNullable:i,hasDefault:o,defaultValue:a,references:p}}function V(n){let e=[],t=n._indexes??n.indexes;if(t&&typeof t=="object")for(let[r,s]of Object.entries(t)){if(!s||typeof s!="object")continue;let i=s,o=[];if(Array.isArray(i.columns))for(let a of i.columns)typeof a=="string"?o.push(a):a&&typeof a=="object"&&"name"in a&&o.push(String(a.name));e.push({name:r,columns:o,isUnique:i.isUnique===true||i.unique===true});}return e}function b(n,e,t){let r=[];for(let[s,i]of Object.entries(n)){if(!A(i))continue;let o=i,p=o._?.name??s,u=[];for(let[m,l]of Object.entries(o)){if(m==="_"||m.startsWith("_")||!U(l))continue;let f=q(m,l);u.push(f);}let c=V(o);r.push({name:p,schemaType:t,columns:u,indexes:c,filePath:e});}return r}async function D(n,e){let{glob:t}=await import('glob'),{resolve:r}=await import('path'),s=r(n,"**/*.ts");return (await t(s,{ignore:["**/*.test.ts","**/*.spec.ts","**/node_modules/**"]})).map(o=>({filePath:o,type:e}))}async function N(n,e){try{let t=await import(n);return b(t,n,e)}catch(t){return console.warn(`Warning: Could not parse schema file ${n}:`,t.message),[]}}function Z(n){let e=n.toLowerCase();if(e==="uuid")return {type:"string",format:"uuid"};if(e==="text"||e==="string")return {type:"string"};if(e.startsWith("varchar")||e.startsWith("character varying")){let t=e.match(/\((\d+)\)/),r=t?.[1]?parseInt(t[1],10):void 0;return {type:"string",...r&&{maxLength:r}}}if(e.startsWith("char")||e.startsWith("character")){let t=e.match(/\((\d+)\)/),r=t?.[1]?parseInt(t[1],10):void 0;return {type:"string",...r&&{maxLength:r}}}return e==="integer"||e==="int"||e==="int4"?{type:"integer",minimum:-2147483648,maximum:2147483647}:e==="smallint"||e==="int2"?{type:"integer",minimum:-32768,maximum:32767}:e==="bigint"||e==="int8"?{type:"integer"}:e==="serial"||e==="serial4"?{type:"integer",minimum:1,maximum:2147483647}:e==="bigserial"||e==="serial8"?{type:"integer",minimum:1}:e==="smallserial"||e==="serial2"?{type:"integer",minimum:1,maximum:32767}:e==="real"||e==="float4"||e==="float"?{type:"number"}:e==="double precision"||e==="float8"||e==="double"?{type:"number"}:e.startsWith("numeric")||e.startsWith("decimal")?{type:"number"}:e==="boolean"||e==="bool"?{type:"boolean"}:e==="date"?{type:"string",format:"date"}:e.startsWith("timestamp")?{type:"string",format:"date-time"}:e==="time"||e.startsWith("time ")?{type:"string",format:"time"}:e==="interval"?{type:"string"}:e==="json"||e==="jsonb"?{type:["object","array","string","number","boolean","null"]}:e.endsWith("[]")?{type:"array"}:e.startsWith("enum")?{type:"string"}:e==="bytea"?{type:"string",format:"byte"}:e==="inet"||e==="cidr"?{type:"string"}:e==="macaddr"||e==="macaddr8"?{type:"string"}:{type:"string"}}function z(n){return n.split("_").map(e=>e.charAt(0).toUpperCase()+e.slice(1).toLowerCase()).join("")}function B(n){let e={},t=[];for(let r of n.columns){let i={...Z(r.dataType)};if(r.isPrimaryKey?i.description="Primary key":r.references&&(i.description=`Foreign key to ${r.references.table}.${r.references.column}`,i.$ref=`#/definitions/${z(r.references.table)}`),r.hasDefault&&r.defaultValue!=null&&r.defaultValue!==""){let o=r.defaultValue;o==="true"||o==="false"?i.default=o==="true":isNaN(Number(o))?o.startsWith("'")&&o.endsWith("'")&&(i.default=o.slice(1,-1)):i.default=Number(o);}r.isNullable&&typeof i.type=="string"&&(i.type=[i.type,"null"]),e[r.name]=i,!r.isNullable&&!r.hasDefault&&t.push(r.name);}return {type:"object",description:`Schema for ${n.name} table (${n.schemaType})`,properties:e,required:t,additionalProperties:false}}var h=class{export(e,t){let r={};for(let i of e){let o=z(i.name);r[o]=B(i);}let s={$schema:"http://json-schema.org/draft-07/schema#",...t.projectName&&{$id:`${t.projectName}/schemas`},title:t.projectName?`${t.projectName} Database Schemas`:"Database Schemas",description:"Auto-generated JSON Schema from Drizzle ORM schema definitions",definitions:r};return JSON.stringify(s,null,2)}};function Q(){return new h}function C(n,e){let t=n.toLowerCase(),r;if(t==="uuid")r="string";else if(t==="text"||t==="string")r="string";else if(t.startsWith("varchar")||t.startsWith("character varying")||t.startsWith("char")||t.startsWith("character"))r="string";else if(t==="integer"||t==="int"||t==="int4"||t==="smallint"||t==="int2"||t==="serial"||t==="serial4"||t==="smallserial"||t==="serial2")r="number";else if(t==="bigint"||t==="int8"||t==="bigserial"||t==="serial8")r="string";else if(t==="real"||t==="float4"||t==="float"||t==="double precision"||t==="float8"||t==="double"||t.startsWith("numeric")||t.startsWith("decimal"))r="number";else if(t==="boolean"||t==="bool")r="boolean";else if(t==="date")r="string";else if(t.startsWith("timestamp"))r="Date";else if(t==="time"||t.startsWith("time "))r="string";else if(t==="interval")r="string";else if(t==="json"||t==="jsonb")r="unknown";else if(t.endsWith("[]")){let s=t.slice(0,-2);r=`${C(s,false)}[]`;}else t.startsWith("enum")?r="string":t==="bytea"?r="Buffer":r="unknown";return e?`${r} | null`:r}function T(n){return n.split("_").map(e=>e.charAt(0).toUpperCase()+e.slice(1).toLowerCase()).join("")}function Y(n){let e=T(n);return e.charAt(0).toLowerCase()+e.slice(1)}function G(n){let e=[];return n.isPrimaryKey&&e.push("Primary key"),n.references&&e.push(`Foreign key to ${n.references.table}.${n.references.column}`),n.hasDefault&&n.defaultValue!==null&&e.push(`Default: ${n.defaultValue}`),e.length===0?null:e.length===1?` /** ${e[0]} */`:[" /**",...e.map(t=>` * ${t}`)," */"].join(`
2
+ `)}function W(n){let e=T(n.name),t=[];t.push("/**"),t.push(` * ${n.name} table schema (${n.schemaType})`),t.push(" */"),t.push(`export interface ${e} {`);for(let r of n.columns){let s=G(r);s&&t.push(s);let i=C(r.dataType,r.isNullable),o=r.hasDefault||r.isNullable?"?":"";t.push(` ${r.name}${o}: ${i};`);}return t.push("}"),t.join(`
3
+ `)}function P(n){let t=`New${T(n.name)}`,r=[];r.push("/**"),r.push(` * Insert type for ${n.name}`),r.push(" */"),r.push(`export interface ${t} {`);for(let s of n.columns){let i=C(s.dataType,s.isNullable),o=s.hasDefault||s.isNullable?"?":"";r.push(` ${s.name}${o}: ${i};`);}return r.push("}"),r.join(`
4
+ `)}function k(n){let e=`${Y(n.name)}Schema`,t=[];t.push("/**"),t.push(` * Zod schema for ${n.name}`),t.push(" */"),t.push(`export const ${e} = z.object({`);for(let r of n.columns){let s=R(r.dataType);r.isNullable&&(s=`${s}.nullable()`),r.hasDefault&&(s=`${s}.optional()`),t.push(` ${r.name}: ${s},`);}return t.push("});"),t.push(""),t.push(`export type ${T(n.name)}Validated = z.infer<typeof ${e}>;`),t.join(`
5
+ `)}function R(n){let e=n.toLowerCase();if(e==="uuid")return "z.string().uuid()";if(e==="text"||e==="string")return "z.string()";if(e.startsWith("varchar")||e.startsWith("character varying")||e.startsWith("char")){let t=e.match(/\((\d+)\)/);return t?`z.string().max(${t[1]})`:"z.string()"}if(e==="integer"||e==="int"||e==="int4"||e==="smallint"||e==="serial")return "z.number().int()";if(e==="bigint"||e==="int8"||e==="bigserial")return "z.string()";if(e==="real"||e==="float4"||e==="float"||e==="double precision"||e.startsWith("numeric")||e.startsWith("decimal"))return "z.number()";if(e==="boolean"||e==="bool")return "z.boolean()";if(e==="date")return "z.string().date()";if(e.startsWith("timestamp"))return "z.date()";if(e==="json"||e==="jsonb")return "z.unknown()";if(e.endsWith("[]")){let t=e.slice(0,-2);return `z.array(${R(t)})`}return "z.unknown()"}var d=class{export(e,t){let r=t.typescript??{},s=[];s.push("/**"),s.push(" * Auto-generated TypeScript types from Drizzle ORM schemas"),s.push(` * Generated at: ${new Date().toISOString()}`),t.projectName&&s.push(` * Project: ${t.projectName}`),s.push(" */"),s.push(""),r.includeZod&&(s.push("import { z } from 'zod';"),s.push(""));let i=e.filter(a=>a.schemaType==="tenant"),o=e.filter(a=>a.schemaType==="shared");if(i.length>0){s.push("// ================================"),s.push("// Tenant Schema Types"),s.push("// ================================"),s.push("");for(let a of i)r.includeSelectTypes!==false&&(s.push(W(a)),s.push("")),r.includeInsertTypes!==false&&(s.push(P(a)),s.push("")),r.includeZod&&(s.push(k(a)),s.push(""));}if(o.length>0){s.push("// ================================"),s.push("// Shared Schema Types"),s.push("// ================================"),s.push("");for(let a of o)r.includeSelectTypes!==false&&(s.push(W(a)),s.push("")),r.includeInsertTypes!==false&&(s.push(P(a)),s.push("")),r.includeZod&&(s.push(k(a)),s.push(""));}return s.join(`
6
+ `)}};function H(){return new d}function X(n){let e=n.toLowerCase();return e==="uuid"?"uuid":e==="text"||e==="string"?"text":e.startsWith("varchar")||e.startsWith("character varying")?"varchar":e.startsWith("char")||e.startsWith("character")?"char":e==="integer"||e==="int"||e==="int4"?"int":e==="smallint"||e==="int2"?"smallint":e==="bigint"||e==="int8"?"bigint":e==="serial"||e==="serial4"?"serial":e==="bigserial"||e==="serial8"?"bigserial":e==="real"||e==="float4"||e==="float"?"float":e==="double precision"||e==="float8"?"double":e.startsWith("numeric")||e.startsWith("decimal")?"decimal":e==="boolean"||e==="bool"?"bool":e==="date"?"date":e.startsWith("timestamp")?"timestamp":e==="time"||e.startsWith("time ")?"time":e==="json"||e==="jsonb"?"json":e==="bytea"?"binary":e}function ee(n){return n.isPrimaryKey&&n.references?"PK,FK":n.isPrimaryKey?"PK":n.references?"FK":""}function O(n){return n.replace(/[^a-zA-Z0-9_]/g,"_")}function te(n,e){return "||--o{"}var g=class{export(e,t){let r=t.mermaid??{},s=[];s.push("```mermaid"),r.theme&&r.theme!=="default"&&s.push(`%%{init: {'theme': '${r.theme}'}}%%`),s.push("erDiagram"),s.push("");let i=e.filter(p=>p.schemaType==="tenant"),o=e.filter(p=>p.schemaType==="shared");if(i.length>0){s.push(" %% Tenant Schema Tables");for(let p of i)s.push(...this.generateTableDefinition(p,r));s.push("");}if(o.length>0){s.push(" %% Shared Schema Tables");for(let p of o)s.push(...this.generateTableDefinition(p,r));s.push("");}let a=this.generateRelationships(e);return a.length>0&&(s.push(" %% Relationships"),s.push(...a)),s.push("```"),s.join(`
7
+ `)}generateTableDefinition(e,t){let r=[],s=O(e.name);r.push(` ${s} {`);for(let i of e.columns){let o=[];if(t.includeDataTypes!==false&&o.push(X(i.dataType)),o.push(i.name),t.showPrimaryKeys!==false||t.showForeignKeys!==false){let a=ee(i);a&&o.push(a);}i.isNullable&&o.push('"nullable"'),r.push(` ${o.join(" ")}`);}if(r.push(" }"),t.includeIndexes&&e.indexes.length>0){let i=e.indexes.map(o=>{let a=o.isUnique?"(unique)":"";return `${o.name}${a}`});r.push(` %% Indexes: ${i.join(", ")}`);}return r}generateRelationships(e){let t=[],r=new Map(e.map(s=>[s.name,s]));for(let s of e)for(let i of s.columns){if(!i.references||!r.get(i.references.table))continue;let a=O(s.name),p=O(i.references.table),u=te(),c=`"${i.name} -> ${i.references.column}"`;t.push(` ${p} ${u} ${a} : ${c}`);}return t}};function re(){return new g}function S(n){return {name:n.name,schemaType:n.schemaType,columns:n.columns,indexes:n.indexes,filePath:n.filePath}}var $=class{jsonExporter=new h;tsExporter=new d;mermaidExporter=new g;async exportFromDirectories(e,t){let r=[];if(e.tenantDir){let s=await D(e.tenantDir,"tenant");for(let i of s){let o=await N(i.filePath,"tenant");r.push(...o.map(S));}}if(e.sharedDir){let s=await D(e.sharedDir,"shared");for(let i of s){let o=await N(i.filePath,"shared");r.push(...o.map(S));}}return this.export(r,t)}exportFromModules(e,t){let r=[];if(e.tenant){let s=b(e.tenant,"tenant-schema","tenant");r.push(...s.map(S));}if(e.shared){let s=b(e.shared,"shared-schema","shared");r.push(...s.map(S));}return this.export(r,t)}export(e,t){switch(t.format){case "json":return this.exportToJson(e,t);case "typescript":return this.tsExporter.export(e,t);case "mermaid":return this.mermaidExporter.export(e,t);default:throw new Error(`Unknown export format: ${t.format}`)}}exportToJson(e,t){let r={version:"1.0.0",exportedAt:new Date().toISOString(),tables:e,...t.projectName&&{projectName:t.projectName}};if(t.includeMetadata){let s=e.filter(u=>u.schemaType==="tenant").length,i=e.filter(u=>u.schemaType==="shared").length,o=e.reduce((u,c)=>u+c.columns.length,0),a=e.reduce((u,c)=>u+c.indexes.length,0),p=e.reduce((u,c)=>u+c.columns.filter(m=>m.references).length,0);r.metadata={tenantCount:s,sharedCount:i,totalColumns:o,totalIndexes:a,totalRelations:p};}return JSON.stringify(r,null,2)}exportToJsonSchema(e,t){return this.jsonExporter.export(e,t)}exportToTypeScript(e,t){return this.tsExporter.export(e,t)}exportToMermaid(e,t){return this.mermaidExporter.export(e,t)}getSupportedFormats(){return ["json","typescript","mermaid"]}};function ne(){return new $}function M(n){let e=n.toLowerCase();if(e==="uuid")return {import:"uuid",usage:"uuid('$name')"};if(e==="text"||e==="string")return {import:"text",usage:"text('$name')"};if(e.startsWith("varchar")||e.startsWith("character varying")){let t=e.match(/\((\d+)\)/);return {import:"varchar",usage:`varchar('$name', { length: ${t?t[1]:"255"} })`}}if(e.startsWith("char")||e.startsWith("character")){let t=e.match(/\((\d+)\)/);return {import:"char",usage:`char('$name', { length: ${t?t[1]:"1"} })`}}if(e==="integer"||e==="int"||e==="int4")return {import:"integer",usage:"integer('$name')"};if(e==="smallint"||e==="int2")return {import:"smallint",usage:"smallint('$name')"};if(e==="bigint"||e==="int8")return {import:"bigint",usage:"bigint('$name', { mode: 'number' })"};if(e==="serial"||e==="serial4")return {import:"serial",usage:"serial('$name')"};if(e==="bigserial"||e==="serial8")return {import:"bigserial",usage:"bigserial('$name', { mode: 'number' })"};if(e==="real"||e==="float4"||e==="float")return {import:"real",usage:"real('$name')"};if(e==="double precision"||e==="float8"||e==="double")return {import:"doublePrecision",usage:"doublePrecision('$name')"};if(e.startsWith("numeric")||e.startsWith("decimal")){let t=e.match(/\((\d+)(?:,\s*(\d+))?\)/),r=t?.[1]??"10",s=t?.[2]??"2";return {import:"numeric",usage:`numeric('$name', { precision: ${r}, scale: ${s} })`}}return e==="boolean"||e==="bool"?{import:"boolean",usage:"boolean('$name')"}:e==="date"?{import:"date",usage:"date('$name')"}:e.startsWith("timestamp")?{import:"timestamp",usage:e.includes("with time zone")||e.includes("timestamptz")?"timestamp('$name', { withTimezone: true })":"timestamp('$name')"}:e==="time"||e.startsWith("time ")?{import:"time",usage:e.includes("with time zone")?"time('$name', { withTimezone: true })":"time('$name')"}:e==="json"?{import:"json",usage:"json('$name')"}:e==="jsonb"?{import:"jsonb",usage:"jsonb('$name')"}:e==="bytea"?{import:"customType",usage:"bytea('$name')"}:{import:"text",usage:"text('$name')"}}function x(n){return n.split("_").map(e=>e.charAt(0).toUpperCase()+e.slice(1).toLowerCase()).join("")}function w(n){let e=x(n);return e.charAt(0).toLowerCase()+e.slice(1)}function J(n,e){let t=[],r=new Set;r.add("pgTable");for(let a of n.columns){let{import:p}=M(a.dataType);r.add(p);}n.indexes.length>0&&(r.add("index"),n.indexes.some(p=>p.isUnique)&&r.add("uniqueIndex")),t.push("/**"),t.push(` * ${n.name} schema`),t.push(" * Auto-generated from schema import"),t.push(` * Schema type: ${n.schemaType}`),t.push(" */"),t.push(""),t.push(`import { ${Array.from(r).sort().join(", ")} } from 'drizzle-orm/pg-core';`),e.includeZod&&(t.push("import { createInsertSchema, createSelectSchema } from 'drizzle-zod';"),t.push("import { z } from 'zod';")),t.push("");let s=n.columns.filter(a=>a.references).map(a=>a.references);if(s.length>0){let a=[...new Set(s.map(p=>p.table))];for(let p of a)p!==n.name&&(t.push(`// TODO: Adjust import path for ${p}`),t.push(`// import { ${w(p)} } from './${p}';`));t.push("");}let i=w(n.name);t.push(`export const ${i} = pgTable('${n.name}', {`);let o=n.columns.length;if(n.columns.forEach((a,p)=>{let{usage:u}=M(a.dataType),c=p===o-1,m=u.replace("$name",a.name),l=[];if(a.isPrimaryKey&&(l.push(".primaryKey()"),a.dataType.toLowerCase()==="uuid"&&l.push(".defaultRandom()")),!a.isNullable&&!a.isPrimaryKey&&l.push(".notNull()"),a.hasDefault&&a.defaultValue!=null&&a.defaultValue!==""&&!a.isPrimaryKey){let f=a.defaultValue;f==="now()"||f==="CURRENT_TIMESTAMP"?l.push(".defaultNow()"):f==="true"||f==="false"?l.push(`.default(${f})`):isNaN(Number(f))?f.startsWith("'")&&f.endsWith("'")&&l.push(`.default(${f})`):l.push(`.default(${f})`);}a.references&&l.push(`// .references(() => ${w(a.references.table)}.${a.references.column})`),m+=l.join(""),t.push(` ${a.name}: ${m}${c?"":","}`);}),t.push("});"),t.push(""),n.indexes.length>0){t.push(`export const ${i}Indexes = {`);let a=n.indexes.length;n.indexes.forEach((p,u)=>{let c=u===a-1,m=p.isUnique?"uniqueIndex":"index",l=p.columns.map(f=>`${i}.${f}`).join(", ");t.push(` ${w(p.name)}: ${m}('${p.name}').on(${l})${c?"":","}`);}),t.push("};"),t.push("");}return e.includeZod&&(t.push(`export const insert${x(n.name)}Schema = createInsertSchema(${i});`),t.push(`export const select${x(n.name)}Schema = createSelectSchema(${i});`),t.push("")),e.includeTypes!==false&&(t.push(`export type ${x(n.name)} = typeof ${i}.$inferSelect;`),t.push(`export type New${x(n.name)} = typeof ${i}.$inferInsert;`)),t.join(`
8
+ `)}function L(n){let e=[];e.push("/**"),e.push(" * Barrel export for all schema files"),e.push(" * Auto-generated from schema import"),e.push(" */"),e.push("");for(let t of n)e.push(`export * from './${t.name}';`);return e.join(`
9
+ `)}async function j(n){try{return await access(n),!0}catch{return false}}var I=class{async import(e,t){let r={success:true,filesCreated:[],filesSkipped:[],errors:[]},s=resolve(t.outputDir),i=join(s,"tenant"),o=join(s,"shared");t.dryRun||(await mkdir(i,{recursive:true}),await mkdir(o,{recursive:true}));let a=e.tables.filter(u=>u.schemaType==="tenant"),p=e.tables.filter(u=>u.schemaType==="shared");if(t.generateTenant!==false){for(let u of a){let c=join(i,`${u.name}.ts`);try{if(!t.overwrite&&await j(c)){r.filesSkipped.push(c);continue}let m=J(u,t);t.dryRun||await writeFile(c,m,"utf-8"),r.filesCreated.push(c);}catch(m){r.success=false,r.errors.push({file:c,error:m.message});}}if(a.length>0){let u=join(i,"index.ts");try{if(t.overwrite||!await j(u)){let c=L(a);t.dryRun||await writeFile(u,c,"utf-8"),r.filesCreated.push(u);}else r.filesSkipped.push(u);}catch(c){r.errors.push({file:u,error:c.message});}}}if(t.generateShared!==false){for(let u of p){let c=join(o,`${u.name}.ts`);try{if(!t.overwrite&&await j(c)){r.filesSkipped.push(c);continue}let m=J(u,t);t.dryRun||await writeFile(c,m,"utf-8"),r.filesCreated.push(c);}catch(m){r.success=false,r.errors.push({file:c,error:m.message});}}if(p.length>0){let u=join(o,"index.ts");try{if(t.overwrite||!await j(u)){let c=L(p);t.dryRun||await writeFile(u,c,"utf-8"),r.filesCreated.push(u);}else r.filesSkipped.push(u);}catch(c){r.errors.push({file:u,error:c.message});}}}return r}};function ae(){return new I}async function oe(n){let e=await readFile(resolve(n),"utf-8");return JSON.parse(e)}export{h as JsonSchemaExporter,g as MermaidExporter,$ as SchemaExporter,I as SchemaImporter,d as TypeScriptExporter,Q as createJsonSchemaExporter,re as createMermaidExporter,ne as createSchemaExporter,ae as createSchemaImporter,H as createTypeScriptExporter,oe as loadSchemaExport};
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
- import { C as Config, T as TenantManager, R as RetryConfig } from './types-BhK96FPC.js';
2
- export { b as ConnectionConfig, n as ConnectionMetrics, o as DEFAULT_CONFIG, D as DebugConfig, e as DebugContext, h as HealthCheckOptions, i as HealthCheckResult, H as Hooks, I as IsolationConfig, c as IsolationStrategy, M as MetricsConfig, l as MetricsResult, P as PoolEntry, j as PoolHealth, k as PoolHealthStatus, d as SchemasConfig, S as SharedDb, a as TenantDb, m as TenantPoolMetrics, g as TenantWarmupResult, W as WarmupOptions, f as WarmupResult } from './types-BhK96FPC.js';
3
- export { B as BaseTenantContext, a as TenantContext, T as TenantContextData, c as createTenantContext } from './context-Vki959ri.js';
4
- export { A as AppliedMigration, C as CreateTenantOptions, D as DropTenantOptions, d as MigrateOptions, i as MigrationErrorHandler, b as MigrationFile, g as MigrationHooks, h as MigrationProgressCallback, e as MigrationResults, M as Migrator, a as MigratorConfig, S as SeedFunction, j as SeedOptions, l as SeedResults, T as TenantMigrationResult, f as TenantMigrationStatus, k as TenantSeedResult, c as createMigrator } from './migrator-BDgFzSh8.js';
1
+ import { C as Config, T as TenantManager, R as RetryConfig } from './types-CGqsPe2Q.js';
2
+ export { b as ConnectionConfig, n as ConnectionMetrics, q as DEFAULT_CONFIG, D as DebugConfig, e as DebugContext, h as HealthCheckOptions, i as HealthCheckResult, H as Hooks, I as IsolationConfig, c as IsolationStrategy, p as LintConfig, L as LintRuleConfig, o as LintRulesConfig, M as MetricsConfig, l as MetricsResult, P as PoolEntry, j as PoolHealth, k as PoolHealthStatus, d as SchemasConfig, S as SharedDb, a as TenantDb, m as TenantPoolMetrics, g as TenantWarmupResult, W as WarmupOptions, f as WarmupResult } from './types-CGqsPe2Q.js';
3
+ export { B as BaseTenantContext, a as TenantContext, T as TenantContextData, c as createTenantContext } from './context-BBLPNjmk.js';
4
+ export { A as AppliedMigration, C as CreateTenantOptions, D as DropTenantOptions, d as MigrateOptions, i as MigrationErrorHandler, b as MigrationFile, g as MigrationHooks, h as MigrationProgressCallback, e as MigrationResults, M as Migrator, a as MigratorConfig, S as SeedFunction, j as SeedOptions, l as SeedResults, m as SharedSeedFunction, n as SharedSeedResult, T as TenantMigrationResult, f as TenantMigrationStatus, k as TenantSeedResult, c as createMigrator } from './migrator-C7FtsZ0H.js';
5
5
  export { ColumnSelection, CrossSchemaContext, CrossSchemaQueryBuilder, CrossSchemaRawOptions, InferSelectResult, InferSelectedColumns, JoinCondition, JoinDefinition, JoinType, LookupResult, SchemaSource, SharedLookupConfig, TableReference, WithSharedConfig, WithSharedOptions, WithSharedQueryBuilder, buildCrossSchemaSelect, createCrossSchemaQuery, crossSchemaRaw, withShared, withSharedLookup } from './cross-schema/index.js';
6
6
  import 'pg';
7
7
  import 'drizzle-orm/node-postgres';