Skip to content

Commit

Permalink
feat(utils): added util to parse query
Browse files Browse the repository at this point in the history
  • Loading branch information
kedrzu committed Aug 25, 2023
1 parent 63f0f0d commit 61598bc
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 4 deletions.
5 changes: 4 additions & 1 deletion packages/utils/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ export * from './array/forEachParalell.js';
export * from './string/formatWith.js';
export * from './string/isDigit.js';

export * from './url/stringifyQuery.js';
export * from './url/parseQuery.js';
export * from './url/queryTypes.js';

export * from './assert.js';
export * from './cachedGetter.js';
export * from './cachedProp.js';
Expand All @@ -40,4 +44,3 @@ export * from './timeout.js';
export * from './writable.js';
export * from './promiseAll.js';
export * from './getTopLevelDomain.js';
export * from './stringifyQuery.js';
56 changes: 56 additions & 0 deletions packages/utils/src/url/parseQuery.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { QueryParams, QueryParamsSimple } from './queryTypes.js';

export function parseQuery(querystring: string | null | undefined): QueryParamsSimple;
export function parseQuery(
querystring: string | null | undefined,
options: { multiple: false },
): QueryParamsSimple;
export function parseQuery(
querystring: string | null | undefined,
options: { multiple: true },
): QueryParams;
export function parseQuery(
querystring: string | null | undefined,
options?: { multiple: boolean },
): QueryParams {
const query: QueryParams = {};
const multiple = options?.multiple || false;

if (!querystring) {
return query;
}

if (querystring.startsWith('?')) {
querystring = querystring.slice(1);
}

for (const item of querystring.split('&')) {
const [rawKey, rawValue] = item.split('=');
const key = decodeURIComponent(rawKey);
const value = decodeURIComponent(rawValue);

// Sometimes a query string can have multiple values
// for the same key, so to factor that case in, you
// could collect an array of values for the same key
let entry = query[key];

if (entry === undefined) {
query[key] = value;
continue;
}

if (!multiple) {
// Allows only for a single value per key
continue;
}

// If the value for this key was not previously an array, update it
if (!Array.isArray(entry)) {
query[key] = entry = [entry];
}

entry.push(value);
}

return query;
}
4 changes: 4 additions & 0 deletions packages/utils/src/url/queryTypes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
type QueryParamValue = string | null;
export type QueryParam = QueryParamValue | QueryParamValue[];
export type QueryParams = Record<string, QueryParam | undefined>;
export type QueryParamsSimple = Record<string, string | undefined | null>;
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
type QueryParamValue = string | null;
export type QueryParam = QueryParamValue | QueryParamValue[];
export type QueryParams = Record<string, QueryParam | undefined>;
import { QueryParams } from './queryTypes.js';

export function stringifyQuery(params: QueryParams) {
let qs = '';
Expand Down

0 comments on commit 61598bc

Please sign in to comment.