1
\$\begingroup\$

The goal of this module is to take in a string (user input, someone copy and pasting a large list of proxies) and parse it into an array of objects.

I appreciate any and all feedback, but I'm specifically interested in improving the stringToProxy function.

Namely I'm unsure about mutating the string parameter, seems like there could be a better solution. And the way I'm declaring the proxy at the beginning of the function feels wrong to me (using As) but I couldn't think of any better solution. I also feel as though I may be overusing string.split().

Thanks for your time!

Edit: Incorporated the url module as Nazar recommended. I'm happy with this solution but still taking feedback.

const { URL } = require("url"); interface Proxy { host: string; port: number; protocol: string; auth?: { username: string; password: string; }; } function parse(string: string): Proxy[] { const rawArray = stringToArray(string); const fixedArray = rawArray.map((string) => fixProxyString(string)); const proxyArray = fixedArray.map((string) => stringToProxy(string)); return proxyArray; } function stringToArray(string: string): string[] { return string.trim().replace(/[ ,\n]+/g, ",").split(","); } function fixProxyString(string: string): string { return string.includes("://") ? string : `http://${string}`; //if user doesnt specify a protocol, default to http } function stringToProxy(string: string): Proxy { const url = new URL(string); return { host: url.hostname, port: url.port ? parseInt(url.port) : 80, //if proxy is 80 url will ignore it so i need to explicitly add it protocol: url.protocol.slice(0, -1), //removing the colon auth: url.username ? { username: url.username, password: url.password } : undefined }; } export = parse; 

Before edit:

interface Proxy { host: string; port: number; auth?: { username: string; password: string; }; protocol?: string; } function parse(string: string): Proxy[] { const rawArray = stringToArray(string); const proxyArray = rawArray.map((string) => stringToProxy(string)); return proxyArray; } function stringToArray(string: string): string[] { return string.trim().replace(/[ ,\n]+/g, ",").split(","); } function stringToProxy(string: string) { const proxy = {} as Proxy; if (string.includes("://")) { const [protocol, remainder] = string.split("://"); proxy.protocol = protocol; string = remainder; } if (string.includes("@")) { const [auth, remainder] = string.split("@"); const [username, password] = auth.split(":"); proxy.auth = { username, password }; string = remainder; } const [host, port] = string.split(":"); proxy.port = parseInt(port); proxy.host = host; return proxy; } export = parse; 

Usage:

const parse = require("parse-proxy"); parse(`1.1.1.1:80, 2.2.2.2:80, 3.3.3.3:80`) //result [ { host: '1.1.1.1', port: 80 }, { host: '2.2.2.2', port: 80 }, { host: '3.3.3.3', port: 80 } ] parse(`https://user:[email protected]:8080\nhttps://user:[email protected]:3128`) //result [ { protocol: 'https', auth: { username: 'user', password: 'pass' }, host: '104.236.55.48', port: 8080 }, { protocol: 'https', auth: { username: 'user', password: 'pass' }, host: '213.105.29.14', port: 3128 } ] 
\$\endgroup\$
2
  • \$\begingroup\$I would suggest using a built-in WHATWG API. You can get almost the same output by calling require('url').parse function.\$\endgroup\$
    – Nazar
    CommentedJan 17, 2021 at 21:55
  • \$\begingroup\$Ah yes, that does the trick, thanks for the help!\$\endgroup\$
    – DevHigley
    CommentedJan 17, 2021 at 23:49

1 Answer 1

1
\$\begingroup\$

A couple of small comments:

Don't call your parameter the same thing as its type string: string. This makes the code needlessly difficult to read - don't make the reader waste time wondering whether this string a type or the variable. Use input, source or something else that makes sense.

Don't shadow outer variables/arguments in arrow functions, again this harms readability rawArray.map((string) => fixProxyString(string));. Note that the parenthesis are optional for one parameter too. Consider instead:

function parse(input: string): Proxy[] { const rawArray = stringToArray(input); const fixedArray = rawArray.map(raw => fixProxyString(raw)); const proxyArray = fixedArray.map(fixed => stringToProxy(fixed)); return proxyArray; } 

I think (although not tested) that you can further simplify:

function parse(input: string): Proxy[] { return stringToArray(input) .map(fixProxyString) .map(stringToProxy); } 

You don't need to replace and then split here return string.trim().replace(/[ ,\n]+/g, ",").split(",");. You can just split by the regex directly.

\$\endgroup\$

    Start asking to get answers

    Find the answer to your question by asking.

    Ask question

    Explore related questions

    See similar questions with these tags.