mutano 2.0.0 → 2.1.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 +12 -140
- package/dist/main.js +6 -2
- package/package.json +3 -1
package/README.md
CHANGED
|
@@ -9,6 +9,7 @@ Converts Prisma/MySQL/PostgreSQL/SQLite schemas to Zod schemas, TypeScript inter
|
|
|
9
9
|
- Handles nullable, default, auto-increment and enum fields
|
|
10
10
|
- Supports custom type overrides via configuration or database comments
|
|
11
11
|
- Intelligently handles field nullability based on operation type (table, insertable, updateable, selectable)
|
|
12
|
+
- All fields in updateable schemas are automatically made optional
|
|
12
13
|
|
|
13
14
|
## Installation
|
|
14
15
|
|
|
@@ -57,7 +58,7 @@ await generate({
|
|
|
57
58
|
type: 'zod',
|
|
58
59
|
useDateType: true,
|
|
59
60
|
useTrim: false,
|
|
60
|
-
nullish: false,
|
|
61
|
+
nullish: false, // When true, nullable fields use nullish() instead of nullable()
|
|
61
62
|
folder: './generated',
|
|
62
63
|
suffix: 'schema'
|
|
63
64
|
}]
|
|
@@ -303,16 +304,16 @@ export const insertable_user = z.object({
|
|
|
303
304
|
})
|
|
304
305
|
|
|
305
306
|
export const updateable_user = z.object({
|
|
306
|
-
name: z.string().min(10).max(255),
|
|
307
|
-
username: z.string(),
|
|
308
|
-
password: z.string(),
|
|
309
|
-
profile_picture: z.string().nullable(),
|
|
310
|
-
role: z.enum(['admin', 'user']),
|
|
307
|
+
name: z.string().min(10).max(255).optional(),
|
|
308
|
+
username: z.string().optional(),
|
|
309
|
+
password: z.string().optional(),
|
|
310
|
+
profile_picture: z.string().nullable().optional(),
|
|
311
|
+
role: z.enum(['admin', 'user']).optional(),
|
|
311
312
|
})
|
|
312
313
|
|
|
313
314
|
export const selectable_user = z.object({
|
|
314
315
|
id: z.number().nonnegative(),
|
|
315
|
-
name: z.string()
|
|
316
|
+
name: z.string(),
|
|
316
317
|
username: z.string(),
|
|
317
318
|
password: z.string(),
|
|
318
319
|
profile_picture: z.string().nullable(),
|
|
@@ -372,92 +373,6 @@ export interface SelectableUser {
|
|
|
372
373
|
}
|
|
373
374
|
```
|
|
374
375
|
|
|
375
|
-
### TypeScript Interface Output Example (Enum Type for Enums)
|
|
376
|
-
|
|
377
|
-
```typescript
|
|
378
|
-
// TypeScript interfaces for user
|
|
379
|
-
|
|
380
|
-
// Enum declarations
|
|
381
|
-
enum RoleEnum {
|
|
382
|
-
admin = 'admin',
|
|
383
|
-
user = 'user'
|
|
384
|
-
}
|
|
385
|
-
|
|
386
|
-
export interface User {
|
|
387
|
-
id: number;
|
|
388
|
-
name: string;
|
|
389
|
-
username: string;
|
|
390
|
-
password: string;
|
|
391
|
-
profile_picture: string | null;
|
|
392
|
-
role: RoleEnum;
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
export interface InsertableUser {
|
|
396
|
-
name: string | null; // Optional because it has a default value
|
|
397
|
-
username: string;
|
|
398
|
-
password: string;
|
|
399
|
-
profile_picture: string | null;
|
|
400
|
-
role: RoleEnum;
|
|
401
|
-
}
|
|
402
|
-
|
|
403
|
-
export interface UpdateableUser {
|
|
404
|
-
name: string | null; // Optional for updates
|
|
405
|
-
username: string | null; // Optional for updates
|
|
406
|
-
password: string | null; // Optional for updates
|
|
407
|
-
profile_picture: string | null;
|
|
408
|
-
role: RoleEnum | null; // Optional for updates
|
|
409
|
-
}
|
|
410
|
-
|
|
411
|
-
export interface SelectableUser {
|
|
412
|
-
id: number;
|
|
413
|
-
name: string;
|
|
414
|
-
username: string;
|
|
415
|
-
password: string;
|
|
416
|
-
profile_picture: string | null;
|
|
417
|
-
role: RoleEnum;
|
|
418
|
-
}
|
|
419
|
-
```
|
|
420
|
-
|
|
421
|
-
### TypeScript Type Alias Output Example
|
|
422
|
-
|
|
423
|
-
```typescript
|
|
424
|
-
// TypeScript types for user
|
|
425
|
-
|
|
426
|
-
export type User = {
|
|
427
|
-
id: number;
|
|
428
|
-
name: string;
|
|
429
|
-
username: string;
|
|
430
|
-
password: string;
|
|
431
|
-
profile_picture: string | null;
|
|
432
|
-
role: 'admin' | 'user';
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
export type InsertableUser = {
|
|
436
|
-
name: string | null; // Optional because it has a default value
|
|
437
|
-
username: string;
|
|
438
|
-
password: string;
|
|
439
|
-
profile_picture: string | null;
|
|
440
|
-
role: 'admin' | 'user';
|
|
441
|
-
}
|
|
442
|
-
|
|
443
|
-
export type UpdateableUser = {
|
|
444
|
-
name: string | null; // Optional for updates
|
|
445
|
-
username: string | null; // Optional for updates
|
|
446
|
-
password: string | null; // Optional for updates
|
|
447
|
-
profile_picture: string | null;
|
|
448
|
-
role: 'admin' | 'user' | null; // Optional for updates
|
|
449
|
-
}
|
|
450
|
-
|
|
451
|
-
export type SelectableUser = {
|
|
452
|
-
id: number;
|
|
453
|
-
name: string;
|
|
454
|
-
username: string;
|
|
455
|
-
password: string;
|
|
456
|
-
profile_picture: string | null;
|
|
457
|
-
role: 'admin' | 'user';
|
|
458
|
-
}
|
|
459
|
-
```
|
|
460
|
-
|
|
461
376
|
### Kysely Type Definitions Output Example
|
|
462
377
|
|
|
463
378
|
```typescript
|
|
@@ -500,49 +415,6 @@ export type NewUser = Insertable<UserTable>;
|
|
|
500
415
|
export type UserUpdate = Updateable<UserTable>;
|
|
501
416
|
```
|
|
502
417
|
|
|
503
|
-
### Kysely Type Definitions Output Example with Custom Schema Name
|
|
504
|
-
|
|
505
|
-
```typescript
|
|
506
|
-
import { Generated, ColumnType, Selectable, Insertable, Updateable } from 'kysely';
|
|
507
|
-
import { CustomTypes } from './types';
|
|
508
|
-
|
|
509
|
-
// JSON type definitions
|
|
510
|
-
export type Json = ColumnType<JsonValue, string, string>;
|
|
511
|
-
|
|
512
|
-
export type JsonArray = JsonValue[];
|
|
513
|
-
|
|
514
|
-
export type JsonObject = {
|
|
515
|
-
[x: string]: JsonValue | undefined;
|
|
516
|
-
};
|
|
517
|
-
|
|
518
|
-
export type JsonPrimitive = boolean | number | string | null;
|
|
519
|
-
|
|
520
|
-
export type JsonValue = JsonArray | JsonObject | JsonPrimitive;
|
|
521
|
-
|
|
522
|
-
// Kysely type definitions for user
|
|
523
|
-
|
|
524
|
-
// This interface defines the structure of the 'user' table
|
|
525
|
-
export interface UserTable {
|
|
526
|
-
id: Generated<number>;
|
|
527
|
-
name: string;
|
|
528
|
-
username: string;
|
|
529
|
-
password: string;
|
|
530
|
-
profile_picture: string | null;
|
|
531
|
-
metadata: Json;
|
|
532
|
-
role: 'admin' | 'user';
|
|
533
|
-
}
|
|
534
|
-
|
|
535
|
-
// Define the database interface
|
|
536
|
-
export interface Database {
|
|
537
|
-
user: UserTable;
|
|
538
|
-
}
|
|
539
|
-
|
|
540
|
-
// Use these types for inserting, selecting and updating the table
|
|
541
|
-
export type User = Selectable<UserTable>;
|
|
542
|
-
export type NewUser = Insertable<UserTable>;
|
|
543
|
-
export type UserUpdate = Updateable<UserTable>;
|
|
544
|
-
```
|
|
545
|
-
|
|
546
418
|
## Config
|
|
547
419
|
|
|
548
420
|
```json
|
|
@@ -596,8 +468,8 @@ export type UserUpdate = Updateable<UserTable>;
|
|
|
596
468
|
"type": "zod",
|
|
597
469
|
"useDateType": true,
|
|
598
470
|
"useTrim": false,
|
|
599
|
-
"nullish": false,
|
|
600
|
-
"requiredString": false,
|
|
471
|
+
"nullish": false, // When true, nullable fields use nullish() instead of nullable()
|
|
472
|
+
"requiredString": false, // When true, adds min(1) validation to non-nullable string fields
|
|
601
473
|
"header": "import { z } from 'zod';\nimport { CustomValidator } from './validators';",
|
|
602
474
|
"folder": "@zod",
|
|
603
475
|
"suffix": "table"
|
|
@@ -633,8 +505,8 @@ export type UserUpdate = Updateable<UserTable>;
|
|
|
633
505
|
| destinations[].type | The type of output to generate: "zod", "ts", or "kysely" |
|
|
634
506
|
| destinations[].useDateType | (Zod only) Use a specialized Zod type for date-like fields instead of string |
|
|
635
507
|
| destinations[].useTrim | (Zod only) Use `z.string().trim()` instead of `z.string()` |
|
|
636
|
-
| destinations[].nullish | (Zod only)
|
|
637
|
-
| destinations[].requiredString | (Zod only) Add `min(1)` for string
|
|
508
|
+
| destinations[].nullish | (Zod only) Use `nullish()` instead of `nullable()` for nullable fields. In updateable schemas, fields that were already nullable will become nullish |
|
|
509
|
+
| destinations[].requiredString | (Zod only) Add `min(1)` for non-nullable string fields |
|
|
638
510
|
| destinations[].enumType | (TypeScript only) How to represent enum types: "union" (default) or "enum" |
|
|
639
511
|
| destinations[].modelType | (TypeScript only) How to represent models: "interface" (default) or "type" |
|
|
640
512
|
| destinations[].schemaName | (Kysely only) Name of the database interface (default: "DB") |
|
package/dist/main.js
CHANGED
|
@@ -164,6 +164,7 @@ function getType(op, desc, config, destination, tableName) {
|
|
|
164
164
|
const { Default, Extra, Null, Type, Comment, EnumOptions } = desc;
|
|
165
165
|
const isZodDestination = destination.type === "zod";
|
|
166
166
|
const isTsDestination = destination.type === "ts";
|
|
167
|
+
const isKyselyDestination = destination.type === "kysely";
|
|
167
168
|
const isNullish = isZodDestination && destination.type === "zod" && destination.nullish === true;
|
|
168
169
|
const isTrim = isZodDestination && destination.type === "zod" && destination.useTrim === true && op !== "selectable";
|
|
169
170
|
const isUseDateType = isZodDestination && destination.type === "zod" && destination.useDateType === true;
|
|
@@ -174,11 +175,11 @@ function getType(op, desc, config, destination, tableName) {
|
|
|
174
175
|
return;
|
|
175
176
|
const isRequiredString = destination.type === "zod" && destination.requiredString === true && op !== "selectable";
|
|
176
177
|
const type = schemaType === "mysql" ? Type.split("(")[0].split(" ")[0] : Type;
|
|
177
|
-
if (isTsDestination) {
|
|
178
|
+
if (isTsDestination || isKyselyDestination) {
|
|
178
179
|
const tsOverrideType = config.magicComments ? extractTSExpression(Comment) : null;
|
|
179
180
|
const shouldBeNullable = isNull || ["insertable", "updateable"].includes(op) && (hasDefaultValue || isGenerated) || op === "updateable" && !isNull && !hasDefaultValue;
|
|
180
181
|
if (tsOverrideType) {
|
|
181
|
-
return shouldBeNullable ? `${tsOverrideType} | null` : tsOverrideType;
|
|
182
|
+
return shouldBeNullable ? tsOverrideType.includes("| null") ? tsOverrideType : `${tsOverrideType} | null` : tsOverrideType;
|
|
182
183
|
}
|
|
183
184
|
if (dateTypes[schemaType].includes(type)) {
|
|
184
185
|
return shouldBeNullable ? "Date | null" : "Date";
|
|
@@ -552,6 +553,9 @@ async function generate(config) {
|
|
|
552
553
|
let prismaTables = [];
|
|
553
554
|
let schema = null;
|
|
554
555
|
let db = null;
|
|
556
|
+
if (config.destinations.length === 0) {
|
|
557
|
+
throw new Error("Empty destinations object.");
|
|
558
|
+
}
|
|
555
559
|
const dryRunOutput = {};
|
|
556
560
|
if (config.origin.type === "mysql") {
|
|
557
561
|
db = knex({
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mutano",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "2.
|
|
4
|
+
"version": "2.1.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",
|
|
@@ -25,6 +25,8 @@
|
|
|
25
25
|
"devDependencies": {
|
|
26
26
|
"@types/fs-extra": "^11.0.4",
|
|
27
27
|
"esbuild": "^0.25.3",
|
|
28
|
+
"ts-node": "^10.9.2",
|
|
29
|
+
"tsx": "^4.19.4",
|
|
28
30
|
"typescript": "^5.8.3",
|
|
29
31
|
"vitest": "^3.1.2"
|
|
30
32
|
}
|