npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@datafn/cli

v0.0.2

Published

CLI and Codegen for DataFn

Readme

@datafn/cli

CLI tools and TypeScript code generation for DataFn. Generates Drizzle ORM schema definitions and typed interfaces from DataFn schemas.

Installation

npm install @datafn/cli

Features

| Feature | Description | |---------|-------------| | Schema Generation | Generate Drizzle ORM schema (pgTable, mysqlTable, sqliteTable) from DataFn schema | | Type Generation | Generate TypeScript interfaces, Tables map, and TypedClient from DataFn schema | | Multi-Database | PostgreSQL, MySQL, SQLite — each with dialect-specific Drizzle column types | | CLI Interface | npx @datafn/cli generate command for schema + type generation |


CLI Usage

generate

Generate Drizzle ORM schema and TypeScript type definitions from a DataFn schema.

# Auto-discover schema file
npx @datafn/cli generate --adapter drizzle --database postgres

# Explicit schema file
npx @datafn/cli generate --adapter drizzle --database postgres --schema ./schema.datafn.ts

# Custom output directory
npx @datafn/cli generate --adapter drizzle --database postgres --output ./src/db/

Options

| Option | Description | Default | |--------|-------------|---------| | --adapter <name> | ORM adapter (currently only drizzle supported) | Required | | --database <name> | Database dialect: postgres, mysql, sqlite | Required | | --schema <path> | Schema file (.json or .datafn.ts). Auto-discovers if omitted | Auto-discover | | --output <dir> | Output directory for generated files | ./ | | -h, --help | Show help | — |

Output Files

The generate command produces two files in the output directory:

  1. datafn-schema.drizzle.ts — Drizzle ORM table definitions
  2. datafn-types.ts — TypeScript type definitions

Example Output: Drizzle Schema (PostgreSQL)

Given this DataFn schema:

// schema.datafn.ts
export default {
  resources: [
    {
      name: 'task',
      version: 1,
      fields: [
        { name: 'id', type: 'string', required: true },
        { name: 'title', type: 'string', required: true },
        { name: 'done', type: 'boolean', required: false, default: false },
        { name: 'createdAt', type: 'date', required: true },
      ],
      indices: { base: ['createdAt'] },
    },
  ],
  relations: [],
};

The generated datafn-schema.drizzle.ts will be:

// Generated by @datafn/cli. DO NOT EDIT.
// Database: postgres

import { pgTable, text, boolean, bigint, index } from "drizzle-orm/pg-core";

export const task = pgTable("task", {
  createdAt: bigint("created_at", { mode: "number" }).notNull(),
  done: boolean("done").default(false),
  id: text("id").primaryKey(),
  title: text("title").notNull(),
}, (table) => [
  index("task_created_at_idx").on(table.createdAt),
]);

export const schema = { task };

Auto-Discovery

When --schema is omitted, the CLI searches for schema files in this order:

  1. ./schema.datafn.ts
  2. ./src/schema.datafn.ts
  3. ./schema.json
  4. ./src/schema.json

Production Workflow

The recommended workflow for DataFn with generated schemas:

1. Define Your Schema

Write your DataFn schema as the single source of truth:

// schema.datafn.ts
import type { DatafnSchema } from '@datafn/core';

export default {
  resources: [
    {
      name: 'user',
      version: 1,
      fields: [
        { name: 'id', type: 'string', required: true },
        { name: 'email', type: 'string', required: true, unique: true },
        { name: 'name', type: 'string', required: true },
      ],
    },
  ],
  relations: [],
} satisfies DatafnSchema;

2. Generate ORM Schema + Types

datafn generate --adapter drizzle --database postgres

This creates:

  • ./datafn-schema.drizzle.ts — Drizzle table definitions
  • ./datafn-types.ts — TypeScript interfaces

3. Generate Migrations

Use your ORM's native migration tools:

# Drizzle
drizzle-kit generate
drizzle-kit migrate

4. Use Generated Schema in Your App

import { drizzle } from 'drizzle-orm/node-postgres';
import { schema } from './datafn-schema.drizzle';
import { Pool } from 'pg';

const pool = new Pool({ connectionString: process.env.DATABASE_URL });
const db = drizzle(pool, { schema });

