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

@bladelabs/dmn-zod

v0.4.1

Published

Generate Zod schemas from OMG DMN 1.4 metamodel — like drizzle-zod but for decision models

Readme

@bladelabs/dmn-zod

Generate Zod schemas from the OMG DMN 1.4 metamodel — like drizzle-zod but for decision models.

Install

npm install @bladelabs/dmn-zod dmn-moddle
# or
pnpm add @bladelabs/dmn-zod dmn-moddle

dmn-moddle provides the dmn13.json metamodel. zod is a peer dependency.

Usage

Golden shapes (pure absorption)

import { createDmnSchema, createDmnEnumSchema } from '@bladelabs/dmn-zod'

// Generate a complete DecisionTable schema from the metamodel
export const DecisionTableShape = createDmnSchema('DecisionTable')

// Generate an enum schema
export const HitPolicyShape = createDmnEnumSchema('HitPolicy')

Before (hand-authored — 190 lines):

import { z } from 'zod/v4'
import { InputClauseShape } from './input-clause.shape.js'
import { OutputClauseShape } from './output-clause.shape.js'
import { DecisionRuleShape } from './decision-rule.shape.js'
// ... 7 more imports

export const DecisionTableShape = z
  .object({
    id: z.string().describe('Unique identifier...'),
    description: z.string().optional().describe('Human-readable...'),
    extensionElements: ExtensionElementsShape.optional().describe('Container for...'),
    extensionAttribute: z.array(ExtensionAttributeShape).optional().describe('Array of...'),
    label: z.string().optional().describe('Display label...'),
    typeRef: z.string().optional().describe('Reference to...'),
    input: z.array(InputClauseShape).optional().describe('Array of input clauses...'),
    output: z.array(OutputClauseShape).optional().describe('Array of output clauses...'),
    annotation: z.array(RuleAnnotationClauseShape).optional().describe('...'),
    rule: z.array(DecisionRuleShape).optional().describe('Array of decision rules...'),
    hitPolicy: HitPolicyShape.optional().describe('Hit policy governing...'),
    aggregation: BuiltinAggregatorShape.optional().describe('Aggregation function...'),
    preferredOrientation: DecisionTableOrientationShape.optional().describe('Visual layout...'),
    outputLabel: z.string().optional().describe('Display label for...'),
  })
  .describe('DMN decision table...')
  .meta({
    id: 'zeroh:dmn/decision-table',
    prefLabel: 'DMN Decision Table',
    definition: '...',
    broader: ['zeroh:dmn/expression'],
    related: ['zeroh:dmn/input-clause', ...],
    exactMatch: ['omg-dmn:DecisionTable'],
    wasDerivedFrom: ['https://www.omg.org/spec/DMN/1.4/PDF', ...],
    cascadeGroup: 'dmn',
    name: 'DecisionTableShape',
    description: '...',
    version: '1.0.0',
    category: 'dmn',
    standards_provenance: { ... },
  }) satisfies z.ZodType<DmnDecisionTable>

After (generated — 1 line):

import { createDmnSchema } from '@bladelabs/dmn-zod'

export const DecisionTableShape = createDmnSchema('DecisionTable')

Same fields. Same .describe() text. Same .meta() with provenance. One line.

Domain shapes (refined + extended)

import { z } from 'zod/v4'
import { createDmnSchema } from '@bladelabs/dmn-zod'

// Mudarabah compliance decision — extends golden DMN shape
export const MudarabahDecisionShape = createDmnSchema('DecisionTable', {
  // Refine: tighten hitPolicy for Islamic finance
  refinements: {
    hitPolicy: (s) => s.default('FIRST'),
  },
  // Extend: add domain-specific fields
  extensions: {
    obligation_refs: z.array(z.string()).describe('AAOIFI SS-13 obligations'),
    is_hard_gate: z.boolean().describe('Blocks workflow if failed'),
  },
  // Override meta for domain identity
  metaOverrides: {
    id: 'zeroh:grc-islamic/mudarabah-decision',
    cascadeGroup: 'grc-islamic-finance',
  },
})

Explicit metamodel path

If dmn-moddle isn't in node_modules, provide the path:

import { initDmnMetamodel, createDmnSchema } from '@bladelabs/dmn-zod'

initDmnMetamodel('/path/to/dmn13.json')
const schema = createDmnSchema('DecisionTable')

Subpath imports

// Main API
import { createDmnSchema } from '@bladelabs/dmn-zod'

// Schema module directly
import { createDmnSchema } from '@bladelabs/dmn-zod/schema'

// Metamodel types and reader
import type { ModdleDescriptor } from '@bladelabs/dmn-zod/metamodel'

Architecture

Follows drizzle-zod's 6-layer pattern:

  1. EntrycreateDmnSchema(typeName, options?)
  2. Introspect — reads dmn13.json metamodel
  3. Map types — moddle types to Zod (String to z.string(), Enum to z.enum(), etc.)
  4. Inheritance — flattens superClass chain (DMNElement to NamedElement to Expression to ...)
  5. Refinements — callbacks or overrides per field (drizzle-zod pattern)
  6. Meta — auto-populates .meta() with OMG DMN 1.4 provenance

Plus a description layer from descriptions.ts — hand-authored semantic descriptions for every field, since the metamodel has no annotations.

API

| Function | Input | Output | |---|---|---| | createDmnSchema(type, opts?) | DMN type name | z.ZodObject with .meta() | | createDmnEnumSchema(enum, opts?) | DMN enum name | z.ZodEnum with .meta() | | initDmnMetamodel(path) | File path or object | void (configures reader) | | getDmnTypeNames() | — | string[] of all type names | | getDmnEnumNames() | — | string[] of all enum names | | getDmnTypeProperties(type) | DMN type name | ModdleProperty[] | | registerDmnSchema(type, schema) | Name + schema | void (for cross-type refs) |

Test

pnpm test          # 124 tests
  • 28 schema smoke tests (fields, meta, refinements, parse)
  • 96 gold-set parity tests (generated vs hand-authored for all 49 types)

Upgrading (when OMG releases a new DMN version)

When dmn-moddle ships a new version (e.g., DMN 1.5):

# 1. Update the moddle dependency
pnpm update dmn-moddle

# 2. Copy the new descriptor into the package
cp node_modules/dmn-moddle/resources/dmn/json/*.json src/data/

# 3. Update the spec constants (one file, ~5 fields)
#    Edit src/standard-config.ts:
#      version: '1.5'
#      fullName: 'OMG Decision Model and Notation 1.5'
#      specPdfUrl: 'https://www.omg.org/spec/DMN/1.5/PDF'

# 4. Regenerate types and verify
pnpm generate:overloads   # regenerates types.generated.ts
pnpm check                # build + test + type-check + publint

The package derives metadata from the moddle JSON descriptor at runtime (prefix, uri, type names, inheritance chains). Only the declared constants in standard-config.ts need manual updating — everything else regenerates automatically.

Architecture

src/
  data/dmn13.json          # Bundled moddle descriptor (copied from dmn-moddle)
  standard-config.ts       # Spec constants — the ONE file to edit on upgrade
  metamodel.ts             # Reads descriptor, resolves inheritance chains
  descriptions.ts          # Hand-authored field descriptions from OMG spec
  schema.ts                # Schema factory — derives all meta from config + descriptor
  types.generated.ts       # Auto-generated: type names, interfaces, TYPE_CHAINS
scripts/
  generate-overloads.ts    # Codegen: reads descriptor → emits types.generated.ts