@bladelabs/cmmn-zod
v0.5.1
Published
Generate Zod schemas from OMG CMMN 1.1 metamodel — like drizzle-zod but for case management models
Keywords
Readme
@bladelabs/cmmn-zod
Generate Zod schemas from the OMG CMMN 1.1 metamodel — like drizzle-zod but for case management models.
Install
npm install @bladelabs/cmmn-zod cmmn-moddle
# or
pnpm add @bladelabs/cmmn-zod cmmn-moddlecmmn-moddle provides the cmmn.json metamodel descriptor. zod is a peer dependency.
Usage
Golden shapes (pure absorption)
import { createCmmnSchema, createCmmnEnumSchema } from '@bladelabs/cmmn-zod'
// Generate a complete Stage schema from the metamodel
export const StageShape = createCmmnSchema('Stage')
// Generate an enum schema
export const AssociationDirectionShape = createCmmnEnumSchema('AssociationDirection')Domain shapes (refined + extended)
import { createCmmnSchema } from '@bladelabs/cmmn-zod'
import { z } from 'zod/v4'
// Add Islamic finance extensions to a CMMN Stage
export const IslamicCaseStage = createCmmnSchema('Stage', {
extensions: {
maqasid_refs: z.array(z.string()),
obligation_refs: z.array(z.string()),
},
metaOverrides: {
id: 'zeroh:grc-islamic/murabaha-stage',
cascadeGroup: 'grc-islamic-finance',
},
})Coercion for XML parsing
// XML attributes come in as strings — coerce to native types
const StageXmlSchema = createCmmnSchema('Stage', { coerce: true })
StageXmlSchema.parse({ id: 'stage-1', autoComplete: 'true' }) // autoComplete → boolean trueProject-wide factory
import { createCmmnSchemaFactory } from '@bladelabs/cmmn-zod'
const { createCmmnSchema, createCmmnEnumSchema } = createCmmnSchemaFactory({
coerce: true,
metaOverrides: { cascadeGroup: 'grc-islamic' },
})
// All schemas from this factory inherit coerce + cascadeGroup
const stage = createCmmnSchema('Stage')
const dir = createCmmnEnumSchema('AssociationDirection')Discovery helpers
import {
getCmmnTypeNames,
getCmmnEnumNames,
getCmmnTypeProperties,
} from '@bladelabs/cmmn-zod'
getCmmnTypeNames() // ['ApplicabilityRule', 'Artifact', 'Association', ...]
getCmmnEnumNames() // ['AssociationDirection', 'CaseFileItemTransition', ...]
getCmmnTypeProperties('Stage') // all inherited + own propertiesCMMN Metamodel Summary
Source: OMG CMMN 1.1 — [email protected] (resources/cmmn/json/cmmn.json)
- 56 complex types — Case, Stage, HumanTask, CaseFileItem, Sentry, PlanItem, ...
- 5 enumerations — AssociationDirection, CaseFileItemTransition, MultiplicityEnum, PlanItemTransition, RelationshipDirection
- Namespace URI:
http://www.omg.org/spec/CMMN/20151109/MODEL - Prefix:
cmmn
Key inheritance chains
CMMNElement
├─ Case
├─ CaseFile
├─ CaseFileItem
├─ Criterion (abstract)
│ ├─ EntryCriterion
│ └─ ExitCriterion
├─ Definitions
├─ Parameter (abstract)
│ ├─ CaseParameter
│ ├─ CaseRoles
│ ├─ DecisionParameter
│ └─ ProcessParameter
├─ PlanItemDefinition (abstract)
│ ├─ EventListener
│ │ └─ TimerEventListener
│ │ └─ UserEventListener
│ ├─ Milestone
│ ├─ PlanFragment
│ │ └─ Stage ← primary container
│ └─ Task (abstract)
│ ├─ CaseTask
│ ├─ DecisionTask
│ ├─ HumanTask
│ └─ ProcessTask
├─ Sentry
├─ StartTrigger (abstract)
│ ├─ CaseFileItemStartTrigger
│ └─ PlanItemStartTrigger
└─ TableItem (abstract)
├─ DiscretionaryItem
└─ PlanningTableKnown quirk: "emumerations" typo in cmmn.json
[email protected] ships cmmn.json with the key "emumerations" (extra 'm') instead of "enumerations". This package normalises it transparently on load — consumers see enumerations throughout.
API Reference
createCmmnSchema(typeName, options?)
Creates a z.ZodObject from any CMMN complex type. Resolves the full inheritance chain, applies refinements, and populates .meta() with SKOS identity and standards provenance.
| Option | Type | Description |
|--------|------|-------------|
| refinements | Record<key, ZodType \| fn> | Per-field override or callback (type-safe when typeName is a literal) |
| extensions | Record<string, ZodType> | Extra fields beyond the CMMN spec |
| metaOverrides | Record<string, unknown> | Override auto-generated .meta() fields |
| coerce | boolean | Use z.coerce.* for XML string→native conversion |
createCmmnEnumSchema(enumName, options?)
Creates a z.ZodEnum from any CMMN enumeration. Populates .meta() with the same provenance shape.
createCmmnSchemaFactory(defaults)
Returns { createCmmnSchema, createCmmnEnumSchema, createCmmnValidationSchema, createCmmnPartialSchema } with defaults pre-applied.
createCmmnValidationSchema(typeName, options?)
Strict schema — all fields required. Use for inbound validation.
createCmmnPartialSchema(typeName, options?)
Partial schema — all fields optional. Use for PATCH-style updates.
Relationship to @bladelabs/dmn-zod
This package mirrors @bladelabs/dmn-zod exactly, targeting CMMN 1.1 instead of DMN 1.4. Both follow the same drizzle-zod pattern: read metamodel → map properties → resolve inheritance → apply refinements → attach provenance meta.
In the ZeroH GRC pipeline:
- DMN handles decision logic (
dmn-zod) - CMMN handles case orchestration (
cmmn-zod) — the when and how around decisions
Upgrading (when OMG releases a new CMMN version)
pnpm update cmmn-moddle # 1. Update moddle
cp node_modules/cmmn-moddle/resources/cmmn/json/*.json src/data/ # 2. Copy descriptor
# 3. Edit src/standard-config.ts (version, fullName, specPdfUrl)
pnpm generate:overloads && pnpm check # 4. Regenerate + verifySee src/standard-config.ts for the ~5 fields to update. Everything else derives from the moddle JSON automatically.
Architecture
src/
data/cmmn.json # Bundled moddle descriptor (copied from cmmn-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_CHAINSLicense
Apache-2.0 — Copyright 2026 Blade Labs Inc.
