diff --git a/package-lock.json b/package-lock.json index 275adb59..e1b8a720 100644 --- a/package-lock.json +++ b/package-lock.json @@ -35,6 +35,7 @@ "semver-utils": "^1.1.4", "source-map-support": "^0.5.21", "spawn-please": "^2.0.1", + "strip-json-comments": "^5.0.0", "untildify": "^4.0.0", "update-notifier": "^6.0.2", "yaml": "^2.2.1" @@ -810,6 +811,18 @@ "node": "*" } }, + "node_modules/@eslint/eslintrc/node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/@eslint/eslintrc/node_modules/type-fest": { "version": "0.20.2", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", @@ -3893,6 +3906,18 @@ "node": ">=8" } }, + "node_modules/eslint/node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/eslint/node_modules/type-fest": { "version": "0.20.2", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", @@ -6165,6 +6190,18 @@ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true }, + "node_modules/mocha/node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/mocha/node_modules/supports-color": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", @@ -7586,6 +7623,18 @@ "run-con": "cli.js" } }, + "node_modules/run-con/node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -8076,12 +8125,11 @@ } }, "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-5.0.0.tgz", + "integrity": "sha512-V1LGY4UUo0jgwC+ELQ2BNWfPa17TIuwBLg+j1AA/9RPzKINl1lhxVEu2r+ZTTO8aetIsUzE5Qj6LMSBkoGYKKw==", "engines": { - "node": ">=8" + "node": ">=14.16" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -9418,6 +9466,12 @@ "brace-expansion": "^1.1.7" } }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true + }, "type-fest": { "version": "0.20.2", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", @@ -11404,6 +11458,12 @@ "ansi-regex": "^5.0.1" } }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true + }, "type-fest": { "version": "0.20.2", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", @@ -13425,6 +13485,12 @@ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true + }, "supports-color": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", @@ -14452,6 +14518,14 @@ "ini": "~3.0.0", "minimist": "^1.2.6", "strip-json-comments": "~3.1.1" + }, + "dependencies": { + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true + } } }, "run-parallel": { @@ -14828,10 +14902,9 @@ "dev": true }, "strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-5.0.0.tgz", + "integrity": "sha512-V1LGY4UUo0jgwC+ELQ2BNWfPa17TIuwBLg+j1AA/9RPzKINl1lhxVEu2r+ZTTO8aetIsUzE5Qj6LMSBkoGYKKw==" }, "supports-color": { "version": "7.2.0", diff --git a/package.json b/package.json index c45fd7c8..12c0ced1 100644 --- a/package.json +++ b/package.json @@ -80,6 +80,7 @@ "semver-utils": "^1.1.4", "source-map-support": "^0.5.21", "spawn-please": "^2.0.1", + "strip-json-comments": "^5.0.0", "untildify": "^4.0.0", "update-notifier": "^6.0.2", "yaml": "^2.2.1" diff --git a/src/lib/findLockfile.ts b/src/lib/findLockfile.ts index 429533c2..9024d675 100644 --- a/src/lib/findLockfile.ts +++ b/src/lib/findLockfile.ts @@ -31,6 +31,8 @@ export default async function findLockfile( return { directoryPath: currentPath, filename: 'pnpm-lock.yaml' } } else if (files.includes('deno.json')) { return { directoryPath: currentPath, filename: 'deno.json' } + } else if (files.includes('deno.jsonc')) { + return { directoryPath: currentPath, filename: 'deno.jsonc' } } const pathParent = path.resolve(currentPath, '..') diff --git a/src/lib/findPackage.ts b/src/lib/findPackage.ts index f2b17c62..3bbf9467 100644 --- a/src/lib/findPackage.ts +++ b/src/lib/findPackage.ts @@ -70,7 +70,11 @@ async function findPackage(options: Options) { pkgData = data || getPackageDataFromFile(await pkgFile, pkgPath) } else { // find the closest package starting from the current working directory and going up to the root - pkgFile = pkgPath ? findUp.sync(pkgPath, { cwd: options.cwd || process.cwd() }) : null + pkgFile = pkgPath + ? findUp.sync(!options.packageFile && options.packageManager === 'deno' ? ['deno.json', 'deno.jsonc'] : pkgPath, { + cwd: options.cwd || process.cwd(), + }) + : null pkgData = getPackageDataFromFile(pkgFile, pkgPath) } diff --git a/src/lib/initOptions.ts b/src/lib/initOptions.ts index 8ae38326..28786a13 100644 --- a/src/lib/initOptions.ts +++ b/src/lib/initOptions.ts @@ -158,11 +158,7 @@ async function initOptions(runOptions: RunOptions, { cli }: { cli?: boolean } = const resolvedOptions: Options = { ...options, - ...(options.deep - ? { packageFile: '**/package.json' } - : packageManager === 'deno' && !options.packageFile - ? { packageFile: 'deno.json' } - : null), + ...(options.deep ? { packageFile: '**/package.json' } : null), ...(packageManager === 'deno' && options.dep !== cliOptionsMap.dep.default ? { dep: ['imports'] } : null), ...(options.format && options.format.length > 0 ? { format: options.format } : null), filter: args || filter, diff --git a/src/lib/runLocal.ts b/src/lib/runLocal.ts index fa1f0541..9dea7604 100644 --- a/src/lib/runLocal.ts +++ b/src/lib/runLocal.ts @@ -164,13 +164,16 @@ async function runLocal( print(options, '\nOptions:', 'verbose') print(options, sortOptions(options), 'verbose') - let pkg + let pkg: PackageFile try { if (!pkgData) { - throw new Error('Missing pkgData: ' + pkgData) + throw new Error('Missing pkgData') } else { - pkg = jph.parse(pkgData) + // strip comments from jsonc files + const pkgDataStripped = + pkgFile?.endsWith('.jsonc') && pkgData ? (await import('strip-json-comments')).default(pkgData) : pkgData + pkg = jph.parse(pkgDataStripped) } } catch (e: any) { programError( diff --git a/test/package-managers/deno/index.test.ts b/test/package-managers/deno/index.test.ts index 429ae68f..a98945b6 100644 --- a/test/package-managers/deno/index.test.ts +++ b/test/package-managers/deno/index.test.ts @@ -24,11 +24,11 @@ describe('deno', async function () { 'ncu-test-v2': 'npm:ncu-test-v2@1.0.0', }, } - await fs.writeFile(pkgFile, JSON.stringify(pkg), 'utf-8') + await fs.writeFile(pkgFile, JSON.stringify(pkg)) try { const pkgData = await spawn( 'node', - [bin, '--jsonUpgraded', '--verbose', '--packageManager', 'deno', '--packageFile', pkgFile], + [bin, '--jsonUpgraded', '--packageManager', 'deno', '--packageFile', pkgFile], undefined, ) const pkg = jph.parse(pkgData) @@ -46,9 +46,9 @@ describe('deno', async function () { 'ncu-test-v2': 'npm:ncu-test-v2@1.0.0', }, } - await fs.writeFile(pkgFile, JSON.stringify(pkg), 'utf-8') + await fs.writeFile(pkgFile, JSON.stringify(pkg)) try { - const pkgData = await spawn('node', [bin, '--jsonUpgraded', '--verbose'], undefined, { + const pkgData = await spawn('node', [bin, '--jsonUpgraded'], undefined, { cwd: tempDir, }) const pkg = jph.parse(pkgData) @@ -57,4 +57,71 @@ describe('deno', async function () { await fs.rm(tempDir, { recursive: true, force: true }) } }) + + it('rewrite deno.json', async () => { + const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), 'npm-check-updates-')) + const pkgFile = path.join(tempDir, 'deno.json') + const pkg = { + imports: { + 'ncu-test-v2': 'npm:ncu-test-v2@1.0.0', + }, + } + await fs.writeFile(pkgFile, JSON.stringify(pkg)) + try { + await spawn('node', [bin, '-u'], undefined, { cwd: tempDir }) + const pkgDataNew = await fs.readFile(pkgFile, 'utf-8') + const pkg = jph.parse(pkgDataNew) + pkg.should.deep.equal({ + imports: { + 'ncu-test-v2': 'npm:ncu-test-v2@2.0.0', + }, + }) + } finally { + await fs.rm(tempDir, { recursive: true, force: true }) + } + }) + + it('auto detect deno.jsonc', async () => { + const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), 'npm-check-updates-')) + const pkgFile = path.join(tempDir, 'deno.jsonc') + const pkgString = `{ + "imports": { + // this comment should be ignored in a jsonc file + "ncu-test-v2": "npm:ncu-test-v2@1.0.0" + } +}` + await fs.writeFile(pkgFile, pkgString) + try { + const pkgData = await spawn('node', [bin, '--jsonUpgraded'], undefined, { + cwd: tempDir, + }) + const pkg = jph.parse(pkgData) + pkg.should.have.property('ncu-test-v2') + } finally { + await fs.rm(tempDir, { recursive: true, force: true }) + } + }) + + it('rewrite deno.jsonc', async () => { + const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), 'npm-check-updates-')) + const pkgFile = path.join(tempDir, 'deno.jsonc') + const pkg = { + imports: { + 'ncu-test-v2': 'npm:ncu-test-v2@1.0.0', + }, + } + await fs.writeFile(pkgFile, JSON.stringify(pkg)) + try { + await spawn('node', [bin, '-u'], undefined, { cwd: tempDir }) + const pkgDataNew = await fs.readFile(pkgFile, 'utf-8') + const pkg = jph.parse(pkgDataNew) + pkg.should.deep.equal({ + imports: { + 'ncu-test-v2': 'npm:ncu-test-v2@2.0.0', + }, + }) + } finally { + await fs.rm(tempDir, { recursive: true, force: true }) + } + }) })