UNPKG

frappe-sdk-react-i4z

Version:
747 lines (746 loc) 22 kB
import oe, { createContext as ce, useState as y, useEffect as W, useContext as ie, useCallback as _ } from "react"; import U from "swr"; var P = { exports: {} }, O = {}; /** * @license React * react-jsx-runtime.production.js * * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ var q; function le() { if (q) return O; q = 1; var c = Symbol.for("react.transitional.element"), r = Symbol.for("react.fragment"); function t(n, a, s) { var l = null; if (s !== void 0 && (l = "" + s), a.key !== void 0 && (l = "" + a.key), "key" in a) { s = {}; for (var i in a) i !== "key" && (s[i] = a[i]); } else s = a; return a = s.ref, { $$typeof: c, type: n, key: l, ref: a !== void 0 ? a : null, props: s }; } return O.Fragment = r, O.jsx = t, O.jsxs = t, O; } var D = {}; /** * @license React * react-jsx-runtime.development.js * * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ var z; function ue() { return z || (z = 1, process.env.NODE_ENV !== "production" && (function() { function c(e) { if (e == null) return null; if (typeof e == "function") return e.$$typeof === ne ? null : e.displayName || e.name || null; if (typeof e == "string") return e; switch (e) { case T: return "Fragment"; case X: return "Profiler"; case x: return "StrictMode"; case K: return "Suspense"; case ee: return "SuspenseList"; case re: return "Activity"; } if (typeof e == "object") switch (typeof e.tag == "number" && console.error( "Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue." ), e.$$typeof) { case g: return "Portal"; case B: return (e.displayName || "Context") + ".Provider"; case Q: return (e._context.displayName || "Context") + ".Consumer"; case Z: var u = e.render; return e = e.displayName, e || (e = u.displayName || u.name || "", e = e !== "" ? "ForwardRef(" + e + ")" : "ForwardRef"), e; case te: return u = e.displayName || null, u !== null ? u : c(e.type) || "Memo"; case F: u = e._payload, e = e._init; try { return c(e(u)); } catch { } } return null; } function r(e) { return "" + e; } function t(e) { try { r(e); var u = !1; } catch { u = !0; } if (u) { u = console; var m = u.error, w = typeof Symbol == "function" && Symbol.toStringTag && e[Symbol.toStringTag] || e.constructor.name || "Object"; return m.call( u, "The provided key is an unsupported type %s. This value must be coerced to a string before using it here.", w ), r(e); } } function n(e) { if (e === T) return "<>"; if (typeof e == "object" && e !== null && e.$$typeof === F) return "<...>"; try { var u = c(e); return u ? "<" + u + ">" : "<...>"; } catch { return "<...>"; } } function a() { var e = A.A; return e === null ? null : e.getOwner(); } function s() { return Error("react-stack-top-frame"); } function l(e) { if (L.call(e, "key")) { var u = Object.getOwnPropertyDescriptor(e, "key").get; if (u && u.isReactWarning) return !1; } return e.key !== void 0; } function i(e, u) { function m() { I || (I = !0, console.error( "%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)", u )); } m.isReactWarning = !0, Object.defineProperty(e, "key", { get: m, configurable: !0 }); } function o() { var e = c(this.type); return Y[e] || (Y[e] = !0, console.error( "Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release." )), e = this.props.ref, e !== void 0 ? e : null; } function d(e, u, m, w, S, R, $, j) { return m = R.ref, e = { $$typeof: E, type: e, key: u, props: R, _owner: S }, (m !== void 0 ? m : null) !== null ? Object.defineProperty(e, "ref", { enumerable: !1, get: o }) : Object.defineProperty(e, "ref", { enumerable: !1, value: null }), e._store = {}, Object.defineProperty(e._store, "validated", { configurable: !1, enumerable: !1, writable: !0, value: 0 }), Object.defineProperty(e, "_debugInfo", { configurable: !1, enumerable: !1, writable: !0, value: null }), Object.defineProperty(e, "_debugStack", { configurable: !1, enumerable: !1, writable: !0, value: $ }), Object.defineProperty(e, "_debugTask", { configurable: !1, enumerable: !1, writable: !0, value: j }), Object.freeze && (Object.freeze(e.props), Object.freeze(e)), e; } function p(e, u, m, w, S, R, $, j) { var b = u.children; if (b !== void 0) if (w) if (se(b)) { for (w = 0; w < b.length; w++) f(b[w]); Object.freeze && Object.freeze(b); } else console.error( "React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead." ); else f(b); if (L.call(u, "key")) { b = c(e); var v = Object.keys(u).filter(function(ae) { return ae !== "key"; }); w = 0 < v.length ? "{key: someKey, " + v.join(": ..., ") + ": ...}" : "{key: someKey}", M[b + w] || (v = 0 < v.length ? "{" + v.join(": ..., ") + ": ...}" : "{}", console.error( `A props object containing a "key" prop is being spread into JSX: let props = %s; <%s {...props} /> React keys must be passed directly to JSX without using spread: let props = %s; <%s key={someKey} {...props} />`, w, b, v, b ), M[b + w] = !0); } if (b = null, m !== void 0 && (t(m), b = "" + m), l(u) && (t(u.key), b = "" + u.key), "key" in u) { m = {}; for (var N in u) N !== "key" && (m[N] = u[N]); } else m = u; return b && i( m, typeof e == "function" ? e.displayName || e.name || "Unknown" : e ), d( e, b, R, S, a(), m, $, j ); } function f(e) { typeof e == "object" && e !== null && e.$$typeof === E && e._store && (e._store.validated = 1); } var h = oe, E = Symbol.for("react.transitional.element"), g = Symbol.for("react.portal"), T = Symbol.for("react.fragment"), x = Symbol.for("react.strict_mode"), X = Symbol.for("react.profiler"), Q = Symbol.for("react.consumer"), B = Symbol.for("react.context"), Z = Symbol.for("react.forward_ref"), K = Symbol.for("react.suspense"), ee = Symbol.for("react.suspense_list"), te = Symbol.for("react.memo"), F = Symbol.for("react.lazy"), re = Symbol.for("react.activity"), ne = Symbol.for("react.client.reference"), A = h.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, L = Object.prototype.hasOwnProperty, se = Array.isArray, C = console.createTask ? console.createTask : function() { return null; }; h = { react_stack_bottom_frame: function(e) { return e(); } }; var I, Y = {}, J = h.react_stack_bottom_frame.bind( h, s )(), G = C(n(s)), M = {}; D.Fragment = T, D.jsx = function(e, u, m, w, S) { var R = 1e4 > A.recentlyCreatedOwnerStacks++; return p( e, u, m, !1, w, S, R ? Error("react-stack-top-frame") : J, R ? C(n(e)) : G ); }, D.jsxs = function(e, u, m, w, S) { var R = 1e4 > A.recentlyCreatedOwnerStacks++; return p( e, u, m, !0, w, S, R ? Error("react-stack-top-frame") : J, R ? C(n(e)) : G ); }; })()), D; } var H; function de() { return H || (H = 1, process.env.NODE_ENV === "production" ? P.exports = le() : P.exports = ue()), P.exports; } var fe = de(); class pe { baseUrl; token; useToken; constructor(r = {}) { this.baseUrl = r.url || (typeof window < "u" ? window.location.origin : ""), this.useToken = r.useToken || !1, this.token = r.tokenParams?.token; } getHeaders() { const r = { "Content-Type": "application/json", Accept: "application/json" }; return this.useToken && this.token && (r.Authorization = `token ${this.token}`), r; } async handleResponse(r) { const t = await r.json(); if (!r.ok) throw { message: t.message || t.exc || "An error occurred", exception: t.exception, exc_type: t.exc_type, indicator: t.indicator }; return t.message || t; } async call(r) { const { method: t, args: n = {}, httpMethod: a = "POST" } = r, s = `${this.baseUrl}/api/method/${t}`; if (a === "GET") { const i = new URLSearchParams(); Object.entries(n).forEach(([p, f]) => { i.append(p, JSON.stringify(f)); }); const o = i.toString() ? `${s}?${i.toString()}` : s, d = await fetch(o, { method: "GET", headers: this.getHeaders(), credentials: this.useToken ? "omit" : "include" }); return this.handleResponse(d); } const l = await fetch(s, { method: "POST", headers: this.getHeaders(), credentials: this.useToken ? "omit" : "include", body: JSON.stringify(n) }); return this.handleResponse(l); } async login(r, t) { const n = await fetch(`${this.baseUrl}/api/method/login`, { method: "POST", headers: { "Content-Type": "application/json", Accept: "application/json" }, credentials: "include", body: JSON.stringify({ usr: r, pwd: t }) }); return this.handleResponse(n); } async logout() { const r = await fetch(`${this.baseUrl}/api/method/logout`, { method: "POST", headers: this.getHeaders(), credentials: this.useToken ? "omit" : "include" }); await this.handleResponse(r); } async getCurrentUser() { return this.call({ method: "frappe.auth.get_logged_user" }); } async getDoc(r, t) { const n = await fetch( `${this.baseUrl}/api/resource/${r}/${encodeURIComponent(t)}`, { method: "GET", headers: this.getHeaders(), credentials: this.useToken ? "omit" : "include" } ); return (await this.handleResponse(n)).data; } async getDocList(r) { const { doctype: t, fields: n = ["*"], filters: a = {}, or_filters: s, order_by: l, limit_start: i = 0, limit_page_length: o = 20, group_by: d, parent: p } = r, f = new URLSearchParams({ fields: JSON.stringify(n), filters: JSON.stringify(a), limit_start: i.toString(), limit_page_length: o.toString() }); s && f.append("or_filters", JSON.stringify(s)), l && f.append("order_by", l), d && f.append("group_by", d), p && f.append("parent", p); const h = await fetch(`${this.baseUrl}/api/resource/${t}?${f.toString()}`, { method: "GET", headers: this.getHeaders(), credentials: this.useToken ? "omit" : "include" }); return (await this.handleResponse(h)).data; } async getDocCount(r) { const { doctype: t, filters: n = {}, cache: a = !0 } = r, s = new URLSearchParams({ filters: JSON.stringify(n), cache: a.toString() }), l = await fetch(`${this.baseUrl}/api/resource/${t}?${s.toString()}&limit_page_length=1&fields=["name"]`, { method: "GET", headers: this.getHeaders(), credentials: this.useToken ? "omit" : "include" }); return (await this.handleResponse(l)).count || 0; } async createDoc(r) { const { doctype: t, doc: n } = r, a = await fetch(`${this.baseUrl}/api/resource/${t}`, { method: "POST", headers: this.getHeaders(), credentials: this.useToken ? "omit" : "include", body: JSON.stringify(n) }); return (await this.handleResponse(a)).data; } async updateDoc(r) { const { doctype: t, name: n, doc: a } = r, s = await fetch(`${this.baseUrl}/api/resource/${t}/${encodeURIComponent(n)}`, { method: "PUT", headers: this.getHeaders(), credentials: this.useToken ? "omit" : "include", body: JSON.stringify(a) }); return (await this.handleResponse(s)).data; } async deleteDoc(r) { const { doctype: t, name: n } = r, a = await fetch(`${this.baseUrl}/api/resource/${t}/${encodeURIComponent(n)}`, { method: "DELETE", headers: this.getHeaders(), credentials: this.useToken ? "omit" : "include" }); await this.handleResponse(a); } async uploadFile(r) { const { file: t, is_private: n = !1, doctype: a, docname: s, fieldname: l } = r, i = new FormData(); i.append("file", t), i.append("is_private", n.toString()), a && i.append("doctype", a), s && i.append("docname", s), l && i.append("fieldname", l); const o = {}; this.useToken && this.token && (o.Authorization = `token ${this.token}`); const d = await fetch(`${this.baseUrl}/api/method/upload_file`, { method: "POST", headers: o, credentials: this.useToken ? "omit" : "include", body: i }); return this.handleResponse(d); } async searchLink(r, t, n = {}) { return this.call({ method: "frappe.desk.search.search_link", args: { doctype: r, txt: t, filters: n } }); } } const V = ce(null), ge = ({ children: c, config: r = {} }) => { const [t] = y(() => new pe(r)), [n, a] = y(null), [s, l] = y(!1); W(() => { const o = async () => { try { const d = await t.getCurrentUser(); a(d), l(!0); } catch { a(null), l(!1); } }; r.useToken ? r.tokenParams?.token && l(!0) : o(); }, [t, r.useToken, r.tokenParams?.token]); const i = { url: t.baseUrl, call: async (o) => t.call(o), db: { getDoc: async (o, d) => t.getDoc(o, d), getDocList: async (o) => t.getDocList(o), getDocCount: async (o) => t.getDocCount(o), createDoc: async (o) => t.createDoc(o), updateDoc: async (o) => t.updateDoc(o), deleteDoc: async (o) => t.deleteDoc(o) }, auth: { login: async (o, d) => { const p = await t.login(o, d); try { const f = await t.getCurrentUser(); a(f), l(!0); } catch (f) { console.error("Failed to get user after login:", f); } return p; }, logout: async () => { await t.logout(), a(null), l(!1); }, getUser: async () => { const o = await t.getCurrentUser(); return a(o), o; }, currentUser: n, isLoggedIn: s }, file: { upload: async (o) => t.uploadFile(o) } }; return /* @__PURE__ */ fe.jsx(V.Provider, { value: i, children: c }); }, k = () => { const c = ie(V); if (!c) throw new Error("useFrappeContext must be used within a FrappeProvider"); return c; }, ye = () => { const { auth: c } = k(); return c; }, Ee = (c, r, t = "POST") => { const { call: n } = k(), [a, s] = y(null), [l, i] = y(null), [o, d] = y(!1), p = _( async (h = {}) => { if (!c && !h.method) throw new Error("Method is required"); const E = { method: h.method || c, args: { ...r, ...h.args }, httpMethod: h.httpMethod || t }; d(!0), i(null); try { const g = await n(E); return s(g), g; } catch (g) { const T = g instanceof Error ? g : new Error(String(g)); throw i(T), T; } finally { d(!1); } }, [n, c, r, t] ), f = _(() => { s(null), i(null), d(!1); }, []); return { call: p, data: a, error: l, loading: o, reset: f }; }, we = (c) => { const { db: r } = k(), [t, n] = y(null), [a, s] = y(null), [l, i] = y(!1), o = _( async (p) => { if (!c) throw new Error("Doctype is required"); const f = { doctype: c, doc: p }; i(!0), s(null); try { const h = await r.createDoc(f); return n(h), h; } catch (h) { const E = h instanceof Error ? h : new Error(String(h)); throw s(E), E; } finally { i(!1); } }, [r, c] ), d = _(() => { n(null), s(null), i(!1); }, []); return { createDoc: o, data: t, error: a, loading: l, reset: d }; }, be = (c) => { const { db: r } = k(), [t, n] = y(null), [a, s] = y(!1), l = _( async (o) => { if (!c) throw new Error("Doctype is required"); const d = { doctype: c, name: o }; s(!0), n(null); try { await r.deleteDoc(d); } catch (p) { const f = p instanceof Error ? p : new Error(String(p)); throw n(f), f; } finally { s(!1); } }, [r, c] ), i = _(() => { n(null), s(!1); }, []); return { deleteDoc: l, error: t, loading: a, reset: i }; }, Te = () => { const { file: c } = k(), [r, t] = y(null), [n, a] = y(null), [s, l] = y(!1), [i, o] = y(null), d = _( async (f, h = {}) => { const E = { file: f, is_private: !1, ...h }; l(!0), a(null), o({ loaded: 0, total: f.size, percentage: 0 }); try { const g = await c.upload(E); return t(g), o({ loaded: f.size, total: f.size, percentage: 100 }), g; } catch (g) { const T = g instanceof Error ? g : new Error(String(g)); throw a(T), T; } finally { l(!1); } }, [c] ), p = _(() => { t(null), a(null), l(!1), o(null); }, []); return { upload: d, data: r, error: n, loading: s, progress: i, reset: p }; }, _e = (c, r, t = {}) => { const { db: n } = k(), a = c && r ? `${c}/${r}` : null, { data: s, error: l, mutate: i, isValidating: o, isLoading: d } = U( a, a ? async () => n.getDoc(c, r) : null, { revalidateIfStale: !0, revalidateOnFocus: !1, revalidateOnReconnect: !0, ...t } ); return { data: s, error: l, mutate: i, isValidating: o, isLoading: d }; }, Re = (c, r = {}) => { const { db: t } = k(), n = c?.doctype ? JSON.stringify({ ...c, type: "count" }) : null, { data: a, error: s, mutate: l, isValidating: i, isLoading: o } = U( n, n ? async () => t.getDocCount(c) : null, { revalidateIfStale: !0, revalidateOnFocus: !1, revalidateOnReconnect: !0, ...r } ); return { data: a || 0, error: s, mutate: l, isValidating: i, isLoading: o }; }, ke = (c, r = {}) => { const { db: t } = k(), n = c?.doctype ? JSON.stringify(c) : null, { data: a, error: s, mutate: l, isValidating: i, isLoading: o } = U( n, n ? async () => t.getDocList(c) : null, { revalidateIfStale: !0, revalidateOnFocus: !1, revalidateOnReconnect: !0, ...r } ); return { data: a || [], error: s, mutate: l, isValidating: i, isLoading: o }; }, Se = (c, r = {}, t = 300) => { const { call: n } = k(), [a, s] = y([]), [l, i] = y(null), [o, d] = y(!1), [p, f] = y(""), h = _((g) => { f(g); }, []); W(() => { if (!p.trim() || !c) { s([]); return; } const g = setTimeout(async () => { d(!0), i(null); try { const T = await n({ method: "frappe.desk.search.search_link", args: { doctype: c, txt: p, filters: r } }); s(T || []); } catch (T) { const x = T instanceof Error ? T : new Error(String(T)); i(x), s([]); } finally { d(!1); } }, t); return () => clearTimeout(g); }, [p, c, r, t, n]); const E = _(() => { s([]), i(null), d(!1), f(""); }, []); return { search: h, data: a, error: l, loading: o, reset: E }; }, ve = (c) => { const { db: r } = k(), [t, n] = y(null), [a, s] = y(null), [l, i] = y(!1), o = _( async (p, f) => { if (!c) throw new Error("Doctype is required"); const h = { doctype: c, name: p, doc: f }; i(!0), s(null); try { const E = await r.updateDoc(h); return n(E), E; } catch (E) { const g = E instanceof Error ? E : new Error(String(E)); throw s(g), g; } finally { i(!1); } }, [r, c] ), d = _(() => { n(null), s(null), i(!1); }, []); return { updateDoc: o, data: t, error: a, loading: l, reset: d }; }; export { pe as FrappeClient, ge as FrappeProvider, ye as useFrappeAuth, Ee as useFrappeCall, k as useFrappeContext, we as useFrappeCreateDoc, be as useFrappeDeleteDoc, Te as useFrappeFileUpload, _e as useFrappeGetDoc, Re as useFrappeGetDocCount, ke as useFrappeGetDocList, Se as useFrappeSearch, ve as useFrappeUpdateDoc };