🚀 Big News: Socket Acquires Coana to Bring Reachability Analysis to Every Appsec Team.Learn more →

nested-query-params

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

nested-query-params - npm Package Compare versions

Comparing version

to
1.1.1

@@ -14,28 +14,6 @@ /**

*/
declare type MaybeArray<T> = T | Array<MaybeArray<T>>;
export declare type SearchParamKey = string;
export declare type SearchParamVal = MaybeArray<SearchParams | string>;
export declare type SearchParam = [SearchParamKey, SearchParamVal];
export declare type SearchParams = {
[key: SearchParamKey]: SearchParamVal;
};
export declare enum SearchParamPathComponentKind {
Map = 0,
List = 1
}
export declare type SearchParamPathComponent = [SearchParamPathComponentKind.Map, string] | [SearchParamPathComponentKind.List];
/**
* Expands a search params into structural types. Supported types are Arrays,
* Objects and basic value types. Heavily inspired by
* {@link https://github.com/rack/rack/blob/bad8fe37c8867596855dcd0b3fe3030acc6b8621/lib/rack/query_parser.rb#L63-L68|Rack's nested query parser}.
*
* @example
* // returns { one: { two: "3" } };
* parseQuery("?one[two]=3")
*/
export declare function parseQuery(query: string): SearchParams;
/**
* Parses nested search parameters keys into their individual path components.
*/
export declare function parseQueryParamKey(key: SearchParamKey): SearchParamPathComponent[];
export {};
export * from "./parse";
export * from "./print";
export * from "./types";
export { printQuery as print } from "./print";
export { parseQuery as parse } from "./parse";

@@ -15,143 +15,25 @@ "use strict";

