@bobtail.software/eslint-plugin-b-durable
v1.0.5
Published
ESLint rules for b-durable workflows
Maintainers
Readme
eslint-plugin-b-durable
This plugin provides ESLint rules for the b-durable library.
The b-durable compiler transforms your async functions into a deterministic state machine. This process imposes certain restrictions on the code constructs that can be used inside a workflow.
This plugin helps you avoid common pitfalls by:
- Flagging unsupported language constructs—such as loops (
for,while) and nestedtry/catchblocks—only inside your workflow files. - Enforcing architectural boundaries: preventing your application code from importing workflow sources, and preventing workflow sources from importing compiled artifacts.
Installation
First, install ESLint, the TypeScript parser, and this plugin in your project:
# Using npm
npm install --save-dev eslint typescript-eslint @bobtail.software/eslint-plugin-b-durable
# Using yarn
yarn add --dev eslint typescript-eslint @bobtail.software/eslint-plugin-b-durable
# Using pnpm
pnpm add -D eslint typescript-eslint @bobtail.software/eslint-plugin-b-durableUsage
The plugin supports both modern "flat" config and legacy .eslintrc formats.
Flat Config ( eslint.config.js ) - Recommended
This is ESLint's modern configuration format. In your eslint.config.js, spread the recommended configuration into your config array.
// eslint.config.js
import js from '@eslint/js';
import tseslint from 'typescript-eslint';
import bDurablePlugin from '@bobtail.software/eslint-plugin-b-durable';
export default tseslint.config(
// Base configurations
js.configs.recommended,
...tseslint.configs.recommended,
// Simply spread the b-durable recommended config.
// The `...` is important!
...bDurablePlugin.configs.recommended
);Legacy Config ( .eslintrc.js )
If you are still using the traditional .eslintrc.js or .eslintrc.json file, extend the recommended-legacy configuration.
// .eslintrc.js
module.exports = {
root: true,
parser: '@typescript-eslint/parser',
plugins: [
'@typescript-eslint',
'@bobtail.software/b-durable',
],
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
// Note: use the 'recommended-legacy' config for .eslintrc files
'plugin:@bobtail.software/b-durable/recommended-legacy',
],
};✨ Automatic Scoping
The plugin intelligently applies rules where they make sense:
- Workflow-only rules (like
no-unsupported-constructs) are applied only to files ending in.workflow.ts,.workflow.mts, or.workflow.cts. - Project-wide rules (like
no-direct-workflow-import) are applied globally to enforce correct architectural boundaries.
Supported Rules
The following rules are included and enabled by default in the recommended configurations.
| Rule | Description | Scope |
| :---------------------------------------------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :------------ |
| @bobtail.software/b-durable/no-unsupported-constructs | Disallows the use of loops (for, while, do-while) and switch statements inside a bDurable workflow. | Workflow Only |
| @bobtail.software/b-durable/no-nested-try | Disallows nesting try/catch statements inside a bDurable workflow. | Workflow Only |
| @bobtail.software/b-durable/no-direct-workflow-import | Enforces clean architectural boundaries for workflow imports. | Global |
Example: no-direct-workflow-import
This rule enforces two critical architectural principles:
1. Application code must use compiled workflows.
// ❌ Incorrect: An API file should not import the source workflow.
// In: src/api/start-process.ts
import { userOnboardingWorkflow } from '../workflows/onboarding.workflow'; // <-- ESLint error
// ✅ Correct: The API file should import the compiled workflow from the generated index.
// In: src/api/start-process.ts
import { userOnboardingWorkflow } from '../generated';2. Workflow source code must not depend on compiled artifacts.
// ✅ Correct: A workflow can import another source workflow for composition.
// In: src/workflows/main-orchestrator.workflow.ts
import { userOnboardingWorkflow } from './onboarding.workflow'; // <-- OK
// ❌ Incorrect: A source workflow cannot import a compiled workflow.
// In: src/workflows/main-orchestrator.workflow.ts
import { userOnboardingWorkflow } from '../generated/onboarding.workflow.compiled.mts'; // <-- ESLint errorContributing
Contributions are welcome! If you have ideas for new rules or improvements, please open an issue or a pull request.
License
This project is licensed under the GPL-3.0 License. See the LICENSE file for details.
