diff --git a/.github/renovate.json b/.github/renovate.json index fa4ea29..1710eb6 100644 --- a/.github/renovate.json +++ b/.github/renovate.json @@ -1,6 +1,6 @@ { "$schema": "https://docs.renovatebot.com/renovate-schema.json", - "extends": ["config:best-practices", "customManagers:biomeVersions"], + "extends": ["config:best-practices"], "timezone": "Asia/Tokyo", "schedule": ["before 5am on Monday"], "labels": ["dependencies"], diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5a17ed2..f62ac72 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -84,15 +84,7 @@ jobs: name: Status Check runs-on: ubuntu-slim timeout-minutes: 1 - needs: - [ - setup, - lint-format, - type-check, - test, - export-validation, - dependency-review, - ] + needs: [setup, lint-format, type-check, test, export-validation, dependency-review] if: always() && (contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled')) steps: - run: exit 1 diff --git a/.oxfmtrc.json b/.oxfmtrc.json new file mode 100644 index 0000000..96faf12 --- /dev/null +++ b/.oxfmtrc.json @@ -0,0 +1,22 @@ +{ + "$schema": "./node_modules/oxfmt/configuration_schema.json", + "useTabs": true, + "tabWidth": 2, + "printWidth": 100, + "singleQuote": false, + "jsxSingleQuote": false, + "quoteProps": "as-needed", + "trailingComma": "all", + "semi": true, + "arrowParens": "always", + "bracketSameLine": false, + "bracketSpacing": true, + "overrides": [ + { + "files": ["*.md", "*.{yml,yaml}"], + "options": { + "useTabs": false + } + } + ] +} diff --git a/CLAUDE.md b/CLAUDE.md index 6650560..6e04f35 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -48,8 +48,7 @@ bun run check:type:example | **tsup** | Build (bundler) | | **vitest** | Test runner | | **oxlint** | Linter | -| **Biome** | Formatter (TS/JS/JSON) | -| **Prettier** | Formatter (Markdown/YAML) | +| **oxfmt** | Formatter (TS/JS/JSON) | | **publint** / **attw** | Package export validation | | **npm-run-all2** | Script orchestration | @@ -73,7 +72,7 @@ bun run test:watch # Watch mode for testing ```bash bun run lint # oxlint (deny-warnings) bun run lint:fix # oxlint --fix-suggestions -bun run format # Biome + Prettier (write) +bun run format # oxfmt (write) bun run fix # lint:fix + format (all-in-one auto-fix) ``` diff --git a/README.md b/README.md index 2ad5033..858fc1e 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,7 @@ It enforces strict rules on keys and forbids structural inference by design. - [Result](#result) - [Issues](#issues) - [Versioning](#versioning) + - [Contributing](#contributing) - [License](#license) --- diff --git a/biome.json b/biome.json deleted file mode 100644 index 65fefb9..0000000 --- a/biome.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "$schema": "https://biomejs.dev/schemas/2.3.10/schema.json", - "vcs": { - "enabled": true, - "clientKind": "git", - "useIgnoreFile": true - }, - "files": { - "includes": ["**", "!!**/coverage", "!!**/dist"] - }, - "linter": { - "enabled": false - }, - "formatter": { - "enabled": true, - "lineWidth": 100 - }, - "assist": { - "enabled": true, - "actions": { - "source": { - "organizeImports": "on" - } - } - } -} diff --git a/bun.lock b/bun.lock index f93d93f..733763d 100644 --- a/bun.lock +++ b/bun.lock @@ -6,13 +6,12 @@ "name": "safe-formdata", "devDependencies": { "@arethetypeswrong/cli": "0.18.2", - "@biomejs/biome": "2.3.10", "@types/node": "25.0.3", "@vitest/coverage-v8": "4.0.16", "happy-dom": "20.0.11", "npm-run-all2": "8.0.4", + "oxfmt": "0.35.0", "oxlint": "1.34.0", - "prettier": "3.7.4", "publint": "0.3.16", "terser": "5.44.1", "tsup": "8.5.1", @@ -38,24 +37,6 @@ "@bcoe/v8-coverage": ["@bcoe/v8-coverage@1.0.2", "", {}, "sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA=="], - "@biomejs/biome": ["@biomejs/biome@2.3.10", "", { "optionalDependencies": { "@biomejs/cli-darwin-arm64": "2.3.10", "@biomejs/cli-darwin-x64": "2.3.10", "@biomejs/cli-linux-arm64": "2.3.10", "@biomejs/cli-linux-arm64-musl": "2.3.10", "@biomejs/cli-linux-x64": "2.3.10", "@biomejs/cli-linux-x64-musl": "2.3.10", "@biomejs/cli-win32-arm64": "2.3.10", "@biomejs/cli-win32-x64": "2.3.10" }, "bin": { "biome": "bin/biome" } }, "sha512-/uWSUd1MHX2fjqNLHNL6zLYWBbrJeG412/8H7ESuK8ewoRoMPUgHDebqKrPTx/5n6f17Xzqc9hdg3MEqA5hXnQ=="], - - "@biomejs/cli-darwin-arm64": ["@biomejs/cli-darwin-arm64@2.3.10", "", { "os": "darwin", "cpu": "arm64" }, "sha512-M6xUjtCVnNGFfK7HMNKa593nb7fwNm43fq1Mt71kpLpb+4mE7odO8W/oWVDyBVO4ackhresy1ZYO7OJcVo/B7w=="], - - "@biomejs/cli-darwin-x64": ["@biomejs/cli-darwin-x64@2.3.10", "", { "os": "darwin", "cpu": "x64" }, "sha512-Vae7+V6t/Avr8tVbFNjnFSTKZogZHFYl7MMH62P/J1kZtr0tyRQ9Fe0onjqjS2Ek9lmNLmZc/VR5uSekh+p1fg=="], - - "@biomejs/cli-linux-arm64": ["@biomejs/cli-linux-arm64@2.3.10", "", { "os": "linux", "cpu": "arm64" }, "sha512-hhPw2V3/EpHKsileVOFynuWiKRgFEV48cLe0eA+G2wO4SzlwEhLEB9LhlSrVeu2mtSn205W283LkX7Fh48CaxA=="], - - "@biomejs/cli-linux-arm64-musl": ["@biomejs/cli-linux-arm64-musl@2.3.10", "", { "os": "linux", "cpu": "arm64" }, "sha512-B9DszIHkuKtOH2IFeeVkQmSMVUjss9KtHaNXquYYWCjH8IstNgXgx5B0aSBQNr6mn4RcKKRQZXn9Zu1rM3O0/A=="], - - "@biomejs/cli-linux-x64": ["@biomejs/cli-linux-x64@2.3.10", "", { "os": "linux", "cpu": "x64" }, "sha512-wwAkWD1MR95u+J4LkWP74/vGz+tRrIQvr8kfMMJY8KOQ8+HMVleREOcPYsQX82S7uueco60L58Wc6M1I9WA9Dw=="], - - "@biomejs/cli-linux-x64-musl": ["@biomejs/cli-linux-x64-musl@2.3.10", "", { "os": "linux", "cpu": "x64" }, "sha512-QTfHZQh62SDFdYc2nfmZFuTm5yYb4eO1zwfB+90YxUumRCR171tS1GoTX5OD0wrv4UsziMPmrePMtkTnNyYG3g=="], - - "@biomejs/cli-win32-arm64": ["@biomejs/cli-win32-arm64@2.3.10", "", { "os": "win32", "cpu": "arm64" }, "sha512-o7lYc9n+CfRbHvkjPhm8s9FgbKdYZu5HCcGVMItLjz93EhgJ8AM44W+QckDqLA9MKDNFrR8nPbO4b73VC5kGGQ=="], - - "@biomejs/cli-win32-x64": ["@biomejs/cli-win32-x64@2.3.10", "", { "os": "win32", "cpu": "x64" }, "sha512-pHEFgq7dUEsKnqG9mx9bXihxGI49X+ar+UBrEIj3Wqj3UCZp1rNgV+OoyjFgcXsjCWpuEAF4VJdkZr3TrWdCbQ=="], - "@braidai/lang": ["@braidai/lang@1.1.2", "", {}, "sha512-qBcknbBufNHlui137Hft8xauQMTZDKdophmLFv05r2eNmdIv/MlPuP4TdUknHG68UdWLgVZwgxVe735HzJNIwA=="], "@colors/colors": ["@colors/colors@1.5.0", "", {}, "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ=="], @@ -124,6 +105,44 @@ "@loaderkit/resolve": ["@loaderkit/resolve@1.0.4", "", { "dependencies": { "@braidai/lang": "^1.0.0" } }, "sha512-rJzYKVcV4dxJv+vW6jlvagF8zvGxHJ2+HTr1e2qOejfmGhAApgJHl8Aog4mMszxceTRiKTTbnpgmTO1bEZHV/A=="], + "@oxfmt/binding-android-arm-eabi": ["@oxfmt/binding-android-arm-eabi@0.35.0", "", { "os": "android", "cpu": "arm" }, "sha512-BaRKlM3DyG81y/xWTsE6gZiv89F/3pHe2BqX2H4JbiB8HNVlWWtplzgATAE5IDSdwChdeuWLDTQzJ92Lglw3ZA=="], + + "@oxfmt/binding-android-arm64": ["@oxfmt/binding-android-arm64@0.35.0", "", { "os": "android", "cpu": "arm64" }, "sha512-/O+EbuAJYs6nde/anv+aID6uHsGQApyE9JtYBo/79KyU8e6RBN3DMbT0ix97y1SOnCglurmL2iZ+hlohjP2PnQ=="], + + "@oxfmt/binding-darwin-arm64": ["@oxfmt/binding-darwin-arm64@0.35.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-pGqRtqlNdn9d4VrmGUWVyQjkw79ryhI6je9y2jfqNUIZCfqceob+R97YYAoG7C5TFyt8ILdLVoN+L2vw/hSFyA=="], + + "@oxfmt/binding-darwin-x64": ["@oxfmt/binding-darwin-x64@0.35.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-8GmsDcSozTPjrCJeGpp+sCmS9+9V5yRrdEZ1p/sTWxPG5nYeAfSLuS0nuEYjXSO+CtdSbStIW6dxa+4NM58yRw=="], + + "@oxfmt/binding-freebsd-x64": ["@oxfmt/binding-freebsd-x64@0.35.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-QyfKfTe0ytHpFKHAcHCGQEzN45QSqq1AHJOYYxQMgLM3KY4xu8OsXHpCnINjDsV4XGnQzczJDU9e04Zmd8XqIQ=="], + + "@oxfmt/binding-linux-arm-gnueabihf": ["@oxfmt/binding-linux-arm-gnueabihf@0.35.0", "", { "os": "linux", "cpu": "arm" }, "sha512-u+kv3JD6P3J38oOyUaiCqgY5TNESzBRZJ5lyZQ6c2czUW2v5SIN9E/KWWa9vxoc+P8AFXQFUVrdzGy1tK+nbPQ=="], + + "@oxfmt/binding-linux-arm-musleabihf": ["@oxfmt/binding-linux-arm-musleabihf@0.35.0", "", { "os": "linux", "cpu": "arm" }, "sha512-1NiZroCiV57I7Pf8kOH4XGR366kW5zir3VfSMBU2D0V14GpYjiYmPYFAoJboZvp8ACnZKUReWyMkNKSa5ad58A=="], + + "@oxfmt/binding-linux-arm64-gnu": ["@oxfmt/binding-linux-arm64-gnu@0.35.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-7Q0Xeg7ZnW2nxnZ4R7aF6DEbCFls4skgHZg+I63XitpNvJCbVIU8MFOTZlvZGRsY9+rPgWPQGeUpLHlyx0wvMA=="], + + "@oxfmt/binding-linux-arm64-musl": ["@oxfmt/binding-linux-arm64-musl@0.35.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-5Okqi+uhYFxwKz8hcnUftNNwdm8BCkf6GSCbcz9xJxYMm87k1E4p7PEmAAbhLTk7cjSdDre6TDL0pDzNX+Y22Q=="], + + "@oxfmt/binding-linux-ppc64-gnu": ["@oxfmt/binding-linux-ppc64-gnu@0.35.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-9k66pbZQXM/lBJWys3Xbc5yhl4JexyfqkEf/tvtq8976VIJnLAAL3M127xHA3ifYSqxdVHfVGTg84eiBHCGcNw=="], + + "@oxfmt/binding-linux-riscv64-gnu": ["@oxfmt/binding-linux-riscv64-gnu@0.35.0", "", { "os": "linux", "cpu": "none" }, "sha512-aUcY9ofKPtjO52idT6t0SAQvEF6ctjzUQa1lLp7GDsRpSBvuTrBQGeq0rYKz3gN8dMIQ7mtMdGD9tT4LhR8jAQ=="], + + "@oxfmt/binding-linux-riscv64-musl": ["@oxfmt/binding-linux-riscv64-musl@0.35.0", "", { "os": "linux", "cpu": "none" }, "sha512-C6yhY5Hvc2sGM+mCPek9ZLe5xRUOC/BvhAt2qIWFAeXMn4il04EYIjl3DsWiJr0xDMTJhvMOmD55xTRPlNp39w=="], + + "@oxfmt/binding-linux-s390x-gnu": ["@oxfmt/binding-linux-s390x-gnu@0.35.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-RG2hlvOMK4OMZpO3mt8MpxLQ0AAezlFqhn5mI/g5YrVbPFyoCv9a34AAvbSJS501ocOxlFIRcKEuw5hFvddf9g=="], + + "@oxfmt/binding-linux-x64-gnu": ["@oxfmt/binding-linux-x64-gnu@0.35.0", "", { "os": "linux", "cpu": "x64" }, "sha512-wzmh90Pwvqj9xOKHJjkQYBpydRkaXG77ZvDz+iFDRRQpnqIEqGm5gmim2s6vnZIkDGsvKCuTdtxm0GFmBjM1+w=="], + + "@oxfmt/binding-linux-x64-musl": ["@oxfmt/binding-linux-x64-musl@0.35.0", "", { "os": "linux", "cpu": "x64" }, "sha512-+HCqYCJPCUy5I+b2cf+gUVaApfgtoQT3HdnSg/l7NIcLHOhKstlYaGyrFZLmUpQt4WkFbpGKZZayG6zjRU0KFA=="], + + "@oxfmt/binding-openharmony-arm64": ["@oxfmt/binding-openharmony-arm64@0.35.0", "", { "os": "none", "cpu": "arm64" }, "sha512-kFYmWfR9YL78XyO5ws+1dsxNvZoD973qfVMNFOS4e9bcHXGF7DvGC2tY5UDFwyMCeB33t3sDIuGONKggnVNSJA=="], + + "@oxfmt/binding-win32-arm64-msvc": ["@oxfmt/binding-win32-arm64-msvc@0.35.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-uD/NGdM65eKNCDGyTGdO8e9n3IHX+wwuorBvEYrPJXhDXL9qz6gzddmXH8EN04ejUXUujlq4FsoSeCfbg0Y+Jg=="], + + "@oxfmt/binding-win32-ia32-msvc": ["@oxfmt/binding-win32-ia32-msvc@0.35.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-oSRD2k8J2uxYDEKR2nAE/YTY9PobOEnhZgCmspHu0+yBQ665yH8lFErQVSTE7fcGJmJp/cC6322/gc8VFuQf7g=="], + + "@oxfmt/binding-win32-x64-msvc": ["@oxfmt/binding-win32-x64-msvc@0.35.0", "", { "os": "win32", "cpu": "x64" }, "sha512-WCDJjlS95NboR0ugI2BEwzt1tYvRDorDRM9Lvctls1SLyKYuNRCyrPwp1urUPFBnwgBNn9p2/gnmo7gFMySRoQ=="], + "@oxlint/darwin-arm64": ["@oxlint/darwin-arm64@1.34.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-euz3Dtp5/UE9axFkQnllOWp3gOwoqaxfZPUUwiW8HBelqhI9PRMVIfQ/akmwl+G5XixQZIgXkXQ5SJxnb1+Qww=="], "@oxlint/darwin-x64": ["@oxlint/darwin-x64@1.34.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-XpmNviE5KOnHkhmQPwJJIBs+mJkr0qItTZBN4dz+O3p9gWN+gCqi3CBP71RiVahZw4qAEQSgY4wro+z0kx+erg=="], @@ -358,6 +377,8 @@ "obug": ["obug@2.1.1", "", {}, "sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ=="], + "oxfmt": ["oxfmt@0.35.0", "", { "dependencies": { "tinypool": "2.1.0" }, "optionalDependencies": { "@oxfmt/binding-android-arm-eabi": "0.35.0", "@oxfmt/binding-android-arm64": "0.35.0", "@oxfmt/binding-darwin-arm64": "0.35.0", "@oxfmt/binding-darwin-x64": "0.35.0", "@oxfmt/binding-freebsd-x64": "0.35.0", "@oxfmt/binding-linux-arm-gnueabihf": "0.35.0", "@oxfmt/binding-linux-arm-musleabihf": "0.35.0", "@oxfmt/binding-linux-arm64-gnu": "0.35.0", "@oxfmt/binding-linux-arm64-musl": "0.35.0", "@oxfmt/binding-linux-ppc64-gnu": "0.35.0", "@oxfmt/binding-linux-riscv64-gnu": "0.35.0", "@oxfmt/binding-linux-riscv64-musl": "0.35.0", "@oxfmt/binding-linux-s390x-gnu": "0.35.0", "@oxfmt/binding-linux-x64-gnu": "0.35.0", "@oxfmt/binding-linux-x64-musl": "0.35.0", "@oxfmt/binding-openharmony-arm64": "0.35.0", "@oxfmt/binding-win32-arm64-msvc": "0.35.0", "@oxfmt/binding-win32-ia32-msvc": "0.35.0", "@oxfmt/binding-win32-x64-msvc": "0.35.0" }, "bin": { "oxfmt": "bin/oxfmt" } }, "sha512-QYeXWkP+aLt7utt5SLivNIk09glWx9QE235ODjgcEZ3sd1VMaUBSpLymh6ZRCA76gD2rMP4bXanUz/fx+nLM9Q=="], + "oxlint": ["oxlint@1.34.0", "", { "optionalDependencies": { "@oxlint/darwin-arm64": "1.34.0", "@oxlint/darwin-x64": "1.34.0", "@oxlint/linux-arm64-gnu": "1.34.0", "@oxlint/linux-arm64-musl": "1.34.0", "@oxlint/linux-x64-gnu": "1.34.0", "@oxlint/linux-x64-musl": "1.34.0", "@oxlint/win32-arm64": "1.34.0", "@oxlint/win32-x64": "1.34.0" }, "peerDependencies": { "oxlint-tsgolint": ">=0.9.2" }, "optionalPeers": ["oxlint-tsgolint"], "bin": { "oxc_language_server": "bin/oxc_language_server", "oxlint": "bin/oxlint" } }, "sha512-Ni0N8wAiKlgaYkI/Yz4VrutfVIZgd2shDtS+loQxyBTwO8YUAnk3+g7OQ1cyI/aatHiFwvFNfV/uvZyHUtyPpA=="], "package-manager-detector": ["package-manager-detector@1.6.0", "", {}, "sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA=="], @@ -384,8 +405,6 @@ "postcss-load-config": ["postcss-load-config@6.0.1", "", { "dependencies": { "lilconfig": "^3.1.1" }, "peerDependencies": { "jiti": ">=1.21.0", "postcss": ">=8.0.9", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["jiti", "postcss", "tsx", "yaml"] }, "sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g=="], - "prettier": ["prettier@3.7.4", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-v6UNi1+3hSlVvv8fSaoUbggEM5VErKmmpGA7Pl3HF8V6uKY7rvClBOJlH6yNwQtfTueNkGVpOv/mtWL9L4bgRA=="], - "publint": ["publint@0.3.16", "", { "dependencies": { "@publint/pack": "^0.1.2", "package-manager-detector": "^1.6.0", "picocolors": "^1.1.1", "sade": "^1.8.1" }, "bin": { "publint": "src/cli.js" } }, "sha512-MFqyfRLAExPVZdTQFwkAQELzA8idyXzROVOytg6nEJ/GEypXBUmMGrVaID8cTuzRS1U5L8yTOdOJtMXgFUJAeA=="], "read-package-json-fast": ["read-package-json-fast@4.0.0", "", { "dependencies": { "json-parse-even-better-errors": "^4.0.0", "npm-normalize-package-bin": "^4.0.0" } }, "sha512-qpt8EwugBWDw2cgE2W+/3oxC+KTez2uSVR8JU9Q36TXPAGCaozfQUs59v4j4GFpWTaw0i6hAZSvOmu1J0uOEUg=="], @@ -444,6 +463,8 @@ "tinyglobby": ["tinyglobby@0.2.15", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.3" } }, "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ=="], + "tinypool": ["tinypool@2.1.0", "", {}, "sha512-Pugqs6M0m7Lv1I7FtxN4aoyToKg1C4tu+/381vH35y8oENM/Ai7f7C4StcoK4/+BSw9ebcS8jRiVrORFKCALLw=="], + "tinyrainbow": ["tinyrainbow@3.0.3", "", {}, "sha512-PSkbLUoxOFRzJYjjxHJt9xro7D+iilgMX/C9lawzVuYiIdcihh9DXmVibBe8lmcFrRi/VzlPjBxbN7rH24q8/Q=="], "tree-kill": ["tree-kill@1.2.2", "", { "bin": { "tree-kill": "cli.js" } }, "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A=="], diff --git a/package.json b/package.json index 9ce474b..b44d898 100644 --- a/package.json +++ b/package.json @@ -2,15 +2,30 @@ "name": "safe-formdata", "version": "0.1.3", "description": "Boundary-focused FormData parser with strict security guarantees", + "keywords": [ + "boundary", + "formdata", + "parser", + "prototype-pollution", + "security" + ], + "homepage": "https://github.com/roottool/safe-formdata#readme", + "bugs": { + "url": "https://github.com/roottool/safe-formdata/issues" + }, + "license": "MIT", "author": "roottool", "repository": { "type": "git", "url": "git+https://github.com/roottool/safe-formdata.git" }, - "bugs": { - "url": "https://github.com/roottool/safe-formdata/issues" - }, - "homepage": "https://github.com/roottool/safe-formdata#readme", + "files": [ + "dist" + ], + "type": "module", + "main": "./dist/index.js", + "module": "./dist/index.js", + "types": "./dist/index.d.ts", "imports": { "#*": { "types": "./src/*.ts", @@ -19,10 +34,6 @@ }, "#safe-formdata": "./src/index.ts" }, - "type": "module", - "main": "./dist/index.js", - "module": "./dist/index.js", - "types": "./dist/index.d.ts", "exports": { ".": { "types": "./dist/index.d.ts", @@ -30,28 +41,19 @@ "default": "./dist/index.js" } }, - "files": [ - "dist" - ], "scripts": { "dev": "tsup --watch", "lint": "oxlint . --deny-warnings", "lint:fix": "oxlint . --fix-suggestions", - "format:biome": "biome check --write --assist-enabled true", - "format:prettier": "prettier --cache --write \"**/*.{md,yml,yaml}\"", - "format": "npm-run-all2 format:biome format:prettier", + "format": "oxfmt", "fix": "npm-run-all2 lint:fix format", - "check:biome": "biome check . --assist-enabled true", - "check:prettier": "prettier --cache --check \"**/*.{md,yml,yaml}\"", - "check:format": "npm-run-all2 check:biome check:prettier", + "check:format": "oxfmt --check", "check:source": "npm-run-all2 lint check:format", "check": "bun run check:source", "check:type:source": "tsc --noEmit", "check:type:example": "tsc --project tsconfig.examples.json --noEmit", "check:type": "npm-run-all2 check:type:source check:type:example", - "check:prettier:ci": "prettier --check \"**/*.{md,yml,yaml}\"", - "check:format:ci": "npm-run-all2 check:biome check:prettier:ci", - "check:source:ci": "npm-run-all2 lint check:format:ci", + "check:source:ci": "npm-run-all2 lint check:format", "test": "vitest run", "test:watch": "vitest", "test:coverage": "vitest run --coverage", @@ -61,25 +63,16 @@ }, "devDependencies": { "@arethetypeswrong/cli": "0.18.2", - "@biomejs/biome": "2.3.10", "@types/node": "25.0.3", "@vitest/coverage-v8": "4.0.16", "happy-dom": "20.0.11", "npm-run-all2": "8.0.4", + "oxfmt": "0.35.0", "oxlint": "1.34.0", - "prettier": "3.7.4", "publint": "0.3.16", "terser": "5.44.1", "tsup": "8.5.1", "typescript": "5.9.3", "vitest": "4.0.16" - }, - "license": "MIT", - "keywords": [ - "formdata", - "parser", - "security", - "boundary", - "prototype-pollution" - ] + } } diff --git a/skills/boundary-validator/examples/bad-code.md b/skills/boundary-validator/examples/bad-code.md index 981bd2c..3d087a6 100644 --- a/skills/boundary-validator/examples/bad-code.md +++ b/skills/boundary-validator/examples/bad-code.md @@ -460,11 +460,7 @@ export function parse(formData: FormData, strict?: boolean): ParseResult { ```typescript // ❌ WRONG: Adding new issue code in minor version -export type IssueCode = - | "invalid_key" - | "forbidden_key" - | "duplicate_key" - | "invalid_value"; // NEW - requires major version bump! +export type IssueCode = "invalid_key" | "forbidden_key" | "duplicate_key" | "invalid_value"; // NEW - requires major version bump! // Problem: Breaking change without major version bump // Violates: API contract (IssueCode stability) diff --git a/skills/boundary-validator/references/api-contract.md b/skills/boundary-validator/references/api-contract.md index 6df40c1..8e361d5 100644 --- a/skills/boundary-validator/references/api-contract.md +++ b/skills/boundary-validator/references/api-contract.md @@ -34,10 +34,7 @@ function parse(formData: FormData): ParseResult; function parse(formData: FormData, options: ParseOptions): ParseResult; // Adding options -function parse( - formData: FormData, - options?: { allowDuplicates?: boolean }, -): ParseResult; +function parse(formData: FormData, options?: { allowDuplicates?: boolean }): ParseResult; // Adding framework adapters function parseRequest(req: NextRequest): ParseResult; @@ -191,11 +188,7 @@ export type IssueCode = "invalid_key" | "forbidden_key" | "duplicate_key"; export type IssueCode = "invalid_key" | "forbidden_key" | "duplicate_key"; // v1.0.0 - Major version allows changes -export type IssueCode = - | "invalid_key" - | "forbidden_key" - | "duplicate_key" - | "invalid_value"; // OK in major version +export type IssueCode = "invalid_key" | "forbidden_key" | "duplicate_key" | "invalid_value"; // OK in major version ``` --- diff --git a/skills/boundary-validator/references/validation-patterns.md b/skills/boundary-validator/references/validation-patterns.md index ecc0798..57b5823 100644 --- a/skills/boundary-validator/references/validation-patterns.md +++ b/skills/boundary-validator/references/validation-patterns.md @@ -104,9 +104,7 @@ data[key] = value; // If key exists, this silently overwrites ```typescript // ❌ Violation: Converting to array for duplicates if (data[key]) { - data[key] = Array.isArray(data[key]) - ? [...data[key], value] - : [data[key], value]; + data[key] = Array.isArray(data[key]) ? [...data[key], value] : [data[key], value]; } // ❌ Violation: Array push @@ -392,11 +390,7 @@ export function parse(formData: FormData, strict: boolean): ParseResult; ```typescript // ❌ Violation: Adding new issue codes without major version bump -export type IssueCode = - | "invalid_key" - | "forbidden_key" - | "duplicate_key" - | "invalid_value"; // NEW CODE - requires major version! +export type IssueCode = "invalid_key" | "forbidden_key" | "duplicate_key" | "invalid_value"; // NEW CODE - requires major version! ``` ### Correct Patterns