@tasoskakour/react-use-oauth2 1.2.0 → 1.3.2

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/README.md CHANGED
@@ -14,7 +14,7 @@
14
14
 
15
15
  ## Install
16
16
 
17
- _Requires `react@16.8.0` or higher that includes hooks._
17
+ _Requires `react@18.0.0` or higher_
18
18
 
19
19
  ```console
20
20
  yarn add @tasoskakour/react-use-oauth2
@@ -106,6 +106,8 @@ After a successful authorization, data will get persisted to **localStorage** an
106
106
 
107
107
  If you want to re-trigger the authorization flow just call `getAuth()` function again.
108
108
 
109
+ **Note**: In case localStorage is throwing an error (e.g user has disabled it) then you can use the `isPersistent` property which - for this case -will be false. Useful if you want to notify the user that the data is only stored in-memory.
110
+
109
111
  ## API
110
112
 
111
113
  - `function useOAuth2(options): {data, loading, error, getAuth}`
@@ -117,9 +119,10 @@ This is the hook that makes this package to work. `Options` is an object that co
117
119
  - **redirectUri** (string): Determines where the 3rd party API server redirects the user after the user completes the authorization flow. In our [example](#usage-example) the Popup is rendered on that redirectUri.
118
120
  - **scope** (string - _optional_): A list of scopes depending on your application needs.
119
121
  - **responseType** (string): Can be either **code** for _code authorization grant_ or **token** for _implicit grant_.
120
- - **extraQueryParameters** (string - _optional_): An object of extra parameters that you'd like to pass to the query part of the authorizeUrl, e.g {audience: "xyz"}.
122
+ - **extraQueryParameters** (object - _optional_): An object of extra parameters that you'd like to pass to the query part of the authorizeUrl, e.g {audience: "xyz"}.
121
123
  - **exchangeCodeForTokenServerURL** (string): This property is only used when using _code authorization grant_ flow (responseType = code). It specifies the API URL of your server that will get called immediately after the user completes the authorization flow. Read more [here](#what-is-the-purpose-of-exchangecodefortokenserverurl-for-authorization-code-flows).
122
124
  - **exchangeCodeForTokenMethod** (string - _optional_): Specifies the HTTP method that will be used for the code-for-token exchange to your server. Defaults to **POST**.
125
+ - **exchangeCodeForTokenHeaders** (object - _optional_): An object of extra parameters that will be used for the code-for-token exchange to your server.
123
126
  - **onSuccess** (function): Called after a complete successful authorization flow.
124
127
  - **onError** (function): Called when an error occurs.
125
128
 
package/dist/cjs/index.js CHANGED
@@ -1 +1 @@
1
- "use strict";var e=require("react/jsx-runtime"),r=require("react"),t=function(){return t=Object.assign||function(e){for(var r,t=1,n=arguments.length;t<n;t++)for(var o in r=arguments[t])Object.prototype.hasOwnProperty.call(r,o)&&(e[o]=r[o]);return e},t.apply(this,arguments)};function n(e,r,t,n){return new(t||(t=Promise))((function(o,a){function i(e){try{u(n.next(e))}catch(e){a(e)}}function c(e){try{u(n.throw(e))}catch(e){a(e)}}function u(e){var r;e.done?o(e.value):(r=e.value,r instanceof t?r:new t((function(e){e(r)}))).then(i,c)}u((n=n.apply(e,r||[])).next())}))}function o(e,r){var t,n,o,a,i={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return a={next:c(0),throw:c(1),return:c(2)},"function"==typeof Symbol&&(a[Symbol.iterator]=function(){return this}),a;function c(c){return function(u){return function(c){if(t)throw new TypeError("Generator is already executing.");for(;a&&(a=0,c[0]&&(i=0)),i;)try{if(t=1,n&&(o=2&c[0]?n.return:c[0]?n.throw||((o=n.return)&&o.call(n),0):n.next)&&!(o=o.call(n,c[1])).done)return o;switch(n=0,o&&(c=[2&c[0],o.value]),c[0]){case 0:case 1:o=c;break;case 4:return i.label++,{value:c[1],done:!1};case 5:i.label++,n=c[1],c=[0];continue;case 7:c=i.ops.pop(),i.trys.pop();continue;default:if(!(o=i.trys,(o=o.length>0&&o[o.length-1])||6!==c[0]&&2!==c[0])){i=0;continue}if(3===c[0]&&(!o||c[1]>o[0]&&c[1]<o[3])){i.label=c[1];break}if(6===c[0]&&i.label<o[1]){i.label=o[1],o=c;break}if(o&&i.label<o[2]){i.label=o[2],i.ops.push(c);break}o[2]&&i.ops.pop(),i.trys.pop();continue}c=r.call(e,i)}catch(e){c=[6,e],n=0}finally{t=o=0}if(5&c[0])throw c[1];return{value:c[0]?c[1]:void 0,done:!0}}([c,u])}}}var a="react-use-oauth2-state-key",i="react-use-oauth2-response",c=function(e){return new URLSearchParams(e).toString()},u=function(e){var r=new URLSearchParams(e);return Object.fromEntries(r.entries())},s=function(e,r){return e.postMessage(r)},l=function(e,r,t){clearInterval(e.current),r.current&&"function"==typeof r.current.close&&function(e){var r;null===(r=e.current)||void 0===r||r.close()}(r),sessionStorage.removeItem(a),window.removeEventListener("message",t)},d=function(e,r,n,o,a){var i=e.split("?")[0],s=u(e.split("?")[1]);return"".concat(i,"?").concat(c(t(t({},s),{client_id:r,grant_type:"authorization_code",code:n,redirect_uri:o,state:a})))};const f=new Map;function p(e,t){if(void 0===r.useSyncExternalStore)throw new TypeError('You are using React 17 or below. Install with "npm install use-local-storage-state@17".');const[n]=r.useState(null==t?void 0:t.defaultValue);if("undefined"==typeof window)return[n,()=>{},{isPersistent:!0,removeItem:()=>{}}];const o=null==t?void 0:t.serializer;return function(e,t,n=!0,o=w,a=JSON.stringify){if(!f.has(e)&&void 0!==t&&null===localStorage.getItem(e))try{localStorage.setItem(e,a(t))}catch(e){}const i=r.useRef({item:null,parsed:t}),c=r.useSyncExternalStore(r.useCallback((r=>{const t=t=>{e===t&&r()};return v.add(t),()=>{v.delete(t)}}),[e]),(()=>{const r=localStorage.getItem(e);if(f.has(e))i.current={item:r,parsed:f.get(e)};else if(r!==i.current.item){let e;try{e=null===r?t:o(r)}catch(r){e=t}i.current={item:r,parsed:e}}return i.current.parsed}),(()=>t)),u=r.useCallback((r=>{const t=r instanceof Function?r(i.current.parsed):r;try{localStorage.setItem(e,a(t)),f.delete(e)}catch(r){f.set(e,t)}h(e)}),[e,a]);return r.useEffect((()=>{if(!n)return;const r=r=>{r.storageArea===localStorage&&r.key===e&&h(e)};return window.addEventListener("storage",r),()=>window.removeEventListener("storage",r)}),[e,n]),r.useMemo((()=>[c,u,{isPersistent:c===t||!f.has(e),removeItem(){f.delete(e),localStorage.removeItem(e),h(e)}}]),[e,u,c,t])}(e,n,null==t?void 0:t.storageSync,null==o?void 0:o.parse,null==o?void 0:o.stringify)}const v=new Set;function h(e){for(const r of[...v])r(e)}function w(e){return"undefined"===e?void 0:JSON.parse(e)}exports.OAuthPopup=function(n){var o=n.Component,c=void 0===o?e.jsx("div",t({style:{margin:"12px"},"data-testid":"popup-loading"},{children:"Loading..."})):o;return r.useEffect((function(){var e=t(t({},u(window.location.search.split("?")[1])),u(window.location.hash.split("#")[1])),r=null==e?void 0:e.state,n=null==e?void 0:e.error,o=null===window||void 0===window?void 0:window.opener;if(!function(e){return null!=e}(o))throw new Error("No window opener");var c,l=r&&(c=r,sessionStorage.getItem(a)===c);if(!n&&l)s(o,{type:i,payload:e});else{var d=n?decodeURI(n):l?"OAuth error: An error has occured.":"OAuth error: State mismatch.";s(o,{type:i,error:d})}}),[]),c},exports.useOAuth2=function(e){var u=e.authorizeUrl,s=e.clientId,f=e.redirectUri,v=e.scope,h=void 0===v?"":v,w=e.responseType,g=e.extraQueryParameters,y=void 0===g?{}:g,m=e.onSuccess,S=e.onError;!function(e){var r=e.authorizeUrl,t=e.clientId,n=e.redirectUri,o=e.responseType,a=e.extraQueryParameters,i=void 0===a?{}:a,c=e.onSuccess,u=e.onError;if(!(r&&t&&n&&o))throw new Error("Missing required props for useOAuth2. Required props are: {authorizeUrl, clientId, redirectUri, responseType}");if("code"===o&&!e.exchangeCodeForTokenServerURL)throw new Error('exchangeCodeForTokenServerURL is required for responseType of "code" for useOAuth2.');if("code"===o&&e.exchangeCodeForTokenMethod&&!["POST","GET"].includes(e.exchangeCodeForTokenMethod))throw new Error('Invalid exchangeCodeForTokenServerURL value. It can be one of "POST" or "GET".');if("object"!=typeof i)throw new TypeError("extraQueryParameters must be an object for useOAuth2.");if(c&&"function"!=typeof c)throw new TypeError("onSuccess callback must be a function for useOAuth2.");if(u&&"function"!=typeof u)throw new TypeError("onError callback must be a function for useOAuth2.")}(e);var b=r.useRef(y),E=r.useRef(),x=r.useRef(),I=r.useState({loading:!1,error:null}),T=I[0],k=T.loading,O=T.error,P=I[1],A=p("".concat(w,"-").concat(u,"-").concat(s,"-").concat(h),{defaultValue:null}),U=A[0],C=A[1],R=A[2],L=R.removeItem,j=R.isPersistent,F="code"===w&&e.exchangeCodeForTokenServerURL,M="code"===w&&e.exchangeCodeForTokenMethod,_=r.useCallback((function(){P({loading:!0,error:null});var e,r,p,v,g,y=(e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",r=new Uint8Array(40),window.crypto.getRandomValues(r),r=r.map((function(r){return e.codePointAt(r%e.length)})),String.fromCharCode.apply(null,r));function I(e){var r,t,a;return n(this,void 0,void 0,(function(){var n,c,u;return o(this,(function(o){switch(o.label){case 0:if((null===(r=null==e?void 0:e.data)||void 0===r?void 0:r.type)!==i)return[2];o.label=1;case 1:return o.trys.push([1,10,11,12]),"error"in e.data?(n=(null===(t=e.data)||void 0===t?void 0:t.error)||"Unknown Error occured.",P({loading:!1,error:n}),S?[4,S(n)]:[3,3]):[3,4];case 2:o.sent(),o.label=3;case 3:return[3,9];case 4:return c=null===(a=null==e?void 0:e.data)||void 0===a?void 0:a.payload,"code"===w&&F?[4,fetch(d(F,s,null==c?void 0:c.code,f,y),{method:M||"POST"})]:[3,7];case 5:return[4,o.sent().json()];case 6:c=o.sent(),o.label=7;case 7:return P({loading:!1,error:null}),C(c),m?[4,m(c)]:[3,9];case 8:o.sent(),o.label=9;case 9:return[3,12];case 10:return u=o.sent(),console.error(u),P({loading:!1,error:u.toString()}),[3,12];case 11:return l(x,E,I),[7];case 12:return[2]}}))}))}return function(e){sessionStorage.setItem(a,e)}(y),E.current=(p=function(e,r,n,o,a,i,u){void 0===u&&(u={});var s=c(t({response_type:i,client_id:r,redirect_uri:n,scope:o,state:a},u));return"".concat(e,"?").concat(s)}(u,s,f,h,y,w,b.current),v=window.outerHeight/2+window.screenY-350,g=window.outerWidth/2+window.screenX-300,window.open(p,"OAuth2 Popup","height=".concat(700,",width=").concat(600,",top=").concat(v,",left=").concat(g))),window.addEventListener("message",I),x.current=setInterval((function(){var e,r,n;(!(null===(e=E.current)||void 0===e?void 0:e.window)||(null===(n=null===(r=E.current)||void 0===r?void 0:r.window)||void 0===n?void 0:n.closed))&&(P((function(e){return t(t({},e),{loading:!1})})),console.warn("Warning: Popup was closed before completing authentication."),l(x,E,I))}),250),function(){window.removeEventListener("message",I),x.current&&clearInterval(x.current)}}),[u,s,f,h,w,F,M,m,S,P,C]);return{data:U,loading:k,error:O,getAuth:_,logout:r.useCallback((function(){L(),P({loading:!1,error:null})}),[L]),isPersistent:j}};
1
+ "use strict";var e=require("react/jsx-runtime"),r=require("react"),t=function(){return t=Object.assign||function(e){for(var r,t=1,n=arguments.length;t<n;t++)for(var o in r=arguments[t])Object.prototype.hasOwnProperty.call(r,o)&&(e[o]=r[o]);return e},t.apply(this,arguments)};function n(e,r,t,n){return new(t||(t=Promise))((function(o,a){function i(e){try{u(n.next(e))}catch(e){a(e)}}function c(e){try{u(n.throw(e))}catch(e){a(e)}}function u(e){var r;e.done?o(e.value):(r=e.value,r instanceof t?r:new t((function(e){e(r)}))).then(i,c)}u((n=n.apply(e,r||[])).next())}))}function o(e,r){var t,n,o,a,i={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return a={next:c(0),throw:c(1),return:c(2)},"function"==typeof Symbol&&(a[Symbol.iterator]=function(){return this}),a;function c(c){return function(u){return function(c){if(t)throw new TypeError("Generator is already executing.");for(;a&&(a=0,c[0]&&(i=0)),i;)try{if(t=1,n&&(o=2&c[0]?n.return:c[0]?n.throw||((o=n.return)&&o.call(n),0):n.next)&&!(o=o.call(n,c[1])).done)return o;switch(n=0,o&&(c=[2&c[0],o.value]),c[0]){case 0:case 1:o=c;break;case 4:return i.label++,{value:c[1],done:!1};case 5:i.label++,n=c[1],c=[0];continue;case 7:c=i.ops.pop(),i.trys.pop();continue;default:if(!(o=i.trys,(o=o.length>0&&o[o.length-1])||6!==c[0]&&2!==c[0])){i=0;continue}if(3===c[0]&&(!o||c[1]>o[0]&&c[1]<o[3])){i.label=c[1];break}if(6===c[0]&&i.label<o[1]){i.label=o[1],o=c;break}if(o&&i.label<o[2]){i.label=o[2],i.ops.push(c);break}o[2]&&i.ops.pop(),i.trys.pop();continue}c=r.call(e,i)}catch(e){c=[6,e],n=0}finally{t=o=0}if(5&c[0])throw c[1];return{value:c[0]?c[1]:void 0,done:!0}}([c,u])}}}var a="react-use-oauth2-state-key",i="react-use-oauth2-response",c=function(e){return new URLSearchParams(e).toString()},u=function(e){var r=new URLSearchParams(e);return Object.fromEntries(r.entries())},s=function(e,r){return e.postMessage(r)},l=function(e,r,t){clearInterval(e.current),r.current&&"function"==typeof r.current.close&&function(e){var r;null===(r=e.current)||void 0===r||r.close()}(r),sessionStorage.removeItem(a),window.removeEventListener("message",t)},d=function(e,r,n,o,a){var i=e.split("?")[0],s=u(e.split("?")[1]);return"".concat(i,"?").concat(c(t(t({},s),{client_id:r,grant_type:"authorization_code",code:n,redirect_uri:o,state:a})))};const f=new Map;function p(e,t){if(void 0===r.useSyncExternalStore)throw new TypeError('You are using React 17 or below. Install with "npm install use-local-storage-state@17".');const[n]=r.useState(null==t?void 0:t.defaultValue);if("undefined"==typeof window)return[n,()=>{},{isPersistent:!0,removeItem:()=>{}}];const o=null==t?void 0:t.serializer;return function(e,t,n=!0,o=w,a=JSON.stringify){f.has(e)||void 0===t||null!==g((()=>localStorage.getItem(e)))||g((()=>localStorage.setItem(e,a(t))));const i=r.useRef({item:null,parsed:t}),c=r.useSyncExternalStore(r.useCallback((r=>{const t=t=>{e===t&&r()};return v.add(t),()=>{v.delete(t)}}),[e]),(()=>{var r;const n=null!==(r=g((()=>localStorage.getItem(e))))&&void 0!==r?r:null;if(f.has(e))i.current={item:n,parsed:f.get(e)};else if(n!==i.current.item){let e;try{e=null===n?t:o(n)}catch(r){e=t}i.current={item:n,parsed:e}}return i.current.parsed}),(()=>t)),u=r.useCallback((r=>{const t=r instanceof Function?r(i.current.parsed):r;try{localStorage.setItem(e,a(t)),f.delete(e)}catch(r){f.set(e,t)}h(e)}),[e,a]);return r.useEffect((()=>{if(!n)return;const r=r=>{r.storageArea===g((()=>localStorage))&&r.key===e&&h(e)};return window.addEventListener("storage",r),()=>window.removeEventListener("storage",r)}),[e,n]),r.useMemo((()=>[c,u,{isPersistent:c===t||!f.has(e),removeItem(){g((()=>localStorage.removeItem(e))),f.delete(e),h(e)}}]),[e,u,c,t])}(e,n,null==t?void 0:t.storageSync,null==o?void 0:o.parse,null==o?void 0:o.stringify)}const v=new Set;function h(e){for(const r of[...v])r(e)}function w(e){return"undefined"===e?void 0:JSON.parse(e)}function g(e){try{return e()}catch(e){return}}exports.OAuthPopup=function(n){var o=n.Component,c=void 0===o?e.jsx("div",t({style:{margin:"12px"},"data-testid":"popup-loading"},{children:"Loading..."})):o;return r.useEffect((function(){var e=t(t({},u(window.location.search.split("?")[1])),u(window.location.hash.split("#")[1])),r=null==e?void 0:e.state,n=null==e?void 0:e.error,o=null===window||void 0===window?void 0:window.opener;if(!function(e){return null!=e}(o))throw new Error("No window opener");var c,l=r&&(c=r,sessionStorage.getItem(a)===c);if(!n&&l)s(o,{type:i,payload:e});else{var d=n?decodeURI(n):l?"OAuth error: An error has occured.":"OAuth error: State mismatch.";s(o,{type:i,error:d})}}),[]),c},exports.useOAuth2=function(e){var u=e.authorizeUrl,s=e.clientId,f=e.redirectUri,v=e.scope,h=void 0===v?"":v,w=e.responseType,g=e.extraQueryParameters,y=void 0===g?{}:g,m=e.onSuccess,S=e.onError;!function(e){var r=e.authorizeUrl,t=e.clientId,n=e.redirectUri,o=e.responseType,a=e.extraQueryParameters,i=void 0===a?{}:a,c=e.onSuccess,u=e.onError;if(!(r&&t&&n&&o))throw new Error("Missing required props for useOAuth2. Required props are: {authorizeUrl, clientId, redirectUri, responseType}");if("code"===o&&!e.exchangeCodeForTokenServerURL)throw new Error('exchangeCodeForTokenServerURL is required for responseType of "code" for useOAuth2.');if("code"===o&&e.exchangeCodeForTokenMethod&&!["POST","GET"].includes(e.exchangeCodeForTokenMethod))throw new Error('Invalid exchangeCodeForTokenServerURL value. It can be one of "POST" or "GET".');if("object"!=typeof i)throw new TypeError("extraQueryParameters must be an object for useOAuth2.");if(c&&"function"!=typeof c)throw new TypeError("onSuccess callback must be a function for useOAuth2.");if(u&&"function"!=typeof u)throw new TypeError("onError callback must be a function for useOAuth2.")}(e);var b=r.useRef(y),E=r.useRef(),x=r.useRef(),T=r.useState({loading:!1,error:null}),k=T[0],I=k.loading,O=k.error,P=T[1],A=p("".concat(w,"-").concat(u,"-").concat(s,"-").concat(h),{defaultValue:null}),C=A[0],U=A[1],R=A[2],L=R.removeItem,F=R.isPersistent,j="code"===w&&e.exchangeCodeForTokenServerURL,M="code"===w&&e.exchangeCodeForTokenMethod,_="code"===w&&e.exchangeCodeForTokenHeaders,q=r.useCallback((function(){P({loading:!0,error:null});var e,r,p,v,g,y=(e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",r=new Uint8Array(40),window.crypto.getRandomValues(r),r=r.map((function(r){return e.codePointAt(r%e.length)})),String.fromCharCode.apply(null,r));function T(e){var r,t,a;return n(this,void 0,void 0,(function(){var n,c,u;return o(this,(function(o){switch(o.label){case 0:if((null===(r=null==e?void 0:e.data)||void 0===r?void 0:r.type)!==i)return[2];o.label=1;case 1:return o.trys.push([1,10,11,12]),"error"in e.data?(n=(null===(t=e.data)||void 0===t?void 0:t.error)||"Unknown Error occured.",P({loading:!1,error:n}),S?[4,S(n)]:[3,3]):[3,4];case 2:o.sent(),o.label=3;case 3:return[3,9];case 4:return c=null===(a=null==e?void 0:e.data)||void 0===a?void 0:a.payload,"code"===w&&j?[4,fetch(d(j,s,null==c?void 0:c.code,f,y),{method:M||"POST",headers:_||{}})]:[3,7];case 5:return[4,o.sent().json()];case 6:c=o.sent(),o.label=7;case 7:return P({loading:!1,error:null}),U(c),m?[4,m(c)]:[3,9];case 8:o.sent(),o.label=9;case 9:return[3,12];case 10:return u=o.sent(),console.error(u),P({loading:!1,error:u.toString()}),[3,12];case 11:return l(x,E,T),[7];case 12:return[2]}}))}))}return function(e){sessionStorage.setItem(a,e)}(y),E.current=(p=function(e,r,n,o,a,i,u){void 0===u&&(u={});var s=c(t({response_type:i,client_id:r,redirect_uri:n,scope:o,state:a},u));return"".concat(e,"?").concat(s)}(u,s,f,h,y,w,b.current),v=window.outerHeight/2+window.screenY-350,g=window.outerWidth/2+window.screenX-300,window.open(p,"OAuth2 Popup","height=".concat(700,",width=").concat(600,",top=").concat(v,",left=").concat(g))),window.addEventListener("message",T),x.current=setInterval((function(){var e,r,n;(!(null===(e=E.current)||void 0===e?void 0:e.window)||(null===(n=null===(r=E.current)||void 0===r?void 0:r.window)||void 0===n?void 0:n.closed))&&(P((function(e){return t(t({},e),{loading:!1})})),console.warn("Warning: Popup was closed before completing authentication."),l(x,E,T))}),250),function(){window.removeEventListener("message",T),x.current&&clearInterval(x.current)}}),[u,s,f,h,w,j,M,_,m,S,P,U]);return{data:C,loading:I,error:O,getAuth:q,logout:r.useCallback((function(){L(),P({loading:!1,error:null})}),[L]),isPersistent:F}};
@@ -10,6 +10,7 @@ export type TResponseTypeBasedProps<TData> = {
10
10
  responseType: 'code';
11
11
  exchangeCodeForTokenServerURL: string;
12
12
  exchangeCodeForTokenMethod?: 'POST' | 'GET';
13
+ exchangeCodeForTokenHeaders?: Record<string, any>;
13
14
  onSuccess?: (payload: TData) => void;
14
15
  } | {
15
16
  responseType: 'token';
package/dist/esm/index.js CHANGED
@@ -1 +1 @@
1
- import{jsx as e}from"react/jsx-runtime";import{useEffect as r,useSyncExternalStore as n,useState as t,useRef as o,useCallback as i,useMemo as a}from"react";var c=function(){return c=Object.assign||function(e){for(var r,n=1,t=arguments.length;n<t;n++)for(var o in r=arguments[n])Object.prototype.hasOwnProperty.call(r,o)&&(e[o]=r[o]);return e},c.apply(this,arguments)};function u(e,r,n,t){return new(n||(n=Promise))((function(o,i){function a(e){try{u(t.next(e))}catch(e){i(e)}}function c(e){try{u(t.throw(e))}catch(e){i(e)}}function u(e){var r;e.done?o(e.value):(r=e.value,r instanceof n?r:new n((function(e){e(r)}))).then(a,c)}u((t=t.apply(e,r||[])).next())}))}function s(e,r){var n,t,o,i,a={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return i={next:c(0),throw:c(1),return:c(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function c(c){return function(u){return function(c){if(n)throw new TypeError("Generator is already executing.");for(;i&&(i=0,c[0]&&(a=0)),a;)try{if(n=1,t&&(o=2&c[0]?t.return:c[0]?t.throw||((o=t.return)&&o.call(t),0):t.next)&&!(o=o.call(t,c[1])).done)return o;switch(t=0,o&&(c=[2&c[0],o.value]),c[0]){case 0:case 1:o=c;break;case 4:return a.label++,{value:c[1],done:!1};case 5:a.label++,t=c[1],c=[0];continue;case 7:c=a.ops.pop(),a.trys.pop();continue;default:if(!(o=a.trys,(o=o.length>0&&o[o.length-1])||6!==c[0]&&2!==c[0])){a=0;continue}if(3===c[0]&&(!o||c[1]>o[0]&&c[1]<o[3])){a.label=c[1];break}if(6===c[0]&&a.label<o[1]){a.label=o[1],o=c;break}if(o&&a.label<o[2]){a.label=o[2],a.ops.push(c);break}o[2]&&a.ops.pop(),a.trys.pop();continue}c=r.call(e,a)}catch(e){c=[6,e],t=0}finally{n=o=0}if(5&c[0])throw c[1];return{value:c[0]?c[1]:void 0,done:!0}}([c,u])}}}var l="react-use-oauth2-state-key",d="react-use-oauth2-response",f=function(e){return new URLSearchParams(e).toString()},p=function(e){var r=new URLSearchParams(e);return Object.fromEntries(r.entries())},v=function(e,r){return e.postMessage(r)},h=function(e,r,n){clearInterval(e.current),r.current&&"function"==typeof r.current.close&&function(e){var r;null===(r=e.current)||void 0===r||r.close()}(r),sessionStorage.removeItem(l),window.removeEventListener("message",n)},w=function(e,r,n,t,o){var i=e.split("?")[0],a=p(e.split("?")[1]);return"".concat(i,"?").concat(f(c(c({},a),{client_id:r,grant_type:"authorization_code",code:n,redirect_uri:t,state:o})))},g=function(n){var t=n.Component,o=void 0===t?e("div",c({style:{margin:"12px"},"data-testid":"popup-loading"},{children:"Loading..."})):t;return r((function(){var e=c(c({},p(window.location.search.split("?")[1])),p(window.location.hash.split("#")[1])),r=null==e?void 0:e.state,n=null==e?void 0:e.error,t=null===window||void 0===window?void 0:window.opener;if(!function(e){return null!=e}(t))throw new Error("No window opener");var o,i=r&&(o=r,sessionStorage.getItem(l)===o);if(!n&&i)v(t,{type:d,payload:e});else{var a=n?decodeURI(n):i?"OAuth error: An error has occured.":"OAuth error: State mismatch.";v(t,{type:d,error:a})}}),[]),o};const m=new Map;function y(e,c){if(void 0===n)throw new TypeError('You are using React 17 or below. Install with "npm install use-local-storage-state@17".');const[u]=t(null==c?void 0:c.defaultValue);if("undefined"==typeof window)return[u,()=>{},{isPersistent:!0,removeItem:()=>{}}];const s=null==c?void 0:c.serializer;return function(e,t,c=!0,u=E,s=JSON.stringify){if(!m.has(e)&&void 0!==t&&null===localStorage.getItem(e))try{localStorage.setItem(e,s(t))}catch(e){}const l=o({item:null,parsed:t}),d=n(i((r=>{const n=n=>{e===n&&r()};return b.add(n),()=>{b.delete(n)}}),[e]),(()=>{const r=localStorage.getItem(e);if(m.has(e))l.current={item:r,parsed:m.get(e)};else if(r!==l.current.item){let e;try{e=null===r?t:u(r)}catch(r){e=t}l.current={item:r,parsed:e}}return l.current.parsed}),(()=>t)),f=i((r=>{const n=r instanceof Function?r(l.current.parsed):r;try{localStorage.setItem(e,s(n)),m.delete(e)}catch(r){m.set(e,n)}S(e)}),[e,s]);return r((()=>{if(!c)return;const r=r=>{r.storageArea===localStorage&&r.key===e&&S(e)};return window.addEventListener("storage",r),()=>window.removeEventListener("storage",r)}),[e,c]),a((()=>[d,f,{isPersistent:d===t||!m.has(e),removeItem(){m.delete(e),localStorage.removeItem(e),S(e)}}]),[e,f,d,t])}(e,u,null==c?void 0:c.storageSync,null==s?void 0:s.parse,null==s?void 0:s.stringify)}const b=new Set;function S(e){for(const r of[...b])r(e)}function E(e){return"undefined"===e?void 0:JSON.parse(e)}var I=function(e){var r=e.authorizeUrl,n=e.clientId,a=e.redirectUri,p=e.scope,v=void 0===p?"":p,g=e.responseType,m=e.extraQueryParameters,b=void 0===m?{}:m,S=e.onSuccess,E=e.onError;!function(e){var r=e.authorizeUrl,n=e.clientId,t=e.redirectUri,o=e.responseType,i=e.extraQueryParameters,a=void 0===i?{}:i,c=e.onSuccess,u=e.onError;if(!(r&&n&&t&&o))throw new Error("Missing required props for useOAuth2. Required props are: {authorizeUrl, clientId, redirectUri, responseType}");if("code"===o&&!e.exchangeCodeForTokenServerURL)throw new Error('exchangeCodeForTokenServerURL is required for responseType of "code" for useOAuth2.');if("code"===o&&e.exchangeCodeForTokenMethod&&!["POST","GET"].includes(e.exchangeCodeForTokenMethod))throw new Error('Invalid exchangeCodeForTokenServerURL value. It can be one of "POST" or "GET".');if("object"!=typeof a)throw new TypeError("extraQueryParameters must be an object for useOAuth2.");if(c&&"function"!=typeof c)throw new TypeError("onSuccess callback must be a function for useOAuth2.");if(u&&"function"!=typeof u)throw new TypeError("onError callback must be a function for useOAuth2.")}(e);var I=o(b),T=o(),x=o(),O=t({loading:!1,error:null}),P=O[0],k=P.loading,U=P.error,A=O[1],L=y("".concat(g,"-").concat(r,"-").concat(n,"-").concat(v),{defaultValue:null}),C=L[0],R=L[1],F=L[2],j=F.removeItem,M=F.isPersistent,_="code"===g&&e.exchangeCodeForTokenServerURL,z="code"===g&&e.exchangeCodeForTokenMethod,q=i((function(){A({loading:!0,error:null});var e,t,o,i,p,m=(e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",t=new Uint8Array(40),window.crypto.getRandomValues(t),t=t.map((function(r){return e.codePointAt(r%e.length)})),String.fromCharCode.apply(null,t));function y(e){var r,t,o;return u(this,void 0,void 0,(function(){var i,c,u;return s(this,(function(s){switch(s.label){case 0:if((null===(r=null==e?void 0:e.data)||void 0===r?void 0:r.type)!==d)return[2];s.label=1;case 1:return s.trys.push([1,10,11,12]),"error"in e.data?(i=(null===(t=e.data)||void 0===t?void 0:t.error)||"Unknown Error occured.",A({loading:!1,error:i}),E?[4,E(i)]:[3,3]):[3,4];case 2:s.sent(),s.label=3;case 3:return[3,9];case 4:return c=null===(o=null==e?void 0:e.data)||void 0===o?void 0:o.payload,"code"===g&&_?[4,fetch(w(_,n,null==c?void 0:c.code,a,m),{method:z||"POST"})]:[3,7];case 5:return[4,s.sent().json()];case 6:c=s.sent(),s.label=7;case 7:return A({loading:!1,error:null}),R(c),S?[4,S(c)]:[3,9];case 8:s.sent(),s.label=9;case 9:return[3,12];case 10:return u=s.sent(),console.error(u),A({loading:!1,error:u.toString()}),[3,12];case 11:return h(x,T,y),[7];case 12:return[2]}}))}))}return function(e){sessionStorage.setItem(l,e)}(m),T.current=(o=function(e,r,n,t,o,i,a){void 0===a&&(a={});var u=f(c({response_type:i,client_id:r,redirect_uri:n,scope:t,state:o},a));return"".concat(e,"?").concat(u)}(r,n,a,v,m,g,I.current),i=window.outerHeight/2+window.screenY-350,p=window.outerWidth/2+window.screenX-300,window.open(o,"OAuth2 Popup","height=".concat(700,",width=").concat(600,",top=").concat(i,",left=").concat(p))),window.addEventListener("message",y),x.current=setInterval((function(){var e,r,n;(!(null===(e=T.current)||void 0===e?void 0:e.window)||(null===(n=null===(r=T.current)||void 0===r?void 0:r.window)||void 0===n?void 0:n.closed))&&(A((function(e){return c(c({},e),{loading:!1})})),console.warn("Warning: Popup was closed before completing authentication."),h(x,T,y))}),250),function(){window.removeEventListener("message",y),x.current&&clearInterval(x.current)}}),[r,n,a,v,g,_,z,S,E,A,R]);return{data:C,loading:k,error:U,getAuth:q,logout:i((function(){j(),A({loading:!1,error:null})}),[j]),isPersistent:M}};export{g as OAuthPopup,I as useOAuth2};
1
+ import{jsx as e}from"react/jsx-runtime";import{useEffect as r,useSyncExternalStore as n,useState as t,useRef as o,useCallback as a,useMemo as i}from"react";var c=function(){return c=Object.assign||function(e){for(var r,n=1,t=arguments.length;n<t;n++)for(var o in r=arguments[n])Object.prototype.hasOwnProperty.call(r,o)&&(e[o]=r[o]);return e},c.apply(this,arguments)};function u(e,r,n,t){return new(n||(n=Promise))((function(o,a){function i(e){try{u(t.next(e))}catch(e){a(e)}}function c(e){try{u(t.throw(e))}catch(e){a(e)}}function u(e){var r;e.done?o(e.value):(r=e.value,r instanceof n?r:new n((function(e){e(r)}))).then(i,c)}u((t=t.apply(e,r||[])).next())}))}function s(e,r){var n,t,o,a,i={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return a={next:c(0),throw:c(1),return:c(2)},"function"==typeof Symbol&&(a[Symbol.iterator]=function(){return this}),a;function c(c){return function(u){return function(c){if(n)throw new TypeError("Generator is already executing.");for(;a&&(a=0,c[0]&&(i=0)),i;)try{if(n=1,t&&(o=2&c[0]?t.return:c[0]?t.throw||((o=t.return)&&o.call(t),0):t.next)&&!(o=o.call(t,c[1])).done)return o;switch(t=0,o&&(c=[2&c[0],o.value]),c[0]){case 0:case 1:o=c;break;case 4:return i.label++,{value:c[1],done:!1};case 5:i.label++,t=c[1],c=[0];continue;case 7:c=i.ops.pop(),i.trys.pop();continue;default:if(!(o=i.trys,(o=o.length>0&&o[o.length-1])||6!==c[0]&&2!==c[0])){i=0;continue}if(3===c[0]&&(!o||c[1]>o[0]&&c[1]<o[3])){i.label=c[1];break}if(6===c[0]&&i.label<o[1]){i.label=o[1],o=c;break}if(o&&i.label<o[2]){i.label=o[2],i.ops.push(c);break}o[2]&&i.ops.pop(),i.trys.pop();continue}c=r.call(e,i)}catch(e){c=[6,e],t=0}finally{n=o=0}if(5&c[0])throw c[1];return{value:c[0]?c[1]:void 0,done:!0}}([c,u])}}}var l="react-use-oauth2-state-key",d="react-use-oauth2-response",f=function(e){return new URLSearchParams(e).toString()},p=function(e){var r=new URLSearchParams(e);return Object.fromEntries(r.entries())},v=function(e,r){return e.postMessage(r)},h=function(e,r,n){clearInterval(e.current),r.current&&"function"==typeof r.current.close&&function(e){var r;null===(r=e.current)||void 0===r||r.close()}(r),sessionStorage.removeItem(l),window.removeEventListener("message",n)},w=function(e,r,n,t,o){var a=e.split("?")[0],i=p(e.split("?")[1]);return"".concat(a,"?").concat(f(c(c({},i),{client_id:r,grant_type:"authorization_code",code:n,redirect_uri:t,state:o})))},g=function(n){var t=n.Component,o=void 0===t?e("div",c({style:{margin:"12px"},"data-testid":"popup-loading"},{children:"Loading..."})):t;return r((function(){var e=c(c({},p(window.location.search.split("?")[1])),p(window.location.hash.split("#")[1])),r=null==e?void 0:e.state,n=null==e?void 0:e.error,t=null===window||void 0===window?void 0:window.opener;if(!function(e){return null!=e}(t))throw new Error("No window opener");var o,a=r&&(o=r,sessionStorage.getItem(l)===o);if(!n&&a)v(t,{type:d,payload:e});else{var i=n?decodeURI(n):a?"OAuth error: An error has occured.":"OAuth error: State mismatch.";v(t,{type:d,error:i})}}),[]),o};const m=new Map;function y(e,c){if(void 0===n)throw new TypeError('You are using React 17 or below. Install with "npm install use-local-storage-state@17".');const[u]=t(null==c?void 0:c.defaultValue);if("undefined"==typeof window)return[u,()=>{},{isPersistent:!0,removeItem:()=>{}}];const s=null==c?void 0:c.serializer;return function(e,t,c=!0,u=T,s=JSON.stringify){m.has(e)||void 0===t||null!==E((()=>localStorage.getItem(e)))||E((()=>localStorage.setItem(e,s(t))));const l=o({item:null,parsed:t}),d=n(a((r=>{const n=n=>{e===n&&r()};return b.add(n),()=>{b.delete(n)}}),[e]),(()=>{var r;const n=null!==(r=E((()=>localStorage.getItem(e))))&&void 0!==r?r:null;if(m.has(e))l.current={item:n,parsed:m.get(e)};else if(n!==l.current.item){let e;try{e=null===n?t:u(n)}catch(r){e=t}l.current={item:n,parsed:e}}return l.current.parsed}),(()=>t)),f=a((r=>{const n=r instanceof Function?r(l.current.parsed):r;try{localStorage.setItem(e,s(n)),m.delete(e)}catch(r){m.set(e,n)}S(e)}),[e,s]);return r((()=>{if(!c)return;const r=r=>{r.storageArea===E((()=>localStorage))&&r.key===e&&S(e)};return window.addEventListener("storage",r),()=>window.removeEventListener("storage",r)}),[e,c]),i((()=>[d,f,{isPersistent:d===t||!m.has(e),removeItem(){E((()=>localStorage.removeItem(e))),m.delete(e),S(e)}}]),[e,f,d,t])}(e,u,null==c?void 0:c.storageSync,null==s?void 0:s.parse,null==s?void 0:s.stringify)}const b=new Set;function S(e){for(const r of[...b])r(e)}function T(e){return"undefined"===e?void 0:JSON.parse(e)}function E(e){try{return e()}catch(e){return}}var I=function(e){var r=e.authorizeUrl,n=e.clientId,i=e.redirectUri,p=e.scope,v=void 0===p?"":p,g=e.responseType,m=e.extraQueryParameters,b=void 0===m?{}:m,S=e.onSuccess,T=e.onError;!function(e){var r=e.authorizeUrl,n=e.clientId,t=e.redirectUri,o=e.responseType,a=e.extraQueryParameters,i=void 0===a?{}:a,c=e.onSuccess,u=e.onError;if(!(r&&n&&t&&o))throw new Error("Missing required props for useOAuth2. Required props are: {authorizeUrl, clientId, redirectUri, responseType}");if("code"===o&&!e.exchangeCodeForTokenServerURL)throw new Error('exchangeCodeForTokenServerURL is required for responseType of "code" for useOAuth2.');if("code"===o&&e.exchangeCodeForTokenMethod&&!["POST","GET"].includes(e.exchangeCodeForTokenMethod))throw new Error('Invalid exchangeCodeForTokenServerURL value. It can be one of "POST" or "GET".');if("object"!=typeof i)throw new TypeError("extraQueryParameters must be an object for useOAuth2.");if(c&&"function"!=typeof c)throw new TypeError("onSuccess callback must be a function for useOAuth2.");if(u&&"function"!=typeof u)throw new TypeError("onError callback must be a function for useOAuth2.")}(e);var E=o(b),I=o(),x=o(),k=t({loading:!1,error:null}),O=k[0],P=O.loading,U=O.error,A=k[1],L=y("".concat(g,"-").concat(r,"-").concat(n,"-").concat(v),{defaultValue:null}),C=L[0],R=L[1],F=L[2],j=F.removeItem,M=F.isPersistent,_="code"===g&&e.exchangeCodeForTokenServerURL,z="code"===g&&e.exchangeCodeForTokenMethod,q="code"===g&&e.exchangeCodeForTokenHeaders,G=a((function(){A({loading:!0,error:null});var e,t,o,a,p,m=(e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",t=new Uint8Array(40),window.crypto.getRandomValues(t),t=t.map((function(r){return e.codePointAt(r%e.length)})),String.fromCharCode.apply(null,t));function y(e){var r,t,o;return u(this,void 0,void 0,(function(){var a,c,u;return s(this,(function(s){switch(s.label){case 0:if((null===(r=null==e?void 0:e.data)||void 0===r?void 0:r.type)!==d)return[2];s.label=1;case 1:return s.trys.push([1,10,11,12]),"error"in e.data?(a=(null===(t=e.data)||void 0===t?void 0:t.error)||"Unknown Error occured.",A({loading:!1,error:a}),T?[4,T(a)]:[3,3]):[3,4];case 2:s.sent(),s.label=3;case 3:return[3,9];case 4:return c=null===(o=null==e?void 0:e.data)||void 0===o?void 0:o.payload,"code"===g&&_?[4,fetch(w(_,n,null==c?void 0:c.code,i,m),{method:z||"POST",headers:q||{}})]:[3,7];case 5:return[4,s.sent().json()];case 6:c=s.sent(),s.label=7;case 7:return A({loading:!1,error:null}),R(c),S?[4,S(c)]:[3,9];case 8:s.sent(),s.label=9;case 9:return[3,12];case 10:return u=s.sent(),console.error(u),A({loading:!1,error:u.toString()}),[3,12];case 11:return h(x,I,y),[7];case 12:return[2]}}))}))}return function(e){sessionStorage.setItem(l,e)}(m),I.current=(o=function(e,r,n,t,o,a,i){void 0===i&&(i={});var u=f(c({response_type:a,client_id:r,redirect_uri:n,scope:t,state:o},i));return"".concat(e,"?").concat(u)}(r,n,i,v,m,g,E.current),a=window.outerHeight/2+window.screenY-350,p=window.outerWidth/2+window.screenX-300,window.open(o,"OAuth2 Popup","height=".concat(700,",width=").concat(600,",top=").concat(a,",left=").concat(p))),window.addEventListener("message",y),x.current=setInterval((function(){var e,r,n;(!(null===(e=I.current)||void 0===e?void 0:e.window)||(null===(n=null===(r=I.current)||void 0===r?void 0:r.window)||void 0===n?void 0:n.closed))&&(A((function(e){return c(c({},e),{loading:!1})})),console.warn("Warning: Popup was closed before completing authentication."),h(x,I,y))}),250),function(){window.removeEventListener("message",y),x.current&&clearInterval(x.current)}}),[r,n,i,v,g,_,z,q,S,T,A,R]);return{data:C,loading:P,error:U,getAuth:G,logout:a((function(){j(),A({loading:!1,error:null})}),[j]),isPersistent:M}};export{g as OAuthPopup,I as useOAuth2};
@@ -10,6 +10,7 @@ export type TResponseTypeBasedProps<TData> = {
10
10
  responseType: 'code';
11
11
  exchangeCodeForTokenServerURL: string;
12
12
  exchangeCodeForTokenMethod?: 'POST' | 'GET';
13
+ exchangeCodeForTokenHeaders?: Record<string, any>;
13
14
  onSuccess?: (payload: TData) => void;
14
15
  } | {
15
16
  responseType: 'token';
package/dist/index.d.ts CHANGED
@@ -19,6 +19,7 @@ type TResponseTypeBasedProps<TData> = {
19
19
  responseType: 'code';
20
20
  exchangeCodeForTokenServerURL: string;
21
21
  exchangeCodeForTokenMethod?: 'POST' | 'GET';
22
+ exchangeCodeForTokenHeaders?: Record<string, any>;
22
23
  onSuccess?: (payload: TData) => void;
23
24
  } | {
24
25
  responseType: 'token';
package/package.json CHANGED
@@ -12,7 +12,7 @@
12
12
  "nodejs",
13
13
  "oauth2"
14
14
  ],
15
- "version": "1.2.0",
15
+ "version": "1.3.2",
16
16
  "description": "A React hook that handles OAuth2 authorization flow.",
17
17
  "license": "MIT",
18
18
  "homepage": "https://github.com/tasoskakour/react-use-oauth2#readme",
@@ -23,7 +23,7 @@
23
23
  "main": "dist/cjs/index.js",
24
24
  "module": "dist/esm/index.js",
25
25
  "dependencies": {
26
- "use-local-storage-state": "^18.3.0"
26
+ "use-local-storage-state": "^18.3.3"
27
27
  },
28
28
  "scripts": {
29
29
  "build": "rollup -c",
@@ -49,55 +49,56 @@
49
49
  ]
50
50
  },
51
51
  "peerDependencies": {
52
- "react": "^18.2.0"
52
+ "react": "^18.0.0"
53
53
  },
54
54
  "devDependencies": {
55
55
  "@babel/core": "^7.21.4",
56
56
  "@babel/plugin-transform-runtime": "^7.21.4",
57
- "@babel/preset-env": "^7.21.4",
57
+ "@babel/preset-env": "^7.21.5",
58
58
  "@babel/preset-react": "^7.18.6",
59
59
  "@babel/preset-typescript": "^7.21.4",
60
- "@rollup/plugin-commonjs": "^24.0.1",
60
+ "@rollup/plugin-commonjs": "^25.0.0",
61
61
  "@rollup/plugin-json": "^6.0.0",
62
62
  "@rollup/plugin-node-resolve": "^15.0.2",
63
63
  "@rollup/plugin-replace": "^5.0.2",
64
64
  "@rollup/plugin-run": "^3.0.1",
65
65
  "@rollup/plugin-terser": "^0.4.0",
66
- "@rollup/plugin-typescript": "^11.1.0",
66
+ "@rollup/plugin-typescript": "^11.1.1",
67
67
  "@testing-library/react": "^14.0.0",
68
- "@types/jest": "^29.5.0",
69
- "@types/node": "^18.15.11",
70
- "@types/react": "^18.0.33",
71
- "@types/react-dom": "^18.0.11",
68
+ "@types/jest": "^29.5.1",
69
+ "@types/node": "^20.2.3",
70
+ "@types/react": "^18.2.8",
71
+ "@types/react-dom": "^18.2.4",
72
72
  "babel-jest": "^29.5.0",
73
73
  "babel-loader": "^9.1.2",
74
74
  "builtin-modules": "^3.3.0",
75
75
  "delay": "^5.0.0",
76
- "eslint": "^8.37.0",
76
+ "eslint": "^8.39.0",
77
77
  "eslint-config-tasoskakour-typescript-prettier": "^2.1.0",
78
- "fastify": "^4.15.0",
78
+ "fastify": "^4.17.0",
79
79
  "husky": "^8.0.3",
80
- "jest": "^29.5.0",
81
- "jest-environment-jsdom": "^29.5.0",
80
+ "jest": "^29.7.0",
81
+ "jest-environment-jsdom": "^29.7.0",
82
82
  "jest-fetch-mock": "^3.0.3",
83
- "jest-puppeteer": "^8.0.6",
84
- "lint-staged": "^13.2.0",
85
- "puppeteer": "^19.8.3",
83
+ "jest-puppeteer": "^9.0.0",
84
+ "lint-staged": "^13.2.2",
85
+ "puppeteer": "21.0.0",
86
86
  "react-dom": "^18.2.0",
87
- "react-router-dom": "^6.10.0",
88
- "rollup": "^3.20.2",
87
+ "react-router-dom": "^6.11.2",
88
+ "rollup": "^3.20.7",
89
89
  "rollup-plugin-delete": "^2.0.0",
90
90
  "rollup-plugin-dts": "^5.3.0",
91
91
  "rollup-plugin-livereload": "^2.0.5",
92
92
  "rollup-plugin-peer-deps-external": "^2.2.4",
93
93
  "rollup-plugin-serve": "^2.0.2",
94
94
  "start-server-and-test": "^2.0.0",
95
- "ts-jest": "^29.1.0",
95
+ "ts-jest": "^29.1.1",
96
+ "ts-jest-resolver": "^2.0.1",
96
97
  "ts-node": "^10.9.1",
97
98
  "typescript": "^5.0.3"
98
99
  },
99
100
  "engines": {
100
- "node": ">=14"
101
+ "node": ">=16"
101
102
  },
102
103
  "files": [
103
104
  "dist"