JSPM

  • Created
  • Published
  • Downloads 152
  • Score
    100M100P100Q107241F
  • License MIT

ESLint rules for FormSpec decorator DSL type safety

Package Exports

  • @formspec/eslint-plugin
  • @formspec/eslint-plugin/base

Readme

@formspec/eslint-plugin

ESLint rules for FormSpec TSDoc tags and Chain DSL usage.

Install

pnpm add -D @formspec/eslint-plugin @typescript-eslint/parser eslint

Flat Config

import formspec from "@formspec/eslint-plugin";

export default [...formspec.configs.recommended];

Strict

import formspec from "@formspec/eslint-plugin";

export default [...formspec.configs.strict];

Manual

import formspec from "@formspec/eslint-plugin";

export default [
  {
    plugins: {
      formspec,
    },
    rules: {
      "formspec/tag-recognition/no-unknown-tags": "warn",
      "formspec/tag-recognition/require-tag-arguments": "error",
      "formspec/value-parsing/valid-numeric-value": "error",
      "formspec/type-compatibility/tag-type-check": "error",
      "formspec/target-resolution/valid-path-target": "error",
      "formspec/constraint-validation/no-contradictions": "error",
      "formspec/constraint-validation/no-description-tag": "error",
    },
  },
];

Keeping Docs Current

pnpm --filter @formspec/eslint-plugin run fix:eslint-docs
pnpm --filter @formspec/eslint-plugin run check:eslint-docs

Rule Groups

Tag Recognition

  • tag-recognition/no-unknown-tags
  • tag-recognition/require-tag-arguments
  • tag-recognition/no-disabled-tags
  • tag-recognition/no-markdown-formatting

Value Parsing

  • value-parsing/valid-numeric-value
  • value-parsing/valid-integer-value
  • value-parsing/valid-regex-pattern
  • value-parsing/valid-json-value

Type Compatibility

  • type-compatibility/tag-type-check

Target Resolution

  • target-resolution/valid-path-target
  • target-resolution/valid-member-target
  • target-resolution/no-unsupported-targeting
  • target-resolution/no-member-target-on-object

Constraint Validation

  • constraint-validation/no-contradictions
  • constraint-validation/no-duplicate-tags
  • constraint-validation/no-description-tag
  • constraint-validation/no-contradictory-rules
  • constraint-validation/valid-discriminator

.formspec.yml Capability Rules

  • constraints-allowed-field-types
  • constraints-allowed-layouts

Base Entry Point

Extension authors can use @formspec/eslint-plugin/base for createConstraintRule(...), the shared JSDoc/type helpers used by the built-in rules, and the shared metadata-analysis helpers re-exported from @formspec/analysis.

Example with typescript-eslint parser services:

import { ESLintUtils } from "@typescript-eslint/utils";
import { analyzeMetadataForNode } from "@formspec/eslint-plugin/base";

export const rule = ESLintUtils.RuleCreator(() => "")({
  name: "require-explicit-api-name",
  meta: {
    type: "problem",
    docs: { description: "" },
    schema: [],
    messages: { missing: "Missing explicit apiName" },
  },
  defaultOptions: [],
  create(context) {
    const services = ESLintUtils.getParserServices(context);

    return {
      PropertyDefinition(node) {
        const tsNode = services.esTreeNodeToTSNodeMap.get(node);
        const analysis = analyzeMetadataForNode({
          program: services.program,
          node: tsNode,
        });

        if (analysis?.resolvedMetadata?.apiName?.source !== "explicit") {
          context.report({ node, messageId: "missing" });
        }
      },
    };
  },
});

Rules

🔧 Automatically fixable by the --fix CLI option.

Name Description 🔧
constraint-validation/no-contradictions Reports contradictory FormSpec constraint combinations
constraint-validation/no-contradictory-rules Reports contradictory FormSpec conditional rules on the same behavioral axis
constraint-validation/no-description-tag Bans @description, which is not a standard TSDoc tag
constraint-validation/no-double-underscore-fields Warns when a property starts with "__", indicating it will be excluded from the generated schema
constraint-validation/no-duplicate-tags Reports duplicate FormSpec tags on the same field target
constraint-validation/valid-discriminator Validates declaration placement, targeting, and source operands for @discriminator
constraints-allowed-field-types Validates that field types are allowed by the project's constraints
constraints-allowed-layouts Validates that layout constructs (group, conditionals) are allowed by the project's constraints
tag-recognition/no-disabled-tags Reports FormSpec tags disabled by project configuration
tag-recognition/no-markdown-formatting Forbids Markdown formatting in configured FormSpec tag values 🔧
tag-recognition/no-unknown-tags Reports FormSpec tags that are not part of the specification
tag-recognition/require-tag-arguments Requires arguments for FormSpec tags that need values
target-resolution/no-member-target-on-object Disallows member-target syntax on non-string-literal-union fields
target-resolution/no-unsupported-targeting Disallows path or member target syntax on tags that do not support it
target-resolution/valid-member-target Validates member-target references against string literal union fields
target-resolution/valid-path-target Validates path-target references against the resolved field type
type-compatibility/tag-type-check Ensures FormSpec tags are applied to compatible field types
value-parsing/valid-integer-value Validates integer-valued FormSpec tags
value-parsing/valid-json-value Validates JSON-valued FormSpec tags
value-parsing/valid-numeric-value Validates numeric-valued FormSpec tags
value-parsing/valid-regex-pattern Validates @pattern tag values as regular expressions

Example

class Example {
  /** @minimum 0 */
  age!: number;

  /** @uniqueItems */
  tags!: string[];
}

The plugin validates tag names, argument syntax, target paths, and type compatibility before your build gets to static schema generation.

License

This package is part of the FormSpec monorepo and is released under the MIT License. See LICENSE for details.