import { isSerializableObject, Serializable, SerializableArray, SerializableObject, } from '../types'; function stringifyString(string: string, prefix?: string): string { if (!prefix) throw new TypeError('stringify expects an object'); return `${prefix}=${encodeURIComponent(string)}`; } function stringifyArray(array: SerializableArray, prefix?: string): string { if (!prefix) throw new TypeError('stringify expects an object'); const ret: string[] = []; for (let i = 0, l = array.length; i < l; i += 1) { ret.push(stringify(array[i], `${prefix}[${i}]`)); // eslint-disable-line no-use-before-define } return ret.join('&'); } function stringifyObject(object: SerializableObject, prefix?: string): string { const ret: string[] = []; Object.keys(object).forEach((key) => { if (Object.prototype.hasOwnProperty.call(object, key)) { if (key === '') return; if (object[key] == null) { ret.push(prefix ? `${prefix}[${encodeURIComponent(key)}]=` : `${encodeURIComponent(key)}=`); } else { ret.push(stringify(object[key], prefix // eslint-disable-line no-use-before-define ? `${prefix}[${encodeURIComponent(key)}]` : encodeURIComponent(key))); } } }); return ret.join('&'); } export default function stringify(object: Serializable, prefix?: string): string { if (object === null) { return `${prefix || ''}=${encodeURIComponent(String(object))}`; } if (Array.isArray(object)) { return stringifyArray(object, prefix); } if (isSerializableObject(object)) { return stringifyObject(object, prefix); } if (typeof object === 'string') { return stringifyString(object, prefix); } return `${prefix || ''}=${encodeURIComponent(String(object))}`; }