-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add tests, switch to bun, outsource regex
- Loading branch information
1 parent
57999ab
commit 1ec9870
Showing
10 changed files
with
209 additions
and
1,321 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import type { BuildConfig } from "bun"; | ||
|
||
const defaultBuildConfig: BuildConfig = { | ||
entrypoints: ["./index.ts"], | ||
|
||
outdir: "./dist", | ||
target: "node", | ||
}; | ||
|
||
await Promise.all([ | ||
Bun.build({ | ||
...defaultBuildConfig, | ||
|
||
format: "esm", | ||
naming: "[dir]/[name].js", | ||
}), | ||
Bun.build({ | ||
...defaultBuildConfig, | ||
format: "cjs", | ||
naming: "[dir]/[name].cjs", | ||
}), | ||
]); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
// An example file that this might run on | ||
const script = `https://apis.google.com/js/api.js?q=${Date.now()}`; | ||
fetch(`https://apis.google.com/js/api.js?onload=${a}*`).catch((c = "")); | ||
("https://www.google.com/recaptcha/enterprise.js?render="); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import { expect, test } from "bun:test"; | ||
import { extractJsLinks } from "./index"; | ||
import fs from "fs"; | ||
|
||
// More or less from https://github.com/kevva/url-regex/blob/master/test.js | ||
|
||
test("match js URLs in text", () => { | ||
const fixture = ` | ||
<a href="http://example.com/file.js">example.com</a> | ||
<a href="http://example.com/with-path/file.js">with path</a> | ||
[and another](https://another.example.com/file.min.js) and | ||
https://another.example.com/file.min.js?withqueryparams=true | ||
`; | ||
|
||
expect(extractJsLinks(fixture)).toEqual([ | ||
"http://example.com/file.js", | ||
"http://example.com/with-path/file.js", | ||
"https://another.example.com/file.min.js", | ||
"https://another.example.com/file.min.js?withqueryparams=true", | ||
]); | ||
}); | ||
|
||
test("dont't match these urls", () => { | ||
const fixture = ` | ||
"https://www.googletagmanager.com/gtag/js" | ||
`; | ||
|
||
expect(extractJsLinks(fixture)).toEqual([]); | ||
}); | ||
|
||
test("match js URLs in js", () => { | ||
const fixture = fs.readFileSync("./folder/fixture.js", "utf-8"); | ||
|
||
expect(extractJsLinks(fixture)).toEqual([ | ||
"https://apis.google.com/js/api.js?q=$", | ||
"https://apis.google.com/js/api.js?onload=$", | ||
"https://www.google.com/recaptcha/enterprise.js?render=", | ||
]); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
#!/usr/bin/env node | ||
|
||
import fs from "fs"; | ||
import path from "path"; | ||
import arg from "arg"; | ||
import invariant from "tiny-invariant"; | ||
|
||
const urlRegex = | ||
/((?<!\+)https?:\/\/(?:www\.)?(?:[-\p{Letter}.]+?[.@][a-zA-Z\d]{2,}|localhost)(?:[-\w\p{Letter}.:%+~#*$!?&/=@]*?(?:,(?!\s))*?)*)/gu; | ||
|
||
const helpText = ` | ||
Description: | ||
a cli to find and remove links that might annoy the chrome web store team | ||
often these are firebase links for some reason | ||
Usage: | ||
badlinks <file_or_folder> [options] | ||
Options: | ||
-r, --remove Remove the found JS links | ||
-h, --help Display this help message | ||
`; | ||
|
||
function showHelp() { | ||
console.log(helpText); | ||
process.exit(0); | ||
} | ||
|
||
export function extractJsLinks(text: string) { | ||
return text.match(urlRegex)?.filter((link) => link.includes(".js")) || []; | ||
} | ||
|
||
function processFile(filePath: string, shouldRemove: boolean) { | ||
let fileContent = fs.readFileSync(filePath, "utf-8"); | ||
const jsLinks = extractJsLinks(fileContent); | ||
|
||
if (jsLinks.length > 0) { | ||
console.log(`JS link(s) found in ${filePath}:`); | ||
console.log(jsLinks); | ||
|
||
if (shouldRemove) { | ||
for (const link of jsLinks) { | ||
fileContent = fileContent.replace(link, ""); | ||
} | ||
fs.writeFileSync(filePath, fileContent); | ||
console.log(`JS link(s) removed from ${filePath}`); | ||
} else { | ||
console.error("Links found (use --remove to remove them)."); | ||
} | ||
} | ||
} | ||
|
||
function processPath(inputPath: string, shouldRemove: boolean) { | ||
const fileStats = fs.statSync(inputPath); | ||
|
||
if (fileStats.isDirectory()) { | ||
const fileNames = fs.readdirSync(inputPath); | ||
for (const fileName of fileNames) { | ||
processPath(path.join(inputPath, fileName), shouldRemove); | ||
} | ||
} else if (fileStats.isFile() && path.extname(inputPath) === ".js") { | ||
processFile(inputPath, shouldRemove); | ||
} | ||
} | ||
|
||
function parseArgs() { | ||
const argSpec = { | ||
"--help": Boolean, | ||
"--remove": Boolean, | ||
"-h": "--help", | ||
"-r": "--remove", | ||
}; | ||
|
||
try { | ||
const args = arg(argSpec); | ||
|
||
if (args["--help"]) { | ||
showHelp(); | ||
} | ||
|
||
const inputPath = args._.length > 0 ? args._[0] : null; | ||
|
||
if (!inputPath) { | ||
console.error("** Error: A file or folder path is required \n --- "); | ||
showHelp(); | ||
} | ||
|
||
return { | ||
inputPath, | ||
remove: args["--remove"] || false, | ||
}; | ||
} catch (error) { | ||
// @ts-ignore | ||
console.error(`Error: ${error?.message}`); | ||
showHelp(); | ||
} | ||
} | ||
|
||
try { | ||
const options = parseArgs(); | ||
invariant(options?.inputPath, "No input path"); | ||
processPath(options.inputPath, options.remove); | ||
} catch (error) { | ||
// @ts-ignore | ||
console.error("Error:", error.message); | ||
process.exit(1); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.