diff --git a/eslint.config.js b/eslint.config.js index c91d73f02..54af1e2a3 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -72,6 +72,9 @@ export default defineConfig( "no-useless-rename": "error", "object-shorthand": "error", "operator-assignment": "error", + + // https://github.com/eslint-community/eslint-plugin-n/issues/472 + "n/no-unpublished-bin": "off", }, settings: { perfectionist: { partitionByComment: true, type: "natural" } }, }, diff --git a/package.json b/package.json index d7fa5136a..77cf639ef 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,6 @@ "main": "lib/index.js", "bin": "bin/index.js", "files": [ - "bin/index.js", "lib/" ], "scripts": { @@ -94,7 +93,7 @@ "eslint-plugin-jsonc": "2.21.0", "eslint-plugin-markdown": "5.1.0", "eslint-plugin-n": "17.23.1", - "eslint-plugin-package-json": "0.54.0", + "eslint-plugin-package-json": "0.85.0", "eslint-plugin-perfectionist": "4.15.1", "eslint-plugin-regexp": "2.10.0", "eslint-plugin-yml": "1.19.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c2ad58cf6..ae08caa56 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -184,8 +184,8 @@ importers: specifier: 17.23.1 version: 17.23.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3) eslint-plugin-package-json: - specifier: 0.54.0 - version: 0.54.0(@types/estree@1.0.8)(eslint@9.39.1(jiti@2.6.1))(jsonc-eslint-parser@2.4.1) + specifier: 0.85.0 + version: 0.85.0(@types/estree@1.0.8)(eslint@9.39.1(jiti@2.6.1))(jsonc-eslint-parser@2.4.1) eslint-plugin-perfectionist: specifier: 4.15.1 version: 4.15.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3) @@ -2441,9 +2441,9 @@ packages: peerDependencies: eslint: '>=8.23.0' - eslint-plugin-package-json@0.54.0: - resolution: {integrity: sha512-KXVMhx/Hj2Rb8LbBbWG0fXoqImNz5rUVdF5FO8EGDsgWd3zGBisxFf9rZGGzPeMQTF67Bo/49c8xXFyT+Nd+dw==} - engines: {node: ^=20.19.0 || >=22.12.0} + eslint-plugin-package-json@0.85.0: + resolution: {integrity: sha512-MrOxFvhbqLuk4FIPG9v3u9Amn0n137J8LKILHvgfxK3rRyAHEVzuZM0CtpXFTx7cx4LzmAzONtlpjbM0UFNuTA==} + engines: {node: ^20.19.0 || >=22.12.0} peerDependencies: eslint: '>=8.0.0' jsonc-eslint-parser: ^2.0.0 @@ -3495,8 +3495,8 @@ packages: resolution: {integrity: sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==} engines: {node: '>= 14'} - package-json-validator@0.29.1: - resolution: {integrity: sha512-xS8okscm06Nw2OhInIqFpFhkVWLRYRjCujHN7yeEUHlS+Ppg1n/ec4AkDlycdhUX/98HbAuOfKJ0lLXt6NIV9w==} + package-json-validator@0.59.0: + resolution: {integrity: sha512-WBTDKtO9pBa9GmA1sPbQHqlWxRdnHNfLFIIA49PPgV7px/rG27gHX57DWy77qyu374fla4veaIHy+gA+qRRuug==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true @@ -3927,9 +3927,6 @@ packages: resolution: {integrity: sha512-ueSlHJMwpIw42CJ4B11Uxzh/S0p0AlOyiNktlv2KOu5e1JpUE6DlC4AAUjXqesHdBRv/g0wC9Q4vwq0NP2pA9w==} engines: {node: '>=20'} - sort-object-keys@1.1.3: - resolution: {integrity: sha512-855pvK+VkU7PaKYPc+Jjnmt4EzejQHyhhF33q31qG8x7maDzkeFhAAThdCYay11CISO+qAMwjOBP+fPZe0IPyg==} - sort-object-keys@2.0.1: resolution: {integrity: sha512-R89fO+z3x7hiKPXX5P0qim+ge6Y60AjtlW+QQpRozrrNcR1lw9Pkpm5MLB56HoNvdcLHL4wbpq16OcvGpEDJIg==} @@ -4233,9 +4230,9 @@ packages: validate-npm-package-license@3.0.4: resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} - validate-npm-package-name@6.0.2: - resolution: {integrity: sha512-IUoow1YUtvoBBC06dXs8bR8B9vuA3aJfmQNKMoaPG/OFsPmoQvw8xh+6Ye25Gx9DQhoEom3Pcu9MKHerm/NpUQ==} - engines: {node: ^18.17.0 || >=20.5.0} + validate-npm-package-name@7.0.0: + resolution: {integrity: sha512-bwVk/OK+Qu108aJcMAEiU4yavHUI7aN20TgZNBj9MR2iU1zPUl1Z1Otr7771ExfYTPTvfN8ZJ1pbr5Iklgt4xg==} + engines: {node: ^20.17.0 || >=22.9.0} vite@7.2.6: resolution: {integrity: sha512-tI2l/nFHC5rLh7+5+o7QjKjSR04ivXDF4jcgV0f/bTQ+OJiITy5S6gaynVsEM+7RqzufMnVbIon6Sr5x1SDYaQ==} @@ -6537,7 +6534,7 @@ snapshots: transitivePeerDependencies: - typescript - eslint-plugin-package-json@0.54.0(@types/estree@1.0.8)(eslint@9.39.1(jiti@2.6.1))(jsonc-eslint-parser@2.4.1): + eslint-plugin-package-json@0.85.0(@types/estree@1.0.8)(eslint@9.39.1(jiti@2.6.1))(jsonc-eslint-parser@2.4.1): dependencies: '@altano/repository-tools': 2.0.1 change-case: 5.4.4 @@ -6546,11 +6543,11 @@ snapshots: eslint: 9.39.1(jiti@2.6.1) eslint-fix-utils: 0.4.0(@types/estree@1.0.8)(eslint@9.39.1(jiti@2.6.1)) jsonc-eslint-parser: 2.4.1 - package-json-validator: 0.29.1 + package-json-validator: 0.59.0 semver: 7.7.3 - sort-object-keys: 1.1.3 + sort-object-keys: 2.0.1 sort-package-json: 3.5.0 - validate-npm-package-name: 6.0.2 + validate-npm-package-name: 7.0.0 transitivePeerDependencies: - '@types/estree' @@ -7791,10 +7788,11 @@ snapshots: degenerator: 5.0.1 netmask: 2.0.2 - package-json-validator@0.29.1: + package-json-validator@0.59.0: dependencies: semver: 7.7.3 validate-npm-package-license: 3.0.4 + validate-npm-package-name: 7.0.0 yargs: 18.0.0 parent-module@1.0.1: @@ -8245,8 +8243,6 @@ snapshots: dependencies: is-plain-obj: 4.1.0 - sort-object-keys@1.1.3: {} - sort-object-keys@2.0.1: {} sort-package-json@3.5.0: @@ -8518,7 +8514,7 @@ snapshots: spdx-correct: 3.2.0 spdx-expression-parse: 3.0.1 - validate-npm-package-name@6.0.2: {} + validate-npm-package-name@7.0.0: {} vite@7.2.6(@types/node@24.10.1)(jiti@2.6.1)(tsx@4.19.2)(yaml@2.8.2): dependencies: diff --git a/src/blocks/blockESLintNode.test.ts b/src/blocks/blockESLintNode.test.ts index 04c7e0d8a..d6dfdb339 100644 --- a/src/blocks/blockESLintNode.test.ts +++ b/src/blocks/blockESLintNode.test.ts @@ -27,6 +27,14 @@ describe("blockESLintNode", () => { "files": [ "**/*.{js,ts}", ], + "rules": [ + { + "comment": "https://github.com/eslint-community/eslint-plugin-n/issues/472", + "entries": { + "n/no-unpublished-bin": "off", + }, + }, + ], }, { "extends": [ diff --git a/src/blocks/blockESLintNode.ts b/src/blocks/blockESLintNode.ts index c64e6ba78..0cef5b9ab 100644 --- a/src/blocks/blockESLintNode.ts +++ b/src/blocks/blockESLintNode.ts @@ -14,6 +14,15 @@ export const blockESLintNode = base.createBlock({ { extends: ['n.configs["flat/recommended"]'], files: [getScriptFileExtension(options)], + rules: [ + { + comment: + "https://github.com/eslint-community/eslint-plugin-n/issues/472", + entries: { + "n/no-unpublished-bin": "off", + }, + }, + ], }, { extends: ["tseslint.configs.disableTypeChecked"], diff --git a/src/blocks/blockPackageJson.test.ts b/src/blocks/blockPackageJson.test.ts index 553a2bfe8..4439ae524 100644 --- a/src/blocks/blockPackageJson.test.ts +++ b/src/blocks/blockPackageJson.test.ts @@ -247,7 +247,7 @@ describe("blockPackageJson", () => { expect(creation).toMatchInlineSnapshot(` { "files": { - "package.json": "{"name":"test-repository","version":"0.0.0","description":"A very very very very very very very very very very very very very very very very long HTML-ish description ending with an emoji. 🧵","repository":{"type":"git","url":"git+https://github.com/test-owner/test-repository.git"},"author":{"email":"npm@email.com"},"type":"module","bin":"bin/index.js","files":["bin/index.js"],"engines":{"node":">=20.12.0"}}", + "package.json": "{"name":"test-repository","version":"0.0.0","description":"A very very very very very very very very very very very very very very very very long HTML-ish description ending with an emoji. 🧵","repository":{"type":"git","url":"git+https://github.com/test-owner/test-repository.git"},"author":{"email":"npm@email.com"},"type":"module","bin":"bin/index.js","engines":{"node":">=20.12.0"}}", }, "scripts": [ { @@ -275,7 +275,7 @@ describe("blockPackageJson", () => { expect(creation).toMatchInlineSnapshot(` { "files": { - "package.json": "{"name":"test-repository","version":"0.0.0","description":"A very very very very very very very very very very very very very very very very long HTML-ish description ending with an emoji. 🧵","repository":{"type":"git","url":"git+https://github.com/test-owner/test-repository.git"},"author":{"email":"npm@email.com"},"type":"module","bin":{"absolute":"bin/absolute.js","relative":"./bin/relative.js"},"files":["bin/absolute.js","bin/relative.js"],"engines":{"node":">=20.12.0"}}", + "package.json": "{"name":"test-repository","version":"0.0.0","description":"A very very very very very very very very very very very very very very very very long HTML-ish description ending with an emoji. 🧵","repository":{"type":"git","url":"git+https://github.com/test-owner/test-repository.git"},"author":{"email":"npm@email.com"},"type":"module","bin":{"absolute":"bin/absolute.js","relative":"./bin/relative.js"},"engines":{"node":">=20.12.0"}}", }, "scripts": [ { diff --git a/src/blocks/blockPackageJson.ts b/src/blocks/blockPackageJson.ts index 8acaa84c1..2af5c7287 100644 --- a/src/blocks/blockPackageJson.ts +++ b/src/blocks/blockPackageJson.ts @@ -59,10 +59,7 @@ export const blockPackageJson = base.createBlock({ ...(options.pnpm && { packageManager: `pnpm@${options.pnpm}`, }), - files: processFiles([ - ...collectBinFiles(options.bin), - ...(addons.properties.files ?? []), - ]), + files: processFiles(addons.properties.files), keywords: options.keywords, name: options.repository, repository: { @@ -97,17 +94,12 @@ export const blockPackageJson = base.createBlock({ }, }); -function collectBinFiles(bin: Record | string | undefined) { - if (!bin) { - return []; +function processFiles(files: string[] | undefined) { + // If no files have been specified, we can skip the property altogether + if (!files?.length) { + return undefined; } - const files = typeof bin === "object" ? Object.values(bin) : [bin]; - - return files.map((file) => file.replace(/^\.\//, "")); -} - -function processFiles(files: string[]) { // First sort so that shorter entries are first (e.g. "lib/")... const sortedByLength = files .filter(Boolean)