npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@open-tomato/eslint-plugin-define-config

v0.0.0

Published

ESLint rules that surface @open-tomato/define-config merge and step-graph diagnostics at the config entry that causes them.

Downloads

118

Readme

eslint-plugin-define-config

ESLint plugin for validating config entries and schemas with @open-tomato/define-config.

Install

npm install --save-dev @open-tomato/eslint-plugin-define-config

Requires ESLint ≥9 and @open-tomato/define-config ≥0.4.0.

Usage

Add the plugin's recommended preset to your ESLint flat config, alongside settings that describe your config files:

import defineConfigPlugin from '@open-tomato/eslint-plugin-define-config';

import defaults from './defaults/rafa.config';
import { steps } from './steps';

export default [
  defineConfigPlugin.configs.recommended,
  {
    settings: {
      'define-config': {
        defaults,
        steps,
      },
    },
  },
];

The plugin will report @open-tomato/define-config diagnostics on the config entries that cause them. For example, a duplicate-key diagnostic surfaces at the line where a key is set a second time within the same layer.

Supported File Shape

The plugin reports on TypeScript files that export config entries built with @open-tomato/define-config's defineConfig() function:

// rafa.config.ts — config entries, one or more per file
import { defineConfig } from '@open-tomato/define-config';

export default defineConfig([
  { timeout: 30, flows: { /* ... */ } },
  { timeout: 60 },  // also checked for duplicates and validity
]);

Config files should:

  • Use the defineConfig() wrapper for type safety and documentation
  • Export a default value (recognized by ESLint's linting scope)
  • Be discoverable by the loader's lookup glob pattern (commonly rafa.config.ts or config.ts)
  • Contain object literals (the plugin performs static analysis; identifiers and expressions are not analyzed for their values)

settings['define-config']

The plugin requires two settings keys:

defaults

The default layer config entries: an array of configuration objects returned by defineConfig(). These are merged first before any file-specific entries, and used to establish the baseline for detecting duplicates and validating required keys.

import { defineConfig } from '@open-tomato/define-config';

const config = defineConfig([
  { timeout: 30, flows: { ship: { /* ... */ } } },
]);

export const defaults = config;

steps

A StepRegistry object mapping step names to their declared outcomes. This is used to validate that handlers in flows reference only declared outcomes and steps.

import type { StepRegistry } from '@open-tomato/define-config';

export const steps: StepRegistry = {
  build: { outcomes: ['success', 'fail'] },
  deploy: { outcomes: ['success'] },
};

Each step maps to an object with an outcomes array; handlers in flows must target only outcomes that the step declares.

Recommended Preset

The recommended preset enables all rules at their default severity levels. Include it in your config:

import defineConfigPlugin from '@open-tomato/eslint-plugin-define-config';

export default [defineConfigPlugin.configs.recommended];

Rule Levels

| Rule | Level | Description | |------|-------|-------------| | define-config/settings | error | Missing or malformed settings | | define-config/duplicate-key | warn | A key set twice in the same layer | | define-config/required-dropped | error | A required key was removed by an entry | | define-config/handler-conflict | error | Two handlers target the same outcome | | define-config/unknown-step | error | A handler targets a step not in the registry | | define-config/unknown-outcome | error | A handler targets an outcome the step doesn't declare | | define-config/impure-when | error | A $when condition is not pure (has side effects) | | define-config/cycle | error | A handler creates a cycle in the flow graph | | define-config/interactive-unattended | error | An interactive flow is marked unattended | | define-config/unreachable | warn | A step is unreachable from the flow's start step |

You can override any rule's level in your config:

import defineConfigPlugin from '@open-tomato/eslint-plugin-define-config';

export default [
  defineConfigPlugin.configs.recommended,
  {
    rules: {
      'define-config/duplicate-key': 'error',
      'define-config/unreachable': 'off',
    },
  },
];

What is Never Reported

The plugin does not report the following @open-tomato/define-config diagnostic codes:

  • schema — Schema validation errors (e.g., invalid type for a field). These are caught by TypeScript's type checker when you import and use the config via @open-tomato/define-config's useConfig().
  • load-failed — File I/O or parsing errors from the loader. These are issues with the config file's syntax or the loader's directory setup; ESLint already reports parser errors for TypeScript files.

Both of these are validation concerns that happen outside the merge and flow-graph phases the ESLint plugin analyzes.