From bcf3bdd3ea9a0e4a13f28a9310fecf67fdaa3297 Mon Sep 17 00:00:00 2001 From: Kudakwashe Mupeni Date: Tue, 13 Aug 2024 12:01:43 +0200 Subject: [PATCH] feat: update code as per linter --- rollup.config.js | 8 ++++-- src/__tests__/index.test.ts | 52 ++++++++++++++++++++----------------- src/decode-uri-component.ts | 32 +++++++++++++---------- src/index.ts | 10 +++---- src/source-map-resolve.ts | 6 ++--- tsconfig.json | 4 +-- 6 files changed, 63 insertions(+), 49 deletions(-) diff --git a/rollup.config.js b/rollup.config.js index 4213853..11cb9fd 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -1,7 +1,7 @@ -import swc from '@rollup/plugin-swc'; -import { globSync } from 'glob'; import path from 'node:path'; import { fileURLToPath } from 'node:url'; +import swc from '@rollup/plugin-swc'; +import { globSync } from 'glob'; export default /** @type {import('rollup').RollupOptions} */ ({ input: Object.fromEntries( @@ -16,6 +16,7 @@ export default /** @type {import('rollup').RollupOptions} */ ({ fileURLToPath(new URL(file, import.meta.url)), ]), ), + external: () => true, plugins: [swc()], output: [ @@ -32,6 +33,9 @@ export default /** @type {import('rollup').RollupOptions} */ ({ sourcemap: true, entryFileNames: '[name].cjs', preserveModules: true, + generatedCode: { + constBindings: true, + }, }, ], }); diff --git a/src/__tests__/index.test.ts b/src/__tests__/index.test.ts index 8fc7acc..288ad5e 100644 --- a/src/__tests__/index.test.ts +++ b/src/__tests__/index.test.ts @@ -1,13 +1,12 @@ -/* eslint-disable @typescript-eslint/require-await, @typescript-eslint/no-non-null-assertion */ -import { describe, expect, it, test } from 'vitest'; -import fs from 'fs'; -import path from 'path'; +import fs from 'node:fs'; +import path from 'node:path'; +import util from 'node:util'; import { rollup } from 'rollup'; import ts from 'typescript'; -import util from 'util'; +/* eslint-disable @typescript-eslint/require-await, @typescript-eslint/no-non-null-assertion */ +import { describe, expect, it, test } from 'vitest'; -import sourcemaps from '..'; -import { SourcemapsPluginOptions } from '..'; +import sourcemaps, { type SourcemapsPluginOptions } from '..'; const inputPath = path.join(__dirname, '../index.ts'); const inputText = fs.readFileSync(inputPath, 'utf8'); @@ -31,13 +30,13 @@ function comparePath(a: string, b: string): boolean { const second = b.split(/[\\/]/); // If the platform is Windows, convert the first segment (drive letter) to lowercase - if (process.platform == 'win32') { + if (process.platform === 'win32') { first[0] = first[0].toLowerCase(); second[0] = second[0].toLowerCase(); } // Return true if both paths have the same number of segments and all corresponding segments are equal - return first.length === second.length && first.every((v, i) => v == second[i]); + return first.length === second.length && first.every((v, i) => v === second[i]); } async function rollupBundle({ @@ -50,11 +49,16 @@ async function rollupBundle({ const load = async (path: string) => { if (comparePath(path, inputPath)) { return inputText; - } else if (comparePath(path, outputPath)) { + } + + if (comparePath(path, outputPath)) { return outputText; - } else if (comparePath(path, sourceMapPath)) { - return sourceMapText!; } + + if (sourceMapText && comparePath(path, sourceMapPath)) { + return sourceMapText; + } + throw new Error(`Unexpected path: ${path}`); }; @@ -97,8 +101,8 @@ it('ignores files with no source maps', async () => { const { map } = await rollupBundle({ outputText, sourceMapText }); expect(map).toBeDefined(); - expect(map!.sources).toStrictEqual([outputPath]); - expect(map!.sourcesContent).toStrictEqual([outputText]); + expect(map?.sources).toStrictEqual([outputPath]); + expect(map?.sourcesContent).toStrictEqual([outputText]); }); describe('detects files with source maps', () => { @@ -130,8 +134,8 @@ describe('detects files with source maps', () => { const { map } = await rollupBundle({ outputText, sourceMapText }); expect(map).toBeDefined(); - expect(map!.sources.map(source => path.normalize(source))).toStrictEqual([inputPath]); - expect(map!.sourcesContent).toStrictEqual([inputText]); + expect(map?.sources.map(source => path.normalize(source))).toStrictEqual([inputPath]); + expect(map?.sourcesContent).toStrictEqual([inputText]); }, ); }); @@ -157,8 +161,8 @@ describe('ignores filtered files', () => { }); expect(map).toBeDefined(); - expect(map!.sources.map(source => path.normalize(source))).toStrictEqual([outputPath]); - expect(map!.sourcesContent).toStrictEqual([outputText]); + expect(map?.sources.map(source => path.normalize(source))).toStrictEqual([outputPath]); + expect(map?.sourcesContent).toStrictEqual([outputText]); }); test('excluded', async () => { @@ -181,8 +185,8 @@ describe('ignores filtered files', () => { }); expect(map).toBeDefined(); - expect(map!.sources.map(source => path.normalize(source))).toStrictEqual([outputPath]); - expect(map!.sourcesContent).toStrictEqual([outputText]); + expect(map?.sources.map(source => path.normalize(source))).toStrictEqual([outputPath]); + expect(map?.sourcesContent).toStrictEqual([outputText]); }); }); @@ -208,8 +212,8 @@ it('delegates failing file reads to the next plugin', async () => { }); expect(map).toBeDefined(); - expect(map!.sources.map(source => path.normalize(source))).toStrictEqual([outputPath]); - expect(map!.sourcesContent).toStrictEqual([outputText]); + expect(map?.sources.map(source => path.normalize(source))).toStrictEqual([outputPath]); + expect(map?.sourcesContent).toStrictEqual([outputText]); }); it('handles failing source maps reads', async () => { @@ -241,6 +245,6 @@ it('handles failing source maps reads', async () => { }); expect(map).toBeDefined(); - expect(map!.sources.map(source => path.normalize(source))).toStrictEqual([outputPath]); - expect(map!.sourcesContent).toStrictEqual([outputText]); + expect(map?.sources.map(source => path.normalize(source))).toStrictEqual([outputPath]); + expect(map?.sourcesContent).toStrictEqual([outputText]); }); diff --git a/src/decode-uri-component.ts b/src/decode-uri-component.ts index 47789b1..f3c7cd7 100644 --- a/src/decode-uri-component.ts +++ b/src/decode-uri-component.ts @@ -3,6 +3,8 @@ const singleMatcher = new RegExp(`(${token})|([^%]+?)`, 'gi'); const multiMatcher = new RegExp(`(${token})+`, 'gi'); function decodeComponents(components: RegExpMatchArray | [], split?: number): string[] { + let splitAt = split; + try { // Try to decode the entire string first return [decodeURIComponent(components.join(''))]; @@ -14,11 +16,11 @@ function decodeComponents(components: RegExpMatchArray | [], split?: number): st return components; } - split = split ?? 1; + splitAt = splitAt ?? 1; // Split the array in 2 parts - const left = components.slice(0, split) as RegExpMatchArray; - const right = components.slice(split) as RegExpMatchArray; + const left = components.slice(0, splitAt) as RegExpMatchArray; + const right = components.slice(splitAt) as RegExpMatchArray; return Array.prototype.concat.call( [], @@ -28,29 +30,33 @@ function decodeComponents(components: RegExpMatchArray | [], split?: number): st } function decode(input: string): string { + let localInput = input; + try { - return decodeURIComponent(input); + return decodeURIComponent(localInput); } catch { - let tokens = RegExp(singleMatcher).exec(input) || []; + let tokens = RegExp(singleMatcher).exec(localInput) || []; for (let i = 1; i < tokens.length; i++) { - input = decodeComponents(tokens, i).join(''); + localInput = decodeComponents(tokens, i).join(''); - tokens = RegExp(singleMatcher).exec(input) || []; + tokens = RegExp(singleMatcher).exec(localInput) || []; } - return input; + return localInput; } } function customDecodeURIComponent(input: string): string { + let localInput = input; + // Keep track of all the replacements and prefill the map with the `BOM` const replaceMap: Record = { '%FE%FF': '\uFFFD\uFFFD', '%FF%FE': '\uFFFD\uFFFD', }; - let match = multiMatcher.exec(input); + let match = multiMatcher.exec(localInput); while (match) { try { // Decode as big chunks as possible @@ -63,7 +69,7 @@ function customDecodeURIComponent(input: string): string { } } - match = multiMatcher.exec(input); + match = multiMatcher.exec(localInput); } // Add `%C2` at the end of the map to make sure it does not replace the combinator before everything else @@ -73,16 +79,16 @@ function customDecodeURIComponent(input: string): string { for (const key of entries) { // Replace all decoded components - input = input.replace(new RegExp(key, 'g'), replaceMap[key]); + localInput = localInput.replace(new RegExp(key, 'g'), replaceMap[key]); } - return input; + return localInput; } export default function decodeUriComponent(encodedURI: string): string { if (typeof encodedURI !== 'string') { throw new TypeError( - 'Expected `encodedURI` to be of type `string`, got `' + typeof encodedURI + '`', + `Expected \`encodedURI\` to be of type \`string\`, got \`${typeof encodedURI}\``, ); } diff --git a/src/index.ts b/src/index.ts index 49eae5f..e27d02a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,7 +1,7 @@ -import pluginUtils, { CreateFilter } from '@rollup/pluginutils'; -import fs from 'fs'; -import { ExistingRawSourceMap, Plugin, PluginContext } from 'rollup'; -import { promisify } from 'util'; +import fs from 'node:fs'; +import { promisify } from 'node:util'; +import pluginUtils, { type CreateFilter } from '@rollup/pluginutils'; +import type { ExistingRawSourceMap, Plugin, PluginContext } from 'rollup'; import { resolveSourceMap, resolveSources } from './source-map-resolve.js'; const { createFilter } = pluginUtils; @@ -46,7 +46,7 @@ export default function sourcemaps( this.addWatchFile(cleanId); } catch { // If reading still fails, warn and return null - this.warn(`Failed reading file`); + this.warn('Failed reading file'); return null; } } diff --git a/src/source-map-resolve.ts b/src/source-map-resolve.ts index 516460e..f988d98 100644 --- a/src/source-map-resolve.ts +++ b/src/source-map-resolve.ts @@ -1,5 +1,5 @@ -import { ExistingRawSourceMap } from 'rollup'; -import * as urlLib from 'url'; +import * as urlLib from 'node:url'; +import type { ExistingRawSourceMap } from 'rollup'; import decodeUriComponent from './decode-uri-component.js'; interface ResolvedSources { @@ -47,7 +47,7 @@ export async function resolveSourceMap( if (dataUri) { const mimeType = dataUri[1] || 'text/plain'; if (!/^(?:application|text)\/json$/.test(mimeType)) { - throw new Error('Unuseful data uri mime type: ' + mimeType); + throw new Error(`Unuseful data uri mime type: ${mimeType}`); } const map = parseMapToJSON( (dataUri[2] === ';base64' ? atob : decodeURIComponent)(dataUri[3] || ''), diff --git a/tsconfig.json b/tsconfig.json index d1e5e11..fd16b80 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -5,7 +5,7 @@ "declaration": true, "lib": ["es2015", "es2016", "es2017", "esnext"], "emitDeclarationOnly": true, - "rootDir": "./", + "rootDir": "src", "outDir": "dist", "sourceMap": true, "inlineSources": true, @@ -18,6 +18,6 @@ "allowSyntheticDefaultImports": true, "types": ["node"] }, - "include": ["src", "vitest.config.ts"], + "include": ["src"], "exclude": ["node_modules"] }