nebius/SWE-rebench-V2-PRs huggingface dataset:
Repository: patrickhoefler/dockerfilegraph
Pull request #263 (2023-01-27 16:13:32)

Add SVG export


Patch:
diff --git a/README.md b/README.md
index 7eb587f..cd9773f 100644
--- a/README.md
+++ b/README.md
@@ -108,7 +108,7 @@ Flags:
   -h, --help              help for dockerfilegraph
       --layers            display all layers (default false)
       --legend            add a legend (default false)
-  -o, --output            output file format, one of: canon, dot, pdf, png (default pdf)
+  -o, --output            output file format, one of: canon, dot, pdf, png, svg (default pdf)
       --version           display the version of dockerfilegraph
 ```
 
diff --git a/internal/cmd/root.go b/internal/cmd/root.go
index 1173964..151f3ca 100644
--- a/internal/cmd/root.go
+++ b/internal/cmd/root.go
@@ -131,7 +131,7 @@ It outputs a graph representation of the build process.`,
 		"add a legend (default false)",
 	)
 
-	outputFlag = newEnum("pdf", "canon", "dot", "png")
+	outputFlag = newEnum("pdf", "canon", "dot", "png", "svg")
 	rootCmd.Flags().VarP(
 		&outputFlag,
 		"output",


Test patch:
diff --git a/internal/cmd/root_test.go b/internal/cmd/root_test.go
index a247796..e1afe95 100644
--- a/internal/cmd/root_test.go
+++ b/internal/cmd/root_test.go
@@ -31,7 +31,7 @@ Flags:
   -h, --help              help for dockerfilegraph
       --layers            display all layers (default false)
       --legend            add a legend (default false)
-  -o, --output            output file format, one of: canon, dot, pdf, png (default pdf)
+  -o, --output            output file format, one of: canon, dot, pdf, png, svg (default pdf)
       --version           display the version of dockerfilegraph
 `
 
@@ -177,6 +177,12 @@ It outputs a graph representation of the build process.
 			wantOut:     "Successfully created Dockerfile.png\n",
 			wantOutFile: "Dockerfile.png",
 		},
+		{
+			name:        "output flag svg",
+			cliArgs:     []string{"--output", "svg"},
+			wantOut:     "Successfully created Dockerfile.svg\n",
+			wantOutFile: "Dockerfile.svg",
+		},
 		{
 			name:        "filename flag",
 			cliArgs:     []string{"--filename", "subdir/../Dockerfile"},
Repository: patrickhoefler/dockerfilegraph
Pull request #281 (2023-02-05 12:49:07)

Improve the help text


Patch:
diff --git a/README.md b/README.md
index ec99104..db2ab9f 100644
--- a/README.md
+++ b/README.md
@@ -105,7 +105,7 @@ make build
 ```text
 ❯ dockerfilegraph --help
 dockerfilegraph visualizes your multi-stage Dockerfile.
-It outputs a graph representation of the build process.
+It creates a visual graph representation of the build process.
 
 Usage:
   dockerfilegraph [flags]
diff --git a/internal/cmd/root.go b/internal/cmd/root.go
index 8057aaa..17f60c7 100644
--- a/internal/cmd/root.go
+++ b/internal/cmd/root.go
@@ -44,7 +44,7 @@ func NewRootCmd(dfgWriter io.Writer, inputFS afero.Fs) *cobra.Command {
 		Use:   "dockerfilegraph",
 		Short: "Visualize your multi-stage Dockerfile",
 		Long: `dockerfilegraph visualizes your multi-stage Dockerfile.
-It outputs a graph representation of the build process.`,
+It creates a visual graph representation of the build process.`,
 		Args: cobra.NoArgs,
 		PreRunE: func(cmd *cobra.Command, args []string) (err error) {
 			return checkFlags()


Test patch:
diff --git a/internal/cmd/root_test.go b/internal/cmd/root_test.go
index b9903a3..b777447 100644
--- a/internal/cmd/root_test.go
+++ b/internal/cmd/root_test.go
@@ -79,7 +79,7 @@ func TestRootCmd(t *testing.T) {
 			name:    "help flag",
 			cliArgs: []string{"--help"},
 			wantOut: `dockerfilegraph visualizes your multi-stage Dockerfile.
-It outputs a graph representation of the build process.
+It creates a visual graph representation of the build process.
 
 ` + usage,
 		},
Repository: patrickhoefler/dockerfilegraph
Pull request #283 (2023-02-05 18:04:24)

Don't truncate stage labels in `--layers` mode


Patch:
diff --git a/examples/images/Dockerfile-layers.svg b/examples/images/Dockerfile-layers.svg
index 1068990..88b23c3 100644
--- a/examples/images/Dockerfile-layers.svg
+++ b/examples/images/Dockerfile-layers.svg
@@ -17,7 +17,7 @@
 <g id="clust2" class="cluster">
 <title>cluster_stage_1</title>
 <polygon fill="none" stroke="black" points="344,-332 344,-423 700,-423 700,-332 344,-332"/>
-<text text-anchor="middle" x="522" y="-407.8" font-family="Times,serif" font-size="14.00">build&#45;tool&#45;depend...</text>
+<text text-anchor="middle" x="522" y="-407.8" font-family="Times,serif" font-size="14.00">build&#45;tool&#45;dependencies</text>
 </g>
 <g id="clust3" class="cluster">
 <title>cluster_stage_2</title>
diff --git a/internal/dockerfile2dot/build.go b/internal/dockerfile2dot/build.go
index c5edd2e..0f20f6e 100644
--- a/internal/dockerfile2dot/build.go
+++ b/internal/dockerfile2dot/build.go
@@ -74,7 +74,7 @@ func BuildDotFile(
 			cluster := fmt.Sprintf("cluster_stage_%d", stageIndex)
 
 			clusterAttrs := map[string]string{
-				"label":  getStageLabel(stageIndex, stage, maxLabelLength),
+				"label":  getStageLabel(stageIndex, stage, 0),
 				"margin": "16",
 			}
 
@@ -237,7 +237,7 @@ func addLegend(graph *gographviz.Escape, edgestyle string) {
 }
 
 func getStageLabel(stageIndex int, stage Stage, maxLabelLength int) string {
-	if len(stage.Name) > maxLabelLength {
+	if maxLabelLength > 0 && len(stage.Name) > maxLabelLength {
 		return truncate.Truncate(
 			stage.Name, maxLabelLength, "...", truncate.PositionEnd,
 		)


Test patch:
diff --git a/internal/cmd/root_test.go b/internal/cmd/root_test.go
index 0d338cc..cce189a 100644
--- a/internal/cmd/root_test.go
+++ b/internal/cmd/root_test.go
@@ -174,7 +174,7 @@ It creates a visual graph representation of the build process.
 }
 ;
 	subgraph cluster_stage_1 {
-	label="build-tool-depend...";
+	label="build-tool-dependencies";
 	margin=16;
 	stage_1_layer_0 [ fillcolor=white, label="FROM golang:1.19 ...", penwidth=0.5, shape=box, style="filled,rounded", width=2 ];
 	stage_1_layer_1 [ fillcolor=white, label="RUN --mount=type=...", penwidth=0.5, shape=box, style="filled,rounded", width=2 ];
@@ -232,7 +232,7 @@ It creates a visual graph representation of the build process.
 		stage_0_layer_0 -> stage_0_layer_1;
 	}
 	subgraph cluster_stage_1 {
-		graph [label="build-tool-depend...",
+		graph [label="build-tool-dependencies",
 			margin=16
 		];
 		stage_1_layer_0	[fillcolor=white,
Repository: sjbarag/brs
Pull request #382 (2020-03-08 21:16:32)

fix(manifest): Fix parsing of numbers in manifest
We were previously not handling number parsing properly, with two nasty side-effects:

1. Floating-point values were truncated to integer values only (e.g. `"3.14" => 3`)
2. Strings that began with numbers were parsed as numbers and also truncated (e.g. `"1.2.3.4.5" => 1`)

Both of these stemmed from my misreading of the docs for `parseInt`; what I actually wanted was the `Number()` function followed by `Number.isNaN()`!

sjbarag: @alimnios72 we chatted about this in-person a few days ago!  Should be fixed in the next release (publishing that in a few minutes)

Patch:
diff --git a/src/preprocessor/Manifest.ts b/src/preprocessor/Manifest.ts
index e076f04..42cf352 100644
--- a/src/preprocessor/Manifest.ts
+++ b/src/preprocessor/Manifest.ts
@@ -89,7 +89,8 @@ export function parseManifest(contents: string) {
                 return [key, false];
             }
 
-            let maybeNumber = Number.parseInt(value);
+            let maybeNumber = Number(value);
+
             // if it's not a number, it's just a string
             if (Number.isNaN(maybeNumber)) {
                 return [key, value];


Test patch:
diff --git a/test/preprocessor/Manifest.test.js b/test/preprocessor/Manifest.test.js
index cc182ca..49440e4 100644
--- a/test/preprocessor/Manifest.test.js
+++ b/test/preprocessor/Manifest.test.js
@@ -56,7 +56,10 @@ describe("manifest support", () => {
 
         it("parses key-value pairs", () => {
             fs.readFile.mockImplementation((filename, encoding, cb) =>
-                cb(/* no error */ null, ["foo=bar=baz", "lorem=true", "five=5"].join("\n"))
+                cb(
+                    /* no error */ null,
+                    ["foo=bar=baz", "lorem=true", "five=5", "six=6.000", "version=1.2.3"].join("\n")
+                )
             );
 
             return expect(getManifest("/has/a/manifest")).resolves.toEqual(
@@ -64,6 +67,8 @@ describe("manifest support", () => {
                     ["foo", "bar=baz"],
                     ["lorem", true],
                     ["five", 5],
+                    ["six", 6],
+                    ["version", "1.2.3"],
                 ])
             );
         });
Repository: sindresorhus/normalize-url
Pull request #103 (2020-01-06 09:35:10)

Require Node.js 10
Node 8 is end-of-life. We can use only URL global.

sindresorhus: You need to update package.json too.
TrySound: @sindresorhus Done
TrySound: Hi @sindresorhus 
Friendly ping in case you missed update
TrySound: Hi @sindresorhus Is everything good now?

Patch:
diff --git a/.travis.yml b/.travis.yml
index 1492647..fd301d7 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -2,6 +2,5 @@ language: node_js
 node_js:
   - '12'
   - '10'
-  - '8'
 after_success:
   - './node_modules/.bin/nyc report --reporter=text-lcov | ./node_modules/.bin/coveralls'
diff --git a/index.js b/index.js
index 4eea255..cca0667 100644
--- a/index.js
+++ b/index.js
@@ -1,6 +1,4 @@
 'use strict';
-// TODO: Use the `URL` global when targeting Node.js 10
-const URLParser = typeof URL === 'undefined' ? require('url').URL : URL;
 
 // https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs
 const DATA_URL_DEFAULT_MIME_TYPE = 'text/plain';
@@ -106,7 +104,7 @@ const normalizeUrl = (urlString, options) => {
 		urlString = urlString.replace(/^(?!(?:\w+:)?\/\/)|^\/\//, options.defaultProtocol);
 	}
 
-	const urlObj = new URLParser(urlString);
+	const urlObj = new URL(urlString);
 
 	if (options.forceHttp && options.forceHttps) {
 		throw new Error('The `forceHttp` and `forceHttps` options cannot be used together');
@@ -146,7 +144,9 @@ const normalizeUrl = (urlString, options) => {
 
 	// Decode URI octets
 	if (urlObj.pathname) {
-		urlObj.pathname = decodeURI(urlObj.pathname);
+		try {
+			urlObj.pathname = decodeURI(urlObj.pathname);
+		} catch (_) {}
 	}
 
 	// Remove directory index
diff --git a/package.json b/package.json
index 062ad53..3a7c0a7 100644
--- a/package.json
+++ b/package.json
@@ -10,7 +10,7 @@
 		"url": "sindresorhus.com"
 	},
 	"engines": {
-		"node": ">=8"
+		"node": ">=10"
 	},
 	"scripts": {
 		"test": "xo && nyc ava && tsd"


Test patch:
diff --git a/test.js b/test.js
index dba2e13..85e706d 100644
--- a/test.js
+++ b/test.js
@@ -24,6 +24,7 @@ test('main', t => {
 	t.is(normalizeUrl('https://foo.com/http://bar.com'), 'https://foo.com/http://bar.com');
 	t.is(normalizeUrl('https://foo.com/http://bar.com/foo//bar'), 'https://foo.com/http://bar.com/foo/bar');
 	t.is(normalizeUrl('http://sindresorhus.com/%7Efoo/'), 'http://sindresorhus.com/~foo', 'decode URI octets');
+	t.is(normalizeUrl('https://foo.com/%FAIL%/07/94/ca/55.jpg'), 'https://foo.com/%FAIL%/07/94/ca/55.jpg');
 	t.is(normalizeUrl('http://sindresorhus.com/?'), 'http://sindresorhus.com');
 	t.is(normalizeUrl('êxample.com'), 'http://xn--xample-hva.com');
 	t.is(normalizeUrl('http://sindresorhus.com/?b=bar&a=foo'), 'http://sindresorhus.com/?a=foo&b=bar');
Repository: sindresorhus/normalize-url
Pull request #104 (2020-01-18 15:20:44)

Don't throw if decoding the path fails
Hello,

I found this case where the URL is considered valid but decode pathname fails.


Patch:
diff --git a/index.js b/index.js
index 4eea255..61016d5 100644
--- a/index.js
+++ b/index.js
@@ -146,7 +146,9 @@ const normalizeUrl = (urlString, options) => {
 
 	// Decode URI octets
 	if (urlObj.pathname) {
-		urlObj.pathname = decodeURI(urlObj.pathname);
+		try {
+			urlObj.pathname = decodeURI(urlObj.pathname);
+		} catch (_) {}
 	}
 
 	// Remove directory index


Test patch:
diff --git a/test.js b/test.js
index dba2e13..85e706d 100644
--- a/test.js
+++ b/test.js
@@ -24,6 +24,7 @@ test('main', t => {
 	t.is(normalizeUrl('https://foo.com/http://bar.com'), 'https://foo.com/http://bar.com');
 	t.is(normalizeUrl('https://foo.com/http://bar.com/foo//bar'), 'https://foo.com/http://bar.com/foo/bar');
 	t.is(normalizeUrl('http://sindresorhus.com/%7Efoo/'), 'http://sindresorhus.com/~foo', 'decode URI octets');
+	t.is(normalizeUrl('https://foo.com/%FAIL%/07/94/ca/55.jpg'), 'https://foo.com/%FAIL%/07/94/ca/55.jpg');
 	t.is(normalizeUrl('http://sindresorhus.com/?'), 'http://sindresorhus.com');
 	t.is(normalizeUrl('êxample.com'), 'http://xn--xample-hva.com');
 	t.is(normalizeUrl('http://sindresorhus.com/?b=bar&a=foo'), 'http://sindresorhus.com/?a=foo&b=bar');
Repository: sindresorhus/query-string
Pull request #89 (2017-04-10 13:37:16)

Fix single bracketed array should wrap its value in an one index array
Single bracketed array should wrap its value in an one index array.


Patch:
diff --git a/index.js b/index.js
index 942be38..490d774 100644
--- a/index.js
+++ b/index.js
@@ -69,7 +69,7 @@ function parserForArrayFormat(opts) {
 				key = key.replace(/\[\]$/, '');
 
 				if (!result || accumulator[key] === undefined) {
-					accumulator[key] = value;
+					accumulator[key] = [value];
 					return;
 				}
 


Test patch:
diff --git a/test/parse.js b/test/parse.js
index 66eb363..0a71266 100644
--- a/test/parse.js
+++ b/test/parse.js
@@ -93,6 +93,10 @@ test('query strings having indexed arrays keeping index order', t => {
 	t.deepEqual(fn.parse('foo[1]=bar&foo[0]=baz'), {'foo[1]': 'bar', 'foo[0]': 'baz'});
 });
 
+test('query string having a single bracketed value and format option as `bracket`', t => {
+	t.deepEqual(fn.parse('foo[]=bar', {arrayFormat: 'bracket'}), {foo: ['bar']});
+});
+
 test('query strings having brackets arrays and format option as `bracket`', t => {
 	t.deepEqual(fn.parse('foo[]=bar&foo[]=baz', {
 		arrayFormat: 'bracket'
Repository: sindresorhus/query-string
Pull request #91 (2017-04-18 11:44:46)

Prevent non-array values from being wrapped in arrays
#89 (`4.3.3`) broke non-array values when `arrayFormat` was set to `bracket`.

`foo=bar` resulted in `{foo: ['bar']}` instead of `{foo: 'bar'}`

sindresorhus: // @rapzo 
rapzo: Nice catch! It felt like there had to be some case the previous fix was breaking. Thanks for adding tests that cover it!

Patch:
diff --git a/index.js b/index.js
index 490d774..2d22df2 100644
--- a/index.js
+++ b/index.js
@@ -65,10 +65,12 @@ function parserForArrayFormat(opts) {
 		case 'bracket':
 			return function (key, value, accumulator) {
 				result = /(\[\])$/.exec(key);
-
 				key = key.replace(/\[\]$/, '');
 
-				if (!result || accumulator[key] === undefined) {
+				if (!result) {
+					accumulator[key] = value;
+					return;
+				} else if (accumulator[key] === undefined) {
 					accumulator[key] = [value];
 					return;
 				}


Test patch:
diff --git a/test/parse.js b/test/parse.js
index 0a71266..d1561ef 100644
--- a/test/parse.js
+++ b/test/parse.js
@@ -97,6 +97,14 @@ test('query string having a single bracketed value and format option as `bracket
 	t.deepEqual(fn.parse('foo[]=bar', {arrayFormat: 'bracket'}), {foo: ['bar']});
 });
 
