From f27d4b063b7995759d629af64fe7c6b58a55a685 Mon Sep 17 00:00:00 2001
From: antareepsarkar <sarkar.antareep.9035@gmail.com>
Date: Tue, 20 Jan 2026 18:37:10 +0530
Subject: [PATCH] [New]: add allowDotsForIndices option

---
 eslint.config.mjs |  2 +-
 lib/stringify.js  | 15 +++++++++++++++
 test/stringify.js |  6 ++++++
 3 files changed, 22 insertions(+), 1 deletion(-)

diff --git a/eslint.config.mjs b/eslint.config.mjs
index bdde6e94..d85836a1 100644
--- a/eslint.config.mjs
+++ b/eslint.config.mjs
@@ -26,7 +26,7 @@ export default [
                 'error',
                 { max: 150 },
             ],
-            'max-params': ['error', 18],
+            'max-params': ['error', 19],
             'max-statements': ['error', 100],
             'multiline-comment-style': 'off',
             'no-continue': 'warn',
diff --git a/lib/stringify.js b/lib/stringify.js
index 2666eaf9..75a3b592 100644
--- a/lib/stringify.js
+++ b/lib/stringify.js
@@ -10,6 +10,9 @@ var arrayPrefixGenerators = {
         return prefix + '[]';
     },
     comma: 'comma',
+    dots: function dots(prefix, key) {
+        return prefix + '.' + key;
+    },
     indices: function indices(prefix, key) {
         return prefix + '[' + key + ']';
     },
@@ -30,6 +33,7 @@ var defaultFormat = formats['default'];
 var defaults = {
     addQueryPrefix: false,
     allowDots: false,
+    allowDotsForIndices: false,
     allowEmptyArrays: false,
     arrayFormat: 'indices',
     charset: 'utf-8',
@@ -75,6 +79,7 @@ var stringify = function stringify(
     filter,
     sort,
     allowDots,
+    allowDotsForIndices,
     serializeDate,
     format,
     formatter,
@@ -191,6 +196,7 @@ var stringify = function stringify(
             filter,
             sort,
             allowDots,
+            allowDotsForIndices,
             serializeDate,
             format,
             formatter,
@@ -220,6 +226,10 @@ var normalizeStringifyOptions = function normalizeStringifyOptions(opts) {
         throw new TypeError('Encoder has to be a function.');
     }
 
+    if ('allowDots' in opts && opts.allowDots === false && opts.allowDotsForIndices) {
+        throw new TypeError('allowDots cannot be false and allowDotsForIndices true at the same time');
+    }
+
     var charset = opts.charset || defaults.charset;
     if (typeof opts.charset !== 'undefined' && opts.charset !== 'utf-8' && opts.charset !== 'iso-8859-1') {
         throw new TypeError('The charset option must be either utf-8, iso-8859-1, or undefined');
@@ -244,6 +254,8 @@ var normalizeStringifyOptions = function normalizeStringifyOptions(opts) {
         arrayFormat = opts.arrayFormat;
     } else if ('indices' in opts) {
         arrayFormat = opts.indices ? 'indices' : 'repeat';
+    } else if (opts.allowDotsForIndices) {
+        arrayFormat = 'dots';
     } else {
         arrayFormat = defaults.arrayFormat;
     }
@@ -253,10 +265,12 @@ var normalizeStringifyOptions = function normalizeStringifyOptions(opts) {
     }
 
     var allowDots = typeof opts.allowDots === 'undefined' ? opts.encodeDotInKeys === true ? true : defaults.allowDots : !!opts.allowDots;
+    var allowDotsForIndices = opts.allowDotsForIndices;
 
     return {
         addQueryPrefix: typeof opts.addQueryPrefix === 'boolean' ? opts.addQueryPrefix : defaults.addQueryPrefix,
         allowDots: allowDots,
+        allowDotsForIndices: allowDotsForIndices,
         allowEmptyArrays: typeof opts.allowEmptyArrays === 'boolean' ? !!opts.allowEmptyArrays : defaults.allowEmptyArrays,
         arrayFormat: arrayFormat,
         charset: charset,
@@ -330,6 +344,7 @@ module.exports = function (object, opts) {
             options.filter,
             options.sort,
             options.allowDots,
+            options.allowDotsForIndices,
             options.serializeDate,
             options.format,
             options.formatter,
diff --git a/test/stringify.js b/test/stringify.js
index 4d776947..d21947df 100644
--- a/test/stringify.js
+++ b/test/stringify.js
@@ -227,6 +227,12 @@ test('stringify()', function (t) {
         st.end();
     });
 
+    t.test('`allowDotsForIndices` option: stringifies a nested object with converting indices to dot notation', function (st) {
+        st.equal(qs.stringify({ a: [1, 2] }, { allowDotsForIndices: true }), 'a.0=1&a.1=2');
+        st.equal(qs.stringify({ a: [{ b: 'c', d: 'e' }] }, { allowDotsForIndices: true, allowDots: true }), 'a.0.b=c&a.0.d=e');
+        st.end();
+    });
+
     t.test('stringifies an array value', function (st) {
         st.equal(
             qs.stringify({ a: ['b', 'c', 'd'] }, { arrayFormat: 'indices' }),