// Schema is now registered with Drizzle

5. Create DataFn Server

import { createDatafnServer } from '@datafn/server';
import { drizzleAdapter } from '@superfunctions/db/adapters';
import { schema as datafnSchema } from './schema.datafn';

const server = await createDatafnServer({
  schema: datafnSchema,
  db: drizzleAdapter(db),
});

Important: When upgrading to a new version of DataFn with schema changes, always:

  1. Run datafn generate to update schema files
  2. Run ORM migration tools to apply database changes
  3. Deploy updated code

TypeScript Schema Support

Overview

The DataFn CLI supports TypeScript schema files for a better developer experience with type safety and IDE autocomplete.

Convention: .datafn.ts Extension

TypeScript schema files must use the .datafn.ts extension:

// schema.datafn.ts
import type { DatafnSchema } from '@datafn/core';

export default {
  resources: [
    {
      name: 'task',
      version: 1,
      fields: [
        { name: 'id', type: 'string', required: true },
        { name: 'title', type: 'string', required: true },
        { name: 'done', type: 'boolean', required: false },
      ],
    },
  ],
  relations: [],
} satisfies DatafnSchema;

Why .datafn.ts?

  • Security: Prevents accidental execution of arbitrary TypeScript files
  • Clarity: Signals that the file contains a DataFn schema
  • Convention: Similar to *.config.ts, *.spec.ts, etc.

Auto-Discovery

When you run datafn generate without the --schema flag, the CLI automatically searches for schema files in this order:

  1. ./schema.datafn.ts (current directory)
  2. ./src/schema.datafn.ts (source directory)
  3. ./schema.json (JSON schema file)
  4. ./src/schema.json (JSON schema file in src)

The first file found is used.

Export Formats

Your .datafn.ts file must export the schema in one of these ways:

Default export (recommended):

export default { resources: [...], relations: [...] };

Named export:

export const schema = { resources: [...], relations: [...] };

Security Best Practices

⚠️ Important: .datafn.ts files are executed during import. Follow these guidelines:

✅ Do:

  • Define schema as a plain object literal
  • Import types from @datafn/core
  • Use simple object/array compositions

❌ Don't:

  • Make network requests
  • Perform file system operations
  • Execute side effects in module scope
  • Import runtime dependencies unnecessarily

Good Example:

import type { DatafnSchema } from '@datafn/core';

export default {
  resources: [/* ... */],
  relations: [],
} satisfies DatafnSchema;

Bad Example:

import axios from 'axios'; // ❌ Runtime dependency

const data = await axios.get('/api/schema'); // ❌ Side effect

export default data.schema;

Migrating from JSON to TypeScript

To convert an existing JSON schema to TypeScript:

  1. Rename schema.json to schema.datafn.ts
  2. Add type import: import type { DatafnSchema } from '@datafn/core';
  3. Add export: export default before the schema object
  4. Add type annotation: satisfies DatafnSchema after the object
  5. Remove quotes from unquoted JSON keys if desired

Before (schema.json):

{
  "resources": [
    {
      "name": "task",
      "version": 1,
      "fields": [...]
    }
  ],
  "relations": []
}

After (schema.datafn.ts):

import type { DatafnSchema } from '@datafn/core';

export default {
  resources: [
    {
      name: 'task',
      version: 1,
      fields: [...]
    }
  ],
  relations: []
} satisfies DatafnSchema;

Troubleshooting

Error: "Invalid schema file extension"

  • Cause: Trying to use .ts file without .datafn. convention
  • Solution: Rename to *.datafn.ts

Error: "No schema export found"

  • Cause: File doesn't export schema
  • Solution: Add export default { ... } or export const schema = { ... }

Error: "Failed to load TypeScript schema" (Node.js)

  • Cause: tsx package not installed
  • Solution: Run npm install tsx --save-dev or use Bun

Types don't match expectations

  • Cause: Schema validation failed
  • Solution: Check console output for validation errors from validateSchema()

Runtime Requirements

  • Bun: Native TypeScript support (no additional deps)
  • Node.js: Requires tsx package (npm install tsx --save-dev)

Programmatic API

