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.
Files changed (3) hide show
  1. package/README.md +12 -140
  2. package/dist/main.js +6 -2
  3. 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().min(10).max(255),
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) Set schema as `nullish` instead of `nullable` |
637
- | destinations[].requiredString | (Zod only) Add `min(1)` for string schema |
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.0.0",
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
  }