mutano 2.6.6 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +154 -0
- package/dist/main.js +2 -6
- package/package.json +11 -9
package/README.md
CHANGED
|
@@ -5,11 +5,13 @@ Converts Prisma/MySQL/PostgreSQL/SQLite schemas to Zod schemas, TypeScript inter
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
7
|
- Generates Zod schemas, Typescript interfaces or Kysely type definitions for MySQL, PostgreSQL, SQLite, and Prisma schemas
|
|
8
|
+
- **NEW: Database Views Support** - Extract and generate types for database views (read-only)
|
|
8
9
|
- Supports camelCase conversion
|
|
9
10
|
- Handles nullable, default, auto-increment and enum fields
|
|
10
11
|
- Supports custom type overrides via configuration or database comments
|
|
11
12
|
- Intelligently handles field nullability based on operation type (table, insertable, updateable, selectable)
|
|
12
13
|
- All fields in updateable schemas are automatically made optional
|
|
14
|
+
- Views are treated as read-only entities (no insertable/updateable schemas generated)
|
|
13
15
|
|
|
14
16
|
## Installation
|
|
15
17
|
|
|
@@ -278,8 +280,104 @@ await generate({
|
|
|
278
280
|
|
|
279
281
|
This will generate all three types of output files for each table in your database, placing them in separate folders with appropriate suffixes.
|
|
280
282
|
|
|
283
|
+
### Database Views Example
|
|
284
|
+
|
|
285
|
+
```typescript
|
|
286
|
+
import { generate } from 'mutano'
|
|
287
|
+
|
|
288
|
+
await generate({
|
|
289
|
+
origin: {
|
|
290
|
+
type: 'mysql',
|
|
291
|
+
host: '127.0.0.1',
|
|
292
|
+
port: 3306,
|
|
293
|
+
user: 'root',
|
|
294
|
+
password: 'secret',
|
|
295
|
+
database: 'myapp'
|
|
296
|
+
},
|
|
297
|
+
destinations: [{
|
|
298
|
+
type: 'zod',
|
|
299
|
+
folder: './generated/schemas',
|
|
300
|
+
suffix: 'schema'
|
|
301
|
+
}],
|
|
302
|
+
includeViews: true, // Enable views processing
|
|
303
|
+
views: ['user_profile_view', 'order_summary_view'], // Optional: specify which views to include
|
|
304
|
+
ignoreViews: ['temp_view'] // Optional: specify which views to ignore
|
|
305
|
+
})
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
**Database Views Features:**
|
|
309
|
+
- **Read-only**: Views generate only selectable schemas (no insertable/updateable)
|
|
310
|
+
- **All database types**: Supports MySQL, PostgreSQL, SQLite, and Prisma views
|
|
311
|
+
- **Filtering**: Use `views` and `ignoreViews` options to control which views are processed
|
|
312
|
+
- **Type safety**: Full TypeScript/Zod/Kysely type generation for view columns
|
|
313
|
+
- **Prisma integration**: Automatically detects `view` blocks in Prisma schema files
|
|
314
|
+
|
|
315
|
+
### Prisma Views Integration
|
|
316
|
+
|
|
317
|
+
Mutano automatically detects and processes `view` blocks in your Prisma schema:
|
|
318
|
+
|
|
319
|
+
```prisma
|
|
320
|
+
// schema.prisma
|
|
321
|
+
generator client {
|
|
322
|
+
provider = "prisma-client-js"
|
|
323
|
+
previewFeatures = ["views"]
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
model User {
|
|
327
|
+
id Int @id @default(autoincrement())
|
|
328
|
+
email String @unique
|
|
329
|
+
name String?
|
|
330
|
+
profile Profile?
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
model Profile {
|
|
334
|
+
id Int @id @default(autoincrement())
|
|
335
|
+
bio String
|
|
336
|
+
user User @relation(fields: [userId], references: [id])
|
|
337
|
+
userId Int @unique
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
// This view will be automatically processed by Mutano
|
|
341
|
+
view UserInfo {
|
|
342
|
+
id Int
|
|
343
|
+
email String
|
|
344
|
+
name String?
|
|
345
|
+
bio String?
|
|
346
|
+
}
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
```typescript
|
|
350
|
+
// Generate types from Prisma schema with views
|
|
351
|
+
await generate({
|
|
352
|
+
origin: {
|
|
353
|
+
type: 'prisma',
|
|
354
|
+
path: './schema.prisma'
|
|
355
|
+
},
|
|
356
|
+
destinations: [{
|
|
357
|
+
type: 'zod',
|
|
358
|
+
useDateType: true
|
|
359
|
+
}],
|
|
360
|
+
includeViews: true
|
|
361
|
+
})
|
|
362
|
+
```
|
|
363
|
+
|
|
281
364
|
The generator will create `user.type.ts`, `user.schema.ts`, and `user.db.ts` files with the following contents:
|
|
282
365
|
|
|
366
|
+
### Database View Output Examples
|
|
367
|
+
|
|
368
|
+
For a database view like:
|
|
369
|
+
```sql
|
|
370
|
+
CREATE VIEW user_profile_view AS
|
|
371
|
+
SELECT
|
|
372
|
+
u.id,
|
|
373
|
+
u.name,
|
|
374
|
+
u.email,
|
|
375
|
+
p.bio,
|
|
376
|
+
p.avatar_url
|
|
377
|
+
FROM users u
|
|
378
|
+
LEFT JOIN profiles p ON u.id = p.user_id;
|
|
379
|
+
```
|
|
380
|
+
|
|
283
381
|
### Zod Schema Output Example with Custom Header
|
|
284
382
|
|
|
285
383
|
```typescript
|
|
@@ -415,6 +513,56 @@ export type NewUser = Insertable<UserTable>;
|
|
|
415
513
|
export type UserUpdate = Updateable<UserTable>;
|
|
416
514
|
```
|
|
417
515
|
|
|
516
|
+
### View Output Examples
|
|
517
|
+
|
|
518
|
+
#### Zod Schema for Views (Read-only)
|
|
519
|
+
|
|
520
|
+
```typescript
|
|
521
|
+
import { z } from 'zod';
|
|
522
|
+
|
|
523
|
+
// View schema (read-only)
|
|
524
|
+
export const user_profile_view = z.object({
|
|
525
|
+
id: z.number().nonnegative(),
|
|
526
|
+
name: z.string(),
|
|
527
|
+
email: z.string(),
|
|
528
|
+
bio: z.string().nullable(),
|
|
529
|
+
avatar_url: z.string().nullable(),
|
|
530
|
+
})
|
|
531
|
+
|
|
532
|
+
export type UserProfileViewType = z.infer<typeof user_profile_view>
|
|
533
|
+
```
|
|
534
|
+
|
|
535
|
+
#### TypeScript Interface for Views (Read-only)
|
|
536
|
+
|
|
537
|
+
```typescript
|
|
538
|
+
// TypeScript interface for user_profile_view (view - read-only)
|
|
539
|
+
export interface UserProfileView {
|
|
540
|
+
id: number;
|
|
541
|
+
name: string;
|
|
542
|
+
email: string;
|
|
543
|
+
bio: string | null;
|
|
544
|
+
avatar_url: string | null;
|
|
545
|
+
}
|
|
546
|
+
```
|
|
547
|
+
|
|
548
|
+
#### Kysely Type Definitions for Views (Read-only)
|
|
549
|
+
|
|
550
|
+
```typescript
|
|
551
|
+
// Kysely type definitions for user_profile_view (view)
|
|
552
|
+
|
|
553
|
+
// This interface defines the structure of the 'user_profile_view' view (read-only)
|
|
554
|
+
export interface UserProfileView {
|
|
555
|
+
id: number;
|
|
556
|
+
name: string;
|
|
557
|
+
email: string;
|
|
558
|
+
bio: string | null;
|
|
559
|
+
avatar_url: string | null;
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
// Helper types for user_profile_view (view - read-only)
|
|
563
|
+
export type SelectableUserProfileView = Selectable<UserProfileView>;
|
|
564
|
+
```
|
|
565
|
+
|
|
418
566
|
## Config
|
|
419
567
|
|
|
420
568
|
```json
|
|
@@ -490,7 +638,10 @@ export type UserUpdate = Updateable<UserTable>;
|
|
|
490
638
|
}
|
|
491
639
|
],
|
|
492
640
|
"tables": ["user", "log"],
|
|
641
|
+
"views": ["user_profile_view", "order_summary"],
|
|
493
642
|
"ignore": ["log", "/^temp/"],
|
|
643
|
+
"ignoreViews": ["temp_view", "/^debug_/"],
|
|
644
|
+
"includeViews": true,
|
|
494
645
|
"camelCase": false,
|
|
495
646
|
"silent": false,
|
|
496
647
|
"dryRun": false,
|
|
@@ -515,7 +666,10 @@ export type UserUpdate = Updateable<UserTable>;
|
|
|
515
666
|
| destinations[].suffix | Suffix to the name of a generated file (eg: `user.table.ts`) |
|
|
516
667
|
| destinations[].outFile | (Kysely only) Specify the output file for the generated content. All tables will be written to this file |
|
|
517
668
|
| tables | Filter the tables to include only those specified |
|
|
669
|
+
| views | Filter the views to include only those specified (requires `includeViews: true`) |
|
|
518
670
|
| ignore | Filter the tables to exclude those specified. If a table name begins and ends with "/", it will be processed as a regular expression |
|
|
671
|
+
| ignoreViews | Filter the views to exclude those specified. If a view name begins and ends with "/", it will be processed as a regular expression |
|
|
672
|
+
| includeViews | When true, database views will be processed and included in the output. Views are read-only (no insertable/updateable schemas) |
|
|
519
673
|
| camelCase | Convert all table names and their properties to camelcase. (eg: `profile_picture` becomes `profilePicture`) |
|
|
520
674
|
| silent | Don't log anything to the console |
|
|
521
675
|
| dryRun | When true, doesn't write files to disk but returns an object with filenames as keys and generated content as values |
|
package/dist/main.js
CHANGED
|
@@ -506,9 +506,7 @@ export type ${camelCase(table, { pascalCase: true })} = {`;
|
|
|
506
506
|
`;
|
|
507
507
|
} else if (destination.type === "zod") {
|
|
508
508
|
const header = destination.header;
|
|
509
|
-
content = header ?
|
|
510
|
-
|
|
511
|
-
` : defaultZodHeader2(destination.version || 3);
|
|
509
|
+
content = header ? header + "\n\n" : defaultZodHeader2(destination.version || 3);
|
|
512
510
|
content += `export const ${table} = z.object({`;
|
|
513
511
|
for (const desc of describes) {
|
|
514
512
|
const field = isCamelCase ? camelCase(desc.Field) : desc.Field;
|
|
@@ -574,9 +572,7 @@ export type Selectable${camelCase(`${table}Type`, {
|
|
|
574
572
|
return content;
|
|
575
573
|
}
|
|
576
574
|
const defaultKyselyHeader = "import { ColumnType, Selectable, Insertable, Updateable } from 'kysely';\n\n";
|
|
577
|
-
const defaultZodHeader = (version) =>
|
|
578
|
-
|
|
579
|
-
`;
|
|
575
|
+
const defaultZodHeader = (version) => "import { z } from 'zod" + (version === 3 ? "" : "/v4") + "';\n\n";
|
|
580
576
|
async function generate(config) {
|
|
581
577
|
let tables = [];
|
|
582
578
|
let prismaTables = [];
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mutano",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "3.0.0",
|
|
5
5
|
"description": "Converts Prisma/MySQL/PostgreSQL/SQLite schemas to Zod/TS/Kysely interfaces",
|
|
6
6
|
"author": "Alisson Cavalcante Agiani <thelinuxlich@gmail.com>",
|
|
7
7
|
"license": "MIT",
|
|
@@ -14,20 +14,22 @@
|
|
|
14
14
|
"test": "vitest run"
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
|
-
"@mrleebo/prisma-ast": "^0.
|
|
17
|
+
"@mrleebo/prisma-ast": "^0.13.0",
|
|
18
18
|
"camelcase": "^8.0.0",
|
|
19
|
-
"fs-extra": "^11.3.
|
|
19
|
+
"fs-extra": "^11.3.2",
|
|
20
20
|
"knex": "^3.1.0",
|
|
21
|
-
"mysql2": "^3.14.
|
|
22
|
-
"pg": "^8.16.
|
|
21
|
+
"mysql2": "^3.14.4",
|
|
22
|
+
"pg": "^8.16.3",
|
|
23
23
|
"sqlite3": "^5.1.7"
|
|
24
24
|
},
|
|
25
25
|
"devDependencies": {
|
|
26
|
+
"@electric-sql/pglite": "^0.3.8",
|
|
26
27
|
"@types/fs-extra": "^11.0.4",
|
|
27
|
-
"
|
|
28
|
+
"@types/pg": "^8.15.5",
|
|
29
|
+
"esbuild": "^0.25.9",
|
|
28
30
|
"ts-node": "^10.9.2",
|
|
29
|
-
"tsx": "
|
|
30
|
-
"typescript": "^5.
|
|
31
|
-
"vitest": "^3.
|
|
31
|
+
"tsx": "4.19.4",
|
|
32
|
+
"typescript": "^5.9.2",
|
|
33
|
+
"vitest": "^3.2.4"
|
|
32
34
|
}
|
|
33
35
|
}
|