@bgscore/react-core 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/dist/index.cjs +1 -0
- package/dist/index.d.cts +488 -0
- package/dist/index.d.ts +488 -0
- package/dist/index.js +1 -0
- package/package.json +58 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Andry Dharmawan
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the “Software”), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
|
13
|
+
all copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } async function _asyncOptionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = await fn(value); } else if (op === 'call' || op === 'optionalCall') { value = await fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }var _moment = require('moment'); var _moment2 = _interopRequireDefault(_moment);var _react = require('react'); var _react2 = _interopRequireDefault(_react);function $e(){let e=()=>Math.random()*16%16|0;return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,t=>(t==="x"?e():e()&3|8).toString(16))}function je(e,t){try{return JSON.stringify(e)!==JSON.stringify(t)}catch (e2){return!1}}var Ve=e=>(Object.keys(e).forEach(t=>{e[t]===void 0&&(e[t]=null)}),e);function ze(e,t){let n=!1;return e&&typeof e=="object"&&Array.isArray(e)&&(typeof t=="number"?e.length>t&&(n=!0):n=!0),n}function q(e){return!(e==null||typeof e=="string"&&e.trim()===""||Array.isArray(e)&&e.length===0||typeof e=="object"&&e!==null&&!Array.isArray(e)&&Object.keys(e).length===0)}var X={camelCase:(e="")=>(e=e.split(".").map(t=>(t=t.charAt(0).toUpperCase()+t.slice(1),t)).join(" "),e=e.replace(/([a-z0-9])([A-Z])/g,"$1 $2"),e.charAt(0).toUpperCase()+e.slice(1)),snackCase:(e="")=>{let n=e.replace(/_([a-z])/g,(o,a)=>a.toUpperCase()).replace(/([A-Z])/g," $1");return n=n.charAt(0).toUpperCase()+n.slice(1),n},changeAll:(e="",t=!1)=>{let n="";try{e=_optionalChain([e, 'optionalAccess', _2 => _2.split, 'call', _3 => _3("."), 'access', _4 => _4[_optionalChain([e, 'optionalAccess', _5 => _5.split, 'call', _6 => _6("."), 'optionalAccess', _7 => _7.length])-1]]),e=_optionalChain([e, 'optionalAccess', _8 => _8.split, 'call', _9 => _9("[]"), 'access', _10 => _10[_optionalChain([e, 'optionalAccess', _11 => _11.split, 'call', _12 => _12("[]"), 'optionalAccess', _13 => _13.length])-1]]),n=X.snackCase(X.camelCase(e)),t&&(n=_optionalChain([n, 'optionalAccess', _14 => _14.split, 'call', _15 => _15(" "), 'optionalAccess', _16 => _16.map, 'call', _17 => _17(o=>_optionalChain([o, 'optionalAccess', _18 => _18.length])<=3?_optionalChain([o, 'optionalAccess', _19 => _19.toUpperCase, 'call', _20 => _20()]):o), 'optionalAccess', _21 => _21.join, 'call', _22 => _22(" ")]))}catch (e3){}return _optionalChain([n, 'optionalAccess', _23 => _23.trim, 'call', _24 => _24()])}};function Je(e,t){return typeof e=="function"?e(t):e}var O=(e,t,n="")=>{if(!e)return n;if(e.hasOwnProperty(t))return e[t];let o=t.replace(/\[(\d+)\]/g,".$1").split("."),a=e;for(let r of o){if(a==null)return n;a=a[r]}return a===void 0?n:a},We= exports.sorting ={desc:(e,t)=>(e||(e=[]),e.sort((n,o)=>{if(t){let a=O(n,t)?O(n,t):"",r=O(o,t)?O(n,t):"";return a<r?1:-1}else return n<o?1:-1})),asc:(e,t)=>(e||(e=[]),e.sort((n,o)=>{if(t){let a=O(n,t)?O(n,t):"",r=O(o,t)?O(o,t):"";return a>r?1:-1}else return n>o?1:-1}))},Ge= exports.summary =(e,t)=>{Array.isArray(e)||(e=[]);let n=[];return n=e.map(o=>Number(t?O(o,t)||0:o||0)),n.reduce((o,a)=>(o||0)+(a||0),0)||0};function Xe(e){try{return e&&JSON.parse(JSON.stringify(e))}catch (e4){return e}}function me(e){let t=new WeakSet;return _nullishCoalesce(JSON.stringify(e,function(n,o){return o!==null&&typeof o=="object"?t.has(o)?void 0:(t.add(o),Object.keys(o).sort().reduce((a,r)=>(a[r]=o[r],a),{})):o}), () => (""))}function _(e,t){return me([_nullishCoalesce(t, () => ("undefined")),_nullishCoalesce(e, () => ("undefined"))])}var _jsxruntime = require('react/jsx-runtime');var Z=_react.createContext.call(void 0, void 0);function N(){let e=_react.useContext.call(void 0, Z);return e||{}}var ge=({children:e,value:t})=>{let n={...t};return _jsxruntime.jsx.call(void 0, Z.Provider,{value:n,children:e})};var _aes = require('crypto-js/aes'); var _aes2 = _interopRequireDefault(_aes);var _pbkdf2 = require('crypto-js/pbkdf2'); var _pbkdf22 = _interopRequireDefault(_pbkdf2);var _encutf8 = require('crypto-js/enc-utf8'); var _encutf82 = _interopRequireDefault(_encutf8);var _encbase64 = require('crypto-js/enc-base64'); var _encbase642 = _interopRequireDefault(_encbase64);var _libtypedarrays = require('crypto-js/lib-typedarrays'); var _libtypedarrays2 = _interopRequireDefault(_libtypedarrays);function I(e,t){let n=_libtypedarrays2.default.random(16),o=_libtypedarrays2.default.random(16),a=_pbkdf22.default.call(void 0, t,n,{keySize:256/32,iterations:1e3}),r=_aes2.default.encrypt(JSON.stringify(e),a,{iv:o}).toString();return{salt:n.toString(_encbase642.default),iv:o.toString(_encbase642.default),encrypted:r}}function H(e,t){let{salt:n,iv:o,encrypted:a}=e,r=_pbkdf22.default.call(void 0, t,_encbase642.default.parse(n),{keySize:256/32,iterations:1e3}),i=_aes2.default.decrypt(a,r,{iv:_encbase642.default.parse(o)}).toString(_encutf82.default);return JSON.parse(i)}function te(e,t){return JSON.stringify(I(e,t))}function re(e,t){return H(JSON.parse(e),t)}function M(){let{passphrase:e}=N();return{passphrase:e,encrypt(t,n){return I(t,n||e)},decrypt(t,n){return H(t,n||e)},encryptString(t,n){return te(t,n||e)},decryptString(t,n){return re(t,n||e)}}}var ne=()=>{let{encrypt:e,decrypt:t}=M(),n=_react.useCallback.call(void 0, (c,i)=>{try{let d=e(i);localStorage.setItem(c,JSON.stringify(d))}catch(d){console.error("Failed to save to storage:",d)}},[e]),o=_react.useCallback.call(void 0, c=>{try{let i=localStorage.getItem(c);return i?t(JSON.parse(i)):null}catch(i){return console.error("Failed to get from storage:",i),null}},[t]),a=c=>{let[i,d]=_react.useState.call(void 0, ()=>{try{let l=localStorage.getItem(c);return l?t(JSON.parse(l)):null}catch(l){return console.error("Failed to parse localStorage value",l),null}});return _react.useEffect.call(void 0, ()=>{let l=R=>{if(R.key===c)if(R.newValue)try{d(t(JSON.parse(R.newValue)))}catch(S){console.error("Decrypt error from storage event",S)}else d(null)};return window.addEventListener("storage",l),()=>window.removeEventListener("storage",l)},[c,t]),i},r=_react.useCallback.call(void 0, c=>{c?localStorage.removeItem(c):localStorage.clear()},[]);return{save:n,get:o,clear:r,useWatchStorage:a}};function oe(e){let t=e,n=new Set;function o(){return t}function a(i){return n.add(i),()=>n.delete(i)}function r(i){typeof i=="function"?t=i(t):t=i,n.forEach(d=>d())}function c(i){return _react.useSyncExternalStore.call(void 0, a,()=>i?i(t):t,()=>i?i(t):t)}return{getSnapshot:o,subscribe:a,setState:r,useStore:c}}var $=new Map;function F(e){return $.has(e)||$.set(e,oe([null,{}])),$.get(e)}function Se(e,t,n){let o=arguments.length===3,a=o?t:void 0,r=o?n:t,{storageKey:c,cache:i}=N(),d=ne(),[l,R]=_react.useState.call(void 0, !1),[S,b]=_react.useState.call(void 0, !1),[T,C]=_react.useState.call(void 0, ),g=_react.useRef.call(void 0, void 0),x=_react.useRef.call(void 0, null),{cacheName:P,cacheKey:A,timeout:J,timeoutUnit:W,persistence:G}=_react.useMemo.call(void 0, ()=>{let p=c?d.get(c):void 0,s=typeof _optionalChain([r, 'optionalAccess', _25 => _25.cache])=="object"?_nullishCoalesce(_optionalChain([r, 'optionalAccess', _26 => _26.cache, 'optionalAccess', _27 => _27.cacheName]), () => (e.name)):e.name,f=_({...a,session:p},typeof _optionalChain([r, 'optionalAccess', _28 => _28.cache])=="object"?_optionalChain([r, 'optionalAccess', _29 => _29.cache, 'optionalAccess', _30 => _30.cacheKey]):void 0),y=!1;typeof _optionalChain([i, 'optionalAccess', _31 => _31.persistence])=="boolean"&&(y=_optionalChain([i, 'optionalAccess', _32 => _32.persistence])),typeof _optionalChain([r, 'optionalAccess', _33 => _33.cache])=="object"&&typeof _optionalChain([r, 'optionalAccess', _34 => _34.cache, 'optionalAccess', _35 => _35.persistence])=="boolean"&&(y=_nullishCoalesce(_optionalChain([r, 'optionalAccess', _36 => _36.cache, 'optionalAccess', _37 => _37.persistence]), () => (!1)));let h=60*5,u="s";return q(_optionalChain([i, 'optionalAccess', _38 => _38.timeout]))&&(typeof _optionalChain([i, 'optionalAccess', _39 => _39.timeout])=="number"?(h=i.timeout,u="s"):typeof _optionalChain([i, 'optionalAccess', _40 => _40.timeout])=="object"&&(h=_optionalChain([i, 'optionalAccess', _41 => _41.timeout, 'access', _42 => _42.value]),u=_optionalChain([i, 'optionalAccess', _43 => _43.timeout, 'access', _44 => _44.unit]))),_optionalChain([r, 'optionalAccess', _45 => _45.cache])&&typeof r.cache!="boolean"&&(typeof r.cache.timeout=="number"?(h=r.cache.timeout,u="s"):typeof r.cache.timeout=="object"&&(h=r.cache.timeout.value,u=r.cache.timeout.unit)),{cacheName:s,cacheKey:f,timeout:h,timeoutUnit:u,persistence:y}},[_optionalChain([r, 'optionalAccess', _46 => _46.cache]),c,i]);_react.useEffect.call(void 0, ()=>{let p=JSON.stringify(q(g.current)?g.current:""),s=JSON.stringify(q(a)?a:""),f=g.current===void 0;(p!==s||f)&&!_optionalChain([r, 'optionalAccess', _47 => _47.hold])&&(C(null),U(),g.current=a),_optionalChain([r, 'optionalAccess', _48 => _48.onChange])&&_optionalChain([r, 'optionalAccess', _49 => _49.onChange, 'call', _50 => _50(a,m)])},[a,_optionalChain([r, 'optionalAccess', _51 => _51.hold]),..._optionalChain([r, 'optionalAccess', _52 => _52.trigger])||[]]),_react.useEffect.call(void 0, ()=>{let p=async()=>{!G&&P&&A&&(await caches.open(P)).delete(A)};return window.addEventListener("beforeunload",p),()=>{window.removeEventListener("beforeunload",p),_optionalChain([x, 'access', _53 => _53.current, 'optionalAccess', _54 => _54.abort, 'call', _55 => _55()])}},[]);let U=_react.useCallback.call(void 0, async p=>{let s=a;if(_optionalChain([r, 'optionalAccess', _56 => _56.hold])&&_optionalChain([r, 'optionalAccess', _57 => _57.logging])&&console.log("Hold active"),_optionalChain([r, 'optionalAccess', _58 => _58.beforeRequest])&&(s=_optionalChain([r, 'optionalAccess', _59 => _59.beforeRequest, 'call', _60 => _60(a)])),_optionalChain([r, 'optionalAccess', _61 => _61.cache])&&!p&&!S){R(!0),_optionalChain([r, 'optionalAccess', _62 => _62.onBeforeRequest])&&_optionalChain([r, 'optionalAccess', _63 => _63.onBeforeRequest, 'call', _64 => _64(a)]);let f=await caches.open(P),h=awaitawait _asyncOptionalChain([(await f.match(A)), 'optionalAccess', async _65 => _65.json, 'call', async _66 => _66()]);if(h){let{data:u,expired:w}=h;if(_moment2.default.call(void 0, ).isAfter(w))await f.delete(A);else{_optionalChain([r, 'optionalAccess', _67 => _67.afterResponse])&&_optionalChain([u, 'optionalAccess', _68 => _68.data])&&(u.data=_optionalChain([r, 'optionalAccess', _69 => _69.afterResponse, 'call', _70 => _70(u.data)])),_optionalChain([r, 'optionalAccess', _71 => _71.logging])&&console.log("After request: Using Cache",u),_optionalChain([r, 'optionalAccess', _72 => _72.onAfterResponse])&&_optionalChain([r, 'optionalAccess', _73 => _73.onAfterResponse, 'call', _74 => _74(u)]),R(!1),C(u);return}}}if(typeof e=="function"){_optionalChain([x, 'access', _75 => _75.current, 'optionalAccess', _76 => _76.abort, 'call', _77 => _77()]);let f=new AbortController;x.current=f,R(!0),_optionalChain([r, 'optionalAccess', _78 => _78.logging])&&console.log("Before request",a),_optionalChain([r, 'optionalAccess', _79 => _79.onBeforeRequest])&&_optionalChain([r, 'optionalAccess', _80 => _80.onBeforeRequest, 'call', _81 => _81(a)]);let y=o?await e(s,void 0,{...r,signal:f.signal}):await e(void 0,{...r,signal:f.signal});if(_optionalChain([r, 'optionalAccess', _82 => _82.afterResponse])&&_optionalChain([y, 'optionalAccess', _83 => _83.data])&&(y.data=_optionalChain([r, 'optionalAccess', _84 => _84.afterResponse, 'call', _85 => _85(y.data)])),_optionalChain([r, 'optionalAccess', _86 => _86.logging])&&console.log("After request",y),_optionalChain([r, 'optionalAccess', _87 => _87.onAfterResponse])&&_optionalChain([r, 'optionalAccess', _88 => _88.onAfterResponse, 'call', _89 => _89(y)]),R(!1),C(y),b(!1),_optionalChain([r, 'optionalAccess', _90 => _90.cache])&&y.status){let h=_moment2.default.call(void 0, ).add(J,W).toISOString(),u={data:y,expired:h},w=await caches.open(P),v=new Response(JSON.stringify(u));await w.put(A,v)}}},[a,e,r]);_react.useEffect.call(void 0, ()=>{if(_optionalChain([r, 'optionalAccess', _91 => _91.refreshInterval])){let p=typeof r.refreshInterval=="number"?r.refreshInterval:r.refreshInterval.value,s=typeof r.refreshInterval=="number"?"s":r.refreshInterval.unit,f=setInterval(()=>{U()},_moment2.default.duration(p,s).asMilliseconds());return()=>clearInterval(f)}return()=>{}},[_optionalChain([r, 'optionalAccess', _92 => _92.refreshInterval]),U]),_react.useEffect.call(void 0, ()=>{if(!_optionalChain([r, 'optionalAccess', _93 => _93.refetchOnWindowFocus]))return;let p=()=>{U()};return window.addEventListener("focus",p),()=>{window.removeEventListener("focus",p)}},[_optionalChain([r, 'optionalAccess', _94 => _94.refetchOnWindowFocus]),U]);let m={...T,loading:l,refresh:U,abort:()=>{_optionalChain([x, 'access', _95 => _95.current, 'optionalAccess', _96 => _96.abort, 'call', _97 => _97()]),x.current=null,R(!1),b(!0)},clear:()=>{R(!1),C(null)},response:T,isCancel:S,clone:(p,s)=>Se(e,p,s)};return _react.useEffect.call(void 0, ()=>{_optionalChain([r, 'optionalAccess', _98 => _98.storeName])&&F(_optionalChain([r, 'optionalAccess', _99 => _99.storeName])).setState([_optionalChain([T, 'optionalAccess', _100 => _100.data]),m])},[T,m,_optionalChain([r, 'optionalAccess', _101 => _101.storeName])]),[_optionalChain([T, 'optionalAccess', _102 => _102.data]),m]}async function St(e,t=()=>{}){let n=e*1e3;return new Promise(o=>{let a=0,r=setInterval(()=>{t(),a===9&&clearInterval(r)},1e3);setTimeout(async()=>{await t(),o(!0)},n)})}var ae=(r=>(r.POST="POST",r.PUT="PUT",r.PATCH="PATCH",r.DELETE="DELETE",r.GET="GET",r))(ae||{}),ie= exports.DataTypeEnum =(s=>(s.number="number",s.currency="currency",s.percent="percent",s.date="date",s.dateTime="dateTime",s.month="month",s.year="year",s.time="time",s.timestamp="timestamp",s.string="string",s.textarea="textarea",s.code="code",s.password="password",s.boolean="boolean",s.toggle="toggle",s.email="email",s.phone="phone",s.url="url",s.json="json",s.file="file",s.image="image",s.array="array",s.object="object",s.enum="enum",s.user="user",s.department="department",s.status="status",s))(ie||{});var vt=(e,t,n)=>{let{format:o}=N();return t==="number"?we(e,{thouSep:o.number.thouSep,decDigits:o.number.decDigits,decSep:o.number.decSep,...n}):["date","dateTime","month","year","time"].includes(t)?Ue(e,{display:_optionalChain([o, 'access', _103 => _103[t], 'optionalAccess', _104 => _104.display]),value:_optionalChain([o, 'access', _105 => _105[t], 'optionalAccess', _106 => _106.value]),...n}):t==="boolean"?Oe(e,n):t==="string"?qe(e,n):_nullishCoalesce(_optionalChain([e, 'optionalAccess', _107 => _107.toString, 'call', _108 => _108()]), () => (""))};function Oe(e,t){let n=typeof e=="string"?e==="true":!!e,o=_nullishCoalesce(_optionalChain([t, 'optionalAccess', _109 => _109.trueLabel]), () => ("Yes")),a=_nullishCoalesce(_optionalChain([t, 'optionalAccess', _110 => _110.falseLabel]), () => ("No"));return n?o:a}function qe(e,t){if(!q(e))return"";let n=String(e);return _optionalChain([t, 'optionalAccess', _111 => _111.capitalize])&&(n=n.charAt(0).toUpperCase()+n.slice(1)),_optionalChain([t, 'optionalAccess', _112 => _112.ellipsis])&&n.length>t.ellipsis&&(n=n.slice(0,t.ellipsis)+"..."),n}function we(e,{thouSep:t,decSep:n,decDigits:o,method:a}){if(e==null||isNaN(Number(e)))return"";let r=typeof e=="string"?parseFloat(e):e;if(a)if(typeof o=="number"){let l=Math.pow(10,o);r=Math[a](r*l)/l}else r=Math[a](r);else if(typeof o=="number"){let l=Math.pow(10,o);r=Math.floor(r*l)/l}let c=0;if(o==="auto"){let l=r.toString(),R=l.indexOf(".");R!==-1&&(c=l.length-R-1)}let i={style:"decimal",useGrouping:!0,minimumFractionDigits:o==="auto"?c:o||0,maximumFractionDigits:o==="auto"?c:o||0,minimumIntegerDigits:1};return r.toLocaleString("en-US",i).replace(/\./g,"decSep").replace(/,/g,"thouSep").replace(/decSep/g,n).replace(/thouSep/g,t)}function Ue(e,{display:t,value:n}){if(!q(e))return e;let o=_moment2.default.call(void 0, e,n);return o.isValid()?o.format(t):e}function Mt(e,{interval:t,lead:n}){let o=_react.useRef.call(void 0, null);_react.useEffect.call(void 0, ()=>{o.current=e},[e]),_react.useEffect.call(void 0, ()=>{let a=()=>o.current();if(n&&a(),t!==null){let r=setInterval(a,t);return()=>clearInterval(r)}},[t])}function It(e,t,n){let[o,a]=_react.useState.call(void 0, !1),r=(l,R)=>typeof e=="string"&&l===e||typeof e=="number"&&R===e,c=l=>l!==null&&(["INPUT","TEXTAREA","SELECT","BUTTON"].includes(l.tagName)||l.hasAttribute("contentEditable")),i=l=>{let{key:R,keyCode:S}=l,b=l.ctrlKey,T=l.altKey,C=l.shiftKey;if(!c(document.activeElement))if(t)if(typeof t=="string")r(R,S)&&(t==="ctrl"&&b||t==="alt"&&T||t==="shift"&&C)&&(l.preventDefault(),n&&l.stopPropagation(),a(!o));else{let g=t.every(x=>x==="ctrl"?b:x==="alt"?T:x==="shift"?C:!1);r(R,S)&&g&&(l.preventDefault(),n&&l.stopPropagation(),a(!o))}else r(R,S)&&(l.preventDefault(),n&&l.stopPropagation(),a(!o))},d=({key:l,keyCode:R})=>{r(l,R)&&a(!1)};return _react.useEffect.call(void 0, ()=>(window.addEventListener("keydown",i),window.addEventListener("keyup",d),()=>{window.removeEventListener("keydown",i),window.removeEventListener("keyup",d)}),[]),o}var _axios = require('axios'); var _axios2 = _interopRequireDefault(_axios);var er=({url:e,token:t,beforeRequest:n,onCallback:o,headers:a,onUnauthorized:r,handleToast:c,handleAuthorization:i,disabledToastWhenCancel:d,withCredentials:l,encryptRequest:R,encryptResponse:S,passphrase:b})=>{let{encrypt:T,decrypt:C,passphrase:g}=M(),x=(m,p,s,f)=>{let y=_optionalChain([f, 'optionalAccess', _113 => _113.code])==="ERR_CANCELED",h=m.status===401,u=_optionalChain([m, 'optionalAccess', _114 => _114.data]);if((typeof _optionalChain([s, 'optionalAccess', _115 => _115.encryptResponse])=="boolean"?_optionalChain([s, 'optionalAccess', _116 => _116.encryptResponse]):S)&&u){let E=_optionalChain([s, 'optionalAccess', _117 => _117.passphrase])?typeof s.passphrase=="boolean"&&s.passphrase?g:s.passphrase:b;try{u=C(u,E)}catch (e5){try{u=C(u,g)}catch (e6){}}}let D={...o({...m,data:u,isCancel:y,isUnauthorization:h},f),isCancel:y,isUnauthorization:h,httpCode:m.status},B=typeof _optionalChain([s, 'optionalAccess', _118 => _118.disabledToastWhenCancel])=="boolean"?_optionalChain([s, 'optionalAccess', _119 => _119.disabledToastWhenCancel]):d,de=i?i(D,s):!h;if((_optionalChain([s, 'optionalAccess', _120 => _120.infoSuccess])&&D.status||_optionalChain([s, 'optionalAccess', _121 => _121.infoError])&&!D.status)&&c&&(!y||!B)&&c(D),!de&&(!y||!_optionalChain([s, 'optionalAccess', _122 => _122.disabledHandleUnauthorized]))){let E=_optionalChain([s, 'optionalAccess', _123 => _123.onUnauthorized])||r;E&&E(D)}if(p)p(D);else return D},P=(m,p=()=>{})=>_axios2.default.create({baseURL:`${e}`,withCredentials:typeof m.withCredentials=="boolean"?m.withCredentials:l})(m).then(p).catch(f=>p(f.response,f)),A=(m,p,s,f,y)=>{let u={...{token:!0,infoError:!0,infoSuccess:!0,responseType:"json"},...y},w={"Content-Type":"application/json",...a,...u.headers};if(u.token&&(typeof u.token=="boolean"?t&&(w.Authorization=`Bearer ${t}`):u.token&&(w.Authorization=`Bearer ${u.token}`)),n&&(s=n(s)),(typeof _optionalChain([u, 'optionalAccess', _124 => _124.encryptRequest])=="boolean"?_optionalChain([u, 'optionalAccess', _125 => _125.encryptRequest]):R)&&s){let D=_optionalChain([y, 'optionalAccess', _126 => _126.passphrase])?typeof y.passphrase=="boolean"&&y.passphrase?g:y.passphrase:b;s=T(s,D)}return P({url:p,method:m,data:s,headers:w,responseType:u.responseType,signal:u.signal,withCredentials:u.withCredentials,onUploadProgress:D=>{_optionalChain([u, 'optionalAccess', _127 => _127.onUploadProgress])&&_optionalChain([u, 'optionalAccess', _128 => _128.onUploadProgress, 'call', _129 => _129(D)])}},(D,B)=>x(D,f,u,B))};return{client:P,post:(m,p,s,f)=>A("POST",`${m}`,p,s,f),put:(m,p,s,f)=>A("PUT",`${m}`,p,s,f),patch:(m,p,s,f)=>A("PATCH",`${m}`,p,s,f),delete:(m,p,s)=>A("DELETE",`${m}`,null,p,s),get:(m,p,s)=>A("GET",`${m}`,null,p,s),upload:(m,p,s,f)=>{let y=new FormData;return Object.keys(p).forEach(h=>y.append(h,p[h])),A("POST",`${m}`,y,s,{infoSuccess:!1,...f,headers:{"Content-Type":"multipart/form-data",..._optionalChain([f, 'optionalAccess', _130 => _130.headers])}})}}};function or(e,t){let[n,o]=_react.useState.call(void 0, !1),[a,r]=_react.useState.call(void 0, ),[c,i]=_react.useState.call(void 0, 0),d=_react.useRef.call(void 0, null);return _react.useEffect.call(void 0, ()=>{if(_optionalChain([t, 'optionalAccess', _131 => _131.abortOnUnmount]))return()=>{_optionalChain([d, 'access', _132 => _132.current, 'optionalAccess', _133 => _133.abort, 'call', _134 => _134()])}},[]),[async b=>{_optionalChain([d, 'access', _135 => _135.current, 'optionalAccess', _136 => _136.abort, 'call', _137 => _137()]);let T=new AbortController;d.current=T,o(!0),_optionalChain([t, 'optionalAccess', _138 => _138.beforeRequest])&&(b=_optionalChain([t, 'optionalAccess', _139 => _139.beforeRequest, 'call', _140 => _140(b)])),_optionalChain([t, 'optionalAccess', _141 => _141.logging])&&console.log("Before request",b);let C={...t,signal:T.signal,onUploadProgress:x=>{let P=Math.round(x.loaded*100/(x.total||1));i(P)}},g=q(b)?await e(b,void 0,C):await e(void 0,C);_optionalChain([t, 'optionalAccess', _142 => _142.logging])&&console.log("After response",g),r(g),o(!1),i(0),g.status&&_optionalChain([t, 'optionalAccess', _143 => _143.onSuccess])&&_optionalChain([t, 'optionalAccess', _144 => _144.onSuccess, 'call', _145 => _145(g)]),!g.status&&_optionalChain([t, 'optionalAccess', _146 => _146.onError])&&_optionalChain([t, 'optionalAccess', _147 => _147.onError, 'call', _148 => _148(g)]),_optionalChain([t, 'optionalAccess', _149 => _149.afterResponse])&&_optionalChain([t, 'optionalAccess', _150 => _150.afterResponse, 'call', _151 => _151(g)])},{...a,loading:n,abort:()=>{_optionalChain([d, 'access', _152 => _152.current, 'optionalAccess', _153 => _153.abort, 'call', _154 => _154()]),d.current=null,o(!1),i(0)},progress:c,reset:()=>{o(!1),i(0),r(null)}}]}function ir(e="vertical"){let t=_react.useRef.call(void 0, null),[n,o]=_react.useState.call(void 0, !1),[a,r]=_react.useState.call(void 0, !1),c=_react.useCallback.call(void 0, ()=>{let i=t.current;if(i)if(e==="vertical"){let d=Math.ceil(i.scrollTop+i.clientHeight),l=Math.floor(i.scrollHeight);o(i.scrollTop>0),r(d<l)}else{let d=Math.ceil(i.scrollLeft+i.clientWidth),l=Math.floor(i.scrollWidth);o(i.scrollLeft>0),r(d<l)}},[e]);return _react.useEffect.call(void 0, ()=>{let i=t.current;if(i)return c(),i.addEventListener("scroll",c),()=>i.removeEventListener("scroll",c)},[c]),{ref:t,showStartShadow:n,showEndShadow:a}}var cr=(e,t)=>F(t).useStore();var dr=(e,t)=>{let n=o=>e(o);return n.displayName=t,n},mr= exports.splitElement =(e,t)=>{let n={};n.others=[];let o=a=>{_react2.default.Children.forEach(a,r=>{if(_react2.default.isValidElement(r)){let c=r.type.displayName;if(t.includes(c))n[c]=r;else{let i=r;_optionalChain([i, 'access', _155 => _155.props, 'optionalAccess', _156 => _156.children])?o(i.props.children):n.others.push(r)}}else n.others.push(r)})};return o(e),n};exports.BgsCoreProvider = ge; exports.DataTypeEnum = ie; exports.HttpMethod = ae; exports.createApiHelper = er; exports.createElement = dr; exports.decrypt = H; exports.decryptString = re; exports.diffJson = je; exports.encrypt = I; exports.encryptString = te; exports.generateCacheKey = _; exports.generateUUID = $e; exports.getFieldValue = O; exports.isArray = ze; exports.isNotEmpty = q; exports.jsonCopy = Xe; exports.labelFormatter = X; exports.mappingUndefinedtoNull = Ve; exports.renderChildren = Je; exports.sorting = We; exports.splitElement = mr; exports.stableStringify = me; exports.summary = Ge; exports.useApiLoad = Se; exports.useApiSend = or; exports.useApiStore = cr; exports.useBgsCore = N; exports.useCrypto = M; exports.useDelay = St; exports.useFormatted = vt; exports.useInterval = Mt; exports.useKeyPress = It; exports.useScroll = ir; exports.useStorage = ne;
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,488 @@
|
|
|
1
|
+
import moment from 'moment';
|
|
2
|
+
import { GenericAbortSignal, AxiosProgressEvent, AxiosResponse, AxiosRequestConfig } from 'axios';
|
|
3
|
+
import * as React$1 from 'react';
|
|
4
|
+
import React__default, { PropsWithChildren } from 'react';
|
|
5
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
6
|
+
|
|
7
|
+
type Children<T = unknown> = ChildFunction<T> | React.ReactNode;
|
|
8
|
+
type ChildFunction<T = unknown> = (props: T) => Children<T>;
|
|
9
|
+
interface PaginationMeta {
|
|
10
|
+
limit: number;
|
|
11
|
+
page: number;
|
|
12
|
+
totalItems: number;
|
|
13
|
+
totalPages: number;
|
|
14
|
+
}
|
|
15
|
+
interface ApiResponse<T = any> {
|
|
16
|
+
status: boolean;
|
|
17
|
+
data: T;
|
|
18
|
+
paging?: PaginationMeta;
|
|
19
|
+
message: string;
|
|
20
|
+
code: number;
|
|
21
|
+
isCancel: boolean;
|
|
22
|
+
isUnauthorization: boolean;
|
|
23
|
+
httpCode: number;
|
|
24
|
+
}
|
|
25
|
+
type CallbackHelper<T = any> = ((response: ApiResponse<T>) => (void | ApiResponse<T>));
|
|
26
|
+
type HandleCallback<T = any> = (props: AxiosResponse<T> & {
|
|
27
|
+
isCancel: boolean;
|
|
28
|
+
isUnauthorization: boolean;
|
|
29
|
+
}, err?: any) => Omit<ApiResponse, "httpCode" | "isCancel" | "isUnauthorization">;
|
|
30
|
+
interface UseHelperProps {
|
|
31
|
+
/** Base URL API */
|
|
32
|
+
url: string;
|
|
33
|
+
/** Header tambahan untuk request */
|
|
34
|
+
headers?: Record<string, string>;
|
|
35
|
+
/** Token autentikasi, bisa string atau null/undefined jika tidak ada */
|
|
36
|
+
token?: string | null | undefined;
|
|
37
|
+
/** Callback yang dijalankan setiap response atau error */
|
|
38
|
+
onCallback: HandleCallback;
|
|
39
|
+
/** Handler khusus jika response tidak authorized */
|
|
40
|
+
onUnauthorized?: (response: ApiResponse) => void;
|
|
41
|
+
/** Fungsi untuk memeriksa otorisasi response, return true jika authorized */
|
|
42
|
+
handleAuthorization?: (response: ApiResponse, options?: OptionsHelper) => boolean;
|
|
43
|
+
/** Fungsi untuk menampilkan toast/notification berdasarkan response */
|
|
44
|
+
handleToast?: (response: ApiResponse) => void;
|
|
45
|
+
/**
|
|
46
|
+
* Fungsi manipulasi/preparasi data sebelum dikirim ke server.
|
|
47
|
+
*/
|
|
48
|
+
beforeRequest?: (data: any) => any;
|
|
49
|
+
/** Jika true, toast tidak ditampilkan ketika request dibatalkan */
|
|
50
|
+
disabledToastWhenCancel?: boolean;
|
|
51
|
+
/**
|
|
52
|
+
* Jika true, maka cookie seperti HttpOnly akan dikirim dalam request.
|
|
53
|
+
* Digunakan saat autentikasi berbasis cookie (bukan token di header Authorization).
|
|
54
|
+
*/
|
|
55
|
+
withCredentials?: boolean;
|
|
56
|
+
/**
|
|
57
|
+
* Jika `true`, data request akan dienkripsi sebelum dikirim ke server.
|
|
58
|
+
* Pastikan server dapat mendekripsi payload ini.
|
|
59
|
+
*/
|
|
60
|
+
encryptRequest?: boolean;
|
|
61
|
+
/**
|
|
62
|
+
* Jika `true`, data response dari server akan didekripsi.
|
|
63
|
+
* Asumsinya response telah terenkripsi sebelumnya oleh server.
|
|
64
|
+
*/
|
|
65
|
+
encryptResponse?: boolean;
|
|
66
|
+
/**
|
|
67
|
+
* Kata sandi atau kunci untuk proses enkripsi dan dekripsi data.
|
|
68
|
+
* Digunakan bersama `encryptRequest` dan `encryptResponse` untuk memastikan
|
|
69
|
+
* data terenkripsi dan terdekripsi dengan algoritma yang sama di sisi client dan server.
|
|
70
|
+
* Harus disepakati antara client dan server.
|
|
71
|
+
*
|
|
72
|
+
* Secara default, nilai passphrase akan diambil dari context `bgsCore` jika ada.
|
|
73
|
+
*/
|
|
74
|
+
passphrase?: string | null;
|
|
75
|
+
}
|
|
76
|
+
interface OptionsHelper {
|
|
77
|
+
/** Menampilkan toast/info ketika response success */
|
|
78
|
+
infoSuccess: boolean;
|
|
79
|
+
/** Menampilkan toast/info ketika response error */
|
|
80
|
+
infoError: boolean;
|
|
81
|
+
/** Menyisipkan Authorization token.
|
|
82
|
+
* - `true` → pakai token default dari `UseHelperProps`
|
|
83
|
+
* - `string` → pakai token string ini
|
|
84
|
+
* - `false` → tidak menyisipkan token
|
|
85
|
+
*/
|
|
86
|
+
token: boolean | string;
|
|
87
|
+
/** Header tambahan untuk request */
|
|
88
|
+
headers: Record<string, string>;
|
|
89
|
+
/** Signal dari AbortController, bisa dipakai untuk cancel request */
|
|
90
|
+
signal: GenericAbortSignal;
|
|
91
|
+
/** Response type seperti 'json', 'blob', dll */
|
|
92
|
+
responseType: ResponseType;
|
|
93
|
+
/** Callback ketika ada upload progress (biasanya untuk form upload) */
|
|
94
|
+
onUploadProgress: (props: AxiosProgressEvent) => void;
|
|
95
|
+
/** Handler saat request unauthorized (status 401/403), bisa override default */
|
|
96
|
+
onUnauthorized: (response: ApiResponse) => void;
|
|
97
|
+
/** Jika `true`, maka onUnauthorized tidak akan dijalankan */
|
|
98
|
+
disabledHandleUnauthorized: boolean;
|
|
99
|
+
/** Jika `true`, maka tidak akan munculkan toast saat request dibatalkan (abort) */
|
|
100
|
+
disabledToastWhenCancel?: boolean;
|
|
101
|
+
/**
|
|
102
|
+
* Jika true, maka cookie seperti HttpOnly akan dikirim dalam request.
|
|
103
|
+
* Digunakan saat autentikasi berbasis cookie (bukan token di header Authorization).
|
|
104
|
+
*/
|
|
105
|
+
withCredentials?: boolean;
|
|
106
|
+
/**
|
|
107
|
+
* Jika `true`, data request akan dienkripsi sebelum dikirim ke server.
|
|
108
|
+
* Pastikan server dapat mendekripsi payload ini.
|
|
109
|
+
*/
|
|
110
|
+
encryptRequest?: boolean;
|
|
111
|
+
/**
|
|
112
|
+
* Jika `true`, data response dari server akan didekripsi.
|
|
113
|
+
* Asumsinya response telah terenkripsi sebelumnya oleh server.
|
|
114
|
+
*/
|
|
115
|
+
encryptResponse?: boolean;
|
|
116
|
+
/**
|
|
117
|
+
* Kata sandi atau kunci untuk proses enkripsi dan dekripsi data.
|
|
118
|
+
* Digunakan bersama `encryptRequest` dan `encryptResponse` untuk memastikan
|
|
119
|
+
* data terenkripsi dan terdekripsi dengan algoritma yang sama di sisi client dan server.
|
|
120
|
+
* Harus disepakati antara client dan server.
|
|
121
|
+
*
|
|
122
|
+
* Secara default, nilai passphrase akan diambil dari context `bgsCore` jika ada.
|
|
123
|
+
*/
|
|
124
|
+
passphrase?: string | true | null;
|
|
125
|
+
}
|
|
126
|
+
type ClientCallback<T> = (response: AxiosResponse<T>, err?: any) => any;
|
|
127
|
+
declare enum HttpMethod {
|
|
128
|
+
POST = "POST",
|
|
129
|
+
PUT = "PUT",
|
|
130
|
+
PATCH = "PATCH",
|
|
131
|
+
DELETE = "DELETE",
|
|
132
|
+
GET = "GET"
|
|
133
|
+
}
|
|
134
|
+
type ApiMethod<DReq = any, DRes = DReq> = (data: DReq, callback?: CallbackHelper<DRes>, options?: Partial<OptionsHelper>) => Promise<ApiResponse<DRes>>;
|
|
135
|
+
type ApiMethodVoid<DRes = any> = <Res = DRes>(callback?: CallbackHelper<Res>, options?: Partial<OptionsHelper>) => Promise<ApiResponse<Res>>;
|
|
136
|
+
type ApiDefaultMethod<DReq = any, DRes = DReq> = <Req = DReq, Res = DRes>(url: string, data: Req, callback?: CallbackHelper<Res>, options?: Partial<OptionsHelper>) => Promise<ApiResponse<Res>>;
|
|
137
|
+
type ApiDefaultFetch<DRes = any> = <Res = DRes>(url: string, callback?: CallbackHelper<Res>, options?: Partial<OptionsHelper>) => Promise<ApiResponse<Res>>;
|
|
138
|
+
type ResponseType = 'arraybuffer' | 'blob' | 'document' | 'json' | 'text' | 'stream' | 'formdata';
|
|
139
|
+
type OptionsCallReturn<DReq, DRes = DReq> = Partial<ApiResponse<DRes>> & {
|
|
140
|
+
/** Status loading saat request berlangsung */
|
|
141
|
+
loading: boolean;
|
|
142
|
+
/** Menjalankan ulang request dengan payload & config sebelumnya */
|
|
143
|
+
refresh: (force?: boolean) => void;
|
|
144
|
+
/** Membatalkan request yang sedang berjalan */
|
|
145
|
+
abort: () => void;
|
|
146
|
+
/** Clear/reset response dan status terkait */
|
|
147
|
+
clear: () => void;
|
|
148
|
+
/** Response dari server (bisa undefined/null jika belum ada atau sudah di-clear) */
|
|
149
|
+
response: ApiResponse<DRes> | undefined | null;
|
|
150
|
+
/**
|
|
151
|
+
* Mengkloning call API dengan payload/config baru.
|
|
152
|
+
* Cocok untuk membuat instance baru tanpa mempengaruhi state lama.
|
|
153
|
+
*/
|
|
154
|
+
clone: <T = unknown>(newPayload?: DReq, newConfig?: Partial<UseCallOptionsProps<DReq, DRes & T>>) => UseCallReturnType<DReq, DRes>;
|
|
155
|
+
/** Menunjukkan apakah request terakhir dibatalkan (via abort).
|
|
156
|
+
* Berguna untuk mengabaikan cache saat refresh berikutnya.
|
|
157
|
+
*/
|
|
158
|
+
isCancel: boolean;
|
|
159
|
+
};
|
|
160
|
+
type UseCallReturnType<DReq, DRes = DReq> = [
|
|
161
|
+
DRes | undefined,
|
|
162
|
+
OptionsCallReturn<DReq, DRes>
|
|
163
|
+
];
|
|
164
|
+
interface TimeoutConfig {
|
|
165
|
+
value: number;
|
|
166
|
+
unit: moment.DurationInputArg2;
|
|
167
|
+
}
|
|
168
|
+
interface CacheProps {
|
|
169
|
+
/**
|
|
170
|
+
* Nama cache yang akan digunakan sebagai container atau namespace.
|
|
171
|
+
* Biasanya untuk membedakan jenis cache yang berbeda.
|
|
172
|
+
*/
|
|
173
|
+
cacheName?: string;
|
|
174
|
+
/**
|
|
175
|
+
* Kunci unik untuk menyimpan dan mengambil data dari cache.
|
|
176
|
+
* Biasanya merepresentasikan entri spesifik dalam cacheName.
|
|
177
|
+
*/
|
|
178
|
+
cacheKey?: string | Array<string | number | boolean | null | undefined | Record<string, any>>;
|
|
179
|
+
/**
|
|
180
|
+
* Durasi timeout cache sebelum dianggap kedaluwarsa.
|
|
181
|
+
* Bisa berupa angka (dalam satuan detik) atau objek konfigurasi timeout.
|
|
182
|
+
*/
|
|
183
|
+
timeout?: number | TimeoutConfig;
|
|
184
|
+
/**
|
|
185
|
+
* Jika true, data cache akan dipertahankan walau halaman direfresh atau ditutup.
|
|
186
|
+
* Jika false atau tidak diisi, cache akan dihapus saat halaman ditutup.
|
|
187
|
+
*/
|
|
188
|
+
persistence?: boolean;
|
|
189
|
+
}
|
|
190
|
+
interface CacheData<DRes> {
|
|
191
|
+
/**
|
|
192
|
+
* Waktu kedaluwarsa cache dalam bentuk ISO string.
|
|
193
|
+
*/
|
|
194
|
+
expired: string;
|
|
195
|
+
/**
|
|
196
|
+
* Data respon API yang disimpan dalam cache.
|
|
197
|
+
*/
|
|
198
|
+
data: ApiResponse<DRes>;
|
|
199
|
+
}
|
|
200
|
+
interface UseCallOptionsProps<DReq, DRes> extends OptionsHelper {
|
|
201
|
+
/**
|
|
202
|
+
* Jika true, proses request & response akan dicetak ke console.
|
|
203
|
+
*/
|
|
204
|
+
logging: boolean;
|
|
205
|
+
/**
|
|
206
|
+
* Fungsi manipulasi/preparasi data sebelum dikirim ke server.
|
|
207
|
+
*/
|
|
208
|
+
beforeRequest: (request: DReq) => DReq;
|
|
209
|
+
/**
|
|
210
|
+
* Fungsi manipulasi respon dari server sebelum disimpan atau ditampilkan.
|
|
211
|
+
*/
|
|
212
|
+
afterResponse: (response: DRes) => DRes;
|
|
213
|
+
/**
|
|
214
|
+
* Hook yang dijalankan sebelum request diproses.
|
|
215
|
+
*/
|
|
216
|
+
onBeforeRequest: (request: DReq) => void;
|
|
217
|
+
/**
|
|
218
|
+
* Hook yang dijalankan setelah respon diterima dari server.
|
|
219
|
+
*/
|
|
220
|
+
onAfterResponse: (response: ApiResponse<DRes>) => void;
|
|
221
|
+
/**
|
|
222
|
+
* Daftar dependency yang dapat memicu ulang pemanggilan API jika berubah.
|
|
223
|
+
*/
|
|
224
|
+
trigger: any[];
|
|
225
|
+
/**
|
|
226
|
+
* Jika true, maka request tidak dijalankan otomatis hingga dipanggil secara manual.
|
|
227
|
+
*/
|
|
228
|
+
hold: boolean;
|
|
229
|
+
/**
|
|
230
|
+
* Callback yang dipanggil setiap kali data berubah.
|
|
231
|
+
*/
|
|
232
|
+
onChange: (data: DReq, options: OptionsCallReturn<DReq, DRes>) => void;
|
|
233
|
+
/**
|
|
234
|
+
* Mengaktifkan cache untuk menyimpan respon API.
|
|
235
|
+
* Bisa true (default pengaturan) atau objek konfigurasi `CacheProps`.
|
|
236
|
+
*/
|
|
237
|
+
cache: true | CacheProps;
|
|
238
|
+
/**
|
|
239
|
+
* Interval auto refresh data. Bisa dalam detik atau konfigurasi TimeoutConfig.
|
|
240
|
+
*/
|
|
241
|
+
refreshInterval: number | TimeoutConfig;
|
|
242
|
+
/**
|
|
243
|
+
* Menentukan apakah data akan difetch ulang saat tab aktif kembali.
|
|
244
|
+
*/
|
|
245
|
+
refetchOnWindowFocus: boolean;
|
|
246
|
+
/**
|
|
247
|
+
* Nama unik untuk store/context/cache dari request API ini.
|
|
248
|
+
*
|
|
249
|
+
* Properti ini digunakan sebagai identitas untuk:
|
|
250
|
+
* - Menyimpan hasil request di global store agar bisa diakses antar komponen.
|
|
251
|
+
* - Menamai cache secara otomatis jika `cacheName` tidak diatur manual.
|
|
252
|
+
* - Menghindari konflik antar pemanggilan API yang berbeda.
|
|
253
|
+
*
|
|
254
|
+
* Disarankan menggunakan nama yang deskriptif dan unik per endpoint,
|
|
255
|
+
* seperti: "historyAbsence", "dashboardSummary", "userProfile", dst.
|
|
256
|
+
*
|
|
257
|
+
* Contoh penggunaan bersama context:
|
|
258
|
+
* const [data, options] = useApiStore(api.absence.history, "historyAbsence")
|
|
259
|
+
*/
|
|
260
|
+
storeName: string;
|
|
261
|
+
}
|
|
262
|
+
interface UseApiSendProps<Req, Res> extends Partial<OptionsHelper> {
|
|
263
|
+
/**
|
|
264
|
+
* Callback ketika respon berhasil.
|
|
265
|
+
*/
|
|
266
|
+
onSuccess?: OnCallback<Res>;
|
|
267
|
+
/**
|
|
268
|
+
* Callback ketika terjadi error.
|
|
269
|
+
*/
|
|
270
|
+
onError?: OnCallback<Res>;
|
|
271
|
+
/**
|
|
272
|
+
* Jika true, proses request & response akan dicetak ke console.
|
|
273
|
+
*/
|
|
274
|
+
logging?: boolean;
|
|
275
|
+
/**
|
|
276
|
+
* Fungsi manipulasi sebelum request dikirim.
|
|
277
|
+
*/
|
|
278
|
+
beforeRequest?: (request: Req) => Req;
|
|
279
|
+
/**
|
|
280
|
+
* Fungsi manipulasi setelah respon diterima.
|
|
281
|
+
*/
|
|
282
|
+
afterResponse?: OnCallback<Res>;
|
|
283
|
+
/**
|
|
284
|
+
* Jika true, request akan otomatis dibatalkan saat komponen unmount.
|
|
285
|
+
*/
|
|
286
|
+
abortOnUnmount?: boolean;
|
|
287
|
+
}
|
|
288
|
+
type OnCallback<T = any> = (response: ApiResponse<T>) => void;
|
|
289
|
+
type ApiActionState<Res> = Partial<ApiResponse<Res>> & {
|
|
290
|
+
/** Membatalkan request yang sedang berjalan */
|
|
291
|
+
abort: () => void;
|
|
292
|
+
/** Clear/reset response dan status terkait */
|
|
293
|
+
reset: () => void;
|
|
294
|
+
/** Status loading saat request berlangsung */
|
|
295
|
+
loading: boolean;
|
|
296
|
+
/** Progress upload/download, nilai antara 0 - 100 */
|
|
297
|
+
progress: number;
|
|
298
|
+
};
|
|
299
|
+
type UseApiSendReturnType<Req, Res> = Req extends undefined ? [
|
|
300
|
+
(values?: Req) => void,
|
|
301
|
+
ApiActionState<Res>
|
|
302
|
+
] : [
|
|
303
|
+
(values: Req) => void,
|
|
304
|
+
ApiActionState<Res>
|
|
305
|
+
];
|
|
306
|
+
declare enum DataTypeEnum {
|
|
307
|
+
number = "number",
|
|
308
|
+
currency = "currency",
|
|
309
|
+
percent = "percent",
|
|
310
|
+
date = "date",
|
|
311
|
+
dateTime = "dateTime",
|
|
312
|
+
month = "month",
|
|
313
|
+
year = "year",
|
|
314
|
+
time = "time",
|
|
315
|
+
timestamp = "timestamp",
|
|
316
|
+
string = "string",
|
|
317
|
+
textarea = "textarea",
|
|
318
|
+
code = "code",
|
|
319
|
+
password = "password",
|
|
320
|
+
boolean = "boolean",
|
|
321
|
+
toggle = "toggle",// Optional, untuk UI switch boolean
|
|
322
|
+
email = "email",
|
|
323
|
+
phone = "phone",
|
|
324
|
+
url = "url",
|
|
325
|
+
json = "json",
|
|
326
|
+
file = "file",
|
|
327
|
+
image = "image",
|
|
328
|
+
array = "array",
|
|
329
|
+
object = "object",
|
|
330
|
+
enum = "enum",
|
|
331
|
+
user = "user",
|
|
332
|
+
department = "department",
|
|
333
|
+
status = "status"
|
|
334
|
+
}
|
|
335
|
+
type DataType = `${DataTypeEnum}`;
|
|
336
|
+
type NestedKeyOf<T> = T extends object ? T extends Array<infer U> ? `${number}` | `${number}.${NestedKeyOf<U>}` : {
|
|
337
|
+
[K in keyof T]: T[K] extends Array<infer U> ? `${K & string}` | `${K & string}[${number}]` | `${K & string}[${number}].${NestedKeyOf<U>}` : T[K] extends object ? `${K & string}` | `${K & string}.${NestedKeyOf<T[K]>}` : `${K & string}`;
|
|
338
|
+
}[keyof T] : never;
|
|
339
|
+
type PathValue<T, P extends string> = P extends `${infer K}[${infer I}].${infer R}` ? K extends keyof T ? T[K] extends Array<infer U> ? PathValue<U, R> : never : never : P extends `${infer K}[${infer I}]` ? K extends keyof T ? T[K] extends Array<infer U> ? U : never : never : P extends `${infer K}.${infer R}` ? K extends keyof T ? PathValue<T[K], R> : never : P extends keyof T ? T[P] : never;
|
|
340
|
+
type SelectedNested<T> = Partial<Record<NestedKeyOf<T>, any>>;
|
|
341
|
+
|
|
342
|
+
declare function useApiLoad<DRes>(api: ApiMethodVoid<DRes>, options?: Partial<UseCallOptionsProps<undefined, DRes>>): UseCallReturnType<undefined, DRes>;
|
|
343
|
+
declare function useApiLoad<DReq, DRes>(api: ApiMethod<DReq, DRes>, data: DReq, options?: Partial<UseCallOptionsProps<DReq, DRes>>): UseCallReturnType<DReq, DRes>;
|
|
344
|
+
|
|
345
|
+
declare function useDelay(s: number, callback?: Function): Promise<unknown>;
|
|
346
|
+
|
|
347
|
+
type OptionsNumberProps = {
|
|
348
|
+
thouSep: string;
|
|
349
|
+
decSep: string;
|
|
350
|
+
decDigits: number | "auto";
|
|
351
|
+
};
|
|
352
|
+
type OptionsNumber = OptionsNumberProps & {
|
|
353
|
+
dataType: Extract<DataType, "number">;
|
|
354
|
+
method?: "round" | "ceil" | "floor";
|
|
355
|
+
};
|
|
356
|
+
type DataTypeDateGroup = Extract<DataType, "date" | "dateTime" | "month" | "year" | "time">;
|
|
357
|
+
type OptionsDate = {
|
|
358
|
+
dataType: DataTypeDateGroup;
|
|
359
|
+
display: string;
|
|
360
|
+
value: string;
|
|
361
|
+
};
|
|
362
|
+
type OptionsBoolean = {
|
|
363
|
+
dataType: Extract<DataType, "boolean">;
|
|
364
|
+
trueLabel?: string;
|
|
365
|
+
falseLabel?: string;
|
|
366
|
+
};
|
|
367
|
+
type OptionsString = {
|
|
368
|
+
dataType: Extract<DataType, "string">;
|
|
369
|
+
capitalize?: boolean;
|
|
370
|
+
ellipsis?: number;
|
|
371
|
+
};
|
|
372
|
+
type UseFormattedOptions<T extends DataType> = T extends "number" ? Partial<OptionsNumber> : T extends DataTypeDateGroup ? Partial<OptionsDate> : T extends "boolean" ? Partial<OptionsBoolean> : T extends "string" ? Partial<OptionsString> : never;
|
|
373
|
+
declare const useFormatted: <T extends DataType>(value: unknown, dataType: T, options?: UseFormattedOptions<T>) => string;
|
|
374
|
+
|
|
375
|
+
declare function useInterval<P extends Function>(callback: P, { interval, lead }: {
|
|
376
|
+
interval: number;
|
|
377
|
+
lead?: boolean;
|
|
378
|
+
}): void;
|
|
379
|
+
|
|
380
|
+
type CombinationType = "ctrl" | "alt" | "shift";
|
|
381
|
+
declare function useKeyPress(targetKey: string | number, combination?: CombinationType | CombinationType[], stopPropagation?: boolean): boolean;
|
|
382
|
+
|
|
383
|
+
declare const createApiHelper: <DReq = any, DRes = any>({ url, token, beforeRequest, onCallback, headers: headerProps, onUnauthorized, handleToast, handleAuthorization, disabledToastWhenCancel: disabledToastWhenCancelProps, withCredentials, encryptRequest: encryptRequestDefault, encryptResponse: encryptResponseDefault, passphrase, }: UseHelperProps) => {
|
|
384
|
+
client: (props: AxiosRequestConfig, callback?: ClientCallback<DRes>) => Promise<any>;
|
|
385
|
+
post: ApiDefaultMethod<DReq, DRes>;
|
|
386
|
+
put: ApiDefaultMethod<DReq, DRes>;
|
|
387
|
+
patch: ApiDefaultMethod<DReq, DRes>;
|
|
388
|
+
delete: ApiDefaultFetch<DRes>;
|
|
389
|
+
get: ApiDefaultFetch<DRes>;
|
|
390
|
+
upload: ApiDefaultMethod<DReq, DRes>;
|
|
391
|
+
};
|
|
392
|
+
|
|
393
|
+
declare function useApiSend<DReq, DRes>(api: ApiMethod<DReq, DRes>, props?: UseApiSendProps<DReq, DRes>): UseApiSendReturnType<DReq, DRes>;
|
|
394
|
+
declare function useApiSend<DRes>(api: ApiMethodVoid<DRes>, props?: UseApiSendProps<undefined, DRes>): UseApiSendReturnType<undefined, DRes>;
|
|
395
|
+
|
|
396
|
+
type Direction = "vertical" | "horizontal";
|
|
397
|
+
declare function useScroll<T extends HTMLDivElement>(direction?: Direction): {
|
|
398
|
+
ref: React$1.RefObject<T | null>;
|
|
399
|
+
showStartShadow: boolean;
|
|
400
|
+
showEndShadow: boolean;
|
|
401
|
+
};
|
|
402
|
+
|
|
403
|
+
declare const useStorage: () => {
|
|
404
|
+
save: <T = any>(key: string, data: T) => void;
|
|
405
|
+
get: <T = any>(key: string) => T | null;
|
|
406
|
+
clear: (key?: string) => void;
|
|
407
|
+
useWatchStorage: <T = any>(key: string) => T | null;
|
|
408
|
+
};
|
|
409
|
+
|
|
410
|
+
type EncryptedPayload = {
|
|
411
|
+
salt: string;
|
|
412
|
+
iv: string;
|
|
413
|
+
encrypted: string;
|
|
414
|
+
};
|
|
415
|
+
declare function encrypt<T = unknown>(payload: T, passphrase: string): EncryptedPayload;
|
|
416
|
+
declare function decrypt<T = unknown>(cipherPayload: EncryptedPayload, passphrase: string): T;
|
|
417
|
+
declare function encryptString(plain: string, passphrase: string): string;
|
|
418
|
+
declare function decryptString(encryptedJson: string, passphrase: string): string;
|
|
419
|
+
|
|
420
|
+
declare function useCrypto(): {
|
|
421
|
+
passphrase: string | undefined;
|
|
422
|
+
encrypt<T>(payload: T, passphraseProps?: string | null): EncryptedPayload;
|
|
423
|
+
decrypt<T>(data: EncryptedPayload, passphraseProps?: string | null): T;
|
|
424
|
+
encryptString(payload: string, passphraseProps?: string | null): string;
|
|
425
|
+
decryptString(data: string, passphraseProps?: string | null): string;
|
|
426
|
+
};
|
|
427
|
+
|
|
428
|
+
type InferApiRequest<T> = T extends ApiMethod<infer Req, any> ? Req : never;
|
|
429
|
+
type InferApiResponse<T> = T extends ApiMethod<any, infer Res> ? Res : never;
|
|
430
|
+
declare const useApiStore: <T extends ApiMethod<any, any>>(api: T, key: string) => UseCallReturnType<InferApiRequest<T>, InferApiResponse<T>>;
|
|
431
|
+
|
|
432
|
+
type CreateElementProps<P = unknown> = {
|
|
433
|
+
(element: (props: P) => React__default.JSX.Element, elementName: string): React__default.FC<P>;
|
|
434
|
+
};
|
|
435
|
+
declare const createElement: <T>(element: (props: T) => React__default.JSX.Element, elementName: string) => React__default.FC<T>;
|
|
436
|
+
type SplitElementResult<T extends string> = {
|
|
437
|
+
[K in T]?: React__default.ReactNode;
|
|
438
|
+
} & {
|
|
439
|
+
others?: React__default.ReactNode[];
|
|
440
|
+
};
|
|
441
|
+
declare const splitElement: <T extends string>(children: React__default.ReactNode, elementNames: T[]) => SplitElementResult<T>;
|
|
442
|
+
|
|
443
|
+
declare function generateUUID(): string;
|
|
444
|
+
declare function diffJson(data1: any, data2: any): boolean;
|
|
445
|
+
declare const mappingUndefinedtoNull: (values: any) => any;
|
|
446
|
+
declare function isArray(data: any, length?: number): boolean;
|
|
447
|
+
declare function isNotEmpty(value: unknown): boolean;
|
|
448
|
+
declare const labelFormatter: {
|
|
449
|
+
camelCase: (value?: string) => string;
|
|
450
|
+
snackCase: (value?: string) => string;
|
|
451
|
+
changeAll: (value?: string, capShortWords?: boolean) => string;
|
|
452
|
+
};
|
|
453
|
+
declare function renderChildren<T = unknown>(children: Children, props: T): any;
|
|
454
|
+
declare const getFieldValue: <T, P extends NestedKeyOf<T>, D = undefined>(obj: T, path: P, defaultValue?: D) => PathValue<T, P> | D;
|
|
455
|
+
declare const sorting: {
|
|
456
|
+
desc: <T>(data: T[], field?: NestedKeyOf<T>) => T[];
|
|
457
|
+
asc: <T>(data: T[], field?: NestedKeyOf<T>) => T[];
|
|
458
|
+
};
|
|
459
|
+
declare const summary: <T>(data: T[], field?: NestedKeyOf<T>) => number;
|
|
460
|
+
declare function jsonCopy<T>(data: T): T;
|
|
461
|
+
declare function stableStringify(obj: any): string;
|
|
462
|
+
declare function generateCacheKey(data?: any, cacheKey?: string | any[]): string;
|
|
463
|
+
|
|
464
|
+
type FormatType = {
|
|
465
|
+
display: string;
|
|
466
|
+
value: string;
|
|
467
|
+
};
|
|
468
|
+
type FormatContextProps = {
|
|
469
|
+
date: FormatType;
|
|
470
|
+
month: FormatType;
|
|
471
|
+
year: FormatType;
|
|
472
|
+
dateTime: FormatType;
|
|
473
|
+
time: FormatType;
|
|
474
|
+
number: OptionsNumberProps;
|
|
475
|
+
};
|
|
476
|
+
type BgsCoreProps = {
|
|
477
|
+
passphrase?: string;
|
|
478
|
+
storageKey?: string;
|
|
479
|
+
format: FormatContextProps;
|
|
480
|
+
cache?: Omit<CacheProps, "cacheName" | "cacheKey">;
|
|
481
|
+
};
|
|
482
|
+
declare function useBgsCore(): BgsCoreProps;
|
|
483
|
+
interface BgsCoreProviderProps {
|
|
484
|
+
value: BgsCoreProps;
|
|
485
|
+
}
|
|
486
|
+
declare const BgsCoreProvider: ({ children, value: options }: PropsWithChildren<BgsCoreProviderProps>) => react_jsx_runtime.JSX.Element;
|
|
487
|
+
|
|
488
|
+
export { type ApiActionState, type ApiDefaultFetch, type ApiDefaultMethod, type ApiMethod, type ApiMethodVoid, type ApiResponse, type BgsCoreProps, BgsCoreProvider, type CacheData, type CacheProps, type CallbackHelper, type Children, type ClientCallback, type CombinationType, type CreateElementProps, type DataType, DataTypeEnum, type EncryptedPayload, HttpMethod, type NestedKeyOf, type OptionsCallReturn, type OptionsHelper, type OptionsNumberProps, type PaginationMeta, type PathValue, type ResponseType, type SelectedNested, type SplitElementResult, type UseApiSendProps, type UseApiSendReturnType, type UseCallOptionsProps, type UseCallReturnType, type UseHelperProps, createApiHelper, createElement, decrypt, decryptString, diffJson, encrypt, encryptString, generateCacheKey, generateUUID, getFieldValue, isArray, isNotEmpty, jsonCopy, labelFormatter, mappingUndefinedtoNull, renderChildren, sorting, splitElement, stableStringify, summary, useApiLoad, useApiSend, useApiStore, useBgsCore, useCrypto, useDelay, useFormatted, useInterval, useKeyPress, useScroll, useStorage };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,488 @@
|
|
|
1
|
+
import moment from 'moment';
|
|
2
|
+
import { GenericAbortSignal, AxiosProgressEvent, AxiosResponse, AxiosRequestConfig } from 'axios';
|
|
3
|
+
import * as React$1 from 'react';
|
|
4
|
+
import React__default, { PropsWithChildren } from 'react';
|
|
5
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
6
|
+
|
|
7
|
+
type Children<T = unknown> = ChildFunction<T> | React.ReactNode;
|
|
8
|
+
type ChildFunction<T = unknown> = (props: T) => Children<T>;
|
|
9
|
+
interface PaginationMeta {
|
|
10
|
+
limit: number;
|
|
11
|
+
page: number;
|
|
12
|
+
totalItems: number;
|
|
13
|
+
totalPages: number;
|
|
14
|
+
}
|
|
15
|
+
interface ApiResponse<T = any> {
|
|
16
|
+
status: boolean;
|
|
17
|
+
data: T;
|
|
18
|
+
paging?: PaginationMeta;
|
|
19
|
+
message: string;
|
|
20
|
+
code: number;
|
|
21
|
+
isCancel: boolean;
|
|
22
|
+
isUnauthorization: boolean;
|
|
23
|
+
httpCode: number;
|
|
24
|
+
}
|
|
25
|
+
type CallbackHelper<T = any> = ((response: ApiResponse<T>) => (void | ApiResponse<T>));
|
|
26
|
+
type HandleCallback<T = any> = (props: AxiosResponse<T> & {
|
|
27
|
+
isCancel: boolean;
|
|
28
|
+
isUnauthorization: boolean;
|
|
29
|
+
}, err?: any) => Omit<ApiResponse, "httpCode" | "isCancel" | "isUnauthorization">;
|
|
30
|
+
interface UseHelperProps {
|
|
31
|
+
/** Base URL API */
|
|
32
|
+
url: string;
|
|
33
|
+
/** Header tambahan untuk request */
|
|
34
|
+
headers?: Record<string, string>;
|
|
35
|
+
/** Token autentikasi, bisa string atau null/undefined jika tidak ada */
|
|
36
|
+
token?: string | null | undefined;
|
|
37
|
+
/** Callback yang dijalankan setiap response atau error */
|
|
38
|
+
onCallback: HandleCallback;
|
|
39
|
+
/** Handler khusus jika response tidak authorized */
|
|
40
|
+
onUnauthorized?: (response: ApiResponse) => void;
|
|
41
|
+
/** Fungsi untuk memeriksa otorisasi response, return true jika authorized */
|
|
42
|
+
handleAuthorization?: (response: ApiResponse, options?: OptionsHelper) => boolean;
|
|
43
|
+
/** Fungsi untuk menampilkan toast/notification berdasarkan response */
|
|
44
|
+
handleToast?: (response: ApiResponse) => void;
|
|
45
|
+
/**
|
|
46
|
+
* Fungsi manipulasi/preparasi data sebelum dikirim ke server.
|
|
47
|
+
*/
|
|
48
|
+
beforeRequest?: (data: any) => any;
|
|
49
|
+
/** Jika true, toast tidak ditampilkan ketika request dibatalkan */
|
|
50
|
+
disabledToastWhenCancel?: boolean;
|
|
51
|
+
/**
|
|
52
|
+
* Jika true, maka cookie seperti HttpOnly akan dikirim dalam request.
|
|
53
|
+
* Digunakan saat autentikasi berbasis cookie (bukan token di header Authorization).
|
|
54
|
+
*/
|
|
55
|
+
withCredentials?: boolean;
|
|
56
|
+
/**
|
|
57
|
+
* Jika `true`, data request akan dienkripsi sebelum dikirim ke server.
|
|
58
|
+
* Pastikan server dapat mendekripsi payload ini.
|
|
59
|
+
*/
|
|
60
|
+
encryptRequest?: boolean;
|
|
61
|
+
/**
|
|
62
|
+
* Jika `true`, data response dari server akan didekripsi.
|
|
63
|
+
* Asumsinya response telah terenkripsi sebelumnya oleh server.
|
|
64
|
+
*/
|
|
65
|
+
encryptResponse?: boolean;
|
|
66
|
+
/**
|
|
67
|
+
* Kata sandi atau kunci untuk proses enkripsi dan dekripsi data.
|
|
68
|
+
* Digunakan bersama `encryptRequest` dan `encryptResponse` untuk memastikan
|
|
69
|
+
* data terenkripsi dan terdekripsi dengan algoritma yang sama di sisi client dan server.
|
|
70
|
+
* Harus disepakati antara client dan server.
|
|
71
|
+
*
|
|
72
|
+
* Secara default, nilai passphrase akan diambil dari context `bgsCore` jika ada.
|
|
73
|
+
*/
|
|
74
|
+
passphrase?: string | null;
|
|
75
|
+
}
|
|
76
|
+
interface OptionsHelper {
|
|
77
|
+
/** Menampilkan toast/info ketika response success */
|
|
78
|
+
infoSuccess: boolean;
|
|
79
|
+
/** Menampilkan toast/info ketika response error */
|
|
80
|
+
infoError: boolean;
|
|
81
|
+
/** Menyisipkan Authorization token.
|
|
82
|
+
* - `true` → pakai token default dari `UseHelperProps`
|
|
83
|
+
* - `string` → pakai token string ini
|
|
84
|
+
* - `false` → tidak menyisipkan token
|
|
85
|
+
*/
|
|
86
|
+
token: boolean | string;
|
|
87
|
+
/** Header tambahan untuk request */
|
|
88
|
+
headers: Record<string, string>;
|
|
89
|
+
/** Signal dari AbortController, bisa dipakai untuk cancel request */
|
|
90
|
+
signal: GenericAbortSignal;
|
|
91
|
+
/** Response type seperti 'json', 'blob', dll */
|
|
92
|
+
responseType: ResponseType;
|
|
93
|
+
/** Callback ketika ada upload progress (biasanya untuk form upload) */
|
|
94
|
+
onUploadProgress: (props: AxiosProgressEvent) => void;
|
|
95
|
+
/** Handler saat request unauthorized (status 401/403), bisa override default */
|
|
96
|
+
onUnauthorized: (response: ApiResponse) => void;
|
|
97
|
+
/** Jika `true`, maka onUnauthorized tidak akan dijalankan */
|
|
98
|
+
disabledHandleUnauthorized: boolean;
|
|
99
|
+
/** Jika `true`, maka tidak akan munculkan toast saat request dibatalkan (abort) */
|
|
100
|
+
disabledToastWhenCancel?: boolean;
|
|
101
|
+
/**
|
|
102
|
+
* Jika true, maka cookie seperti HttpOnly akan dikirim dalam request.
|
|
103
|
+
* Digunakan saat autentikasi berbasis cookie (bukan token di header Authorization).
|
|
104
|
+
*/
|
|
105
|
+
withCredentials?: boolean;
|
|
106
|
+
/**
|
|
107
|
+
* Jika `true`, data request akan dienkripsi sebelum dikirim ke server.
|
|
108
|
+
* Pastikan server dapat mendekripsi payload ini.
|
|
109
|
+
*/
|
|
110
|
+
encryptRequest?: boolean;
|
|
111
|
+
/**
|
|
112
|
+
* Jika `true`, data response dari server akan didekripsi.
|
|
113
|
+
* Asumsinya response telah terenkripsi sebelumnya oleh server.
|
|
114
|
+
*/
|
|
115
|
+
encryptResponse?: boolean;
|
|
116
|
+
/**
|
|
117
|
+
* Kata sandi atau kunci untuk proses enkripsi dan dekripsi data.
|
|
118
|
+
* Digunakan bersama `encryptRequest` dan `encryptResponse` untuk memastikan
|
|
119
|
+
* data terenkripsi dan terdekripsi dengan algoritma yang sama di sisi client dan server.
|
|
120
|
+
* Harus disepakati antara client dan server.
|
|
121
|
+
*
|
|
122
|
+
* Secara default, nilai passphrase akan diambil dari context `bgsCore` jika ada.
|
|
123
|
+
*/
|
|
124
|
+
passphrase?: string | true | null;
|
|
125
|
+
}
|
|
126
|
+
type ClientCallback<T> = (response: AxiosResponse<T>, err?: any) => any;
|
|
127
|
+
declare enum HttpMethod {
|
|
128
|
+
POST = "POST",
|
|
129
|
+
PUT = "PUT",
|
|
130
|
+
PATCH = "PATCH",
|
|
131
|
+
DELETE = "DELETE",
|
|
132
|
+
GET = "GET"
|
|
133
|
+
}
|
|
134
|
+
type ApiMethod<DReq = any, DRes = DReq> = (data: DReq, callback?: CallbackHelper<DRes>, options?: Partial<OptionsHelper>) => Promise<ApiResponse<DRes>>;
|
|
135
|
+
type ApiMethodVoid<DRes = any> = <Res = DRes>(callback?: CallbackHelper<Res>, options?: Partial<OptionsHelper>) => Promise<ApiResponse<Res>>;
|
|
136
|
+
type ApiDefaultMethod<DReq = any, DRes = DReq> = <Req = DReq, Res = DRes>(url: string, data: Req, callback?: CallbackHelper<Res>, options?: Partial<OptionsHelper>) => Promise<ApiResponse<Res>>;
|
|
137
|
+
type ApiDefaultFetch<DRes = any> = <Res = DRes>(url: string, callback?: CallbackHelper<Res>, options?: Partial<OptionsHelper>) => Promise<ApiResponse<Res>>;
|
|
138
|
+
type ResponseType = 'arraybuffer' | 'blob' | 'document' | 'json' | 'text' | 'stream' | 'formdata';
|
|
139
|
+
type OptionsCallReturn<DReq, DRes = DReq> = Partial<ApiResponse<DRes>> & {
|
|
140
|
+
/** Status loading saat request berlangsung */
|
|
141
|
+
loading: boolean;
|
|
142
|
+
/** Menjalankan ulang request dengan payload & config sebelumnya */
|
|
143
|
+
refresh: (force?: boolean) => void;
|
|
144
|
+
/** Membatalkan request yang sedang berjalan */
|
|
145
|
+
abort: () => void;
|
|
146
|
+
/** Clear/reset response dan status terkait */
|
|
147
|
+
clear: () => void;
|
|
148
|
+
/** Response dari server (bisa undefined/null jika belum ada atau sudah di-clear) */
|
|
149
|
+
response: ApiResponse<DRes> | undefined | null;
|
|
150
|
+
/**
|
|
151
|
+
* Mengkloning call API dengan payload/config baru.
|
|
152
|
+
* Cocok untuk membuat instance baru tanpa mempengaruhi state lama.
|
|
153
|
+
*/
|
|
154
|
+
clone: <T = unknown>(newPayload?: DReq, newConfig?: Partial<UseCallOptionsProps<DReq, DRes & T>>) => UseCallReturnType<DReq, DRes>;
|
|
155
|
+
/** Menunjukkan apakah request terakhir dibatalkan (via abort).
|
|
156
|
+
* Berguna untuk mengabaikan cache saat refresh berikutnya.
|
|
157
|
+
*/
|
|
158
|
+
isCancel: boolean;
|
|
159
|
+
};
|
|
160
|
+
type UseCallReturnType<DReq, DRes = DReq> = [
|
|
161
|
+
DRes | undefined,
|
|
162
|
+
OptionsCallReturn<DReq, DRes>
|
|
163
|
+
];
|
|
164
|
+
interface TimeoutConfig {
|
|
165
|
+
value: number;
|
|
166
|
+
unit: moment.DurationInputArg2;
|
|
167
|
+
}
|
|
168
|
+
interface CacheProps {
|
|
169
|
+
/**
|
|
170
|
+
* Nama cache yang akan digunakan sebagai container atau namespace.
|
|
171
|
+
* Biasanya untuk membedakan jenis cache yang berbeda.
|
|
172
|
+
*/
|
|
173
|
+
cacheName?: string;
|
|
174
|
+
/**
|
|
175
|
+
* Kunci unik untuk menyimpan dan mengambil data dari cache.
|
|
176
|
+
* Biasanya merepresentasikan entri spesifik dalam cacheName.
|
|
177
|
+
*/
|
|
178
|
+
cacheKey?: string | Array<string | number | boolean | null | undefined | Record<string, any>>;
|
|
179
|
+
/**
|
|
180
|
+
* Durasi timeout cache sebelum dianggap kedaluwarsa.
|
|
181
|
+
* Bisa berupa angka (dalam satuan detik) atau objek konfigurasi timeout.
|
|
182
|
+
*/
|
|
183
|
+
timeout?: number | TimeoutConfig;
|
|
184
|
+
/**
|
|
185
|
+
* Jika true, data cache akan dipertahankan walau halaman direfresh atau ditutup.
|
|
186
|
+
* Jika false atau tidak diisi, cache akan dihapus saat halaman ditutup.
|
|
187
|
+
*/
|
|
188
|
+
persistence?: boolean;
|
|
189
|
+
}
|
|
190
|
+
interface CacheData<DRes> {
|
|
191
|
+
/**
|
|
192
|
+
* Waktu kedaluwarsa cache dalam bentuk ISO string.
|
|
193
|
+
*/
|
|
194
|
+
expired: string;
|
|
195
|
+
/**
|
|
196
|
+
* Data respon API yang disimpan dalam cache.
|
|
197
|
+
*/
|
|
198
|
+
data: ApiResponse<DRes>;
|
|
199
|
+
}
|
|
200
|
+
interface UseCallOptionsProps<DReq, DRes> extends OptionsHelper {
|
|
201
|
+
/**
|
|
202
|
+
* Jika true, proses request & response akan dicetak ke console.
|
|
203
|
+
*/
|
|
204
|
+
logging: boolean;
|
|
205
|
+
/**
|
|
206
|
+
* Fungsi manipulasi/preparasi data sebelum dikirim ke server.
|
|
207
|
+
*/
|
|
208
|
+
beforeRequest: (request: DReq) => DReq;
|
|
209
|
+
/**
|
|
210
|
+
* Fungsi manipulasi respon dari server sebelum disimpan atau ditampilkan.
|
|
211
|
+
*/
|
|
212
|
+
afterResponse: (response: DRes) => DRes;
|
|
213
|
+
/**
|
|
214
|
+
* Hook yang dijalankan sebelum request diproses.
|
|
215
|
+
*/
|
|
216
|
+
onBeforeRequest: (request: DReq) => void;
|
|
217
|
+
/**
|
|
218
|
+
* Hook yang dijalankan setelah respon diterima dari server.
|
|
219
|
+
*/
|
|
220
|
+
onAfterResponse: (response: ApiResponse<DRes>) => void;
|
|
221
|
+
/**
|
|
222
|
+
* Daftar dependency yang dapat memicu ulang pemanggilan API jika berubah.
|
|
223
|
+
*/
|
|
224
|
+
trigger: any[];
|
|
225
|
+
/**
|
|
226
|
+
* Jika true, maka request tidak dijalankan otomatis hingga dipanggil secara manual.
|
|
227
|
+
*/
|
|
228
|
+
hold: boolean;
|
|
229
|
+
/**
|
|
230
|
+
* Callback yang dipanggil setiap kali data berubah.
|
|
231
|
+
*/
|
|
232
|
+
onChange: (data: DReq, options: OptionsCallReturn<DReq, DRes>) => void;
|
|
233
|
+
/**
|
|
234
|
+
* Mengaktifkan cache untuk menyimpan respon API.
|
|
235
|
+
* Bisa true (default pengaturan) atau objek konfigurasi `CacheProps`.
|
|
236
|
+
*/
|
|
237
|
+
cache: true | CacheProps;
|
|
238
|
+
/**
|
|
239
|
+
* Interval auto refresh data. Bisa dalam detik atau konfigurasi TimeoutConfig.
|
|
240
|
+
*/
|
|
241
|
+
refreshInterval: number | TimeoutConfig;
|
|
242
|
+
/**
|
|
243
|
+
* Menentukan apakah data akan difetch ulang saat tab aktif kembali.
|
|
244
|
+
*/
|
|
245
|
+
refetchOnWindowFocus: boolean;
|
|
246
|
+
/**
|
|
247
|
+
* Nama unik untuk store/context/cache dari request API ini.
|
|
248
|
+
*
|
|
249
|
+
* Properti ini digunakan sebagai identitas untuk:
|
|
250
|
+
* - Menyimpan hasil request di global store agar bisa diakses antar komponen.
|
|
251
|
+
* - Menamai cache secara otomatis jika `cacheName` tidak diatur manual.
|
|
252
|
+
* - Menghindari konflik antar pemanggilan API yang berbeda.
|
|
253
|
+
*
|
|
254
|
+
* Disarankan menggunakan nama yang deskriptif dan unik per endpoint,
|
|
255
|
+
* seperti: "historyAbsence", "dashboardSummary", "userProfile", dst.
|
|
256
|
+
*
|
|
257
|
+
* Contoh penggunaan bersama context:
|
|
258
|
+
* const [data, options] = useApiStore(api.absence.history, "historyAbsence")
|
|
259
|
+
*/
|
|
260
|
+
storeName: string;
|
|
261
|
+
}
|
|
262
|
+
interface UseApiSendProps<Req, Res> extends Partial<OptionsHelper> {
|
|
263
|
+
/**
|
|
264
|
+
* Callback ketika respon berhasil.
|
|
265
|
+
*/
|
|
266
|
+
onSuccess?: OnCallback<Res>;
|
|
267
|
+
/**
|
|
268
|
+
* Callback ketika terjadi error.
|
|
269
|
+
*/
|
|
270
|
+
onError?: OnCallback<Res>;
|
|
271
|
+
/**
|
|
272
|
+
* Jika true, proses request & response akan dicetak ke console.
|
|
273
|
+
*/
|
|
274
|
+
logging?: boolean;
|
|
275
|
+
/**
|
|
276
|
+
* Fungsi manipulasi sebelum request dikirim.
|
|
277
|
+
*/
|
|
278
|
+
beforeRequest?: (request: Req) => Req;
|
|
279
|
+
/**
|
|
280
|
+
* Fungsi manipulasi setelah respon diterima.
|
|
281
|
+
*/
|
|
282
|
+
afterResponse?: OnCallback<Res>;
|
|
283
|
+
/**
|
|
284
|
+
* Jika true, request akan otomatis dibatalkan saat komponen unmount.
|
|
285
|
+
*/
|
|
286
|
+
abortOnUnmount?: boolean;
|
|
287
|
+
}
|
|
288
|
+
type OnCallback<T = any> = (response: ApiResponse<T>) => void;
|
|
289
|
+
type ApiActionState<Res> = Partial<ApiResponse<Res>> & {
|
|
290
|
+
/** Membatalkan request yang sedang berjalan */
|
|
291
|
+
abort: () => void;
|
|
292
|
+
/** Clear/reset response dan status terkait */
|
|
293
|
+
reset: () => void;
|
|
294
|
+
/** Status loading saat request berlangsung */
|
|
295
|
+
loading: boolean;
|
|
296
|
+
/** Progress upload/download, nilai antara 0 - 100 */
|
|
297
|
+
progress: number;
|
|
298
|
+
};
|
|
299
|
+
type UseApiSendReturnType<Req, Res> = Req extends undefined ? [
|
|
300
|
+
(values?: Req) => void,
|
|
301
|
+
ApiActionState<Res>
|
|
302
|
+
] : [
|
|
303
|
+
(values: Req) => void,
|
|
304
|
+
ApiActionState<Res>
|
|
305
|
+
];
|
|
306
|
+
declare enum DataTypeEnum {
|
|
307
|
+
number = "number",
|
|
308
|
+
currency = "currency",
|
|
309
|
+
percent = "percent",
|
|
310
|
+
date = "date",
|
|
311
|
+
dateTime = "dateTime",
|
|
312
|
+
month = "month",
|
|
313
|
+
year = "year",
|
|
314
|
+
time = "time",
|
|
315
|
+
timestamp = "timestamp",
|
|
316
|
+
string = "string",
|
|
317
|
+
textarea = "textarea",
|
|
318
|
+
code = "code",
|
|
319
|
+
password = "password",
|
|
320
|
+
boolean = "boolean",
|
|
321
|
+
toggle = "toggle",// Optional, untuk UI switch boolean
|
|
322
|
+
email = "email",
|
|
323
|
+
phone = "phone",
|
|
324
|
+
url = "url",
|
|
325
|
+
json = "json",
|
|
326
|
+
file = "file",
|
|
327
|
+
image = "image",
|
|
328
|
+
array = "array",
|
|
329
|
+
object = "object",
|
|
330
|
+
enum = "enum",
|
|
331
|
+
user = "user",
|
|
332
|
+
department = "department",
|
|
333
|
+
status = "status"
|
|
334
|
+
}
|
|
335
|
+
type DataType = `${DataTypeEnum}`;
|
|
336
|
+
type NestedKeyOf<T> = T extends object ? T extends Array<infer U> ? `${number}` | `${number}.${NestedKeyOf<U>}` : {
|
|
337
|
+
[K in keyof T]: T[K] extends Array<infer U> ? `${K & string}` | `${K & string}[${number}]` | `${K & string}[${number}].${NestedKeyOf<U>}` : T[K] extends object ? `${K & string}` | `${K & string}.${NestedKeyOf<T[K]>}` : `${K & string}`;
|
|
338
|
+
}[keyof T] : never;
|
|
339
|
+
type PathValue<T, P extends string> = P extends `${infer K}[${infer I}].${infer R}` ? K extends keyof T ? T[K] extends Array<infer U> ? PathValue<U, R> : never : never : P extends `${infer K}[${infer I}]` ? K extends keyof T ? T[K] extends Array<infer U> ? U : never : never : P extends `${infer K}.${infer R}` ? K extends keyof T ? PathValue<T[K], R> : never : P extends keyof T ? T[P] : never;
|
|
340
|
+
type SelectedNested<T> = Partial<Record<NestedKeyOf<T>, any>>;
|
|
341
|
+
|
|
342
|
+
declare function useApiLoad<DRes>(api: ApiMethodVoid<DRes>, options?: Partial<UseCallOptionsProps<undefined, DRes>>): UseCallReturnType<undefined, DRes>;
|
|
343
|
+
declare function useApiLoad<DReq, DRes>(api: ApiMethod<DReq, DRes>, data: DReq, options?: Partial<UseCallOptionsProps<DReq, DRes>>): UseCallReturnType<DReq, DRes>;
|
|
344
|
+
|
|
345
|
+
declare function useDelay(s: number, callback?: Function): Promise<unknown>;
|
|
346
|
+
|
|
347
|
+
type OptionsNumberProps = {
|
|
348
|
+
thouSep: string;
|
|
349
|
+
decSep: string;
|
|
350
|
+
decDigits: number | "auto";
|
|
351
|
+
};
|
|
352
|
+
type OptionsNumber = OptionsNumberProps & {
|
|
353
|
+
dataType: Extract<DataType, "number">;
|
|
354
|
+
method?: "round" | "ceil" | "floor";
|
|
355
|
+
};
|
|
356
|
+
type DataTypeDateGroup = Extract<DataType, "date" | "dateTime" | "month" | "year" | "time">;
|
|
357
|
+
type OptionsDate = {
|
|
358
|
+
dataType: DataTypeDateGroup;
|
|
359
|
+
display: string;
|
|
360
|
+
value: string;
|
|
361
|
+
};
|
|
362
|
+
type OptionsBoolean = {
|
|
363
|
+
dataType: Extract<DataType, "boolean">;
|
|
364
|
+
trueLabel?: string;
|
|
365
|
+
falseLabel?: string;
|
|
366
|
+
};
|
|
367
|
+
type OptionsString = {
|
|
368
|
+
dataType: Extract<DataType, "string">;
|
|
369
|
+
capitalize?: boolean;
|
|
370
|
+
ellipsis?: number;
|
|
371
|
+
};
|
|
372
|
+
type UseFormattedOptions<T extends DataType> = T extends "number" ? Partial<OptionsNumber> : T extends DataTypeDateGroup ? Partial<OptionsDate> : T extends "boolean" ? Partial<OptionsBoolean> : T extends "string" ? Partial<OptionsString> : never;
|
|
373
|
+
declare const useFormatted: <T extends DataType>(value: unknown, dataType: T, options?: UseFormattedOptions<T>) => string;
|
|
374
|
+
|
|
375
|
+
declare function useInterval<P extends Function>(callback: P, { interval, lead }: {
|
|
376
|
+
interval: number;
|
|
377
|
+
lead?: boolean;
|
|
378
|
+
}): void;
|
|
379
|
+
|
|
380
|
+
type CombinationType = "ctrl" | "alt" | "shift";
|
|
381
|
+
declare function useKeyPress(targetKey: string | number, combination?: CombinationType | CombinationType[], stopPropagation?: boolean): boolean;
|
|
382
|
+
|
|
383
|
+
declare const createApiHelper: <DReq = any, DRes = any>({ url, token, beforeRequest, onCallback, headers: headerProps, onUnauthorized, handleToast, handleAuthorization, disabledToastWhenCancel: disabledToastWhenCancelProps, withCredentials, encryptRequest: encryptRequestDefault, encryptResponse: encryptResponseDefault, passphrase, }: UseHelperProps) => {
|
|
384
|
+
client: (props: AxiosRequestConfig, callback?: ClientCallback<DRes>) => Promise<any>;
|
|
385
|
+
post: ApiDefaultMethod<DReq, DRes>;
|
|
386
|
+
put: ApiDefaultMethod<DReq, DRes>;
|
|
387
|
+
patch: ApiDefaultMethod<DReq, DRes>;
|
|
388
|
+
delete: ApiDefaultFetch<DRes>;
|
|
389
|
+
get: ApiDefaultFetch<DRes>;
|
|
390
|
+
upload: ApiDefaultMethod<DReq, DRes>;
|
|
391
|
+
};
|
|
392
|
+
|
|
393
|
+
declare function useApiSend<DReq, DRes>(api: ApiMethod<DReq, DRes>, props?: UseApiSendProps<DReq, DRes>): UseApiSendReturnType<DReq, DRes>;
|
|
394
|
+
declare function useApiSend<DRes>(api: ApiMethodVoid<DRes>, props?: UseApiSendProps<undefined, DRes>): UseApiSendReturnType<undefined, DRes>;
|
|
395
|
+
|
|
396
|
+
type Direction = "vertical" | "horizontal";
|
|
397
|
+
declare function useScroll<T extends HTMLDivElement>(direction?: Direction): {
|
|
398
|
+
ref: React$1.RefObject<T | null>;
|
|
399
|
+
showStartShadow: boolean;
|
|
400
|
+
showEndShadow: boolean;
|
|
401
|
+
};
|
|
402
|
+
|
|
403
|
+
declare const useStorage: () => {
|
|
404
|
+
save: <T = any>(key: string, data: T) => void;
|
|
405
|
+
get: <T = any>(key: string) => T | null;
|
|
406
|
+
clear: (key?: string) => void;
|
|
407
|
+
useWatchStorage: <T = any>(key: string) => T | null;
|
|
408
|
+
};
|
|
409
|
+
|
|
410
|
+
type EncryptedPayload = {
|
|
411
|
+
salt: string;
|
|
412
|
+
iv: string;
|
|
413
|
+
encrypted: string;
|
|
414
|
+
};
|
|
415
|
+
declare function encrypt<T = unknown>(payload: T, passphrase: string): EncryptedPayload;
|
|
416
|
+
declare function decrypt<T = unknown>(cipherPayload: EncryptedPayload, passphrase: string): T;
|
|
417
|
+
declare function encryptString(plain: string, passphrase: string): string;
|
|
418
|
+
declare function decryptString(encryptedJson: string, passphrase: string): string;
|
|
419
|
+
|
|
420
|
+
declare function useCrypto(): {
|
|
421
|
+
passphrase: string | undefined;
|
|
422
|
+
encrypt<T>(payload: T, passphraseProps?: string | null): EncryptedPayload;
|
|
423
|
+
decrypt<T>(data: EncryptedPayload, passphraseProps?: string | null): T;
|
|
424
|
+
encryptString(payload: string, passphraseProps?: string | null): string;
|
|
425
|
+
decryptString(data: string, passphraseProps?: string | null): string;
|
|
426
|
+
};
|
|
427
|
+
|
|
428
|
+
type InferApiRequest<T> = T extends ApiMethod<infer Req, any> ? Req : never;
|
|
429
|
+
type InferApiResponse<T> = T extends ApiMethod<any, infer Res> ? Res : never;
|
|
430
|
+
declare const useApiStore: <T extends ApiMethod<any, any>>(api: T, key: string) => UseCallReturnType<InferApiRequest<T>, InferApiResponse<T>>;
|
|
431
|
+
|
|
432
|
+
type CreateElementProps<P = unknown> = {
|
|
433
|
+
(element: (props: P) => React__default.JSX.Element, elementName: string): React__default.FC<P>;
|
|
434
|
+
};
|
|
435
|
+
declare const createElement: <T>(element: (props: T) => React__default.JSX.Element, elementName: string) => React__default.FC<T>;
|
|
436
|
+
type SplitElementResult<T extends string> = {
|
|
437
|
+
[K in T]?: React__default.ReactNode;
|
|
438
|
+
} & {
|
|
439
|
+
others?: React__default.ReactNode[];
|
|
440
|
+
};
|
|
441
|
+
declare const splitElement: <T extends string>(children: React__default.ReactNode, elementNames: T[]) => SplitElementResult<T>;
|
|
442
|
+
|
|
443
|
+
declare function generateUUID(): string;
|
|
444
|
+
declare function diffJson(data1: any, data2: any): boolean;
|
|
445
|
+
declare const mappingUndefinedtoNull: (values: any) => any;
|
|
446
|
+
declare function isArray(data: any, length?: number): boolean;
|
|
447
|
+
declare function isNotEmpty(value: unknown): boolean;
|
|
448
|
+
declare const labelFormatter: {
|
|
449
|
+
camelCase: (value?: string) => string;
|
|
450
|
+
snackCase: (value?: string) => string;
|
|
451
|
+
changeAll: (value?: string, capShortWords?: boolean) => string;
|
|
452
|
+
};
|
|
453
|
+
declare function renderChildren<T = unknown>(children: Children, props: T): any;
|
|
454
|
+
declare const getFieldValue: <T, P extends NestedKeyOf<T>, D = undefined>(obj: T, path: P, defaultValue?: D) => PathValue<T, P> | D;
|
|
455
|
+
declare const sorting: {
|
|
456
|
+
desc: <T>(data: T[], field?: NestedKeyOf<T>) => T[];
|
|
457
|
+
asc: <T>(data: T[], field?: NestedKeyOf<T>) => T[];
|
|
458
|
+
};
|
|
459
|
+
declare const summary: <T>(data: T[], field?: NestedKeyOf<T>) => number;
|
|
460
|
+
declare function jsonCopy<T>(data: T): T;
|
|
461
|
+
declare function stableStringify(obj: any): string;
|
|
462
|
+
declare function generateCacheKey(data?: any, cacheKey?: string | any[]): string;
|
|
463
|
+
|
|
464
|
+
type FormatType = {
|
|
465
|
+
display: string;
|
|
466
|
+
value: string;
|
|
467
|
+
};
|
|
468
|
+
type FormatContextProps = {
|
|
469
|
+
date: FormatType;
|
|
470
|
+
month: FormatType;
|
|
471
|
+
year: FormatType;
|
|
472
|
+
dateTime: FormatType;
|
|
473
|
+
time: FormatType;
|
|
474
|
+
number: OptionsNumberProps;
|
|
475
|
+
};
|
|
476
|
+
type BgsCoreProps = {
|
|
477
|
+
passphrase?: string;
|
|
478
|
+
storageKey?: string;
|
|
479
|
+
format: FormatContextProps;
|
|
480
|
+
cache?: Omit<CacheProps, "cacheName" | "cacheKey">;
|
|
481
|
+
};
|
|
482
|
+
declare function useBgsCore(): BgsCoreProps;
|
|
483
|
+
interface BgsCoreProviderProps {
|
|
484
|
+
value: BgsCoreProps;
|
|
485
|
+
}
|
|
486
|
+
declare const BgsCoreProvider: ({ children, value: options }: PropsWithChildren<BgsCoreProviderProps>) => react_jsx_runtime.JSX.Element;
|
|
487
|
+
|
|
488
|
+
export { type ApiActionState, type ApiDefaultFetch, type ApiDefaultMethod, type ApiMethod, type ApiMethodVoid, type ApiResponse, type BgsCoreProps, BgsCoreProvider, type CacheData, type CacheProps, type CallbackHelper, type Children, type ClientCallback, type CombinationType, type CreateElementProps, type DataType, DataTypeEnum, type EncryptedPayload, HttpMethod, type NestedKeyOf, type OptionsCallReturn, type OptionsHelper, type OptionsNumberProps, type PaginationMeta, type PathValue, type ResponseType, type SelectedNested, type SplitElementResult, type UseApiSendProps, type UseApiSendReturnType, type UseCallOptionsProps, type UseCallReturnType, type UseHelperProps, createApiHelper, createElement, decrypt, decryptString, diffJson, encrypt, encryptString, generateCacheKey, generateUUID, getFieldValue, isArray, isNotEmpty, jsonCopy, labelFormatter, mappingUndefinedtoNull, renderChildren, sorting, splitElement, stableStringify, summary, useApiLoad, useApiSend, useApiStore, useBgsCore, useCrypto, useDelay, useFormatted, useInterval, useKeyPress, useScroll, useStorage };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import j from"moment";import{useCallback as De,useEffect as k,useMemo as Ae,useRef as se,useState as V}from"react";function $e(){let e=()=>Math.random()*16%16|0;return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,t=>(t==="x"?e():e()&3|8).toString(16))}function je(e,t){try{return JSON.stringify(e)!==JSON.stringify(t)}catch{return!1}}var Ve=e=>(Object.keys(e).forEach(t=>{e[t]===void 0&&(e[t]=null)}),e);function ze(e,t){let n=!1;return e&&typeof e=="object"&&Array.isArray(e)&&(typeof t=="number"?e.length>t&&(n=!0):n=!0),n}function q(e){return!(e==null||typeof e=="string"&&e.trim()===""||Array.isArray(e)&&e.length===0||typeof e=="object"&&e!==null&&!Array.isArray(e)&&Object.keys(e).length===0)}var X={camelCase:(e="")=>(e=e.split(".").map(t=>(t=t.charAt(0).toUpperCase()+t.slice(1),t)).join(" "),e=e.replace(/([a-z0-9])([A-Z])/g,"$1 $2"),e.charAt(0).toUpperCase()+e.slice(1)),snackCase:(e="")=>{let n=e.replace(/_([a-z])/g,(o,a)=>a.toUpperCase()).replace(/([A-Z])/g," $1");return n=n.charAt(0).toUpperCase()+n.slice(1),n},changeAll:(e="",t=!1)=>{let n="";try{e=e?.split(".")[e?.split(".")?.length-1],e=e?.split("[]")[e?.split("[]")?.length-1],n=X.snackCase(X.camelCase(e)),t&&(n=n?.split(" ")?.map(o=>o?.length<=3?o?.toUpperCase():o)?.join(" "))}catch{}return n?.trim()}};function Je(e,t){return typeof e=="function"?e(t):e}var O=(e,t,n="")=>{if(!e)return n;if(e.hasOwnProperty(t))return e[t];let o=t.replace(/\[(\d+)\]/g,".$1").split("."),a=e;for(let r of o){if(a==null)return n;a=a[r]}return a===void 0?n:a},We={desc:(e,t)=>(e||(e=[]),e.sort((n,o)=>{if(t){let a=O(n,t)?O(n,t):"",r=O(o,t)?O(n,t):"";return a<r?1:-1}else return n<o?1:-1})),asc:(e,t)=>(e||(e=[]),e.sort((n,o)=>{if(t){let a=O(n,t)?O(n,t):"",r=O(o,t)?O(o,t):"";return a>r?1:-1}else return n>o?1:-1}))},Ge=(e,t)=>{Array.isArray(e)||(e=[]);let n=[];return n=e.map(o=>Number(t?O(o,t)||0:o||0)),n.reduce((o,a)=>(o||0)+(a||0),0)||0};function Xe(e){try{return e&&JSON.parse(JSON.stringify(e))}catch{return e}}function me(e){let t=new WeakSet;return JSON.stringify(e,function(n,o){return o!==null&&typeof o=="object"?t.has(o)?void 0:(t.add(o),Object.keys(o).sort().reduce((a,r)=>(a[r]=o[r],a),{})):o})??""}function _(e,t){return me([t??"undefined",e??"undefined"])}import{createContext as ye,useContext as Re}from"react";import{jsx as he}from"react/jsx-runtime";var Z=ye(void 0);function N(){let e=Re(Z);return e||{}}var ge=({children:e,value:t})=>{let n={...t};return he(Z.Provider,{value:n,children:e})};import{useCallback as L,useEffect as xe,useState as Te}from"react";import Q from"crypto-js/aes";import ee from"crypto-js/pbkdf2";import be from"crypto-js/enc-utf8";import K from"crypto-js/enc-base64";import Y from"crypto-js/lib-typedarrays";function I(e,t){let n=Y.random(16),o=Y.random(16),a=ee(t,n,{keySize:256/32,iterations:1e3}),r=Q.encrypt(JSON.stringify(e),a,{iv:o}).toString();return{salt:n.toString(K),iv:o.toString(K),encrypted:r}}function H(e,t){let{salt:n,iv:o,encrypted:a}=e,r=ee(t,K.parse(n),{keySize:256/32,iterations:1e3}),i=Q.decrypt(a,r,{iv:K.parse(o)}).toString(be);return JSON.parse(i)}function te(e,t){return JSON.stringify(I(e,t))}function re(e,t){return H(JSON.parse(e),t)}function M(){let{passphrase:e}=N();return{passphrase:e,encrypt(t,n){return I(t,n||e)},decrypt(t,n){return H(t,n||e)},encryptString(t,n){return te(t,n||e)},decryptString(t,n){return re(t,n||e)}}}var ne=()=>{let{encrypt:e,decrypt:t}=M(),n=L((c,i)=>{try{let d=e(i);localStorage.setItem(c,JSON.stringify(d))}catch(d){console.error("Failed to save to storage:",d)}},[e]),o=L(c=>{try{let i=localStorage.getItem(c);return i?t(JSON.parse(i)):null}catch(i){return console.error("Failed to get from storage:",i),null}},[t]),a=c=>{let[i,d]=Te(()=>{try{let l=localStorage.getItem(c);return l?t(JSON.parse(l)):null}catch(l){return console.error("Failed to parse localStorage value",l),null}});return xe(()=>{let l=R=>{if(R.key===c)if(R.newValue)try{d(t(JSON.parse(R.newValue)))}catch(S){console.error("Decrypt error from storage event",S)}else d(null)};return window.addEventListener("storage",l),()=>window.removeEventListener("storage",l)},[c,t]),i},r=L(c=>{c?localStorage.removeItem(c):localStorage.clear()},[]);return{save:n,get:o,clear:r,useWatchStorage:a}};import{useSyncExternalStore as Ce}from"react";function oe(e){let t=e,n=new Set;function o(){return t}function a(i){return n.add(i),()=>n.delete(i)}function r(i){typeof i=="function"?t=i(t):t=i,n.forEach(d=>d())}function c(i){return Ce(a,()=>i?i(t):t,()=>i?i(t):t)}return{getSnapshot:o,subscribe:a,setState:r,useStore:c}}var $=new Map;function F(e){return $.has(e)||$.set(e,oe([null,{}])),$.get(e)}function Se(e,t,n){let o=arguments.length===3,a=o?t:void 0,r=o?n:t,{storageKey:c,cache:i}=N(),d=ne(),[l,R]=V(!1),[S,b]=V(!1),[T,C]=V(),g=se(void 0),x=se(null),{cacheName:P,cacheKey:A,timeout:J,timeoutUnit:W,persistence:G}=Ae(()=>{let p=c?d.get(c):void 0,s=typeof r?.cache=="object"?r?.cache?.cacheName??e.name:e.name,f=_({...a,session:p},typeof r?.cache=="object"?r?.cache?.cacheKey:void 0),y=!1;typeof i?.persistence=="boolean"&&(y=i?.persistence),typeof r?.cache=="object"&&typeof r?.cache?.persistence=="boolean"&&(y=r?.cache?.persistence??!1);let h=60*5,u="s";return q(i?.timeout)&&(typeof i?.timeout=="number"?(h=i.timeout,u="s"):typeof i?.timeout=="object"&&(h=i?.timeout.value,u=i?.timeout.unit)),r?.cache&&typeof r.cache!="boolean"&&(typeof r.cache.timeout=="number"?(h=r.cache.timeout,u="s"):typeof r.cache.timeout=="object"&&(h=r.cache.timeout.value,u=r.cache.timeout.unit)),{cacheName:s,cacheKey:f,timeout:h,timeoutUnit:u,persistence:y}},[r?.cache,c,i]);k(()=>{let p=JSON.stringify(q(g.current)?g.current:""),s=JSON.stringify(q(a)?a:""),f=g.current===void 0;(p!==s||f)&&!r?.hold&&(C(null),U(),g.current=a),r?.onChange&&r?.onChange(a,m)},[a,r?.hold,...r?.trigger||[]]),k(()=>{let p=async()=>{!G&&P&&A&&(await caches.open(P)).delete(A)};return window.addEventListener("beforeunload",p),()=>{window.removeEventListener("beforeunload",p),x.current?.abort()}},[]);let U=De(async p=>{let s=a;if(r?.hold&&r?.logging&&console.log("Hold active"),r?.beforeRequest&&(s=r?.beforeRequest(a)),r?.cache&&!p&&!S){R(!0),r?.onBeforeRequest&&r?.onBeforeRequest(a);let f=await caches.open(P),h=await(await f.match(A))?.json();if(h){let{data:u,expired:w}=h;if(j().isAfter(w))await f.delete(A);else{r?.afterResponse&&u?.data&&(u.data=r?.afterResponse(u.data)),r?.logging&&console.log("After request: Using Cache",u),r?.onAfterResponse&&r?.onAfterResponse(u),R(!1),C(u);return}}}if(typeof e=="function"){x.current?.abort();let f=new AbortController;x.current=f,R(!0),r?.logging&&console.log("Before request",a),r?.onBeforeRequest&&r?.onBeforeRequest(a);let y=o?await e(s,void 0,{...r,signal:f.signal}):await e(void 0,{...r,signal:f.signal});if(r?.afterResponse&&y?.data&&(y.data=r?.afterResponse(y.data)),r?.logging&&console.log("After request",y),r?.onAfterResponse&&r?.onAfterResponse(y),R(!1),C(y),b(!1),r?.cache&&y.status){let h=j().add(J,W).toISOString(),u={data:y,expired:h},w=await caches.open(P),v=new Response(JSON.stringify(u));await w.put(A,v)}}},[a,e,r]);k(()=>{if(r?.refreshInterval){let p=typeof r.refreshInterval=="number"?r.refreshInterval:r.refreshInterval.value,s=typeof r.refreshInterval=="number"?"s":r.refreshInterval.unit,f=setInterval(()=>{U()},j.duration(p,s).asMilliseconds());return()=>clearInterval(f)}return()=>{}},[r?.refreshInterval,U]),k(()=>{if(!r?.refetchOnWindowFocus)return;let p=()=>{U()};return window.addEventListener("focus",p),()=>{window.removeEventListener("focus",p)}},[r?.refetchOnWindowFocus,U]);let m={...T,loading:l,refresh:U,abort:()=>{x.current?.abort(),x.current=null,R(!1),b(!0)},clear:()=>{R(!1),C(null)},response:T,isCancel:S,clone:(p,s)=>Se(e,p,s)};return k(()=>{r?.storeName&&F(r?.storeName).setState([T?.data,m])},[T,m,r?.storeName]),[T?.data,m]}async function St(e,t=()=>{}){let n=e*1e3;return new Promise(o=>{let a=0,r=setInterval(()=>{t(),a===9&&clearInterval(r)},1e3);setTimeout(async()=>{await t(),o(!0)},n)})}import Pe from"moment";var ae=(r=>(r.POST="POST",r.PUT="PUT",r.PATCH="PATCH",r.DELETE="DELETE",r.GET="GET",r))(ae||{}),ie=(s=>(s.number="number",s.currency="currency",s.percent="percent",s.date="date",s.dateTime="dateTime",s.month="month",s.year="year",s.time="time",s.timestamp="timestamp",s.string="string",s.textarea="textarea",s.code="code",s.password="password",s.boolean="boolean",s.toggle="toggle",s.email="email",s.phone="phone",s.url="url",s.json="json",s.file="file",s.image="image",s.array="array",s.object="object",s.enum="enum",s.user="user",s.department="department",s.status="status",s))(ie||{});var vt=(e,t,n)=>{let{format:o}=N();return t==="number"?we(e,{thouSep:o.number.thouSep,decDigits:o.number.decDigits,decSep:o.number.decSep,...n}):["date","dateTime","month","year","time"].includes(t)?Ue(e,{display:o[t]?.display,value:o[t]?.value,...n}):t==="boolean"?Oe(e,n):t==="string"?qe(e,n):e?.toString()??""};function Oe(e,t){let n=typeof e=="string"?e==="true":!!e,o=t?.trueLabel??"Yes",a=t?.falseLabel??"No";return n?o:a}function qe(e,t){if(!q(e))return"";let n=String(e);return t?.capitalize&&(n=n.charAt(0).toUpperCase()+n.slice(1)),t?.ellipsis&&n.length>t.ellipsis&&(n=n.slice(0,t.ellipsis)+"..."),n}function we(e,{thouSep:t,decSep:n,decDigits:o,method:a}){if(e==null||isNaN(Number(e)))return"";let r=typeof e=="string"?parseFloat(e):e;if(a)if(typeof o=="number"){let l=Math.pow(10,o);r=Math[a](r*l)/l}else r=Math[a](r);else if(typeof o=="number"){let l=Math.pow(10,o);r=Math.floor(r*l)/l}let c=0;if(o==="auto"){let l=r.toString(),R=l.indexOf(".");R!==-1&&(c=l.length-R-1)}let i={style:"decimal",useGrouping:!0,minimumFractionDigits:o==="auto"?c:o||0,maximumFractionDigits:o==="auto"?c:o||0,minimumIntegerDigits:1};return r.toLocaleString("en-US",i).replace(/\./g,"decSep").replace(/,/g,"thouSep").replace(/decSep/g,n).replace(/thouSep/g,t)}function Ue(e,{display:t,value:n}){if(!q(e))return e;let o=Pe(e,n);return o.isValid()?o.format(t):e}import{useEffect as le,useRef as Ne}from"react";function Mt(e,{interval:t,lead:n}){let o=Ne(null);le(()=>{o.current=e},[e]),le(()=>{let a=()=>o.current();if(n&&a(),t!==null){let r=setInterval(a,t);return()=>clearInterval(r)}},[t])}import{useEffect as ke,useState as ve}from"react";function It(e,t,n){let[o,a]=ve(!1),r=(l,R)=>typeof e=="string"&&l===e||typeof e=="number"&&R===e,c=l=>l!==null&&(["INPUT","TEXTAREA","SELECT","BUTTON"].includes(l.tagName)||l.hasAttribute("contentEditable")),i=l=>{let{key:R,keyCode:S}=l,b=l.ctrlKey,T=l.altKey,C=l.shiftKey;if(!c(document.activeElement))if(t)if(typeof t=="string")r(R,S)&&(t==="ctrl"&&b||t==="alt"&&T||t==="shift"&&C)&&(l.preventDefault(),n&&l.stopPropagation(),a(!o));else{let g=t.every(x=>x==="ctrl"?b:x==="alt"?T:x==="shift"?C:!1);r(R,S)&&g&&(l.preventDefault(),n&&l.stopPropagation(),a(!o))}else r(R,S)&&(l.preventDefault(),n&&l.stopPropagation(),a(!o))},d=({key:l,keyCode:R})=>{r(l,R)&&a(!1)};return ke(()=>(window.addEventListener("keydown",i),window.addEventListener("keyup",d),()=>{window.removeEventListener("keydown",i),window.removeEventListener("keyup",d)}),[]),o}import Ee from"axios";var er=({url:e,token:t,beforeRequest:n,onCallback:o,headers:a,onUnauthorized:r,handleToast:c,handleAuthorization:i,disabledToastWhenCancel:d,withCredentials:l,encryptRequest:R,encryptResponse:S,passphrase:b})=>{let{encrypt:T,decrypt:C,passphrase:g}=M(),x=(m,p,s,f)=>{let y=f?.code==="ERR_CANCELED",h=m.status===401,u=m?.data;if((typeof s?.encryptResponse=="boolean"?s?.encryptResponse:S)&&u){let E=s?.passphrase?typeof s.passphrase=="boolean"&&s.passphrase?g:s.passphrase:b;try{u=C(u,E)}catch{try{u=C(u,g)}catch{}}}let D={...o({...m,data:u,isCancel:y,isUnauthorization:h},f),isCancel:y,isUnauthorization:h,httpCode:m.status},B=typeof s?.disabledToastWhenCancel=="boolean"?s?.disabledToastWhenCancel:d,de=i?i(D,s):!h;if((s?.infoSuccess&&D.status||s?.infoError&&!D.status)&&c&&(!y||!B)&&c(D),!de&&(!y||!s?.disabledHandleUnauthorized)){let E=s?.onUnauthorized||r;E&&E(D)}if(p)p(D);else return D},P=(m,p=()=>{})=>Ee.create({baseURL:`${e}`,withCredentials:typeof m.withCredentials=="boolean"?m.withCredentials:l})(m).then(p).catch(f=>p(f.response,f)),A=(m,p,s,f,y)=>{let u={...{token:!0,infoError:!0,infoSuccess:!0,responseType:"json"},...y},w={"Content-Type":"application/json",...a,...u.headers};if(u.token&&(typeof u.token=="boolean"?t&&(w.Authorization=`Bearer ${t}`):u.token&&(w.Authorization=`Bearer ${u.token}`)),n&&(s=n(s)),(typeof u?.encryptRequest=="boolean"?u?.encryptRequest:R)&&s){let D=y?.passphrase?typeof y.passphrase=="boolean"&&y.passphrase?g:y.passphrase:b;s=T(s,D)}return P({url:p,method:m,data:s,headers:w,responseType:u.responseType,signal:u.signal,withCredentials:u.withCredentials,onUploadProgress:D=>{u?.onUploadProgress&&u?.onUploadProgress(D)}},(D,B)=>x(D,f,u,B))};return{client:P,post:(m,p,s,f)=>A("POST",`${m}`,p,s,f),put:(m,p,s,f)=>A("PUT",`${m}`,p,s,f),patch:(m,p,s,f)=>A("PATCH",`${m}`,p,s,f),delete:(m,p,s)=>A("DELETE",`${m}`,null,p,s),get:(m,p,s)=>A("GET",`${m}`,null,p,s),upload:(m,p,s,f)=>{let y=new FormData;return Object.keys(p).forEach(h=>y.append(h,p[h])),A("POST",`${m}`,y,s,{infoSuccess:!1,...f,headers:{"Content-Type":"multipart/form-data",...f?.headers}})}}};import{useEffect as Ke,useRef as Me,useState as z}from"react";function or(e,t){let[n,o]=z(!1),[a,r]=z(),[c,i]=z(0),d=Me(null);return Ke(()=>{if(t?.abortOnUnmount)return()=>{d.current?.abort()}},[]),[async b=>{d.current?.abort();let T=new AbortController;d.current=T,o(!0),t?.beforeRequest&&(b=t?.beforeRequest(b)),t?.logging&&console.log("Before request",b);let C={...t,signal:T.signal,onUploadProgress:x=>{let P=Math.round(x.loaded*100/(x.total||1));i(P)}},g=q(b)?await e(b,void 0,C):await e(void 0,C);t?.logging&&console.log("After response",g),r(g),o(!1),i(0),g.status&&t?.onSuccess&&t?.onSuccess(g),!g.status&&t?.onError&&t?.onError(g),t?.afterResponse&&t?.afterResponse(g)},{...a,loading:n,abort:()=>{d.current?.abort(),d.current=null,o(!1),i(0)},progress:c,reset:()=>{o(!1),i(0),r(null)}}]}import{useCallback as Fe,useEffect as Be,useRef as Ie,useState as pe}from"react";function ir(e="vertical"){let t=Ie(null),[n,o]=pe(!1),[a,r]=pe(!1),c=Fe(()=>{let i=t.current;if(i)if(e==="vertical"){let d=Math.ceil(i.scrollTop+i.clientHeight),l=Math.floor(i.scrollHeight);o(i.scrollTop>0),r(d<l)}else{let d=Math.ceil(i.scrollLeft+i.clientWidth),l=Math.floor(i.scrollWidth);o(i.scrollLeft>0),r(d<l)}},[e]);return Be(()=>{let i=t.current;if(i)return c(),i.addEventListener("scroll",c),()=>i.removeEventListener("scroll",c)},[c]),{ref:t,showStartShadow:n,showEndShadow:a}}var cr=(e,t)=>F(t).useStore();import ce from"react";var dr=(e,t)=>{let n=o=>e(o);return n.displayName=t,n},mr=(e,t)=>{let n={};n.others=[];let o=a=>{ce.Children.forEach(a,r=>{if(ce.isValidElement(r)){let c=r.type.displayName;if(t.includes(c))n[c]=r;else{let i=r;i.props?.children?o(i.props.children):n.others.push(r)}}else n.others.push(r)})};return o(e),n};export{ge as BgsCoreProvider,ie as DataTypeEnum,ae as HttpMethod,er as createApiHelper,dr as createElement,H as decrypt,re as decryptString,je as diffJson,I as encrypt,te as encryptString,_ as generateCacheKey,$e as generateUUID,O as getFieldValue,ze as isArray,q as isNotEmpty,Xe as jsonCopy,X as labelFormatter,Ve as mappingUndefinedtoNull,Je as renderChildren,We as sorting,mr as splitElement,me as stableStringify,Ge as summary,Se as useApiLoad,or as useApiSend,cr as useApiStore,N as useBgsCore,M as useCrypto,St as useDelay,vt as useFormatted,Mt as useInterval,It as useKeyPress,ir as useScroll,ne as useStorage};
|
package/package.json
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@bgscore/react-core",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "A React utility library that provides advanced API hooks (fetch, mutation, caching). Built for scalable and flexible data handling in modern React applications.",
|
|
5
|
+
"main": "dist/index.cjs",
|
|
6
|
+
"module": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"type": "module",
|
|
9
|
+
"files": [
|
|
10
|
+
"dist"
|
|
11
|
+
],
|
|
12
|
+
"exports": {
|
|
13
|
+
".": {
|
|
14
|
+
"require": "./dist/index.cjs",
|
|
15
|
+
"import": "./dist/index.js"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"repository": {
|
|
19
|
+
"type": "git",
|
|
20
|
+
"url": "git+https://github.com/andrydharmawan/react-core.git"
|
|
21
|
+
},
|
|
22
|
+
"scripts": {
|
|
23
|
+
"build": "tsup",
|
|
24
|
+
"dev": "tsup --watch"
|
|
25
|
+
},
|
|
26
|
+
"keywords": [
|
|
27
|
+
"react",
|
|
28
|
+
"hooks",
|
|
29
|
+
"api",
|
|
30
|
+
"core",
|
|
31
|
+
"react-hooks",
|
|
32
|
+
"react-api",
|
|
33
|
+
"react-core",
|
|
34
|
+
"bgscore",
|
|
35
|
+
"mutation",
|
|
36
|
+
"fetching",
|
|
37
|
+
"caching",
|
|
38
|
+
"context"
|
|
39
|
+
],
|
|
40
|
+
"author": "Andry Bagus Dharmawan",
|
|
41
|
+
"license": "MIT",
|
|
42
|
+
"peerDependencies": {
|
|
43
|
+
"axios": ">=1.6.0",
|
|
44
|
+
"moment": ">=2.0.0",
|
|
45
|
+
"react": ">=17.0.0",
|
|
46
|
+
"react-dom": ">=17.0.0"
|
|
47
|
+
},
|
|
48
|
+
"dependencies": {
|
|
49
|
+
"crypto-js": "^4.2.0"
|
|
50
|
+
},
|
|
51
|
+
"devDependencies": {
|
|
52
|
+
"@types/crypto-js": "^4.2.2",
|
|
53
|
+
"@types/react": "^19.1.1",
|
|
54
|
+
"@types/react-dom": "^19.1.2",
|
|
55
|
+
"tsup": "^8.4.0",
|
|
56
|
+
"typescript": "^5.8.3"
|
|
57
|
+
}
|
|
58
|
+
}
|