Skip to main content

Built and signed on GitHub Actions

Works with
This package works with Node.js, Deno, Bun
This package works with Node.js
This package works with Deno
This package works with Bun
JSR Score76%
License
MIT
Downloads1/wk
Published2 days ago (2.1.2)

Fedify linting rules and plugins

@fedify/lint: ESLint plugin for Fedify

JSR npm Follow @fedify@hollo.social

This package is available since Fedify 2.0.0.

This package provides Deno Lint and ESLint plugin with lint rules specifically designed for Fedify applications. It helps you catch common mistakes and enforce best practices when building federated server apps with Fedify.

The plugin includes rules that check for:

  • Proper actor ID configuration
  • Required actor properties (inbox, outbox, followers, etc.)
  • Correct URL patterns for actor collections
  • Public key and assertion method requirements
  • Collection filtering implementation

Deno Lint configuration example

// deno.json

{
  "lint": {
    "plugins": {
      "@fedify/lint": "jsr:@fedify/lint"
    },
    "rules": {
      "@fedify/lint/actor-id-required": "error",
      "@fedify/lint/actor-id-mismatch": "error",
      "@fedify/lint/actor-inbox-property-required": "warn"
      // ... other rules
    }
  }
}

ESLint configuration example

// eslint.config.ts

import fedifyLint from "@fedify/lint";

export default fedifyLint;

Features

The @fedify/lint package provides comprehensive linting rules for Fedify federation code:

Actor validation rules

  • actor-id-required: Ensures all actors have an id property
  • actor-id-mismatch: Validates that actor IDs match the expected URI from Context.getActorUri()
  • actor-public-key-required: Ensures actors have public keys for HTTP Signatures
  • actor-assertion-method-required: Validates assertion methods for Object Integrity Proofs

Collection property rules

  • actor-inbox-property-required: Ensures inbox is defined when setInboxListeners is set
  • actor-inbox-property-mismatch: Validates inbox URI from getInboxUri
  • actor-outbox-property-required: Ensures outbox is defined when setOutboxDispatcher is set
  • actor-outbox-property-mismatch: Validates outbox URI from getOutboxUri
  • actor-followers-property-required: Ensures followers is defined when setFollowersDispatcher is set
  • actor-followers-property-mismatch: Validates followers URI from getFollowersUri
  • actor-following-property-required: Ensures following is defined when setFollowingDispatcher is set
  • actor-following-property-mismatch: Validates following URI from getFollowingUri
  • actor-liked-property-required: Ensures liked is defined when setLikedDispatcher is set
  • actor-liked-property-mismatch: Validates liked URI from getLikedUri
  • actor-featured-property-required: Ensures featured is defined when setFeaturedDispatcher is set
  • actor-featured-property-mismatch: Validates featured URI from getFeaturedUri
  • actor-featured-tags-property-required: Ensures featuredTags is defined when setFeaturedTagsDispatcher is set
  • actor-featured-tags-property-mismatch: Validates featuredTags URI from getFeaturedTagsUri
  • actor-shared-inbox-property-required: Ensures sharedInbox is defined when setInboxListeners is set
  • actor-shared-inbox-property-mismatch: Validates sharedInbox URI from getInboxUri

Other rules

  • collection-filtering-not-implemented: Warns about missing collection filtering implementation (setFollowersDispatcher only for now)

Installation

::: code-group

deno add jsr:@fedify/lint
npm add -D @fedify/lint
pnpm add -D @fedify/lint
yarn add -D @fedify/lint
bun add -D @fedify/lint

:::

Usage (Deno Lint)

Basic setup

Add the plugin to your deno.json configuration file:

{
  "lint": {
    "plugins": ["jsr:@fedify/lint"]
  }
}

By default, this enables all recommended rules.

Custom configuration

You can customize which rules to enable and their severity levels:

