
Security News
Node.js Drops Bug Bounty Rewards After Funding Dries Up
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.
Convert database schemas to TypeScript types, Zod schemas, or Kysely definitions.
npm install mutano
import { generate } from 'mutano'
// Basic usage with database
await generate({
origin: {
type: 'mysql', // or 'postgres', 'sqlite', 'prisma', 'sql'
host: '127.0.0.1',
port: 3306,
user: 'root',
password: 'secret',
database: 'myapp'
},
destinations: [{
type: 'zod', // or 'ts', 'kysely'
folder: './generated'
}]
})
// Using SQL DDL files (no database required)
await generate({
origin: {
type: 'sql',
path: './schemas/myapp.sql', // Path to SQL file
dialect: 'mysql' // or 'postgres', 'sqlite'
},
destinations: [{
type: 'zod',
folder: './generated'
}]
})
// Multiple outputs
await generate({
origin: { /* ... */ },
destinations: [
{ type: 'zod', folder: './zod' },
{ type: 'ts', folder: './types' },
{ type: 'kysely', outFile: './db.ts' }
]
})
// With views support
await generate({
origin: { /* ... */ },
destinations: [{ type: 'zod' }],
includeViews: true,
views: ['user_profile_view'], // optional filter
ignoreViews: ['temp_view'] // optional exclude
})
Zod Schema:
export const user = z.object({
id: z.number().nonnegative(),
name: z.string().min(1),
email: z.string().email(),
role: z.enum(['admin', 'user']),
})
export const insertable_user = z.object({
name: z.string().min(1),
email: z.string().email(),
role: z.enum(['admin', 'user']),
})
export type UserType = z.infer<typeof user>
TypeScript Interface:
export interface User {
id: number;
name: string;
email: string;
role: 'admin' | 'user';
}
export interface InsertableUser {
name: string;
email: string;
role: 'admin' | 'user';
}
Kysely Types:
export interface User {
id: Generated<number>;
name: string;
email: string;
role: 'admin' | 'user';
}
export type SelectableUser = Selectable<User>;
export type InsertableUser = Insertable<User>;
export type UpdateableUser = Updateable<User>;
// MySQL/PostgreSQL
{
type: 'mysql' | 'postgres',
host: string,
port: number,
user: string,
password: string,
database: string,
schema?: string, // PostgreSQL only
ssl?: { ca, cert, key }
}
// SQLite
{
type: 'sqlite',
path: string
}
// Prisma
{
type: 'prisma',
path: string
}
// SQL DDL Files (no database required)
{
type: 'sql',
path: string, // Path to .sql file with CREATE TABLE statements
dialect: 'mysql' | 'postgres' | 'sqlite' // Determines type mappings
}
{
type: 'zod' | 'ts' | 'kysely',
folder?: string,
suffix?: string,
outFile?: string, // Kysely only
header?: string, // Custom imports
// Zod specific
useDateType?: boolean,
useBooleanType?: boolean,
useTrim?: boolean,
nullish?: boolean,
requiredString?: boolean,
version?: 3 | 4,
// TypeScript specific
enumType?: 'union' | 'enum',
modelType?: 'interface' | 'type',
// Kysely specific
schemaName?: string // Default: 'DB'
}
useDateType: When true, generates z.union([z.number(), z.string(), z.date()]).pipe(z.coerce.date()) instead of z.date() for date fieldsuseBooleanType: When true, generates z.union([z.number(), z.string(), z.boolean()]).pipe(z.coerce.boolean()) instead of z.boolean() for boolean fieldsuseTrim: When true, adds .trim() to string fieldsnullish: When true, uses .nullish() instead of .nullable() for nullable fields (except selectable schemas)requiredString: When true, adds .min(1) validation to required string fieldsversion: Zod version (3 or 4) for compatibility| Option | Description |
|---|---|
tables | Include only specified tables |
views | Include only specified views |
ignore | Exclude specified tables (supports regex) |
ignoreViews | Exclude specified views (supports regex) |
includeViews | Process database views |
camelCase | Convert to camelCase |
dryRun | Return content without writing files |
magicComments | Enable @zod/@ts/@kysely comments (Obs.: no SQLite support) |
inflection | Transform model names: 'singular', 'plural', or 'none' (default) |
overrideTypes | Override types globally per destination (see below) |
overrideColumns | Override specific columns per table (see below) |
Transform table/view names to singular or plural form in generated types:
// Singular inflection - "users" table becomes "User" type
await generate({
origin: { /* ... */ },
destinations: [{ type: 'zod' }],
inflection: 'singular'
})
// Plural inflection - "user" table becomes "Users" type
await generate({
origin: { /* ... */ },
destinations: [{ type: 'ts' }],
inflection: 'plural'
})
Examples:
| Table Name | inflection: 'singular' | inflection: 'plural' | inflection: 'none' |
|---|---|---|---|
users | UserType | UsersType | UsersType |
companies | CompanyType | CompaniesType | CompaniesType |
people | PersonType | PeopleType | PeopleType |
categories | CategoryType | CategoriesType | CategoriesType |
user_accounts | UserAccountType | UserAccountsType | UserAccountsType |
Works with all output types (Zod, TypeScript, Kysely) and combines with camelCase option.
Override types for specific columns using database comments:
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) COMMENT '@zod(z.string().min(2).max(50))',
`email` varchar(255) COMMENT '@ts(EmailAddress) @kysely(string)',
`metadata` json COMMENT '@ts(UserMetadata)',
`password_hash` varchar(255) COMMENT '@ignore',
PRIMARY KEY (`id`)
);
Supported Comments:
@zod(...) - Override Zod schema@ts(...) - Override TypeScript type@kysely(...) - Override Kysely type@ignore - Exclude column from generated types@@ignore - Exclude table/model from generated typesUse @ignore and @@ignore directives to exclude columns and tables from code generation:
Ignore specific fields:
model User {
id Int @id @default(autoincrement())
email String @unique
password String @ignore // This field will be excluded
createdAt DateTime @default(now())
}
Ignore entire models:
model AuditLog {
id Int @id @default(autoincrement())
action String
userId Int
timestamp DateTime @default(now())
@@ignore // This entire model will be excluded
}
Ignore specific columns in MySQL:
ALTER TABLE users MODIFY COLUMN password_hash VARCHAR(255) COMMENT '@ignore';
ALTER TABLE users MODIFY COLUMN internal_id VARCHAR(100) COMMENT 'Internal tracking @ignore';
Ignore specific columns in PostgreSQL:
COMMENT ON COLUMN users.password_hash IS '@ignore';
COMMENT ON COLUMN users.internal_id IS 'Internal tracking @ignore';
Ignore entire tables in MySQL:
ALTER TABLE audit_logs COMMENT = '@@ignore';
ALTER TABLE internal_metrics COMMENT = 'Internal table @@ignore';
Ignore entire tables in PostgreSQL:
COMMENT ON TABLE audit_logs IS '@@ignore';
COMMENT ON TABLE internal_metrics IS 'Internal table @@ignore';
Example with mixed ignored and non-ignored columns:
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`email` varchar(255) NOT NULL,
`name` varchar(255),
`password_hash` varchar(255) COMMENT '@ignore',
`internal_tracking_id` varchar(100) COMMENT 'Internal use only @ignore',
`metadata` json COMMENT '@ts(UserMetadata)',
PRIMARY KEY (`id`)
);
Generated types will only include: id, email, name, and metadata
Override default types globally. Define destination-specific overrides for each output type:
{
origin: {
type: 'mysql',
// ... connection config
},
overrideTypes: {
zod: {
json: 'z.record(z.string())',
text: 'z.string().max(1000)',
decimal: 'z.number().positive()'
},
ts: {
json: 'Record<string, string>',
text: 'string',
decimal: 'number'
},
kysely: {
json: 'Json',
text: 'string',
decimal: 'Decimal'
}
}
}
Single destination with multiple outputs:
{
origin: {
type: 'postgres',
// ...
},
destinations: [
{ type: 'zod', folder: './zod' },
{ type: 'ts', folder: './types' },
{ type: 'kysely', outFile: './db.ts' }
],
overrideTypes: {
zod: { jsonb: 'z.record(z.string())' },
ts: { jsonb: 'Record<string, string>' },
kysely: { jsonb: 'Json' }
}
}
Common Overrides:
json, text, decimal, enumjsonb, uuid, text, numericjson, text, realJson, String, DecimalOverride specific columns from specific tables. Takes priority over magic comments:
{
origin: {
type: 'mysql',
// ... connection config
},
destinations: [
{ type: 'zod', folder: './zod' },
{ type: 'ts', folder: './types' },
{ type: 'kysely', outFile: './db.ts' }
],
overrideColumns: {
zod: {
users: {
email: 'z.string().email()',
metadata: 'z.record(z.unknown())'
},
posts: {
content: 'z.string().max(10000)'
}
},
ts: {
users: {
email: 'EmailAddress',
metadata: 'Record<string, unknown>'
}
},
kysely: {
users: {
metadata: 'CustomJsonType'
}
}
}
}
Priority order (highest to lowest):
overrideColumns - Specific column overrides@zod, @ts, @kysely) - Column-level commentsoverrideTypes - Global type overridesFAQs
Converts Prisma/MySQL/PostgreSQL/SQLite schemas to Zod/TS/Kysely interfaces
The npm package mutano receives a total of 651 weekly downloads. As such, mutano popularity was classified as not popular.
We found that mutano demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.

Security News
The Axios compromise shows how time-dependent dependency resolution makes exposure harder to detect and contain.

Research
A supply chain attack on Axios introduced a malicious dependency, plain-crypto-js@4.2.1, published minutes earlier and absent from the project’s GitHub releases.