From 35ffdced8931955f69ce1c237f8fa4e819f34991 Mon Sep 17 00:00:00 2001 From: mahsashadi <70196035+mahsashadi@users.noreply.github.com> Date: Sun, 29 Aug 2021 10:49:37 +0430 Subject: [PATCH 01/10] Improve unserialization of VFS URL query parameters --- src/vfs.js | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/src/vfs.js b/src/vfs.js index 54d98b6..23be9b2 100644 --- a/src/vfs.js +++ b/src/vfs.js @@ -111,7 +111,7 @@ const createMiddleware = core => { }; const createOptions = req => { - const options = req.fields.options; + const options = req.fields.options ? req.fields.options : decodeOptions(req.fields); const range = req.headers && req.headers.range; const session = {...req.session || {}}; let result = options || {}; @@ -134,6 +134,30 @@ const createOptions = req => { }; }; +const decodeOptions = (reqFileds) => { + let options = {}; + let keyPath = []; + Object.keys(reqFileds).map((item) => { + keyPath = item.split('.'); + assignObject(options, keyPath, reqFileds[item]); + }); + console.log(options) + return options; +}; + +const assignObject = (obj, keyPath, value) => { + let lastKeyIndex = keyPath.length - 1; + let key; + for (let i = 0; i < lastKeyIndex; i++) { + key = keyPath[i]; + if (!(key in obj)) { + obj[key] = {}; + } + obj = obj[key]; + } + obj[keyPath[lastKeyIndex]] = value; +}; + // Standard request with only a target const createRequestFactory = findMountpoint => (getter, method, readOnly, respond) => async (req, res) => { const options = createOptions(req); From b2bd640a6b69eadb347e200ac53a3d4fc37111cd Mon Sep 17 00:00:00 2001 From: mahsa shadi <mahsa.shadi@mail.um.ac.ir> Date: Fri, 3 Sep 2021 11:41:14 -0400 Subject: [PATCH 02/10] add unserialization of VFS URL query parameters into utils --- src/utils/vfs.js | 31 +++++++++++++++++++++++++++++-- src/vfs.js | 28 ++-------------------------- 2 files changed, 31 insertions(+), 28 deletions(-) diff --git a/src/utils/vfs.js b/src/utils/vfs.js index e4dd10c..e02a782 100644 --- a/src/utils/vfs.js +++ b/src/utils/vfs.js @@ -176,10 +176,37 @@ const mountpointResolver = core => async (path) => { */ const parseGet = req => { const {query} = url.parse(req.url, true); - - return Promise.resolve({fields: query, files: {}}); + const assembledQuery = assembleQueryData(query); + + return Promise.resolve({fields: assembledQuery, files: {}}); }; +/* + * Assembles a given object query + */ +const assembleQueryData = (object) => { + const assembled = {} + const keys = Object.keys(object) + + for (let i = 0; i < keys.length; i++) { + const key = keys[i] + const dots = key.split('.') + + let last = assembled + for (let j = 0; j < dots.length; j++) { + const dot = dots[j] + if (j >= dots.length - 1) { + last[dot] = object[key] + } else { + last[dot] = last[dot] || {} + } + + last = last[dot] + } + } + return assembled; +} + /* * Parses Json Body */ diff --git a/src/vfs.js b/src/vfs.js index 23be9b2..17fb2be 100644 --- a/src/vfs.js +++ b/src/vfs.js @@ -111,7 +111,7 @@ const createMiddleware = core => { }; const createOptions = req => { - const options = req.fields.options ? req.fields.options : decodeOptions(req.fields); + const options = req.fields.options; const range = req.headers && req.headers.range; const session = {...req.session || {}}; let result = options || {}; @@ -134,30 +134,6 @@ const createOptions = req => { }; }; -const decodeOptions = (reqFileds) => { - let options = {}; - let keyPath = []; - Object.keys(reqFileds).map((item) => { - keyPath = item.split('.'); - assignObject(options, keyPath, reqFileds[item]); - }); - console.log(options) - return options; -}; - -const assignObject = (obj, keyPath, value) => { - let lastKeyIndex = keyPath.length - 1; - let key; - for (let i = 0; i < lastKeyIndex; i++) { - key = keyPath[i]; - if (!(key in obj)) { - obj[key] = {}; - } - obj = obj[key]; - } - obj[keyPath[lastKeyIndex]] = value; -}; - // Standard request with only a target const createRequestFactory = findMountpoint => (getter, method, readOnly, respond) => async (req, res) => { const options = createOptions(req); @@ -321,4 +297,4 @@ module.exports = core => { }); return {router, methods}; -}; +}; \ No newline at end of file From 7be875504ed4d1a73b020f855b0bc07cc104bade Mon Sep 17 00:00:00 2001 From: mahsa shadi <mahsa.shadi@mail.um.ac.ir> Date: Sat, 4 Sep 2021 09:54:59 +0430 Subject: [PATCH 03/10] export assembleQueryData method and add tests --- __tests__/utils/vfs.js | 32 ++++++++++++++++++++++++++++++++ src/utils/vfs.js | 40 ++++++++++++++++++++-------------------- 2 files changed, 52 insertions(+), 20 deletions(-) diff --git a/__tests__/utils/vfs.js b/__tests__/utils/vfs.js index 85e968a..ae2bef7 100644 --- a/__tests__/utils/vfs.js +++ b/__tests__/utils/vfs.js @@ -243,4 +243,36 @@ describe('VFS Utils', () => { test('parseFields - POST w/Form', () => { // TODO }); + + test('assembleQueryData', () => { + const result = utils.assembleQueryData({ + 'a': 'b', + 'b.a': 'foo', + 'b.b.a': 'foo', + 'b.b.b': 'foo', + 'b.b.c': 'foo', + 'b.b.d': 'foo', + 'b.b.e': 'foo', + 'c': 'null', + 'd': 'true', + 'e': '1' + }); + + expect(result).toEqual({ + a: 'b', + b: { + a: 'foo', + b: { + a: 'foo', + b: 'foo', + c: 'foo', + d: 'foo', + e: 'foo' + } + }, + c: 'null', + d: 'true', + e: '1' + }); + }); }); diff --git a/src/utils/vfs.js b/src/utils/vfs.js index e02a782..1e1d341 100644 --- a/src/utils/vfs.js +++ b/src/utils/vfs.js @@ -171,42 +171,41 @@ const mountpointResolver = core => async (path) => { return Object.freeze({mount, adapter}); }; -/* - * Parses URL Body - */ -const parseGet = req => { - const {query} = url.parse(req.url, true); - const assembledQuery = assembleQueryData(query); - - return Promise.resolve({fields: assembledQuery, files: {}}); -}; - /* * Assembles a given object query */ const assembleQueryData = (object) => { - const assembled = {} - const keys = Object.keys(object) + const assembled = {}; + const keys = Object.keys(object); for (let i = 0; i < keys.length; i++) { - const key = keys[i] - const dots = key.split('.') + const key = keys[i]; + const dots = key.split('.'); - let last = assembled + let last = assembled; for (let j = 0; j < dots.length; j++) { - const dot = dots[j] + const dot = dots[j]; if (j >= dots.length - 1) { - last[dot] = object[key] + last[dot] = object[key]; } else { - last[dot] = last[dot] || {} + last[dot] = last[dot] || {}; } - last = last[dot] + last = last[dot]; } } return assembled; } +/* + * Parses URL Body + */ +const parseGet = req => { + const {query} = url.parse(req.url, true); + const assembledQuery = assembleQueryData(query); + return Promise.resolve({fields: assembledQuery, files: {}}); +}; + /* * Parses Json Body */ @@ -281,5 +280,6 @@ module.exports = { getPrefix, parseFields, errorCodes, - methodArguments + methodArguments, + assembleQueryData }; From 3ecb734b1afafbf8982ad277ec12ea7509236e2e Mon Sep 17 00:00:00 2001 From: mahsa shadi <mahsa.shadi@mail.um.ac.ir> Date: Sat, 4 Sep 2021 10:47:44 +0430 Subject: [PATCH 04/10] fixed some eslint newLine errors --- src/utils/vfs.js | 2 +- src/vfs.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/utils/vfs.js b/src/utils/vfs.js index 1e1d341..790b86f 100644 --- a/src/utils/vfs.js +++ b/src/utils/vfs.js @@ -195,7 +195,7 @@ const assembleQueryData = (object) => { } } return assembled; -} +}; /* * Parses URL Body diff --git a/src/vfs.js b/src/vfs.js index 17fb2be..54d98b6 100644 --- a/src/vfs.js +++ b/src/vfs.js @@ -297,4 +297,4 @@ module.exports = core => { }); return {router, methods}; -}; \ No newline at end of file +}; From d1335a2a96c5d0b4f68816c8e7cf2af87272439c Mon Sep 17 00:00:00 2001 From: mahsa shadi <mahsa.shadi@mail.um.ac.ir> Date: Sun, 5 Sep 2021 15:31:51 -0400 Subject: [PATCH 05/10] add array support in assembleQueryData method --- __tests__/utils/vfs.js | 36 ++++++++++++++++++++++++++++++++++-- src/utils/vfs.js | 8 +++++++- 2 files changed, 41 insertions(+), 3 deletions(-) diff --git a/__tests__/utils/vfs.js b/__tests__/utils/vfs.js index ae2bef7..3a72c4d 100644 --- a/__tests__/utils/vfs.js +++ b/__tests__/utils/vfs.js @@ -245,7 +245,7 @@ describe('VFS Utils', () => { }); test('assembleQueryData', () => { - const result = utils.assembleQueryData({ + const result1 = utils.assembleQueryData({ 'a': 'b', 'b.a': 'foo', 'b.b.a': 'foo', @@ -258,7 +258,21 @@ describe('VFS Utils', () => { 'e': '1' }); - expect(result).toEqual({ + const result2 = utils.assembleQueryData({ + 'a.0': 'foo', + 'a.1': 'foo', + 'b.0': 'foo', + 'b.1': 'foo', + 'b.a': 'foo', + 'c.a': 'foo', + 'c.b.0': 'foo', + 'c.b.1': 'foo', + 'c.c.0': 'foo', + 'c.c.1': 'foo', + 'c.c.a': 'foo', + }); + + expect(result1).toEqual({ a: 'b', b: { a: 'foo', @@ -274,5 +288,23 @@ describe('VFS Utils', () => { d: 'true', e: '1' }); + + expect(result2).toEqual({ + a: ['foo', 'foo'], + b:{ + '0': 'foo', + '1': 'foo', + 'a': 'foo', + }, + c: { + a: 'foo', + b: ['foo', 'foo'], + c: { + '0': 'foo', + '1': 'foo', + 'a': 'foo' + } + } + }); }); }); diff --git a/src/utils/vfs.js b/src/utils/vfs.js index 790b86f..13237b7 100644 --- a/src/utils/vfs.js +++ b/src/utils/vfs.js @@ -183,14 +183,20 @@ const assembleQueryData = (object) => { const dots = key.split('.'); let last = assembled; + let parent = null; for (let j = 0; j < dots.length; j++) { const dot = dots[j]; if (j >= dots.length - 1) { + if (!/^\d+$/.test(dot) && Array.isArray(last)) { + last = Object.fromEntries(last.map((value, i) => [i, value])); + parent[dots[j - 1]] = last; + } last[dot] = object[key]; } else { - last[dot] = last[dot] || {}; + last[dot] = last[dot] || (/^\d+$/.test(dots[j + 1]) ? [] : {}); } + parent = last; last = last[dot]; } } From 97f5821d22291662da722f205f17a756b5b1d53b Mon Sep 17 00:00:00 2001 From: mahsa shadi <mahsa.shadi@mail.um.ac.ir> Date: Mon, 6 Sep 2021 14:02:47 +0430 Subject: [PATCH 06/10] Solve type casting in assembleQueryData --- __tests__/utils/vfs.js | 52 ++++++++++++++++++++++-------------------- src/utils/vfs.js | 16 ++++++++++++- 2 files changed, 42 insertions(+), 26 deletions(-) diff --git a/__tests__/utils/vfs.js b/__tests__/utils/vfs.js index 3a72c4d..43ac987 100644 --- a/__tests__/utils/vfs.js +++ b/__tests__/utils/vfs.js @@ -203,7 +203,7 @@ describe('VFS Utils', () => { const parser = utils.parseFields(); return expect(parser({ - url: '/foo/?bar=baz&jazz=bass', + url: '/foo/?bar.s=baz&jazz.s=bass', method: 'get' })) .resolves @@ -246,30 +246,31 @@ describe('VFS Utils', () => { test('assembleQueryData', () => { const result1 = utils.assembleQueryData({ - 'a': 'b', - 'b.a': 'foo', - 'b.b.a': 'foo', - 'b.b.b': 'foo', - 'b.b.c': 'foo', - 'b.b.d': 'foo', - 'b.b.e': 'foo', - 'c': 'null', - 'd': 'true', - 'e': '1' + 'a.s': 'b', + 'b.a.s': 'foo', + 'b.b.a.s': 'foo', + 'b.b.b.s': 'foo', + 'b.b.c.s': 'foo', + 'b.b.d.s': 'foo', + 'b.b.e.s': 'foo', + 'c.n': 'null', + 'd.b': 'true', + 'e.i': '1', + 'f.u': 'undefined' }); const result2 = utils.assembleQueryData({ - 'a.0': 'foo', - 'a.1': 'foo', - 'b.0': 'foo', - 'b.1': 'foo', - 'b.a': 'foo', - 'c.a': 'foo', - 'c.b.0': 'foo', - 'c.b.1': 'foo', - 'c.c.0': 'foo', - 'c.c.1': 'foo', - 'c.c.a': 'foo', + 'a.0.s': 'foo', + 'a.1.s': 'foo', + 'b.0.s': 'foo', + 'b.1.s': 'foo', + 'b.a.s': 'foo', + 'c.a.s': 'foo', + 'c.b.0.s': 'foo', + 'c.b.1.s': 'foo', + 'c.c.0.s': 'foo', + 'c.c.1.s': 'foo', + 'c.c.a.s': 'foo', }); expect(result1).toEqual({ @@ -284,9 +285,10 @@ describe('VFS Utils', () => { e: 'foo' } }, - c: 'null', - d: 'true', - e: '1' + c: null, + d: true, + e: 1, + f: undefined }); expect(result2).toEqual({ diff --git a/src/utils/vfs.js b/src/utils/vfs.js index 13237b7..e3c3dd9 100644 --- a/src/utils/vfs.js +++ b/src/utils/vfs.js @@ -42,6 +42,17 @@ const errorCodes = { EACCES: 401 }; +/** + * A map of data types + */ +const typeMap = { + i: str => parseInt(str, 10), + s: str => str, + b: str => str === 'true', + u: str => undefined, + n: str => null +}; + /** * Gets prefix of a VFS path */ @@ -181,6 +192,8 @@ const assembleQueryData = (object) => { for (let i = 0; i < keys.length; i++) { const key = keys[i]; const dots = key.split('.'); + const type = dots[dots.length - 1]; + dots.pop(); let last = assembled; let parent = null; @@ -191,7 +204,7 @@ const assembleQueryData = (object) => { last = Object.fromEntries(last.map((value, i) => [i, value])); parent[dots[j - 1]] = last; } - last[dot] = object[key]; + last[dot] = typeMap[type](object[key]); } else { last[dot] = last[dot] || (/^\d+$/.test(dots[j + 1]) ? [] : {}); } @@ -208,6 +221,7 @@ const assembleQueryData = (object) => { */ const parseGet = req => { const {query} = url.parse(req.url, true); + console.log(query); const assembledQuery = assembleQueryData(query); return Promise.resolve({fields: assembledQuery, files: {}}); }; From 9dacd351ade98067ed2e7fb8fb5e793059d4309c Mon Sep 17 00:00:00 2001 From: mahsa shadi <mahsa.shadi@mail.um.ac.ir> Date: Mon, 6 Sep 2021 14:07:12 +0430 Subject: [PATCH 07/10] Remove unnecessary console.log --- src/utils/vfs.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/utils/vfs.js b/src/utils/vfs.js index e3c3dd9..67998bf 100644 --- a/src/utils/vfs.js +++ b/src/utils/vfs.js @@ -221,7 +221,6 @@ const assembleQueryData = (object) => { */ const parseGet = req => { const {query} = url.parse(req.url, true); - console.log(query); const assembledQuery = assembleQueryData(query); return Promise.resolve({fields: assembledQuery, files: {}}); }; From 9e9359c550f743d3dd7d20a48a3a27dbe85ecedc Mon Sep 17 00:00:00 2001 From: mahsa shadi <mahsa.shadi@mail.um.ac.ir> Date: Sun, 7 Nov 2021 13:42:46 +0330 Subject: [PATCH 08/10] vfs capabilities, stat totalCount, and stat totalSize is added --- src/adapters/vfs/system.js | 49 +++++++++++++++++++++++++++++--------- src/vfs.js | 2 ++ 2 files changed, 40 insertions(+), 11 deletions(-) diff --git a/src/adapters/vfs/system.js b/src/adapters/vfs/system.js index 1469c7d..2baf6e1 100644 --- a/src/adapters/vfs/system.js +++ b/src/adapters/vfs/system.js @@ -36,20 +36,35 @@ const chokidar = require('chokidar'); /* * Creates an object readable by client */ -const createFileIter = (core, realRoot, file) => { +const createFileIter = (core, realRoot, file, options = {}) => { const filename = path.basename(file); const realPath = path.join(realRoot, filename); const {mime} = core.make('osjs/vfs'); - const createStat = stat => ({ - isDirectory: stat.isDirectory(), - isFile: stat.isFile(), - mime: stat.isFile() ? mime(realPath) : null, - size: stat.size, - path: file, - filename, - stat - }); + const createStat = async stat => { + let totalSize = 0; + let files = []; + if (stat.isDirectory()) { + files = await fs.readdir(realPath); + if(!options.showHiddenFiles) { + files = files.filter(f => f.substr(0, 1) !== '.'); + } + const promises = files.map(f => fs.stat(path.join(realPath, f))); + const allPromises = await Promise.all(promises); + allPromises.map(s => totalSize += s.size); + } + return ({ + isDirectory: stat.isDirectory(), + isFile: stat.isFile(), + mime: stat.isFile() ? mime(realPath) : null, + size: stat.size, + path: file, + totalCount: files.length, + totalSize: totalSize, + filename, + stat + }); + }; return fs.stat(realPath) .then(createStat) @@ -184,9 +199,21 @@ module.exports = (core) => { Promise.resolve(getRealPath(core, options.session, vfs.mount, file)) .then(realPath => { return fs.access(realPath, fs.F_OK) - .then(() => createFileIter(core, path.dirname(realPath), realPath)); + .then(() => createFileIter(core, path.dirname(realPath), realPath, options)); }), + /** + * Reads directory + * @param {String} root The file path from client + * @param {Object} [options={}] Options + * @return {Object[]} + */ + capabilities: vfs => (file, options = {}) => + Promise.resolve({ + sort:false, + pagination:false + }), + /** * Reads directory * @param {String} root The file path from client diff --git a/src/vfs.js b/src/vfs.js index 54d98b6..c4e8fb4 100644 --- a/src/vfs.js +++ b/src/vfs.js @@ -238,6 +238,7 @@ const vfs = core => { realpath: createRequest(requestPath, 'realpath', false), exists: createRequest(requestPath, 'exists', false, respondBoolean), stat: createRequest(requestPath, 'stat', false), + capabilities: createRequest(requestPath, 'capabilities', false), readdir: createRequest(requestPath, 'readdir', false), readfile: createRequest(requestPath, 'readfile', false), writefile: createRequest(requestFile, 'writefile', true, respondNumber), @@ -268,6 +269,7 @@ module.exports = core => { // Then all VFS routes (needs implementation above) router.get('/exists', wrapper(methods.exists)); router.get('/stat', wrapper(methods.stat)); + router.get('/capabilities', wrapper(methods.capabilities)); router.get('/readdir', wrapper(methods.readdir)); router.get('/readfile', wrapper(methods.readfile)); router.post('/writefile', wrapper(methods.writefile)); From 6191979f62d8c6def0828c3362e50ae48453f7b4 Mon Sep 17 00:00:00 2001 From: mahsa shadi <mahsa.shadi@mail.um.ac.ir> Date: Sun, 7 Nov 2021 13:48:30 +0330 Subject: [PATCH 09/10] description in comment is fixed --- src/adapters/vfs/system.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/adapters/vfs/system.js b/src/adapters/vfs/system.js index 2baf6e1..1a689c5 100644 --- a/src/adapters/vfs/system.js +++ b/src/adapters/vfs/system.js @@ -203,10 +203,10 @@ module.exports = (core) => { }), /** - * Reads directory - * @param {String} root The file path from client + * Get vfs capabilities + * @param {String} file The optional file path from client * @param {Object} [options={}] Options - * @return {Object[]} + * @return {Object} */ capabilities: vfs => (file, options = {}) => Promise.resolve({ From 23b3c5756e67eda6b6bfd8cf3967284db25bfe0a Mon Sep 17 00:00:00 2001 From: mahsa shadi <mahsa.shadi@mail.um.ac.ir> Date: Sun, 24 Jul 2022 10:43:19 +0430 Subject: [PATCH 10/10] Support unserialization of VFS URL query parameters --- __tests__/utils/vfs.js | 63 +++++++----------------------------------- src/utils/vfs.js | 48 +++++++------------------------- 2 files changed, 20 insertions(+), 91 deletions(-) diff --git a/__tests__/utils/vfs.js b/__tests__/utils/vfs.js index 43ac987..7dd3e17 100644 --- a/__tests__/utils/vfs.js +++ b/__tests__/utils/vfs.js @@ -203,7 +203,7 @@ describe('VFS Utils', () => { const parser = utils.parseFields(); return expect(parser({ - url: '/foo/?bar.s=baz&jazz.s=bass', + url: '/foo/?bar=baz&jazz=bass', method: 'get' })) .resolves @@ -246,65 +246,22 @@ describe('VFS Utils', () => { test('assembleQueryData', () => { const result1 = utils.assembleQueryData({ - 'a.s': 'b', - 'b.a.s': 'foo', - 'b.b.a.s': 'foo', - 'b.b.b.s': 'foo', - 'b.b.c.s': 'foo', - 'b.b.d.s': 'foo', - 'b.b.e.s': 'foo', - 'c.n': 'null', - 'd.b': 'true', - 'e.i': '1', - 'f.u': 'undefined' - }); - - const result2 = utils.assembleQueryData({ - 'a.0.s': 'foo', - 'a.1.s': 'foo', - 'b.0.s': 'foo', - 'b.1.s': 'foo', - 'b.a.s': 'foo', - 'c.a.s': 'foo', - 'c.b.0.s': 'foo', - 'c.b.1.s': 'foo', - 'c.c.0.s': 'foo', - 'c.c.1.s': 'foo', - 'c.c.a.s': 'foo', + 'a': 'b', + 'b': '{"a":"foo"}', + 'c': '{"a":false,"c":null,"d":1,"e":{"a":"foo"}}' }); expect(result1).toEqual({ a: 'b', b: { - a: 'foo', - b: { - a: 'foo', - b: 'foo', - c: 'foo', - d: 'foo', - e: 'foo' - } - }, - c: null, - d: true, - e: 1, - f: undefined - }); - - expect(result2).toEqual({ - a: ['foo', 'foo'], - b:{ - '0': 'foo', - '1': 'foo', - 'a': 'foo', + a: 'foo' }, c: { - a: 'foo', - b: ['foo', 'foo'], - c: { - '0': 'foo', - '1': 'foo', - 'a': 'foo' + a: false, + c: null, + d: 1, + e: { + a: 'foo' } } }); diff --git a/src/utils/vfs.js b/src/utils/vfs.js index 67998bf..9c6d7fc 100644 --- a/src/utils/vfs.js +++ b/src/utils/vfs.js @@ -42,17 +42,6 @@ const errorCodes = { EACCES: 401 }; -/** - * A map of data types - */ -const typeMap = { - i: str => parseInt(str, 10), - s: str => str, - b: str => str === 'true', - u: str => undefined, - n: str => null -}; - /** * Gets prefix of a VFS path */ @@ -185,35 +174,18 @@ const mountpointResolver = core => async (path) => { /* * Assembles a given object query */ -const assembleQueryData = (object) => { - const assembled = {}; - const keys = Object.keys(object); - - for (let i = 0; i < keys.length; i++) { - const key = keys[i]; - const dots = key.split('.'); - const type = dots[dots.length - 1]; - dots.pop(); - - let last = assembled; - let parent = null; - for (let j = 0; j < dots.length; j++) { - const dot = dots[j]; - if (j >= dots.length - 1) { - if (!/^\d+$/.test(dot) && Array.isArray(last)) { - last = Object.fromEntries(last.map((value, i) => [i, value])); - parent[dots[j - 1]] = last; - } - last[dot] = typeMap[type](object[key]); - } else { - last[dot] = last[dot] || (/^\d+$/.test(dots[j + 1]) ? [] : {}); +const assembleQueryData = (data) => { + const entries = Object + .entries(data) + .map(([k, v]) => { + try { + return [k, JSON.parse(v)]; + } catch (e) { + return [k, v]; } + }); - parent = last; - last = last[dot]; - } - } - return assembled; + return Object.fromEntries(entries); }; /*