@descope/react-sdk 3.2.1 → 3.3.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/README.md +122 -2
- package/dist/cjs/components/Descope.js +1 -1
- package/dist/cjs/components/Descope.js.map +1 -1
- package/dist/cjs/constants.js +1 -1
- package/dist/esm/components/Descope.js +1 -1
- package/dist/esm/components/Descope.js.map +1 -1
- package/dist/esm/constants.js +1 -1
- package/dist/index.umd.js +2 -2
- package/dist/index.umd.js.map +1 -1
- package/package.json +34 -22
package/README.md
CHANGED
|
@@ -5,6 +5,7 @@ The Descope SDK for React provides convenient access to the Descope for an appli
|
|
|
5
5
|
## Requirements
|
|
6
6
|
|
|
7
7
|
- The SDK supports React version 16 and above.
|
|
8
|
+
- The SDK also runs on [Preact](#preact-support) 10.11+ via `preact/compat`.
|
|
8
9
|
- A Descope `Project ID` is required for using the SDK. Find it on the [project page in the Descope Console](https://app.descope.com/settings/project).
|
|
9
10
|
|
|
10
11
|
## Installing the SDK
|
|
@@ -410,7 +411,7 @@ function Layout() {
|
|
|
410
411
|
|
|
411
412
|
<AuthProvider projectId="my-project-id" autoRefresh={{ customActivityTracking: true }}>
|
|
412
413
|
<Layout />
|
|
413
|
-
</AuthProvider
|
|
414
|
+
</AuthProvider>;
|
|
414
415
|
```
|
|
415
416
|
|
|
416
417
|
**For more SDK usage examples refer to [docs](https://docs.descope.com/build/guides/client_sdks/)**
|
|
@@ -808,7 +809,9 @@ Example:
|
|
|
808
809
|
|
|
809
810
|
## Code Example
|
|
810
811
|
|
|
811
|
-
You can find an example react app in the [examples folder](./examples)
|
|
812
|
+
You can find an example react app in the [examples folder](./examples), and a
|
|
813
|
+
Preact one in [examples/preact-app](./examples/preact-app) (see
|
|
814
|
+
[Preact Support](#preact-support)).
|
|
812
815
|
|
|
813
816
|
### Setup
|
|
814
817
|
|
|
@@ -853,6 +856,123 @@ See the following table for customization environment variables for the example
|
|
|
853
856
|
| DESCOPE_OIDC_ENABLED | **"true"** - Use OIDC login | None |
|
|
854
857
|
| DESCOPE_OIDC_APPLICATION_ID | Descope OIDC Application ID, In case OIDC login is used | None |
|
|
855
858
|
|
|
859
|
+
## Preact Support
|
|
860
|
+
|
|
861
|
+
The SDK runs unmodified on Preact 10.11+ through `preact/compat` - the same
|
|
862
|
+
package, the same API, no Preact-specific entry point. Its test suite is
|
|
863
|
+
executed twice in CI: once against React and once with `react` aliased to
|
|
864
|
+
`preact/compat` (`npm run test:preact`), so hooks, `<Descope />`, and the
|
|
865
|
+
widgets are covered under both.
|
|
866
|
+
|
|
867
|
+
### Setup
|
|
868
|
+
|
|
869
|
+
Alias `react` and `react-dom` to `preact/compat` in your bundler. Most Preact
|
|
870
|
+
setups already do this:
|
|
871
|
+
|
|
872
|
+
```js
|
|
873
|
+
// vite.config.js
|
|
874
|
+
import { defineConfig } from 'vite';
|
|
875
|
+
import preact from '@preact/preset-vite';
|
|
876
|
+
|
|
877
|
+
export default defineConfig({
|
|
878
|
+
plugins: [preact()], // aliases react/react-dom -> preact/compat
|
|
879
|
+
});
|
|
880
|
+
```
|
|
881
|
+
|
|
882
|
+
```js
|
|
883
|
+
// webpack.config.js
|
|
884
|
+
module.exports = {
|
|
885
|
+
resolve: {
|
|
886
|
+
alias: {
|
|
887
|
+
react: 'preact/compat',
|
|
888
|
+
'react-dom': 'preact/compat',
|
|
889
|
+
'react-dom/test-utils': 'preact/compat/test-utils',
|
|
890
|
+
'react/jsx-runtime': 'preact/compat/jsx-runtime',
|
|
891
|
+
},
|
|
892
|
+
},
|
|
893
|
+
};
|
|
894
|
+
```
|
|
895
|
+
|
|
896
|
+
The SDK declares `react` as a peer dependency. Point it at `preact/compat` so
|
|
897
|
+
installs stay quiet without pulling React in:
|
|
898
|
+
|
|
899
|
+
```json
|
|
900
|
+
{
|
|
901
|
+
"dependencies": {
|
|
902
|
+
"react": "npm:@preact/compat",
|
|
903
|
+
"react-dom": "npm:@preact/compat"
|
|
904
|
+
}
|
|
905
|
+
}
|
|
906
|
+
```
|
|
907
|
+
|
|
908
|
+
For TypeScript, map the types as well - the SDK's declarations reference
|
|
909
|
+
`React.FC`, `React.Ref` and `DOMAttributes`:
|
|
910
|
+
|
|
911
|
+
```json
|
|
912
|
+
{
|
|
913
|
+
"compilerOptions": {
|
|
914
|
+
"paths": {
|
|
915
|
+
"react": ["./node_modules/preact/compat/"],
|
|
916
|
+
"react-dom": ["./node_modules/preact/compat/"]
|
|
917
|
+
}
|
|
918
|
+
}
|
|
919
|
+
}
|
|
920
|
+
```
|
|
921
|
+
|
|
922
|
+
Then use the SDK exactly as documented above:
|
|
923
|
+
|
|
924
|
+
```jsx
|
|
925
|
+
import { render } from 'preact';
|
|
926
|
+
import { AuthProvider, Descope, useSession } from '@descope/react-sdk';
|
|
927
|
+
|
|
928
|
+
render(
|
|
929
|
+
<AuthProvider projectId="my-project-id">
|
|
930
|
+
<App />
|
|
931
|
+
</AuthProvider>,
|
|
932
|
+
document.getElementById('root'),
|
|
933
|
+
);
|
|
934
|
+
```
|
|
935
|
+
|
|
936
|
+
A complete working app is in [examples/preact-app](./examples/preact-app) -
|
|
937
|
+
run it with `npm run start:preact`.
|
|
938
|
+
|
|
939
|
+
### Behavioural differences to be aware of
|
|
940
|
+
|
|
941
|
+
Two things differ from React. Neither blocks any SDK feature, but both can
|
|
942
|
+
surface in tests or on the server:
|
|
943
|
+
|
|
944
|
+
1. **Effects run after paint.** Preact schedules `useEffect` on the next
|
|
945
|
+
frame, while React flushes it before the browser paints. `<Descope />`
|
|
946
|
+
attaches its `success` / `error` / `ready` listeners from an effect, so an
|
|
947
|
+
event dispatched in the same tick as mount can be missed. Real flows emit
|
|
948
|
+
these events long after mount, so this only tends to matter in tests - wait
|
|
949
|
+
for the listener rather than assuming it is attached:
|
|
950
|
+
|
|
951
|
+
```js
|
|
952
|
+
await waitFor(() => {
|
|
953
|
+
fireEvent(container.querySelector('descope-wc'), new CustomEvent('error'));
|
|
954
|
+
expect(document.querySelector('.error')).not.toBeNull();
|
|
955
|
+
});
|
|
956
|
+
```
|
|
957
|
+
|
|
958
|
+
2. **SSR needs the async renderer.** `<Descope />` and the widgets lazy-load
|
|
959
|
+
their web component, so the first server render suspends.
|
|
960
|
+
`preact-render-to-string`'s synchronous `renderToString` throws on a
|
|
961
|
+
suspended subtree instead of emitting the `<Suspense>` fallback - use
|
|
962
|
+
`renderToStringAsync` (v6+):
|
|
963
|
+
|
|
964
|
+
```js
|
|
965
|
+
import { renderToStringAsync } from 'preact-render-to-string';
|
|
966
|
+
|
|
967
|
+
const html = await renderToStringAsync(<App />);
|
|
968
|
+
```
|
|
969
|
+
|
|
970
|
+
If you would rather not pull in a compat layer at all,
|
|
971
|
+
[`@descope/web-component`](https://www.npmjs.com/package/@descope/web-component)
|
|
972
|
+
is a framework-agnostic custom element - but it does not provide the
|
|
973
|
+
`useSession` / `useUser` / `useDescope` hooks or the `AuthProvider` session
|
|
974
|
+
management this SDK adds.
|
|
975
|
+
|
|
856
976
|
## Performance / Bundle Size
|
|
857
977
|
|
|
858
978
|
To improve modularity and reduce bundle size, all flow-related utilities are available also under `@descope/react-sdk/flows` subpath. Example:
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("tslib"),t=require("react"),r=require("../constants.js"),s=require("../hooks/Context.js"),n=require("../sdk.js"),o=require("./withPropsMapping/index.js");function a(e){return e&&e.__esModule?e:{default:e}}var u=a(t);const l=t.lazy((async()=>((
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("tslib"),t=require("react"),r=require("../constants.js"),s=require("../hooks/Context.js"),n=require("../sdk.js"),o=require("./withPropsMapping/index.js");function a(e){return e&&e.__esModule?e:{default:e}}var u=a(t);const l=t.lazy((async()=>{var s;return((null===(s=globalThis.customElements)||void 0===s?void 0:s.get("descope-wc"))||await import("@descope/web-component").then((e=>e.default))).sdkConfigOverrides={baseHeaders:r.baseHeaders,persistTokens:!1,hooks:{get beforeRequest(){return n.getGlobalSdk().httpClient.hooks.beforeRequest},set beforeRequest(e){}}},{default:o.default(u.default.forwardRef(((s,n)=>{var{"external-request-id":o}=s,a=e.__rest(s,["external-request-id"]);return t.useMemo((()=>{var e,t;e="x-external-rid",(t=o)?r.baseHeaders[e]=t:delete r.baseHeaders[e]}),[o]),u.default.createElement("descope-wc",Object.assign({ref:n},a))})))}})),d=u.default.forwardRef((({flowId:e,onSuccess:r,onError:n,onReady:o,logger:a,tenant:d,theme:i,nonce:c,locale:p,debug:f,client:m,form:v,telemetryKey:b,redirectUrl:E,autoFocus:g,validateOnBlur:h,restartOnError:k,sendSessionToken:L,errorTransformer:y,styleId:S,onScreenUpdate:q,dismissScreenErrorOnInput:U,outboundAppId:O,outboundAppScopes:w,popupOrigin:x,children:I,externalRequestId:C,themeOverride:R},j)=>{const[A,_]=t.useState(null);t.useImperativeHandle(j,(()=>A));const{projectId:H,baseUrl:T,baseStaticUrl:M,baseCdnUrl:N,storeLastAuthenticatedUser:B,keepLastAuthenticatedUserAfterLogout:F,refreshCookieName:K,customStorage:P,sdk:z}=u.default.useContext(s.default),G=t.useCallback((async e=>{await z.httpClient.hooks.afterRequest({},new Response(JSON.stringify(e.detail))),r&&r(e)}),[r]);return t.useEffect((()=>{const e=A;return null==e||e.addEventListener("success",G),n&&(null==e||e.addEventListener("error",n)),o&&(null==e||e.addEventListener("ready",o)),()=>{n&&(null==e||e.removeEventListener("error",n)),o&&(null==e||e.removeEventListener("ready",o)),null==e||e.removeEventListener("success",G)}}),[A,n,G]),t.useEffect((()=>{const e=A;return null==e||e.addEventListener("success",G),()=>{null==e||e.removeEventListener("success",G)}}),[A,G]),t.useEffect((()=>{const e=A;return n&&(null==e||e.addEventListener("error",n)),()=>{n&&(null==e||e.removeEventListener("error",n))}}),[A,n]),t.useEffect((()=>{const e=A;return o&&(null==e||e.addEventListener("ready",o)),()=>{o&&(null==e||e.removeEventListener("error",o))}}),[A,o]),u.default.createElement("form",null,u.default.createElement(t.Suspense,{fallback:null},u.default.createElement(l,{projectId:H,flowId:e,baseUrl:T,baseStaticUrl:M,baseCdnUrl:N,ref:_,telemetryKey:b,redirectUrl:E,autoFocus:g,styleId:S,validateOnBlur:h,restartOnError:k,keepLastAuthenticatedUserAfterLogout:F,tenant:d,externalRequestId:C,customStorage:P,themeOverride:R,"theme.attr":i,"nonce.attr":c,"locale.attr":p,"form.attr":v,"client.attr":m,"debug.attr":f,"outbound-app-id.attr":O,"outbound-app-scopes.attr":w,"popup-origin.attr":x,"store-last-authenticated-user.attr":B,"send-session-token.attr":L,"refreshCookieName.attr":K,"dismiss-screen-error-on-input.attr":U,"errorTransformer.prop":y,"logger.prop":a,"onScreenUpdate.prop":q,"customStorage.prop":P},I)))}));exports.default=d;
|
|
2
2
|
//# sourceMappingURL=Descope.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Descope.js","sources":["../../../src/components/Descope.tsx"],"sourcesContent":["/* eslint-disable react/prop-types */\nimport React, {\n lazy,\n Suspense,\n useCallback,\n useEffect,\n useImperativeHandle,\n useMemo,\n useState,\n} from 'react';\nimport { baseHeaders } from '../constants';\nimport Context from '../hooks/Context';\nimport { DescopeProps } from '../types';\nimport { getGlobalSdk } from '../sdk';\nimport withPropsMapping from './withPropsMapping';\n\n// web-component code uses browser API, but can be used in SSR apps, hence the lazy loading\nconst DescopeWC = lazy(async () => {\n const updateDynamicHeader = (key: string, value: string) => {\n if (value) {\n baseHeaders[key] = value;\n } else {\n delete baseHeaders[key];\n }\n };\n\n const WebComponent: any =\n customElements?.get('descope-wc') ||\n (await import('@descope/web-component').then((module) => module.default));\n\n WebComponent.sdkConfigOverrides = {\n // Overrides the web-component's base headers to indicate usage via the React SDK\n baseHeaders,\n // Disables token persistence within the web-component to delegate token management\n // to the global SDK hooks. This ensures token handling aligns with the SDK's configuration,\n // and web-component requests leverage the global SDK's beforeRequest hooks for consistency\n persistTokens: false,\n hooks: {\n get beforeRequest() {\n // Retrieves the beforeRequest hook from the global SDK, which is initialized\n // within the AuthProvider using the desired configuration. This approach ensures\n // the web-component utilizes the same beforeRequest hooks as the global SDK\n return getGlobalSdk().httpClient.hooks.beforeRequest;\n },\n set beforeRequest(_) {\n // The empty setter prevents runtime errors when attempts are made to assign a value to 'beforeRequest'.\n // JavaScript objects default to having both getters and setters\n },\n },\n };\n\n return {\n default: withPropsMapping(\n React.forwardRef<HTMLElement>(\n ({ 'external-request-id': externalRequestId, ...props }: any, ref) => {\n // update the dynamic headers with the external request ID if provided\n useMemo(() => {\n updateDynamicHeader('x-external-rid', externalRequestId);\n }, [externalRequestId]);\n\n return <descope-wc ref={ref} {...props} />;\n },\n ),\n ),\n };\n});\n\nconst Descope = React.forwardRef<HTMLElement, DescopeProps>(\n (\n {\n flowId,\n onSuccess,\n onError,\n onReady,\n logger,\n tenant,\n theme,\n nonce,\n locale,\n debug,\n client,\n form,\n telemetryKey,\n redirectUrl,\n autoFocus,\n validateOnBlur,\n restartOnError,\n sendSessionToken,\n errorTransformer,\n styleId,\n onScreenUpdate,\n dismissScreenErrorOnInput,\n outboundAppId,\n outboundAppScopes,\n popupOrigin,\n children,\n externalRequestId,\n themeOverride,\n },\n ref,\n ) => {\n const [innerRef, setInnerRef] = useState(null);\n\n useImperativeHandle(ref, () => innerRef);\n\n const {\n projectId,\n baseUrl,\n baseStaticUrl,\n baseCdnUrl,\n storeLastAuthenticatedUser,\n keepLastAuthenticatedUserAfterLogout,\n refreshCookieName,\n customStorage,\n sdk,\n } = React.useContext(Context);\n\n const handleSuccess = useCallback(\n async (e: CustomEvent) => {\n // In order to make sure all the after-hooks are running with the success response\n // we are generating a fake response with the success data and calling the http client after hook fn with it\n await sdk.httpClient.hooks.afterRequest(\n {} as any,\n new Response(JSON.stringify(e.detail)),\n );\n if (onSuccess) {\n onSuccess(e);\n }\n },\n [onSuccess],\n );\n\n useEffect(() => {\n const ele = innerRef;\n ele?.addEventListener('success', handleSuccess);\n if (onError) ele?.addEventListener('error', onError);\n if (onReady) ele?.addEventListener('ready', onReady);\n\n return () => {\n if (onError) ele?.removeEventListener('error', onError);\n if (onReady) ele?.removeEventListener('ready', onReady);\n\n ele?.removeEventListener('success', handleSuccess);\n };\n }, [innerRef, onError, handleSuccess]);\n\n // Success event\n useEffect(() => {\n const ele = innerRef;\n ele?.addEventListener('success', handleSuccess);\n return () => {\n ele?.removeEventListener('success', handleSuccess);\n };\n }, [innerRef, handleSuccess]);\n\n // Error event\n useEffect(() => {\n const ele = innerRef;\n if (onError) ele?.addEventListener('error', onError);\n\n return () => {\n if (onError) ele?.removeEventListener('error', onError);\n };\n }, [innerRef, onError]);\n\n // Ready event\n useEffect(() => {\n const ele = innerRef;\n if (onReady) ele?.addEventListener('ready', onReady);\n\n return () => {\n if (onReady) ele?.removeEventListener('error', onReady);\n };\n }, [innerRef, onReady]);\n\n return (\n /**\n * in order to avoid redundant remounting of the WC, we are wrapping it with a form element\n * this workaround is done in order to support webauthn passkeys\n * it can be removed once this issue will be solved\n * https://bugs.chromium.org/p/chromium/issues/detail?id=1404106#c2\n */\n\t<form>\n\t\t<Suspense fallback={null}>\n\t\t\t<DescopeWC\n projectId={projectId}\n flowId={flowId}\n baseUrl={baseUrl}\n baseStaticUrl={baseStaticUrl}\n baseCdnUrl={baseCdnUrl}\n ref={setInnerRef}\n telemetryKey={telemetryKey}\n redirectUrl={redirectUrl}\n autoFocus={autoFocus}\n styleId={styleId}\n validateOnBlur={validateOnBlur}\n restartOnError={restartOnError}\n keepLastAuthenticatedUserAfterLogout={\n keepLastAuthenticatedUserAfterLogout\n }\n tenant={tenant}\n externalRequestId={externalRequestId}\n customStorage={customStorage}\n themeOverride={themeOverride}\n {...{\n // attributes\n 'theme.attr': theme,\n 'nonce.attr': nonce,\n 'locale.attr': locale,\n 'form.attr': form,\n 'client.attr': client,\n 'debug.attr': debug,\n 'outbound-app-id.attr': outboundAppId,\n 'outbound-app-scopes.attr': outboundAppScopes,\n 'popup-origin.attr': popupOrigin,\n 'store-last-authenticated-user.attr': storeLastAuthenticatedUser,\n 'send-session-token.attr': sendSessionToken,\n 'refreshCookieName.attr': refreshCookieName,\n 'dismiss-screen-error-on-input.attr': dismissScreenErrorOnInput,\n // props\n 'errorTransformer.prop': errorTransformer,\n 'logger.prop': logger,\n 'onScreenUpdate.prop': onScreenUpdate,\n 'customStorage.prop': customStorage,\n }}\n >\n\t\t\t\t{children}\n\t\t\t</DescopeWC>\n\t\t</Suspense>\n\t</form>\n );\n },\n);\n\nexport default Descope;\n"],"names":["DescopeWC","lazy","async","customElements","get","import","then","module","default","sdkConfigOverrides","baseHeaders","persistTokens","hooks","beforeRequest","getGlobalSdk","httpClient","_","withPropsMapping","React","forwardRef","_a","ref","externalRequestId","props","__rest","useMemo","key","value","Descope","flowId","onSuccess","onError","onReady","logger","tenant","theme","nonce","locale","debug","client","form","telemetryKey","redirectUrl","autoFocus","validateOnBlur","restartOnError","sendSessionToken","errorTransformer","styleId","onScreenUpdate","dismissScreenErrorOnInput","outboundAppId","outboundAppScopes","popupOrigin","children","themeOverride","innerRef","setInnerRef","useState","useImperativeHandle","projectId","baseUrl","baseStaticUrl","baseCdnUrl","storeLastAuthenticatedUser","keepLastAuthenticatedUserAfterLogout","refreshCookieName","customStorage","sdk","useContext","Context","handleSuccess","useCallback","e","afterRequest","Response","JSON","stringify","detail","useEffect","ele","addEventListener","removeEventListener","createElement","Suspense","fallback"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Descope.js","sources":["../../../src/components/Descope.tsx"],"sourcesContent":["/* eslint-disable react/prop-types */\nimport React, {\n lazy,\n Suspense,\n useCallback,\n useEffect,\n useImperativeHandle,\n useMemo,\n useState,\n} from 'react';\nimport { baseHeaders } from '../constants';\nimport Context from '../hooks/Context';\nimport { DescopeProps } from '../types';\nimport { getGlobalSdk } from '../sdk';\nimport withPropsMapping from './withPropsMapping';\n\n// web-component code uses browser API, but can be used in SSR apps, hence the lazy loading\nconst DescopeWC = lazy(async () => {\n const updateDynamicHeader = (key: string, value: string) => {\n if (value) {\n baseHeaders[key] = value;\n } else {\n delete baseHeaders[key];\n }\n };\n\n const WebComponent: any =\n // `customElements` is undeclared (not just undefined) on the server, so it\n // has to be reached through `globalThis` - `customElements?.` alone throws\n // a ReferenceError and defeats the lazy loading above.\n globalThis.customElements?.get('descope-wc') ||\n (await import('@descope/web-component').then((module) => module.default));\n\n WebComponent.sdkConfigOverrides = {\n // Overrides the web-component's base headers to indicate usage via the React SDK\n baseHeaders,\n // Disables token persistence within the web-component to delegate token management\n // to the global SDK hooks. This ensures token handling aligns with the SDK's configuration,\n // and web-component requests leverage the global SDK's beforeRequest hooks for consistency\n persistTokens: false,\n hooks: {\n get beforeRequest() {\n // Retrieves the beforeRequest hook from the global SDK, which is initialized\n // within the AuthProvider using the desired configuration. This approach ensures\n // the web-component utilizes the same beforeRequest hooks as the global SDK\n return getGlobalSdk().httpClient.hooks.beforeRequest;\n },\n set beforeRequest(_) {\n // The empty setter prevents runtime errors when attempts are made to assign a value to 'beforeRequest'.\n // JavaScript objects default to having both getters and setters\n },\n },\n };\n\n return {\n default: withPropsMapping(\n React.forwardRef<HTMLElement>(\n ({ 'external-request-id': externalRequestId, ...props }: any, ref) => {\n // update the dynamic headers with the external request ID if provided\n useMemo(() => {\n updateDynamicHeader('x-external-rid', externalRequestId);\n }, [externalRequestId]);\n\n return <descope-wc ref={ref} {...props} />;\n },\n ),\n ),\n };\n});\n\nconst Descope = React.forwardRef<HTMLElement, DescopeProps>(\n (\n {\n flowId,\n onSuccess,\n onError,\n onReady,\n logger,\n tenant,\n theme,\n nonce,\n locale,\n debug,\n client,\n form,\n telemetryKey,\n redirectUrl,\n autoFocus,\n validateOnBlur,\n restartOnError,\n sendSessionToken,\n errorTransformer,\n styleId,\n onScreenUpdate,\n dismissScreenErrorOnInput,\n outboundAppId,\n outboundAppScopes,\n popupOrigin,\n children,\n externalRequestId,\n themeOverride,\n },\n ref,\n ) => {\n const [innerRef, setInnerRef] = useState(null);\n\n useImperativeHandle(ref, () => innerRef);\n\n const {\n projectId,\n baseUrl,\n baseStaticUrl,\n baseCdnUrl,\n storeLastAuthenticatedUser,\n keepLastAuthenticatedUserAfterLogout,\n refreshCookieName,\n customStorage,\n sdk,\n } = React.useContext(Context);\n\n const handleSuccess = useCallback(\n async (e: CustomEvent) => {\n // In order to make sure all the after-hooks are running with the success response\n // we are generating a fake response with the success data and calling the http client after hook fn with it\n await sdk.httpClient.hooks.afterRequest(\n {} as any,\n new Response(JSON.stringify(e.detail)),\n );\n if (onSuccess) {\n onSuccess(e);\n }\n },\n [onSuccess],\n );\n\n useEffect(() => {\n const ele = innerRef;\n ele?.addEventListener('success', handleSuccess);\n if (onError) ele?.addEventListener('error', onError);\n if (onReady) ele?.addEventListener('ready', onReady);\n\n return () => {\n if (onError) ele?.removeEventListener('error', onError);\n if (onReady) ele?.removeEventListener('ready', onReady);\n\n ele?.removeEventListener('success', handleSuccess);\n };\n }, [innerRef, onError, handleSuccess]);\n\n // Success event\n useEffect(() => {\n const ele = innerRef;\n ele?.addEventListener('success', handleSuccess);\n return () => {\n ele?.removeEventListener('success', handleSuccess);\n };\n }, [innerRef, handleSuccess]);\n\n // Error event\n useEffect(() => {\n const ele = innerRef;\n if (onError) ele?.addEventListener('error', onError);\n\n return () => {\n if (onError) ele?.removeEventListener('error', onError);\n };\n }, [innerRef, onError]);\n\n // Ready event\n useEffect(() => {\n const ele = innerRef;\n if (onReady) ele?.addEventListener('ready', onReady);\n\n return () => {\n if (onReady) ele?.removeEventListener('error', onReady);\n };\n }, [innerRef, onReady]);\n\n return (\n /**\n * in order to avoid redundant remounting of the WC, we are wrapping it with a form element\n * this workaround is done in order to support webauthn passkeys\n * it can be removed once this issue will be solved\n * https://bugs.chromium.org/p/chromium/issues/detail?id=1404106#c2\n */\n\t<form>\n\t\t<Suspense fallback={null}>\n\t\t\t<DescopeWC\n projectId={projectId}\n flowId={flowId}\n baseUrl={baseUrl}\n baseStaticUrl={baseStaticUrl}\n baseCdnUrl={baseCdnUrl}\n ref={setInnerRef}\n telemetryKey={telemetryKey}\n redirectUrl={redirectUrl}\n autoFocus={autoFocus}\n styleId={styleId}\n validateOnBlur={validateOnBlur}\n restartOnError={restartOnError}\n keepLastAuthenticatedUserAfterLogout={\n keepLastAuthenticatedUserAfterLogout\n }\n tenant={tenant}\n externalRequestId={externalRequestId}\n customStorage={customStorage}\n themeOverride={themeOverride}\n {...{\n // attributes\n 'theme.attr': theme,\n 'nonce.attr': nonce,\n 'locale.attr': locale,\n 'form.attr': form,\n 'client.attr': client,\n 'debug.attr': debug,\n 'outbound-app-id.attr': outboundAppId,\n 'outbound-app-scopes.attr': outboundAppScopes,\n 'popup-origin.attr': popupOrigin,\n 'store-last-authenticated-user.attr': storeLastAuthenticatedUser,\n 'send-session-token.attr': sendSessionToken,\n 'refreshCookieName.attr': refreshCookieName,\n 'dismiss-screen-error-on-input.attr': dismissScreenErrorOnInput,\n // props\n 'errorTransformer.prop': errorTransformer,\n 'logger.prop': logger,\n 'onScreenUpdate.prop': onScreenUpdate,\n 'customStorage.prop': customStorage,\n }}\n >\n\t\t\t\t{children}\n\t\t\t</DescopeWC>\n\t\t</Suspense>\n\t</form>\n );\n },\n);\n\nexport default Descope;\n"],"names":["DescopeWC","lazy","async","_a","globalThis","customElements","get","import","then","module","default","sdkConfigOverrides","baseHeaders","persistTokens","hooks","beforeRequest","getGlobalSdk","httpClient","_","withPropsMapping","React","forwardRef","ref","externalRequestId","props","__rest","useMemo","key","value","Descope","flowId","onSuccess","onError","onReady","logger","tenant","theme","nonce","locale","debug","client","form","telemetryKey","redirectUrl","autoFocus","validateOnBlur","restartOnError","sendSessionToken","errorTransformer","styleId","onScreenUpdate","dismissScreenErrorOnInput","outboundAppId","outboundAppScopes","popupOrigin","children","themeOverride","innerRef","setInnerRef","useState","useImperativeHandle","projectId","baseUrl","baseStaticUrl","baseCdnUrl","storeLastAuthenticatedUser","keepLastAuthenticatedUserAfterLogout","refreshCookieName","customStorage","sdk","useContext","Context","handleSuccess","useCallback","e","afterRequest","Response","JSON","stringify","detail","useEffect","ele","addEventListener","removeEventListener","createElement","Suspense","fallback"],"mappings":"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"}
|
package/dist/cjs/constants.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";const e="undefined"!=typeof window;exports.IS_BROWSER=e,exports.baseHeaders={"x-descope-sdk-name":"react","x-descope-sdk-version":"3.
|
|
1
|
+
"use strict";const e="undefined"!=typeof window;exports.IS_BROWSER=e,exports.baseHeaders={"x-descope-sdk-name":"react","x-descope-sdk-version":"3.3.1"};
|
|
2
2
|
//# sourceMappingURL=constants.js.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{__rest as e}from"tslib";import t,{lazy as r,useMemo as n,useState as o,useImperativeHandle as s,useCallback as a,useEffect as l,Suspense as
|
|
1
|
+
import{__rest as e}from"tslib";import t,{lazy as r,useMemo as n,useState as o,useImperativeHandle as s,useCallback as a,useEffect as l,Suspense as d}from"react";import{baseHeaders as u}from"../constants.js";import i from"../hooks/Context.js";import{getGlobalSdk as c}from"../sdk.js";import p from"./withPropsMapping/index.js";const m=r((async()=>{var r;return((null===(r=globalThis.customElements)||void 0===r?void 0:r.get("descope-wc"))||await import("@descope/web-component").then((e=>e.default))).sdkConfigOverrides={baseHeaders:u,persistTokens:!1,hooks:{get beforeRequest(){return c().httpClient.hooks.beforeRequest},set beforeRequest(e){}}},{default:p(t.forwardRef(((r,o)=>{var{"external-request-id":s}=r,a=e(r,["external-request-id"]);return n((()=>{var e,t;e="x-external-rid",(t=s)?u[e]=t:delete u[e]}),[s]),t.createElement("descope-wc",Object.assign({ref:o},a))})))}})),f=t.forwardRef((({flowId:e,onSuccess:r,onError:n,onReady:u,logger:c,tenant:p,theme:f,nonce:v,locale:b,debug:E,client:g,form:h,telemetryKey:L,redirectUrl:k,autoFocus:y,validateOnBlur:U,restartOnError:S,sendSessionToken:w,errorTransformer:O,styleId:x,onScreenUpdate:I,dismissScreenErrorOnInput:R,outboundAppId:C,outboundAppScopes:q,popupOrigin:j,children:A,externalRequestId:T,themeOverride:N},B)=>{const[F,K]=o(null);s(B,(()=>F));const{projectId:H,baseUrl:J,baseStaticUrl:M,baseCdnUrl:P,storeLastAuthenticatedUser:z,keepLastAuthenticatedUserAfterLogout:D,refreshCookieName:G,customStorage:Q,sdk:V}=t.useContext(i),W=a((async e=>{await V.httpClient.hooks.afterRequest({},new Response(JSON.stringify(e.detail))),r&&r(e)}),[r]);return l((()=>{const e=F;return null==e||e.addEventListener("success",W),n&&(null==e||e.addEventListener("error",n)),u&&(null==e||e.addEventListener("ready",u)),()=>{n&&(null==e||e.removeEventListener("error",n)),u&&(null==e||e.removeEventListener("ready",u)),null==e||e.removeEventListener("success",W)}}),[F,n,W]),l((()=>{const e=F;return null==e||e.addEventListener("success",W),()=>{null==e||e.removeEventListener("success",W)}}),[F,W]),l((()=>{const e=F;return n&&(null==e||e.addEventListener("error",n)),()=>{n&&(null==e||e.removeEventListener("error",n))}}),[F,n]),l((()=>{const e=F;return u&&(null==e||e.addEventListener("ready",u)),()=>{u&&(null==e||e.removeEventListener("error",u))}}),[F,u]),t.createElement("form",null,t.createElement(d,{fallback:null},t.createElement(m,{projectId:H,flowId:e,baseUrl:J,baseStaticUrl:M,baseCdnUrl:P,ref:K,telemetryKey:L,redirectUrl:k,autoFocus:y,styleId:x,validateOnBlur:U,restartOnError:S,keepLastAuthenticatedUserAfterLogout:D,tenant:p,externalRequestId:T,customStorage:Q,themeOverride:N,"theme.attr":f,"nonce.attr":v,"locale.attr":b,"form.attr":h,"client.attr":g,"debug.attr":E,"outbound-app-id.attr":C,"outbound-app-scopes.attr":q,"popup-origin.attr":j,"store-last-authenticated-user.attr":z,"send-session-token.attr":w,"refreshCookieName.attr":G,"dismiss-screen-error-on-input.attr":R,"errorTransformer.prop":O,"logger.prop":c,"onScreenUpdate.prop":I,"customStorage.prop":Q},A)))}));export{f as default};
|
|
2
2
|
//# sourceMappingURL=Descope.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Descope.js","sources":["../../../src/components/Descope.tsx"],"sourcesContent":["/* eslint-disable react/prop-types */\nimport React, {\n lazy,\n Suspense,\n useCallback,\n useEffect,\n useImperativeHandle,\n useMemo,\n useState,\n} from 'react';\nimport { baseHeaders } from '../constants';\nimport Context from '../hooks/Context';\nimport { DescopeProps } from '../types';\nimport { getGlobalSdk } from '../sdk';\nimport withPropsMapping from './withPropsMapping';\n\n// web-component code uses browser API, but can be used in SSR apps, hence the lazy loading\nconst DescopeWC = lazy(async () => {\n const updateDynamicHeader = (key: string, value: string) => {\n if (value) {\n baseHeaders[key] = value;\n } else {\n delete baseHeaders[key];\n }\n };\n\n const WebComponent: any =\n customElements?.get('descope-wc') ||\n (await import('@descope/web-component').then((module) => module.default));\n\n WebComponent.sdkConfigOverrides = {\n // Overrides the web-component's base headers to indicate usage via the React SDK\n baseHeaders,\n // Disables token persistence within the web-component to delegate token management\n // to the global SDK hooks. This ensures token handling aligns with the SDK's configuration,\n // and web-component requests leverage the global SDK's beforeRequest hooks for consistency\n persistTokens: false,\n hooks: {\n get beforeRequest() {\n // Retrieves the beforeRequest hook from the global SDK, which is initialized\n // within the AuthProvider using the desired configuration. This approach ensures\n // the web-component utilizes the same beforeRequest hooks as the global SDK\n return getGlobalSdk().httpClient.hooks.beforeRequest;\n },\n set beforeRequest(_) {\n // The empty setter prevents runtime errors when attempts are made to assign a value to 'beforeRequest'.\n // JavaScript objects default to having both getters and setters\n },\n },\n };\n\n return {\n default: withPropsMapping(\n React.forwardRef<HTMLElement>(\n ({ 'external-request-id': externalRequestId, ...props }: any, ref) => {\n // update the dynamic headers with the external request ID if provided\n useMemo(() => {\n updateDynamicHeader('x-external-rid', externalRequestId);\n }, [externalRequestId]);\n\n return <descope-wc ref={ref} {...props} />;\n },\n ),\n ),\n };\n});\n\nconst Descope = React.forwardRef<HTMLElement, DescopeProps>(\n (\n {\n flowId,\n onSuccess,\n onError,\n onReady,\n logger,\n tenant,\n theme,\n nonce,\n locale,\n debug,\n client,\n form,\n telemetryKey,\n redirectUrl,\n autoFocus,\n validateOnBlur,\n restartOnError,\n sendSessionToken,\n errorTransformer,\n styleId,\n onScreenUpdate,\n dismissScreenErrorOnInput,\n outboundAppId,\n outboundAppScopes,\n popupOrigin,\n children,\n externalRequestId,\n themeOverride,\n },\n ref,\n ) => {\n const [innerRef, setInnerRef] = useState(null);\n\n useImperativeHandle(ref, () => innerRef);\n\n const {\n projectId,\n baseUrl,\n baseStaticUrl,\n baseCdnUrl,\n storeLastAuthenticatedUser,\n keepLastAuthenticatedUserAfterLogout,\n refreshCookieName,\n customStorage,\n sdk,\n } = React.useContext(Context);\n\n const handleSuccess = useCallback(\n async (e: CustomEvent) => {\n // In order to make sure all the after-hooks are running with the success response\n // we are generating a fake response with the success data and calling the http client after hook fn with it\n await sdk.httpClient.hooks.afterRequest(\n {} as any,\n new Response(JSON.stringify(e.detail)),\n );\n if (onSuccess) {\n onSuccess(e);\n }\n },\n [onSuccess],\n );\n\n useEffect(() => {\n const ele = innerRef;\n ele?.addEventListener('success', handleSuccess);\n if (onError) ele?.addEventListener('error', onError);\n if (onReady) ele?.addEventListener('ready', onReady);\n\n return () => {\n if (onError) ele?.removeEventListener('error', onError);\n if (onReady) ele?.removeEventListener('ready', onReady);\n\n ele?.removeEventListener('success', handleSuccess);\n };\n }, [innerRef, onError, handleSuccess]);\n\n // Success event\n useEffect(() => {\n const ele = innerRef;\n ele?.addEventListener('success', handleSuccess);\n return () => {\n ele?.removeEventListener('success', handleSuccess);\n };\n }, [innerRef, handleSuccess]);\n\n // Error event\n useEffect(() => {\n const ele = innerRef;\n if (onError) ele?.addEventListener('error', onError);\n\n return () => {\n if (onError) ele?.removeEventListener('error', onError);\n };\n }, [innerRef, onError]);\n\n // Ready event\n useEffect(() => {\n const ele = innerRef;\n if (onReady) ele?.addEventListener('ready', onReady);\n\n return () => {\n if (onReady) ele?.removeEventListener('error', onReady);\n };\n }, [innerRef, onReady]);\n\n return (\n /**\n * in order to avoid redundant remounting of the WC, we are wrapping it with a form element\n * this workaround is done in order to support webauthn passkeys\n * it can be removed once this issue will be solved\n * https://bugs.chromium.org/p/chromium/issues/detail?id=1404106#c2\n */\n\t<form>\n\t\t<Suspense fallback={null}>\n\t\t\t<DescopeWC\n projectId={projectId}\n flowId={flowId}\n baseUrl={baseUrl}\n baseStaticUrl={baseStaticUrl}\n baseCdnUrl={baseCdnUrl}\n ref={setInnerRef}\n telemetryKey={telemetryKey}\n redirectUrl={redirectUrl}\n autoFocus={autoFocus}\n styleId={styleId}\n validateOnBlur={validateOnBlur}\n restartOnError={restartOnError}\n keepLastAuthenticatedUserAfterLogout={\n keepLastAuthenticatedUserAfterLogout\n }\n tenant={tenant}\n externalRequestId={externalRequestId}\n customStorage={customStorage}\n themeOverride={themeOverride}\n {...{\n // attributes\n 'theme.attr': theme,\n 'nonce.attr': nonce,\n 'locale.attr': locale,\n 'form.attr': form,\n 'client.attr': client,\n 'debug.attr': debug,\n 'outbound-app-id.attr': outboundAppId,\n 'outbound-app-scopes.attr': outboundAppScopes,\n 'popup-origin.attr': popupOrigin,\n 'store-last-authenticated-user.attr': storeLastAuthenticatedUser,\n 'send-session-token.attr': sendSessionToken,\n 'refreshCookieName.attr': refreshCookieName,\n 'dismiss-screen-error-on-input.attr': dismissScreenErrorOnInput,\n // props\n 'errorTransformer.prop': errorTransformer,\n 'logger.prop': logger,\n 'onScreenUpdate.prop': onScreenUpdate,\n 'customStorage.prop': customStorage,\n }}\n >\n\t\t\t\t{children}\n\t\t\t</DescopeWC>\n\t\t</Suspense>\n\t</form>\n );\n },\n);\n\nexport default Descope;\n"],"names":["DescopeWC","lazy","async","customElements","get","import","then","module","default","sdkConfigOverrides","baseHeaders","persistTokens","hooks","beforeRequest","getGlobalSdk","httpClient","_","withPropsMapping","React","forwardRef","_a","ref","externalRequestId","props","__rest","useMemo","key","value","Descope","flowId","onSuccess","onError","onReady","logger","tenant","theme","nonce","locale","debug","client","form","telemetryKey","redirectUrl","autoFocus","validateOnBlur","restartOnError","sendSessionToken","errorTransformer","styleId","onScreenUpdate","dismissScreenErrorOnInput","outboundAppId","outboundAppScopes","popupOrigin","children","themeOverride","innerRef","setInnerRef","useState","useImperativeHandle","projectId","baseUrl","baseStaticUrl","baseCdnUrl","storeLastAuthenticatedUser","keepLastAuthenticatedUserAfterLogout","refreshCookieName","customStorage","sdk","useContext","Context","handleSuccess","useCallback","e","afterRequest","Response","JSON","stringify","detail","useEffect","ele","addEventListener","removeEventListener","createElement","Suspense","fallback"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Descope.js","sources":["../../../src/components/Descope.tsx"],"sourcesContent":["/* eslint-disable react/prop-types */\nimport React, {\n lazy,\n Suspense,\n useCallback,\n useEffect,\n useImperativeHandle,\n useMemo,\n useState,\n} from 'react';\nimport { baseHeaders } from '../constants';\nimport Context from '../hooks/Context';\nimport { DescopeProps } from '../types';\nimport { getGlobalSdk } from '../sdk';\nimport withPropsMapping from './withPropsMapping';\n\n// web-component code uses browser API, but can be used in SSR apps, hence the lazy loading\nconst DescopeWC = lazy(async () => {\n const updateDynamicHeader = (key: string, value: string) => {\n if (value) {\n baseHeaders[key] = value;\n } else {\n delete baseHeaders[key];\n }\n };\n\n const WebComponent: any =\n // `customElements` is undeclared (not just undefined) on the server, so it\n // has to be reached through `globalThis` - `customElements?.` alone throws\n // a ReferenceError and defeats the lazy loading above.\n globalThis.customElements?.get('descope-wc') ||\n (await import('@descope/web-component').then((module) => module.default));\n\n WebComponent.sdkConfigOverrides = {\n // Overrides the web-component's base headers to indicate usage via the React SDK\n baseHeaders,\n // Disables token persistence within the web-component to delegate token management\n // to the global SDK hooks. This ensures token handling aligns with the SDK's configuration,\n // and web-component requests leverage the global SDK's beforeRequest hooks for consistency\n persistTokens: false,\n hooks: {\n get beforeRequest() {\n // Retrieves the beforeRequest hook from the global SDK, which is initialized\n // within the AuthProvider using the desired configuration. This approach ensures\n // the web-component utilizes the same beforeRequest hooks as the global SDK\n return getGlobalSdk().httpClient.hooks.beforeRequest;\n },\n set beforeRequest(_) {\n // The empty setter prevents runtime errors when attempts are made to assign a value to 'beforeRequest'.\n // JavaScript objects default to having both getters and setters\n },\n },\n };\n\n return {\n default: withPropsMapping(\n React.forwardRef<HTMLElement>(\n ({ 'external-request-id': externalRequestId, ...props }: any, ref) => {\n // update the dynamic headers with the external request ID if provided\n useMemo(() => {\n updateDynamicHeader('x-external-rid', externalRequestId);\n }, [externalRequestId]);\n\n return <descope-wc ref={ref} {...props} />;\n },\n ),\n ),\n };\n});\n\nconst Descope = React.forwardRef<HTMLElement, DescopeProps>(\n (\n {\n flowId,\n onSuccess,\n onError,\n onReady,\n logger,\n tenant,\n theme,\n nonce,\n locale,\n debug,\n client,\n form,\n telemetryKey,\n redirectUrl,\n autoFocus,\n validateOnBlur,\n restartOnError,\n sendSessionToken,\n errorTransformer,\n styleId,\n onScreenUpdate,\n dismissScreenErrorOnInput,\n outboundAppId,\n outboundAppScopes,\n popupOrigin,\n children,\n externalRequestId,\n themeOverride,\n },\n ref,\n ) => {\n const [innerRef, setInnerRef] = useState(null);\n\n useImperativeHandle(ref, () => innerRef);\n\n const {\n projectId,\n baseUrl,\n baseStaticUrl,\n baseCdnUrl,\n storeLastAuthenticatedUser,\n keepLastAuthenticatedUserAfterLogout,\n refreshCookieName,\n customStorage,\n sdk,\n } = React.useContext(Context);\n\n const handleSuccess = useCallback(\n async (e: CustomEvent) => {\n // In order to make sure all the after-hooks are running with the success response\n // we are generating a fake response with the success data and calling the http client after hook fn with it\n await sdk.httpClient.hooks.afterRequest(\n {} as any,\n new Response(JSON.stringify(e.detail)),\n );\n if (onSuccess) {\n onSuccess(e);\n }\n },\n [onSuccess],\n );\n\n useEffect(() => {\n const ele = innerRef;\n ele?.addEventListener('success', handleSuccess);\n if (onError) ele?.addEventListener('error', onError);\n if (onReady) ele?.addEventListener('ready', onReady);\n\n return () => {\n if (onError) ele?.removeEventListener('error', onError);\n if (onReady) ele?.removeEventListener('ready', onReady);\n\n ele?.removeEventListener('success', handleSuccess);\n };\n }, [innerRef, onError, handleSuccess]);\n\n // Success event\n useEffect(() => {\n const ele = innerRef;\n ele?.addEventListener('success', handleSuccess);\n return () => {\n ele?.removeEventListener('success', handleSuccess);\n };\n }, [innerRef, handleSuccess]);\n\n // Error event\n useEffect(() => {\n const ele = innerRef;\n if (onError) ele?.addEventListener('error', onError);\n\n return () => {\n if (onError) ele?.removeEventListener('error', onError);\n };\n }, [innerRef, onError]);\n\n // Ready event\n useEffect(() => {\n const ele = innerRef;\n if (onReady) ele?.addEventListener('ready', onReady);\n\n return () => {\n if (onReady) ele?.removeEventListener('error', onReady);\n };\n }, [innerRef, onReady]);\n\n return (\n /**\n * in order to avoid redundant remounting of the WC, we are wrapping it with a form element\n * this workaround is done in order to support webauthn passkeys\n * it can be removed once this issue will be solved\n * https://bugs.chromium.org/p/chromium/issues/detail?id=1404106#c2\n */\n\t<form>\n\t\t<Suspense fallback={null}>\n\t\t\t<DescopeWC\n projectId={projectId}\n flowId={flowId}\n baseUrl={baseUrl}\n baseStaticUrl={baseStaticUrl}\n baseCdnUrl={baseCdnUrl}\n ref={setInnerRef}\n telemetryKey={telemetryKey}\n redirectUrl={redirectUrl}\n autoFocus={autoFocus}\n styleId={styleId}\n validateOnBlur={validateOnBlur}\n restartOnError={restartOnError}\n keepLastAuthenticatedUserAfterLogout={\n keepLastAuthenticatedUserAfterLogout\n }\n tenant={tenant}\n externalRequestId={externalRequestId}\n customStorage={customStorage}\n themeOverride={themeOverride}\n {...{\n // attributes\n 'theme.attr': theme,\n 'nonce.attr': nonce,\n 'locale.attr': locale,\n 'form.attr': form,\n 'client.attr': client,\n 'debug.attr': debug,\n 'outbound-app-id.attr': outboundAppId,\n 'outbound-app-scopes.attr': outboundAppScopes,\n 'popup-origin.attr': popupOrigin,\n 'store-last-authenticated-user.attr': storeLastAuthenticatedUser,\n 'send-session-token.attr': sendSessionToken,\n 'refreshCookieName.attr': refreshCookieName,\n 'dismiss-screen-error-on-input.attr': dismissScreenErrorOnInput,\n // props\n 'errorTransformer.prop': errorTransformer,\n 'logger.prop': logger,\n 'onScreenUpdate.prop': onScreenUpdate,\n 'customStorage.prop': customStorage,\n }}\n >\n\t\t\t\t{children}\n\t\t\t</DescopeWC>\n\t\t</Suspense>\n\t</form>\n );\n },\n);\n\nexport default Descope;\n"],"names":["DescopeWC","lazy","async","_a","globalThis","customElements","get","import","then","module","default","sdkConfigOverrides","baseHeaders","persistTokens","hooks","beforeRequest","getGlobalSdk","httpClient","_","withPropsMapping","React","forwardRef","ref","externalRequestId","props","__rest","useMemo","key","value","Descope","flowId","onSuccess","onError","onReady","logger","tenant","theme","nonce","locale","debug","client","form","telemetryKey","redirectUrl","autoFocus","validateOnBlur","restartOnError","sendSessionToken","errorTransformer","styleId","onScreenUpdate","dismissScreenErrorOnInput","outboundAppId","outboundAppScopes","popupOrigin","children","themeOverride","innerRef","setInnerRef","useState","useImperativeHandle","projectId","baseUrl","baseStaticUrl","baseCdnUrl","storeLastAuthenticatedUser","keepLastAuthenticatedUserAfterLogout","refreshCookieName","customStorage","sdk","useContext","Context","handleSuccess","useCallback","e","afterRequest","Response","JSON","stringify","detail","useEffect","ele","addEventListener","removeEventListener","createElement","Suspense","fallback"],"mappings":"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"}
|
package/dist/esm/constants.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const e={"x-descope-sdk-name":"react","x-descope-sdk-version":"3.
|
|
1
|
+
const e={"x-descope-sdk-name":"react","x-descope-sdk-version":"3.3.1"},d="undefined"!=typeof window;export{d as IS_BROWSER,e as baseHeaders};
|
|
2
2
|
//# sourceMappingURL=constants.js.map
|