This file is for AI coding agents (and humans who like density) working on
@imqueue/validation. It captures how the codebase is built, tested and
structured, plus the invariants that are easy to get wrong. Read it before
making changes. For contribution process/terms see
CONTRIBUTING.md; for end-user docs see the
README and https://imqueue.org/.
@imqueue/validation is the input-validation layer of the @imqueue framework:
Zod-backed, field- and method-level validation exposed as native (TC39)
decorators (@validate, @validatable, @validated, plus schemaOf). It is
used by @imqueue/rpc services and by code
generated by @imqueue/pg-prisma to
validate RPC inputs.
- ESM only,
"type": "module". Useimport, notrequire(). Import sibling modules with the.jsextension (NodeNext resolves it to the.tssource), e.g.import { validate } from './validate.js'. - TypeScript,
module/moduleResolution: nodenext,target: es2024,verbatimModuleSyntax: true,isolatedModules: true,strict: true. Useimport type/import { type X }for type-only imports. - Node ≥ 22.12.
- Native TC39 decorators — the code relies on the standard decorator emit,
not
experimentalDecoratorsand notreflect-metadata. Do not enableexperimentalDecorators; it changes decorator semantics and would break the buffer/seal mechanism. - Single runtime dependency:
zod. Do not add heavyweight deps; this package is meant to stay small. - Lint/format:
oxlint+oxfmt. Runnpm run formatbefore committing; CI checksnpm run format:check. - Build emits
.js/.d.ts/.js.mapnext to sources; these are gitignored, not committed (buildrunsclean-compiledfirst). Never commit compiled output. removeCommentsis intentionallyfalse— downstream tooling relies on doc-blocks surviving compilation. Keep it that way.
npm install
npm run build # clean-compiled + tsc (emits alongside sources)
npm test # build + node:test over every test/**/*.spec.js
npm run lint # oxlint
npm run format # oxfmt (write) | npm run format:check (verify)
npm run test-coverage # tests + experimental coverage summary
npm run test-lcov # writes coverage/lcov.info| Path | Role |
|---|---|
index.ts |
Public entry: export * from './src/index.js' |
src/index.ts |
Barrel re-exporting the public API |
src/validate.ts |
The whole implementation: @validate, @validatable, @validated, schemaOf, and the Validator type. |
test/** |
node:test specs (*.spec.ts, run compiled). |
- Field decorators buffer; the class decorator seals. TC39 metadata
(
Symbol.metadata) is not reliably populated by esbuild/tsx, so@validatewrites into a module-level buffer and@validatable()moves that buffer into aWeakMapregistry keyed by the class. This is safe only because field decorators run before the class decorator and class bodies evaluate sequentially — do not introduce async between them or reorder. - A class field decorated with
@validaterequires the class to be@validatable()forschemaOfto see it. - Validators resolve lazily. A
@validatableclass used as a validator is resolved viaschemaOfon first use, so classes can reference each other regardless of definition order. - Invalid input throws the raw
ZodError(which surfaces to the RPC caller). Do not wrap or swallow it.
GPL-3.0. Commercial licensing for closed-source products: https://imqueue.com/.