@sanity/plugin-kit
7.0.28.0.0
−
Removed (23 files)
+
Added (30 files)
~
Modified (6 files)
Index: package/assets/inject/semver-workflow/commitlint.template.js
===================================================================
--- package/assets/inject/semver-workflow/commitlint.template.js
+++ package/assets/inject/semver-workflow/commitlint.template.js
@@ -1,3 +1,3 @@
-module.exports = {
+export default {
extends: ['@commitlint/config-conventional'],
} Index: package/dist/index.js
===================================================================
--- package/dist/index.js
+++ package/dist/index.js
@@ -1,25 +1,25 @@
-import { t as cliName } from "./constants-BDxElAZy.js";
+import { t as cliName } from "./constants-BLTUL_Wd.js";
import { n as sharedFlags_default, t as log_default } from "./log-DgQL-Rv9.js";
import meow from "meow";
var cmds_default = {
init: async (options) => {
- await (await import("./init-BOM4Irb1.js")).default(options);
+ await (await import("./init-v15fyisU.js")).default(options);
},
inject: async (options) => {
- await (await import("./inject-CargN-jD.js")).default(options);
+ await (await import("./inject-B41UktQ3.js")).default(options);
},
"link-watch": async (options) => {
- await (await import("./link-watch-BnomBUbx.js")).default(options);
+ await (await import("./link-watch-B2ixqs1y.js")).default(options);
},
"verify-package": async (options) => {
- await (await import("./verify-package-Bfi7IL_f.js")).default(options);
+ await (await import("./verify-package-B32oCYay.js")).default(options);
},
"verify-studio": async (options) => {
- await (await import("./verify-studio-BwxN9e5-.js")).default(options);
+ await (await import("./verify-studio-DUoKxnYy.js")).default(options);
},
version: async (options) => {
- (await import("./version--tGGV9UM.js")).default(options);
+ (await import("./version-N9n1cr5G.js")).default(options);
}
};
/** @public */
async function cliEntry(argv = process.argv) { Index: package/assets/inject/semver-workflow/lint-staged.template.js
===================================================================
--- package/assets/inject/semver-workflow/lint-staged.template.js
+++ package/assets/inject/semver-workflow/lint-staged.template.js
@@ -1,4 +1,4 @@
-module.exports = {
- '**/*.{js,jsx}': ['eslint'],
- '**/*.{ts,tsx}': ['eslint', () => 'tsc --build'],
+export default {
+ '**/*.{json,jsonc,md}': ['oxfmt'],
+ '**/*.{js,jsx,ts,tsx}': ['oxfmt', 'oxlint'],
} Index: package/package.json
===================================================================
--- package/package.json
+++ package/package.json
@@ -1,7 +1,7 @@
{
"name": "@sanity/plugin-kit",
- "version": "7.0.2",
+ "version": "8.0.0",
"description": "Enhanced Sanity.io plugin development experience",
"keywords": [
"bootstrap",
"development",
@@ -32,8 +32,10 @@
"type": "module",
"types": "./dist/index.d.ts",
"exports": {
".": "./dist/index.js",
+ "./oxfmt": "./dist/oxfmt.js",
+ "./oxlint": "./dist/oxlint.js",
"./package.json": "./package.json"
},
"dependencies": {
"@rexxars/choosealicense-list": "^1.1.2",
@@ -49,48 +51,48 @@
"inquirer": "^8.2.7",
"json5": "^2.2.3",
"meow": "^9.0.0",
"nodemon": "3.1.0",
- "npm-run-path": "^4.0.1",
"outdent": "^0.8.0",
"p-any": "^3.0.0",
"p-props": "^4.0.0",
"validate-npm-package-name": "^8.0.0",
"xdg-basedir": "^4.0.0",
"yalc": "1.0.0-pre.53"
},
"devDependencies": {
- "@sanity/pkg-utils": "^11.0.1",
- "@sanity/tsconfig": "^2.2.0",
- "@sanity/tsdown-config": "^0.14.0",
- "@types/eslint": "^8.56.12",
+ "@sanity/pkg-utils": "^11.0.3",
+ "@sanity/tsconfig": "^2.2.1",
+ "@sanity/tsdown-config": "^0.14.2",
"@types/github-url-to-object": "^4.0.4",
"@types/inquirer": "^9.0.3",
"@types/node": "^24.13.3",
"@types/nodemon": "1.19.6",
"@types/react": "^19.2.17",
"@types/validate-npm-package-name": "^4.0.2",
- "@typescript-eslint/eslint-plugin": "^8.63.0",
- "@typescript-eslint/parser": "^8.63.0",
- "eslint": "^8.57.1",
- "eslint-config-prettier": "^10.1.8",
- "eslint-config-sanity": "^7.1.4",
- "eslint-plugin-prettier": "^5.5.6",
- "eslint-plugin-react": "^7.37.5",
- "eslint-plugin-react-hooks": "^7.1.1",
- "prettier": "^3.9.5",
+ "oxfmt": "^0.58.0",
+ "oxlint": "^1.73.0",
+ "oxlint-tsgolint": "^0.24.0",
"react": "^19.2.7",
"react-dom": "^19.2.7",
- "sanity": "^6.4.0",
+ "sanity": "^6.5.0",
"styled-components": "^6.4.3",
- "tsdown": "^0.22.7",
+ "tsdown": "^0.22.8",
"typescript": "7.0.2"
},
"peerDependencies": {
- "@sanity/pkg-utils": "^11.0.1",
- "eslint": ">=8.0.0",
- "typescript": "6.x || 7.x"
+ "@sanity/pkg-utils": "^11.0.3",
+ "oxfmt": "^0.58.0",
+ "oxlint": "^1.73.0"
},
+ "peerDependenciesMeta": {
+ "oxfmt": {
+ "optional": true
+ },
+ "oxlint": {
+ "optional": true
+ }
+ },
"engines": {
"node": ">=20.19 <22 || >=22.12"
},
"binname": "plugin-kit", Index: package/README.md
===================================================================
--- package/README.md
+++ package/README.md
@@ -29,8 +29,10 @@
## Table of contents
- [Installation](#installation)
- [Initialize a new plugin](#initialize-a-new-plugin)
+- [Formatting with oxfmt](#formatting-with-oxfmt)
+- [Linting with oxlint](#linting-with-oxlint)
- [Verify plugin package](#verify-plugin-package)
- [Upgrading a v2 plugin](#upgrading-a-v2-plugin)
- [Upgrade help in v2 Studio](#upgrade-help-in-v2-studio)
- [Inject config into existing v3 plugin](#inject-config-into-existing-package)
@@ -113,8 +115,85 @@
```
for up-to-date specifics.
+## Formatting with oxfmt
+
+Plugins are formatted with [oxfmt](https://oxc.rs/docs/guide/usage/formatter.html) using a shared
+preset exported as `@sanity/plugin-kit/oxfmt`. `plugin-kit init` sets this up automatically: it adds
+an `oxfmt` devDependency, a `format` script, and an `oxfmt.config.ts` re-exporting the preset:
+
+```ts
+export {default} from '@sanity/plugin-kit/oxfmt'
+```
+
+The config file belongs next to the `package.json` that installs and runs oxfmt. In a monorepo that
+is the workspace root, so every package is formatted the same way; in a standalone plugin repository
+it is the plugin directory itself.
+
+Oxfmt has no `extends` mechanism. To customize, spread the preset and override options:
+
+```ts
+import pluginKitOxfmt from '@sanity/plugin-kit/oxfmt'
+import {defineConfig} from 'oxfmt'
+
+export default defineConfig({
+ ...pluginKitOxfmt,
+ ignorePatterns: [...(pluginKitOxfmt.ignorePatterns ?? []), 'CHANGELOG.md'],
+})
+```
+
+Note: oxfmt loads TypeScript config files with Node's native TypeScript support, which requires
+Node `^20.19 || >=22.18`.
+
+Migrating a plugin from prettier? Remove the prettier config file (custom options can be migrated
+with `npx oxfmt --migrate=prettier`), drop the `prettier`, `prettier-plugin-packagejson` and
+`eslint-plugin-prettier` devDependencies, and add the `oxfmt.config.ts` above.
+
+## Linting with oxlint
+
+Plugins are linted with [oxlint](https://oxc.rs/docs/guide/usage/linter.html) using a shared config
+exported as `@sanity/plugin-kit/oxlint`. It enables type-aware rules and TypeScript type checking
+(via [oxlint-tsgolint](https://github.com/oxc-project/tsgolint)), treats warnings as errors, and
+turns on the React, React Compiler, import, promise, a11y and unicorn rule sets - the same setup
+the [sanity-io/plugins](https://github.com/sanity-io/plugins) monorepo uses. Because oxlint
+type-checks as part of linting, there is no separate `tsc` step.
+
+`plugin-kit init` sets this up automatically: it adds `oxlint` and `oxlint-tsgolint`
+devDependencies, a `lint` script, and an `oxlint.config.ts` re-exporting the shared config:
+
+```ts
+export {default} from '@sanity/plugin-kit/oxlint'
+```
+
+Like the oxfmt config, the `oxlint.config.ts` belongs next to the `package.json` that installs and
+runs oxlint: the workspace root in a monorepo, otherwise the plugin directory. To customize,
+[extend](https://oxc.rs/docs/guide/usage/linter/config.html#extend-shared-configs) the shared
+config and add your own options (`ignorePatterns` do not propagate through `extends`, so spread
+them explicitly when adding your own):
+
+```ts
+import sanityPluginKitOxlint from '@sanity/plugin-kit/oxlint'
+import {defineConfig} from 'oxlint'
+
+export default defineConfig({
+ extends: [sanityPluginKitOxlint],
+ ignorePatterns: [...(sanityPluginKitOxlint.ignorePatterns ?? []), 'examples/**'],
+ overrides: [
+ {
+ files: ['test/**'],
+ rules: {'no-console': 'off'},
+ },
+ ],
+})
+```
+
+Note: TypeScript config files require the Node-based `oxlint` package and Node `>=22.18`.
+
+Migrating a plugin from eslint? Remove the eslint config files and the eslint devDependencies
+(`eslint`, `eslint-config-*`, `eslint-plugin-*`, `@typescript-eslint/*`), and add the
+`oxlint.config.ts` above.
+
## Verify plugin package
Verify that the plugin package is configured correctly by running:
@@ -130,12 +209,12 @@
- recommended usage of devDependencies/peerDependencies/dependencies for certain packages
- Check for redundant v2 config:
- babel
- the deprecated `@sanity/incompatible-plugin` v2 compatibility shim (`sanity.json` + `v2-incompatible.js`)
-- Check for sanity imports that has changed in v3, using eslint
+- Check that the plugin is formatted with oxfmt using the shared `@sanity/plugin-kit/oxfmt` preset (and that no legacy prettier config remains)
+- Check that the plugin lints with oxlint using the shared `@sanity/plugin-kit/oxlint` config (and that no legacy eslint config remains)
- Check tsconfig.json settings
- Check for [SPDX](https://spdx.org/licenses/) compatible license definition
-- If the package uses TypeScript, this will also run `tsc --build` when all other checks have passed
Each check will explain why it is needed, steps to fix it and how it can be individually disabled.
### What it is _not_
@@ -166,9 +245,8 @@
This will:
- Check for `sanity.json,` `sanity.config.(ts|js)` and `sanity.cli.(ts|js)` and advice on how to convert the former to the latter two.
- Check for sanity dependencies that has changed in v3
-- Check for sanity imports that has changed in v3, using ESlint
### Fail fast mode
```sh
@@ -425,21 +503,20 @@
"verifyPackage": {
"packageName": true,
"esmOnly": true,
"tsconfig": true,
- "tsc": true,
"dependencies": true,
"deprecatedDependencies": true,
"babelConfig": true,
"incompatiblePlugin": true,
- "eslintImports": true,
"scripts": true,
"pkg-utils": true,
"nodeEngine": true,
"studioConfig": true,
"srcIndex": true,
"bannedFiles": true,
- "duplicateConfig": true
+ "oxfmt": true,
+ "oxlint": true
}
}
}
``` Index: package/assets/inject/semver-workflow/.github/workflows/main.yml
===================================================================
--- package/assets/inject/semver-workflow/.github/workflows/main.yml
+++ package/assets/inject/semver-workflow/.github/workflows/main.yml
@@ -45,9 +45,9 @@
runs-on: ubuntu-latest
name: Lint & Build
steps:
- uses: actions/checkout@v7
- - uses: actions/setup-node@v4
+ - uses: actions/setup-node@v7
with:
cache: npm
node-version: lts/*
- run: npm clean-install
@@ -85,9 +85,9 @@
run: |
git config --global core.autocrlf false
git config --global core.eol lf
- uses: actions/checkout@v7
- - uses: actions/setup-node@v4
+ - uses: actions/setup-node@v7
with:
cache: npm
node-version: ${{ matrix.node }}
- run: npm install
@@ -109,9 +109,9 @@
with:
# Need to fetch entire commit history to
# analyze every commit since last release
fetch-depth: 0
- - uses: actions/setup-node@v4
+ - uses: actions/setup-node@v7
with:
cache: npm
node-version: lts/*
- run: npm clean-install