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

@eloquentjs/codegen

v0.0.3

Published

Shared code generation engine for EloquentJS — introspect models, render stubs, emit GraphQL SDL, TypeScript types, OpenAPI specs

Downloads

60

Readme

@eloquentjs/codegen

Shared code generation engine for EloquentJS. Introspects Model classes and generates GraphQL SDL, TypeScript types, OpenAPI specs, and source stubs. Used internally by @eloquentjs/graphql and @eloquentjs/cli.

npm install @eloquentjs/codegen

What It Does

@eloquentjs/codegen is the single source of truth for all code generation in the EloquentJS ecosystem. Instead of each package duplicating generation logic, they all call into this one engine:

Model class
    │
    ▼
introspect()  ──→  ModelSchema (normalized descriptor)
    │
    ├──→ generateGraphqlSchema()   → schema.graphql
    ├──→ generateTypeScriptFile()  → models.d.ts
    ├──→ generateOpenApiSpec()     → openapi.json / openapi.yaml
    ├──→ generateModelStub()       → app/models/User.js
    ├──→ generateMigrationStub()   → database/migrations/...
    ├──→ generateFactoryStub()     → database/factories/UserFactory.js
    └──→ generateSeederStub()      → database/seeders/UserSeeder.js

Core Concept: ModelSchema

introspect(ModelClass) returns a normalized ModelSchema object. Every generator consumes this — you never need to pass raw Model classes into templates directly.

import { introspect } from '@eloquentjs/codegen'

const schema = introspect(User)
// {
//   name: 'User',
//   table: 'users',
//   primaryKey: 'id',
//   softDeletes: false,
//   timestamps: true,
//   fillable: ['name', 'email'],
//   hidden: ['password'],
//   fields: [
//     { name: 'id',       cast: 'uuid',    gqlType: 'ID',      tsType: 'string',  openApiType: { type: 'string' },  isPk: true },
//     { name: 'name',     cast: 'string',  gqlType: 'String',  tsType: 'string',  openApiType: { type: 'string' },  fillable: true },
//     { name: 'is_admin', cast: 'boolean', gqlType: 'Boolean', tsType: 'boolean', openApiType: { type: 'boolean' }, hidden: false },
//     { name: 'created_at', cast: 'datetime', gqlType: 'DateTime', tsType: 'Date', isTimestamp: true },
//     ...
//   ],
//   relations: [
//     { name: 'posts', type: 'hasMany', related: 'Post', isList: true },
//     { name: 'profile', type: 'hasOne', related: 'Profile', isList: false },
//   ],
//   scopes: [
//     { name: 'active', methodName: 'scopeActive' },
//   ],
//   graphql: { hidden: Set, disabled: {}, subscription: true, middleware: [] },
//   ModelClass: User,
// }

Introspection

import { introspect, introspectAll } from '@eloquentjs/codegen'

// From a live Model class
const schema = introspect(User)

// From a plain descriptor (no database needed — for CLI scaffold)
const schema = introspect({
  name:        'Product',
  table:       'products',
  primaryKey:  'id',
  fillable:    ['name', 'price'],
  hidden:      [],
  casts:       { name: 'string', price: 'decimal:2', in_stock: 'boolean' },
  timestamps:  true,
  softDeletes: false,
})

// Multiple at once
const schemas = introspectAll([User, Post, Comment])

Field Type Mapping

Every field in ModelSchema.fields includes all type representations:

| Cast | gqlType | tsType | openApiType.type | | ------------------------ | ---------- | ------------------------- | ---------------------------- | | integer / int | Int | number | integer | | float / double | Float | number | number | | decimal:2 | Float | number | number | | string / text | String | string | string | | boolean / bool | Boolean | boolean | boolean | | date | DateTime | Date | string (format: date) | | datetime / timestamp | DateTime | Date | string (format: date-time) | | json / jsonb | JSON | Record<string, unknown> | object | | array | JSON | unknown[] | array | | uuid | ID | string | string (format: uuid) |


Templates

GraphQL SDL

import { generateGraphqlSDL, generateGraphqlSchema } from '@eloquentjs/codegen'

// SDL fragments for one model (used by @eloquentjs/graphql internally)
const {
  typeDef,           // type User { ... }
  inputCreate,       // input CreateUserInput { ... }
  inputUpdate,       // input UpdateUserInput { ... }
  inputWhere,        // input UserWhereInput { ... }
  paginated,         // type UserPage { ... }
  queryLines,        // ['  user(id: ID!): User', ...]
  mutationLines,     // ['  createUser(...): User!', ...]
  subscriptionLines, // ['  userCreated: User!', ...]
} = generateGraphqlSDL(schema, {
  pagination:    'offset',  // 'offset' | 'relay'
  subscriptions: true,
})

// Complete standalone .graphql file for one or more models
const sdl = generateGraphqlSchema([userSchema, postSchema], {
  pagination:    'offset',
  subscriptions: true,
  scalars:       ['BigInt'],
  header:        true,      // include generation comment
})
// → write to schema.graphql

TypeScript Types

