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

@8ux-co/eelzap-cli

v0.10.0

Published

The Eel Zap command line: `eelzap codegen` generates TypeScript types for your collections and documents. Install it as a devDependency.

Readme

@8ux-co/eelzap-cli

The Eel Zap command line. eelzap codegen reads your live collections and documents and generates TypeScript types for them, which you use with the client from @8ux-co/eelzap.

It is a development tool: install it as a devDependency, so its prompt and .env dependencies never ship with your site.

Install

npm install --save-dev @8ux-co/eelzap-cli
npm install @8ux-co/eelzap

The generated files import their helper types from @8ux-co/eelzap, so the site needs the client installed as a regular dependency.

Quick usage

# Reads EELZAP_API_KEY from .env.local, .env and the other env files
npx eelzap codegen

# Explicit command form
npx eelzap codegen generate --api-key secret_abc123 --output-dir src/generated/cms

# Preview only
npx eelzap codegen --dry-run

eelzap gen is an alias of eelzap codegen, and eelzap generate … is short for eelzap codegen generate ….

Generated output defaults to types/eel-zap/:

types/eel-zap/
├── index.ts
├── collections/
│   ├── index.ts
│   └── blog-posts.ts
└── documents/
    ├── index.ts
    └── homepage.ts

Config file

The CLI looks for one of:

  • eelzap.config.ts
  • eelzap.config.js
  • eelzap.config.mjs
  • eelzap.config.json
  • .eelzaprc.json
// eelzap.config.ts
import type { EelZapCodegenConfig } from '@8ux-co/eelzap-cli/codegen'

export default {
  apiKey: process.env.EELZAP_API_KEY,
  baseUrl: process.env.EELZAP_BASE_URL,
  outputDir: 'types/eel-zap',
  collections: true,
  documents: true,
  includeCollections: ['blog-posts'],
  excludeDocuments: ['internal-notes'],
  fileNameCasing: 'kebab',
  folderNameCasing: 'kebab',
  typeNameCasing: 'pascal',
  addFieldComments: true,
  generateIndex: true,
  includeSeo: true,
  includeMeta: true,
  header: '/* Auto-generated by @8ux-co/eelzap-cli codegen - DO NOT EDIT */',
} satisfies EelZapCodegenConfig

When you run eelzap codegen without flags and without a config file, it enters interactive mode, prompts for the missing values, and writes eelzap.config.json for subsequent runs. The API key is kept in .env.

Flags

--api-key <key>         API key (overrides config/env)
--base-url <url>        Base URL (overrides config/env)
--output-dir <path>     Output directory (default: types/eel-zap)
--collections-only      Only generate collection types
--documents-only        Only generate document types
--include <keys...>     Only include these collection/document keys
--exclude <keys...>     Exclude these collection/document keys
--no-comments           Skip JSDoc comments
--no-seo                Skip SEO helper fields
--no-meta               Skip meta helper fields
--no-index              Skip barrel index.ts files
--dry-run               Print generated files without writing them
--verbose               Print detailed progress
--config <path>         Path to config file

Environment files

The CLI reads the env files of the directory you run it in, with the names and precedence Next.js uses. Highest first:

  1. Variables already set in the environment: they always win.
  2. .env.$NODE_ENV.local
  3. .env.local (skipped when NODE_ENV is test)
  4. .env.$NODE_ENV
  5. .env

NODE_ENV is development when it is not set, so a plain npx eelzap codegen reads .env.development.local, .env.local, .env.development and .env; NODE_ENV=production reads the production files instead. A missing file is skipped. Values are not expanded ($OTHER stays as written). --verbose prints which files were read, never their values.

Base URL and the path prefix

Of the env files, the CLI only understands EELZAP_API_KEY and EELZAP_BASE_URL. There is no --path-prefix flag, no EELZAP_PATH_PREFIX read, and no pathPrefix config key: the CLI always uses the client's default /v1.

The prefix composes, so put everything before /v1 in the base URL and let the default supply the rest:

# Target a local Zap at http://localhost:5047/api/public/v1/...
EELZAP_BASE_URL=http://localhost:5047/api/public npx eelzap codegen
#   or: npx eelzap codegen --base-url http://localhost:5047/api/public

Do not put the full /api/public/v1 in the base URL: the default /v1 is appended to it and you get /api/public/v1/v1/....

What the generated types say

Codegen reads each collection's and document's schema (its fields and sections) and writes:

  • The builder's order. Fields come in the order Zap's field builder shows them: fields outside a section and sections in their place, each section's fields in its own order.
  • Required fields as non-null. Zap refuses a save that leaves a required field empty, for entries and documents alike, so delivered content has it: title: string. Any other field may be empty and is T | null, except a gallery, which is delivered as [] when empty and so is always an array.
  • ENUM values narrowed to the field's options: EnumValue & { value: 'a' | 'b' }.

Required-ness is checked when content is saved, so two cases can still read as null: content saved before the field was made required, until it is saved again, and a draft or preview of a document that was never saved.

Use a secret key. The schema routes refuse a public_ key; codegen then falls back to the delivery schema and warns: collections keep their required-ness but follow the delivery order, and every document field is typed T | null with ENUMs not narrowed.

Generated type usage

import { createClient } from '@8ux-co/eelzap'
import type { BlogPostsContent, HomepageDocument } from '@/types/eel-zap'

const cms = createClient({
  apiKey: process.env.EELZAP_API_KEY!,
})

const { data: posts } = await cms.items.list<BlogPostsContent>('blog-posts', {
  pageSize: 10,
})

const homepage = await cms.documents.get<HomepageDocument['content']>('homepage')

posts[0]?.content.title
homepage.content.hero_title

Next.js workflow

{
  "scripts": {
    "codegen": "eelzap codegen generate",
    "dev": "npm run codegen && next dev",
    "build": "npm run codegen && next build"
  }
}

Programmatic API

import { generateTypes } from '@8ux-co/eelzap-cli/codegen'

const result = await generateTypes({
  apiKey: process.env.EELZAP_API_KEY,
  outputDir: 'types/eel-zap',
  writeFiles: true,
})

console.log(result.filesWritten)
for (const warning of result.warnings) console.warn(warning)

warnings lists what the types could not reflect, such as a key that cannot read the schema. generateTypes reads process.env but no env file: load those yourself.

@8ux-co/eelzap-cli/codegen also exports resolveCodegenConfig, DEFAULT_CODEGEN_CONFIG and the EelZapCodegenConfig and ResolvedCodegenConfig types.

Moving from @8ux-co/eelzap-api-sdk-ts

Up to 0.9.x the CLI shipped inside the SDK package as the eelzap-codegen bin. From 0.10.0:

| Before | Now | | -------------------------------------------------- | ----------------------------------------- | | npx eelzap-codegen [generate] [options] | npx eelzap codegen [generate] [options] | | @8ux-co/eelzap-api-sdk-ts/codegen | @8ux-co/eelzap-cli/codegen | | generated files import @8ux-co/eelzap-api-sdk-ts | generated files import @8ux-co/eelzap |

Regenerate your types after upgrading so the generated imports point at the new client package.

License

MIT