Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: support react-19 #860

Merged
merged 23 commits into from
Dec 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,11 @@ const createValidateAttributesMixin =
}

async init() {
await super.init?.();

// check attributes initial values
mappingsNames.forEach((attr) =>
this.#handleError(attr, this.getAttribute(attr)),
);
await super.init?.();
nirgur marked this conversation as resolved.
Show resolved Hide resolved
}
};
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ export const loggerMixin = createSingletonMixin(
}, {}) as Logger;
}

set logger(logger: Partial<Logger>) {
this.#logger = this.#wrapLogger(logger);
set logger(logger: Partial<Logger> | undefined) {
this.#logger = this.#wrapLogger(logger || console);
}

get logger(): Logger {
Expand Down
2 changes: 1 addition & 1 deletion packages/sdks/nextjs-sdk/examples/app-router/next-env.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
/// <reference types="next/image-types/global" />

// NOTE: This file should not be edited
// see https://nextjs.org/docs/basic-features/typescript for more information.
// see https://nextjs.org/docs/app/building-your-application/configuring/typescript for more information.
3 changes: 0 additions & 3 deletions packages/sdks/nextjs-sdk/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,6 @@
"@testing-library/jest-dom": "^6.4.2",
"@testing-library/react": "^14.2.1",
"@types/jest": "^29.5.12",
"@types/react": "18.3.3",
"@types/react-dom": "18.2.18",
"@types/react-router-dom": "^5.3.3",
"babel": "^6.23.0",
"babel-jest": "^27.5.1",
"eslint": "8.56.0",
Expand Down
9 changes: 8 additions & 1 deletion packages/sdks/nextjs-sdk/src/server/session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ import { NextApiRequest } from 'next';
import { headers } from 'next/headers';
import { DESCOPE_SESSION_HEADER } from './constants';

// This type is declared to allow simpler migration to Next.15
// It will be removed in the future
type HeaderTypes = Awaited<ReturnType<typeof headers>>;

const extractSession = (
descopeSession?: string
): AuthenticationInfo | undefined => {
Expand All @@ -21,7 +25,10 @@ const extractSession = (
// returns the session token if it exists in the headers
// This function require middleware
export const session = (): AuthenticationInfo | undefined => {
const sessionHeader = headers()?.get(DESCOPE_SESSION_HEADER);
// from Next.js 15, headers() returns a Promise
// It can still be used synchronously to facilitate migration
const reqHeaders = headers() as never as HeaderTypes;
const sessionHeader = reqHeaders.get(DESCOPE_SESSION_HEADER);
return extractSession(sessionHeader);
};

Expand Down
4 changes: 2 additions & 2 deletions packages/sdks/react-sdk/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,8 @@ const App = () => {
// - "skipFirstScreen": automatically focus on the first input of each screen, except first screen
// autoFocus="skipFirstScreen"

// validateOnBlur: set it to true will show input validation errors on blur, in addition to on submit
// validateOnBlur: set it to true will show input validation errors on blur, in addition to on submit

// restartOnError: if set to true, in case of flow version mismatch, will restart the flow if the components version was not changed. Default is false

// errorTransformer is a function that receives an error object and returns a string. The returned string will be displayed to the user.
Expand Down
2 changes: 1 addition & 1 deletion packages/sdks/react-sdk/examples/app/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ const Layout = () => (
</div>
);

const ProtectedRoute = ({ children }: { children: JSX.Element }) => {
const ProtectedRoute = ({ children }: { children: React.ReactNode }) => {
const { isAuthenticated, isSessionLoading } = useSession();

if (isSessionLoading) {
Expand Down
2 changes: 2 additions & 0 deletions packages/sdks/react-sdk/examples/app/Login.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,13 @@ const Login = () => {
client={{ version: '1.0.2' }} // found in context key: client.version
debug={process.env.DESCOPE_DEBUG_MODE === 'true'}
theme={process.env.DESCOPE_THEME as any}
styleId={process.env.DESCOPE_STYLE_ID}
locale={process.env.DESCOPE_LOCALE as string}
redirectUrl={process.env.DESCOPE_REDIRECT_URL}
tenant={process.env.DESCOPE_TENANT_ID}
telemetryKey={process.env.DESCOPE_TELEMETRY_KEY}
errorTransformer={errorTransformer}
logger={console}
/>
)}
{errorMessage && (
Expand Down
8 changes: 8 additions & 0 deletions packages/sdks/react-sdk/examples/app/ManageAccessKeys.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,19 @@ const ManageAccessKeys = () => {
<AccessKeyManagement
widgetId="access-key-management-widget"
tenant={process.env.DESCOPE_TENANT_ID!}
theme={process.env.DESCOPE_THEME as any}
styleId={process.env.DESCOPE_STYLE_ID}
debug={process.env.DESCOPE_DEBUG_MODE === 'true'}
logger={console}
/>
<h2>Manage My Access Keys</h2>
<AccessKeyManagement
widgetId="user-access-key-management-widget"
tenant={process.env.DESCOPE_TENANT_ID!}
theme={process.env.DESCOPE_THEME as any}
styleId={process.env.DESCOPE_STYLE_ID}
debug={process.env.DESCOPE_DEBUG_MODE === 'true'}
logger={console}
/>
</>
);
Expand Down
6 changes: 5 additions & 1 deletion packages/sdks/react-sdk/examples/app/ManageAudit.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,11 @@ const ManageAudit = () => {
<h2>Manage Audit</h2>
<AuditManagement
widgetId="audit-management-widget"
tenant={process.env.DESCOPE_TENANT_ID}
tenant={process.env.DESCOPE_TENANT_ID!}
theme={process.env.DESCOPE_THEME as any}
styleId={process.env.DESCOPE_STYLE_ID}
debug={process.env.DESCOPE_DEBUG_MODE === 'true'}
logger={console}
/>
</>
);
Expand Down
6 changes: 5 additions & 1 deletion packages/sdks/react-sdk/examples/app/ManageRoles.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,11 @@ const ManageRoles = () => {
<h2>Manage Roles</h2>
<RoleManagement
widgetId="role-management-widget"
tenant={process.env.DESCOPE_TENANT_ID}
tenant={process.env.DESCOPE_TENANT_ID!}
theme={process.env.DESCOPE_THEME as any}
styleId={process.env.DESCOPE_STYLE_ID}
debug={process.env.DESCOPE_DEBUG_MODE === 'true'}
logger={console}
/>
</>
);
Expand Down
6 changes: 5 additions & 1 deletion packages/sdks/react-sdk/examples/app/ManageUsers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,11 @@ const ManageUsers = () => {
<h2>Manage Users</h2>
<UserManagement
widgetId="user-management-widget"
tenant={process.env.DESCOPE_TENANT_ID}
tenant={process.env.DESCOPE_TENANT_ID!}
theme={process.env.DESCOPE_THEME as any}
styleId={process.env.DESCOPE_STYLE_ID}
debug={process.env.DESCOPE_DEBUG_MODE === 'true'}
logger={console}
/>
</>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,13 @@ const MyApplicationsPortal = () => {
</div>
</header>
<h2>Applications Portal</h2>
<ApplicationsPortal widgetId="applications-portal-widget" />
<ApplicationsPortal
widgetId="applications-portal-widget"
theme={process.env.DESCOPE_THEME as any}
styleId={process.env.DESCOPE_STYLE_ID}
debug={process.env.DESCOPE_DEBUG_MODE === 'true'}
logger={console}
/>
</>
);
};
Expand Down
4 changes: 4 additions & 0 deletions packages/sdks/react-sdk/examples/app/MyUserProfile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ const MyUserProfile = () => {
<h2>My Profile</h2>
<UserProfile
widgetId="user-profile-widget"
theme={process.env.DESCOPE_THEME as any}
styleId={process.env.DESCOPE_STYLE_ID}
debug={process.env.DESCOPE_DEBUG_MODE === 'true'}
logger={console}
onLogout={() => {
window.location.href = '/login';
}}
Expand Down
3 changes: 2 additions & 1 deletion packages/sdks/react-sdk/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
"leaks": "bash ./scripts/gitleaks/gitleaks.sh",
"lint": "eslint '+(src|examples)/**/*.+(ts|tsx)' --fix",
"prepublishOnly": "npm run build",
"start": "npm run build && rollup -c rollup.config.app.mjs -w",
"start": "npx nx run react-sdk:build && rollup -c rollup.config.app.mjs -w",
"test": "jest"
},
"lint-staged": {
Expand All @@ -59,6 +59,7 @@
]
},
"dependencies": {
"@descope/sdk-helpers": "workspace:*",
"@descope/access-key-management-widget": "workspace:*",
"@descope/audit-management-widget": "workspace:*",
"@descope/role-management-widget": "workspace:*",
Expand Down
61 changes: 19 additions & 42 deletions packages/sdks/react-sdk/src/components/AccessKeyManagement.tsx
Original file line number Diff line number Diff line change
@@ -1,73 +1,50 @@
import React, {
lazy,
Suspense,
useEffect,
useImperativeHandle,
useState,
} from 'react';
import React, { lazy, Suspense, useImperativeHandle, useState } from 'react';
import Context from '../hooks/Context';
import { AccessKeyManagementProps } from '../types';
import withPropsMapping from './withPropsMapping';

// web-component code uses browser API, but can be used in SSR apps, hence the lazy loading
const AccessKeyManagementWC = lazy(async () => {
await import('@descope/access-key-management-widget');

return {
default: ({
projectId,
baseUrl,
baseStaticUrl,
innerRef,
tenant,
widgetId,
theme,
debug,
styleId,
}) => (
<descope-access-key-management-widget
project-id={projectId}
widget-id={widgetId}
base-url={baseUrl}
base-static-url={baseStaticUrl}
theme={theme}
tenant={tenant}
debug={debug}
style-id={styleId}
ref={innerRef}
/>
default: withPropsMapping(
React.forwardRef<HTMLElement>((props, ref) => (
<descope-access-key-management-widget ref={ref} {...props} />
)),
),
};
});

const AccessKeyManagement = React.forwardRef<
HTMLElement,
AccessKeyManagementProps
>(({ logger, tenant, theme, debug, widgetId }, ref) => {
>(({ logger, tenant, theme, debug, widgetId, styleId }, ref) => {
const [innerRef, setInnerRef] = useState(null);

useImperativeHandle(ref, () => innerRef);

const { projectId, baseUrl, baseStaticUrl } = React.useContext(Context);

useEffect(() => {
if (innerRef && logger) {
innerRef.logger = logger;
}
}, [innerRef, logger]);

return (
<Suspense fallback={null}>
<AccessKeyManagementWC
<Suspense fallback={null}>
<AccessKeyManagementWC
projectId={projectId}
widgetId={widgetId}
baseUrl={baseUrl}
baseStaticUrl={baseStaticUrl}
innerRef={setInnerRef}
tenant={tenant}
theme={theme}
debug={debug}
{...{
// attributes
'tenant.attr': tenant,
'theme.attr': theme,
'debug.attr': debug,
'styleId.attr': styleId,
// props
'logger.prop': logger,
}}
/>
</Suspense>
</Suspense>
);
});

Expand Down
55 changes: 17 additions & 38 deletions packages/sdks/react-sdk/src/components/ApplicationsPortal.tsx
Original file line number Diff line number Diff line change
@@ -1,38 +1,17 @@
import React, {
lazy,
Suspense,
useEffect,
useImperativeHandle,
useState,
} from 'react';
import React, { lazy, Suspense, useImperativeHandle, useState } from 'react';
import Context from '../hooks/Context';
import { ApplicationsPortalProps } from '../types';
import withPropsMapping from './withPropsMapping';

// web-component code uses browser API, but can be used in SSR apps, hence the lazy loading
const ApplicationsPortalWC = lazy(async () => {
await import('@descope/applications-portal-widget');

return {
default: ({
projectId,
baseUrl,
baseStaticUrl,
innerRef,
widgetId,
theme,
debug,
styleId,
}) => (
<descope-applications-portal-widget
project-id={projectId}
widget-id={widgetId}
base-url={baseUrl}
base-static-url={baseStaticUrl}
theme={theme}
debug={debug}
style-id={styleId}
ref={innerRef}
/>
default: withPropsMapping(
React.forwardRef<HTMLElement>((props, ref) => (
<descope-applications-portal-widget ref={ref} {...props} />
)),
),
};
});
Expand All @@ -47,24 +26,24 @@ const ApplicationsPortal = React.forwardRef<

const { projectId, baseUrl, baseStaticUrl } = React.useContext(Context);

useEffect(() => {
if (innerRef && logger) {
innerRef.logger = logger;
}
}, [innerRef, logger]);
return (
<Suspense fallback={null}>
<ApplicationsPortalWC
<Suspense fallback={null}>
<ApplicationsPortalWC
projectId={projectId}
widgetId={widgetId}
baseUrl={baseUrl}
baseStaticUrl={baseStaticUrl}
innerRef={setInnerRef}
theme={theme}
debug={debug}
styleId={styleId}
{...{
// attributes
'theme.attr': theme,
'debug.attr': debug,
'styleId.attr': styleId,
// props
'logger.prop': logger,
}}
/>
</Suspense>
</Suspense>
);
});

Expand Down
Loading
Loading