Skip to content

Instantly share code, notes, and snippets.

@suhaotian
Last active July 9, 2024 09:15
Show Gist options
  • Save suhaotian/c152e3922b9c37bb630612e6d3fd47ab to your computer and use it in GitHub Desktop.
Save suhaotian/c152e3922b9c37bb630612e6d3fd47ab to your computer and use it in GitHub Desktop.
Lightweight `qs.stringify` implementation
/** Ref: https://github.com/suhaotian/xior/blob/main/src/utils.ts#L8 */
export function encodeParams<T = any>(
params: T,
encodeURI = true,
parentKey: string | null = null,
options?: {
allowDots?: boolean;
serializeDate?: (value: Date) => string;
arrayFormat?: 'indices' | 'repeat' | 'brackets';
}
): string {
if (params === undefined || params === null) return '';
const encodedParams = [];
const encodeURIFn = encodeURI ? encodeURIComponent : (v: string) => v;
const paramsIsArray = Array.isArray(params);
const getKey = (key: string) => {
if (options?.allowDots && !paramsIsArray) return `.${key}`;
if (paramsIsArray) {
if (options?.arrayFormat === 'brackets') {
return `[]`;
} else if (options?.arrayFormat === 'repeat') {
return ``;
}
}
return `[${key}]`;
};
for (const key in params) {
if (Object.prototype.hasOwnProperty.call(params, key)) {
let value = (params as any)[key];
if (value !== undefinedValue) {
const encodedKey = parentKey ? `${parentKey}${getKey(key)}` : (key as string);
if (value instanceof Date) {
value = options?.serializeDate ? options?.serializeDate(value) : value.toISOString();
}
if (typeof value === 'object') {
// If the value is an object or array, recursively encode its contents
const result = encodeParams(value, encodeURI, encodedKey, options);
if (result !== '') encodedParams.push(result);
} else {
// Otherwise, encode the key-value pair
encodedParams.push(`${encodeURIFn(encodedKey)}=${encodeURIFn(value)}`);
}
}
}
}
return encodedParams.join('&');
}
@suhaotian
Copy link
Author

Usage:

const query = {a: 1, b: [1, 2, 3], d: new Date()};
const result = encodeParams(query, true, null, {
  allowDots: false,
  arrayFormat: 'indices',
  serializeDate: d => d.toISOString()
})

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment