@dismissible/react-client 0.3.2 → 1.0.0
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/README.md +325 -170
- package/dist/components/Dismissible.d.ts +3 -4
- package/dist/contexts/DismissibleContext.d.ts +3 -2
- package/dist/contexts/DismissibleProvider.d.ts +3 -1
- package/dist/dismissible-client.es.js +405 -359
- package/dist/dismissible-client.umd.js +1 -1
- package/dist/hooks/useDismissibleItem.d.ts +6 -7
- package/dist/mockServiceWorker.js +17 -12
- package/dist/{style.css → react-client.css} +1 -1
- package/dist/root.d.ts +0 -1
- package/dist/types/dismissible.types.d.ts +7 -3
- package/dist/utils/auth.utils.d.ts +0 -6
- package/package.json +55 -36
|
@@ -1 +1 @@
|
|
|
1
|
-
(function(l,u){typeof exports=="object"&&typeof module!="undefined"?u(exports,require("react/jsx-runtime"),require("react")):typeof define=="function"&&define.amd?define(["exports","react/jsx-runtime","react"],u):(l=typeof globalThis!="undefined"?globalThis:l||self,u(l.DismissibleClient={},l.React.jsxRuntime,l.React))})(this,function(l,u,a){"use strict";var Te=Object.defineProperty,Ue=Object.defineProperties;var qe=Object.getOwnPropertyDescriptors;var W=Object.getOwnPropertySymbols;var de=Object.prototype.hasOwnProperty,he=Object.prototype.propertyIsEnumerable;var fe=(l,u,a)=>u in l?Te(l,u,{enumerable:!0,configurable:!0,writable:!0,value:a}):l[u]=a,p=(l,u)=>{for(var a in u||(u={}))de.call(u,a)&&fe(l,a,u[a]);if(W)for(var a of W(u))he.call(u,a)&&fe(l,a,u[a]);return l},S=(l,u)=>Ue(l,qe(u));var Y=(l,u)=>{var a={};for(var C in l)de.call(l,C)&&u.indexOf(C)<0&&(a[C]=l[C]);if(l!=null&&W)for(var C of W(l))u.indexOf(C)<0&&he.call(l,C)&&(a[C]=l[C]);return a};var O=(l,u,a)=>new Promise((C,L)=>{var V=D=>{try{T(a.next(D))}catch(k){L(k)}},B=D=>{try{T(a.throw(D))}catch(k){L(k)}},T=D=>D.done?C(D.value):Promise.resolve(D.value).then(V,B);T((a=a.apply(l,u)).next())});const C=/\{[^{}]+\}/g,L=()=>{var e,r;return typeof process=="object"&&Number.parseInt((r=(e=process==null?void 0:process.versions)==null?void 0:e.node)==null?void 0:r.substring(0,2))>=18&&process.versions.undici};function V(){return Math.random().toString(36).slice(2,11)}function B(e){let U=p({},e),{baseUrl:r="",Request:t=globalThis.Request,fetch:n=globalThis.fetch,querySerializer:i,bodySerializer:s,headers:o,requestInitExt:d=void 0}=U,h=Y(U,["baseUrl","Request","fetch","querySerializer","bodySerializer","headers","requestInitExt"]);d=L()?d:void 0,r=te(r);const g=[];function E(f,c){return O(this,null,function*(){var ue;const ce=c||{},{baseUrl:A,fetch:I=n,Request:H=t,headers:x,params:$={},parseAs:F="json",querySerializer:z,bodySerializer:m=s!=null?s:ye,body:y}=ce,j=Y(ce,["baseUrl","fetch","Request","headers","params","parseAs","querySerializer","bodySerializer","body"]);let R=r;A&&(R=(ue=te(A))!=null?ue:r);let K=typeof i=="function"?i:Z(i);z&&(K=typeof z=="function"?z:Z(p(p({},typeof i=="object"?i:{}),z)));const Q=y===void 0?void 0:m(y,ee(o,x,$.header)),De=ee(Q===void 0||Q instanceof FormData?{}:{"Content-Type":"application/json"},o,x,$.header),$e=S(p(p({redirect:"follow"},h),j),{body:Q,headers:De});let J,M,q=new t(be(f,{baseUrl:R,params:$,querySerializer:K}),$e),b;for(const v in j)v in q||(q[v]=j[v]);if(g.length){J=V(),M=Object.freeze({baseUrl:R,fetch:I,parseAs:F,querySerializer:K,bodySerializer:m});for(const v of g)if(v&&typeof v=="object"&&typeof v.onRequest=="function"){const w=yield v.onRequest({request:q,schemaPath:f,params:$,options:M,id:J});if(w)if(w instanceof t)q=w;else if(w instanceof Response){b=w;break}else throw new Error("onRequest: must return new Request() or Response() when modifying the request")}}if(!b){try{b=yield I(q,d)}catch(v){let w=v;if(g.length)for(let P=g.length-1;P>=0;P--){const _=g[P];if(_&&typeof _=="object"&&typeof _.onError=="function"){const N=yield _.onError({request:q,error:w,schemaPath:f,params:$,options:M,id:J});if(N){if(N instanceof Response){w=void 0,b=N;break}if(N instanceof Error){w=N;continue}throw new Error("onError: must return new Response() or instance of Error")}}}if(w)throw w}if(g.length)for(let v=g.length-1;v>=0;v--){const w=g[v];if(w&&typeof w=="object"&&typeof w.onResponse=="function"){const P=yield w.onResponse({request:q,response:b,schemaPath:f,params:$,options:M,id:J});if(P){if(!(P instanceof Response))throw new Error("onResponse: must return new Response() when modifying the response");b=P}}}}if(b.status===204||q.method==="HEAD"||b.headers.get("Content-Length")==="0")return b.ok?{data:void 0,response:b}:{error:void 0,response:b};if(b.ok)return F==="stream"?{data:b.body,response:b}:{data:yield b[F](),response:b};let X=yield b.text();try{X=JSON.parse(X)}catch(v){}return{error:X,response:b}})}return{request(f,c,A){return E(c,S(p({},A),{method:f.toUpperCase()}))},GET(f,c){return E(f,S(p({},c),{method:"GET"}))},PUT(f,c){return E(f,S(p({},c),{method:"PUT"}))},POST(f,c){return E(f,S(p({},c),{method:"POST"}))},DELETE(f,c){return E(f,S(p({},c),{method:"DELETE"}))},OPTIONS(f,c){return E(f,S(p({},c),{method:"OPTIONS"}))},HEAD(f,c){return E(f,S(p({},c),{method:"HEAD"}))},PATCH(f,c){return E(f,S(p({},c),{method:"PATCH"}))},TRACE(f,c){return E(f,S(p({},c),{method:"TRACE"}))},use(...f){for(const c of f)if(c){if(typeof c!="object"||!("onRequest"in c||"onResponse"in c||"onError"in c))throw new Error("Middleware must be an object with one of `onRequest()`, `onResponse() or `onError()`");g.push(c)}},eject(...f){for(const c of f){const A=g.indexOf(c);A!==-1&&g.splice(A,1)}}}}function T(e,r,t){if(r==null)return"";if(typeof r=="object")throw new Error("Deeply-nested arrays/objects aren’t supported. Provide your own `querySerializer()` to handle these.");return`${e}=${(t==null?void 0:t.allowReserved)===!0?r:encodeURIComponent(r)}`}function D(e,r,t){if(!r||typeof r!="object")return"";const n=[],i={simple:",",label:".",matrix:";"}[t.style]||"&";if(t.style!=="deepObject"&&t.explode===!1){for(const d in r)n.push(d,t.allowReserved===!0?r[d]:encodeURIComponent(r[d]));const o=n.join(",");switch(t.style){case"form":return`${e}=${o}`;case"label":return`.${o}`;case"matrix":return`;${e}=${o}`;default:return o}}for(const o in r){const d=t.style==="deepObject"?`${e}[${o}]`:o;n.push(T(d,r[o],t))}const s=n.join(i);return t.style==="label"||t.style==="matrix"?`${i}${s}`:s}function k(e,r,t){if(!Array.isArray(r))return"";if(t.explode===!1){const s={form:",",spaceDelimited:"%20",pipeDelimited:"|"}[t.style]||",",o=(t.allowReserved===!0?r:r.map(d=>encodeURIComponent(d))).join(s);switch(t.style){case"simple":return o;case"label":return`.${o}`;case"matrix":return`;${e}=${o}`;default:return`${e}=${o}`}}const n={simple:",",label:".",matrix:";"}[t.style]||"&",i=[];for(const s of r)t.style==="simple"||t.style==="label"?i.push(t.allowReserved===!0?s:encodeURIComponent(s)):i.push(T(e,s,t));return t.style==="label"||t.style==="matrix"?`${n}${i.join(n)}`:i.join(n)}function Z(e){return function(t){const n=[];if(t&&typeof t=="object")for(const i in t){const s=t[i];if(s!=null){if(Array.isArray(s)){if(s.length===0)continue;n.push(k(i,s,S(p({style:"form",explode:!0},e==null?void 0:e.array),{allowReserved:(e==null?void 0:e.allowReserved)||!1})));continue}if(typeof s=="object"){n.push(D(i,s,S(p({style:"deepObject",explode:!0},e==null?void 0:e.object),{allowReserved:(e==null?void 0:e.allowReserved)||!1})));continue}n.push(T(i,s,e))}}return n.join("&")}}function me(e,r){var n;let t=e;for(const i of(n=e.match(C))!=null?n:[]){let s=i.substring(1,i.length-1),o=!1,d="simple";if(s.endsWith("*")&&(o=!0,s=s.substring(0,s.length-1)),s.startsWith(".")?(d="label",s=s.substring(1)):s.startsWith(";")&&(d="matrix",s=s.substring(1)),!r||r[s]===void 0||r[s]===null)continue;const h=r[s];if(Array.isArray(h)){t=t.replace(i,k(s,h,{style:d,explode:o}));continue}if(typeof h=="object"){t=t.replace(i,D(s,h,{style:d,explode:o}));continue}if(d==="matrix"){t=t.replace(i,`;${T(s,h)}`);continue}t=t.replace(i,d==="label"?`.${encodeURIComponent(h)}`:encodeURIComponent(h))}return t}function ye(e,r){var t,n;return e instanceof FormData?e:r&&(r.get instanceof Function?(t=r.get("Content-Type"))!=null?t:r.get("content-type"):(n=r["Content-Type"])!=null?n:r["content-type"])==="application/x-www-form-urlencoded"?new URLSearchParams(e).toString():JSON.stringify(e)}function be(e,r){var i,s;let t=`${r.baseUrl}${e}`;(i=r.params)!=null&&i.path&&(t=me(t,r.params.path));let n=r.querySerializer((s=r.params.query)!=null?s:{});return n.startsWith("?")&&(n=n.substring(1)),n&&(t+=`?${n}`),t}function ee(...e){const r=new Headers;for(const t of e){if(!t||typeof t!="object")continue;const n=t instanceof Headers?t.entries():Object.entries(t);for(const[i,s]of n)if(s===null)r.delete(i);else if(Array.isArray(s))for(const o of s)r.append(i,o);else s!==void 0&&r.set(i,s)}return r}function te(e){return e.endsWith("/")?e.substring(0,e.length-1):e}const pe={baseUrl:"http://localhost:3200"},ge={development:{baseUrl:"http://localhost:3200"},staging:{baseUrl:"https://api.staging.dismissible.io"},production:{baseUrl:"https://api.dismissible.io"}},we=()=>ge["production"]||pe,re=(e,r,t)=>{try{const n=`${r}_${e}`,i=localStorage.getItem(n);if(!i)return null;const{data:s,timestamp:o}=JSON.parse(i);return t&&Date.now()-o>t?(localStorage.removeItem(n),null):s}catch(n){return null}},se=(e,r,t)=>{try{const n=`${t}_${e}`,i={data:r,timestamp:Date.now()};localStorage.setItem(n,JSON.stringify(i))}catch(n){console.warn("Failed to cache dismissible item:",n)}},ne=(e,r)=>{try{const t=`${r}_${e}`;localStorage.removeItem(t)}catch(t){console.warn("Failed to remove cached dismissible item:",t)}},G=a.createContext(null),ie=()=>a.useContext(G),ve="dismissible",oe=(e,r={})=>{var z;const{initialData:t,enableCache:n=!0,cachePrefix:i=ve,cacheExpiration:s}=r,o=ie(),d=a.useMemo(()=>{const m=we(),y=(o==null?void 0:o.baseUrl)||m.baseUrl;return B({baseUrl:y,headers:{}})},[o]),h=a.useMemo(()=>!!(o!=null&&o.jwt)?`${e}-auth`:e,[e,o==null?void 0:o.jwt]),g=a.useRef({enableCache:n,cachePrefix:i,cacheExpiration:s}),E=a.useRef(e),U=a.useRef(h),[f,c]=a.useState(!1),[A,I]=a.useState(null),[H,x]=a.useState(()=>{if(t)return t;if(n){const m=re(h,i,s);if(m)return m}}),$=a.useCallback(()=>O(this,null,function*(){var m;if(n){const y=re(h,i,s);if(y!=null&&y.dismissedAt){x(y),c(!1);return}}c(!0),I(null);try{const y=o!=null&&o.getAuthHeaders?yield o.getAuthHeaders():{},{data:j,error:R}=yield d.GET("/v1/dismissible/{itemId}",{params:{path:{itemId:e}},headers:y});if(R)throw new Error(((m=R==null?void 0:R.error)==null?void 0:m.message)||"Failed to fetch dismissible item");x(j.data),n&&j.data&&se(h,j.data,i)}catch(y){I(y instanceof Error?y:new Error("Unknown error occurred"))}finally{c(!1)}}),[e,h,n,i,s,d,o]);a.useEffect(()=>{const m=E.current!==e,y=U.current!==h;m||y?(E.current=e,U.current=h,$()):t||$()},[e,h,t]),a.useEffect(()=>{const m=g.current;(m.enableCache!==n||m.cachePrefix!==i||m.cacheExpiration!==s)&&(m.cachePrefix!==i&&ne(h,m.cachePrefix),!n&&m.enableCache&&ne(h,i),g.current={enableCache:n,cachePrefix:i,cacheExpiration:s},$())},[n,i,s,h]);const F=a.useCallback(()=>O(this,null,function*(){var m;I(null);try{const y=o!=null&&o.getAuthHeaders?yield o.getAuthHeaders():{},{data:j,error:R}=yield d.DELETE("/v1/dismissible/{itemId}",{params:{path:{itemId:e}},headers:y});if(R)throw new Error(((m=R==null?void 0:R.error)==null?void 0:m.message)||"Failed to dismiss item");x(j.data),n&&j.data&&se(h,j.data,i)}catch(y){throw I(y instanceof Error?y:new Error("Failed to dismiss item")),y}}),[h,n,i,d,o]);return{dismissedOn:(z=H==null?void 0:H.dismissedAt)!=null?z:null,dismiss:F,isLoading:f,error:A,item:H}},Ee=()=>u.jsx("div",{className:"dismissible-loading","aria-live":"polite",children:"Loading..."}),Ce=({error:e})=>u.jsxs("div",{className:"dismissible-error",role:"alert",children:["Error loading dismissible item: ",e.message]}),Re=({id:e,onDismiss:r,ariaLabel:t})=>u.jsx("button",{id:e,className:"dismissible-button",onClick:r,"aria-label":t,type:"button",children:"×"}),Se=({id:e,children:r,onDismiss:t,LoadingComponent:n=Ee,ErrorComponent:i=Ce,DismissButtonComponent:s=Re,enableCache:o,cachePrefix:d,cacheExpiration:h,ignoreErrors:g=!1})=>{const{dismissedOn:E,isLoading:U,error:f,dismiss:c}=oe(e,{enableCache:o,cachePrefix:d,cacheExpiration:h}),[A,I]=a.useState(!1);a.useEffect(()=>{I(!1)},[e]);const H=()=>O(this,null,function*(){I(!0);try{yield c(),t==null||t()}catch(x){I(!1)}});return U&&n?u.jsx(n,{id:e}):U&&!n?null:f&&i&&!g?u.jsx(i,{id:e,error:f}):E||A?null:u.jsxs("div",{className:"dismissible-container",children:[u.jsx("div",{className:"dismissible-content",children:r}),s?u.jsx(s,{id:e,onDismiss:H,ariaLabel:`Dismiss ${e}`}):null]})},ae=e=>O(this,null,function*(){if(typeof e=="function")try{const r=e();return yield Promise.resolve(r)}catch(r){console.warn("Failed to resolve JWT from function:",r);return}return e}),le=e=>O(this,null,function*(){const r=yield ae(e);return r?{Authorization:`Bearer ${r}`}:{}}),je=e=>{const r=e.split(".");return r.length===3&&r.every(t=>t.length>0)},Ae=({jwt:e,baseUrl:r,children:t})=>{const n=a.useMemo(()=>({jwt:e,baseUrl:r,getAuthHeaders:()=>O(this,null,function*(){return yield le(e)})}),[e,r]);return u.jsx(G.Provider,{value:n,children:t})},Ie="0.3.1";l.Dismissible=Se,l.DismissibleContext=G,l.DismissibleProvider=Ae,l.VERSION=Ie,l.getAuthHeaders=le,l.isValidJwtFormat=je,l.resolveJwt=ae,l.useDismissibleContext=ie,l.useDismissibleItem=oe,Object.defineProperty(l,Symbol.toStringTag,{value:"Module"})});
|
|
1
|
+
(function(c,d){typeof exports=="object"&&typeof module!="undefined"?d(exports,require("react/jsx-runtime"),require("react")):typeof define=="function"&&define.amd?define(["exports","react/jsx-runtime","react"],d):(c=typeof globalThis!="undefined"?globalThis:c||self,d(c.DismissibleClient={},c.React.jsxRuntime,c.React))})(this,(function(c,d,o){"use strict";var Ae=Object.defineProperty,$e=Object.defineProperties;var Te=Object.getOwnPropertyDescriptors;var Q=Object.getOwnPropertySymbols;var ye=Object.prototype.hasOwnProperty,be=Object.prototype.propertyIsEnumerable;var me=(c,d,o)=>d in c?Ae(c,d,{enumerable:!0,configurable:!0,writable:!0,value:o}):c[d]=o,g=(c,d)=>{for(var o in d||(d={}))ye.call(d,o)&&me(c,o,d[o]);if(Q)for(var o of Q(d))be.call(d,o)&&me(c,o,d[o]);return c},S=(c,d)=>$e(c,Te(d));var re=(c,d)=>{var o={};for(var R in c)ye.call(c,R)&&d.indexOf(R)<0&&(o[R]=c[R]);if(c!=null&&Q)for(var R of Q(c))d.indexOf(R)<0&&be.call(c,R)&&(o[R]=c[R]);return o};var U=(c,d,o)=>new Promise((R,M)=>{var V=j=>{try{q(o.next(j))}catch(F){M(F)}},X=j=>{try{q(o.throw(j))}catch(F){M(F)}},q=j=>j.done?R(j.value):Promise.resolve(j.value).then(V,X);q((o=o.apply(c,d)).next())});const R=/\{[^{}]+\}/g,M=()=>{var e,r;return typeof process=="object"&&Number.parseInt((r=(e=process==null?void 0:process.versions)==null?void 0:e.node)==null?void 0:r.substring(0,2))>=18&&process.versions.undici};function V(){return Math.random().toString(36).slice(2,11)}function X(e){let H=g({},e),{baseUrl:r="",Request:t=globalThis.Request,fetch:n=globalThis.fetch,querySerializer:i,bodySerializer:s,headers:a,requestInitExt:h=void 0}=H,b=re(H,["baseUrl","Request","fetch","querySerializer","bodySerializer","headers","requestInitExt"]);h=M()?h:void 0,r=ie(r);const m=[];function C(f,l){return U(this,null,function*(){var he;const de=l||{},{baseUrl:x,fetch:A=n,Request:L=t,headers:$,params:D={},parseAs:O="json",querySerializer:T,bodySerializer:J=s!=null?s:pe,body:W,middleware:_=[]}=de,u=re(de,["baseUrl","fetch","Request","headers","params","parseAs","querySerializer","bodySerializer","body","middleware"]);let p=r;x&&(p=(he=ie(x))!=null?he:r);let y=typeof i=="function"?i:se(i);T&&(y=typeof T=="function"?T:se(g(g({},typeof i=="object"?i:{}),T)));const k=W===void 0?void 0:J(W,ne(a,$,D.header)),ee=ne(k===void 0||k instanceof FormData?{}:{"Content-Type":"application/json"},a,$,D.header),P=[...m,..._],je=S(g(g({redirect:"follow"},b),u),{body:k,headers:ee});let B,G,I=new L(ge(f,{baseUrl:p,params:D,querySerializer:y}),je),w;for(const v in u)v in I||(I[v]=u[v]);if(P.length){B=V(),G=Object.freeze({baseUrl:p,fetch:A,parseAs:O,querySerializer:y,bodySerializer:J});for(const v of P)if(v&&typeof v=="object"&&typeof v.onRequest=="function"){const E=yield v.onRequest({request:I,schemaPath:f,params:D,options:G,id:B});if(E)if(E instanceof L)I=E;else if(E instanceof Response){w=E;break}else throw new Error("onRequest: must return new Request() or Response() when modifying the request")}}if(!w){try{w=yield A(I,h)}catch(v){let E=v;if(P.length)for(let z=P.length-1;z>=0;z--){const K=P[z];if(K&&typeof K=="object"&&typeof K.onError=="function"){const N=yield K.onError({request:I,error:E,schemaPath:f,params:D,options:G,id:B});if(N){if(N instanceof Response){E=void 0,w=N;break}if(N instanceof Error){E=N;continue}throw new Error("onError: must return new Response() or instance of Error")}}}if(E)throw E}if(P.length)for(let v=P.length-1;v>=0;v--){const E=P[v];if(E&&typeof E=="object"&&typeof E.onResponse=="function"){const z=yield E.onResponse({request:I,response:w,schemaPath:f,params:D,options:G,id:B});if(z){if(!(z instanceof Response))throw new Error("onResponse: must return new Response() when modifying the response");w=z}}}}if(w.status===204||I.method==="HEAD"||w.headers.get("Content-Length")==="0")return w.ok?{data:void 0,response:w}:{error:void 0,response:w};if(w.ok)return O==="stream"?{data:w.body,response:w}:{data:yield w[O](),response:w};let te=yield w.text();try{te=JSON.parse(te)}catch(v){}return{error:te,response:w}})}return{request(f,l,x){return C(l,S(g({},x),{method:f.toUpperCase()}))},GET(f,l){return C(f,S(g({},l),{method:"GET"}))},PUT(f,l){return C(f,S(g({},l),{method:"PUT"}))},POST(f,l){return C(f,S(g({},l),{method:"POST"}))},DELETE(f,l){return C(f,S(g({},l),{method:"DELETE"}))},OPTIONS(f,l){return C(f,S(g({},l),{method:"OPTIONS"}))},HEAD(f,l){return C(f,S(g({},l),{method:"HEAD"}))},PATCH(f,l){return C(f,S(g({},l),{method:"PATCH"}))},TRACE(f,l){return C(f,S(g({},l),{method:"TRACE"}))},use(...f){for(const l of f)if(l){if(typeof l!="object"||!("onRequest"in l||"onResponse"in l||"onError"in l))throw new Error("Middleware must be an object with one of `onRequest()`, `onResponse() or `onError()`");m.push(l)}},eject(...f){for(const l of f){const x=m.indexOf(l);x!==-1&&m.splice(x,1)}}}}function q(e,r,t){if(r==null)return"";if(typeof r=="object")throw new Error("Deeply-nested arrays/objects aren’t supported. Provide your own `querySerializer()` to handle these.");return`${e}=${(t==null?void 0:t.allowReserved)===!0?r:encodeURIComponent(r)}`}function j(e,r,t){if(!r||typeof r!="object")return"";const n=[],i={simple:",",label:".",matrix:";"}[t.style]||"&";if(t.style!=="deepObject"&&t.explode===!1){for(const h in r)n.push(h,t.allowReserved===!0?r[h]:encodeURIComponent(r[h]));const a=n.join(",");switch(t.style){case"form":return`${e}=${a}`;case"label":return`.${a}`;case"matrix":return`;${e}=${a}`;default:return a}}for(const a in r){const h=t.style==="deepObject"?`${e}[${a}]`:a;n.push(q(h,r[a],t))}const s=n.join(i);return t.style==="label"||t.style==="matrix"?`${i}${s}`:s}function F(e,r,t){if(!Array.isArray(r))return"";if(t.explode===!1){const s={form:",",spaceDelimited:"%20",pipeDelimited:"|"}[t.style]||",",a=(t.allowReserved===!0?r:r.map(h=>encodeURIComponent(h))).join(s);switch(t.style){case"simple":return a;case"label":return`.${a}`;case"matrix":return`;${e}=${a}`;default:return`${e}=${a}`}}const n={simple:",",label:".",matrix:";"}[t.style]||"&",i=[];for(const s of r)t.style==="simple"||t.style==="label"?i.push(t.allowReserved===!0?s:encodeURIComponent(s)):i.push(q(e,s,t));return t.style==="label"||t.style==="matrix"?`${n}${i.join(n)}`:i.join(n)}function se(e){return function(t){const n=[];if(t&&typeof t=="object")for(const i in t){const s=t[i];if(s!=null){if(Array.isArray(s)){if(s.length===0)continue;n.push(F(i,s,S(g({style:"form",explode:!0},e==null?void 0:e.array),{allowReserved:(e==null?void 0:e.allowReserved)||!1})));continue}if(typeof s=="object"){n.push(j(i,s,S(g({style:"deepObject",explode:!0},e==null?void 0:e.object),{allowReserved:(e==null?void 0:e.allowReserved)||!1})));continue}n.push(q(i,s,e))}}return n.join("&")}}function we(e,r){var n;let t=e;for(const i of(n=e.match(R))!=null?n:[]){let s=i.substring(1,i.length-1),a=!1,h="simple";if(s.endsWith("*")&&(a=!0,s=s.substring(0,s.length-1)),s.startsWith(".")?(h="label",s=s.substring(1)):s.startsWith(";")&&(h="matrix",s=s.substring(1)),!r||r[s]===void 0||r[s]===null)continue;const b=r[s];if(Array.isArray(b)){t=t.replace(i,F(s,b,{style:h,explode:a}));continue}if(typeof b=="object"){t=t.replace(i,j(s,b,{style:h,explode:a}));continue}if(h==="matrix"){t=t.replace(i,`;${q(s,b)}`);continue}t=t.replace(i,h==="label"?`.${encodeURIComponent(b)}`:encodeURIComponent(b))}return t}function pe(e,r){var t,n;return e instanceof FormData?e:r&&(r.get instanceof Function?(t=r.get("Content-Type"))!=null?t:r.get("content-type"):(n=r["Content-Type"])!=null?n:r["content-type"])==="application/x-www-form-urlencoded"?new URLSearchParams(e).toString():JSON.stringify(e)}function ge(e,r){var i,s;let t=`${r.baseUrl}${e}`;(i=r.params)!=null&&i.path&&(t=we(t,r.params.path));let n=r.querySerializer((s=r.params.query)!=null?s:{});return n.startsWith("?")&&(n=n.substring(1)),n&&(t+=`?${n}`),t}function ne(...e){const r=new Headers;for(const t of e){if(!t||typeof t!="object")continue;const n=t instanceof Headers?t.entries():Object.entries(t);for(const[i,s]of n)if(s===null)r.delete(i);else if(Array.isArray(s))for(const a of s)r.append(i,a);else s!==void 0&&r.set(i,s)}return r}function ie(e){return e.endsWith("/")?e.substring(0,e.length-1):e}const oe=(e,r,t)=>{try{const n=`${r}_${e}`,i=localStorage.getItem(n);if(!i)return null;const{data:s,timestamp:a}=JSON.parse(i);return t&&Date.now()-a>t?(localStorage.removeItem(n),null):s}catch(n){return null}},Y=(e,r,t)=>{try{const n=`${t}_${e}`,i={data:r,timestamp:Date.now()};localStorage.setItem(n,JSON.stringify(i))}catch(n){console.warn("Failed to cache dismissible item:",n)}},ae=(e,r)=>{try{const t=`${r}_${e}`;localStorage.removeItem(t)}catch(t){console.warn("Failed to remove cached dismissible item:",t)}},Z=o.createContext(null),ce=()=>{const e=o.useContext(Z);if(!e)throw new Error("useDismissibleContext must be used within a DismissibleProvider");return e},Ee="dismissible",le=(e,r={})=>{var _;const{initialData:t,enableCache:n=!0,cachePrefix:i=Ee,cacheExpiration:s}=r,a=ce(),{userId:h}=a,b=o.useMemo(()=>X({baseUrl:a.baseUrl,headers:{}}),[a.baseUrl]),m=o.useMemo(()=>`${h}-${e}`,[h,e]),C=o.useRef({enableCache:n,cachePrefix:i,cacheExpiration:s}),H=o.useRef(e),f=o.useRef(m),l=o.useRef(null),[x,A]=o.useState(!1),[L,$]=o.useState(null),[D,O]=o.useState(()=>{if(t)return t;if(n){const u=oe(m,i,s);if(u)return u}}),T=o.useCallback(()=>U(null,null,function*(){var p;if(n){const y=oe(m,i,s);if(y!=null&&y.dismissedAt){O(y),A(!1);return}}(p=l.current)==null||p.abort();const u=new AbortController;l.current=u,A(!0),$(null);try{const y=yield a.getAuthHeaders(),{data:k,error:ee}=yield b.GET("/v1/users/{userId}/items/{itemId}",{params:{path:{userId:h,itemId:e}},headers:y,signal:u.signal});if(ee||!k)throw new Error("Failed to fetch dismissible item");O(k.data),n&&Y(m,k.data,i)}catch(y){if(y instanceof Error&&y.name==="AbortError")return;$(y instanceof Error?y:new Error("Unknown error occurred"))}finally{A(!1)}}),[e,h,m,n,i,s,b,a]);o.useEffect(()=>{const u=H.current!==e,p=f.current!==m;u||p?(H.current=e,f.current=m,T()):t||T()},[e,m,t,T]),o.useEffect(()=>()=>{var u;(u=l.current)==null||u.abort()},[]),o.useEffect(()=>{const u=C.current;(u.enableCache!==n||u.cachePrefix!==i||u.cacheExpiration!==s)&&(u.cachePrefix!==i&&ae(m,u.cachePrefix),!n&&u.enableCache&&ae(m,u.cachePrefix),C.current={enableCache:n,cachePrefix:i,cacheExpiration:s},T())},[n,i,s,m,T]);const J=o.useCallback(()=>U(null,null,function*(){$(null);try{const u=yield a.getAuthHeaders(),{data:p,error:y}=yield b.DELETE("/v1/users/{userId}/items/{itemId}",{params:{path:{userId:h,itemId:e}},headers:u});if(y||!p)throw new Error("Failed to dismiss item");O(p.data),n&&Y(m,p.data,i)}catch(u){throw $(u instanceof Error?u:new Error("Failed to dismiss item")),u}}),[e,h,m,n,i,b,a]),W=o.useCallback(()=>U(null,null,function*(){$(null);try{const u=yield a.getAuthHeaders(),{data:p,error:y}=yield b.POST("/v1/users/{userId}/items/{itemId}",{params:{path:{userId:h,itemId:e}},headers:u});if(y||!p)throw new Error("Failed to restore item");O(p.data),n&&Y(m,p.data,i)}catch(u){throw $(u instanceof Error?u:new Error("Failed to restore item")),u}}),[e,h,m,n,i,b,a]);return{dismissedOn:(_=D==null?void 0:D.dismissedAt)!=null?_:null,dismiss:J,restore:W,isLoading:x,error:L,item:D}},ve=()=>d.jsx("div",{className:"dismissible-loading","aria-live":"polite",children:"Loading..."}),Ce=()=>d.jsx("div",{className:"dismissible-error",role:"alert",children:"Unable to load content. Please try again later."}),Re=({onDismiss:e,ariaLabel:r})=>d.jsx("button",{className:"dismissible-button",onClick:e,"aria-label":r,type:"button",children:"×"}),Se=({itemId:e,children:r,onDismiss:t,LoadingComponent:n=ve,ErrorComponent:i=Ce,DismissButtonComponent:s=Re,enableCache:a,cachePrefix:h,cacheExpiration:b,ignoreErrors:m=!1})=>{const{dismissedOn:C,isLoading:H,error:f,dismiss:l}=le(e,{enableCache:a,cachePrefix:h,cacheExpiration:b}),[x,A]=o.useState(!1);o.useEffect(()=>{A(!1)},[e]);const L=()=>U(null,null,function*(){A(!0);try{yield l(),t==null||t()}catch($){A(!1)}});return H&&n?d.jsx(n,{itemId:e}):H&&!n?null:f&&i&&!m?d.jsx(i,{itemId:e,error:f}):C||x?null:d.jsxs("div",{className:"dismissible-container",children:[d.jsx("div",{className:"dismissible-content",children:r}),s?d.jsx(s,{onDismiss:L,ariaLabel:`Dismiss ${e}`}):null]})},ue=e=>U(null,null,function*(){if(typeof e=="function")try{const r=e();return yield Promise.resolve(r)}catch(r){console.warn("Failed to resolve JWT from function:",r);return}return e}),fe=e=>U(null,null,function*(){const r=yield ue(e);return r?{Authorization:`Bearer ${r}`}:{}}),xe=e=>{try{const r=new URL(e),t=r.hostname==="localhost"||r.hostname==="127.0.0.1"||r.hostname==="[::1]",n=r.protocol==="https:";return{isSecure:n||t,isLocalhost:t,isHttps:n}}catch(r){return{isSecure:!1,isLocalhost:!1,isHttps:!1}}},De=({userId:e,jwt:r,baseUrl:t,children:n})=>{const{isSecure:i}=xe(t);i||console.warn(`[dismissible] Insecure baseUrl "${t}". Use https:// in production (or localhost for development). JWT tokens may be exposed over insecure connections.`);const s=o.useMemo(()=>({userId:e,jwt:r,baseUrl:t,getAuthHeaders:()=>U(null,null,function*(){return yield fe(r)})}),[e,r,t]);return d.jsx(Z.Provider,{value:s,children:n})};c.Dismissible=Se,c.DismissibleContext=Z,c.DismissibleProvider=De,c.getAuthHeaders=fe,c.resolveJwt=ue,c.useDismissibleContext=ce,c.useDismissibleItem=le,Object.defineProperty(c,Symbol.toStringTag,{value:"Module"})}));
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { components } from '../generated/contract';
|
|
2
|
-
type DismissibleItem = components["schemas"]["
|
|
2
|
+
type DismissibleItem = components["schemas"]["DismissibleItemResponseDto"];
|
|
3
3
|
export type IDismissibleItem = DismissibleItem;
|
|
4
4
|
export interface UseDismissibleItemOptions {
|
|
5
5
|
/** Initial data for the dismissible item */
|
|
@@ -17,18 +17,17 @@ export interface UseDismissibleItemOptions {
|
|
|
17
17
|
* @param options - Configuration options for the hook
|
|
18
18
|
* @returns Object with dismissedOn, dismiss and restore functions
|
|
19
19
|
*/
|
|
20
|
-
export declare const useDismissibleItem: (
|
|
20
|
+
export declare const useDismissibleItem: (itemId: string, options?: UseDismissibleItemOptions) => {
|
|
21
21
|
dismissedOn: string | null;
|
|
22
22
|
dismiss: () => Promise<void>;
|
|
23
|
+
restore: () => Promise<void>;
|
|
23
24
|
isLoading: boolean;
|
|
24
25
|
error: Error | null;
|
|
25
26
|
item: {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
accountId: string;
|
|
27
|
+
itemId: string;
|
|
28
|
+
userId: string;
|
|
29
29
|
createdAt: string;
|
|
30
|
-
dismissedAt?: string
|
|
31
|
-
expiresAt?: string | null;
|
|
30
|
+
dismissedAt?: string;
|
|
32
31
|
} | undefined;
|
|
33
32
|
};
|
|
34
33
|
export {};
|
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
* - Please do NOT modify this file.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
const PACKAGE_VERSION = '2.
|
|
11
|
-
const INTEGRITY_CHECKSUM = '
|
|
10
|
+
const PACKAGE_VERSION = '2.12.4'
|
|
11
|
+
const INTEGRITY_CHECKSUM = '4db4a41e972cec1b64cc569c66952d82'
|
|
12
12
|
const IS_MOCKED_RESPONSE = Symbol('isMockedResponse')
|
|
13
13
|
const activeClientIds = new Set()
|
|
14
14
|
|
|
@@ -71,11 +71,6 @@ addEventListener('message', async function (event) {
|
|
|
71
71
|
break
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
-
case 'MOCK_DEACTIVATE': {
|
|
75
|
-
activeClientIds.delete(clientId)
|
|
76
|
-
break
|
|
77
|
-
}
|
|
78
|
-
|
|
79
74
|
case 'CLIENT_CLOSED': {
|
|
80
75
|
activeClientIds.delete(clientId)
|
|
81
76
|
|
|
@@ -94,6 +89,8 @@ addEventListener('message', async function (event) {
|
|
|
94
89
|
})
|
|
95
90
|
|
|
96
91
|
addEventListener('fetch', function (event) {
|
|
92
|
+
const requestInterceptedAt = Date.now()
|
|
93
|
+
|
|
97
94
|
// Bypass navigation requests.
|
|
98
95
|
if (event.request.mode === 'navigate') {
|
|
99
96
|
return
|
|
@@ -110,23 +107,29 @@ addEventListener('fetch', function (event) {
|
|
|
110
107
|
|
|
111
108
|
// Bypass all requests when there are no active clients.
|
|
112
109
|
// Prevents the self-unregistered worked from handling requests
|
|
113
|
-
// after it's been
|
|
110
|
+
// after it's been terminated (still remains active until the next reload).
|
|
114
111
|
if (activeClientIds.size === 0) {
|
|
115
112
|
return
|
|
116
113
|
}
|
|
117
114
|
|
|
118
115
|
const requestId = crypto.randomUUID()
|
|
119
|
-
event.respondWith(handleRequest(event, requestId))
|
|
116
|
+
event.respondWith(handleRequest(event, requestId, requestInterceptedAt))
|
|
120
117
|
})
|
|
121
118
|
|
|
122
119
|
/**
|
|
123
120
|
* @param {FetchEvent} event
|
|
124
121
|
* @param {string} requestId
|
|
122
|
+
* @param {number} requestInterceptedAt
|
|
125
123
|
*/
|
|
126
|
-
async function handleRequest(event, requestId) {
|
|
124
|
+
async function handleRequest(event, requestId, requestInterceptedAt) {
|
|
127
125
|
const client = await resolveMainClient(event)
|
|
128
126
|
const requestCloneForEvents = event.request.clone()
|
|
129
|
-
const response = await getResponse(
|
|
127
|
+
const response = await getResponse(
|
|
128
|
+
event,
|
|
129
|
+
client,
|
|
130
|
+
requestId,
|
|
131
|
+
requestInterceptedAt,
|
|
132
|
+
)
|
|
130
133
|
|
|
131
134
|
// Send back the response clone for the "response:*" life-cycle events.
|
|
132
135
|
// Ensure MSW is active and ready to handle the message, otherwise
|
|
@@ -202,9 +205,10 @@ async function resolveMainClient(event) {
|
|
|
202
205
|
* @param {FetchEvent} event
|
|
203
206
|
* @param {Client | undefined} client
|
|
204
207
|
* @param {string} requestId
|
|
208
|
+
* @param {number} requestInterceptedAt
|
|
205
209
|
* @returns {Promise<Response>}
|
|
206
210
|
*/
|
|
207
|
-
async function getResponse(event, client, requestId) {
|
|
211
|
+
async function getResponse(event, client, requestId, requestInterceptedAt) {
|
|
208
212
|
// Clone the request because it might've been already used
|
|
209
213
|
// (i.e. its body has been read and sent to the client).
|
|
210
214
|
const requestClone = event.request.clone()
|
|
@@ -255,6 +259,7 @@ async function getResponse(event, client, requestId) {
|
|
|
255
259
|
type: 'REQUEST',
|
|
256
260
|
payload: {
|
|
257
261
|
id: requestId,
|
|
262
|
+
interceptedAt: requestInterceptedAt,
|
|
258
263
|
...serializedRequest,
|
|
259
264
|
},
|
|
260
265
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
.dismissible-container{position:relative;display:inline-block;width:100%}.dismissible-content{width:100%}.dismissible-button{position:absolute;top:8px;right:8px;background:#0000001a;border:none;border-radius:50%;width:24px;height:24px;display:flex;align-items:center;justify-content:center;cursor:pointer;font-size:16px;line-height:1;color:#666;transition:all .2s ease}.dismissible-button:hover{background:#0003;color:#333}.dismissible-button:focus{outline:2px solid #007bff;outline-offset:2px}.dismissible-button:active{transform:scale(.95)}.dismissible-loading{padding:16px;text-align:center;color:#666;font-style:italic}.dismissible-error{padding:16px;background:#fee;border:1px solid #fcc;border-radius:4px;color:#c33;font-size:14px}@media
|
|
1
|
+
.dismissible-container{position:relative;display:inline-block;width:100%}.dismissible-content{width:100%}.dismissible-button{position:absolute;top:8px;right:8px;background:#0000001a;border:none;border-radius:50%;width:24px;height:24px;display:flex;align-items:center;justify-content:center;cursor:pointer;font-size:16px;line-height:1;color:#666;transition:all .2s ease}.dismissible-button:hover{background:#0003;color:#333}.dismissible-button:focus{outline:2px solid #007bff;outline-offset:2px}.dismissible-button:active{transform:scale(.95)}.dismissible-loading{padding:16px;text-align:center;color:#666;font-style:italic}.dismissible-error{padding:16px;background:#fee;border:1px solid #fcc;border-radius:4px;color:#c33;font-size:14px}@media(max-width:768px){.dismissible-button{width:32px;height:32px;font-size:18px}}
|
package/dist/root.d.ts
CHANGED
|
@@ -9,10 +9,12 @@ export type JwtToken = string | (() => string) | (() => Promise<string>);
|
|
|
9
9
|
* Configuration options for the DismissibleProvider
|
|
10
10
|
*/
|
|
11
11
|
export interface DismissibleProviderProps {
|
|
12
|
+
/** User ID for the current user - required for all API calls */
|
|
13
|
+
userId: string;
|
|
12
14
|
/** JWT token for authentication - can be static string or function */
|
|
13
15
|
jwt?: JwtToken;
|
|
14
|
-
/** Base URL for API requests
|
|
15
|
-
baseUrl
|
|
16
|
+
/** Base URL for API requests */
|
|
17
|
+
baseUrl: string;
|
|
16
18
|
/** Child components */
|
|
17
19
|
children: React.ReactNode;
|
|
18
20
|
}
|
|
@@ -20,10 +22,12 @@ export interface DismissibleProviderProps {
|
|
|
20
22
|
* Context value provided by DismissibleProvider
|
|
21
23
|
*/
|
|
22
24
|
export interface DismissibleContextValue {
|
|
25
|
+
/** User ID for the current user - required for all API calls */
|
|
26
|
+
userId: string;
|
|
23
27
|
/** JWT token for authentication */
|
|
24
28
|
jwt?: JwtToken;
|
|
25
29
|
/** Base URL for API requests */
|
|
26
|
-
baseUrl
|
|
30
|
+
baseUrl: string;
|
|
27
31
|
/** Helper function to get authentication headers */
|
|
28
32
|
getAuthHeaders: () => Promise<AuthHeaders>;
|
|
29
33
|
}
|
|
@@ -11,9 +11,3 @@ export declare const resolveJwt: (jwt: JwtToken | undefined) => Promise<string |
|
|
|
11
11
|
* @returns Promise that resolves to headers object with Authorization header if JWT is available
|
|
12
12
|
*/
|
|
13
13
|
export declare const getAuthHeaders: (jwt?: JwtToken) => Promise<AuthHeaders>;
|
|
14
|
-
/**
|
|
15
|
-
* Validates that a JWT token is properly formatted
|
|
16
|
-
* @param token - The JWT token to validate
|
|
17
|
-
* @returns True if token appears to be a valid JWT format
|
|
18
|
-
*/
|
|
19
|
-
export declare const isValidJwtFormat: (token: string) => boolean;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dismissible/react-client",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist",
|
|
@@ -16,12 +16,18 @@
|
|
|
16
16
|
"require": "./dist/dismissible-client.umd.js"
|
|
17
17
|
}
|
|
18
18
|
},
|
|
19
|
+
"publishConfig": {
|
|
20
|
+
"access": "public"
|
|
21
|
+
},
|
|
19
22
|
"scripts": {
|
|
20
23
|
"dev": "vite",
|
|
21
24
|
"build": "vite build",
|
|
25
|
+
"commit": "cz",
|
|
26
|
+
"commitlint": "commitlint --from HEAD~1 --to HEAD --verbose",
|
|
22
27
|
"lint": "eslint \"{.storybook,src,test}/**/*.{ts,tsx}\" --fix",
|
|
23
|
-
"format": "prettier --write \"src/**/*.{ts,tsx}\"",
|
|
28
|
+
"format": "prettier --write \"src/**/*.{ts,tsx}\" \".github/**/*.{yaml,yml}\"",
|
|
24
29
|
"preview": "vite preview",
|
|
30
|
+
"release": "semantic-release",
|
|
25
31
|
"test": "vitest run --config vitest.config.ts",
|
|
26
32
|
"test:watch": "vitest --config vitest.config.ts",
|
|
27
33
|
"storybook": "storybook dev -p 6006",
|
|
@@ -29,52 +35,65 @@
|
|
|
29
35
|
"build-storybook": "storybook build",
|
|
30
36
|
"script": "ts-node -r tsconfig-paths/register --project tsconfig.json",
|
|
31
37
|
"generate:clean": "rm -rf ./src/generated/contract/*",
|
|
32
|
-
"generate:api": "npm run generate:clean && npx openapi-typescript http://localhost:
|
|
38
|
+
"generate:api": "npm run generate:clean && npx openapi-typescript http://localhost:3001/docs-yaml -o ./src/generated/contract/index.d.ts"
|
|
33
39
|
},
|
|
34
40
|
"dependencies": {
|
|
35
|
-
"openapi-fetch": "^0.
|
|
41
|
+
"openapi-fetch": "^0.15.0"
|
|
36
42
|
},
|
|
37
43
|
"peerDependencies": {
|
|
38
|
-
"react": "
|
|
39
|
-
"react-dom": "
|
|
44
|
+
"react": "^18.0.0 || ^19.0.0",
|
|
45
|
+
"react-dom": "^18.0.0 || ^19.0.0"
|
|
40
46
|
},
|
|
41
47
|
"devDependencies": {
|
|
42
|
-
"@babel/core": "^7.28.
|
|
43
|
-
"@babel/preset-env": "^7.28.
|
|
44
|
-
"@babel/preset-typescript": "^7.
|
|
45
|
-
"@
|
|
46
|
-
"@
|
|
47
|
-
"@
|
|
48
|
-
"@
|
|
49
|
-
"@
|
|
50
|
-
"@
|
|
51
|
-
"@
|
|
52
|
-
"@
|
|
53
|
-
"@
|
|
54
|
-
"@
|
|
55
|
-
"@
|
|
56
|
-
"
|
|
57
|
-
"
|
|
48
|
+
"@babel/core": "^7.28.5",
|
|
49
|
+
"@babel/preset-env": "^7.28.5",
|
|
50
|
+
"@babel/preset-typescript": "^7.28.5",
|
|
51
|
+
"@commitlint/cli": "^20.2.0",
|
|
52
|
+
"@commitlint/config-conventional": "^20.2.0",
|
|
53
|
+
"@semantic-release/changelog": "^6.0.3",
|
|
54
|
+
"@semantic-release/git": "^10.0.1",
|
|
55
|
+
"@semantic-release/github": "^12.0.2",
|
|
56
|
+
"@semantic-release/npm": "^13.1.3",
|
|
57
|
+
"@storybook/addon-a11y": "^10.1.10",
|
|
58
|
+
"@storybook/addon-docs": "^10.1.10",
|
|
59
|
+
"@storybook/react-vite": "^10.1.10",
|
|
60
|
+
"@testing-library/jest-dom": "^6.9.1",
|
|
61
|
+
"@testing-library/react": "^16.3.1",
|
|
62
|
+
"@types/node": "^25.0.3",
|
|
63
|
+
"@types/react": "^19.2.7",
|
|
64
|
+
"@types/react-dom": "^19.2.3",
|
|
65
|
+
"@typescript-eslint/eslint-plugin": "^8.50.0",
|
|
66
|
+
"@typescript-eslint/parser": "^8.50.0",
|
|
67
|
+
"@vitejs/plugin-react": "^5.1.2",
|
|
68
|
+
"commitizen": "^4.3.1",
|
|
69
|
+
"core-js": "^3.47.0",
|
|
70
|
+
"cz-conventional-changelog": "^3.3.0",
|
|
71
|
+
"eslint": "^9.39.2",
|
|
58
72
|
"eslint-plugin-react": "^7.37.5",
|
|
59
|
-
"eslint-plugin-react-hooks": "^
|
|
60
|
-
"eslint-plugin-storybook": "^
|
|
61
|
-
"happy-dom": "^
|
|
62
|
-
"msw": "^2.
|
|
63
|
-
"msw-storybook-addon": "^2.0.
|
|
64
|
-
"openapi-typescript": "^7.
|
|
65
|
-
"prettier": "^3.
|
|
66
|
-
"react": "^
|
|
67
|
-
"react-dom": "^
|
|
68
|
-
"
|
|
73
|
+
"eslint-plugin-react-hooks": "^7.0.1",
|
|
74
|
+
"eslint-plugin-storybook": "^10.1.10",
|
|
75
|
+
"happy-dom": "^20.0.11",
|
|
76
|
+
"msw": "^2.12.4",
|
|
77
|
+
"msw-storybook-addon": "^2.0.6",
|
|
78
|
+
"openapi-typescript": "^7.10.1",
|
|
79
|
+
"prettier": "^3.7.4",
|
|
80
|
+
"react": "^19.2.3",
|
|
81
|
+
"react-dom": "^19.2.3",
|
|
82
|
+
"semantic-release": "^25.0.2",
|
|
83
|
+
"storybook": "^10.1.10",
|
|
69
84
|
"ts-node": "^10.9.2",
|
|
70
|
-
"typescript": "^5.
|
|
71
|
-
"vite": "^
|
|
85
|
+
"typescript": "^5.9.3",
|
|
86
|
+
"vite": "^7.3.0",
|
|
72
87
|
"vite-plugin-dts": "^4.5.4",
|
|
73
|
-
"vitest": "^
|
|
88
|
+
"vitest": "^4.0.16"
|
|
89
|
+
},
|
|
90
|
+
"config": {
|
|
91
|
+
"commitizen": {
|
|
92
|
+
"path": "cz-conventional-changelog"
|
|
93
|
+
}
|
|
74
94
|
},
|
|
75
95
|
"eslintConfig": {
|
|
76
96
|
"extends": [
|
|
77
|
-
"plugin:storybook/recommended",
|
|
78
97
|
"plugin:storybook/recommended"
|
|
79
98
|
]
|
|
80
99
|
},
|