UNPKG

unstorage-driver-query-string

Version:

Query string driver for unstorage - store state in URL parameters

163 lines (162 loc) 4.12 kB
import g from "validator"; import I from "tiny-invariant"; import d from "qs"; import { get as h, isPlainObject as D, set as y, keys as S, omit as m, has as w } from "lodash"; class u extends Error { cause; constructor(n, r) { super(n), this.name = "QueryStringDriverError", this.cause = r; } } function v(e) { const { url: n } = e; let r = null; return { getUrl: () => { if (n) { if (r) return r; if (!g.isURL(n) && (typeof window > "u" || !window.location)) throw new u("Cannot resolve relative URL in non-browser environment"); try { return g.isURL(n) ? r = new URL(n) : r = new URL(n, window.location.origin), I(r, "Failed to create URL"), r; } catch (t) { const o = t instanceof Error ? t.message : "Unknown error"; throw new u(`Invalid URL: ${n} (${o})`, t); } } if (typeof window < "u") return r || new URL(window.location.href); throw new u("URL is required in non-browser environment"); }, updateInternalUrl: (t) => { (n || typeof window < "u") && (r = t); } }; } function p(e) { return d.parse(e, { depth: 10, parseArrays: !0 }); } function R(e) { return D(e); } function L(e) { return { getCurrentData: (r = "") => { const a = e.getUrl().search.slice(1); if (!a) return {}; const t = p(a); if (!r) return t; const o = h(t, r); return R(o) ? o : {}; } }; } function b(e) { return d.stringify(e, { encode: !0, addQueryPrefix: !1, arrayFormat: "brackets" }); } function C(e, n) { const { base: r = "", updateHistory: i = !0, historyMethod: a = "pushState", maxUrlLength: t = 2e3 } = n; return (o) => { const s = e.getUrl(), c = new URL(s); let l; if (r) { const U = p(s.search.slice(1)); l = y({ ...U }, r, o); } else l = o; const f = b(l); if (c.search = f ? `?${f}` : "", c.href.length > t) { console.warn(`URL length (${c.href.length}) exceeds maximum allowed (${t})`); return; } e.updateInternalUrl(c), !n.url && typeof window < "u" && i && (a === "pushState" ? window.history.pushState(null, "", c.href) : window.history.replaceState(null, "", c.href)); }; } function _(e) { return e === null || typeof e == "string" || typeof e == "number" || typeof e == "boolean" || typeof e == "object"; } function $(e, n, r) { const i = { hasItem: (a, t) => { try { return w(e.getCurrentData(r), a); } catch { return !1; } }, getItem: (a, t) => { try { const o = e.getCurrentData(r), s = w(o, a) ? h(o, a, null) : null; return _(s) ? s : null; } catch { return null; } }, getItemRaw: (a, t) => { const o = i.getItem(a, t); return o === null ? null : String(o); }, setItem: (a, t, o) => { try { const s = e.getCurrentData(r), c = t == null ? m(s, a) : y({ ...s }, a, t); return n(c), Promise.resolve(); } catch (s) { throw new u(`Failed to set item: ${String(s)}`, s); } }, removeItem: (a, t) => { try { const o = e.getCurrentData(r); return n(m(o, a)), Promise.resolve(); } catch (o) { throw new u(`Failed to remove item: ${String(o)}`, o); } }, getKeys: (a, t) => { try { return S(e.getCurrentData(r)); } catch { return []; } }, clear: (a, t) => { try { return n({}), Promise.resolve(); } catch (o) { throw new u(`Failed to clear storage: ${String(o)}`, o); } } }; return i; } function q(e, n, r) { const { base: i = "" } = r, a = C(n, r), t = $(e, a, i); return { hasItem: t.hasItem, getItem: t.getItem, getItemRaw: t.getItemRaw, setItem: t.setItem, removeItem: t.removeItem, getKeys: t.getKeys, clear: t.clear, dispose: () => Promise.resolve() }; } function x(e = {}) { const n = v(e), r = L(n), i = q(r, n, e); return { name: "query-string", options: e, ...i }; } export { x as createQueryStringDriver };