generateTypes(schema): string

Generate TypeScript definitions from a DataFn schema. The schema is validated first; invalid schemas throw a DatafnError.

import { generateTypes } from "@datafn/cli";

const code = generateTypes({
  resources: [
    {
      name: "task",
      version: 1,
      fields: [
        { name: "id", type: "string", required: true, unique: true },
        { name: "title", type: "string", required: true },
        { name: "done", type: "boolean", required: false },
        { name: "priority", type: "number", required: false },
        { name: "dueDate", type: "date", required: false },
        { name: "metadata", type: "object", required: false },
        { name: "tags", type: "array", required: false },
      ],
    },
    {
      name: "project",
      version: 1,
      fields: [
        { name: "id", type: "string", required: true, unique: true },
        { name: "name", type: "string", required: true },
      ],
    },
  ],
});

console.log(code);

Generated output:

import type { DatafnClient, DatafnTable } from "@datafn/client";

export interface Project {
  id: string;
  name: string;
}

export interface Task {
  done?: boolean;
  dueDate?: number;
  id: string;
  metadata?: Record<string, unknown>;
  priority?: number;
  tags?: unknown[];
  title: string;
}

export interface Tables {
  project: Project;
  task: Task;
}

export type TypedClient = DatafnClient & {
  project: DatafnTable<Project>;
  task: DatafnTable<Task>;
};

Type mapping:

| DataFn Type | TypeScript Type | |-------------|----------------| | string | string | | number | number | | boolean | boolean | | object | Record<string, unknown> | | array | unknown[] | | date | number (timestamp) | | file | string (URL or ID) |

Resources and fields are sorted alphabetically for deterministic output.


generateDrizzleSchema(schema, dialect): string

Generate Drizzle ORM table definitions from a DataFn schema.

import { generateDrizzleSchema } from "@datafn/cli";

const code = generateDrizzleSchema(
  {
    resources: [
      {
        name: "task",
        version: 1,
        fields: [
          { name: "id", type: "string", required: true },
          { name: "title", type: "string", required: true },
          { name: "done", type: "boolean", default: false },
          { name: "createdAt", type: "date", required: true },
        ],
        indices: { base: ["createdAt"] },
      },
    ],
    relations: [],
  },
  "postgres"
);

console.log(code);

Generated output:

// Generated by @datafn/cli. DO NOT EDIT.
// Database: postgres

import { pgTable, text, boolean, bigint, index } from "drizzle-orm/pg-core";

export const task = pgTable("task", {
  createdAt: bigint("created_at", { mode: "number" }).notNull(),
  done: boolean("done").default(false),
  id: text("id").primaryKey(),
  title: text("title").notNull(),
}, (table) => [
  index("task_created_at_idx").on(table.createdAt),
]);

export const schema = { task };

Supported dialects:

  • "postgres" — PostgreSQL (pgTable)
  • "mysql" — MySQL (mysqlTable)
  • "sqlite" — SQLite (sqliteTable)

Type mapping:

PostgreSQL:

| DataFn Type | Drizzle Column | |-------------|---------------| | string | text("field") | | number | numeric("field") | | boolean | boolean("field") | | date | bigint("field", { mode: "number" }) | | object | jsonb("field") | | array | jsonb("field") | | file | text("field") |

MySQL:

| DataFn Type | Drizzle Column | |-------------|---------------| | string | text("field") | | number | int("field") | | boolean | boolean("field") | | date | bigint("field", { mode: "number" }) | | object | json("field") | | array | json("field") | | file | text("field") |

SQLite:

| DataFn Type | Drizzle Column | |-------------|---------------| | string | text("field") | | number | integer("field") | | boolean | integer("field") | | date | integer("field") | | object | text("field") | | array | text("field") | | file | text("field") |

Features:

  • Automatic id field detection (.primaryKey())
  • Field modifiers: .notNull(), .unique(), .default(value)
  • Index generation from indices.base
  • Join table generation for many-many relations
  • camelCase → snake_case column naming

Exports

// Schema generation
export { generateDrizzleSchema }

// Type generation
export { generateTypes }

// Types
export type { DatafnSchema } from '@datafn/core'

License

MIT