Supazod

repository·main·Indexed 42 days ago

https://github.com/dohooo/supazod

A tool that generates Zod schemas from TypeScript types produced by the Supabase CLI. Version 4.5.0 supports customizable naming patterns, inline type generation, and a programmatic API via `generateContent`. It allows for type-safe configuration through `defineConfig` in a `supazod.config.ts` file and supports the `MergeDeep` pattern from `type-fest` for overriding JSON field types.

Tokens
10.4K
Snippets
35
Records
38
Agent score
50%

What's inside Supazod

  1. Use Inline Types in Supazod

    main

    If you prefer a simpler setup without managing separate .d.ts files, you can use the --inline-types (or -I) flag to include TypeScript types directly in the generated schema file.

    Via CLI:

    $ pnpm supazod -i types.ts -o schemas.ts --inline-types

    Via Configuration File: You can also enable this globally in your supazod.config.ts:

    import { defineConfig } from 'supazod';
    
    export default defineConfig({
      inlineTypes: true,
    });
  2. Supazod MergeDeep Support

    main

    Supazod supports the MergeDeep pattern from type-fest, which is useful for overriding JSON field types in Supabase generated types.

    Requirements:

    • The base type must be defined in the same file as the MergeDeep call.
    • Imported type references are NOT supported.

    Supported Patterns:

    ✅ Inline type literal as first argument:

    export type Database = MergeDeep<{ public: { Tables: { ... } } }, { /* overrides */ }>;

    ✅ Type alias defined in the same file:

    type DatabaseGenerated = { public: { Tables: { ... } } };
    export type Database = MergeDeep<DatabaseGenerated, { /* overrides */ }>;

    Workaround for Imported Types: If you need to use MergeDeep with types from another file, you must copy the generated types into your local file or use a pre-processing script to inline them before running Supazod.

  3. Migrate from v1.x to v2.x

    main

    When upgrading to v2.0.0 or later, note that schema names and TypeScript types have been cleaned up to remove redundant suffixes. Follow these steps to complete the migration:

    1. Update Dependencies: Install the new version.
    2. Update Schema Imports: Remove the duplicated SchemaSchema suffix from your Zod schema imports.
    3. Update Type Imports: Remove the Schema suffix from your TypeScript type imports.
    4. Regenerate Schemas: Run the CLI to generate the new files with the updated naming convention.
    # Step 1: Update Dependencies
    npm install supazod@^2.0.0
    
    # Step 4: Regenerate Schemas
    npx supazod -i types.ts -o schema.ts
  4. Configure Supazod using TypeScript (Recommended)

    main

    For the best developer experience, use a supazod.config.ts file with the defineConfig helper. This provides full IntelliSense, autocomplete for naming patterns, and type checking for placeholders.

    Supported Placeholders:

    • {schema}: Database schema name (e.g., public)
    • {table}: Table name (e.g., users)
    • {operation}: Operation type (e.g., Insert, Update, Row)
    • {function}: Function name (e.g., get_status)
    • {name}: Type name (e.g., user_status for enums)

    Configuration Options:

    • tableOperationPattern: Pattern for table operations.
    • enumPattern: Pattern for enums.
    • functionArgsPattern: Pattern for function arguments.
    • functionReturnsPattern: Pattern for function returns.
    • compositeTypePattern: Pattern for composite types.
    • capitalizeSchema: Boolean to capitalize schema names (default: true).
    • capitalizeNames: Boolean to capitalize type names (default: true).
    • separator: String separator between name parts (default: empty).
    // supazod.config.ts
    import { defineConfig } from 'supazod';
    
    export default defineConfig({
      namingConfig: {
        tableOperationPattern: '{schema}_{table}_{operation}',
        enumPattern: '{schema}_{name}_Enum',
        functionArgsPattern: '{schema}_{function}_Args',
        functionReturnsPattern: '{schema}_{function}_Returns',
        
        capitalizeSchema: true,
        capitalizeNames: true,
        separator: '_',
      }
    });
  5. Quick Start: Generate Zod schemas from Supabase types

    main

    Supazod converts TypeScript types generated by the Supabase CLI into Zod schemas.

    1. Generate Supabase types

    First, ensure you have your Supabase types exported to a file:

    $ supabase gen types typescript --local > types.ts

    2. Run Supazod

    You can choose between two main output modes:

    Option A: Separate types file (Recommended for large projects) Generates Zod schemas in one file and TypeScript definitions in another.

    $ pnpm supazod -i types.ts -o schemas.ts -t schemas.d.ts -s public,schema_a,schema_b

    Option B: Single file with inline types Generates everything (schemas and types) in a single file.

    $ pnpm supazod -i types.ts -o schemas.ts --inline-types
  6. Customizing type name formatting

    main

    The transformTypes function allows you to override how different database entities are named in the output using custom formatter functions. This is useful if you want to change the casing or prefixing of your generated types.

    Supported formatter types:

    • Enums: (name: string) => string
    • Composite Types: (name: string) => string
    • Functions: (name: string, type: string) => string (where type is 'Args' or 'Returns')
    • Tables/Views: (name: string, operation: string) => string (where operation is the operation like 'Select', 'Insert', etc.)
  7. Configure Supazod via TypeScript

    main

    Create a supazod.config.ts file for type-safe configuration. This allows you to customize naming patterns for schemas, tables, enums, and functions using IntelliSense.

    Available Placeholders:

    • {schema}: Database schema name (e.g., public)
    • {table}: Table name (e.g., users)
    • {operation}: Operation type (Insert, Update, Row)
    • {function}: Function name
    • {name}: Type name (e.g., for enums)

    Example Configuration:

    import { defineConfig } from 'supazod';
    
    export default defineConfig({
      namingConfig: {
        tableOperationPattern: '{schema}_{table}_{operation}',
        tableSchemaPattern: '{schema}{table}{operation}',
        enumPattern: '{schema}_{name}_Enum',
        enumSchemaPattern: '{schema}{name}',
        functionArgsPattern: '{schema}_{function}_Args',
        functionArgsSchemaPattern: '{schema}{function}Args',
        functionReturnsPattern: '{schema}_{function}_Returns',
        functionReturnsSchemaPattern: '{schema}{function}Returns',
    
        capitalizeSchema: true,
        capitalizeNames: true,
        separator: '_',
      }
    });
  8. Configure Supazod via JSON or JavaScript

    main

    If you prefer not to use TypeScript, you can use standard JavaScript or JSON configuration files.

    Supported File Names:

    • supazod.config.ts, supazod.config.js, supazod.config.mjs, supazod.config.json
    • .supazodrc.ts, .supazodrc.js, .supazodrc.mjs, .supazodrc.json, .supazodrc
    // supazod.config.json
    {
      "namingConfig": {
        "tableOperationPattern": "{schema}_{table}_{operation}",
        "enumPattern": "{schema}_{name}_Enum",
        "capitalizeSchema": true,
        "capitalizeNames": true,
        "separator": "_"
      }
    }
  9. Configure naming patterns in Supazod

    main

    You can customize how generated schemas, enums, composite types, and function arguments/returns are named using the namingConfig property within the SupazodConfig.

    Naming patterns use placeholders in curly braces (e.g., {schema}, {table}, {operation}, {name}, {function}) which are replaced during code generation. You can also control capitalization and separators.

    Available Placeholders

    • schema: The database schema name.
    • table: The table name.
    • operation: The operation type (e.g., Row, Insert, Update).
    • function: The function name.
    • name: The name of an enum or composite type.
    • type: The type name.
    // supazod.config.ts
    import { defineConfig } from 'supazod';
    
    export default defineConfig({
      namingConfig: {
        tableOperationPattern: '{schema}_{table}_{operation}', // TypeScript will provide autocomplete
        enumPattern: '{schema}_{name}_Enum',
        capitalizeSchema: true,
      }
    });
  10. Configure Supazod using configuration files

    main

    Supazod automatically searches for configuration files in the current working directory. You can provide a configuration file to customize the schema generation behavior.

    Supported file names include:

    • supazod.config.ts, supazod.config.js, supazod.config.mjs, supazod.config.json
    • .supazodrc.ts, .supazodrc.js, .supazodrc.mjs, .supazodrc.json, .supazodrc

    Configuration files can be standard JSON objects or TypeScript/JavaScript modules. If using a module, the configuration can be exported as the default export or as the module itself. Additionally, the configuration can be a function that returns a SupazodConfig object.

    If you need to use a specific configuration file, you can override the default search by providing a path to the loadConfig function.

    // Example of a supazod.config.ts file
    export default () => ({
      // your configuration here
    });
  11. Fixing encoding issues for PowerShell users (Windows)

    main

    On Windows, PowerShell's > redirect operator outputs UTF-16 by default, which Supazod cannot read. Use Out-File with -Encoding utf8 instead when generating your Supabase types.

    For local databases:

    supabase gen types typescript --local | Out-File -FilePath types.ts -Encoding utf8

    For remote Supabase projects:

    supabase gen types typescript --project-id <project-id> | Out-File -FilePath types.ts -Encoding utf8