*/
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.parseQueryParamKey = exports.parseQuery = exports.SearchParamPathComponentKind = void 0;
const util_1 = require("./util");
var SearchParamPathComponentKind;
(function (SearchParamPathComponentKind) {
SearchParamPathComponentKind[SearchParamPathComponentKind["Map"] = 0] = "Map";
SearchParamPathComponentKind[SearchParamPathComponentKind["List"] = 1] = "List";
})(SearchParamPathComponentKind = exports.SearchParamPathComponentKind || (exports.SearchParamPathComponentKind = {}));
const logger = prepareConsole(console, "nested-query-params");
/**
* Expands a search params into structural types. Supported types are Arrays,
* Objects and basic value types. Heavily inspired by
* {@link https://github.com/rack/rack/blob/bad8fe37c8867596855dcd0b3fe3030acc6b8621/lib/rack/query_parser.rb#L63-L68|Rack's nested query parser}.
*
* @example
* // returns { one: { two: "3" } };
* parseQuery("?one[two]=3")
*/
function parseQuery(query) {
const pairs = (0, util_1.splitQuery)(query);
return pairs.reduce((acc, [key, value]) => {
const comps = parseQueryParamKey(key);
if (Array.isArray(value)) {
return value.reduce((acc, value) => applyNestedParam(acc, comps, value), acc);
}
return applyNestedParam(acc, comps, value);
}, {});
}
exports.parseQuery = parseQuery;
/**
* Parses nested search parameters keys into their individual path components.
*/
function parseQueryParamKey(key) {
if (key.trim() === "") {
return [];
}
let start;
if ((start = key.indexOf("[", 1)) === -1) {
return [[SearchParamPathComponentKind.Map, key]];
}
const head = key.slice(0, start);
const rest = key.slice(start);
return [
[SearchParamPathComponentKind.Map, head],
...parseQueryParamKeyComponents(rest),
];
}
exports.parseQueryParamKey = parseQueryParamKey;
/**
* Applies given key value pair to search parameters.
*/
function applyNestedParam(params, comps, value) {
const [head] = comps;
if (!head) {
return params;
}
if (head[0] !== SearchParamPathComponentKind.Map) {
logger.warn("#applyNestedParam", "cannot apply list op to root");
return params;
}
return applyComponent(params, comps, value);
}
function applyComponent(params, comps, value) {
const log = prepareConsole(logger, "#applyComponent");
const [head, ...rest] = comps;
if (!head) {
return params;
}
if (head[0] === SearchParamPathComponentKind.Map) {
if (typeof params !== "object" || Array.isArray(params)) {
params = {};
}
if (rest.length === 0) {
return {
...params,
[head[1]]: Array.isArray(value) ? value[value.length - 1] : value,
};
}
const key = head[1];
return {
...params,
[head[1]]: applyComponent(params[key], rest, value),
};
}
if (head[0] === SearchParamPathComponentKind.List) {
if (!Array.isArray(params)) {
params = [];
}
if (rest.length === 0) {
return [
...params,
...(Array.isArray(value) ? value : [value]),
];
}
const [peek] = rest;
if (peek[0] !== SearchParamPathComponentKind.Map) {
log.warn("expected map");
return params;
}
const last = params[params.length - 1] || undefined;
if (typeof last === "object" && !Array.isArray(last) && !last[peek[1]]) {
const next = applyNestedParam(last, rest, value);
return [...params.slice(0, -1), next];
}
else if (Array.isArray(last)) {
log.warn("nested arrays are not supported");
}
else if (last && typeof last !== "object") {
log.warn("expected map");
}
// add value to list if list was previously empty or the given key is
// already in the map.
const next = applyNestedParam({}, rest, value);
return [...params, next];
}
return params;
}
function parseQueryParamKeyComponents(key) {
// list
if (key.startsWith("[]")) {
return [
[SearchParamPathComponentKind.List],
...parseQueryParamKeyComponents(key.slice(2)),
];
}
// map
let start;
if (key.startsWith("[") && (start = key.indexOf("]", 1)) !== -1) {
return [
[SearchParamPathComponentKind.Map, key.slice(1, start)],
...parseQueryParamKeyComponents(key.slice(start + 1)),
];
}
return [];
}
function prepareConsole(parent, ...init) {
return ["info", "error", "warn", "debug"].reduce((acc, method) => ({
[method]: (...msgs) => parent[method](...init, ...msgs),
...acc,
}), {});
}
exports.parse = exports.print = void 0;
__exportStar(require("./parse"), exports);
__exportStar(require("./print"), exports);
__exportStar(require("./types"), exports);
var print_1 = require("./print");
Object.defineProperty(exports, "print", { enumerable: true, get: function () { return print_1.printQuery; } });
var parse_1 = require("./parse");
Object.defineProperty(exports, "parse", { enumerable: true, get: function () { return parse_1.parseQuery; } });
//# sourceMappingURL=main.js.map
{
"name": "nested-query-params",
"version": "1.0.1",
"version": "1.1.1",
"description": "Rack like parsing of nested query parameters",
"scripts": {
"prepublish": "npm run build",
"build": "rm -r lib && npx tsc -p ./",

@@ -7,0 +8,0 @@ "format": "prettier --write .",

@@ -1,21 +0,7 @@

<p align="center">
<img src="./logo.svg" width="120px"/>
</p>
<header align="center">
<p align="center"><img align="center" src="./logo.svg" width="200px"/></p>
<h3 align="center">Nested Query Params</h3>
<p align="center">A TypeScript implementation of Rack's query string parser.</p>
</header>
<h3 align="center">Nested Query Params</h3>
<p align="center">
A TypeScript implementation of Rack's query string parser.
</p>
<p align="center">
<a href="#">
<img src="https://img.shields.io/github/commit-activity/m/jamesdphillips/nested-query-params.svg?style=flat" />
</a>
<a href="https://github.com/jamesdphillips/nested-query-params/blob/main/LICENSE">
<img src="https://img.shields.io/github/license/jamesdphillips/nested-query-params.svg?style=flat" />
</a>
<a href="https://circleci.com/gh/jamesdphillips/nested-query-params/tree/main">
<img src="https://circleci.com/gh/jamesdphillips/nested-query-params/tree/main.svg?style=svg" />
</a>
</p>
## Overview

@@ -38,3 +24,3 @@

```typescript
import { parseQuery } from "nested-query-params";
import { parseQuery, printQuery } from "nested-query-params";

@@ -52,4 +38,12 @@ // maps

console.debug(mixed); // prints { bar: "baz", foo: { bar: ["baz", "42"] } }
// print
const simple = parseQuery("?foo[bar]=baz");
console.debug(printQuery(simple)); // prints "?foo[bar]=baz"
// print valid
const edited = { ...simple, foo: "bar" };
console.debug(printQuery(edited)); // prints "?foo=bar"
```
[query string parser]: https://github.com/rack/rack/blob/bad8fe37c8867596855dcd0b3fe3030acc6b8621/lib/rack/query_parser.rb#L63
[query string parser]: https://github.com/rack/rack/blob/bad8fe37c8867596855dcd0b3fe3030acc6b8621/lib/rack/query_parser.rb#L63

Sorry, the diff of this file is not supported yet