drizzle-multitenant 1.2.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +28 -8
- package/dist/cli/index.js +1809 -5949
- package/dist/{context-Vki959ri.d.ts → context-BBLPNjmk.d.ts} +1 -1
- package/dist/cross-schema/index.js +1 -426
- package/dist/export/index.d.ts +395 -0
- package/dist/export/index.js +9 -0
- package/dist/index.d.ts +4 -4
- package/dist/index.js +34 -4745
- package/dist/integrations/express.d.ts +3 -3
- package/dist/integrations/express.js +1 -110
- package/dist/integrations/fastify.d.ts +3 -3
- package/dist/integrations/fastify.js +1 -236
- package/dist/integrations/hono.js +0 -3
- package/dist/integrations/nestjs/index.d.ts +1 -1
- package/dist/integrations/nestjs/index.js +3 -11006
- package/dist/lint/index.d.ts +475 -0
- package/dist/lint/index.js +5 -0
- package/dist/metrics/index.d.ts +530 -0
- package/dist/metrics/index.js +3 -0
- package/dist/migrator/index.d.ts +116 -4
- package/dist/migrator/index.js +34 -2990
- package/dist/{migrator-BDgFzSh8.d.ts → migrator-B7oPKe73.d.ts} +245 -2
- package/dist/scaffold/index.d.ts +330 -0
- package/dist/scaffold/index.js +277 -0
- package/dist/{types-BhK96FPC.d.ts → types-CGqsPe2Q.d.ts} +49 -1
- package/package.json +18 -1
- package/dist/cli/index.js.map +0 -1
- package/dist/cross-schema/index.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/integrations/express.js.map +0 -1
- package/dist/integrations/fastify.js.map +0 -1
- package/dist/integrations/hono.js.map +0 -1
- package/dist/integrations/nestjs/index.js.map +0 -1
- package/dist/migrator/index.js.map +0 -1
|
@@ -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-
|
|
2
|
-
export { b as ConnectionConfig, n as ConnectionMetrics,
|
|
3
|
-
export { B as BaseTenantContext, a as TenantContext, T as TenantContextData, c as createTenantContext } from './context-
|
|
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-
|
|
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-B7oPKe73.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';
|