Thanks for your interest! apilint is built so that adding a rule is small, isolated, and testable.
git clone https://github.com/didrod205/apilint.git
cd apilint
npm install
npm test # vitest
npm run typecheck # tsc --noEmit
npm run build # tsup -> dist/
node dist/cli.js scan examples/petstore-bad.yamlsrc/
parse/yaml.ts # dependency-free YAML subset parser
parse/index.ts # JSON/YAML auto-detection -> OpenApiDoc
model.ts # safe accessors: eachOperation, resolveRef, collectRefs
rules/ # structure / info / operations / parameters / naming /
# schemas / security (the interesting part) + registry
score.ts # per-category & overall score, A–F grade
report/ # json | markdown | console renderers
config.ts, types.ts, index.ts, loader.ts, cli.ts
tests/ # vitest specs (incl. YAML parser)
examples/ # petstore-good.yaml, petstore-bad.yaml, config + sample reports
-
Add the rule id to
RuleIdandRULE_LABELSinsrc/types.ts. -
Write the rule in the relevant
src/rules/*.ts:import type { Issue } from "../types.js"; import { eachOperation } from "../model.js"; import { makeIssue, type Rule, type RuleContext } from "./context.js"; export const myRule: Rule = { id: "my-rule", category: "operations", severity: "warning", run(ctx: RuleContext): Issue[] { const issues: Issue[] = []; for (const { path, method, op } of eachOperation(ctx.doc)) { // inspect op and push makeIssue(this, ctx, { message, location, fix }) } return issues; }, };
-
Register it in
src/rules/index.ts(order = report order). -
Add a test in
tests/rules.test.tsproving it fires (and doesn't on a clean spec).
- Deterministic. No randomness, no network, no time-dependent output. Same spec must always produce the same report.
- Opinionated but tunable. Ship sensible defaults; let users disable/retune.
- Static-only. Parse the document; don't execute or fetch anything.
- Dependency-light. Only
cacandpicocolorsat runtime — the YAML parser is intentionally hand-rolled. - Actionable. Every issue carries a
locationand a concretefix.
-
npm run typecheckpasses -
npm testpasses (tests added for new behavior) - New rules have a stable id, a label, and a
fixmessage -
CHANGELOG.mdupdated for user-facing changes - Regenerated
examples/sample-report.*if output changed
This project follows the Contributor Covenant.