diff --git a/.hongdown.toml b/.hongdown.toml index 37c02dcc2..00d2983dd 100644 --- a/.hongdown.toml +++ b/.hongdown.toml @@ -89,6 +89,7 @@ proper_nouns = [ "ngrok", "Object Integrity Proofs", "OpenTelemetry", + "Oxlint", "Piefed", "Pixelfed", "Pleroma", diff --git a/cspell.json b/cspell.json index b6a11b6bd..27ecb7644 100644 --- a/cspell.json +++ b/cspell.json @@ -83,6 +83,8 @@ "nuxt", "operatables", "optique", + "oxlint", + "oxlintrc", "phensley", "Pico", "Pixelfed", diff --git a/deno.json b/deno.json index 2740fe03e..7529eb5d6 100644 --- a/deno.json +++ b/deno.json @@ -33,6 +33,7 @@ "./examples/astro", "./examples/fresh", "./examples/hono-sample", + "./examples/lint/oxlint", "./examples/rfc-9421-test", "./test/smoke/harness" ], diff --git a/deno.lock b/deno.lock index bef73340b..a4c2aa1ba 100644 --- a/deno.lock +++ b/deno.lock @@ -149,6 +149,8 @@ "npm:miniflare@^4.20250523.0": "4.20250906.0", "npm:mysql2@^3.22.3": "3.22.3_@types+node@24.12.2", "npm:ora@^8.2.0": "8.2.0", + "npm:oxlint@*": "1.66.0", + "npm:oxlint@^1.66.0": "1.66.0", "npm:pkijs@^3.2.5": "3.4.0", "npm:pkijs@^3.3.3": "3.4.0", "npm:postgres@^3.4.7": "3.4.9", @@ -2548,6 +2550,101 @@ "@oxc-project/types@0.129.0": { "integrity": "sha512-3oz8m3FGdr2nDXVqmFUw7jolKliC4MoyXYIG2c7gpjBnzUWQpUGIYcXYKxTdTi+N2jusvt610ckTMkxdwHkYEg==" }, + "@oxlint/binding-android-arm-eabi@1.66.0": { + "integrity": "sha512-f7kq8N51T4phpzqfBpA2qaVTI/KrkCmNwaj3t/97I/WLTDI+UhlP5GL9eER+zVxBhtlx5rKXWByJU1/zDAvyaw==", + "os": ["android"], + "cpu": ["arm"] + }, + "@oxlint/binding-android-arm64@1.66.0": { + "integrity": "sha512-xu6QO71tdDS9mjmLZ3AqhtaVHBvdmsOKkYnReNNDgh+XiwnsipeQOIxbiYOOO0iAXycJ+GK0wdMSZP/2j/AmSg==", + "os": ["android"], + "cpu": ["arm64"] + }, + "@oxlint/binding-darwin-arm64@1.66.0": { + "integrity": "sha512-HZ24VimSOC7mxuEA99e0H2FS0C1yO3+iW13jPRAk+e2njsUs3QeAXsafCDyaIrV/MirdOVez+etQNQsJE43zNQ==", + "os": ["darwin"], + "cpu": ["arm64"] + }, + "@oxlint/binding-darwin-x64@1.66.0": { + "integrity": "sha512-awhj8ZvJrrRSnXj7V++rpZvTmnl99L6mi0B7gg7Cp7BN6cKpzuI481bHNLvXGA9GB1/oEgA3ponuyoAc6Md12A==", + "os": ["darwin"], + "cpu": ["x64"] + }, + "@oxlint/binding-freebsd-x64@1.66.0": { + "integrity": "sha512-KQF0oVV21/FjIqkRuL8Q1vh8ECsE5+ocdH5tcqTQ4ZnYuDVoYibQUNfqBjQaUsP6UIIda5Y75Wpm5p4RgQWiWw==", + "os": ["freebsd"], + "cpu": ["x64"] + }, + "@oxlint/binding-linux-arm-gnueabihf@1.66.0": { + "integrity": "sha512-9u1rgwZSEXWb30vbFZzQ78HVXBo0WCKNwJ3a2InRUTNMRng+PUDIoSFmA+m4HdUfBaIqftShq8J8qHc+eE/Vig==", + "os": ["linux"], + "cpu": ["arm"] + }, + "@oxlint/binding-linux-arm-musleabihf@1.66.0": { + "integrity": "sha512-Ynot2HR1bHxUaNWoC280MVTDfZuaWuP3XfSMRDhyuZrVjhzoaBCVFlw8h8qeZjWKVUBhPWFIxB7AQTlK8Z2WWg==", + "os": ["linux"], + "cpu": ["arm"] + }, + "@oxlint/binding-linux-arm64-gnu@1.66.0": { + "integrity": "sha512-xCbgzciGgo+A4aQZEknsNrNiIwY7sU5SfRuMmRjPIvZAgdF34cIHiKvwOsS5XRLjlTVSFwitmq6YclTtHTfU+g==", + "os": ["linux"], + "cpu": ["arm64"] + }, + "@oxlint/binding-linux-arm64-musl@1.66.0": { + "integrity": "sha512-hmo+ZB/lHkR1HdDmnziNpzSLmulnUSu10VEqX2Yex7OwvoBAbjJQLvy4gIBRV3AAwWnCvAxKp5Nv1GE6LU1QMg==", + "os": ["linux"], + "cpu": ["arm64"] + }, + "@oxlint/binding-linux-ppc64-gnu@1.66.0": { + "integrity": "sha512-2Invd4Uyy81mVooQC5FBtfxSNrvcX1OxbMlVQ6M2erRrNI2awFYF26YNW2yFxdVFZ4ffNOWKghtMjhnUPsXsVA==", + "os": ["linux"], + "cpu": ["ppc64"] + }, + "@oxlint/binding-linux-riscv64-gnu@1.66.0": { + "integrity": "sha512-s0iXPDQVdgayE3RGa/N2DZF7tjgg0TwEtD1sGoDxqPDGrIXgo45H0yHknT0f9A0yteASsweYZtDyTuVlM4aSag==", + "os": ["linux"], + "cpu": ["riscv64"] + }, + "@oxlint/binding-linux-riscv64-musl@1.66.0": { + "integrity": "sha512-OekL4XFiu7RPK0JIZi8VeHgtIXPREf42t8Cy/rKEsC+P3gcqDgNAAGiyuUOpdbG4wwbfue1q4CHcCO7spSve6w==", + "os": ["linux"], + "cpu": ["riscv64"] + }, + "@oxlint/binding-linux-s390x-gnu@1.66.0": { + "integrity": "sha512-Ga1D0kj1SFslm34ThA/BdkUlyAYEnTsXyRC4pF0C5agZSwtGdHYWMTQWemUfBGp4RCG4QWXgdO+HmmmKqOtlBg==", + "os": ["linux"], + "cpu": ["s390x"] + }, + "@oxlint/binding-linux-x64-gnu@1.66.0": { + "integrity": "sha512-p5jfP1wUZe/IC3qpQO84n9DRnf9g3lKRtLBlQq23ykyrDglHcVx7sWmVTlPuU6SBw8mNnPzyOn022G3XZHnlww==", + "os": ["linux"], + "cpu": ["x64"] + }, + "@oxlint/binding-linux-x64-musl@1.66.0": { + "integrity": "sha512-vUB/sYlYZorDL1ZD+o9mRv7zbsykrrFRtmgS6R8musZqLtrPRQn1gc1eGpuX+sfdccz42STl/AqldY6XRb2upQ==", + "os": ["linux"], + "cpu": ["x64"] + }, + "@oxlint/binding-openharmony-arm64@1.66.0": { + "integrity": "sha512-yde+6p/F59xRkGR9H1HfngWRif1QRJjynZK349l+UI0H6w9hL3G8/AVaTHFyTtLVQ56qtNbX2/5Dc77n1ovnOg==", + "os": ["openharmony"], + "cpu": ["arm64"] + }, + "@oxlint/binding-win32-arm64-msvc@1.66.0": { + "integrity": "sha512-O9GLucgoTdmOrbBX+EjzNe7o/Ze5TFOvXcib6bzUOtBOmj6cV+zw18NgB+cGKAkDw1Pdqs8vGkfHbbsLuDtXWg==", + "os": ["win32"], + "cpu": ["arm64"] + }, + "@oxlint/binding-win32-ia32-msvc@1.66.0": { + "integrity": "sha512-m3Pjwc2MfTcom4E4gOv7DyuGyt7OfGNCbmqDHd+N7EzXmP+ppHuudm2NjcA3AjV5TSeGxaguVF4SbTKHe1USYA==", + "os": ["win32"], + "cpu": ["ia32"] + }, + "@oxlint/binding-win32-x64-msvc@1.66.0": { + "integrity": "sha512-/DbBvw8UFBhja6PqudUjV4UtfsJr0Oa7jUjWVKB0g86lj/VwnPrkngn0sFql3c9RDA0O16dh7ozsXb6GjNAzBQ==", + "os": ["win32"], + "cpu": ["x64"] + }, "@parcel/watcher-android-arm64@2.5.6": { "integrity": "sha512-YQxSS34tPF/6ZG7r/Ih9xy+kP/WwediEUsqmtf0cuCV5TPPKw/PQHRhueUo6JdeFJaqV3pyjm0GdYjZotbRt/A==", "os": ["android"], @@ -7043,6 +7140,31 @@ "strip-ansi@7.2.0" ] }, + "oxlint@1.66.0": { + "integrity": "sha512-N4LLxYLd94KEBqXDMDM5f+2PUpItTjDLreXe2Gn5KhjhCK4Qp2YUXaBi8Yu325ryOgKwt22m45fpD7nPOn69Yw==", + "optionalDependencies": [ + "@oxlint/binding-android-arm-eabi", + "@oxlint/binding-android-arm64", + "@oxlint/binding-darwin-arm64", + "@oxlint/binding-darwin-x64", + "@oxlint/binding-freebsd-x64", + "@oxlint/binding-linux-arm-gnueabihf", + "@oxlint/binding-linux-arm-musleabihf", + "@oxlint/binding-linux-arm64-gnu", + "@oxlint/binding-linux-arm64-musl", + "@oxlint/binding-linux-ppc64-gnu", + "@oxlint/binding-linux-riscv64-gnu", + "@oxlint/binding-linux-riscv64-musl", + "@oxlint/binding-linux-s390x-gnu", + "@oxlint/binding-linux-x64-gnu", + "@oxlint/binding-linux-x64-musl", + "@oxlint/binding-openharmony-arm64", + "@oxlint/binding-win32-arm64-msvc", + "@oxlint/binding-win32-ia32-msvc", + "@oxlint/binding-win32-x64-msvc" + ], + "bin": true + }, "p-limit@3.1.0": { "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dependencies": [ @@ -9514,7 +9636,8 @@ "packages/lint": { "dependencies": [ "npm:@types/estree@^1.0.8", - "npm:eslint@9" + "npm:eslint@9", + "npm:oxlint@^1.66.0" ], "packageJson": { "dependencies": [ diff --git a/docs/manual/lint.md b/docs/manual/lint.md index 2772ebb98..e1a9695ef 100644 --- a/docs/manual/lint.md +++ b/docs/manual/lint.md @@ -1,8 +1,8 @@ --- description: >- - Fedify provides linting plugins for Deno Lint and ESLint to help you catch - common mistakes and enforce best practices when building federated server - apps. + Fedify provides linting plugins for Deno Lint, ESLint, and Oxlint to help you + catch common mistakes and enforce best practices when building federated + server apps. --- Linting @@ -15,8 +15,9 @@ _This package is available since Fedify 2.0.0._ > app to catch common mistakes early and enforce best practices. Fedify provides the [`@fedify/lint`] package, which includes lint rules -specifically designed for Fedify applications. It supports both [Deno Lint] and -[ESLint], so you can use it regardless of your JavaScript/TypeScript runtime. +specifically designed for Fedify applications. It supports [Deno Lint], +[ESLint], and [Oxlint], so you can use it regardless of your +JavaScript/TypeScript runtime. The plugin includes rules that check for: @@ -29,6 +30,7 @@ The plugin includes rules that check for: [`@fedify/lint`]: https://jsr.io/@fedify/lint [Deno Lint]: https://docs.deno.com/runtime/reference/lint_plugins/ [ESLint]: https://eslint.org/ +[Oxlint]: https://oxc.rs/docs/guide/usage/linter/ Installation @@ -262,6 +264,114 @@ bunx eslint . ::: +Oxlint +------ + +[Oxlint] is a fast Rust-based linter that supports ESLint-compatible JS +plugins. `@fedify/lint` exposes its rules through Oxlint's [JS plugin API] +via the `@fedify/lint/oxlint` subpath export. + +> [!NOTE] +> Oxlint's JS plugin API is currently in alpha and not subject to semver. + +[JS plugin API]: https://oxc.rs/docs/guide/usage/linter/writing-js-plugins.html + +### Basic setup + +Add the plugin to your _.oxlintrc.json_ via the `jsPlugins` field, then enable +the rules you want: + +~~~~ json +{ + "$schema": "https://raw.githubusercontent.com/oxc-project/oxc/main/npm/oxlint/configuration_schema.json", + "jsPlugins": ["@fedify/lint/oxlint"], + "rules": { + "@fedify/lint/actor-id-required": "error", + "@fedify/lint/actor-id-mismatch": "error" + } +} +~~~~ + +Rule IDs are namespaced under `@fedify/lint/`, matching the ESLint preset. + +### Custom configuration + +Each rule accepts `"error"`, `"warn"`, or `"off"`. Enable any subset listed in +the [*Rules* section](#rules) below: + +~~~~ json +{ + "jsPlugins": ["@fedify/lint/oxlint"], + "rules": { + "@fedify/lint/actor-id-required": "error", + "@fedify/lint/actor-id-mismatch": "error", + "@fedify/lint/actor-inbox-property-required": "warn", + "@fedify/lint/actor-outbox-property-required": "warn", + "@fedify/lint/actor-followers-property-required": "warn", + "@fedify/lint/actor-public-key-required": "warn", + "@fedify/lint/actor-assertion-method-required": "warn", + "@fedify/lint/collection-filtering-not-implemented": "warn" + } +} +~~~~ + +### Running Oxlint + +Add a script to _package.json_: + +~~~~ jsonc +{ + "scripts": { + "lint": "oxlint ." + } +} +~~~~ + +Then run the linter: + +::: code-group + +~~~~ sh [npm] +npm run lint +~~~~ + +~~~~ sh [pnpm] +pnpm lint +~~~~ + +~~~~ sh [Yarn] +yarn lint +~~~~ + +~~~~ sh [Bun] +bun lint +~~~~ + +::: + +Or invoke Oxlint directly: + +::: code-group + +~~~~ sh [npm] +npx oxlint . +~~~~ + +~~~~ sh [pnpm] +pnpx oxlint . +~~~~ + +~~~~ sh [Yarn] +yarn oxlint . +~~~~ + +~~~~ sh [Bun] +bunx oxlint . +~~~~ + +::: + + Rules ----- @@ -1217,10 +1327,12 @@ See also - [`@fedify/lint` on npm] - [Deno Lint plugins documentation] - [ESLint documentation] + - [Oxlint documentation] - [Example project] [`@fedify/lint` on JSR]: https://jsr.io/@fedify/lint [`@fedify/lint` on npm]: https://www.npmjs.com/package/@fedify/lint [Deno Lint plugins documentation]: https://docs.deno.com/runtime/reference/lint_plugins/ [ESLint documentation]: https://eslint.org/ +[Oxlint documentation]: https://oxc.rs/docs/guide/usage/linter/ [Example project]: https://github.com/fedify-dev/fedify/tree/main/examples/lint diff --git a/examples/lint/oxlint/.oxlintrc.json b/examples/lint/oxlint/.oxlintrc.json new file mode 100644 index 000000000..fad2f581b --- /dev/null +++ b/examples/lint/oxlint/.oxlintrc.json @@ -0,0 +1,11 @@ +{ + "$schema": "https://raw.githubusercontent.com/oxc-project/oxc/main/npm/oxlint/configuration_schema.json", + "jsPlugins": ["@fedify/lint/oxlint"], + "rules": { + "@fedify/lint/actor-id-required": "error", + "@fedify/lint/actor-id-mismatch": "error", + "@fedify/lint/actor-inbox-property-required": "warn", + "@fedify/lint/actor-outbox-property-required": "warn", + "@fedify/lint/actor-followers-property-required": "warn" + } +} diff --git a/examples/lint/oxlint/README.md b/examples/lint/oxlint/README.md new file mode 100644 index 000000000..e6e1eddcf --- /dev/null +++ b/examples/lint/oxlint/README.md @@ -0,0 +1,72 @@ + + +@fedify/lint with Oxlint +======================== + +This example demonstrates how to use [`@fedify/lint`] together with [Oxlint] +to catch common Fedify federation mistakes. Note that Oxlint's JS plugin +support is upstream alpha and may be unstable. + +[`@fedify/lint`]: https://www.npmjs.com/package/@fedify/lint +[Oxlint]: https://oxc.rs/docs/guide/usage/linter/ + + +Layout +------ + + - *.oxlintrc.json* — Oxlint configuration that enables `@fedify/lint` + via the JS plugin API. + - *federation.ts* — code that intentionally violates several rules + (missing `id`, `inbox`, `outbox`, `followers`). + - *federation.fixed.ts* — corrected version that passes all rules. + + +Usage +----- + +Install dependencies and run the linter: + +~~~~ sh +pnpm install +pnpm lint +~~~~ + +You should see at least one `@fedify/lint(actor-id-required)` error on +*federation.ts*. Running against *federation.fixed.ts* alone produces no +diagnostics: + +~~~~ sh +pnpm lint:fixed +~~~~ + +The same tasks are also wired into *deno.json*, so you can invoke Oxlint +through Deno (the plugin still resolves out of *node\_modules*, so +`pnpm install` is required first): + +~~~~ sh +deno task lint +deno task lint:fixed +~~~~ + + +How it works +------------ + +The plugin is loaded via the `jsPlugins` field in *.oxlintrc.json*: + +~~~~ json +{ + "jsPlugins": ["@fedify/lint/oxlint"], + "rules": { + "@fedify/lint/actor-id-required": "error" + } +} +~~~~ + +`@fedify/lint/oxlint` is a subpath export that exposes the same rules as the +ESLint plugin in Oxlint's plugin shape. Rule IDs are namespaced under +`@fedify/lint/`. + +See the [Linting] manual for the full rule reference. + +[Linting]: https://fedify.dev/manual/lint diff --git a/examples/lint/oxlint/deno.json b/examples/lint/oxlint/deno.json new file mode 100644 index 000000000..7e1b4d1d0 --- /dev/null +++ b/examples/lint/oxlint/deno.json @@ -0,0 +1,6 @@ +{ + "tasks": { + "lint": "deno run -A npm:oxlint .", + "lint:fixed": "deno run -A npm:oxlint federation.fixed.ts" + } +} diff --git a/examples/lint/oxlint/federation.fixed.ts b/examples/lint/oxlint/federation.fixed.ts new file mode 100644 index 000000000..5b4a22f56 --- /dev/null +++ b/examples/lint/oxlint/federation.fixed.ts @@ -0,0 +1,21 @@ +import { + createFederation, + InProcessMessageQueue, + MemoryKvStore, +} from "@fedify/fedify"; +import { Person } from "@fedify/vocab"; + +const federation = createFederation({ + kv: new MemoryKvStore(), + queue: new InProcessMessageQueue(), +}); + +federation.setActorDispatcher("/users/{identifier}", (ctx, identifier) => { + return new Person({ + id: ctx.getActorUri(identifier), + name: "Example User", + inbox: ctx.getInboxUri(identifier), + outbox: ctx.getOutboxUri(identifier), + followers: ctx.getFollowersUri(identifier), + }); +}); diff --git a/examples/lint/oxlint/federation.ts b/examples/lint/oxlint/federation.ts new file mode 100644 index 000000000..7704040a5 --- /dev/null +++ b/examples/lint/oxlint/federation.ts @@ -0,0 +1,17 @@ +import { + createFederation, + InProcessMessageQueue, + MemoryKvStore, +} from "@fedify/fedify"; +import { Person } from "@fedify/vocab"; + +const federation = createFederation({ + kv: new MemoryKvStore(), + queue: new InProcessMessageQueue(), +}); + +federation.setActorDispatcher("/users/{identifier}", (_ctx, _identifier) => { + return new Person({ + name: "Example User", + }); +}); diff --git a/examples/lint/oxlint/package.json b/examples/lint/oxlint/package.json new file mode 100644 index 000000000..5dbef1cd8 --- /dev/null +++ b/examples/lint/oxlint/package.json @@ -0,0 +1,19 @@ +{ + "name": "@fedify/example-lint-oxlint", + "version": "0.0.0", + "private": true, + "description": "Example project demonstrating @fedify/lint with oxlint", + "type": "module", + "scripts": { + "lint": "oxlint .", + "lint:fixed": "oxlint federation.fixed.ts" + }, + "dependencies": { + "@fedify/fedify": "workspace:^", + "@fedify/vocab": "workspace:^" + }, + "devDependencies": { + "@fedify/lint": "workspace:^", + "oxlint": "catalog:" + } +} diff --git a/packages/lint/README.md b/packages/lint/README.md index 3d3979340..499611475 100644 --- a/packages/lint/README.md +++ b/packages/lint/README.md @@ -1,7 +1,7 @@ -@fedify/lint: ESLint plugin for Fedify -====================================== +@fedify/lint: Lint plugins for Fedify +===================================== [![JSR][JSR badge]][JSR] [![npm][npm badge]][npm] @@ -9,10 +9,10 @@ *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. +This package provides [Deno Lint], [ESLint], and [Oxlint] plugins 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: @@ -30,6 +30,7 @@ The plugin includes rules that check for: [@fedify@hollo.social]: https://hollo.social/@fedify [Deno Lint]: https://docs.deno.com/runtime/reference/lint_plugins/ [ESLint]: https://eslint.org/ +[Oxlint]: https://oxc.rs/docs/guide/usage/linter/ [Fedify]: https://fedify.dev/ ### Deno Lint configuration example @@ -62,6 +63,21 @@ import fedifyLint from "@fedify/lint"; export default fedifyLint; ~~~~ +### Oxlint configuration example + +~~~~ jsonc +// .oxlintrc.json + +{ + "jsPlugins": ["@fedify/lint/oxlint"], + "rules": { + "@fedify/lint/actor-id-required": "error", + "@fedify/lint/actor-id-mismatch": "error", + "@fedify/lint/actor-inbox-property-required": "warn" + } +} +~~~~ + Features -------- @@ -403,6 +419,114 @@ bunx eslint . ::: +Usage (Oxlint) +-------------- + +[Oxlint] is a fast Rust-based linter that supports ESLint-compatible JS plugins. +The `@fedify/lint/oxlint` subpath export plugs the Fedify rules into Oxlint's +[JS plugin API]. + +> [!NOTE] +> Oxlint's JS plugin API is currently in alpha and not subject to semver. + +[JS plugin API]: https://oxc.rs/docs/guide/usage/linter/writing-js-plugins.html + +### Basic setup + +Add the plugin and the rules you want to enable to your *.oxlintrc.json*: + +~~~~ json +{ + "$schema": "https://raw.githubusercontent.com/oxc-project/oxc/main/npm/oxlint/configuration_schema.json", + "jsPlugins": ["@fedify/lint/oxlint"], + "rules": { + "@fedify/lint/actor-id-required": "error", + "@fedify/lint/actor-id-mismatch": "error" + } +} +~~~~ + +Rule IDs are namespaced under `@fedify/lint/`, matching the ESLint +configuration above. + +### Custom configuration + +Enable any subset of the rules listed in the *Features* section above. Each +rule can be set to `"error"`, `"warn"`, or `"off"`: + +~~~~ json +{ + "jsPlugins": ["@fedify/lint/oxlint"], + "rules": { + "@fedify/lint/actor-id-required": "error", + "@fedify/lint/actor-id-mismatch": "error", + "@fedify/lint/actor-inbox-property-required": "warn", + "@fedify/lint/actor-outbox-property-required": "warn", + "@fedify/lint/actor-followers-property-required": "warn", + "@fedify/lint/actor-public-key-required": "warn", + "@fedify/lint/actor-assertion-method-required": "warn", + "@fedify/lint/collection-filtering-not-implemented": "warn" + } +} +~~~~ + +### Running Oxlint + +Add a script to *package.json*: + +~~~~ jsonc +{ + "scripts": { + "lint": "oxlint ." + } +} +~~~~ + +Then run: + +::: code-group + +~~~~ sh [npm] +npm run lint +~~~~ + +~~~~ sh [pnpm] +pnpm lint +~~~~ + +~~~~ sh [Yarn] +yarn lint +~~~~ + +~~~~ sh [Bun] +bun lint +~~~~ + +::: + +Or invoke Oxlint directly: + +::: code-group + +~~~~ sh [npm] +npx oxlint . +~~~~ + +~~~~ sh [pnpm] +pnpx oxlint . +~~~~ + +~~~~ sh [Yarn] +yarn oxlint . +~~~~ + +~~~~ sh [Bun] +bunx oxlint . +~~~~ + +::: + + See also -------- diff --git a/packages/lint/deno.json b/packages/lint/deno.json index cf6a0fa27..a785cfda0 100644 --- a/packages/lint/deno.json +++ b/packages/lint/deno.json @@ -3,11 +3,13 @@ "version": "2.3.0", "license": "MIT", "exports": { - ".": "./src/mod.ts" + ".": "./src/mod.ts", + "./oxlint": "./src/oxlint.ts" }, "imports": { "eslint": "npm:eslint@^9.0.0", - "estree": "npm:@types/estree@^1.0.8" + "estree": "npm:@types/estree@^1.0.8", + "oxlint": "npm:oxlint@^1.66.0" }, "publish": { "exclude": [ @@ -16,6 +18,6 @@ ] }, "tasks": { - "test": "deno test --allow-env" + "test": "deno test --allow-env --allow-read --allow-run --allow-sys --allow-write" } } diff --git a/packages/lint/package.json b/packages/lint/package.json index 6bbca994f..da1449c12 100644 --- a/packages/lint/package.json +++ b/packages/lint/package.json @@ -8,7 +8,9 @@ "Fediverse", "Lint", "ESLint", - "ESLint Plugin" + "ESLint Plugin", + "oxlint", + "oxc" ], "author": { "name": "Chanhaeng Lee", @@ -38,6 +40,11 @@ "import": "./dist/index.js", "require": "./dist/index.cjs" }, + "./oxlint": { + "types": "./dist/oxlint.d.ts", + "import": "./dist/oxlint.js", + "require": "./dist/oxlint.cjs" + }, "./package.json": "./package.json" }, "files": [ @@ -60,9 +67,11 @@ "@typescript-eslint/utils": "^8.0.0" }, "devDependencies": { + "@fedify/fixture": "workspace:*", "@types/eslint": "^9.0.0", "@types/estree": "^1.0.9", "eslint": "^9.0.0", + "oxlint": "catalog:", "tsdown": "catalog:", "typescript": "catalog:" }, diff --git a/packages/lint/src/oxlint.ts b/packages/lint/src/oxlint.ts new file mode 100644 index 000000000..f9a0f0461 --- /dev/null +++ b/packages/lint/src/oxlint.ts @@ -0,0 +1,135 @@ +/** + * oxlint plugin for Fedify. + * + * Exposes the same rule set as the ESLint plugin in a shape suitable for + * oxlint's JS plugin API (https://oxc.rs/docs/guide/usage/linter/writing-js-plugins.html). + * + * Configure via `.oxlintrc.json`: + * + * ```json + * { + * "jsPlugins": ["@fedify/lint/oxlint"], + * "rules": { + * "@fedify/lint/actor-id-required": "error" + * } + * } + * ``` + */ +import type { Rule } from "eslint"; +import metadataRaw from "../deno.json" with { type: "json" }; +import { RULE_IDS } from "./lib/const.ts"; +import { + eslint as actorAssertionMethodRequired, +} from "./rules/actor-assertion-method-required.ts"; +import { + eslint as actorFeaturedPropertyMismatch, +} from "./rules/actor-featured-property-mismatch.ts"; +import { + eslint as actorFeaturedPropertyRequired, +} from "./rules/actor-featured-property-required.ts"; +import { + eslint as actorFeaturedTagsPropertyMismatch, +} from "./rules/actor-featured-tags-property-mismatch.ts"; +import { + eslint as actorFeaturedTagsPropertyRequired, +} from "./rules/actor-featured-tags-property-required.ts"; +import { + eslint as actorFollowersPropertyMismatch, +} from "./rules/actor-followers-property-mismatch.ts"; +import { + eslint as actorFollowersPropertyRequired, +} from "./rules/actor-followers-property-required.ts"; +import { + eslint as actorFollowingPropertyMismatch, +} from "./rules/actor-following-property-mismatch.ts"; +import { + eslint as actorFollowingPropertyRequired, +} from "./rules/actor-following-property-required.ts"; +import { eslint as actorIdMismatch } from "./rules/actor-id-mismatch.ts"; +import { eslint as actorIdRequired } from "./rules/actor-id-required.ts"; +import { + eslint as actorInboxPropertyMismatch, +} from "./rules/actor-inbox-property-mismatch.ts"; +import { + eslint as actorInboxPropertyRequired, +} from "./rules/actor-inbox-property-required.ts"; +import { + eslint as actorLikedPropertyMismatch, +} from "./rules/actor-liked-property-mismatch.ts"; +import { + eslint as actorLikedPropertyRequired, +} from "./rules/actor-liked-property-required.ts"; +import { + eslint as actorOutboxPropertyMismatch, +} from "./rules/actor-outbox-property-mismatch.ts"; +import { + eslint as actorOutboxPropertyRequired, +} from "./rules/actor-outbox-property-required.ts"; +import { + eslint as actorPublicKeyRequired, +} from "./rules/actor-public-key-required.ts"; +import { + eslint as actorSharedInboxPropertyMismatch, +} from "./rules/actor-shared-inbox-property-mismatch.ts"; +import { + eslint as actorSharedInboxPropertyRequired, +} from "./rules/actor-shared-inbox-property-required.ts"; +import { + eslint as collectionFiltering, +} from "./rules/collection-filtering-not-implemented.ts"; +import { + eslint as outboxListenerDeliveryRequired, +} from "./rules/outbox-listener-delivery-required.ts"; + +const rules: Record< + typeof RULE_IDS[keyof typeof RULE_IDS], + Rule.RuleModule +> = { + [RULE_IDS.actorIdMismatch]: actorIdMismatch, + [RULE_IDS.actorIdRequired]: actorIdRequired, + [RULE_IDS.actorFollowingPropertyRequired]: actorFollowingPropertyRequired, + [RULE_IDS.actorFollowingPropertyMismatch]: actorFollowingPropertyMismatch, + [RULE_IDS.actorFollowersPropertyRequired]: actorFollowersPropertyRequired, + [RULE_IDS.actorFollowersPropertyMismatch]: actorFollowersPropertyMismatch, + [RULE_IDS.actorOutboxPropertyRequired]: actorOutboxPropertyRequired, + [RULE_IDS.actorOutboxPropertyMismatch]: actorOutboxPropertyMismatch, + [RULE_IDS.actorLikedPropertyRequired]: actorLikedPropertyRequired, + [RULE_IDS.actorLikedPropertyMismatch]: actorLikedPropertyMismatch, + [RULE_IDS.actorFeaturedPropertyRequired]: actorFeaturedPropertyRequired, + [RULE_IDS.actorFeaturedPropertyMismatch]: actorFeaturedPropertyMismatch, + [RULE_IDS.actorFeaturedTagsPropertyRequired]: + actorFeaturedTagsPropertyRequired, + [RULE_IDS.actorFeaturedTagsPropertyMismatch]: + actorFeaturedTagsPropertyMismatch, + [RULE_IDS.actorInboxPropertyRequired]: actorInboxPropertyRequired, + [RULE_IDS.actorInboxPropertyMismatch]: actorInboxPropertyMismatch, + [RULE_IDS.actorSharedInboxPropertyRequired]: actorSharedInboxPropertyRequired, + [RULE_IDS.actorSharedInboxPropertyMismatch]: actorSharedInboxPropertyMismatch, + [RULE_IDS.actorPublicKeyRequired]: actorPublicKeyRequired, + [RULE_IDS.actorAssertionMethodRequired]: actorAssertionMethodRequired, + [RULE_IDS.collectionFilteringNotImplemented]: collectionFiltering, + [RULE_IDS.outboxListenerDeliveryRequired]: outboxListenerDeliveryRequired, +}; + +/** + * Plugin object compatible with Oxlint's JS plugin API. + * + * Kept module-private on purpose: consumers should rely on the default + * export and the Oxlint runtime to resolve the shape, rather than + * importing this type and risking drift from upstream's `Plugin` + * definition in `@oxlint/plugins`. + */ +interface OxlintPlugin { + meta: { name: string; version: string }; + rules: Record; +} + +const plugin: OxlintPlugin = { + meta: { + name: metadataRaw.name, + version: metadataRaw.version, + }, + rules, +}; + +export default plugin; diff --git a/packages/lint/src/tests/oxlint.test.ts b/packages/lint/src/tests/oxlint.test.ts new file mode 100644 index 000000000..fdc767112 --- /dev/null +++ b/packages/lint/src/tests/oxlint.test.ts @@ -0,0 +1,154 @@ +/** + * Integration test for the oxlint plugin entry. + * + * Spawns the oxlint binary against a tmpdir fixture that violates + * `actor-id-required`, parses the JSON diagnostics, and asserts the + * `@fedify/lint/actor-id-required` rule fires. + * + * Runtime notes: + * + * - The test uses `node:child_process`, `node:fs`, `node:os`, + * `node:path`, and `node:process`. Under Deno these resolve via + * the Node compatibility layer, so the same source runs under both + * `pnpm test` (via `node:test`) and `deno task test` (via + * `Deno.test`) — `@fedify/fixture` dispatches the test definition + * to the appropriate runtime. + * - Other rule tests in this package use the in-process linter APIs + * (`Deno.lint.runPlugin` / ESLint's `Linter`). This one is + * different on purpose: oxlint is a Rust binary, so we spawn it as + * a subprocess against a real config file. That's the only way to + * exercise the JS plugin loader end-to-end. + * - Two preconditions are checked at module load. If either is + * missing, the test is skipped via `{ ignore }`: + * * the built loader at `/dist/oxlint.js` + * * the oxlint binary, located under `/node_modules/.bin`, + * the workspace root, or anywhere on `PATH` + */ +import { test } from "@fedify/fixture"; +import { ok } from "node:assert/strict"; +import { spawnSync } from "node:child_process"; +import { existsSync, mkdtempSync, rmSync, writeFileSync } from "node:fs"; +import { tmpdir } from "node:os"; +import { dirname, join, resolve } from "node:path"; +import process from "node:process"; +import { fileURLToPath } from "node:url"; + +const here = dirname(fileURLToPath(import.meta.url)); +const pluginPath = resolve(here, "../../dist/oxlint.js"); +const pluginBuilt = existsSync(pluginPath); + +function findOxlint(): string | null { + const candidates = [ + resolve(here, "../../node_modules/.bin/oxlint"), + resolve(here, "../../../../node_modules/.bin/oxlint"), + ]; + for (const candidate of candidates) { + if (existsSync(candidate)) return candidate; + } + const where = spawnSync( + process.platform === "win32" ? "where" : "which", + ["oxlint"], + { encoding: "utf8" }, + ); + if (where.status === 0 && where.stdout) { + return where.stdout.trim().split(/\r?\n/)[0]; + } + return null; +} + +const oxlintBin = findOxlint(); +const ignore = !pluginBuilt || !oxlintBin; + +if (ignore) { + const missing: string[] = []; + if (!pluginBuilt) missing.push(`built loader at ${pluginPath}`); + if (!oxlintBin) missing.push("oxlint binary on PATH or in node_modules"); + console.warn( + `Skipping oxlint plugin integration test — missing: ${ + missing.join(", ") + }.\n` + + "To enable it, run `mise run install` (or `pnpm install && pnpm --filter @fedify/lint build`) " + + "from the repository root so both the loader and the oxlint binary are available.", + ); +} + +const BAD_CODE = + `import { createFederation, InProcessMessageQueue, MemoryKvStore } from "@fedify/fedify"; +import { Person } from "@fedify/vocab"; + +const federation = createFederation({ + kv: new MemoryKvStore(), + queue: new InProcessMessageQueue(), +}); + +federation.setActorDispatcher("/users/{identifier}", (_ctx, _identifier) => { + return new Person({ + name: "Bad Actor", + }); +}); +`; + +interface OxlintJsonDiagnostic { + code?: string; + message?: string; + severity?: string; +} + +interface OxlintJsonReport { + diagnostics?: OxlintJsonDiagnostic[]; +} + +test( + "oxlint plugin: actor-id-required fires on missing id", + { ignore }, + () => { + const dir = mkdtempSync(join(tmpdir(), "fedify-lint-oxlint-")); + try { + writeFileSync( + join(dir, ".oxlintrc.json"), + JSON.stringify({ + jsPlugins: [pluginPath], + rules: { + "@fedify/lint/actor-id-required": "error", + }, + }), + ); + writeFileSync(join(dir, "federation.ts"), BAD_CODE); + + const result = spawnSync( + oxlintBin!, + ["--format=json", "."], + { cwd: dir, encoding: "utf8" }, + ); + + ok( + result.status !== 0, + `Expected non-zero exit, got ${result.status}. stderr: ${result.stderr}`, + ); + + let payload: OxlintJsonReport; + try { + payload = JSON.parse(result.stdout) as OxlintJsonReport; + } catch (err) { + throw new Error( + `Failed to parse oxlint JSON output: ${(err as Error).message}\n` + + `stdout: ${result.stdout}\nstderr: ${result.stderr}`, + ); + } + + const codes = (payload.diagnostics ?? []).map((d) => d.code ?? ""); + const matched = codes.some((code) => + code === "@fedify/lint(actor-id-required)" || + code.includes("actor-id-required") + ); + ok( + matched, + `Expected @fedify/lint(actor-id-required) diagnostic, got: ${ + codes.join(", ") || "(none)" + }`, + ); + } finally { + rmSync(dir, { recursive: true, force: true }); + } + }, +); diff --git a/packages/lint/tsdown.config.ts b/packages/lint/tsdown.config.ts index 41c45aead..7312e7fd0 100644 --- a/packages/lint/tsdown.config.ts +++ b/packages/lint/tsdown.config.ts @@ -1,7 +1,7 @@ import { defineConfig } from "tsdown"; export default defineConfig({ - entry: ["src/index.ts"], + entry: ["src/index.ts", "src/oxlint.ts"], dts: { compilerOptions: { isolatedDeclarations: true, declaration: true } }, format: ["esm", "cjs"], platform: "node", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f3eba0e1b..622a3c17e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -162,6 +162,9 @@ catalogs: nuxt: specifier: ^4.4.2 version: 4.4.2 + oxlint: + specifier: ^1.66.0 + version: 1.66.0 pkijs: specifier: ^3.3.3 version: 3.3.3 @@ -541,6 +544,22 @@ importers: specifier: ^5.5.4 version: 5.9.2 + examples/lint/oxlint: + dependencies: + '@fedify/fedify': + specifier: workspace:^ + version: link:../../../packages/fedify + '@fedify/vocab': + specifier: workspace:^ + version: link:../../../packages/vocab + devDependencies: + '@fedify/lint': + specifier: workspace:^ + version: link:../../../packages/lint + oxlint: + specifier: 'catalog:' + version: 1.66.0 + examples/next-integration: dependencies: '@fedify/fedify': @@ -710,7 +729,7 @@ importers: version: 1.15.11 nuxt: specifier: 'catalog:' - version: 4.4.2(75d3bb99739572e2ce1a5d32bf0400f3) + version: 4.4.2(9b6f49a83ed1b2fc8889dfd9b7f2c45d) devDependencies: '@types/node': specifier: 'catalog:' @@ -849,7 +868,7 @@ importers: version: 0.10.8 tsdown: specifier: 'catalog:' - version: 0.22.0(tsx@4.21.0)(typescript@6.0.3)(unrun@0.2.34) + version: 0.22.0(tsx@4.21.0)(typescript@6.0.3)(unrun@0.2.34(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)) typescript: specifier: 'catalog:' version: 6.0.3 @@ -865,7 +884,7 @@ importers: devDependencies: tsdown: specifier: 'catalog:' - version: 0.22.0(tsx@4.21.0)(typescript@6.0.3)(unrun@0.2.34) + version: 0.22.0(tsx@4.21.0)(typescript@6.0.3)(unrun@0.2.34(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)) typescript: specifier: 'catalog:' version: 6.0.3 @@ -884,7 +903,7 @@ importers: version: 0.8.71(@cloudflare/workers-types@4.20260511.1)(@vitest/runner@3.2.4)(@vitest/snapshot@3.2.4)(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.3.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.1)(tsx@4.21.0)(yaml@2.9.0)) tsdown: specifier: 'catalog:' - version: 0.22.0(tsx@4.21.0)(typescript@6.0.3)(unrun@0.2.34) + version: 0.22.0(tsx@4.21.0)(typescript@6.0.3)(unrun@0.2.34(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)) typescript: specifier: 'catalog:' version: 6.0.3 @@ -1020,7 +1039,7 @@ importers: version: 22.19.1 tsdown: specifier: 'catalog:' - version: 0.22.0(tsx@4.21.0)(typescript@6.0.3)(unrun@0.2.34) + version: 0.22.0(tsx@4.21.0)(typescript@6.0.3)(unrun@0.2.34(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)) typescript: specifier: 'catalog:' version: 6.0.3 @@ -1045,7 +1064,7 @@ importers: version: 22.19.1 tsdown: specifier: 'catalog:' - version: 0.22.0(tsx@4.21.0)(typescript@6.0.3)(unrun@0.2.34) + version: 0.22.0(tsx@4.21.0)(typescript@6.0.3)(unrun@0.2.34(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)) typescript: specifier: 'catalog:' version: 6.0.3 @@ -1079,7 +1098,7 @@ importers: devDependencies: tsdown: specifier: 'catalog:' - version: 0.22.0(tsx@4.21.0)(typescript@6.0.3)(unrun@0.2.34) + version: 0.22.0(tsx@4.21.0)(typescript@6.0.3)(unrun@0.2.34(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)) typescript: specifier: 'catalog:' version: 6.0.3 @@ -1098,7 +1117,7 @@ importers: version: 1.2.19(@types/react@19.1.8) tsdown: specifier: 'catalog:' - version: 0.22.0(tsx@4.21.0)(typescript@6.0.3)(unrun@0.2.34) + version: 0.22.0(tsx@4.21.0)(typescript@6.0.3)(unrun@0.2.34(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)) typescript: specifier: 'catalog:' version: 6.0.3 @@ -1120,7 +1139,7 @@ importers: version: 22.19.1 tsdown: specifier: 'catalog:' - version: 0.22.0(tsx@4.21.0)(typescript@6.0.3)(unrun@0.2.34) + version: 0.22.0(tsx@4.21.0)(typescript@6.0.3)(unrun@0.2.34(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)) typescript: specifier: 'catalog:' version: 6.0.3 @@ -1142,7 +1161,7 @@ importers: version: 22.19.1 tsdown: specifier: 'catalog:' - version: 0.22.0(tsx@4.21.0)(typescript@6.0.3)(unrun@0.2.34) + version: 0.22.0(tsx@4.21.0)(typescript@6.0.3)(unrun@0.2.34(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)) typescript: specifier: 'catalog:' version: 6.0.3 @@ -1224,7 +1243,7 @@ importers: version: 4.20250617.4 tsdown: specifier: 'catalog:' - version: 0.22.0(tsx@4.21.0)(typescript@6.0.3)(unrun@0.2.34) + version: 0.22.0(tsx@4.21.0)(typescript@6.0.3)(unrun@0.2.34(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)) tsx: specifier: ^4.21.0 version: 4.21.0 @@ -1258,7 +1277,7 @@ importers: version: 0.5.1 tsdown: specifier: 'catalog:' - version: 0.22.0(tsx@4.21.0)(typescript@6.0.3)(unrun@0.2.34) + version: 0.22.0(tsx@4.21.0)(typescript@6.0.3)(unrun@0.2.34(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)) typescript: specifier: 'catalog:' version: 6.0.3 @@ -1277,7 +1296,7 @@ importers: devDependencies: tsdown: specifier: 'catalog:' - version: 0.22.0(tsx@4.21.0)(typescript@6.0.3)(unrun@0.2.34) + version: 0.22.0(tsx@4.21.0)(typescript@6.0.3)(unrun@0.2.34(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)) typescript: specifier: 'catalog:' version: 6.0.3 @@ -1293,7 +1312,7 @@ importers: devDependencies: tsdown: specifier: 'catalog:' - version: 0.22.0(tsx@4.21.0)(typescript@6.0.3)(unrun@0.2.34) + version: 0.22.0(tsx@4.21.0)(typescript@6.0.3)(unrun@0.2.34(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)) typescript: specifier: 'catalog:' version: 6.0.3 @@ -1333,7 +1352,7 @@ importers: version: 22.19.1 tsdown: specifier: 'catalog:' - version: 0.22.0(tsx@4.21.0)(typescript@6.0.3)(unrun@0.2.34) + version: 0.22.0(tsx@4.21.0)(typescript@6.0.3)(unrun@0.2.34(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)) typescript: specifier: 'catalog:' version: 6.0.3 @@ -1355,7 +1374,7 @@ importers: version: 22.19.1 tsdown: specifier: 'catalog:' - version: 0.22.0(tsx@4.21.0)(typescript@6.0.3)(unrun@0.2.34) + version: 0.22.0(tsx@4.21.0)(typescript@6.0.3)(unrun@0.2.34(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)) typescript: specifier: 'catalog:' version: 6.0.3 @@ -1375,6 +1394,9 @@ importers: specifier: ^8.0.0 version: 8.41.0(eslint@9.32.0(jiti@2.6.1))(typescript@6.0.3) devDependencies: + '@fedify/fixture': + specifier: workspace:* + version: link:../fixture '@types/eslint': specifier: ^9.0.0 version: 9.6.1 @@ -1384,9 +1406,12 @@ importers: eslint: specifier: ^9.0.0 version: 9.32.0(jiti@2.6.1) + oxlint: + specifier: 'catalog:' + version: 1.66.0 tsdown: specifier: 'catalog:' - version: 0.22.0(tsx@4.21.0)(typescript@6.0.3)(unrun@0.2.34) + version: 0.22.0(tsx@4.21.0)(typescript@6.0.3)(unrun@0.2.34(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)) typescript: specifier: 'catalog:' version: 6.0.3 @@ -1417,7 +1442,7 @@ importers: version: link:../testing tsdown: specifier: 'catalog:' - version: 0.22.0(tsx@4.21.0)(typescript@6.0.3)(unrun@0.2.34) + version: 0.22.0(tsx@4.21.0)(typescript@6.0.3)(unrun@0.2.34(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)) typescript: specifier: 'catalog:' version: 6.0.3 @@ -1442,7 +1467,7 @@ importers: version: 22.19.1 tsdown: specifier: 'catalog:' - version: 0.22.0(tsx@4.21.0)(typescript@6.0.3)(unrun@0.2.34) + version: 0.22.0(tsx@4.21.0)(typescript@6.0.3)(unrun@0.2.34(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)) typescript: specifier: 'catalog:' version: 6.0.3 @@ -1458,7 +1483,7 @@ importers: devDependencies: tsdown: specifier: 'catalog:' - version: 0.22.0(tsx@4.21.0)(typescript@6.0.3)(unrun@0.2.34) + version: 0.22.0(tsx@4.21.0)(typescript@6.0.3)(unrun@0.2.34(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)) typescript: specifier: 'catalog:' version: 6.0.3 @@ -1479,7 +1504,7 @@ importers: version: 1.15.11 nuxt: specifier: 'catalog:' - version: 4.4.2(75d3bb99739572e2ce1a5d32bf0400f3) + version: 4.4.2(9b6f49a83ed1b2fc8889dfd9b7f2c45d) devDependencies: '@fedify/fixture': specifier: workspace:^ @@ -1489,7 +1514,7 @@ importers: version: 22.19.1 tsdown: specifier: 'catalog:' - version: 0.22.0(tsx@4.21.0)(typescript@6.0.3)(unrun@0.2.34) + version: 0.22.0(tsx@4.21.0)(typescript@6.0.3)(unrun@0.2.34(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)) typescript: specifier: 'catalog:' version: 6.0.3 @@ -1520,7 +1545,7 @@ importers: version: '@jsr/std__async@1.0.13' tsdown: specifier: 'catalog:' - version: 0.22.0(tsx@4.21.0)(typescript@6.0.3)(unrun@0.2.34) + version: 0.22.0(tsx@4.21.0)(typescript@6.0.3)(unrun@0.2.34(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)) typescript: specifier: 'catalog:' version: 6.0.3 @@ -1554,7 +1579,7 @@ importers: version: 22.19.1 tsdown: specifier: 'catalog:' - version: 0.22.0(tsx@4.21.0)(typescript@6.0.3)(unrun@0.2.34) + version: 0.22.0(tsx@4.21.0)(typescript@6.0.3)(unrun@0.2.34(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)) typescript: specifier: 'catalog:' version: 6.0.3 @@ -1579,7 +1604,7 @@ importers: version: link:../vocab-runtime tsdown: specifier: 'catalog:' - version: 0.22.0(tsx@4.21.0)(typescript@6.0.3)(unrun@0.2.34) + version: 0.22.0(tsx@4.21.0)(typescript@6.0.3)(unrun@0.2.34(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)) typescript: specifier: 'catalog:' version: 6.0.3 @@ -1598,7 +1623,7 @@ importers: devDependencies: tsdown: specifier: 'catalog:' - version: 0.22.0(tsx@4.21.0)(typescript@6.0.3)(unrun@0.2.34) + version: 0.22.0(tsx@4.21.0)(typescript@6.0.3)(unrun@0.2.34(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)) typescript: specifier: 'catalog:' version: 6.0.3 @@ -1626,7 +1651,7 @@ importers: version: '@jsr/std__async@1.0.13' tsdown: specifier: 'catalog:' - version: 0.22.0(tsx@4.21.0)(typescript@6.0.3)(unrun@0.2.34) + version: 0.22.0(tsx@4.21.0)(typescript@6.0.3)(unrun@0.2.34(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)) typescript: specifier: 'catalog:' version: 6.0.3 @@ -1642,7 +1667,7 @@ importers: devDependencies: tsdown: specifier: 'catalog:' - version: 0.22.0(tsx@4.21.0)(typescript@6.0.3)(unrun@0.2.34) + version: 0.22.0(tsx@4.21.0)(typescript@6.0.3)(unrun@0.2.34(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)) typescript: specifier: 'catalog:' version: 6.0.3 @@ -1670,7 +1695,7 @@ importers: version: '@jsr/std__async@1.0.13' tsdown: specifier: 'catalog:' - version: 0.22.0(tsx@4.21.0)(typescript@6.0.3)(unrun@0.2.34) + version: 0.22.0(tsx@4.21.0)(typescript@6.0.3)(unrun@0.2.34(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)) typescript: specifier: 'catalog:' version: 6.0.3 @@ -1685,7 +1710,7 @@ importers: version: 22.19.1 tsdown: specifier: 'catalog:' - version: 0.22.0(tsx@4.21.0)(typescript@6.0.3)(unrun@0.2.34) + version: 0.22.0(tsx@4.21.0)(typescript@6.0.3)(unrun@0.2.34(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)) typescript: specifier: 'catalog:' version: 6.0.3 @@ -1740,7 +1765,7 @@ importers: version: 12.6.0 tsdown: specifier: 'catalog:' - version: 0.22.0(tsx@4.21.0)(typescript@6.0.3)(unrun@0.2.34) + version: 0.22.0(tsx@4.21.0)(typescript@6.0.3)(unrun@0.2.34(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)) typescript: specifier: 'catalog:' version: 6.0.3 @@ -1780,7 +1805,7 @@ importers: version: 12.6.0 tsdown: specifier: 'catalog:' - version: 0.22.0(tsx@4.21.0)(typescript@6.0.3)(unrun@0.2.34) + version: 0.22.0(tsx@4.21.0)(typescript@6.0.3)(unrun@0.2.34(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)) typescript: specifier: 'catalog:' version: 6.0.3 @@ -1805,7 +1830,7 @@ importers: version: 22.19.1 tsdown: specifier: 'catalog:' - version: 0.22.0(tsx@4.21.0)(typescript@6.0.3)(unrun@0.2.34) + version: 0.22.0(tsx@4.21.0)(typescript@6.0.3)(unrun@0.2.34(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)) typescript: specifier: 'catalog:' version: 6.0.3 @@ -1836,7 +1861,7 @@ importers: version: 12.6.0 tsdown: specifier: 'catalog:' - version: 0.22.0(tsx@4.21.0)(typescript@6.0.3)(unrun@0.2.34) + version: 0.22.0(tsx@4.21.0)(typescript@6.0.3)(unrun@0.2.34(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)) typescript: specifier: 'catalog:' version: 6.0.3 @@ -4959,6 +4984,120 @@ packages: cpu: [x64] os: [win32] + '@oxlint/binding-android-arm-eabi@1.66.0': + resolution: {integrity: sha512-f7kq8N51T4phpzqfBpA2qaVTI/KrkCmNwaj3t/97I/WLTDI+UhlP5GL9eER+zVxBhtlx5rKXWByJU1/zDAvyaw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [android] + + '@oxlint/binding-android-arm64@1.66.0': + resolution: {integrity: sha512-xu6QO71tdDS9mjmLZ3AqhtaVHBvdmsOKkYnReNNDgh+XiwnsipeQOIxbiYOOO0iAXycJ+GK0wdMSZP/2j/AmSg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] + + '@oxlint/binding-darwin-arm64@1.66.0': + resolution: {integrity: sha512-HZ24VimSOC7mxuEA99e0H2FS0C1yO3+iW13jPRAk+e2njsUs3QeAXsafCDyaIrV/MirdOVez+etQNQsJE43zNQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] + + '@oxlint/binding-darwin-x64@1.66.0': + resolution: {integrity: sha512-awhj8ZvJrrRSnXj7V++rpZvTmnl99L6mi0B7gg7Cp7BN6cKpzuI481bHNLvXGA9GB1/oEgA3ponuyoAc6Md12A==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] + + '@oxlint/binding-freebsd-x64@1.66.0': + resolution: {integrity: sha512-KQF0oVV21/FjIqkRuL8Q1vh8ECsE5+ocdH5tcqTQ4ZnYuDVoYibQUNfqBjQaUsP6UIIda5Y75Wpm5p4RgQWiWw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] + + '@oxlint/binding-linux-arm-gnueabihf@1.66.0': + resolution: {integrity: sha512-9u1rgwZSEXWb30vbFZzQ78HVXBo0WCKNwJ3a2InRUTNMRng+PUDIoSFmA+m4HdUfBaIqftShq8J8qHc+eE/Vig==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@oxlint/binding-linux-arm-musleabihf@1.66.0': + resolution: {integrity: sha512-Ynot2HR1bHxUaNWoC280MVTDfZuaWuP3XfSMRDhyuZrVjhzoaBCVFlw8h8qeZjWKVUBhPWFIxB7AQTlK8Z2WWg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@oxlint/binding-linux-arm64-gnu@1.66.0': + resolution: {integrity: sha512-xCbgzciGgo+A4aQZEknsNrNiIwY7sU5SfRuMmRjPIvZAgdF34cIHiKvwOsS5XRLjlTVSFwitmq6YclTtHTfU+g==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + + '@oxlint/binding-linux-arm64-musl@1.66.0': + resolution: {integrity: sha512-hmo+ZB/lHkR1HdDmnziNpzSLmulnUSu10VEqX2Yex7OwvoBAbjJQLvy4gIBRV3AAwWnCvAxKp5Nv1GE6LU1QMg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + + '@oxlint/binding-linux-ppc64-gnu@1.66.0': + resolution: {integrity: sha512-2Invd4Uyy81mVooQC5FBtfxSNrvcX1OxbMlVQ6M2erRrNI2awFYF26YNW2yFxdVFZ4ffNOWKghtMjhnUPsXsVA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ppc64] + os: [linux] + + '@oxlint/binding-linux-riscv64-gnu@1.66.0': + resolution: {integrity: sha512-s0iXPDQVdgayE3RGa/N2DZF7tjgg0TwEtD1sGoDxqPDGrIXgo45H0yHknT0f9A0yteASsweYZtDyTuVlM4aSag==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [riscv64] + os: [linux] + + '@oxlint/binding-linux-riscv64-musl@1.66.0': + resolution: {integrity: sha512-OekL4XFiu7RPK0JIZi8VeHgtIXPREf42t8Cy/rKEsC+P3gcqDgNAAGiyuUOpdbG4wwbfue1q4CHcCO7spSve6w==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [riscv64] + os: [linux] + + '@oxlint/binding-linux-s390x-gnu@1.66.0': + resolution: {integrity: sha512-Ga1D0kj1SFslm34ThA/BdkUlyAYEnTsXyRC4pF0C5agZSwtGdHYWMTQWemUfBGp4RCG4QWXgdO+HmmmKqOtlBg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [s390x] + os: [linux] + + '@oxlint/binding-linux-x64-gnu@1.66.0': + resolution: {integrity: sha512-p5jfP1wUZe/IC3qpQO84n9DRnf9g3lKRtLBlQq23ykyrDglHcVx7sWmVTlPuU6SBw8mNnPzyOn022G3XZHnlww==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + + '@oxlint/binding-linux-x64-musl@1.66.0': + resolution: {integrity: sha512-vUB/sYlYZorDL1ZD+o9mRv7zbsykrrFRtmgS6R8musZqLtrPRQn1gc1eGpuX+sfdccz42STl/AqldY6XRb2upQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + + '@oxlint/binding-openharmony-arm64@1.66.0': + resolution: {integrity: sha512-yde+6p/F59xRkGR9H1HfngWRif1QRJjynZK349l+UI0H6w9hL3G8/AVaTHFyTtLVQ56qtNbX2/5Dc77n1ovnOg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + + '@oxlint/binding-win32-arm64-msvc@1.66.0': + resolution: {integrity: sha512-O9GLucgoTdmOrbBX+EjzNe7o/Ze5TFOvXcib6bzUOtBOmj6cV+zw18NgB+cGKAkDw1Pdqs8vGkfHbbsLuDtXWg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + + '@oxlint/binding-win32-ia32-msvc@1.66.0': + resolution: {integrity: sha512-m3Pjwc2MfTcom4E4gOv7DyuGyt7OfGNCbmqDHd+N7EzXmP+ppHuudm2NjcA3AjV5TSeGxaguVF4SbTKHe1USYA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ia32] + os: [win32] + + '@oxlint/binding-win32-x64-msvc@1.66.0': + resolution: {integrity: sha512-/DbBvw8UFBhja6PqudUjV4UtfsJr0Oa7jUjWVKB0g86lj/VwnPrkngn0sFql3c9RDA0O16dh7ozsXb6GjNAzBQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] + '@parcel/watcher-android-arm64@2.5.6': resolution: {integrity: sha512-YQxSS34tPF/6ZG7r/Ih9xy+kP/WwediEUsqmtf0cuCV5TPPKw/PQHRhueUo6JdeFJaqV3pyjm0GdYjZotbRt/A==} engines: {node: '>= 10.0.0'} @@ -10536,6 +10675,16 @@ packages: peerDependencies: oxc-parser: '>=0.98.0' + oxlint@1.66.0: + resolution: {integrity: sha512-N4LLxYLd94KEBqXDMDM5f+2PUpItTjDLreXe2Gn5KhjhCK4Qp2YUXaBi8Yu325ryOgKwt22m45fpD7nPOn69Yw==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + peerDependencies: + oxlint-tsgolint: '>=0.22.1' + peerDependenciesMeta: + oxlint-tsgolint: + optional: true + p-limit@3.1.0: resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} engines: {node: '>=10'} @@ -15490,7 +15639,7 @@ snapshots: transitivePeerDependencies: - magicast - '@nuxt/nitro-server@4.4.2(@babel/core@7.29.0)(better-sqlite3@12.9.0)(db0@0.3.4(better-sqlite3@12.9.0)(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260511.1)(@opentelemetry/api@1.9.1)(@types/better-sqlite3@7.6.13)(@types/pg@8.6.1)(better-sqlite3@12.9.0)(bun-types@1.3.3)(mysql2@3.22.3(@types/node@22.19.1))(postgres@3.4.7))(mysql2@3.22.3(@types/node@22.19.1)))(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260511.1)(@opentelemetry/api@1.9.1)(@types/better-sqlite3@7.6.13)(@types/pg@8.6.1)(better-sqlite3@12.9.0)(bun-types@1.3.3)(mysql2@3.22.3(@types/node@22.19.1))(postgres@3.4.7))(ioredis@5.10.1)(magicast@0.5.2)(mysql2@3.22.3(@types/node@22.19.1))(nuxt@4.4.2(75d3bb99739572e2ce1a5d32bf0400f3))(rolldown@1.0.0)(typescript@6.0.3)': + '@nuxt/nitro-server@4.4.2(@babel/core@7.29.0)(better-sqlite3@12.9.0)(db0@0.3.4(better-sqlite3@12.9.0)(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260511.1)(@opentelemetry/api@1.9.1)(@types/better-sqlite3@7.6.13)(@types/pg@8.6.1)(better-sqlite3@12.9.0)(bun-types@1.3.3)(mysql2@3.22.3(@types/node@22.19.1))(postgres@3.4.7))(mysql2@3.22.3(@types/node@22.19.1)))(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260511.1)(@opentelemetry/api@1.9.1)(@types/better-sqlite3@7.6.13)(@types/pg@8.6.1)(better-sqlite3@12.9.0)(bun-types@1.3.3)(mysql2@3.22.3(@types/node@22.19.1))(postgres@3.4.7))(ioredis@5.10.1)(magicast@0.5.2)(mysql2@3.22.3(@types/node@22.19.1))(nuxt@4.4.2(9b6f49a83ed1b2fc8889dfd9b7f2c45d))(rolldown@1.0.0)(typescript@6.0.3)': dependencies: '@babel/plugin-syntax-typescript': 7.28.6(@babel/core@7.29.0) '@nuxt/devalue': 2.0.2 @@ -15509,7 +15658,7 @@ snapshots: klona: 2.0.6 mocked-exports: 0.1.1 nitropack: 2.13.3(better-sqlite3@12.9.0)(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260511.1)(@opentelemetry/api@1.9.1)(@types/better-sqlite3@7.6.13)(@types/pg@8.6.1)(better-sqlite3@12.9.0)(bun-types@1.3.3)(mysql2@3.22.3(@types/node@22.19.1))(postgres@3.4.7))(mysql2@3.22.3(@types/node@22.19.1))(rolldown@1.0.0) - nuxt: 4.4.2(75d3bb99739572e2ce1a5d32bf0400f3) + nuxt: 4.4.2(9b6f49a83ed1b2fc8889dfd9b7f2c45d) nypm: 0.6.5 ohash: 2.0.11 pathe: 2.0.3 @@ -15576,7 +15725,7 @@ snapshots: rc9: 3.0.1 std-env: 4.1.0 - '@nuxt/vite-builder@4.4.2(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0))(@types/node@22.19.1)(lightningcss@1.30.1)(magicast@0.5.2)(nuxt@4.4.2(75d3bb99739572e2ce1a5d32bf0400f3))(optionator@0.9.4)(rolldown@1.0.0)(rollup-plugin-visualizer@7.0.1(rolldown@1.0.0)(rollup@4.60.2))(rollup@4.60.2)(terser@5.46.1)(tsx@4.21.0)(typescript@6.0.3)(vue@3.5.33(typescript@6.0.3))(yaml@2.9.0)': + '@nuxt/vite-builder@4.4.2(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0))(@types/node@22.19.1)(lightningcss@1.30.1)(magicast@0.5.2)(nuxt@4.4.2(9b6f49a83ed1b2fc8889dfd9b7f2c45d))(optionator@0.9.4)(oxlint@1.66.0)(rolldown@1.0.0)(rollup-plugin-visualizer@7.0.1(rolldown@1.0.0)(rollup@4.60.2))(rollup@4.60.2)(terser@5.46.1)(tsx@4.21.0)(typescript@6.0.3)(vue@3.5.33(typescript@6.0.3))(yaml@2.9.0)': dependencies: '@nuxt/kit': 4.4.2(magicast@0.5.2) '@rollup/plugin-replace': 6.0.3(rollup@4.60.2) @@ -15594,7 +15743,7 @@ snapshots: magic-string: 0.30.21 mlly: 1.8.2 mocked-exports: 0.1.1 - nuxt: 4.4.2(75d3bb99739572e2ce1a5d32bf0400f3) + nuxt: 4.4.2(9b6f49a83ed1b2fc8889dfd9b7f2c45d) nypm: 0.6.5 pathe: 2.0.3 pkg-types: 2.3.0 @@ -15605,7 +15754,7 @@ snapshots: unenv: 2.0.0-rc.24 vite: 7.3.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.1)(tsx@4.21.0)(yaml@2.9.0) vite-node: 5.3.0(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.1)(tsx@4.21.0)(yaml@2.9.0) - vite-plugin-checker: 0.12.0(optionator@0.9.4)(typescript@6.0.3)(vite@7.3.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.1)(tsx@4.21.0)(yaml@2.9.0)) + vite-plugin-checker: 0.12.0(optionator@0.9.4)(oxlint@1.66.0)(typescript@6.0.3)(vite@7.3.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.1)(tsx@4.21.0)(yaml@2.9.0)) vue: 3.5.33(typescript@6.0.3) vue-bundle-renderer: 2.2.0 optionalDependencies: @@ -16408,6 +16557,63 @@ snapshots: '@oxc-transform/binding-win32-x64-msvc@0.117.0': optional: true + '@oxlint/binding-android-arm-eabi@1.66.0': + optional: true + + '@oxlint/binding-android-arm64@1.66.0': + optional: true + + '@oxlint/binding-darwin-arm64@1.66.0': + optional: true + + '@oxlint/binding-darwin-x64@1.66.0': + optional: true + + '@oxlint/binding-freebsd-x64@1.66.0': + optional: true + + '@oxlint/binding-linux-arm-gnueabihf@1.66.0': + optional: true + + '@oxlint/binding-linux-arm-musleabihf@1.66.0': + optional: true + + '@oxlint/binding-linux-arm64-gnu@1.66.0': + optional: true + + '@oxlint/binding-linux-arm64-musl@1.66.0': + optional: true + + '@oxlint/binding-linux-ppc64-gnu@1.66.0': + optional: true + + '@oxlint/binding-linux-riscv64-gnu@1.66.0': + optional: true + + '@oxlint/binding-linux-riscv64-musl@1.66.0': + optional: true + + '@oxlint/binding-linux-s390x-gnu@1.66.0': + optional: true + + '@oxlint/binding-linux-x64-gnu@1.66.0': + optional: true + + '@oxlint/binding-linux-x64-musl@1.66.0': + optional: true + + '@oxlint/binding-openharmony-arm64@1.66.0': + optional: true + + '@oxlint/binding-win32-arm64-msvc@1.66.0': + optional: true + + '@oxlint/binding-win32-ia32-msvc@1.66.0': + optional: true + + '@oxlint/binding-win32-x64-msvc@1.66.0': + optional: true + '@parcel/watcher-android-arm64@2.5.6': optional: true @@ -23181,16 +23387,16 @@ snapshots: dependencies: boolbase: 1.0.0 - nuxt@4.4.2(75d3bb99739572e2ce1a5d32bf0400f3): + nuxt@4.4.2(9b6f49a83ed1b2fc8889dfd9b7f2c45d): dependencies: '@dxup/nuxt': 0.4.1(magicast@0.5.2)(typescript@6.0.3) '@nuxt/cli': 3.34.0(@nuxt/schema@4.4.2)(cac@6.7.14)(magicast@0.5.2) '@nuxt/devtools': 3.2.4(vite@7.3.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.1)(tsx@4.21.0)(yaml@2.9.0))(vue@3.5.33(typescript@6.0.3)) '@nuxt/kit': 4.4.2(magicast@0.5.2) - '@nuxt/nitro-server': 4.4.2(@babel/core@7.29.0)(better-sqlite3@12.9.0)(db0@0.3.4(better-sqlite3@12.9.0)(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260511.1)(@opentelemetry/api@1.9.1)(@types/better-sqlite3@7.6.13)(@types/pg@8.6.1)(better-sqlite3@12.9.0)(bun-types@1.3.3)(mysql2@3.22.3(@types/node@22.19.1))(postgres@3.4.7))(mysql2@3.22.3(@types/node@22.19.1)))(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260511.1)(@opentelemetry/api@1.9.1)(@types/better-sqlite3@7.6.13)(@types/pg@8.6.1)(better-sqlite3@12.9.0)(bun-types@1.3.3)(mysql2@3.22.3(@types/node@22.19.1))(postgres@3.4.7))(ioredis@5.10.1)(magicast@0.5.2)(mysql2@3.22.3(@types/node@22.19.1))(nuxt@4.4.2(75d3bb99739572e2ce1a5d32bf0400f3))(rolldown@1.0.0)(typescript@6.0.3) + '@nuxt/nitro-server': 4.4.2(@babel/core@7.29.0)(better-sqlite3@12.9.0)(db0@0.3.4(better-sqlite3@12.9.0)(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260511.1)(@opentelemetry/api@1.9.1)(@types/better-sqlite3@7.6.13)(@types/pg@8.6.1)(better-sqlite3@12.9.0)(bun-types@1.3.3)(mysql2@3.22.3(@types/node@22.19.1))(postgres@3.4.7))(mysql2@3.22.3(@types/node@22.19.1)))(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260511.1)(@opentelemetry/api@1.9.1)(@types/better-sqlite3@7.6.13)(@types/pg@8.6.1)(better-sqlite3@12.9.0)(bun-types@1.3.3)(mysql2@3.22.3(@types/node@22.19.1))(postgres@3.4.7))(ioredis@5.10.1)(magicast@0.5.2)(mysql2@3.22.3(@types/node@22.19.1))(nuxt@4.4.2(9b6f49a83ed1b2fc8889dfd9b7f2c45d))(rolldown@1.0.0)(typescript@6.0.3) '@nuxt/schema': 4.4.2 '@nuxt/telemetry': 2.8.0(@nuxt/kit@4.4.2(magicast@0.5.2)) - '@nuxt/vite-builder': 4.4.2(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0))(@types/node@22.19.1)(lightningcss@1.30.1)(magicast@0.5.2)(nuxt@4.4.2(75d3bb99739572e2ce1a5d32bf0400f3))(optionator@0.9.4)(rolldown@1.0.0)(rollup-plugin-visualizer@7.0.1(rolldown@1.0.0)(rollup@4.60.2))(rollup@4.60.2)(terser@5.46.1)(tsx@4.21.0)(typescript@6.0.3)(vue@3.5.33(typescript@6.0.3))(yaml@2.9.0) + '@nuxt/vite-builder': 4.4.2(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0))(@types/node@22.19.1)(lightningcss@1.30.1)(magicast@0.5.2)(nuxt@4.4.2(9b6f49a83ed1b2fc8889dfd9b7f2c45d))(optionator@0.9.4)(oxlint@1.66.0)(rolldown@1.0.0)(rollup-plugin-visualizer@7.0.1(rolldown@1.0.0)(rollup@4.60.2))(rollup@4.60.2)(terser@5.46.1)(tsx@4.21.0)(typescript@6.0.3)(vue@3.5.33(typescript@6.0.3))(yaml@2.9.0) '@unhead/vue': 2.1.13(vue@3.5.33(typescript@6.0.3)) '@vue/shared': 3.5.33 c12: 3.3.4(magicast@0.5.2) @@ -23550,6 +23756,28 @@ snapshots: magic-regexp: 0.10.0 oxc-parser: 0.117.0(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) + oxlint@1.66.0: + optionalDependencies: + '@oxlint/binding-android-arm-eabi': 1.66.0 + '@oxlint/binding-android-arm64': 1.66.0 + '@oxlint/binding-darwin-arm64': 1.66.0 + '@oxlint/binding-darwin-x64': 1.66.0 + '@oxlint/binding-freebsd-x64': 1.66.0 + '@oxlint/binding-linux-arm-gnueabihf': 1.66.0 + '@oxlint/binding-linux-arm-musleabihf': 1.66.0 + '@oxlint/binding-linux-arm64-gnu': 1.66.0 + '@oxlint/binding-linux-arm64-musl': 1.66.0 + '@oxlint/binding-linux-ppc64-gnu': 1.66.0 + '@oxlint/binding-linux-riscv64-gnu': 1.66.0 + '@oxlint/binding-linux-riscv64-musl': 1.66.0 + '@oxlint/binding-linux-s390x-gnu': 1.66.0 + '@oxlint/binding-linux-x64-gnu': 1.66.0 + '@oxlint/binding-linux-x64-musl': 1.66.0 + '@oxlint/binding-openharmony-arm64': 1.66.0 + '@oxlint/binding-win32-arm64-msvc': 1.66.0 + '@oxlint/binding-win32-ia32-msvc': 1.66.0 + '@oxlint/binding-win32-x64-msvc': 1.66.0 + p-limit@3.1.0: dependencies: yocto-queue: 0.1.0 @@ -25494,7 +25722,7 @@ snapshots: minimist: 1.2.8 strip-bom: 3.0.0 - tsdown@0.22.0(tsx@4.21.0)(typescript@6.0.3)(unrun@0.2.34): + tsdown@0.22.0(tsx@4.21.0)(typescript@6.0.3)(unrun@0.2.34(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)): dependencies: ansis: 4.3.0 cac: 7.0.0 @@ -26115,7 +26343,7 @@ snapshots: - tsx - yaml - vite-plugin-checker@0.12.0(optionator@0.9.4)(typescript@6.0.3)(vite@7.3.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.1)(tsx@4.21.0)(yaml@2.9.0)): + vite-plugin-checker@0.12.0(optionator@0.9.4)(oxlint@1.66.0)(typescript@6.0.3)(vite@7.3.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.1)(tsx@4.21.0)(yaml@2.9.0)): dependencies: '@babel/code-frame': 7.29.0 chokidar: 4.0.3 @@ -26128,6 +26356,7 @@ snapshots: vscode-uri: 3.1.0 optionalDependencies: optionator: 0.9.4 + oxlint: 1.66.0 typescript: 6.0.3 vite-plugin-inspect@11.3.3(@nuxt/kit@4.4.2(magicast@0.5.2))(vite@7.3.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.1)(tsx@4.21.0)(yaml@2.9.0)): diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 896419acb..7f01b4798 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -37,6 +37,7 @@ packages: - examples/elysia - examples/express - examples/koa +- examples/lint/oxlint - examples/next-integration - examples/fastify - examples/next14-app-router @@ -107,6 +108,7 @@ catalog: pkijs: ^3.3.3 mysql2: ^3.22.3 nuxt: ^4.4.2 + oxlint: ^1.66.0 postgres: ^3.4.7 tsdown: ^0.22.0 typescript: ^6.0.0