noctcore-contracts/zod-schema-naming
Every exported zod schema is a PascalCase const suffixed
Schema, paired with a same-named inferred type.
Recommended preset: error · Autofix: no · Suggestions: no · Type information: not needed
A contracts package is a shared spine. A uniform FooSchema + Foo pairing keeps the schema and
its TypeScript type discoverable and prevents a hand-authored duplicate type from drifting away from
the schema it is supposed to mirror.
What it flags
Section titled “What it flags”For every export const whose initializer is rooted at the z identifier (z.object(...),
z.string().min(1), z.union([...]), …):
- the const name must match
^[A-Z][A-Za-z0-9]*Schema$— otherwiseschemaNaming; - a correctly-named
FooSchemamust have a siblingexport type Foo(atypealias orinterface) — otherwisemissingType.
// not suffixed `Schema`export const Task = z.object({});
// no sibling inferred typeexport const TaskSchema = z.object({});export const TaskSchema = z.object({ id: z.string() });export type Task = z.infer<typeof TaskSchema>;What it does not flag
Section titled “What it does not flag”- Exported consts whose initializer is not rooted at
z(export const MAX = 10). - Zod schemas that are not exported.
- Consts ending in one of the configured
roleSuffixes(see Options).
Options
Section titled “Options”| Option | Type | Default | Meaning |
|---|---|---|---|
roleSuffixes |
string[] |
[] |
Const-name suffixes that opt a schema out of the *Schema rule (their naming is owned by wire-message-naming). |
With the default empty list the base convention applies to every exported zod schema. Codebases that
model wire messages as *Event / *Command / *Query discriminated-union members pass those
suffixes to carve them out:
'noctcore-contracts/zod-schema-naming': ['error', { roleSuffixes: ['Event', 'Command', 'Query'] }]// rule options: {"roleSuffixes":["Event","Command","Query"]}// carved out only when 'Command' is listed in roleSuffixesexport const RunTaskCommand = z.object({ type: z.literal('run-task') });When not to use it
Section titled “When not to use it”If your codebase does not import zod as z, or does not pair schemas with inferred types, this rule
will not fit — it keys off the z root identifier and the FooSchema/Foo pairing convention.