unstorage-driver-query-string
Version:
Query string driver for unstorage - store state in URL parameters
163 lines (162 loc) • 4.12 kB
JavaScript
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
};