@schafevormfenster/eslint-plugin
v0.0.8
Published
This package contains **Custom ESLint Rules** that enforce logging, architectural, REST, testing, and other domain-specific patterns for the `@schafevormfenster` platform. It translates our internal guidelines into automated checks that run before code is
Downloads
679
Readme
@schafevormfenster/eslint-plugin
This package contains Custom ESLint Rules that enforce logging, architectural, REST, testing, and other domain-specific patterns for the @schafevormfenster platform. It translates our internal guidelines into automated checks that run before code is committed or deployed.
Purpose
This custom ESLint plugin serves three key functions:
- Enforcement: Automates the verification of internal coding guides (e.g., "Always log before throwing," "Include required API route files").
- Education: Provides helpful error messages to guide developers towards correct patterns during development.
- Safety: Prevents common domain-specific mistakes (e.g., logging sensitive keys, missing cache headers in GET handlers).
Integration
This plugin is designed to be used via @schafevormfenster/eslint-config, which provides pre-configured rule sets for different project types. The plugin integrates seamlessly into your development workflow, running checks during:
- Local development (IDE integration)
- Pre-commit hooks
- CI/CD pipelines
Documentation Structure
This plugin provides two types of documentation:
📚 Coding Instructions (docs/instructions/)
Living guidelines for engineers and AI coding agents. These documents describe how to write code that complies with our architectural patterns:
- logging-guide.md - Structured logging with pino
- rest-service-design-guide.md - REST API design patterns
- caching-guide.md - Caching strategies and limitations
- rest-api-e2e-testing-guide.md - E2E testing patterns
- And more...
For Engineers and AI Agents: Consult these instruction documents as your primary coding guidelines. See INSTRUCTIONS.md for details on how to use these guides.
For Consuming Applications: Maintain an AGENTS.md file in your project root that references these instruction documents so AI coding agents know to follow them before ESLint enforcement runs. See INSTRUCTIONS.md for the recommended pattern.
📋 Rule Catalog (docs/rules/)
Technical documentation for each ESLint rule, including examples of correct and incorrect code:
- enforce-api-route-structure.md - Required files for API routes
- enforce-log-before-throw.md - Logging before throwing errors
- no-sensitive-log-keys.md - Prevent logging sensitive data
- And 21+ more rules...
See the full rule catalog below for a complete list organized by domain.
Semantic Module Architecture
We use a "Logical Monolith" structure. All custom rules live in this single package but are organized into semantic modules (domains). You can enable rules for specific domains without enabling everything.
Domains
- Logging: Enforces structured logging, pino usage, and error handling.
- Architecture: Enforces file naming conventions (kebab-case) and folder structures.
- Caching: Enforces correct caching headers and HTTP method usage.
- REST: Enforces API route structure, schema exports, and path conventions.
- Stack: Enforces technology choices and prevents forbidden imports.
- Testing: Enforces testing best practices (env vars, error matching, file naming).
- Testing-E2E: Rules specific to end-to-end tests (Playwright).
- Testing-Unit: Rules specific to unit tests (Vitest).
- Testing-Integration: Rules specific to integration tests (Vitest).
- Security: (Planned) Prevents usage of insecure patterns.
- Queue: (Planned) Enforces correct retry behavior for queue handlers.
Usage
Typically, you will use this via @schafevormfenster/eslint-config. However, if you need to use it directly or want to understand the available modular configs:
import svfPlugin from "@schafevormfenster/eslint-plugin";
export default [
{
plugins: {
"@schafevormfenster": svfPlugin
},
// Option A: Use a preset (Recommended)
...svfPlugin.configs.logging.rules,
// Option B: Configure manually
rules: {
"@schafevormfenster/enforce-log-before-throw": "error",
"@schafevormfenster/no-sensitive-log-keys": "error"
}
},
// Example: Apply E2E testing rules to e2e directory
{
files: ["**/e2e/**/*.spec.ts"],
rules: {
...svfPlugin.configs["testing-e2e"].rules
}
},
// Example: Apply Unit testing rules to test files
{
files: ["**/*.test.ts"],
rules: {
...svfPlugin.configs["testing-unit"].rules
}
}
];Rules
💼 Configurations enabled in.
⚠️ Configurations set to warn in.
🔧 Automatically fixable by the --fix CLI option.
| Name | Description | 💼 | ⚠️ | 🔧 |
| :----------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------ | :----------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------ | :- |
| enforce-api-route-structure | Enforce presence of required files for API routes (route.test.ts, *.contract.ts, *.schema.ts) | | | |
| enforce-apitest-env-vars | Forbid process.env access in e2e/ unless variable starts with APITEST_ or is TEST_ENV |
| | |
| enforce-file-naming | Enforce kebab-case file naming with semantic suffixes | |
| |
| enforce-folder-structure | Enforce src/ folders: app, clients, lib, types, test, services | |
| |
| enforce-get-logger-category | Enforce getLogger to be called with a category string |
| | |
| enforce-log-before-throw | Enforce logging before throwing an error |
| | |
| enforce-log-level-before-throw | Enforce log level before throwing an error | |
| |
| enforce-schema-type-export | Every exported Zod schema must have a corresponding exported TypeScript type using z.infer |
| | |
| enforce-semantic-cache-headers | Ensure Cache-Control header is set in GET route handlers | |
| |
| enforce-structured-logging | Enforce structured logging (context object + message) |
| | |
| enforce-test-file-naming | Enforce *.spec.ts for Playwright tests and *.test.ts for Vitest tests |
| | |
| enforce-token-in-path | Enforce that API routes either include [token] in path or validate params.token in handler |
| | |
| no-env-preservation-in-tests | Forbid preserving and restoring process.env values in tests - tests should set their own env vars |
| | 🔧 |
| no-forbidden-imports | Forbid libraries that have preferred alternatives per tech stack | |
| |
| no-raw-logging | Prevent logging raw objects without a message | |
| |
| no-redundant-normalize-error | Detect and forbid calls to normalizeError() inside log.error(), as the logger handles this internally |
| | |
| no-reexport-files | Prevent files that primarily re-export from other modules | |
| |
| no-sensitive-log-keys | Prevent logging of sensitive keys |
| | |
| no-unsafe-log-property-access | Prevent unsafe property access in log context | |
| |
| no-use-cache-in-post | Forbid "use cache" directive in POST request handlers |
| | |
| one-function-per-file | Warn if a file exports multiple named functions | |
| |
| prefer-custom-logger | Enforce use of custom logger instead of console | |
| |
| prefer-loose-error-matching | Prefer regex matching over exact string matching for error messages | |
| |
| prefer-schema-extension | Warn if a Zod object is defined from scratch without using .extend() or .merge() when it could reuse common schemas | |
| |
| require-env-setup-in-tests | Require beforeEach to initialize env vars when tests access process.env | |
| 🔧 |
| require-error-in-log-error | Ensure log.error includes an error object | |
| |
