@workos-inc/widgets 1.8.2 → 1.9.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/CHANGELOG.md +11 -0
- package/dist/cjs/admin-portal-domain-verification.client.cjs.map +1 -1
- package/dist/cjs/admin-portal-sso-connection.client.cjs +4 -7
- package/dist/cjs/admin-portal-sso-connection.client.cjs.map +1 -1
- package/dist/cjs/api/api-provider.cjs.map +1 -1
- package/dist/cjs/api/api-provider.d.cts +1 -1
- package/dist/cjs/api/endpoint.cjs +741 -771
- package/dist/cjs/api/endpoint.cjs.map +1 -1
- package/dist/cjs/api/endpoint.d.cts +860 -813
- package/dist/cjs/directory-sync.client.cjs +156 -0
- package/dist/cjs/directory-sync.client.cjs.map +1 -0
- package/dist/cjs/directory-sync.client.d.cts +26 -0
- package/dist/cjs/experimental/api/fetch.cjs +327 -411
- package/dist/cjs/experimental/api/fetch.cjs.map +1 -1
- package/dist/cjs/experimental/api/fetch.d.cts +832 -798
- package/dist/cjs/experimental/api/react-query.cjs +747 -777
- package/dist/cjs/experimental/api/react-query.cjs.map +1 -1
- package/dist/cjs/experimental/api/react-query.d.cts +1378 -1263
- package/dist/cjs/experimental/api/swr.cjs +720 -742
- package/dist/cjs/experimental/api/swr.cjs.map +1 -1
- package/dist/cjs/experimental/api/swr.d.cts +1218 -1175
- package/dist/cjs/index.cjs +5 -0
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.d.cts +2 -0
- package/dist/cjs/lib/add-mfa-dialog.cjs +18 -16
- package/dist/cjs/lib/add-mfa-dialog.cjs.map +1 -1
- package/dist/cjs/lib/admin-portal-sso-connection.cjs +0 -8
- package/dist/cjs/lib/admin-portal-sso-connection.cjs.map +1 -1
- package/dist/cjs/lib/admin-portal-sso-connection.d.cts +1 -2
- package/dist/cjs/lib/api-keys/api-keys-context.cjs +1 -1
- package/dist/cjs/lib/api-keys/api-keys-context.cjs.map +1 -1
- package/dist/cjs/lib/api-keys/api-keys-table.cjs +7 -5
- package/dist/cjs/lib/api-keys/api-keys-table.cjs.map +1 -1
- package/dist/cjs/lib/directory-sync.cjs +288 -0
- package/dist/cjs/lib/directory-sync.cjs.map +1 -0
- package/dist/cjs/lib/directory-sync.d.cts +72 -0
- package/dist/cjs/lib/identity-providers.cjs +57 -1
- package/dist/cjs/lib/identity-providers.cjs.map +1 -1
- package/dist/cjs/lib/identity-providers.d.cts +5 -3
- package/dist/cjs/lib/pipes.cjs +9 -9
- package/dist/cjs/lib/pipes.cjs.map +1 -1
- package/dist/cjs/lib/provider-icon.cjs.map +1 -1
- package/dist/cjs/lib/provider-icon.d.cts +2 -2
- package/dist/cjs/lib/reset-mfa-dialog.cjs +2 -1
- package/dist/cjs/lib/reset-mfa-dialog.cjs.map +1 -1
- package/dist/cjs/lib/use-permissions.cjs.map +1 -1
- package/dist/cjs/lib/use-permissions.d.cts +1 -1
- package/dist/cjs/lib/users-management-context.cjs +1 -1
- package/dist/cjs/lib/users-management-context.cjs.map +1 -1
- package/dist/cjs/lib/users-management.cjs +3 -3
- package/dist/cjs/lib/users-management.cjs.map +1 -1
- package/dist/cjs/lib/utils.cjs +9 -0
- package/dist/cjs/lib/utils.cjs.map +1 -1
- package/dist/cjs/lib/utils.d.cts +16 -2
- package/dist/cjs/workos-widgets.client.cjs +13 -1
- package/dist/cjs/workos-widgets.client.cjs.map +1 -1
- package/dist/esm/admin-portal-domain-verification.client.js +2 -2
- package/dist/esm/admin-portal-domain-verification.client.js.map +1 -1
- package/dist/esm/admin-portal-sso-connection.client.js +6 -9
- package/dist/esm/admin-portal-sso-connection.client.js.map +1 -1
- package/dist/esm/api/api-provider.d.ts +1 -1
- package/dist/esm/api/api-provider.js.map +1 -1
- package/dist/esm/api/endpoint.d.ts +860 -813
- package/dist/esm/api/endpoint.js +727 -751
- package/dist/esm/api/endpoint.js.map +1 -1
- package/dist/esm/directory-sync.client.d.ts +26 -0
- package/dist/esm/directory-sync.client.js +134 -0
- package/dist/esm/directory-sync.client.js.map +1 -0
- package/dist/esm/experimental/api/fetch.d.ts +832 -798
- package/dist/esm/experimental/api/fetch.js +319 -391
- package/dist/esm/experimental/api/fetch.js.map +1 -1
- package/dist/esm/experimental/api/react-query.d.ts +1378 -1263
- package/dist/esm/experimental/api/react-query.js +730 -757
- package/dist/esm/experimental/api/react-query.js.map +1 -1
- package/dist/esm/experimental/api/swr.d.ts +1218 -1175
- package/dist/esm/experimental/api/swr.js +706 -722
- package/dist/esm/experimental/api/swr.js.map +1 -1
- package/dist/esm/index.d.ts +2 -0
- package/dist/esm/index.js +6 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/lib/add-mfa-dialog.js +18 -16
- package/dist/esm/lib/add-mfa-dialog.js.map +1 -1
- package/dist/esm/lib/admin-portal-sso-connection.d.ts +1 -2
- package/dist/esm/lib/admin-portal-sso-connection.js +0 -8
- package/dist/esm/lib/admin-portal-sso-connection.js.map +1 -1
- package/dist/esm/lib/api-keys/api-keys-context.js +1 -1
- package/dist/esm/lib/api-keys/api-keys-context.js.map +1 -1
- package/dist/esm/lib/api-keys/api-keys-table.js +7 -5
- package/dist/esm/lib/api-keys/api-keys-table.js.map +1 -1
- package/dist/esm/lib/directory-sync.d.ts +72 -0
- package/dist/esm/lib/directory-sync.js +259 -0
- package/dist/esm/lib/directory-sync.js.map +1 -0
- package/dist/esm/lib/identity-providers.d.ts +5 -3
- package/dist/esm/lib/identity-providers.js +55 -1
- package/dist/esm/lib/identity-providers.js.map +1 -1
- package/dist/esm/lib/pipes.js +9 -10
- package/dist/esm/lib/pipes.js.map +1 -1
- package/dist/esm/lib/provider-icon.d.ts +2 -2
- package/dist/esm/lib/provider-icon.js.map +1 -1
- package/dist/esm/lib/reset-mfa-dialog.js +2 -1
- package/dist/esm/lib/reset-mfa-dialog.js.map +1 -1
- package/dist/esm/lib/use-permissions.d.ts +1 -1
- package/dist/esm/lib/use-permissions.js.map +1 -1
- package/dist/esm/lib/users-management-context.js +1 -1
- package/dist/esm/lib/users-management-context.js.map +1 -1
- package/dist/esm/lib/users-management.js +5 -4
- package/dist/esm/lib/users-management.js.map +1 -1
- package/dist/esm/lib/utils.d.ts +16 -2
- package/dist/esm/lib/utils.js +8 -0
- package/dist/esm/lib/utils.js.map +1 -1
- package/dist/esm/workos-widgets.client.js +13 -1
- package/dist/esm/workos-widgets.client.js.map +1 -1
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/lib/utils.ts"],"sourcesContent":["import { Member } from \"../api/endpoint.js\";\nimport Bowser from \"bowser\";\nimport cx from \"clsx\";\nimport {\n WIDGETS_CLASS_NAMESPACE,\n WIDGETS_DATA_ATTRIBUTE_NAMESPACE,\n} from \"./constants.js\";\nimport type { Elements } from \"./elements.js\";\n\nexport const canUseDOM = !!(\n typeof window !== \"undefined\" &&\n window.document &&\n window.document.createElement\n);\n\nexport function getBestName({\n firstName,\n lastName,\n}: Pick<Member, \"firstName\" | \"lastName\">) {\n return [firstName, lastName].filter(Boolean).join(\" \") || null;\n}\n\nexport function getComparativeReadableDate(\n now: Date,\n then: Date,\n options: { locale: string; timeZone?: string },\n): string {\n const locale = options.locale ?? \"en-US\";\n const timeSince = now.getTime() - then.getTime();\n const formatter = new Intl.RelativeTimeFormat(locale, { numeric: \"auto\" });\n\n // Has it been less than a minute?\n if (timeSince < 60_000) {\n return formatter.format(0, \"second\"); // Returns \"now\" / \"maintenant\" / \"jetzt\" etc.\n }\n\n // Has it been less than an hour?\n if (timeSince < 3_600_000) {\n const timePassed = Math.floor(timeSince / 60_000);\n return formatter.format(-timePassed, \"minute\");\n }\n\n // Has it been less than a day?\n if (timeSince < 86_400_000) {\n const timePassed = Math.floor(timeSince / 3_600_000);\n return formatter.format(-timePassed, \"hour\");\n }\n\n // Has it been less than a week?\n if (timeSince < 604_800_000) {\n const timePassed = Math.floor(timeSince / 86_400_000);\n return formatter.format(-timePassed, \"day\");\n }\n\n // Has it been less than a month?\n if (timeSince < 2_592_000_000) {\n const timePassed = Math.floor(timeSince / 604_800_000);\n return formatter.format(-timePassed, \"week\");\n }\n\n // Any later?\n return then.toLocaleDateString(locale, {\n timeZone: options.timeZone,\n month: \"long\",\n day: \"numeric\",\n // omit year if it's the same as the current year\n year: now.getFullYear() !== then.getFullYear() ? \"numeric\" : undefined,\n });\n}\n\nexport function isObjectLike(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\nexport function isErrorLike(\n value: unknown,\n): value is Record<string, unknown> & { message: string } {\n return isObjectLike(value) && typeof value.message === \"string\";\n}\n\nexport function isPromiseLike(value: unknown): value is PromiseLike<unknown> {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"then\" in value &&\n typeof value.then === \"function\"\n );\n}\n\nexport async function parseErrorResponse(\n response: Response,\n): Promise<{ message: string; status: number }> {\n try {\n const json = await response.json();\n if (!isObjectLike(json) || typeof json.message !== \"string\") {\n return {\n status: response.status,\n message: response.statusText,\n };\n }\n return {\n ...json,\n status: response.status,\n message: json.message || response.statusText,\n };\n } catch {\n return {\n status: response.status,\n message: response.statusText,\n };\n }\n}\n\nexport function namespaceClassNames(\n ...classNames: (string | undefined | null | boolean)[]\n): string {\n return classNames\n .filter(Boolean)\n .map((className) => `${WIDGETS_CLASS_NAMESPACE}-${className}`)\n .join(\" \");\n}\n\ninterface CommonDomArgs {\n className?: string | undefined | null;\n dataAttributes?: Record<string, string | boolean | undefined | null>;\n}\n\ninterface WidgetRootDomArgs {\n isWidgetRoot: true;\n widgetId: string;\n elementId?: never;\n widgetState: WidgetRootState;\n}\n\ninterface WidgetElementDomArgs {\n isWidgetRoot?: false;\n widgetId?: string;\n elementId?: keyof Elements;\n widgetState?: never;\n className: string | undefined | null;\n}\n\ntype DomArgs = CommonDomArgs & (WidgetRootDomArgs | WidgetElementDomArgs);\n\ntype DataAttributeProps = {\n [K in `data-${string}`]?: string | boolean;\n};\n\ntype DomProps = {\n className: string | undefined;\n} & DataAttributeProps;\n\nexport function getDomProps(args: DomArgs) {\n let {\n className,\n dataAttributes,\n isWidgetRoot = false,\n widgetId,\n elementId,\n widgetState,\n ...passthroughProps\n } = args;\n\n const elementClassName = elementId\n ? (() => {\n // TODO: Overrides for specific elements are mostly here for backwards\n // compatibility. They should be removed in the next major version.\n if (\n elementId === \"primaryButton\" ||\n elementId === \"secondaryButton\" ||\n elementId === \"destructiveButton\"\n ) {\n return namespaceClassNames(\"button\");\n }\n\n if (elementId === \"iconButton\") {\n return namespaceClassNames(\"button\", \"icon-button\");\n }\n\n if (\n elementId === \"primaryMenuItem\" ||\n elementId === \"destructiveMenuItem\"\n ) {\n return namespaceClassNames(\"menu-item\");\n }\n\n if (elementId === \"textfield\") {\n return namespaceClassNames(elementId, \"text-field\");\n }\n\n return namespaceClassNames(fastKebabCase(elementId));\n })()\n : undefined;\n\n const props: DomProps = {\n ...passthroughProps,\n className: cx(\n className,\n isWidgetRoot && namespaceClassNames(\"widget\"),\n elementClassName,\n ),\n };\n\n if (widgetId) {\n props[`data-${WIDGETS_DATA_ATTRIBUTE_NAMESPACE}-widget-id`] = widgetId;\n }\n\n if (isWidgetRoot) {\n widgetState ??= \"resolved\";\n props[`data-${WIDGETS_DATA_ATTRIBUTE_NAMESPACE}-widget`] = true;\n props[`data-${WIDGETS_DATA_ATTRIBUTE_NAMESPACE}-widget-state`] =\n widgetState;\n }\n\n if (dataAttributes) {\n for (const [key, value] of Object.entries(dataAttributes)) {\n if (value != null) {\n const parts = [widgetId, elementId, key]\n .filter((v) => v != null)\n .map(fastKebabCase)\n .join(\"-\");\n if (parts) {\n props[`data-${WIDGETS_DATA_ATTRIBUTE_NAMESPACE}-${parts}`] = value;\n }\n }\n }\n }\n\n if (elementId) {\n props[`data-${WIDGETS_DATA_ATTRIBUTE_NAMESPACE}-element`] =\n fastKebabCase(elementId);\n }\n\n return props;\n}\n\n/**\n * Opt for simplicity and performance over capturing edge cases. Input strings\n * are expected to only be alphabetic.\n */\nfunction fastKebabCase(alphaString: string) {\n return alphaString.replace(/([A-Z])/g, \"-$1\").toLowerCase();\n}\n\nexport function parseUserAgent(userAgent?: string | null) {\n const browser = Bowser.getParser(userAgent ?? \"\");\n const browserName = browser.getBrowserName().replace(/^Mobile\\s*/i, \"\");\n const osName = browser.getOSName();\n const pretty = [browserName, osName].filter(Boolean).join(\" on \");\n\n return { pretty, isMobile: browser.getPlatformType() === \"mobile\" };\n}\n\nexport function getUserLocation(\n location?: {\n cityName: string;\n countryISOCode: string;\n } | null,\n ipAddress?: string | null,\n) {\n if (location) {\n return (\n [location.cityName, location.countryISOCode].filter(Boolean).join(\", \") ||\n \"Unknown location\"\n );\n }\n\n if (ipAddress) {\n return ipAddress;\n }\n\n return \"Unknown location\";\n}\n\nexport function unreachable(value: never): never {\n throw new TypeError(`Unreachable code: ${value}`);\n}\n\nexport function pluralize(word = \"\", amount = 0, showAmount = true): string {\n return `${showAmount ? `${amount} ` : \"\"}${word}${amount === 1 ? \"\" : \"s\"}`;\n}\n\n// Props that all widgets should accept.\nexport interface WidgetRootDomProps {\n className?: string;\n}\n\nexport type WidgetRootState = \"loading\" | \"error\" | \"resolved\";\n"],"mappings":"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","names":["cx","Bowser"]}
|
|
1
|
+
{"version":3,"sources":["../../../src/lib/utils.ts"],"sourcesContent":["import { ListMetadata, Member } from \"../api/endpoint.js\";\nimport Bowser from \"bowser\";\nimport cx from \"clsx\";\nimport {\n WIDGETS_CLASS_NAMESPACE,\n WIDGETS_DATA_ATTRIBUTE_NAMESPACE,\n} from \"./constants.js\";\nimport type { Elements } from \"./elements.js\";\n\nexport const canUseDOM = !!(\n typeof window !== \"undefined\" &&\n window.document &&\n window.document.createElement\n);\n\nexport function getBestName({\n firstName,\n lastName,\n}: Pick<Member, \"firstName\" | \"lastName\">) {\n return [firstName, lastName].filter(Boolean).join(\" \") || null;\n}\n\nexport function getComparativeReadableDate(\n now: Date,\n then: Date,\n options: { locale: string; timeZone?: string },\n): string {\n const locale = options.locale ?? \"en-US\";\n const timeSince = now.getTime() - then.getTime();\n const formatter = new Intl.RelativeTimeFormat(locale, { numeric: \"auto\" });\n\n // Has it been less than a minute?\n if (timeSince < 60_000) {\n return formatter.format(0, \"second\"); // Returns \"now\" / \"maintenant\" / \"jetzt\" etc.\n }\n\n // Has it been less than an hour?\n if (timeSince < 3_600_000) {\n const timePassed = Math.floor(timeSince / 60_000);\n return formatter.format(-timePassed, \"minute\");\n }\n\n // Has it been less than a day?\n if (timeSince < 86_400_000) {\n const timePassed = Math.floor(timeSince / 3_600_000);\n return formatter.format(-timePassed, \"hour\");\n }\n\n // Has it been less than a week?\n if (timeSince < 604_800_000) {\n const timePassed = Math.floor(timeSince / 86_400_000);\n return formatter.format(-timePassed, \"day\");\n }\n\n // Has it been less than a month?\n if (timeSince < 2_592_000_000) {\n const timePassed = Math.floor(timeSince / 604_800_000);\n return formatter.format(-timePassed, \"week\");\n }\n\n // Any later?\n return then.toLocaleDateString(locale, {\n timeZone: options.timeZone,\n month: \"long\",\n day: \"numeric\",\n // omit year if it's the same as the current year\n year: now.getFullYear() !== then.getFullYear() ? \"numeric\" : undefined,\n });\n}\n\nexport function isObjectLike(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\nexport function isErrorLike(\n value: unknown,\n): value is Record<string, unknown> & { message: string } {\n return isObjectLike(value) && typeof value.message === \"string\";\n}\n\nexport function isPromiseLike(value: unknown): value is PromiseLike<unknown> {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"then\" in value &&\n typeof value.then === \"function\"\n );\n}\n\nexport async function parseErrorResponse(\n response: Response,\n): Promise<{ message: string; status: number }> {\n try {\n const json = await response.json();\n if (!isObjectLike(json) || typeof json.message !== \"string\") {\n return {\n status: response.status,\n message: response.statusText,\n };\n }\n return {\n ...json,\n status: response.status,\n message: json.message || response.statusText,\n };\n } catch {\n return {\n status: response.status,\n message: response.statusText,\n };\n }\n}\n\nexport function namespaceClassNames(\n ...classNames: (string | undefined | null | boolean)[]\n): string {\n return classNames\n .filter(Boolean)\n .map((className) => `${WIDGETS_CLASS_NAMESPACE}-${className}`)\n .join(\" \");\n}\n\ninterface CommonDomArgs {\n className?: string | undefined | null;\n dataAttributes?: Record<string, string | boolean | undefined | null>;\n}\n\ninterface WidgetRootDomArgs {\n isWidgetRoot: true;\n widgetId: string;\n elementId?: never;\n widgetState: WidgetRootState;\n}\n\ninterface WidgetElementDomArgs {\n isWidgetRoot?: false;\n widgetId?: string;\n elementId?: keyof Elements;\n widgetState?: never;\n className: string | undefined | null;\n}\n\ntype DomArgs = CommonDomArgs & (WidgetRootDomArgs | WidgetElementDomArgs);\n\ntype DataAttributeProps = {\n [K in `data-${string}`]?: string | boolean;\n};\n\ntype DomProps = {\n className: string | undefined;\n} & DataAttributeProps;\n\nexport function getDomProps(args: DomArgs) {\n let {\n className,\n dataAttributes,\n isWidgetRoot = false,\n widgetId,\n elementId,\n widgetState,\n ...passthroughProps\n } = args;\n\n const elementClassName = elementId\n ? (() => {\n // TODO: Overrides for specific elements are mostly here for backwards\n // compatibility. They should be removed in the next major version.\n if (\n elementId === \"primaryButton\" ||\n elementId === \"secondaryButton\" ||\n elementId === \"destructiveButton\"\n ) {\n return namespaceClassNames(\"button\");\n }\n\n if (elementId === \"iconButton\") {\n return namespaceClassNames(\"button\", \"icon-button\");\n }\n\n if (\n elementId === \"primaryMenuItem\" ||\n elementId === \"destructiveMenuItem\"\n ) {\n return namespaceClassNames(\"menu-item\");\n }\n\n if (elementId === \"textfield\") {\n return namespaceClassNames(elementId, \"text-field\");\n }\n\n return namespaceClassNames(fastKebabCase(elementId));\n })()\n : undefined;\n\n const props: DomProps = {\n ...passthroughProps,\n className: cx(\n className,\n isWidgetRoot && namespaceClassNames(\"widget\"),\n elementClassName,\n ),\n };\n\n if (widgetId) {\n props[`data-${WIDGETS_DATA_ATTRIBUTE_NAMESPACE}-widget-id`] = widgetId;\n }\n\n if (isWidgetRoot) {\n widgetState ??= \"resolved\";\n props[`data-${WIDGETS_DATA_ATTRIBUTE_NAMESPACE}-widget`] = true;\n props[`data-${WIDGETS_DATA_ATTRIBUTE_NAMESPACE}-widget-state`] =\n widgetState;\n }\n\n if (dataAttributes) {\n for (const [key, value] of Object.entries(dataAttributes)) {\n if (value != null) {\n const parts = [widgetId, elementId, key]\n .filter((v) => v != null)\n .map(fastKebabCase)\n .join(\"-\");\n if (parts) {\n props[`data-${WIDGETS_DATA_ATTRIBUTE_NAMESPACE}-${parts}`] = value;\n }\n }\n }\n }\n\n if (elementId) {\n props[`data-${WIDGETS_DATA_ATTRIBUTE_NAMESPACE}-element`] =\n fastKebabCase(elementId);\n }\n\n return props;\n}\n\n/**\n * Opt for simplicity and performance over capturing edge cases. Input strings\n * are expected to only be alphabetic.\n */\nfunction fastKebabCase(alphaString: string) {\n return alphaString.replace(/([A-Z])/g, \"-$1\").toLowerCase();\n}\n\nexport function parseUserAgent(userAgent?: string | null) {\n const browser = Bowser.getParser(userAgent ?? \"\");\n const browserName = browser.getBrowserName().replace(/^Mobile\\s*/i, \"\");\n const osName = browser.getOSName();\n const pretty = [browserName, osName].filter(Boolean).join(\" on \");\n\n return { pretty, isMobile: browser.getPlatformType() === \"mobile\" };\n}\n\nexport function getUserLocation(\n location?: {\n cityName: string;\n countryISOCode: string;\n } | null,\n ipAddress?: string | null,\n) {\n if (location) {\n return (\n [location.cityName, location.countryISOCode].filter(Boolean).join(\", \") ||\n \"Unknown location\"\n );\n }\n\n if (ipAddress) {\n return ipAddress;\n }\n\n return \"Unknown location\";\n}\n\nexport function unreachable(value: never): never {\n throw new TypeError(`Unreachable code: ${value}`);\n}\n\nexport function pluralize(word = \"\", amount = 0, showAmount = true): string {\n return `${showAmount ? `${amount} ` : \"\"}${word}${amount === 1 ? \"\" : \"s\"}`;\n}\n\n// Props that all widgets should accept.\nexport interface WidgetRootDomProps {\n className?: string;\n}\n\nexport type WidgetRootState = \"loading\" | \"error\" | \"resolved\";\n\n// The API response previously returned an object with the `listMetadata`\n// property where `before` and `after` fields were not strictly required.\ntype Pagination = Nullable<{ before: string; after: string }>;\ntype DeprecatedListMetadataResponse = {\n listMetadata: Pagination;\n};\ntype NewListMetadataResponse = {\n list_metadata: Pagination;\n};\n\nexport function getListMetadata<\n T extends DeprecatedListMetadataResponse | NewListMetadataResponse,\n>(responseObject: T | undefined | null): ListMetadata {\n const listMetadata =\n responseObject && \"listMetadata\" in responseObject\n ? responseObject.listMetadata\n : responseObject?.list_metadata;\n\n return {\n before: listMetadata?.before ?? null,\n after: listMetadata?.after ?? null,\n };\n}\n\nexport type Nullable<T> = {\n [K in keyof T]?: T[K] | null;\n};\n"],"mappings":"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","names":["cx","Bowser"]}
|
package/dist/cjs/lib/utils.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Member } from '../api/endpoint.cjs';
|
|
1
|
+
import { Member, ListMetadata } from '../api/endpoint.cjs';
|
|
2
2
|
import { Elements } from './elements.cjs';
|
|
3
3
|
import '@tanstack/react-query';
|
|
4
4
|
import '../api/widgets-api-client.cjs';
|
|
@@ -69,5 +69,19 @@ interface WidgetRootDomProps {
|
|
|
69
69
|
className?: string;
|
|
70
70
|
}
|
|
71
71
|
type WidgetRootState = "loading" | "error" | "resolved";
|
|
72
|
+
type Pagination = Nullable<{
|
|
73
|
+
before: string;
|
|
74
|
+
after: string;
|
|
75
|
+
}>;
|
|
76
|
+
type DeprecatedListMetadataResponse = {
|
|
77
|
+
listMetadata: Pagination;
|
|
78
|
+
};
|
|
79
|
+
type NewListMetadataResponse = {
|
|
80
|
+
list_metadata: Pagination;
|
|
81
|
+
};
|
|
82
|
+
declare function getListMetadata<T extends DeprecatedListMetadataResponse | NewListMetadataResponse>(responseObject: T | undefined | null): ListMetadata;
|
|
83
|
+
type Nullable<T> = {
|
|
84
|
+
[K in keyof T]?: T[K] | null;
|
|
85
|
+
};
|
|
72
86
|
|
|
73
|
-
export { type WidgetRootDomProps, type WidgetRootState, canUseDOM, getBestName, getComparativeReadableDate, getDomProps, getUserLocation, isErrorLike, isObjectLike, isPromiseLike, namespaceClassNames, parseErrorResponse, parseUserAgent, pluralize, unreachable };
|
|
87
|
+
export { type Nullable, type WidgetRootDomProps, type WidgetRootState, canUseDOM, getBestName, getComparativeReadableDate, getDomProps, getListMetadata, getUserLocation, isErrorLike, isObjectLike, isPromiseLike, namespaceClassNames, parseErrorResponse, parseUserAgent, pluralize, unreachable };
|
|
@@ -38,6 +38,7 @@ var import_react_query = require("@tanstack/react-query");
|
|
|
38
38
|
var import_clsx = __toESM(require("clsx"), 1);
|
|
39
39
|
var React = __toESM(require("react"), 1);
|
|
40
40
|
var import_utils = require("./lib/utils.js");
|
|
41
|
+
var import_errors = require("./lib/errors.js");
|
|
41
42
|
var import_config = require("./lib/api/config.js");
|
|
42
43
|
var import_widgets_context = require("./lib/widgets-context.js");
|
|
43
44
|
var import_constants = require("./lib/constants.js");
|
|
@@ -86,7 +87,18 @@ const QueryClientProviderImpl = ({
|
|
|
86
87
|
children
|
|
87
88
|
}) => {
|
|
88
89
|
const [queryClient] = React.useState(
|
|
89
|
-
() => providedClient ?? new import_react_query.QueryClient(
|
|
90
|
+
() => providedClient ?? new import_react_query.QueryClient({
|
|
91
|
+
defaultOptions: {
|
|
92
|
+
queries: {
|
|
93
|
+
retry: (failureCount, error) => {
|
|
94
|
+
if (error instanceof import_errors.IncorrectPermissionsError) {
|
|
95
|
+
return false;
|
|
96
|
+
}
|
|
97
|
+
return failureCount < 3;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
})
|
|
90
102
|
);
|
|
91
103
|
const client = (0, import_react_query.useQueryClient)(queryClient);
|
|
92
104
|
if (Object.is(client, providedClient)) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/workos-widgets.client.tsx"],"sourcesContent":["\"use client\";\n\nimport { Theme as RadixThemes } from \"@radix-ui/themes\";\nimport type { GetPropDefTypes, themePropDefs } from \"@radix-ui/themes/props\";\nimport {\n QueryClient,\n QueryClientProvider,\n useQueryClient,\n} from \"@tanstack/react-query\";\nimport cx from \"clsx\";\nimport * as React from \"react\";\nimport { namespaceClassNames } from \"./lib/utils.js\";\nimport { DEFAULT_API_HOSTNAME } from \"./lib/api/config.js\";\nimport type { Elements } from \"./lib/elements.js\";\nimport { WidgetsContext } from \"./lib/widgets-context.js\";\nimport { WIDGETS_DATA_ATTRIBUTE_NAMESPACE } from \"./lib/constants.js\";\n\nexport interface WorkOsWidgetsProps {\n elements?: Elements;\n theme?: Omit<GetPropDefTypes<typeof themePropDefs>, \"asChild\"> & {\n fontFamily?: string;\n };\n style?: React.CSSProperties;\n className?: string;\n children: React.ReactNode;\n apiHostname?: string;\n port?: number | null;\n https?: boolean;\n /**\n * Optional query client for users who are already using Tanstack Query. If\n * not provided, a new query client will be created and mounted internally.\n */\n queryClient?: QueryClient;\n}\n\nexport const WorkOsWidgets: React.FC<WorkOsWidgetsProps> = ({\n elements = {},\n className,\n theme: { fontFamily, ...radixThemesProps } = {},\n style = {},\n children,\n apiHostname = DEFAULT_API_HOSTNAME,\n port = null,\n https = true,\n queryClient,\n}) => {\n const customStyle: React.CSSProperties = fontFamily\n ? {\n \"--default-font-family\": fontFamily,\n ...style,\n }\n : style;\n\n const apiBaseUrl = React.useMemo(() => {\n try {\n const url = new URL(\n \"/\",\n `${https ? \"https\" : \"http\"}://${apiHostname}${port ? `:${port}` : \"\"}`,\n );\n return url.toString().slice(0, -1);\n } catch {\n console.error(\n \"Failed to validate the WorkOS API URL. Check to ensure that valid `apiHostname` and `port` props are passed to WorkOsWidgets\",\n );\n return `https://${DEFAULT_API_HOSTNAME}`;\n }\n }, [apiHostname, https, port]);\n\n return (\n <QueryClientProviderImpl client={queryClient}>\n <RadixThemes\n {...radixThemesProps}\n {...{ [`data-${WIDGETS_DATA_ATTRIBUTE_NAMESPACE}-root`]: true }}\n style={customStyle}\n className={cx(namespaceClassNames(\"root\"), className)}\n >\n <WidgetsContext.Provider value={{ elements, apiBaseUrl }}>\n {children}\n </WidgetsContext.Provider>\n </RadixThemes>\n </QueryClientProviderImpl>\n );\n};\n\nconst QueryClientProviderImpl = ({\n client: providedClient,\n children,\n}: {\n client: QueryClient | undefined;\n children: React.ReactNode;\n}) => {\n const [queryClient] = React.useState(\n ()
|
|
1
|
+
{"version":3,"sources":["../../src/workos-widgets.client.tsx"],"sourcesContent":["\"use client\";\n\nimport { Theme as RadixThemes } from \"@radix-ui/themes\";\nimport type { GetPropDefTypes, themePropDefs } from \"@radix-ui/themes/props\";\nimport {\n QueryClient,\n QueryClientProvider,\n useQueryClient,\n} from \"@tanstack/react-query\";\nimport cx from \"clsx\";\nimport * as React from \"react\";\nimport { namespaceClassNames } from \"./lib/utils.js\";\nimport { IncorrectPermissionsError } from \"./lib/errors.js\";\nimport { DEFAULT_API_HOSTNAME } from \"./lib/api/config.js\";\nimport type { Elements } from \"./lib/elements.js\";\nimport { WidgetsContext } from \"./lib/widgets-context.js\";\nimport { WIDGETS_DATA_ATTRIBUTE_NAMESPACE } from \"./lib/constants.js\";\n\nexport interface WorkOsWidgetsProps {\n elements?: Elements;\n theme?: Omit<GetPropDefTypes<typeof themePropDefs>, \"asChild\"> & {\n fontFamily?: string;\n };\n style?: React.CSSProperties;\n className?: string;\n children: React.ReactNode;\n apiHostname?: string;\n port?: number | null;\n https?: boolean;\n /**\n * Optional query client for users who are already using Tanstack Query. If\n * not provided, a new query client will be created and mounted internally.\n */\n queryClient?: QueryClient;\n}\n\nexport const WorkOsWidgets: React.FC<WorkOsWidgetsProps> = ({\n elements = {},\n className,\n theme: { fontFamily, ...radixThemesProps } = {},\n style = {},\n children,\n apiHostname = DEFAULT_API_HOSTNAME,\n port = null,\n https = true,\n queryClient,\n}) => {\n const customStyle: React.CSSProperties = fontFamily\n ? {\n \"--default-font-family\": fontFamily,\n ...style,\n }\n : style;\n\n const apiBaseUrl = React.useMemo(() => {\n try {\n const url = new URL(\n \"/\",\n `${https ? \"https\" : \"http\"}://${apiHostname}${port ? `:${port}` : \"\"}`,\n );\n return url.toString().slice(0, -1);\n } catch {\n console.error(\n \"Failed to validate the WorkOS API URL. Check to ensure that valid `apiHostname` and `port` props are passed to WorkOsWidgets\",\n );\n return `https://${DEFAULT_API_HOSTNAME}`;\n }\n }, [apiHostname, https, port]);\n\n return (\n <QueryClientProviderImpl client={queryClient}>\n <RadixThemes\n {...radixThemesProps}\n {...{ [`data-${WIDGETS_DATA_ATTRIBUTE_NAMESPACE}-root`]: true }}\n style={customStyle}\n className={cx(namespaceClassNames(\"root\"), className)}\n >\n <WidgetsContext.Provider value={{ elements, apiBaseUrl }}>\n {children}\n </WidgetsContext.Provider>\n </RadixThemes>\n </QueryClientProviderImpl>\n );\n};\n\nconst QueryClientProviderImpl = ({\n client: providedClient,\n children,\n}: {\n client: QueryClient | undefined;\n children: React.ReactNode;\n}) => {\n const [queryClient] = React.useState(\n () =>\n providedClient ??\n new QueryClient({\n defaultOptions: {\n queries: {\n retry: (failureCount, error) => {\n if (error instanceof IncorrectPermissionsError) {\n return false;\n }\n return failureCount < 3;\n },\n },\n },\n }),\n );\n\n const client = useQueryClient(queryClient);\n if (Object.is(client, providedClient)) {\n // No need for a new context provider if the user provided the client to\n // their own provider, which has already mounted the client.\n return <>{children}</>;\n }\n\n return <QueryClientProvider client={client}>{children}</QueryClientProvider>;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AA6EQ;AA3ER,oBAAqC;AAErC,yBAIO;AACP,kBAAe;AACf,YAAuB;AACvB,mBAAoC;AACpC,oBAA0C;AAC1C,oBAAqC;AAErC,6BAA+B;AAC/B,uBAAiD;AAoB1C,MAAM,gBAA8C,CAAC;AAAA,EAC1D,WAAW,CAAC;AAAA,EACZ;AAAA,EACA,OAAO,EAAE,YAAY,GAAG,iBAAiB,IAAI,CAAC;AAAA,EAC9C,QAAQ,CAAC;AAAA,EACT;AAAA,EACA,cAAc;AAAA,EACd,OAAO;AAAA,EACP,QAAQ;AAAA,EACR;AACF,MAAM;AACJ,QAAM,cAAmC,aACrC;AAAA,IACE,yBAAyB;AAAA,IACzB,GAAG;AAAA,EACL,IACA;AAEJ,QAAM,aAAa,MAAM,QAAQ,MAAM;AACrC,QAAI;AACF,YAAM,MAAM,IAAI;AAAA,QACd;AAAA,QACA,GAAG,QAAQ,UAAU,MAAM,MAAM,WAAW,GAAG,OAAO,IAAI,IAAI,KAAK,EAAE;AAAA,MACvE;AACA,aAAO,IAAI,SAAS,EAAE,MAAM,GAAG,EAAE;AAAA,IACnC,QAAQ;AACN,cAAQ;AAAA,QACN;AAAA,MACF;AACA,aAAO,WAAW,kCAAoB;AAAA,IACxC;AAAA,EACF,GAAG,CAAC,aAAa,OAAO,IAAI,CAAC;AAE7B,SACE,4CAAC,2BAAwB,QAAQ,aAC/B;AAAA,IAAC,cAAAA;AAAA,IAAA;AAAA,MACE,GAAG;AAAA,MACH,GAAG,EAAE,CAAC,QAAQ,iDAAgC,OAAO,GAAG,KAAK;AAAA,MAC9D,OAAO;AAAA,MACP,eAAW,YAAAC,aAAG,kCAAoB,MAAM,GAAG,SAAS;AAAA,MAEpD,sDAAC,sCAAe,UAAf,EAAwB,OAAO,EAAE,UAAU,WAAW,GACpD,UACH;AAAA;AAAA,EACF,GACF;AAEJ;AAEA,MAAM,0BAA0B,CAAC;AAAA,EAC/B,QAAQ;AAAA,EACR;AACF,MAGM;AACJ,QAAM,CAAC,WAAW,IAAI,MAAM;AAAA,IAC1B,MACE,kBACA,IAAI,+BAAY;AAAA,MACd,gBAAgB;AAAA,QACd,SAAS;AAAA,UACP,OAAO,CAAC,cAAc,UAAU;AAC9B,gBAAI,iBAAiB,yCAA2B;AAC9C,qBAAO;AAAA,YACT;AACA,mBAAO,eAAe;AAAA,UACxB;AAAA,QACF;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACL;AAEA,QAAM,aAAS,mCAAe,WAAW;AACzC,MAAI,OAAO,GAAG,QAAQ,cAAc,GAAG;AAGrC,WAAO,2EAAG,UAAS;AAAA,EACrB;AAEA,SAAO,4CAAC,0CAAoB,QAAiB,UAAS;AACxD;","names":["RadixThemes","cx"]}
|
|
@@ -7,11 +7,11 @@ import {
|
|
|
7
7
|
} from "./lib/admin-portal-domain-verification.js";
|
|
8
8
|
import { ApiProvider, useApiReady } from "./api/api-provider.js";
|
|
9
9
|
import {
|
|
10
|
-
useGenerateAdminPortalLink,
|
|
11
10
|
useListOrganizationDomains,
|
|
12
11
|
getListOrganizationDomainsQueryKey,
|
|
13
12
|
useDeleteOrganizationDomain,
|
|
14
|
-
useReverifyOrganizationDomain
|
|
13
|
+
useReverifyOrganizationDomain,
|
|
14
|
+
useGenerateAdminPortalLink
|
|
15
15
|
} from "./api/endpoint.js";
|
|
16
16
|
import { useWorkOsApiUrl } from "./lib/widgets-context.js";
|
|
17
17
|
import { ErrorBoundary } from "./lib/error-boundary.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/admin-portal-domain-verification.client.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport {\n AdminPortalDomainVerificationError,\n AdminPortalDomainVerificationLoading,\n AdminPortalDomainVerification as AdminPortalDomainVerificationPresentational,\n} from \"./lib/admin-portal-domain-verification.js\";\nimport type {\n AdminPortalDomainVerificationErrorProps,\n AdminPortalDomainVerificationLoadingProps,\n} from \"./lib/admin-portal-domain-verification.js\";\nimport { ApiProvider, AuthToken, useApiReady } from \"./api/api-provider.js\";\nimport {\n
|
|
1
|
+
{"version":3,"sources":["../../src/admin-portal-domain-verification.client.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport {\n AdminPortalDomainVerificationError,\n AdminPortalDomainVerificationLoading,\n AdminPortalDomainVerification as AdminPortalDomainVerificationPresentational,\n} from \"./lib/admin-portal-domain-verification.js\";\nimport type {\n AdminPortalDomainVerificationErrorProps,\n AdminPortalDomainVerificationLoadingProps,\n} from \"./lib/admin-portal-domain-verification.js\";\nimport { ApiProvider, AuthToken, useApiReady } from \"./api/api-provider.js\";\nimport {\n useListOrganizationDomains,\n getListOrganizationDomainsQueryKey,\n useDeleteOrganizationDomain,\n useReverifyOrganizationDomain,\n useGenerateAdminPortalLink,\n} from \"./api/endpoint.js\";\nimport { useWorkOsApiUrl } from \"./lib/widgets-context.js\";\nimport { ErrorBoundary } from \"./lib/error-boundary.js\";\nimport { useQueryClient } from \"@tanstack/react-query\";\nimport { WidgetRootDomProps } from \"./lib/utils.js\";\n\ninterface AdminPortalDomainVerificationProps extends WidgetRootDomProps {\n authToken: AuthToken;\n}\n\nconst AdminPortalDomainVerification: React.FC<\n AdminPortalDomainVerificationProps\n> = ({ authToken, ...domProps }) => {\n const baseUrl = useWorkOsApiUrl();\n\n return (\n <ErrorBoundary\n fallbackRender={({ error }) => (\n <AdminPortalDomainVerificationError error={error} {...domProps} />\n )}\n >\n <ApiProvider\n widgetType=\"admin-portal-domain-verification\"\n authToken={authToken}\n baseUrl={baseUrl}\n >\n <AdminPortalDomainVerificationImpl {...domProps} />\n </ApiProvider>\n </ErrorBoundary>\n );\n};\n\nconst AdminPortalDomainVerificationImpl = (\n props: Omit<AdminPortalDomainVerificationProps, \"authToken\">,\n) => {\n const isApiReady = useApiReady();\n const queryClient = useQueryClient();\n const {\n data: organizationDomains,\n isLoading,\n error,\n } = useListOrganizationDomains();\n\n const { mutate: generateAdminPortalLink, isPending } =\n useGenerateAdminPortalLink({\n mutation: {\n onSuccess: (data) => {\n window.open(data.link, \"_blank\", \"noopener,noreferrer\");\n },\n },\n });\n\n const { mutate: deleteDomain } = useDeleteOrganizationDomain({\n mutation: {\n onSuccess: () => {\n queryClient.invalidateQueries({\n queryKey: getListOrganizationDomainsQueryKey(),\n });\n },\n },\n });\n\n const { mutate: reverifyDomain } = useReverifyOrganizationDomain({\n mutation: {\n onSuccess: () => {\n queryClient.invalidateQueries({\n queryKey: getListOrganizationDomainsQueryKey(),\n });\n },\n },\n });\n\n const handleAddDomain = () => {\n generateAdminPortalLink({\n params: {\n intent: \"domain_verification\",\n },\n });\n };\n\n const handleDeleteDomain = (domainId: string) => {\n deleteDomain({ domainId });\n };\n\n const handleReverifyDomain = (domainId: string) => {\n reverifyDomain({ domainId });\n };\n\n if (!isApiReady || isLoading) {\n return <AdminPortalDomainVerificationLoading {...props} />;\n }\n\n if (error) {\n return <AdminPortalDomainVerificationError error={error} {...props} />;\n }\n\n const domains = organizationDomains?.data || [];\n\n return (\n <ErrorBoundary\n fallbackRender={({ error }) => (\n <AdminPortalDomainVerificationError error={error} {...props} />\n )}\n >\n <AdminPortalDomainVerificationPresentational\n organizationDomains={domains}\n onAddDomain={handleAddDomain}\n onDeleteDomain={handleDeleteDomain}\n onReverifyDomain={handleReverifyDomain}\n isPending={isPending}\n {...props}\n />\n </ErrorBoundary>\n );\n};\n\nexport type {\n AdminPortalDomainVerificationProps,\n AdminPortalDomainVerificationLoadingProps,\n AdminPortalDomainVerificationErrorProps,\n};\nexport {\n AdminPortalDomainVerification,\n AdminPortalDomainVerificationLoading,\n AdminPortalDomainVerificationError,\n};\n"],"mappings":";AAqCQ;AAlCR;AAAA,EACE;AAAA,EACA;AAAA,EACA,iCAAiC;AAAA,OAC5B;AAKP,SAAS,aAAwB,mBAAmB;AACpD;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,uBAAuB;AAChC,SAAS,qBAAqB;AAC9B,SAAS,sBAAsB;AAO/B,MAAM,gCAEF,CAAC,EAAE,WAAW,GAAG,SAAS,MAAM;AAClC,QAAM,UAAU,gBAAgB;AAEhC,SACE;AAAA,IAAC;AAAA;AAAA,MACC,gBAAgB,CAAC,EAAE,MAAM,MACvB,oBAAC,sCAAmC,OAAe,GAAG,UAAU;AAAA,MAGlE;AAAA,QAAC;AAAA;AAAA,UACC,YAAW;AAAA,UACX;AAAA,UACA;AAAA,UAEA,8BAAC,qCAAmC,GAAG,UAAU;AAAA;AAAA,MACnD;AAAA;AAAA,EACF;AAEJ;AAEA,MAAM,oCAAoC,CACxC,UACG;AACH,QAAM,aAAa,YAAY;AAC/B,QAAM,cAAc,eAAe;AACnC,QAAM;AAAA,IACJ,MAAM;AAAA,IACN;AAAA,IACA;AAAA,EACF,IAAI,2BAA2B;AAE/B,QAAM,EAAE,QAAQ,yBAAyB,UAAU,IACjD,2BAA2B;AAAA,IACzB,UAAU;AAAA,MACR,WAAW,CAAC,SAAS;AACnB,eAAO,KAAK,KAAK,MAAM,UAAU,qBAAqB;AAAA,MACxD;AAAA,IACF;AAAA,EACF,CAAC;AAEH,QAAM,EAAE,QAAQ,aAAa,IAAI,4BAA4B;AAAA,IAC3D,UAAU;AAAA,MACR,WAAW,MAAM;AACf,oBAAY,kBAAkB;AAAA,UAC5B,UAAU,mCAAmC;AAAA,QAC/C,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF,CAAC;AAED,QAAM,EAAE,QAAQ,eAAe,IAAI,8BAA8B;AAAA,IAC/D,UAAU;AAAA,MACR,WAAW,MAAM;AACf,oBAAY,kBAAkB;AAAA,UAC5B,UAAU,mCAAmC;AAAA,QAC/C,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF,CAAC;AAED,QAAM,kBAAkB,MAAM;AAC5B,4BAAwB;AAAA,MACtB,QAAQ;AAAA,QACN,QAAQ;AAAA,MACV;AAAA,IACF,CAAC;AAAA,EACH;AAEA,QAAM,qBAAqB,CAAC,aAAqB;AAC/C,iBAAa,EAAE,SAAS,CAAC;AAAA,EAC3B;AAEA,QAAM,uBAAuB,CAAC,aAAqB;AACjD,mBAAe,EAAE,SAAS,CAAC;AAAA,EAC7B;AAEA,MAAI,CAAC,cAAc,WAAW;AAC5B,WAAO,oBAAC,wCAAsC,GAAG,OAAO;AAAA,EAC1D;AAEA,MAAI,OAAO;AACT,WAAO,oBAAC,sCAAmC,OAAe,GAAG,OAAO;AAAA,EACtE;AAEA,QAAM,UAAU,qBAAqB,QAAQ,CAAC;AAE9C,SACE;AAAA,IAAC;AAAA;AAAA,MACC,gBAAgB,CAAC,EAAE,OAAAA,OAAM,MACvB,oBAAC,sCAAmC,OAAOA,QAAQ,GAAG,OAAO;AAAA,MAG/D;AAAA,QAAC;AAAA;AAAA,UACC,qBAAqB;AAAA,UACrB,aAAa;AAAA,UACb,gBAAgB;AAAA,UAChB,kBAAkB;AAAA,UAClB;AAAA,UACC,GAAG;AAAA;AAAA,MACN;AAAA;AAAA,EACF;AAEJ;","names":["error"]}
|
|
@@ -9,8 +9,8 @@ import {
|
|
|
9
9
|
} from "./lib/admin-portal-sso-connection.js";
|
|
10
10
|
import { ApiProvider, useApiReady } from "./api/api-provider.js";
|
|
11
11
|
import {
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
useListSsoConnections,
|
|
13
|
+
useGenerateAdminPortalLink
|
|
14
14
|
} from "./api/endpoint.js";
|
|
15
15
|
import { useWorkOsApiUrl } from "./lib/widgets-context.js";
|
|
16
16
|
import { ErrorBoundary } from "./lib/error-boundary.js";
|
|
@@ -44,14 +44,13 @@ const AdminPortalSsoConnectionImpl = (props) => {
|
|
|
44
44
|
if (isApiReady && currentDate === null) {
|
|
45
45
|
setCurrentDate(/* @__PURE__ */ new Date());
|
|
46
46
|
}
|
|
47
|
-
const { mutate: generateAdminPortalLink,
|
|
47
|
+
const { mutate: generateAdminPortalLink, isPending } = useGenerateAdminPortalLink({
|
|
48
48
|
mutation: {
|
|
49
49
|
onSuccess: (data) => {
|
|
50
50
|
window.open(data.link, "_blank", "noopener,noreferrer");
|
|
51
51
|
}
|
|
52
52
|
}
|
|
53
53
|
});
|
|
54
|
-
const adminPortalLink = mutation.data?.link ?? null;
|
|
55
54
|
const query = useListSsoConnections();
|
|
56
55
|
const initConfig = () => {
|
|
57
56
|
generateAdminPortalLink({
|
|
@@ -83,8 +82,7 @@ const AdminPortalSsoConnectionImpl = (props) => {
|
|
|
83
82
|
adminPortalOpenButton: /* @__PURE__ */ jsx(
|
|
84
83
|
AdminPortalOpenButton,
|
|
85
84
|
{
|
|
86
|
-
isPending
|
|
87
|
-
href: adminPortalLink,
|
|
85
|
+
isPending,
|
|
88
86
|
initConfig
|
|
89
87
|
}
|
|
90
88
|
)
|
|
@@ -139,8 +137,7 @@ const AdminPortalSsoConnectionImpl = (props) => {
|
|
|
139
137
|
adminPortalOpenButton: /* @__PURE__ */ jsx(
|
|
140
138
|
AdminPortalOpenButton,
|
|
141
139
|
{
|
|
142
|
-
isPending
|
|
143
|
-
href: adminPortalLink,
|
|
140
|
+
isPending,
|
|
144
141
|
initConfig
|
|
145
142
|
}
|
|
146
143
|
)
|
|
@@ -186,7 +183,7 @@ function getConnectionState(connection, currentDate) {
|
|
|
186
183
|
return { status: "Inactive" };
|
|
187
184
|
}
|
|
188
185
|
default:
|
|
189
|
-
return unreachable(connection);
|
|
186
|
+
return unreachable(connection.state);
|
|
190
187
|
}
|
|
191
188
|
}
|
|
192
189
|
function getIdentityProvider(connection) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/admin-portal-sso-connection.client.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport {\n AdminPortalOpenButton,\n AdminPortalSsoConnectionError,\n AdminPortalSsoConnectionLoading,\n AdminPortalSsoConnection as AdminPortalSsoConnectionPresentational,\n} from \"./lib/admin-portal-sso-connection.js\";\nimport type {\n AdminPortalSsoConnectionErrorProps,\n AdminPortalSsoConnectionLoadingProps,\n AdminPortalSsoConnectionStatusProps,\n} from \"./lib/admin-portal-sso-connection.js\";\nimport { ApiProvider, AuthToken, useApiReady } from \"./api/api-provider.js\";\nimport {\n type SsoConnection,\n useGenerateAdminPortalLink,\n useListSsoConnections,\n} from \"./api/endpoint.js\";\nimport { useWorkOsApiUrl } from \"./lib/widgets-context.js\";\nimport { ErrorBoundary } from \"./lib/error-boundary.js\";\nimport { unreachable, WidgetRootDomProps } from \"./lib/utils.js\";\nimport { IdentityProvider } from \"./lib/identity-providers.js\";\n\ninterface AdminPortalSsoConnectionProps extends WidgetRootDomProps {\n authToken: AuthToken;\n}\n\nconst AdminPortalSsoConnection: React.FC<AdminPortalSsoConnectionProps> = ({\n authToken,\n ...domProps\n}) => {\n const baseUrl = useWorkOsApiUrl();\n return (\n <ErrorBoundary\n fallbackRender={({ error }) => (\n <AdminPortalSsoConnectionError error={error} {...domProps} />\n )}\n >\n <ApiProvider\n widgetType=\"admin-portal-sso-connection\"\n authToken={authToken}\n baseUrl={baseUrl}\n >\n <AdminPortalSsoConnectionImpl {...domProps} />\n </ApiProvider>\n </ErrorBoundary>\n );\n};\n\nconst AdminPortalSsoConnectionImpl = (props: WidgetRootDomProps) => {\n const isApiReady = useApiReady();\n const [currentDate, setCurrentDate] = React.useState<Date | null>(() =>\n isApiReady ? new Date() : null,\n );\n if (isApiReady && currentDate === null) {\n setCurrentDate(new Date());\n }\n\n const { mutate: generateAdminPortalLink, ...mutation } =\n useGenerateAdminPortalLink({\n mutation: {\n onSuccess: (data) => {\n window.open(data.link, \"_blank\", \"noopener,noreferrer\");\n },\n },\n });\n\n const adminPortalLink = mutation.data?.link ?? null;\n\n const query = useListSsoConnections();\n\n const initConfig = () => {\n generateAdminPortalLink({\n params: {\n intent: \"sso\",\n },\n });\n };\n\n if (query.isLoading) {\n return <AdminPortalSsoConnectionLoading {...props} />;\n }\n\n if (query.isError) {\n return <AdminPortalSsoConnectionError error={query.error} {...props} />;\n }\n\n if (query.data) {\n const connection = query.data[0];\n if (!connection) {\n return (\n <ErrorBoundary\n fallbackRender={({ error }) => (\n <AdminPortalSsoConnectionError error={error} {...props} />\n )}\n >\n <AdminPortalSsoConnectionPresentational\n {...props}\n connectionStatus=\"NotConfigured\"\n currentDate={currentDate}\n lastSession={null}\n adminPortalOpenButton={\n <AdminPortalOpenButton\n isPending={mutation.isPending}\n href={adminPortalLink}\n initConfig={initConfig}\n />\n }\n />\n </ErrorBoundary>\n );\n }\n\n const connectionState = getConnectionState(connection, currentDate);\n const statusProps: AdminPortalSsoConnectionStatusProps = (() => {\n const connectionStatus = connectionState.status;\n if (!connection || connectionStatus === \"NotConfigured\") {\n return {\n connectionStatus: \"NotConfigured\",\n } satisfies AdminPortalSsoConnectionStatusProps;\n }\n\n const identityProvider = getIdentityProvider(connection);\n switch (connectionStatus) {\n case \"Active\":\n return {\n connectionStatus,\n identityProvider,\n } satisfies AdminPortalSsoConnectionStatusProps;\n case \"Inactive\":\n return {\n connectionStatus,\n identityProvider,\n } satisfies AdminPortalSsoConnectionStatusProps;\n case \"Expired\":\n case \"Expiring\":\n return {\n connectionStatus,\n expiryDate: connectionState.expiryDate,\n identityProvider,\n } satisfies AdminPortalSsoConnectionStatusProps;\n default:\n return unreachable(connectionState);\n }\n })();\n\n const lastSession = connection.lastSession\n ? new Date(connection.lastSession.createdAt)\n : null;\n\n return (\n <ErrorBoundary\n fallbackRender={({ error }) => (\n <AdminPortalSsoConnectionError error={error} {...props} />\n )}\n >\n <AdminPortalSsoConnectionPresentational\n {...props}\n {...statusProps}\n currentDate={currentDate}\n lastSession={lastSession}\n adminPortalOpenButton={\n <AdminPortalOpenButton\n isPending={mutation.isPending}\n href={adminPortalLink}\n initConfig={initConfig}\n />\n }\n />\n </ErrorBoundary>\n );\n }\n};\n\ntype ConnectionState =\n | { status: \"NotConfigured\" }\n | { status: \"Active\" }\n | { status: \"Inactive\" }\n | {\n status: \"Expiring\";\n daysUntilExpiry: number | null;\n expiryDate: Date | null;\n }\n | { status: \"Expired\"; expiryDate: Date | null };\n\nfunction getConnectionState(\n connection: SsoConnection,\n currentDate: Date | null,\n): ConnectionState {\n switch (connection.state) {\n case \"Active\":\n case \"Validating\":\n case \"Deleting\": {\n const activeStatus = { status: \"Active\" } satisfies ConnectionState;\n if (connection.providerTag !== \"Saml\") {\n return activeStatus;\n }\n\n if (connection.latestExpiredCertificate) {\n return {\n status: \"Expired\",\n expiryDate: connection.latestExpiredCertificate.notAfter\n ? new Date(connection.latestExpiredCertificate.notAfter)\n : null,\n };\n }\n\n const expiryTime = connection.latestExpiringCertificate?.notAfter;\n if (currentDate == null || expiryTime == null) {\n return activeStatus;\n }\n\n const expiryDate = new Date(expiryTime);\n const daysUntilExpiry = (() => {\n const diff = expiryDate.getTime() - currentDate.getTime();\n if (diff < 0) {\n return -1;\n }\n\n return diff / (1000 * 60 * 60 * 24);\n })();\n\n if (daysUntilExpiry !== -1 && daysUntilExpiry <= 30) {\n return { status: \"Expiring\", daysUntilExpiry, expiryDate };\n }\n\n return activeStatus;\n }\n case \"Inactive\": {\n return { status: \"Inactive\" };\n }\n default:\n return unreachable(connection);\n }\n}\n\nfunction getIdentityProvider(connection: SsoConnection): IdentityProvider {\n switch (connection.type) {\n case \"AdfsSaml\":\n case \"EntraIdOidc\":\n return \"microsoft\";\n case \"Auth0Migration\":\n case \"Auth0Saml\":\n return \"auth0\";\n case \"AzureSaml\":\n return \"azure\";\n case \"CasSaml\":\n return \"cas\";\n case \"ClassLinkSaml\":\n return \"classlink\";\n case \"CloudflareSaml\":\n return \"cloudflare\";\n case \"CyberArkSaml\":\n return \"cyberark\";\n case \"DuoSaml\":\n return \"duo\";\n case \"GenericSaml\":\n return \"generic-saml\";\n case \"GoogleSaml\":\n case \"GoogleOidc\":\n return \"google\";\n case \"JumpCloudSaml\":\n return \"jumpcloud\";\n case \"KeycloakSaml\":\n return \"keycloak\";\n case \"LastPassSaml\":\n return \"lastpass\";\n case \"MiniOrangeSaml\":\n return \"miniorange\";\n case \"NetIqSaml\":\n return \"net-iq\";\n case \"OktaOidc\":\n case \"OktaSaml\":\n return \"okta\";\n case \"OneLoginSaml\":\n return \"onelogin\";\n case \"OracleSaml\":\n return \"oracle\";\n case \"PingFederateSaml\":\n case \"PingOneSaml\":\n return \"ping-identity\";\n case \"RipplingSaml\":\n return \"rippling\";\n case \"SalesforceSaml\":\n return \"salesforce\";\n case \"ShibbolethGenericSaml\":\n case \"ShibbolethSaml\":\n return \"shibboleth\";\n case \"SimpleSamlPhpSaml\":\n return \"simple-saml-php\";\n case \"TestIdp\":\n return \"test-idp\";\n case \"VmWareSaml\":\n return \"vmware\";\n case \"AdpOidc\":\n return \"adp\";\n case \"GenericOidc\":\n return \"generic-oidc\";\n case \"LoginGovOidc\":\n return \"login-gov\";\n case \"CleverOidc\":\n return \"clever\";\n default:\n return unreachable(connection);\n }\n}\n\nexport type {\n AdminPortalSsoConnectionProps,\n AdminPortalSsoConnectionLoadingProps,\n AdminPortalSsoConnectionErrorProps,\n};\nexport {\n AdminPortalSsoConnection,\n AdminPortalSsoConnectionLoading,\n AdminPortalSsoConnectionError,\n};\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/admin-portal-sso-connection.client.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport {\n AdminPortalOpenButton,\n AdminPortalSsoConnectionError,\n AdminPortalSsoConnectionLoading,\n AdminPortalSsoConnection as AdminPortalSsoConnectionPresentational,\n} from \"./lib/admin-portal-sso-connection.js\";\nimport type {\n AdminPortalSsoConnectionErrorProps,\n AdminPortalSsoConnectionLoadingProps,\n AdminPortalSsoConnectionStatusProps,\n} from \"./lib/admin-portal-sso-connection.js\";\nimport { ApiProvider, AuthToken, useApiReady } from \"./api/api-provider.js\";\nimport {\n type SsoConnection,\n useListSsoConnections,\n useGenerateAdminPortalLink,\n} from \"./api/endpoint.js\";\nimport { useWorkOsApiUrl } from \"./lib/widgets-context.js\";\nimport { ErrorBoundary } from \"./lib/error-boundary.js\";\nimport { unreachable, WidgetRootDomProps } from \"./lib/utils.js\";\nimport { IdentityProvider } from \"./lib/identity-providers.js\";\n\ninterface AdminPortalSsoConnectionProps extends WidgetRootDomProps {\n authToken: AuthToken;\n}\n\nconst AdminPortalSsoConnection: React.FC<AdminPortalSsoConnectionProps> = ({\n authToken,\n ...domProps\n}) => {\n const baseUrl = useWorkOsApiUrl();\n return (\n <ErrorBoundary\n fallbackRender={({ error }) => (\n <AdminPortalSsoConnectionError error={error} {...domProps} />\n )}\n >\n <ApiProvider\n widgetType=\"admin-portal-sso-connection\"\n authToken={authToken}\n baseUrl={baseUrl}\n >\n <AdminPortalSsoConnectionImpl {...domProps} />\n </ApiProvider>\n </ErrorBoundary>\n );\n};\n\nconst AdminPortalSsoConnectionImpl = (props: WidgetRootDomProps) => {\n const isApiReady = useApiReady();\n const [currentDate, setCurrentDate] = React.useState<Date | null>(() =>\n isApiReady ? new Date() : null,\n );\n if (isApiReady && currentDate === null) {\n setCurrentDate(new Date());\n }\n\n const { mutate: generateAdminPortalLink, isPending } =\n useGenerateAdminPortalLink({\n mutation: {\n onSuccess: (data) => {\n window.open(data.link, \"_blank\", \"noopener,noreferrer\");\n },\n },\n });\n\n const query = useListSsoConnections();\n\n const initConfig = () => {\n generateAdminPortalLink({\n params: {\n intent: \"sso\",\n },\n });\n };\n\n if (query.isLoading) {\n return <AdminPortalSsoConnectionLoading {...props} />;\n }\n\n if (query.isError) {\n return <AdminPortalSsoConnectionError error={query.error} {...props} />;\n }\n\n if (query.data) {\n const connection = query.data[0];\n if (!connection) {\n return (\n <ErrorBoundary\n fallbackRender={({ error }) => (\n <AdminPortalSsoConnectionError error={error} {...props} />\n )}\n >\n <AdminPortalSsoConnectionPresentational\n {...props}\n connectionStatus=\"NotConfigured\"\n currentDate={currentDate}\n lastSession={null}\n adminPortalOpenButton={\n <AdminPortalOpenButton\n isPending={isPending}\n initConfig={initConfig}\n />\n }\n />\n </ErrorBoundary>\n );\n }\n\n const connectionState = getConnectionState(connection, currentDate);\n const statusProps: AdminPortalSsoConnectionStatusProps = (() => {\n const connectionStatus = connectionState.status;\n if (!connection || connectionStatus === \"NotConfigured\") {\n return {\n connectionStatus: \"NotConfigured\",\n } satisfies AdminPortalSsoConnectionStatusProps;\n }\n\n const identityProvider = getIdentityProvider(connection);\n switch (connectionStatus) {\n case \"Active\":\n return {\n connectionStatus,\n identityProvider,\n } satisfies AdminPortalSsoConnectionStatusProps;\n case \"Inactive\":\n return {\n connectionStatus,\n identityProvider,\n } satisfies AdminPortalSsoConnectionStatusProps;\n case \"Expired\":\n case \"Expiring\":\n return {\n connectionStatus,\n expiryDate: connectionState.expiryDate,\n identityProvider,\n } satisfies AdminPortalSsoConnectionStatusProps;\n default:\n return unreachable(connectionState);\n }\n })();\n\n const lastSession = connection.lastSession\n ? new Date(connection.lastSession.createdAt)\n : null;\n\n return (\n <ErrorBoundary\n fallbackRender={({ error }) => (\n <AdminPortalSsoConnectionError error={error} {...props} />\n )}\n >\n <AdminPortalSsoConnectionPresentational\n {...props}\n {...statusProps}\n currentDate={currentDate}\n lastSession={lastSession}\n adminPortalOpenButton={\n <AdminPortalOpenButton\n isPending={isPending}\n initConfig={initConfig}\n />\n }\n />\n </ErrorBoundary>\n );\n }\n};\n\ntype ConnectionState =\n | { status: \"NotConfigured\" }\n | { status: \"Active\" }\n | { status: \"Inactive\" }\n | {\n status: \"Expiring\";\n daysUntilExpiry: number | null;\n expiryDate: Date | null;\n }\n | { status: \"Expired\"; expiryDate: Date | null };\n\nfunction getConnectionState(\n connection: SsoConnection,\n currentDate: Date | null,\n): ConnectionState {\n switch (connection.state) {\n case \"Active\":\n case \"Validating\":\n case \"Deleting\": {\n const activeStatus = { status: \"Active\" } satisfies ConnectionState;\n if (connection.providerTag !== \"Saml\") {\n return activeStatus;\n }\n\n if (connection.latestExpiredCertificate) {\n return {\n status: \"Expired\",\n expiryDate: connection.latestExpiredCertificate.notAfter\n ? new Date(connection.latestExpiredCertificate.notAfter)\n : null,\n };\n }\n\n const expiryTime = connection.latestExpiringCertificate?.notAfter;\n if (currentDate == null || expiryTime == null) {\n return activeStatus;\n }\n\n const expiryDate = new Date(expiryTime);\n const daysUntilExpiry = (() => {\n const diff = expiryDate.getTime() - currentDate.getTime();\n if (diff < 0) {\n return -1;\n }\n\n return diff / (1000 * 60 * 60 * 24);\n })();\n\n if (daysUntilExpiry !== -1 && daysUntilExpiry <= 30) {\n return { status: \"Expiring\", daysUntilExpiry, expiryDate };\n }\n\n return activeStatus;\n }\n case \"Inactive\": {\n return { status: \"Inactive\" };\n }\n default:\n return unreachable(connection.state);\n }\n}\n\nfunction getIdentityProvider(connection: SsoConnection): IdentityProvider {\n switch (connection.type) {\n case \"AdfsSaml\":\n case \"EntraIdOidc\":\n return \"microsoft\";\n case \"Auth0Migration\":\n case \"Auth0Saml\":\n return \"auth0\";\n case \"AzureSaml\":\n return \"azure\";\n case \"CasSaml\":\n return \"cas\";\n case \"ClassLinkSaml\":\n return \"classlink\";\n case \"CloudflareSaml\":\n return \"cloudflare\";\n case \"CyberArkSaml\":\n return \"cyberark\";\n case \"DuoSaml\":\n return \"duo\";\n case \"GenericSaml\":\n return \"generic-saml\";\n case \"GoogleSaml\":\n case \"GoogleOidc\":\n return \"google\";\n case \"JumpCloudSaml\":\n return \"jumpcloud\";\n case \"KeycloakSaml\":\n return \"keycloak\";\n case \"LastPassSaml\":\n return \"lastpass\";\n case \"MiniOrangeSaml\":\n return \"miniorange\";\n case \"NetIqSaml\":\n return \"net-iq\";\n case \"OktaOidc\":\n case \"OktaSaml\":\n return \"okta\";\n case \"OneLoginSaml\":\n return \"onelogin\";\n case \"OracleSaml\":\n return \"oracle\";\n case \"PingFederateSaml\":\n case \"PingOneSaml\":\n return \"ping-identity\";\n case \"RipplingSaml\":\n return \"rippling\";\n case \"SalesforceSaml\":\n return \"salesforce\";\n case \"ShibbolethGenericSaml\":\n case \"ShibbolethSaml\":\n return \"shibboleth\";\n case \"SimpleSamlPhpSaml\":\n return \"simple-saml-php\";\n case \"TestIdp\":\n return \"test-idp\";\n case \"VmWareSaml\":\n return \"vmware\";\n case \"AdpOidc\":\n return \"adp\";\n case \"GenericOidc\":\n return \"generic-oidc\";\n case \"LoginGovOidc\":\n return \"login-gov\";\n case \"CleverOidc\":\n return \"clever\";\n default:\n return unreachable(connection);\n }\n}\n\nexport type {\n AdminPortalSsoConnectionProps,\n AdminPortalSsoConnectionLoadingProps,\n AdminPortalSsoConnectionErrorProps,\n};\nexport {\n AdminPortalSsoConnection,\n AdminPortalSsoConnectionLoading,\n AdminPortalSsoConnectionError,\n};\n"],"mappings":"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","names":[]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import * as React from 'react';
|
|
3
3
|
|
|
4
|
-
type WidgetType = "admin-portal-domain-verification" | "user-management" | "organization-switcher" | "user-sessions" | "user-security" | "user-profile" | "admin-portal-sso-connection" | "api-keys" | "pipes";
|
|
4
|
+
type WidgetType = "admin-portal-domain-verification" | "user-management" | "organization-switcher" | "user-sessions" | "user-security" | "user-profile" | "admin-portal-sso-connection" | "api-keys" | "pipes" | "directory-sync";
|
|
5
5
|
type AuthToken = string | (() => Promise<string>);
|
|
6
6
|
interface ElevatedAccess {
|
|
7
7
|
token: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/api/api-provider.tsx"],"sourcesContent":["import { useQuery } from \"@tanstack/react-query\";\nimport * as React from \"react\";\nimport { useIsHydrated } from \"../lib/use-is-hydrated.js\";\nimport { getClaims } from \"./utils.js\";\n\nexport type WidgetType =\n | \"admin-portal-domain-verification\"\n | \"user-management\"\n | \"organization-switcher\"\n | \"user-sessions\"\n | \"user-security\"\n | \"user-profile\"\n | \"admin-portal-sso-connection\"\n | \"api-keys\"\n | \"pipes\";\n\nexport type AuthToken = string | (() => Promise<string>);\n\ninterface ElevatedAccess {\n token: string;\n expiresAt: string;\n}\n\ninterface ApiConfig {\n authToken: string | undefined;\n permissions: string[] | undefined;\n baseUrl: string;\n widgetType: WidgetType;\n elevatedAccess?: ElevatedAccess;\n setElevatedAccess: (elevatedAccess?: ElevatedAccess) => void;\n}\n\nconst ApiContext = React.createContext<ApiConfig | undefined>(undefined);\n\ninterface ApiProviderProps {\n authToken: AuthToken;\n baseUrl: string;\n children: React.ReactNode;\n widgetType: WidgetType;\n}\n\nexport const ApiProvider = ({\n authToken,\n baseUrl,\n children,\n widgetType,\n}: ApiProviderProps) => {\n const authTokenQuery = useQuery({\n initialData:\n typeof authToken === \"string\"\n ? {\n authToken,\n permissions: getClaims(authToken).permissions,\n }\n : undefined,\n queryFn: async () => {\n const resolvedToken =\n typeof authToken === \"string\" ? authToken : await authToken();\n\n return {\n authToken: resolvedToken,\n permissions: getClaims(resolvedToken).permissions,\n };\n },\n queryKey: [\"authToken\", widgetType],\n });\n\n const [elevatedAccess, setElevatedAccess] = React.useState<ElevatedAccess>();\n const elevatedAccessTimeout = React.useRef<number | undefined>(undefined);\n\n // This effect manages the expiration of elevated access tokens\n // When an elevated access token is present, it checks every 30 seconds if the token has expired\n // If the token has expired (current time > expiration time), it clears the elevated access\n React.useEffect(() => {\n if (elevatedAccessTimeout.current) {\n window.clearInterval(elevatedAccessTimeout.current);\n }\n\n if (elevatedAccess) {\n elevatedAccessTimeout.current = window.setInterval(() => {\n const now = new Date();\n const expiresAtDate = new Date(elevatedAccess.expiresAt);\n\n // Reset the elevated access if it has expired\n if (now > expiresAtDate) {\n setElevatedAccess(undefined);\n }\n }, 30_000); // every 30 seconds\n }\n\n return () => {\n if (elevatedAccessTimeout.current) {\n window.clearInterval(elevatedAccessTimeout.current);\n }\n };\n }, [elevatedAccess]);\n\n const value = React.useMemo(\n () => ({\n authToken: authTokenQuery.data?.authToken,\n permissions: authTokenQuery.data?.permissions,\n baseUrl,\n elevatedAccess,\n setElevatedAccess,\n widgetType,\n }),\n [\n authTokenQuery.data,\n baseUrl,\n elevatedAccess,\n setElevatedAccess,\n widgetType,\n ],\n );\n\n return <ApiContext.Provider value={value}>{children}</ApiContext.Provider>;\n};\n\nexport const useApi = () => {\n const context = React.useContext(ApiContext);\n\n if (context === undefined) {\n throw new Error(\"useApi must be used within an ApiProvider\");\n }\n\n return context;\n};\n\nexport const useElevatedAccessToken = () => {\n const { elevatedAccess, setElevatedAccess } = useApi();\n\n return { elevatedAccess, setElevatedAccess };\n};\n\nexport const useApiReady = () => {\n const { authToken } = useApi();\n const isHydrated = useIsHydrated();\n\n return isHydrated && authToken !== undefined;\n};\n"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../../../src/api/api-provider.tsx"],"sourcesContent":["import { useQuery } from \"@tanstack/react-query\";\nimport * as React from \"react\";\nimport { useIsHydrated } from \"../lib/use-is-hydrated.js\";\nimport { getClaims } from \"./utils.js\";\n\nexport type WidgetType =\n | \"admin-portal-domain-verification\"\n | \"user-management\"\n | \"organization-switcher\"\n | \"user-sessions\"\n | \"user-security\"\n | \"user-profile\"\n | \"admin-portal-sso-connection\"\n | \"api-keys\"\n | \"pipes\"\n | \"directory-sync\";\n\nexport type AuthToken = string | (() => Promise<string>);\n\ninterface ElevatedAccess {\n token: string;\n expiresAt: string;\n}\n\ninterface ApiConfig {\n authToken: string | undefined;\n permissions: string[] | undefined;\n baseUrl: string;\n widgetType: WidgetType;\n elevatedAccess?: ElevatedAccess;\n setElevatedAccess: (elevatedAccess?: ElevatedAccess) => void;\n}\n\nconst ApiContext = React.createContext<ApiConfig | undefined>(undefined);\n\ninterface ApiProviderProps {\n authToken: AuthToken;\n baseUrl: string;\n children: React.ReactNode;\n widgetType: WidgetType;\n}\n\nexport const ApiProvider = ({\n authToken,\n baseUrl,\n children,\n widgetType,\n}: ApiProviderProps) => {\n const authTokenQuery = useQuery({\n initialData:\n typeof authToken === \"string\"\n ? {\n authToken,\n permissions: getClaims(authToken).permissions,\n }\n : undefined,\n queryFn: async () => {\n const resolvedToken =\n typeof authToken === \"string\" ? authToken : await authToken();\n\n return {\n authToken: resolvedToken,\n permissions: getClaims(resolvedToken).permissions,\n };\n },\n queryKey: [\"authToken\", widgetType],\n });\n\n const [elevatedAccess, setElevatedAccess] = React.useState<ElevatedAccess>();\n const elevatedAccessTimeout = React.useRef<number | undefined>(undefined);\n\n // This effect manages the expiration of elevated access tokens\n // When an elevated access token is present, it checks every 30 seconds if the token has expired\n // If the token has expired (current time > expiration time), it clears the elevated access\n React.useEffect(() => {\n if (elevatedAccessTimeout.current) {\n window.clearInterval(elevatedAccessTimeout.current);\n }\n\n if (elevatedAccess) {\n elevatedAccessTimeout.current = window.setInterval(() => {\n const now = new Date();\n const expiresAtDate = new Date(elevatedAccess.expiresAt);\n\n // Reset the elevated access if it has expired\n if (now > expiresAtDate) {\n setElevatedAccess(undefined);\n }\n }, 30_000); // every 30 seconds\n }\n\n return () => {\n if (elevatedAccessTimeout.current) {\n window.clearInterval(elevatedAccessTimeout.current);\n }\n };\n }, [elevatedAccess]);\n\n const value = React.useMemo(\n () => ({\n authToken: authTokenQuery.data?.authToken,\n permissions: authTokenQuery.data?.permissions,\n baseUrl,\n elevatedAccess,\n setElevatedAccess,\n widgetType,\n }),\n [\n authTokenQuery.data,\n baseUrl,\n elevatedAccess,\n setElevatedAccess,\n widgetType,\n ],\n );\n\n return <ApiContext.Provider value={value}>{children}</ApiContext.Provider>;\n};\n\nexport const useApi = () => {\n const context = React.useContext(ApiContext);\n\n if (context === undefined) {\n throw new Error(\"useApi must be used within an ApiProvider\");\n }\n\n return context;\n};\n\nexport const useElevatedAccessToken = () => {\n const { elevatedAccess, setElevatedAccess } = useApi();\n\n return { elevatedAccess, setElevatedAccess };\n};\n\nexport const useApiReady = () => {\n const { authToken } = useApi();\n const isHydrated = useIsHydrated();\n\n return isHydrated && authToken !== undefined;\n};\n"],"mappings":"AAoHS;AApHT,SAAS,gBAAgB;AACzB,YAAY,WAAW;AACvB,SAAS,qBAAqB;AAC9B,SAAS,iBAAiB;AA8B1B,MAAM,aAAa,MAAM,cAAqC,MAAS;AAShE,MAAM,cAAc,CAAC;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAAwB;AACtB,QAAM,iBAAiB,SAAS;AAAA,IAC9B,aACE,OAAO,cAAc,WACjB;AAAA,MACE;AAAA,MACA,aAAa,UAAU,SAAS,EAAE;AAAA,IACpC,IACA;AAAA,IACN,SAAS,YAAY;AACnB,YAAM,gBACJ,OAAO,cAAc,WAAW,YAAY,MAAM,UAAU;AAE9D,aAAO;AAAA,QACL,WAAW;AAAA,QACX,aAAa,UAAU,aAAa,EAAE;AAAA,MACxC;AAAA,IACF;AAAA,IACA,UAAU,CAAC,aAAa,UAAU;AAAA,EACpC,CAAC;AAED,QAAM,CAAC,gBAAgB,iBAAiB,IAAI,MAAM,SAAyB;AAC3E,QAAM,wBAAwB,MAAM,OAA2B,MAAS;AAKxE,QAAM,UAAU,MAAM;AACpB,QAAI,sBAAsB,SAAS;AACjC,aAAO,cAAc,sBAAsB,OAAO;AAAA,IACpD;AAEA,QAAI,gBAAgB;AAClB,4BAAsB,UAAU,OAAO,YAAY,MAAM;AACvD,cAAM,MAAM,oBAAI,KAAK;AACrB,cAAM,gBAAgB,IAAI,KAAK,eAAe,SAAS;AAGvD,YAAI,MAAM,eAAe;AACvB,4BAAkB,MAAS;AAAA,QAC7B;AAAA,MACF,GAAG,GAAM;AAAA,IACX;AAEA,WAAO,MAAM;AACX,UAAI,sBAAsB,SAAS;AACjC,eAAO,cAAc,sBAAsB,OAAO;AAAA,MACpD;AAAA,IACF;AAAA,EACF,GAAG,CAAC,cAAc,CAAC;AAEnB,QAAM,QAAQ,MAAM;AAAA,IAClB,OAAO;AAAA,MACL,WAAW,eAAe,MAAM;AAAA,MAChC,aAAa,eAAe,MAAM;AAAA,MAClC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA;AAAA,MACE,eAAe;AAAA,MACf;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,SAAO,oBAAC,WAAW,UAAX,EAAoB,OAAe,UAAS;AACtD;AAEO,MAAM,SAAS,MAAM;AAC1B,QAAM,UAAU,MAAM,WAAW,UAAU;AAE3C,MAAI,YAAY,QAAW;AACzB,UAAM,IAAI,MAAM,2CAA2C;AAAA,EAC7D;AAEA,SAAO;AACT;AAEO,MAAM,yBAAyB,MAAM;AAC1C,QAAM,EAAE,gBAAgB,kBAAkB,IAAI,OAAO;AAErD,SAAO,EAAE,gBAAgB,kBAAkB;AAC7C;AAEO,MAAM,cAAc,MAAM;AAC/B,QAAM,EAAE,UAAU,IAAI,OAAO;AAC7B,QAAM,aAAa,cAAc;AAEjC,SAAO,cAAc,cAAc;AACrC;","names":[]}
|