import { generateTypeScriptTypes, generateTypeScriptFile } from '@eloquentjs/codegen'

// Types for one model
const ts = generateTypeScriptTypes(schema, {
  includeCreateInput: true,
  includeUpdateInput: true,
  includeWhereInput:  false,
})
// → export interface User { id: string; name?: string; is_admin?: boolean; ... }
//   export interface CreateUserInput { name?: string; ... }
//   export interface UpdateUserInput { name?: string; ... }

// Full declaration file for all models
const file = generateTypeScriptFile(schemas, { header: true })
// → includes PaginationMeta, PaginatedResult<T>, all model interfaces

OpenAPI 3.0

import { generateOpenApiSpec } from '@eloquentjs/codegen'

const spec = generateOpenApiSpec(schemas, {
  title:    'My API',
  version:  '0.0.2',
  servers:  [{ url: 'https://api.example.com', description: 'Production' }],
  prefix:   '/api',
  security: [{ bearerAuth: [] }],
})
// Returns a full OpenAPI 3.0 spec object — serialize with JSON.stringify or a YAML lib
// Mirrors all routes generated by @eloquentjs/api:
//   GET/POST /api/users
//   GET/PUT/PATCH/DELETE /api/users/{id}
//   GET /api/users/trashed  (if softDeletes)
//   POST /api/users/{id}/restore  (if softDeletes)

Source Stubs

import {
  generateModelStub,
  generateMigrationStub,
  generateFactoryStub,
  generateSeederStub,
} from '@eloquentjs/codegen'

// Model class stub
const modelCode = generateModelStub(schema, {
  importPath:   '@eloquentjs/core',
  withComments: true,
})

// Migration with smart template detection
const migCode = generateMigrationStub('create_users_table')   // → CREATE TABLE template
const migCode = generateMigrationStub('add_avatar_to_users')  // → ALTER TABLE template
const migCode = generateMigrationStub('create_users_table', schema) // with typed columns from schema

// Factory with auto faker hints (name → faker.person.fullName(), email → faker.internet.email(), etc.)
const factCode = generateFactoryStub(schema, { modelsPath: '../models' })

// Seeder
const seedCode = generateSeederStub(schema, { factoriesPath: '../factories' })

Render Engine

The render engine ties everything together — loads model files from disk and writes output:

import {
  loadModelsFromDir,
  loadModelsByName,
  renderGraphql,
  renderTypeScript,
  renderOpenApi,
  renderStubs,
} from '@eloquentjs/codegen/render'

// Load all models from a directory
const models = await loadModelsFromDir('./app/models')

// Load specific models by name
const models = await loadModelsByName('./app/models', ['User', 'Post'])

// Generate and write schema.graphql
await renderGraphql({
  models,               // pass live classes...
  // modelsDir: './app/models',  // ...or load from directory
  outputFile: 'schema.graphql',
  options: { pagination: 'offset', subscriptions: true },
})

// Generate and write models.d.ts
await renderTypeScript({
  models,
  outputFile: 'src/types/models.d.ts',
})

// Generate and write openapi.json or openapi.yaml
await renderOpenApi({
  models,
  outputFile: 'docs/openapi.json',
  format:     'json',   // 'json' | 'yaml'
  options:    { title: 'My API' },
})

// Generate all stubs for a descriptor (no DB connection needed)
const stubs = renderStubs(schema)
// { model: '...', migration: '...', factory: '...', seeder: '...' }

Using with @eloquentjs/graphql

@eloquentjs/graphql uses @eloquentjs/codegen internally. You don't need to call codegen directly for GraphQL — just use buildSchema() or the new buildSchemaFromDir():

import { buildSchema, buildSchemaFromDir } from '@eloquentjs/graphql'

// From live classes (original API — unchanged)
const { typeDefs, resolvers } = buildSchema([User, Post, Comment])

// From a models directory (new — uses codegen render engine)
const { typeDefs, resolvers } = await buildSchemaFromDir('./app/models', {
  subscriptions: true,
  auth: async (ctx) => authenticateUser(ctx),
})

Using with @eloquentjs/cli

The CLI's make:model, make:migration, make:factory, and make:seeder commands use codegen stubs when @eloquentjs/codegen is installed, automatically producing richer output. If codegen is not installed, the CLI falls back to its own inline generators — no hard dependency.

The generate:* commands require codegen:

eloquent generate:graphql           # writes schema.graphql
eloquent generate:types             # writes models.d.ts
eloquent generate:openapi           # writes openapi.json

See the @eloquentjs/cli README for full details.


Exports

| Import path | Exports | | -------------------------------- | ------------------------------------------------------------------------------------------------------------ | | @eloquentjs/codegen | introspect, introspectAll, resolveCastType, CAST_TYPE_MAP, all templates, all render functions | | @eloquentjs/codegen/introspect | introspect, introspectAll, resolveCastType, CAST_TYPE_MAP | | @eloquentjs/codegen/templates | All template generators | | @eloquentjs/codegen/render | loadModelsFromDir, loadModelsByName, renderGraphql, renderTypeScript, renderOpenApi, renderStubs |


License

MIT