{
  "lint": {
    "plugins": ["jsr:@fedify/lint"],
    "rules": {
      "tags": ["recommended"],
      "include": [
        "@fedify/lint/actor-id-required",
        "@fedify/lint/actor-id-mismatch"
      ],
      "exclude": [
        "@fedify/lint/actor-featured-property-required"
      ]
    }
  }
}

Running Deno Lint

After setting up the configuration, run Deno's linter:

deno lint

You can also specify which files to lint:

deno lint federation.ts
deno lint src/federation/

Usage (ESLint)

Basic setup

Add the plugin to your ESLint configuration file (e.g., eslint.config.ts or eslint.config.js):

import fedifyLint from "@fedify/lint";

// If your `createFederation` code is in `federation.ts` or `federation/**.ts`
export default fedifyLint; 

// Or specify your own federation files
export default {
  ...fedifyLint,
  files: ["my-own-federation.ts"],
};

// If you use other ESLint configurations

export default [
  otherConfig,
  fedifyLint,
];

The default configuration applies recommended rules to files that match common federation-related patterns (e.g., federation.ts, federation/*.ts).

Custom configuration

You can customize which files to lint and which rules to enable:

import { plugin } from "@fedify/lint";

export default [{
  files: ["src/federation/**/*.ts"],  // Your federation code location
  plugins: {
    "@fedify/lint": plugin,
  },
  rules: {
    "@fedify/lint/actor-id-required": "error",
    "@fedify/lint/actor-id-mismatch": "error",
    "@fedify/lint/actor-inbox-property-required": "warn",
    // ... other rules
  },
}];

Using configurations

The plugin provides two preset configurations:

Enables critical rules as errors and optional rules as warnings:

import fedifyLint from "@fedify/lint";

export default fedifyLint;

Strict

Enables all rules as errors:

import { plugin } from "@fedify/lint";

export default [{
  files: ["**/*.ts"],
  ...plugin.configs.strict,
}];

Example

Here's an example of code that would trigger lint errors:

// ❌ Wrong: Using relative URL for actor ID
import { createFederation, Person } from "@fedify/fedify";

const federation = createFederation({ /* ... */ });

federation.setActorDispatcher(
  "/{identifier}",
  (_ctx, identifier) => {
    return new Person({
      id: new URL(`/${identifier}`),  // ❌ Should use ctx.getActorUri()
      name: "Example User",
    });
  },
);

Corrected version:

// ✅ Correct: Using Context.getActorUri() for actor ID
import { createFederation, Person } from "@fedify/fedify";

const federation = createFederation({ /* ... */ });

federation.setActorDispatcher(
  "/{identifier}",
  (ctx, identifier) => {
    return new Person({
      id: ctx.getActorUri(identifier),  // ✅ Correct
      name: "Example User",
      inbox: ctx.getInboxUri(identifier),
      outbox: ctx.getOutboxUri(identifier),
      followers: ctx.getFollowersUri(identifier),
      // ... other required properties
    });
  },
);

Running the linter

Deno Lint

Run Deno's linter with the plugin enabled:

deno lint

You can also specify which files or directories to lint:

deno lint federation.ts
deno lint src/federation/

ESLint

Set up your ESLint configuration as shown above and add a follwing script on package.json:

{
  "scripts": {
    "lint": "eslint ."
  }
}
After setting up the configuration, run ESLint on your codebase:

:: code-group

npm run lint
pnpm lint
yarn lint
bun lint

:::

or run the linter directly via command line:

:: code-group

npx eslint .
pnpx eslint .
yarn eslint .
bunx eslint .

:::

See also

Built and signed on
GitHub Actions

Report package

Please provide a reason for reporting this package. We will review your report and take appropriate action.

Please review the JSR usage policy before submitting a report.

Add Package

deno add jsr:@fedify/lint

Import symbol

import lint from "@fedify/lint";
or

Import directly with a jsr specifier

import lint from "jsr:@fedify/lint";