Custom rules
You can define custom rules that can be enforced via the createRule function.
import { writeFile } from "node:fs/promises";import { createRule, defineConfig } from "monoswan";
const requireDescription = createRule(() => ({ name: "require-description", check: (context) => context.packageJson.description == null ? [ { message: "Expected a description", packageContext: context, filePath: `${context.packagePath}/package.json`, locator: { type: "json", locator: ["description"] }, autofix: async ({ packageJson, packagePath }) => { const updated = { ...packageJson, description: "TODO" }; await writeFile( `${packagePath}/package.json`, `${JSON.stringify(updated, null, "\t")}\n`, ); }, }, ] : [],}));
export default defineConfig({ rules: [requireDescription()],});A rule receives packageName, packagePath, packageJson, and the resolved variant. Any other files may be loaded directly via node:fs APIs. Run monoswan lint --fix to apply returned autofixes.
Custom options
Section titled “Custom options”You can define custom options for consumers as part of the rule definition.
import { createRule, defineConfig } from "monoswan";
interface RequireFieldOptions { field: "description" | "license";}
const requireField = createRule<RequireFieldOptions>(({ field }) => ({ name: `require-${field}`, check: (context) => context.packageJson[field] == null ? [ { message: `Expected ${field}`, packageContext: context, filePath: `${context.packagePath}/package.json`, locator: { type: "json", locator: [field] }, }, ] : [],}));
export default defineConfig({ rules: [requireField({ field: "license" }, { ignore: { paths: ["examples/**"] } })],});