+test('query string not having a bracketed value and format option as `bracket`', t => {
+	t.deepEqual(fn.parse('foo=bar', {arrayFormat: 'bracket'}), {foo: 'bar'});
+});
+
+test('query string having a bracketed value and a single value and format option as `bracket`', t => {
+	t.deepEqual(fn.parse('foo=bar&baz[]=bar', {arrayFormat: 'bracket'}), {foo: 'bar', baz: ['bar']});
+});
+
 test('query strings having brackets arrays and format option as `bracket`', t => {
 	t.deepEqual(fn.parse('foo[]=bar&foo[]=baz', {
 		arrayFormat: 'bracket'
Repository: sindresorhus/query-string
Pull request #109 (2017-09-20 12:26:33)

Fix `.extract()` for query strings containing `?`

neykov: Addressed comments.
apuntovanini: Any plans to merge this? Thanks!
rapzo: I would if i could :-)

Patch:
diff --git a/index.js b/index.js
index 00b5f26..7da4fea 100644
--- a/index.js
+++ b/index.js
@@ -114,7 +114,11 @@ function keysSorter(input) {
 }
 
 exports.extract = function (str) {
-	return str.split('?')[1] || '';
+	var queryStart = str.indexOf('?');
+	if (queryStart === -1) {
+		return '';
+	}
+	return str.slice(queryStart + 1);
 };
 
 exports.parse = function (str, opts) {


Test patch:
diff --git a/test/extract.js b/test/extract.js
index 2434ab9..28324e2 100644
--- a/test/extract.js
+++ b/test/extract.js
@@ -4,6 +4,7 @@ import fn from '../';
 test('should extract query string from url', t => {
 	t.is(fn.extract('http://foo.bar/?abc=def&hij=klm'), 'abc=def&hij=klm');
 	t.is(fn.extract('http://foo.bar/?'), '');
+	t.is(fn.extract('http://foo.bar/?regex=ab?c'), 'regex=ab?c');
 });
 
 test('should handle strings not containing query string', t => {
Repository: sindresorhus/query-string
Pull request #173 (2019-04-09 08:43:10)

Support stringifying array containing value 0
For whatever reason, I need to send these kind of query strings to a server:
```
idList=0,1,2,3
```
Before : 0 value was ignored.  
After : 0 value is well added to the final string

padupuy: Could you review please @sindresorhus @kevva @SamVerschueren  ? 

Patch:
diff --git a/index.js b/index.js
index 88a260f..ba23c36 100644
--- a/index.js
+++ b/index.js
@@ -37,7 +37,7 @@ function encoderForArrayFormat(options) {
 
 		case 'comma':
 			return key => (result, value, index) => {
-				if (!value) {
+				if (value === null || value === undefined || value.length === 0) {
 					return result;
 				}
 
@@ -152,7 +152,17 @@ function keysSorter(input) {
 	return input;
 }
 
+function removeHash(input) {
+	const hashStart = input.indexOf('#');
+	if (hashStart !== -1) {
+		input = input.slice(0, hashStart);
+	}
+
+	return input;
+}
+
 function extract(input) {
+	input = removeHash(input);
 	const queryStart = input.indexOf('?');
 	if (queryStart === -1) {
 		return '';
@@ -248,13 +258,8 @@ exports.stringify = (object, options) => {
 };
 
 exports.parseUrl = (input, options) => {
-	const hashStart = input.indexOf('#');
-	if (hashStart !== -1) {
-		input = input.slice(0, hashStart);
-	}
-
 	return {
-		url: input.split('?')[0] || '',
+		url: removeHash(input).split('?')[0] || '',
 		query: parse(extract(input), options)
 	};
 };


Test patch:
diff --git a/test/extract.js b/test/extract.js
index a16d7ae..b7cde18 100644
--- a/test/extract.js
+++ b/test/extract.js
@@ -5,10 +5,13 @@ test('extracts query string from url', t => {
 	t.is(queryString.extract('https://foo.bar/?abc=def&hij=klm'), 'abc=def&hij=klm');
 	t.is(queryString.extract('https://foo.bar/?'), '');
 	t.is(queryString.extract('https://foo.bar/?regex=ab?c'), 'regex=ab?c');
+	t.is(queryString.extract('https://foo.bar#top?foo=bar'), '');
+	t.is(queryString.extract('https://foo.bar?foo=bar#top'), 'foo=bar');
 });
 
 test('handles strings not containing query string', t => {
 	t.is(queryString.extract('https://foo.bar'), '');
+	t.is(queryString.extract('https://foo.bar#top'), '');
 	t.is(queryString.extract(''), '');
 });
 
diff --git a/test/stringify.js b/test/stringify.js
index 6e6b63c..8553ebd 100644
--- a/test/stringify.js
+++ b/test/stringify.js
@@ -135,6 +135,15 @@ test('array stringify representation with array commas and null value', t => {
 	}), 'foo=a');
 });
 
+test('array stringify representation with array commas and 0 value', t => {
+	t.is(queryString.stringify({
+		foo: ['a', null, 0],
+		bar: [null]
+	}, {
+		arrayFormat: 'comma'
+	}), 'foo=a,0');
+});
+
 test('array stringify representation with a bad array format', t => {
 	t.is(queryString.stringify({
 		foo: null,
Repository: sindresorhus/query-string
Pull request #174 (2019-04-11 12:02:46)

Support hash in `.extract()`


Patch:
diff --git a/index.js b/index.js
index 88a260f..78f0f91 100644
--- a/index.js
+++ b/index.js
@@ -152,7 +152,17 @@ function keysSorter(input) {
 	return input;
 }
 
+function removeHash(input) {
+	const hashStart = input.indexOf('#');
+	if (hashStart !== -1) {
+		input = input.slice(0, hashStart);
+	}
+
+	return input;
+}
+
 function extract(input) {
+	input = removeHash(input);
 	const queryStart = input.indexOf('?');
 	if (queryStart === -1) {
 		return '';
@@ -248,13 +258,8 @@ exports.stringify = (object, options) => {
 };
 
 exports.parseUrl = (input, options) => {
-	const hashStart = input.indexOf('#');
-	if (hashStart !== -1) {
-		input = input.slice(0, hashStart);
-	}
-
 	return {
-		url: input.split('?')[0] || '',
+		url: removeHash(input).split('?')[0] || '',
 		query: parse(extract(input), options)
 	};
 };


Test patch:
diff --git a/test/extract.js b/test/extract.js
index a16d7ae..b7cde18 100644
--- a/test/extract.js
+++ b/test/extract.js
@@ -5,10 +5,13 @@ test('extracts query string from url', t => {
 	t.is(queryString.extract('https://foo.bar/?abc=def&hij=klm'), 'abc=def&hij=klm');
 	t.is(queryString.extract('https://foo.bar/?'), '');
 	t.is(queryString.extract('https://foo.bar/?regex=ab?c'), 'regex=ab?c');
+	t.is(queryString.extract('https://foo.bar#top?foo=bar'), '');
+	t.is(queryString.extract('https://foo.bar?foo=bar#top'), 'foo=bar');
 });
 
 test('handles strings not containing query string', t => {
 	t.is(queryString.extract('https://foo.bar'), '');
+	t.is(queryString.extract('https://foo.bar#top'), '');
 	t.is(queryString.extract(''), '');
 });
Repository: sindresorhus/query-string
Pull request #236 (2020-01-21 06:50:44)

Preserve encoded commas when using `arrayFormat: 'comma'`
fix https://github.com/sindresorhus/query-string/issues/211


Patch:
diff --git a/index.js b/index.js
index 7a9ffca..d19e138 100644
--- a/index.js
+++ b/index.js
@@ -106,7 +106,7 @@ function parserForArrayFormat(options) {
 		case 'comma':
 			return (key, value, accumulator) => {
 				const isArray = typeof value === 'string' && value.split('').indexOf(',') > -1;
-				const newValue = isArray ? value.split(',') : value;
+				const newValue = isArray ? value.split(',').map(item => decode(item, options)) : value === null ? value : decode(value, options);
 				accumulator[key] = newValue;
 			};
 
@@ -220,7 +220,7 @@ function parse(input, options) {
 
 		// Missing `=` should be `null`:
 		// http://w3.org/TR/2012/WD-url-20120524/#collect-url-parameters
-		value = value === undefined ? null : decode(value, options);
+		value = value === undefined ? null : options.arrayFormat === 'comma' ? value : decode(value, options);
 		formatter(decode(key, options), value, ret);
 	}
 


Test patch:
diff --git a/test/parse.js b/test/parse.js
index f75a745..b2f4da0 100644
--- a/test/parse.js
+++ b/test/parse.js
@@ -284,3 +284,12 @@ test('parseNumbers and parseBooleans can work with arrayFormat at the same time'
 	t.deepEqual(queryString.parse('foo=true,false&bar=1,2', {parseNumbers: true, parseBooleans: true, arrayFormat: 'comma'}), {foo: [true, false], bar: [1, 2]});
 	t.deepEqual(queryString.parse('foo[0]=true&foo[1]=false&bar[0]=1&bar[1]=2', {parseNumbers: true, parseBooleans: true, arrayFormat: 'index'}), {foo: [true, false], bar: [1, 2]});
 });
+
+test('query strings having comma encoded and format option as `comma`', t => {
+	t.deepEqual(queryString.parse('foo=zero%2Cone,two%2Cthree', {arrayFormat: 'comma'}), {
+		foo: [
+			'zero,one',
+			'two,three'
+		]
+	});
+});