@workos-inc/widgets 1.20.2-next.1792700156145 → 1.20.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +4 -10
- package/dist/cjs/admin-portal-audit-log-streaming.client.cjs +2 -1
- package/dist/cjs/admin-portal-audit-log-streaming.client.cjs.map +1 -1
- package/dist/cjs/admin-portal-domain-verification.client.cjs +3 -2
- package/dist/cjs/admin-portal-domain-verification.client.cjs.map +1 -1
- package/dist/cjs/admin-portal-sso-connection.client.cjs +2 -1
- package/dist/cjs/admin-portal-sso-connection.client.cjs.map +1 -1
- package/dist/cjs/api/api-provider.cjs +23 -1
- package/dist/cjs/api/api-provider.cjs.map +1 -1
- package/dist/cjs/api/api-provider.d.cts.map +1 -1
- package/dist/cjs/api/claims.cjs.map +1 -1
- package/dist/cjs/api/claims.d.cts +2 -1
- package/dist/cjs/api/claims.d.cts.map +1 -1
- package/dist/cjs/api/client-graphql/client.cjs +3 -2
- package/dist/cjs/api/client-graphql/client.cjs.map +1 -1
- package/dist/cjs/api/client-graphql/hooks.cjs +3 -20
- package/dist/cjs/api/client-graphql/hooks.cjs.map +1 -1
- package/dist/cjs/api/client-graphql/hooks.d.cts +3 -12
- package/dist/cjs/api/client-graphql/hooks.d.cts.map +1 -1
- package/dist/cjs/api/client-graphql/query-keys.cjs +25 -0
- package/dist/cjs/api/client-graphql/query-keys.cjs.map +1 -0
- package/dist/cjs/api/client-graphql/query-keys.d.cts +16 -0
- package/dist/cjs/api/client-graphql/query-keys.d.cts.map +1 -0
- package/dist/cjs/components/copy-text.cjs +1 -1
- package/dist/cjs/components/copy-text.cjs.map +1 -1
- package/dist/cjs/components/form.cjs +9 -13
- package/dist/cjs/components/form.cjs.map +1 -1
- package/dist/cjs/components/form.d.cts.map +1 -1
- package/dist/cjs/components/otp-input.cjs +1 -0
- package/dist/cjs/components/otp-input.cjs.map +1 -1
- package/dist/cjs/directory-sync.client.cjs +2 -1
- package/dist/cjs/directory-sync.client.cjs.map +1 -1
- package/dist/cjs/lib/api/api-key.cjs +4 -3
- package/dist/cjs/lib/api/api-key.cjs.map +1 -1
- package/dist/cjs/lib/api/me.cjs +2 -1
- package/dist/cjs/lib/api/me.cjs.map +1 -1
- package/dist/cjs/lib/api/pipes.cjs +7 -6
- package/dist/cjs/lib/api/pipes.cjs.map +1 -1
- package/dist/cjs/lib/api/user-api-key.cjs +3 -2
- package/dist/cjs/lib/api/user-api-key.cjs.map +1 -1
- package/dist/cjs/lib/i18n/intl-context.cjs.map +1 -1
- package/dist/cjs/lib/i18n/intl-context.d.cts +1 -0
- package/dist/cjs/lib/i18n/intl-context.d.cts.map +1 -1
- package/dist/cjs/lib/i18n/use-translation.cjs +2 -2
- package/dist/cjs/lib/i18n/use-translation.cjs.map +1 -1
- package/dist/cjs/lib/use-composed-event-handlers.cjs +15 -0
- package/dist/cjs/lib/use-composed-event-handlers.cjs.map +1 -0
- package/dist/cjs/lib/use-composed-event-handlers.d.cts +6 -0
- package/dist/cjs/lib/use-composed-event-handlers.d.cts.map +1 -0
- package/dist/cjs/lib/use-debounce.cjs +124 -116
- package/dist/cjs/lib/use-debounce.cjs.map +1 -1
- package/dist/cjs/lib/use-debounce.d.cts +53 -48
- package/dist/cjs/lib/use-debounce.d.cts.map +1 -1
- package/dist/cjs/lib/use-widgets-invalidator.cjs +3 -3
- package/dist/cjs/lib/use-widgets-invalidator.cjs.map +1 -1
- package/dist/cjs/lib/use-widgets-invalidator.d.cts.map +1 -1
- package/dist/cjs/lib/utils.cjs +0 -7
- package/dist/cjs/lib/utils.cjs.map +1 -1
- package/dist/cjs/lib/utils.d.cts +0 -3
- package/dist/cjs/lib/utils.d.cts.map +1 -1
- package/dist/cjs/organization-switcher.client.cjs +2 -1
- package/dist/cjs/organization-switcher.client.cjs.map +1 -1
- package/dist/cjs/pipes-admin.client.cjs +2 -1
- package/dist/cjs/pipes-admin.client.cjs.map +1 -1
- package/dist/cjs/pipes.client.cjs +2 -1
- package/dist/cjs/pipes.client.cjs.map +1 -1
- package/dist/cjs/user-security.client.cjs +2 -1
- package/dist/cjs/user-security.client.cjs.map +1 -1
- package/dist/cjs/user-sessions.client.cjs +2 -1
- package/dist/cjs/user-sessions.client.cjs.map +1 -1
- package/dist/cjs/widgets/api-keys/api-keys-search.cjs +1 -1
- package/dist/cjs/widgets/api-keys/api-keys-search.cjs.map +1 -1
- package/dist/cjs/widgets/api-keys/user-api-keys-search.cjs +1 -1
- package/dist/cjs/widgets/api-keys/user-api-keys-search.cjs.map +1 -1
- package/dist/cjs/widgets/organization-switcher/organization-switcher.cjs +19 -5
- package/dist/cjs/widgets/organization-switcher/organization-switcher.cjs.map +1 -1
- package/dist/cjs/widgets/organization-switcher/organization-switcher.d.cts +2 -1
- package/dist/cjs/widgets/organization-switcher/organization-switcher.d.cts.map +1 -1
- package/dist/cjs/widgets/pipes/pipes.cjs +3 -2
- package/dist/cjs/widgets/pipes/pipes.cjs.map +1 -1
- package/dist/cjs/widgets/user-sessions/logout-all-sessions-dialog.cjs +2 -1
- package/dist/cjs/widgets/user-sessions/logout-all-sessions-dialog.cjs.map +1 -1
- package/dist/cjs/widgets/user-sessions/logout-dialog.cjs +2 -1
- package/dist/cjs/widgets/user-sessions/logout-dialog.cjs.map +1 -1
- package/dist/cjs/widgets/users-management/invite-user-dialog.cjs +5 -6
- package/dist/cjs/widgets/users-management/invite-user-dialog.cjs.map +1 -1
- package/dist/cjs/widgets/users-management/users-management-utils.cjs +4 -3
- package/dist/cjs/widgets/users-management/users-management-utils.cjs.map +1 -1
- package/dist/cjs/widgets/users-management/users-management.cjs.map +1 -1
- package/dist/cjs/widgets/users-management/users-search.cjs +1 -1
- package/dist/cjs/widgets/users-management/users-search.cjs.map +1 -1
- package/dist/esm/admin-portal-audit-log-streaming.client.js +2 -1
- package/dist/esm/admin-portal-audit-log-streaming.client.js.map +1 -1
- package/dist/esm/admin-portal-domain-verification.client.js +2 -1
- package/dist/esm/admin-portal-domain-verification.client.js.map +1 -1
- package/dist/esm/admin-portal-sso-connection.client.js +2 -1
- package/dist/esm/admin-portal-sso-connection.client.js.map +1 -1
- package/dist/esm/api/api-provider.d.ts.map +1 -1
- package/dist/esm/api/api-provider.js +23 -1
- package/dist/esm/api/api-provider.js.map +1 -1
- package/dist/esm/api/claims.d.ts +2 -1
- package/dist/esm/api/claims.d.ts.map +1 -1
- package/dist/esm/api/claims.js.map +1 -1
- package/dist/esm/api/client-graphql/client.js +3 -2
- package/dist/esm/api/client-graphql/client.js.map +1 -1
- package/dist/esm/api/client-graphql/hooks.d.ts +3 -12
- package/dist/esm/api/client-graphql/hooks.d.ts.map +1 -1
- package/dist/esm/api/client-graphql/hooks.js +1 -18
- package/dist/esm/api/client-graphql/hooks.js.map +1 -1
- package/dist/esm/api/client-graphql/query-keys.d.ts +16 -0
- package/dist/esm/api/client-graphql/query-keys.d.ts.map +1 -0
- package/dist/esm/api/client-graphql/query-keys.js +23 -0
- package/dist/esm/api/client-graphql/query-keys.js.map +1 -0
- package/dist/esm/components/copy-text.js +1 -1
- package/dist/esm/components/copy-text.js.map +1 -1
- package/dist/esm/components/form.d.ts.map +1 -1
- package/dist/esm/components/form.js +9 -13
- package/dist/esm/components/form.js.map +1 -1
- package/dist/esm/components/otp-input.js +1 -0
- package/dist/esm/components/otp-input.js.map +1 -1
- package/dist/esm/directory-sync.client.js +2 -1
- package/dist/esm/directory-sync.client.js.map +1 -1
- package/dist/esm/lib/api/api-key.js +2 -1
- package/dist/esm/lib/api/api-key.js.map +1 -1
- package/dist/esm/lib/api/me.js +2 -1
- package/dist/esm/lib/api/me.js.map +1 -1
- package/dist/esm/lib/api/pipes.js +2 -1
- package/dist/esm/lib/api/pipes.js.map +1 -1
- package/dist/esm/lib/api/user-api-key.js +2 -1
- package/dist/esm/lib/api/user-api-key.js.map +1 -1
- package/dist/esm/lib/i18n/intl-context.d.ts +1 -0
- package/dist/esm/lib/i18n/intl-context.d.ts.map +1 -1
- package/dist/esm/lib/i18n/intl-context.js.map +1 -1
- package/dist/esm/lib/i18n/use-translation.js +2 -2
- package/dist/esm/lib/i18n/use-translation.js.map +1 -1
- package/dist/esm/lib/use-composed-event-handlers.d.ts +6 -0
- package/dist/esm/lib/use-composed-event-handlers.d.ts.map +1 -0
- package/dist/esm/lib/use-composed-event-handlers.js +12 -0
- package/dist/esm/lib/use-composed-event-handlers.js.map +1 -0
- package/dist/esm/lib/use-debounce.d.ts +53 -48
- package/dist/esm/lib/use-debounce.d.ts.map +1 -1
- package/dist/esm/lib/use-debounce.js +124 -116
- package/dist/esm/lib/use-debounce.js.map +1 -1
- package/dist/esm/lib/use-widgets-invalidator.d.ts.map +1 -1
- package/dist/esm/lib/use-widgets-invalidator.js +2 -2
- package/dist/esm/lib/use-widgets-invalidator.js.map +1 -1
- package/dist/esm/lib/utils.d.ts +0 -3
- package/dist/esm/lib/utils.d.ts.map +1 -1
- package/dist/esm/lib/utils.js +1 -7
- package/dist/esm/lib/utils.js.map +1 -1
- package/dist/esm/organization-switcher.client.js +2 -1
- package/dist/esm/organization-switcher.client.js.map +1 -1
- package/dist/esm/pipes-admin.client.js +2 -1
- package/dist/esm/pipes-admin.client.js.map +1 -1
- package/dist/esm/pipes.client.js +2 -1
- package/dist/esm/pipes.client.js.map +1 -1
- package/dist/esm/user-security.client.js +2 -1
- package/dist/esm/user-security.client.js.map +1 -1
- package/dist/esm/user-sessions.client.js +2 -1
- package/dist/esm/user-sessions.client.js.map +1 -1
- package/dist/esm/widgets/api-keys/api-keys-search.js +1 -1
- package/dist/esm/widgets/api-keys/api-keys-search.js.map +1 -1
- package/dist/esm/widgets/api-keys/user-api-keys-search.js +1 -1
- package/dist/esm/widgets/api-keys/user-api-keys-search.js.map +1 -1
- package/dist/esm/widgets/organization-switcher/organization-switcher.d.ts +2 -1
- package/dist/esm/widgets/organization-switcher/organization-switcher.d.ts.map +1 -1
- package/dist/esm/widgets/organization-switcher/organization-switcher.js +19 -5
- package/dist/esm/widgets/organization-switcher/organization-switcher.js.map +1 -1
- package/dist/esm/widgets/pipes/pipes.js +2 -1
- package/dist/esm/widgets/pipes/pipes.js.map +1 -1
- package/dist/esm/widgets/user-sessions/logout-all-sessions-dialog.js +2 -1
- package/dist/esm/widgets/user-sessions/logout-all-sessions-dialog.js.map +1 -1
- package/dist/esm/widgets/user-sessions/logout-dialog.js +2 -1
- package/dist/esm/widgets/user-sessions/logout-dialog.js.map +1 -1
- package/dist/esm/widgets/users-management/invite-user-dialog.js +5 -6
- package/dist/esm/widgets/users-management/invite-user-dialog.js.map +1 -1
- package/dist/esm/widgets/users-management/users-management-utils.js +2 -1
- package/dist/esm/widgets/users-management/users-management-utils.js.map +1 -1
- package/dist/esm/widgets/users-management/users-management.js.map +1 -1
- package/dist/esm/widgets/users-management/users-search.js +1 -1
- package/dist/esm/widgets/users-management/users-search.js.map +1 -1
- package/package.json +1 -1
- package/src/api/api-provider.tsx +39 -1
- package/src/api/claims.ts +2 -1
- package/src/api/client-graphql/client.ts +8 -2
- package/src/api/client-graphql/hooks.ts +8 -27
- package/src/api/client-graphql/query-keys.ts +29 -0
- package/src/components/copy-text.tsx +1 -1
- package/src/components/form.tsx +33 -29
- package/src/components/otp-input.tsx +2 -0
- package/src/lib/i18n/intl-context.tsx +4 -0
- package/src/lib/i18n/use-translation.ts +1 -4
- package/src/lib/use-composed-event-handlers.ts +25 -0
- package/src/lib/use-debounce.ts +289 -237
- package/src/lib/use-widgets-invalidator.ts +0 -4
- package/src/lib/utils.ts +0 -12
- package/src/widgets/api-keys/api-keys-search.tsx +6 -3
- package/src/widgets/api-keys/user-api-keys-search.tsx +6 -3
- package/src/widgets/organization-switcher/organization-switcher.tsx +32 -8
- package/src/widgets/users-management/invite-user-dialog.tsx +9 -11
- package/src/widgets/users-management/users-management.tsx +1 -1
- package/src/widgets/users-management/users-search.tsx +6 -3
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_api_client_graphql_query_keys = require("../../api/client-graphql/query-keys.cjs");
|
|
2
3
|
const require_api_client_graphql_hooks = require("../../api/client-graphql/hooks.cjs");
|
|
3
4
|
let _tanstack_react_query = require("@tanstack/react-query");
|
|
4
5
|
let react = require("react");
|
|
@@ -311,19 +312,19 @@ async function listAllConfigurableDataProviders(sdk) {
|
|
|
311
312
|
return configurableDataProviders;
|
|
312
313
|
});
|
|
313
314
|
}
|
|
314
|
-
const sharedDataConnectionsQueryKey =
|
|
315
|
-
const dataIntegrationConfigurationsQueryKey =
|
|
316
|
-
const myDataIntegrationsQueryKeys = [
|
|
317
|
-
const organizationDataIntegrationsQueryKey =
|
|
315
|
+
const sharedDataConnectionsQueryKey = require_api_client_graphql_query_keys.clientGraphqlQueryKey("ListSharedDataProviders");
|
|
316
|
+
const dataIntegrationConfigurationsQueryKey = require_api_client_graphql_query_keys.clientGraphqlQueryKey("ListConfigurableDataProviders");
|
|
317
|
+
const myDataIntegrationsQueryKeys = [require_api_client_graphql_query_keys.clientGraphqlQueryKey("ListDataProviders"), require_api_client_graphql_query_keys.clientGraphqlQueryKey("ListDataProviderConnections")];
|
|
318
|
+
const organizationDataIntegrationsQueryKey = require_api_client_graphql_query_keys.clientGraphqlQueryKey("ListOrganizationDataProviders");
|
|
318
319
|
/** The member's connectable providers joined with their own connections. */
|
|
319
320
|
function useMyDataIntegrations({ enabled = true } = {}) {
|
|
320
321
|
const providers = require_api_client_graphql_hooks.useClientGraphqlQuery({
|
|
321
|
-
queryKey:
|
|
322
|
+
queryKey: require_api_client_graphql_query_keys.clientGraphqlQueryKey("ListDataProviders"),
|
|
322
323
|
queryFn: listAllDataProviders,
|
|
323
324
|
enabled
|
|
324
325
|
});
|
|
325
326
|
const connections = require_api_client_graphql_hooks.useClientGraphqlQuery({
|
|
326
|
-
queryKey:
|
|
327
|
+
queryKey: require_api_client_graphql_query_keys.clientGraphqlQueryKey("ListDataProviderConnections"),
|
|
327
328
|
queryFn: listAllDataProviderConnections,
|
|
328
329
|
enabled
|
|
329
330
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pipes.cjs","names":["clientGraphqlQueryKey","useClientGraphqlQuery","useQueryClient","useCallback"],"sources":["../../../../src/lib/api/pipes.ts"],"sourcesContent":["import { useQueryClient } from \"@tanstack/react-query\";\nimport { useCallback } from \"react\";\nimport type {\n ConfigurableDataProviderFieldsFragment,\n DataProviderConfigFieldFieldsFragment,\n DataProviderConnectionFieldsFragment,\n DataProviderFieldsFragment,\n OrganizationDataProviderFieldsFragment,\n Sdk,\n SharedDataProviderFieldsFragment,\n} from \"../../api/client-graphql/generated.js\";\nimport {\n clientGraphqlQueryKey,\n useClientGraphqlQuery,\n} from \"../../api/client-graphql/hooks.js\";\nimport type {\n DataInstallation,\n DataIntegrationConfigField,\n DataIntegrationConfiguration,\n DataIntegrationCredentials,\n DataIntegrationWithConnections,\n OrganizationDataIntegration,\n SharedConnection,\n SharedDataConnection,\n} from \"./types.js\";\n\nconst PAGE_SIZE = 100;\n\n/*\n * The widgets render the REST-shaped DTOs in `./types.ts`, which double as the\n * public shape a host's `filter` predicate sees. What the multiple-connections\n * capabilities add is carried on these local extensions instead, so the\n * public types don't change.\n */\n\ntype AuthMethod = NonNullable<\n DataIntegrationWithConnections[\"authMethods\"]\n>[number];\n\n/** Advisory repair actions on one exact organization-owned connection. */\nexport interface ConnectionCapabilities {\n canReauthorize: boolean;\n canUpdateCredentials: boolean;\n}\n\n/**\n * Whether the owner can add another connection to a provider right now, and\n * with which methods. Advisory: the server rechecks the cap when creating.\n */\nexport interface AddConnectionCapabilities {\n canAddConnection: boolean;\n /** Empty exactly when `canAddConnection` is false. */\n addConnectionMethods: AuthMethod[];\n}\n\n/**\n * A connection with its row-level capabilities: set for organization-owned\n * connections, null for a member's own (whose actions follow from its state).\n */\nexport type ConnectionWithCapabilities = DataInstallation & {\n capabilities: ConnectionCapabilities | null;\n};\n\n// The connection fields are replaced rather than intersected: an intersection\n// of two array types doesn't narrow the element type array methods see.\n\n/** A member's provider, its connections and whether they can add another. */\nexport type DataIntegrationWithCapabilities = Omit<\n DataIntegrationWithConnections,\n \"installation\" | \"connected_accounts\"\n> & {\n installation?: ConnectionWithCapabilities | null;\n connected_accounts: ConnectionWithCapabilities[];\n capabilities: AddConnectionCapabilities;\n};\n\n/** An organization-owned provider, with add and per-connection capabilities. */\nexport type OrganizationDataIntegrationWithCapabilities = Omit<\n OrganizationDataIntegration,\n \"installation\" | \"connected_accounts\" | \"capabilities\"\n> & {\n installation?: ConnectionWithCapabilities | null;\n connected_accounts: ConnectionWithCapabilities[];\n capabilities: OrganizationDataIntegration[\"capabilities\"] &\n AddConnectionCapabilities;\n};\n\n/**\n * The Pipes list queries default to `limit: 10` and the widgets render every\n * row, so each list is walked to its end before it is adapted.\n */\nasync function listAllPages<T>(\n fetchPage: (after: string | null) => Promise<{\n data: T[];\n listMetadata: { after?: string | null };\n }>,\n): Promise<T[]> {\n const rows: T[] = [];\n let after: string | null = null;\n do {\n const page = await fetchPage(after);\n rows.push(...page.data);\n after = page.listMetadata.after ?? null;\n } while (after !== null);\n return rows;\n}\n\nfunction isOneOf<const T extends readonly string[]>(\n values: T,\n value: string,\n): value is T[number] {\n return values.includes(value);\n}\n\nconst AUTH_METHODS = [\"oauth\", \"api_key\", \"client_credentials\"] as const;\nconst CONNECTION_STATES = [\"connected\", \"needs_reauthorization\"] as const;\nconst AVAILABILITIES = [\"available\", \"needs_admin_attention\"] as const;\nconst CREDENTIALS_TYPES = [\"shared\", \"custom\", \"organization\"] as const;\nconst DISABLED_SOURCES = [\"developer\", \"organization\"] as const;\nconst CONFIG_FIELD_SCOPES = [\"integration\", \"installation\"] as const;\n\nfunction toAuthMethods(\n authMethods: readonly string[],\n): NonNullable<DataIntegrationWithConnections[\"authMethods\"]> {\n return authMethods.filter((method) => isOneOf(AUTH_METHODS, method));\n}\n\n/**\n * The GraphQL types carry these as plain strings; the REST DTOs the widgets\n * render from narrow them. Unknown values fall back to the option that\n * renders the least capable state.\n */\nfunction toCredentialsType(\n credentialsType: string,\n): DataIntegrationWithConnections[\"credentialsType\"] {\n return isOneOf(CREDENTIALS_TYPES, credentialsType)\n ? credentialsType\n : \"shared\";\n}\n\nfunction toConnectionState(state: string): DataInstallation[\"state\"] {\n return isOneOf(CONNECTION_STATES, state) ? state : \"needs_reauthorization\";\n}\n\nfunction toConfig(\n entries: readonly { name: string; value: string }[],\n): Record<string, string> {\n return Object.fromEntries(entries.map(({ name, value }) => [name, value]));\n}\n\nfunction toConfigField(\n field: DataProviderConfigFieldFieldsFragment,\n): DataIntegrationConfigField {\n return {\n key: field.key,\n label: field.label,\n required: field.required,\n scope: isOneOf(CONFIG_FIELD_SCOPES, field.scope)\n ? field.scope\n : \"integration\",\n description: field.description ?? undefined,\n example: field.example ?? undefined,\n pattern: field.pattern ?? undefined,\n patternFlags: field.patternFlags ?? undefined,\n order: field.order ?? undefined,\n secret: field.secret ?? undefined,\n default: field.default ?? undefined,\n };\n}\n\nfunction toIconFields(provider: {\n iconSlug?: string | null;\n iconUrl?: string | null;\n iconDarkUrl?: string | null;\n}): Pick<\n DataIntegrationWithConnections,\n \"iconSlug\" | \"iconUrl\" | \"iconDarkUrl\"\n> {\n return {\n iconSlug: provider.iconSlug ?? undefined,\n iconUrl: provider.iconUrl ?? undefined,\n iconDarkUrl: provider.iconDarkUrl ?? undefined,\n };\n}\n\n/**\n * Oldest first: by creation time, then id (ULIDs also sort by time). This is\n * the order the API already uses for organization connections; the member\n * list defaults to newest first, so both are sorted here rather than relying\n * on either endpoint's default.\n */\nfunction byCreation(a: DataInstallation, b: DataInstallation): number {\n return (\n Date.parse(a.created_at) - Date.parse(b.created_at) ||\n a.id.localeCompare(b.id)\n );\n}\n\nfunction toAddConnectionCapabilities(capabilities: {\n canAddConnection: boolean;\n addConnectionMethods: readonly string[];\n}): AddConnectionCapabilities {\n const addConnectionMethods = toAuthMethods(capabilities.addConnectionMethods);\n return {\n // Keep the pair consistent even if an unknown method was filtered out.\n canAddConnection:\n capabilities.canAddConnection && addConnectionMethods.length > 0,\n addConnectionMethods,\n };\n}\n\nfunction toDataInstallation(\n connection: DataProviderConnectionFieldsFragment,\n): ConnectionWithCapabilities {\n return {\n capabilities: connection.capabilities\n ? {\n canReauthorize: connection.capabilities.canReauthorize,\n canUpdateCredentials: connection.capabilities.canUpdateCredentials,\n }\n : null,\n object: \"data_installation\",\n id: connection.id,\n connection_role:\n connection.connectionRole === \"Standard\" ? \"standard\" : \"compatibility\",\n account_identifier: connection.accountIdentifier ?? null,\n account_display_name: connection.accountDisplayName ?? null,\n user_id: connection.userId ?? null,\n organization_id: connection.organizationId ?? null,\n scopes: connection.scopes,\n auth_method: isOneOf(AUTH_METHODS, connection.authMethod)\n ? connection.authMethod\n : \"oauth\",\n api_key_last_4: connection.apiKeyLast4 ?? null,\n client_id: connection.clientId ?? null,\n client_secret_last_4: connection.clientSecretLast4 ?? null,\n config: toConfig(connection.config),\n state: toConnectionState(connection.state),\n created_at: connection.createdAt,\n updated_at: connection.updatedAt,\n };\n}\n\n/**\n * Joins the member's providers with their own connections the way\n * `GET /_widgets/DataIntegrations/mine` did: every connection, oldest first,\n * in `connected_accounts`, and the compatibility connection inline as\n * `installation` — the single connection the unsectioned widget and a host's\n * `filter` see. With the compatibility slot empty, `installation` is null and\n * the provider reads as not connected there, as it does to every other\n * single-connection client.\n */\nfunction toMyDataIntegrations(\n providers: readonly DataProviderFieldsFragment[],\n connections: readonly DataProviderConnectionFieldsFragment[],\n): DataIntegrationWithCapabilities[] {\n const connectionsByProviderId = new Map<\n string,\n ConnectionWithCapabilities[]\n >();\n for (const connection of connections) {\n const installations =\n connectionsByProviderId.get(connection.dataProviderId) ?? [];\n installations.push(toDataInstallation(connection));\n connectionsByProviderId.set(connection.dataProviderId, installations);\n }\n\n return providers.map((provider) => {\n const installations = (connectionsByProviderId.get(provider.id) ?? []).sort(\n byCreation,\n );\n return {\n object: \"data_integration\",\n id: provider.id,\n name: provider.name,\n description: provider.description,\n slug: provider.slug,\n integrationType: provider.integrationType,\n ownership: \"userland_user\",\n credentialsType: toCredentialsType(provider.credentialsType),\n scopes: provider.scopes,\n authMethods: toAuthMethods(provider.authMethods),\n configFields: provider.configFields.map(toConfigField),\n config: toConfig(provider.config),\n installation:\n installations.find(\n (installation) => installation.connection_role === \"compatibility\",\n ) ?? null,\n connected_accounts: installations,\n capabilities: toAddConnectionCapabilities(provider.capabilities),\n createdAt: provider.createdAt,\n updatedAt: provider.updatedAt,\n ...toIconFields(provider),\n };\n });\n}\n\n/**\n * Presents a shared provider the way\n * `GET /_widgets/DataIntegrations/shared-connections` did for any active\n * member: identity, presentation and the state of each shared connection,\n * without credentials or account identifiers.\n */\nfunction toSharedDataConnection(\n provider: SharedDataProviderFieldsFragment,\n): SharedDataConnection {\n return {\n object: \"data_integration\",\n id: provider.id,\n name: provider.name,\n description: provider.description,\n slug: provider.slug,\n ownership: \"organization\",\n connected_accounts: provider.connectedAccounts.map(\n (connection): SharedConnection => ({\n object: \"connected_account\",\n id: connection.id,\n state: toConnectionState(connection.state),\n availability: isOneOf(AVAILABILITIES, connection.availability)\n ? connection.availability\n : \"needs_admin_attention\",\n created_at: connection.createdAt,\n updated_at: connection.updatedAt,\n }),\n ),\n ...toIconFields(provider),\n };\n}\n\n/**\n * Presents the organization's policy configuration of a member-connectable\n * provider the way `GET /_widgets/DataIntegrations/configurations` did.\n */\nfunction toDataIntegrationConfiguration(\n provider: ConfigurableDataProviderFieldsFragment,\n): DataIntegrationConfiguration {\n return {\n object: \"data_integration_configuration\",\n id: provider.id,\n name: provider.name,\n description: provider.description,\n slug: provider.slug,\n integrationType: provider.integrationType,\n ownership: \"userland_user\",\n enabled: provider.enabled,\n scopes: provider.scopes,\n defaultScopes: provider.defaultScopes,\n availableScopes: provider.availableScopes,\n credentials: toCredentials(provider.credentials),\n authMethods: toAuthMethods(provider.authMethods),\n configFields: provider.configFields.map(toConfigField),\n config: toConfig(provider.config),\n createdAt: provider.createdAt,\n updatedAt: provider.updatedAt,\n ...toIconFields(provider),\n };\n}\n\nfunction toCredentials(\n credentials: OrganizationDataProviderFieldsFragment[\"credentials\"],\n): DataIntegrationCredentials {\n return {\n credentialsType: toCredentialsType(credentials.credentialsType),\n hasCredentials: credentials.hasCredentials,\n client_id: credentials.clientId ?? null,\n redactedClientSecret: credentials.redactedClientSecret ?? null,\n redirectUri: credentials.redirectUri,\n };\n}\n\n/**\n * Presents an organization-owned provider the way\n * `GET /_widgets/DataIntegrations/organization` did. The GraphQL type\n * resolves the organization's override into the effective `enabled` /\n * `disabledSource`, so the raw override fields are derived from those.\n */\nfunction toOrganizationDataIntegration(\n provider: OrganizationDataProviderFieldsFragment,\n): OrganizationDataIntegrationWithCapabilities {\n const disabledSource = provider.disabledSource ?? null;\n const overrideDisabled = disabledSource === \"organization\";\n // Already oldest first from the API; sorted anyway so the order doesn't\n // hinge on that, and matches the member list's.\n const connectedAccounts = provider.connectedAccounts\n .map(toDataInstallation)\n .sort(byCreation);\n return {\n object: \"data_integration\",\n id: provider.id,\n name: provider.name,\n description: provider.description,\n slug: provider.slug,\n integrationType: provider.integrationType,\n ownership: \"organization\",\n credentialsType: toCredentialsType(provider.credentialsType),\n scopes: provider.scopes,\n authMethods: toAuthMethods(provider.authMethods),\n configFields: provider.configFields.map(toConfigField),\n config: toConfig(provider.config),\n installation: provider.connection\n ? toDataInstallation(provider.connection)\n : null,\n connected_accounts: connectedAccounts,\n createdAt: provider.createdAt,\n updatedAt: provider.updatedAt,\n ...toIconFields(provider),\n configuration: {\n hasOverride: overrideDisabled,\n rootEnabled: disabledSource !== \"developer\",\n overrideEnabled: overrideDisabled ? false : null,\n enabled: provider.enabled,\n disabledSource:\n disabledSource !== null && isOneOf(DISABLED_SOURCES, disabledSource)\n ? disabledSource\n : null,\n scopes: provider.scopes,\n defaultScopes: provider.defaultScopes,\n availableScopes: provider.availableScopes,\n credentials: toCredentials(provider.credentials),\n configured: provider.configured,\n configFields: provider.configFields.map(toConfigField),\n config: toConfig(provider.config),\n },\n capabilities: {\n canConfigure: provider.capabilities.canConfigure,\n canConnect: provider.capabilities.canConnect,\n canUpdateCredentials: provider.capabilities.canUpdateCredentials,\n canReauthorize: provider.capabilities.canReauthorize,\n canDisconnect: provider.capabilities.canDisconnect,\n ...toAddConnectionCapabilities(provider.capabilities),\n },\n };\n}\n\nasync function listAllDataProviders(\n sdk: Sdk,\n): Promise<DataProviderFieldsFragment[]> {\n return listAllPages(async (after) => {\n const { dataProviders } = await sdk.ListDataProviders({\n after,\n limit: PAGE_SIZE,\n });\n return dataProviders;\n });\n}\n\nasync function listAllDataProviderConnections(\n sdk: Sdk,\n): Promise<DataProviderConnectionFieldsFragment[]> {\n return listAllPages(async (after) => {\n const { dataProviderConnections } = await sdk.ListDataProviderConnections({\n after,\n limit: PAGE_SIZE,\n });\n return dataProviderConnections;\n });\n}\n\nasync function listAllOrganizationDataProviders(\n sdk: Sdk,\n): Promise<OrganizationDataProviderFieldsFragment[]> {\n return listAllPages(async (after) => {\n const { organizationDataProviders } =\n await sdk.ListOrganizationDataProviders({ after, limit: PAGE_SIZE });\n return organizationDataProviders;\n });\n}\n\nasync function listAllSharedDataProviders(\n sdk: Sdk,\n): Promise<SharedDataProviderFieldsFragment[]> {\n return listAllPages(async (after) => {\n const { sharedDataProviders } = await sdk.ListSharedDataProviders({\n after,\n limit: PAGE_SIZE,\n });\n return sharedDataProviders;\n });\n}\n\nasync function listAllConfigurableDataProviders(\n sdk: Sdk,\n): Promise<ConfigurableDataProviderFieldsFragment[]> {\n return listAllPages(async (after) => {\n const { configurableDataProviders } =\n await sdk.ListConfigurableDataProviders({ after, limit: PAGE_SIZE });\n return configurableDataProviders;\n });\n}\n\nexport const sharedDataConnectionsQueryKey = clientGraphqlQueryKey(\n \"ListSharedDataProviders\",\n);\n\nexport const dataIntegrationConfigurationsQueryKey = clientGraphqlQueryKey(\n \"ListConfigurableDataProviders\",\n);\n\nexport const myDataIntegrationsQueryKeys = [\n clientGraphqlQueryKey(\"ListDataProviders\"),\n clientGraphqlQueryKey(\"ListDataProviderConnections\"),\n];\n\nexport const organizationDataIntegrationsQueryKey = clientGraphqlQueryKey(\n \"ListOrganizationDataProviders\",\n);\n\ninterface ListResult<T> {\n data: T[];\n isLoading: boolean;\n isPending: boolean;\n isSuccess: boolean;\n isError: boolean;\n error: Error | null;\n failureCount: number;\n refetch: () => void;\n}\n\n/** The member's connectable providers joined with their own connections. */\nexport function useMyDataIntegrations({\n enabled = true,\n}: { enabled?: boolean } = {}): ListResult<DataIntegrationWithCapabilities> {\n const providers = useClientGraphqlQuery({\n queryKey: clientGraphqlQueryKey(\"ListDataProviders\"),\n queryFn: listAllDataProviders,\n enabled,\n });\n const connections = useClientGraphqlQuery({\n queryKey: clientGraphqlQueryKey(\"ListDataProviderConnections\"),\n queryFn: listAllDataProviderConnections,\n enabled,\n });\n\n const isSuccess = providers.isSuccess && connections.isSuccess;\n return {\n data: isSuccess\n ? toMyDataIntegrations(providers.data, connections.data)\n : [],\n isLoading: providers.isLoading || connections.isLoading,\n isPending: providers.isPending || connections.isPending,\n isSuccess,\n isError: providers.isError || connections.isError,\n error: providers.error ?? connections.error,\n failureCount: Math.max(providers.failureCount, connections.failureCount),\n refetch: () => {\n void providers.refetch();\n void connections.refetch();\n },\n };\n}\n\n/** The organization's provider inventory with its shared connections. */\nexport function useOrganizationDataIntegrations({\n enabled = true,\n}: {\n enabled?: boolean;\n} = {}): ListResult<OrganizationDataIntegrationWithCapabilities> {\n const query = useClientGraphqlQuery({\n queryKey: organizationDataIntegrationsQueryKey,\n queryFn: listAllOrganizationDataProviders,\n select: (providers) => providers.map(toOrganizationDataIntegration),\n enabled,\n });\n return {\n data: query.data ?? [],\n isLoading: query.isLoading,\n isPending: query.isPending,\n isSuccess: query.isSuccess,\n isError: query.isError,\n error: query.error,\n failureCount: query.failureCount,\n refetch: () => {\n void query.refetch();\n },\n };\n}\n\n/** The organization's shared connections, readable by any active member. */\nexport function useSharedDataConnections(): ListResult<SharedDataConnection> {\n const query = useClientGraphqlQuery({\n queryKey: sharedDataConnectionsQueryKey,\n queryFn: listAllSharedDataProviders,\n select: (providers) => providers.map(toSharedDataConnection),\n });\n return {\n data: query.data ?? [],\n isLoading: query.isLoading,\n isPending: query.isPending,\n isSuccess: query.isSuccess,\n isError: query.isError,\n error: query.error,\n failureCount: query.failureCount,\n refetch: () => {\n void query.refetch();\n },\n };\n}\n\n/** The organization's policy configuration of each connectable provider. */\nexport function useDataIntegrationConfigurations({\n enabled = true,\n}: { enabled?: boolean } = {}): ListResult<DataIntegrationConfiguration> {\n const query = useClientGraphqlQuery({\n queryKey: dataIntegrationConfigurationsQueryKey,\n queryFn: listAllConfigurableDataProviders,\n select: (providers) => providers.map(toDataIntegrationConfiguration),\n enabled,\n });\n return {\n data: query.data ?? [],\n isLoading: query.isLoading,\n isPending: query.isPending,\n isSuccess: query.isSuccess,\n isError: query.isError,\n error: query.error,\n failureCount: query.failureCount,\n refetch: () => {\n void query.refetch();\n },\n };\n}\n\n/**\n * Refreshes whatever a write for `owner` changed: the member's own list, or the\n * organization's inventory plus the shared section members see.\n */\nexport function useInvalidateConnections(owner: \"user\" | \"organization\") {\n const queryClient = useQueryClient();\n return useCallback(() => {\n if (owner === \"organization\") {\n queryClient.invalidateQueries({\n queryKey: organizationDataIntegrationsQueryKey,\n });\n queryClient.invalidateQueries({\n queryKey: sharedDataConnectionsQueryKey,\n });\n } else {\n for (const queryKey of myDataIntegrationsQueryKeys) {\n queryClient.invalidateQueries({ queryKey });\n }\n }\n }, [owner, queryClient]);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"pipes.cjs","names":["clientGraphqlQueryKey","useClientGraphqlQuery","useQueryClient","useCallback"],"sources":["../../../../src/lib/api/pipes.ts"],"sourcesContent":["import { useQueryClient } from \"@tanstack/react-query\";\nimport { useCallback } from \"react\";\nimport type {\n ConfigurableDataProviderFieldsFragment,\n DataProviderConfigFieldFieldsFragment,\n DataProviderConnectionFieldsFragment,\n DataProviderFieldsFragment,\n OrganizationDataProviderFieldsFragment,\n Sdk,\n SharedDataProviderFieldsFragment,\n} from \"../../api/client-graphql/generated.js\";\nimport {\n clientGraphqlQueryKey,\n useClientGraphqlQuery,\n} from \"../../api/client-graphql/hooks.js\";\nimport type {\n DataInstallation,\n DataIntegrationConfigField,\n DataIntegrationConfiguration,\n DataIntegrationCredentials,\n DataIntegrationWithConnections,\n OrganizationDataIntegration,\n SharedConnection,\n SharedDataConnection,\n} from \"./types.js\";\n\nconst PAGE_SIZE = 100;\n\n/*\n * The widgets render the REST-shaped DTOs in `./types.ts`, which double as the\n * public shape a host's `filter` predicate sees. What the multiple-connections\n * capabilities add is carried on these local extensions instead, so the\n * public types don't change.\n */\n\ntype AuthMethod = NonNullable<\n DataIntegrationWithConnections[\"authMethods\"]\n>[number];\n\n/** Advisory repair actions on one exact organization-owned connection. */\nexport interface ConnectionCapabilities {\n canReauthorize: boolean;\n canUpdateCredentials: boolean;\n}\n\n/**\n * Whether the owner can add another connection to a provider right now, and\n * with which methods. Advisory: the server rechecks the cap when creating.\n */\nexport interface AddConnectionCapabilities {\n canAddConnection: boolean;\n /** Empty exactly when `canAddConnection` is false. */\n addConnectionMethods: AuthMethod[];\n}\n\n/**\n * A connection with its row-level capabilities: set for organization-owned\n * connections, null for a member's own (whose actions follow from its state).\n */\nexport type ConnectionWithCapabilities = DataInstallation & {\n capabilities: ConnectionCapabilities | null;\n};\n\n// The connection fields are replaced rather than intersected: an intersection\n// of two array types doesn't narrow the element type array methods see.\n\n/** A member's provider, its connections and whether they can add another. */\nexport type DataIntegrationWithCapabilities = Omit<\n DataIntegrationWithConnections,\n \"installation\" | \"connected_accounts\"\n> & {\n installation?: ConnectionWithCapabilities | null;\n connected_accounts: ConnectionWithCapabilities[];\n capabilities: AddConnectionCapabilities;\n};\n\n/** An organization-owned provider, with add and per-connection capabilities. */\nexport type OrganizationDataIntegrationWithCapabilities = Omit<\n OrganizationDataIntegration,\n \"installation\" | \"connected_accounts\" | \"capabilities\"\n> & {\n installation?: ConnectionWithCapabilities | null;\n connected_accounts: ConnectionWithCapabilities[];\n capabilities: OrganizationDataIntegration[\"capabilities\"] &\n AddConnectionCapabilities;\n};\n\n/**\n * The Pipes list queries default to `limit: 10` and the widgets render every\n * row, so each list is walked to its end before it is adapted.\n */\nasync function listAllPages<T>(\n fetchPage: (after: string | null) => Promise<{\n data: T[];\n listMetadata: { after?: string | null };\n }>,\n): Promise<T[]> {\n const rows: T[] = [];\n let after: string | null = null;\n do {\n const page = await fetchPage(after);\n rows.push(...page.data);\n after = page.listMetadata.after ?? null;\n } while (after !== null);\n return rows;\n}\n\nfunction isOneOf<const T extends readonly string[]>(\n values: T,\n value: string,\n): value is T[number] {\n return values.includes(value);\n}\n\nconst AUTH_METHODS = [\"oauth\", \"api_key\", \"client_credentials\"] as const;\nconst CONNECTION_STATES = [\"connected\", \"needs_reauthorization\"] as const;\nconst AVAILABILITIES = [\"available\", \"needs_admin_attention\"] as const;\nconst CREDENTIALS_TYPES = [\"shared\", \"custom\", \"organization\"] as const;\nconst DISABLED_SOURCES = [\"developer\", \"organization\"] as const;\nconst CONFIG_FIELD_SCOPES = [\"integration\", \"installation\"] as const;\n\nfunction toAuthMethods(\n authMethods: readonly string[],\n): NonNullable<DataIntegrationWithConnections[\"authMethods\"]> {\n return authMethods.filter((method) => isOneOf(AUTH_METHODS, method));\n}\n\n/**\n * The GraphQL types carry these as plain strings; the REST DTOs the widgets\n * render from narrow them. Unknown values fall back to the option that\n * renders the least capable state.\n */\nfunction toCredentialsType(\n credentialsType: string,\n): DataIntegrationWithConnections[\"credentialsType\"] {\n return isOneOf(CREDENTIALS_TYPES, credentialsType)\n ? credentialsType\n : \"shared\";\n}\n\nfunction toConnectionState(state: string): DataInstallation[\"state\"] {\n return isOneOf(CONNECTION_STATES, state) ? state : \"needs_reauthorization\";\n}\n\nfunction toConfig(\n entries: readonly { name: string; value: string }[],\n): Record<string, string> {\n return Object.fromEntries(entries.map(({ name, value }) => [name, value]));\n}\n\nfunction toConfigField(\n field: DataProviderConfigFieldFieldsFragment,\n): DataIntegrationConfigField {\n return {\n key: field.key,\n label: field.label,\n required: field.required,\n scope: isOneOf(CONFIG_FIELD_SCOPES, field.scope)\n ? field.scope\n : \"integration\",\n description: field.description ?? undefined,\n example: field.example ?? undefined,\n pattern: field.pattern ?? undefined,\n patternFlags: field.patternFlags ?? undefined,\n order: field.order ?? undefined,\n secret: field.secret ?? undefined,\n default: field.default ?? undefined,\n };\n}\n\nfunction toIconFields(provider: {\n iconSlug?: string | null;\n iconUrl?: string | null;\n iconDarkUrl?: string | null;\n}): Pick<\n DataIntegrationWithConnections,\n \"iconSlug\" | \"iconUrl\" | \"iconDarkUrl\"\n> {\n return {\n iconSlug: provider.iconSlug ?? undefined,\n iconUrl: provider.iconUrl ?? undefined,\n iconDarkUrl: provider.iconDarkUrl ?? undefined,\n };\n}\n\n/**\n * Oldest first: by creation time, then id (ULIDs also sort by time). This is\n * the order the API already uses for organization connections; the member\n * list defaults to newest first, so both are sorted here rather than relying\n * on either endpoint's default.\n */\nfunction byCreation(a: DataInstallation, b: DataInstallation): number {\n return (\n Date.parse(a.created_at) - Date.parse(b.created_at) ||\n a.id.localeCompare(b.id)\n );\n}\n\nfunction toAddConnectionCapabilities(capabilities: {\n canAddConnection: boolean;\n addConnectionMethods: readonly string[];\n}): AddConnectionCapabilities {\n const addConnectionMethods = toAuthMethods(capabilities.addConnectionMethods);\n return {\n // Keep the pair consistent even if an unknown method was filtered out.\n canAddConnection:\n capabilities.canAddConnection && addConnectionMethods.length > 0,\n addConnectionMethods,\n };\n}\n\nfunction toDataInstallation(\n connection: DataProviderConnectionFieldsFragment,\n): ConnectionWithCapabilities {\n return {\n capabilities: connection.capabilities\n ? {\n canReauthorize: connection.capabilities.canReauthorize,\n canUpdateCredentials: connection.capabilities.canUpdateCredentials,\n }\n : null,\n object: \"data_installation\",\n id: connection.id,\n connection_role:\n connection.connectionRole === \"Standard\" ? \"standard\" : \"compatibility\",\n account_identifier: connection.accountIdentifier ?? null,\n account_display_name: connection.accountDisplayName ?? null,\n user_id: connection.userId ?? null,\n organization_id: connection.organizationId ?? null,\n scopes: connection.scopes,\n auth_method: isOneOf(AUTH_METHODS, connection.authMethod)\n ? connection.authMethod\n : \"oauth\",\n api_key_last_4: connection.apiKeyLast4 ?? null,\n client_id: connection.clientId ?? null,\n client_secret_last_4: connection.clientSecretLast4 ?? null,\n config: toConfig(connection.config),\n state: toConnectionState(connection.state),\n created_at: connection.createdAt,\n updated_at: connection.updatedAt,\n };\n}\n\n/**\n * Joins the member's providers with their own connections the way\n * `GET /_widgets/DataIntegrations/mine` did: every connection, oldest first,\n * in `connected_accounts`, and the compatibility connection inline as\n * `installation` — the single connection the unsectioned widget and a host's\n * `filter` see. With the compatibility slot empty, `installation` is null and\n * the provider reads as not connected there, as it does to every other\n * single-connection client.\n */\nfunction toMyDataIntegrations(\n providers: readonly DataProviderFieldsFragment[],\n connections: readonly DataProviderConnectionFieldsFragment[],\n): DataIntegrationWithCapabilities[] {\n const connectionsByProviderId = new Map<\n string,\n ConnectionWithCapabilities[]\n >();\n for (const connection of connections) {\n const installations =\n connectionsByProviderId.get(connection.dataProviderId) ?? [];\n installations.push(toDataInstallation(connection));\n connectionsByProviderId.set(connection.dataProviderId, installations);\n }\n\n return providers.map((provider) => {\n const installations = (connectionsByProviderId.get(provider.id) ?? []).sort(\n byCreation,\n );\n return {\n object: \"data_integration\",\n id: provider.id,\n name: provider.name,\n description: provider.description,\n slug: provider.slug,\n integrationType: provider.integrationType,\n ownership: \"userland_user\",\n credentialsType: toCredentialsType(provider.credentialsType),\n scopes: provider.scopes,\n authMethods: toAuthMethods(provider.authMethods),\n configFields: provider.configFields.map(toConfigField),\n config: toConfig(provider.config),\n installation:\n installations.find(\n (installation) => installation.connection_role === \"compatibility\",\n ) ?? null,\n connected_accounts: installations,\n capabilities: toAddConnectionCapabilities(provider.capabilities),\n createdAt: provider.createdAt,\n updatedAt: provider.updatedAt,\n ...toIconFields(provider),\n };\n });\n}\n\n/**\n * Presents a shared provider the way\n * `GET /_widgets/DataIntegrations/shared-connections` did for any active\n * member: identity, presentation and the state of each shared connection,\n * without credentials or account identifiers.\n */\nfunction toSharedDataConnection(\n provider: SharedDataProviderFieldsFragment,\n): SharedDataConnection {\n return {\n object: \"data_integration\",\n id: provider.id,\n name: provider.name,\n description: provider.description,\n slug: provider.slug,\n ownership: \"organization\",\n connected_accounts: provider.connectedAccounts.map(\n (connection): SharedConnection => ({\n object: \"connected_account\",\n id: connection.id,\n state: toConnectionState(connection.state),\n availability: isOneOf(AVAILABILITIES, connection.availability)\n ? connection.availability\n : \"needs_admin_attention\",\n created_at: connection.createdAt,\n updated_at: connection.updatedAt,\n }),\n ),\n ...toIconFields(provider),\n };\n}\n\n/**\n * Presents the organization's policy configuration of a member-connectable\n * provider the way `GET /_widgets/DataIntegrations/configurations` did.\n */\nfunction toDataIntegrationConfiguration(\n provider: ConfigurableDataProviderFieldsFragment,\n): DataIntegrationConfiguration {\n return {\n object: \"data_integration_configuration\",\n id: provider.id,\n name: provider.name,\n description: provider.description,\n slug: provider.slug,\n integrationType: provider.integrationType,\n ownership: \"userland_user\",\n enabled: provider.enabled,\n scopes: provider.scopes,\n defaultScopes: provider.defaultScopes,\n availableScopes: provider.availableScopes,\n credentials: toCredentials(provider.credentials),\n authMethods: toAuthMethods(provider.authMethods),\n configFields: provider.configFields.map(toConfigField),\n config: toConfig(provider.config),\n createdAt: provider.createdAt,\n updatedAt: provider.updatedAt,\n ...toIconFields(provider),\n };\n}\n\nfunction toCredentials(\n credentials: OrganizationDataProviderFieldsFragment[\"credentials\"],\n): DataIntegrationCredentials {\n return {\n credentialsType: toCredentialsType(credentials.credentialsType),\n hasCredentials: credentials.hasCredentials,\n client_id: credentials.clientId ?? null,\n redactedClientSecret: credentials.redactedClientSecret ?? null,\n redirectUri: credentials.redirectUri,\n };\n}\n\n/**\n * Presents an organization-owned provider the way\n * `GET /_widgets/DataIntegrations/organization` did. The GraphQL type\n * resolves the organization's override into the effective `enabled` /\n * `disabledSource`, so the raw override fields are derived from those.\n */\nfunction toOrganizationDataIntegration(\n provider: OrganizationDataProviderFieldsFragment,\n): OrganizationDataIntegrationWithCapabilities {\n const disabledSource = provider.disabledSource ?? null;\n const overrideDisabled = disabledSource === \"organization\";\n // Already oldest first from the API; sorted anyway so the order doesn't\n // hinge on that, and matches the member list's.\n const connectedAccounts = provider.connectedAccounts\n .map(toDataInstallation)\n .sort(byCreation);\n return {\n object: \"data_integration\",\n id: provider.id,\n name: provider.name,\n description: provider.description,\n slug: provider.slug,\n integrationType: provider.integrationType,\n ownership: \"organization\",\n credentialsType: toCredentialsType(provider.credentialsType),\n scopes: provider.scopes,\n authMethods: toAuthMethods(provider.authMethods),\n configFields: provider.configFields.map(toConfigField),\n config: toConfig(provider.config),\n installation: provider.connection\n ? toDataInstallation(provider.connection)\n : null,\n connected_accounts: connectedAccounts,\n createdAt: provider.createdAt,\n updatedAt: provider.updatedAt,\n ...toIconFields(provider),\n configuration: {\n hasOverride: overrideDisabled,\n rootEnabled: disabledSource !== \"developer\",\n overrideEnabled: overrideDisabled ? false : null,\n enabled: provider.enabled,\n disabledSource:\n disabledSource !== null && isOneOf(DISABLED_SOURCES, disabledSource)\n ? disabledSource\n : null,\n scopes: provider.scopes,\n defaultScopes: provider.defaultScopes,\n availableScopes: provider.availableScopes,\n credentials: toCredentials(provider.credentials),\n configured: provider.configured,\n configFields: provider.configFields.map(toConfigField),\n config: toConfig(provider.config),\n },\n capabilities: {\n canConfigure: provider.capabilities.canConfigure,\n canConnect: provider.capabilities.canConnect,\n canUpdateCredentials: provider.capabilities.canUpdateCredentials,\n canReauthorize: provider.capabilities.canReauthorize,\n canDisconnect: provider.capabilities.canDisconnect,\n ...toAddConnectionCapabilities(provider.capabilities),\n },\n };\n}\n\nasync function listAllDataProviders(\n sdk: Sdk,\n): Promise<DataProviderFieldsFragment[]> {\n return listAllPages(async (after) => {\n const { dataProviders } = await sdk.ListDataProviders({\n after,\n limit: PAGE_SIZE,\n });\n return dataProviders;\n });\n}\n\nasync function listAllDataProviderConnections(\n sdk: Sdk,\n): Promise<DataProviderConnectionFieldsFragment[]> {\n return listAllPages(async (after) => {\n const { dataProviderConnections } = await sdk.ListDataProviderConnections({\n after,\n limit: PAGE_SIZE,\n });\n return dataProviderConnections;\n });\n}\n\nasync function listAllOrganizationDataProviders(\n sdk: Sdk,\n): Promise<OrganizationDataProviderFieldsFragment[]> {\n return listAllPages(async (after) => {\n const { organizationDataProviders } =\n await sdk.ListOrganizationDataProviders({ after, limit: PAGE_SIZE });\n return organizationDataProviders;\n });\n}\n\nasync function listAllSharedDataProviders(\n sdk: Sdk,\n): Promise<SharedDataProviderFieldsFragment[]> {\n return listAllPages(async (after) => {\n const { sharedDataProviders } = await sdk.ListSharedDataProviders({\n after,\n limit: PAGE_SIZE,\n });\n return sharedDataProviders;\n });\n}\n\nasync function listAllConfigurableDataProviders(\n sdk: Sdk,\n): Promise<ConfigurableDataProviderFieldsFragment[]> {\n return listAllPages(async (after) => {\n const { configurableDataProviders } =\n await sdk.ListConfigurableDataProviders({ after, limit: PAGE_SIZE });\n return configurableDataProviders;\n });\n}\n\nexport const sharedDataConnectionsQueryKey = clientGraphqlQueryKey(\n \"ListSharedDataProviders\",\n);\n\nexport const dataIntegrationConfigurationsQueryKey = clientGraphqlQueryKey(\n \"ListConfigurableDataProviders\",\n);\n\nexport const myDataIntegrationsQueryKeys = [\n clientGraphqlQueryKey(\"ListDataProviders\"),\n clientGraphqlQueryKey(\"ListDataProviderConnections\"),\n];\n\nexport const organizationDataIntegrationsQueryKey = clientGraphqlQueryKey(\n \"ListOrganizationDataProviders\",\n);\n\ninterface ListResult<T> {\n data: T[];\n isLoading: boolean;\n isPending: boolean;\n isSuccess: boolean;\n isError: boolean;\n error: Error | null;\n failureCount: number;\n refetch: () => void;\n}\n\n/** The member's connectable providers joined with their own connections. */\nexport function useMyDataIntegrations({\n enabled = true,\n}: { enabled?: boolean } = {}): ListResult<DataIntegrationWithCapabilities> {\n const providers = useClientGraphqlQuery({\n queryKey: clientGraphqlQueryKey(\"ListDataProviders\"),\n queryFn: listAllDataProviders,\n enabled,\n });\n const connections = useClientGraphqlQuery({\n queryKey: clientGraphqlQueryKey(\"ListDataProviderConnections\"),\n queryFn: listAllDataProviderConnections,\n enabled,\n });\n\n const isSuccess = providers.isSuccess && connections.isSuccess;\n return {\n data: isSuccess\n ? toMyDataIntegrations(providers.data, connections.data)\n : [],\n isLoading: providers.isLoading || connections.isLoading,\n isPending: providers.isPending || connections.isPending,\n isSuccess,\n isError: providers.isError || connections.isError,\n error: providers.error ?? connections.error,\n failureCount: Math.max(providers.failureCount, connections.failureCount),\n refetch: () => {\n void providers.refetch();\n void connections.refetch();\n },\n };\n}\n\n/** The organization's provider inventory with its shared connections. */\nexport function useOrganizationDataIntegrations({\n enabled = true,\n}: {\n enabled?: boolean;\n} = {}): ListResult<OrganizationDataIntegrationWithCapabilities> {\n const query = useClientGraphqlQuery({\n queryKey: organizationDataIntegrationsQueryKey,\n queryFn: listAllOrganizationDataProviders,\n select: (providers) => providers.map(toOrganizationDataIntegration),\n enabled,\n });\n return {\n data: query.data ?? [],\n isLoading: query.isLoading,\n isPending: query.isPending,\n isSuccess: query.isSuccess,\n isError: query.isError,\n error: query.error,\n failureCount: query.failureCount,\n refetch: () => {\n void query.refetch();\n },\n };\n}\n\n/** The organization's shared connections, readable by any active member. */\nexport function useSharedDataConnections(): ListResult<SharedDataConnection> {\n const query = useClientGraphqlQuery({\n queryKey: sharedDataConnectionsQueryKey,\n queryFn: listAllSharedDataProviders,\n select: (providers) => providers.map(toSharedDataConnection),\n });\n return {\n data: query.data ?? [],\n isLoading: query.isLoading,\n isPending: query.isPending,\n isSuccess: query.isSuccess,\n isError: query.isError,\n error: query.error,\n failureCount: query.failureCount,\n refetch: () => {\n void query.refetch();\n },\n };\n}\n\n/** The organization's policy configuration of each connectable provider. */\nexport function useDataIntegrationConfigurations({\n enabled = true,\n}: { enabled?: boolean } = {}): ListResult<DataIntegrationConfiguration> {\n const query = useClientGraphqlQuery({\n queryKey: dataIntegrationConfigurationsQueryKey,\n queryFn: listAllConfigurableDataProviders,\n select: (providers) => providers.map(toDataIntegrationConfiguration),\n enabled,\n });\n return {\n data: query.data ?? [],\n isLoading: query.isLoading,\n isPending: query.isPending,\n isSuccess: query.isSuccess,\n isError: query.isError,\n error: query.error,\n failureCount: query.failureCount,\n refetch: () => {\n void query.refetch();\n },\n };\n}\n\n/**\n * Refreshes whatever a write for `owner` changed: the member's own list, or the\n * organization's inventory plus the shared section members see.\n */\nexport function useInvalidateConnections(owner: \"user\" | \"organization\") {\n const queryClient = useQueryClient();\n return useCallback(() => {\n if (owner === \"organization\") {\n queryClient.invalidateQueries({\n queryKey: organizationDataIntegrationsQueryKey,\n });\n queryClient.invalidateQueries({\n queryKey: sharedDataConnectionsQueryKey,\n });\n } else {\n for (const queryKey of myDataIntegrationsQueryKeys) {\n queryClient.invalidateQueries({ queryKey });\n }\n }\n }, [owner, queryClient]);\n}\n"],"mappings":"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"}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_api_client_graphql_query_keys = require("../../api/client-graphql/query-keys.cjs");
|
|
2
3
|
const require_api_client_graphql_hooks = require("../../api/client-graphql/hooks.cjs");
|
|
3
4
|
const require_lib_api_api_key = require("./api-key.cjs");
|
|
4
5
|
const require_widgets_api_keys_user_api_keys_context = require("../../widgets/api-keys/user-api-keys-context.cjs");
|
|
5
6
|
let _tanstack_react_query = require("@tanstack/react-query");
|
|
6
7
|
//#region src/lib/api/user-api-key.ts
|
|
7
8
|
const useListUserApiKeyPermissions = (params) => require_lib_api_api_key.useListApiKeyPermissions("User", params);
|
|
8
|
-
const userApiKeysQueryKey =
|
|
9
|
+
const userApiKeysQueryKey = require_api_client_graphql_query_keys.clientGraphqlQueryKey("ListUserApiKeys");
|
|
9
10
|
function toUserApiKey(apiKey) {
|
|
10
11
|
return {
|
|
11
12
|
id: apiKey.id,
|
|
@@ -57,7 +58,7 @@ const useUserApiKeys = () => {
|
|
|
57
58
|
search: searchQuery || void 0
|
|
58
59
|
};
|
|
59
60
|
return require_api_client_graphql_hooks.useClientGraphqlQuery({
|
|
60
|
-
queryKey:
|
|
61
|
+
queryKey: require_api_client_graphql_query_keys.clientGraphqlQueryKey("ListUserApiKeys", variables),
|
|
61
62
|
queryFn: async (sdk) => {
|
|
62
63
|
const { userApiKeys } = await sdk.ListUserApiKeys(variables);
|
|
63
64
|
return userApiKeys;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"user-api-key.cjs","names":["useListApiKeyPermissions","clientGraphqlQueryKey","apiKeyMutationFailure","useUserApiKeysContext","useClientGraphqlQuery","keepPreviousData","useQueryClient","useClientGraphqlMutation"],"sources":["../../../../src/lib/api/user-api-key.ts"],"sourcesContent":["import { keepPreviousData, useQueryClient } from \"@tanstack/react-query\";\nimport type {\n CreateUserApiKeyMutation,\n ExpireUserApiKeyMutation,\n UserApiKeyFieldsFragment,\n} from \"../../api/client-graphql/generated.js\";\nimport {\n clientGraphqlQueryKey,\n useClientGraphqlMutation,\n useClientGraphqlQuery,\n} from \"../../api/client-graphql/hooks.js\";\nimport { useUserApiKeysContext } from \"../../widgets/api-keys/user-api-keys-context.js\";\nimport {\n API_KEYS_PAGE_SIZE,\n apiKeyMutationFailure,\n useListApiKeyPermissions,\n} from \"./api-key.js\";\nimport type {\n CreateUserApiKeyRequest,\n CreateUserApiKeyResponse,\n ListUserApiKeyPermissionsParams,\n ListUserApiKeysResponse,\n ListUserApiKeysResponseData,\n} from \"./types.js\";\n\nexport type {\n CreateUserApiKeyResponse,\n ListUserApiKeyPermission,\n ListUserApiKeysResponse,\n ListUserApiKeysResponseData,\n} from \"./types.js\";\n\nexport const useListUserApiKeyPermissions = (\n params?: ListUserApiKeyPermissionsParams,\n) => useListApiKeyPermissions(\"User\", params);\n\nconst userApiKeysQueryKey = clientGraphqlQueryKey(\"ListUserApiKeys\");\n\nfunction toUserApiKey(\n apiKey: UserApiKeyFieldsFragment,\n): ListUserApiKeysResponseData {\n return {\n id: apiKey.id,\n owner: {\n type: \"user\",\n id: apiKey.owner.id,\n email: apiKey.owner.email,\n firstName: apiKey.owner.firstName ?? null,\n lastName: apiKey.owner.lastName ?? null,\n displayName: apiKey.owner.displayName,\n },\n name: apiKey.name,\n obfuscatedValue: apiKey.obfuscatedValue,\n createdAt: apiKey.createdAt,\n lastUsedAt: apiKey.lastUsedAt ?? null,\n expiresAt: apiKey.expiresAt ?? null,\n permissions: apiKey.permissions,\n };\n}\n\nfunction unwrapCreateUserApiKey(\n result: CreateUserApiKeyMutation[\"createUserApiKey\"],\n): CreateUserApiKeyResponse {\n switch (result.__typename) {\n case \"UserApiKeyCreated\": {\n const { owner: _owner, ...apiKey } = toUserApiKey(result.apiKey);\n return { ...apiKey, value: result.value };\n }\n case \"ApiKeyPermissionsNotHeld\":\n case \"ApiKeyPermissionsUnsupportedForToken\":\n case \"InvalidApiKeyExpiration\":\n case \"InvalidApiKeyName\":\n case \"InvalidApiKeyPermissions\":\n throw apiKeyMutationFailure(result.__typename, result.message);\n }\n}\n\nfunction unwrapExpireUserApiKey(\n result: ExpireUserApiKeyMutation[\"expireUserApiKey\"],\n): ListUserApiKeysResponseData {\n switch (result.__typename) {\n case \"UserApiKeyExpired\":\n return toUserApiKey(result.apiKey);\n case \"ApiKeyAlreadyExpired\":\n throw apiKeyMutationFailure(\n result.__typename,\n \"API key is already expired\",\n );\n }\n}\n\nexport const useUserApiKeys = () => {\n const {\n state: { pagination, searchQuery },\n } = useUserApiKeysContext();\n const { before, after } = pagination || {};\n const variables = {\n after: after ?? undefined,\n before: before ?? undefined,\n limit: API_KEYS_PAGE_SIZE,\n search: searchQuery || undefined,\n };\n\n return useClientGraphqlQuery({\n queryKey: clientGraphqlQueryKey(\"ListUserApiKeys\", variables),\n queryFn: async (sdk) => {\n const { userApiKeys } = await sdk.ListUserApiKeys(variables);\n return userApiKeys;\n },\n select: (list): ListUserApiKeysResponse => ({\n data: list.data.map(toUserApiKey),\n list_metadata: {\n after: list.listMetadata.after ?? undefined,\n before: list.listMetadata.before ?? undefined,\n },\n }),\n placeholderData: keepPreviousData,\n });\n};\n\nconst useInvalidateUserApiKeys = () => {\n const queryClient = useQueryClient();\n return () => queryClient.invalidateQueries({ queryKey: userApiKeysQueryKey });\n};\n\nexport const useCreateUserApiKeyWithInvalidation = () => {\n const invalidate = useInvalidateUserApiKeys();\n\n return useClientGraphqlMutation({\n mutationFn: async (sdk, { data }: { data: CreateUserApiKeyRequest }) => {\n const { createUserApiKey: result } = await sdk.CreateUserApiKey({\n input: {\n name: data.name,\n permissions: data.permissions,\n expiresAt: data.expiresAt ?? null,\n },\n });\n return unwrapCreateUserApiKey(result);\n },\n onSuccess: invalidate,\n });\n};\n\nexport const useDeleteUserApiKey = ({\n onSuccess,\n}: { onSuccess?: () => void } = {}) => {\n const invalidate = useInvalidateUserApiKeys();\n\n return useClientGraphqlMutation({\n mutationFn: async (sdk, { apiKeyId }: { apiKeyId: string }) => {\n const { deleteUserApiKey } = await sdk.DeleteUserApiKey({ apiKeyId });\n return toUserApiKey(deleteUserApiKey);\n },\n onSuccess: () => {\n void invalidate();\n onSuccess?.();\n },\n });\n};\n\nexport const useExpireUserApiKey = () => {\n const invalidate = useInvalidateUserApiKeys();\n\n return useClientGraphqlMutation({\n mutationFn: async (\n sdk,\n { apiKeyId, expiresAt }: { apiKeyId: string; expiresAt: string | null },\n ) => {\n const { expireUserApiKey: result } = await sdk.ExpireUserApiKey({\n input: { apiKeyId, expiresAt },\n });\n return unwrapExpireUserApiKey(result);\n },\n onSuccess: invalidate,\n });\n};\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"user-api-key.cjs","names":["useListApiKeyPermissions","clientGraphqlQueryKey","apiKeyMutationFailure","useUserApiKeysContext","useClientGraphqlQuery","keepPreviousData","useQueryClient","useClientGraphqlMutation"],"sources":["../../../../src/lib/api/user-api-key.ts"],"sourcesContent":["import { keepPreviousData, useQueryClient } from \"@tanstack/react-query\";\nimport type {\n CreateUserApiKeyMutation,\n ExpireUserApiKeyMutation,\n UserApiKeyFieldsFragment,\n} from \"../../api/client-graphql/generated.js\";\nimport {\n clientGraphqlQueryKey,\n useClientGraphqlMutation,\n useClientGraphqlQuery,\n} from \"../../api/client-graphql/hooks.js\";\nimport { useUserApiKeysContext } from \"../../widgets/api-keys/user-api-keys-context.js\";\nimport {\n API_KEYS_PAGE_SIZE,\n apiKeyMutationFailure,\n useListApiKeyPermissions,\n} from \"./api-key.js\";\nimport type {\n CreateUserApiKeyRequest,\n CreateUserApiKeyResponse,\n ListUserApiKeyPermissionsParams,\n ListUserApiKeysResponse,\n ListUserApiKeysResponseData,\n} from \"./types.js\";\n\nexport type {\n CreateUserApiKeyResponse,\n ListUserApiKeyPermission,\n ListUserApiKeysResponse,\n ListUserApiKeysResponseData,\n} from \"./types.js\";\n\nexport const useListUserApiKeyPermissions = (\n params?: ListUserApiKeyPermissionsParams,\n) => useListApiKeyPermissions(\"User\", params);\n\nconst userApiKeysQueryKey = clientGraphqlQueryKey(\"ListUserApiKeys\");\n\nfunction toUserApiKey(\n apiKey: UserApiKeyFieldsFragment,\n): ListUserApiKeysResponseData {\n return {\n id: apiKey.id,\n owner: {\n type: \"user\",\n id: apiKey.owner.id,\n email: apiKey.owner.email,\n firstName: apiKey.owner.firstName ?? null,\n lastName: apiKey.owner.lastName ?? null,\n displayName: apiKey.owner.displayName,\n },\n name: apiKey.name,\n obfuscatedValue: apiKey.obfuscatedValue,\n createdAt: apiKey.createdAt,\n lastUsedAt: apiKey.lastUsedAt ?? null,\n expiresAt: apiKey.expiresAt ?? null,\n permissions: apiKey.permissions,\n };\n}\n\nfunction unwrapCreateUserApiKey(\n result: CreateUserApiKeyMutation[\"createUserApiKey\"],\n): CreateUserApiKeyResponse {\n switch (result.__typename) {\n case \"UserApiKeyCreated\": {\n const { owner: _owner, ...apiKey } = toUserApiKey(result.apiKey);\n return { ...apiKey, value: result.value };\n }\n case \"ApiKeyPermissionsNotHeld\":\n case \"ApiKeyPermissionsUnsupportedForToken\":\n case \"InvalidApiKeyExpiration\":\n case \"InvalidApiKeyName\":\n case \"InvalidApiKeyPermissions\":\n throw apiKeyMutationFailure(result.__typename, result.message);\n }\n}\n\nfunction unwrapExpireUserApiKey(\n result: ExpireUserApiKeyMutation[\"expireUserApiKey\"],\n): ListUserApiKeysResponseData {\n switch (result.__typename) {\n case \"UserApiKeyExpired\":\n return toUserApiKey(result.apiKey);\n case \"ApiKeyAlreadyExpired\":\n throw apiKeyMutationFailure(\n result.__typename,\n \"API key is already expired\",\n );\n }\n}\n\nexport const useUserApiKeys = () => {\n const {\n state: { pagination, searchQuery },\n } = useUserApiKeysContext();\n const { before, after } = pagination || {};\n const variables = {\n after: after ?? undefined,\n before: before ?? undefined,\n limit: API_KEYS_PAGE_SIZE,\n search: searchQuery || undefined,\n };\n\n return useClientGraphqlQuery({\n queryKey: clientGraphqlQueryKey(\"ListUserApiKeys\", variables),\n queryFn: async (sdk) => {\n const { userApiKeys } = await sdk.ListUserApiKeys(variables);\n return userApiKeys;\n },\n select: (list): ListUserApiKeysResponse => ({\n data: list.data.map(toUserApiKey),\n list_metadata: {\n after: list.listMetadata.after ?? undefined,\n before: list.listMetadata.before ?? undefined,\n },\n }),\n placeholderData: keepPreviousData,\n });\n};\n\nconst useInvalidateUserApiKeys = () => {\n const queryClient = useQueryClient();\n return () => queryClient.invalidateQueries({ queryKey: userApiKeysQueryKey });\n};\n\nexport const useCreateUserApiKeyWithInvalidation = () => {\n const invalidate = useInvalidateUserApiKeys();\n\n return useClientGraphqlMutation({\n mutationFn: async (sdk, { data }: { data: CreateUserApiKeyRequest }) => {\n const { createUserApiKey: result } = await sdk.CreateUserApiKey({\n input: {\n name: data.name,\n permissions: data.permissions,\n expiresAt: data.expiresAt ?? null,\n },\n });\n return unwrapCreateUserApiKey(result);\n },\n onSuccess: invalidate,\n });\n};\n\nexport const useDeleteUserApiKey = ({\n onSuccess,\n}: { onSuccess?: () => void } = {}) => {\n const invalidate = useInvalidateUserApiKeys();\n\n return useClientGraphqlMutation({\n mutationFn: async (sdk, { apiKeyId }: { apiKeyId: string }) => {\n const { deleteUserApiKey } = await sdk.DeleteUserApiKey({ apiKeyId });\n return toUserApiKey(deleteUserApiKey);\n },\n onSuccess: () => {\n void invalidate();\n onSuccess?.();\n },\n });\n};\n\nexport const useExpireUserApiKey = () => {\n const invalidate = useInvalidateUserApiKeys();\n\n return useClientGraphqlMutation({\n mutationFn: async (\n sdk,\n { apiKeyId, expiresAt }: { apiKeyId: string; expiresAt: string | null },\n ) => {\n const { expireUserApiKey: result } = await sdk.ExpireUserApiKey({\n input: { apiKeyId, expiresAt },\n });\n return unwrapExpireUserApiKey(result);\n },\n onSuccess: invalidate,\n });\n};\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"intl-context.cjs","names":["React"],"sources":["../../../../src/lib/i18n/intl-context.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\n\ntype MessageDescriptor = {\n id: string;\n defaultMessage: string;\n description: string;\n};\n\ntype MessageValues = Record<string, string | React.ReactNode>;\n\n/**\n * Shape of the i18n context value.\n * This mirrors the essential parts of react-intl's IntlShape without importing it.\n */\ninterface IntlContextValue {\n locale: string;\n formatMessage(\n descriptor: MessageDescriptor,\n values?: MessageValues,\n ): string | React.ReactNode[];\n}\n\n/**\n * Context for optional i18n support.\n * When this context has a value, translations will use react-intl.\n * When this context is null/undefined, translations will fall back to defaultMessage.\n */\nconst IntlContext = React.createContext<IntlContextValue | null>(null);\nIntlContext.displayName = \"IntlContext\";\n\n/**\n * Hook to access the i18n context.\n * Returns null if no IntlProvider is present in the component tree.\n */\nfunction useIntl(): IntlContextValue | null {\n return React.useContext(IntlContext);\n}\nexport type { MessageDescriptor, MessageValues };\nexport { IntlContext, useIntl };\n"],"mappings":";;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"intl-context.cjs","names":["React"],"sources":["../../../../src/lib/i18n/intl-context.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\n\ntype MessageDescriptor = {\n id: string;\n defaultMessage: string;\n description: string;\n};\n\ntype MessageValues = Record<string, string | React.ReactNode>;\n\n/**\n * Shape of the i18n context value.\n * This mirrors the essential parts of react-intl's IntlShape without importing it.\n */\ninterface IntlContextValue {\n locale: string;\n formatMessage(\n descriptor: MessageDescriptor,\n values?: Record<string, string>,\n ): string;\n formatMessage(\n descriptor: MessageDescriptor,\n values?: MessageValues,\n ): string | React.ReactNode[];\n}\n\n/**\n * Context for optional i18n support.\n * When this context has a value, translations will use react-intl.\n * When this context is null/undefined, translations will fall back to defaultMessage.\n */\nconst IntlContext = React.createContext<IntlContextValue | null>(null);\nIntlContext.displayName = \"IntlContext\";\n\n/**\n * Hook to access the i18n context.\n * Returns null if no IntlProvider is present in the component tree.\n */\nfunction useIntl(): IntlContextValue | null {\n return React.useContext(IntlContext);\n}\nexport type { MessageDescriptor, MessageValues };\nexport { IntlContext, useIntl };\n"],"mappings":";;;;;;;;;;;AAiCA,MAAM,cAAcA,MAAM,cAAuC,IAAI;AACrE,YAAY,cAAc;;;;;AAM1B,SAAS,UAAmC;CAC1C,OAAOA,MAAM,WAAW,WAAW;AACrC"}
|
|
@@ -12,6 +12,7 @@ type MessageValues = Record<string, string | React.ReactNode>;
|
|
|
12
12
|
*/
|
|
13
13
|
interface IntlContextValue {
|
|
14
14
|
locale: string;
|
|
15
|
+
formatMessage(descriptor: MessageDescriptor, values?: Record<string, string>): string;
|
|
15
16
|
formatMessage(descriptor: MessageDescriptor, values?: MessageValues): string | React.ReactNode[];
|
|
16
17
|
}
|
|
17
18
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"intl-context.d.cts","names":[],"sources":["../../../../src/lib/i18n/intl-context.tsx"],"mappings":";;KAIK;EACH;EACA;EACA;;KAGG,gBAAgB,wBAAwB,MAAM;;;;;UAMzC;EACR;EACA,cACE,YAAY,mBACZ,SAAS,yBACC,MAAM;;;;;;;cAQd,aAAW,MAAA,QAAA;;;;;iBAOR,WAAW"}
|
|
1
|
+
{"version":3,"file":"intl-context.d.cts","names":[],"sources":["../../../../src/lib/i18n/intl-context.tsx"],"mappings":";;KAIK;EACH;EACA;EACA;;KAGG,gBAAgB,wBAAwB,MAAM;;;;;UAMzC;EACR;EACA,cACE,YAAY,mBACZ,SAAS;EAEX,cACE,YAAY,mBACZ,SAAS,yBACC,MAAM;;;;;;;cAQd,aAAW,MAAA,QAAA;;;;;iBAOR,WAAW"}
|
|
@@ -13,11 +13,11 @@ function useTranslation() {
|
|
|
13
13
|
const formatMessage = require_lib_i18n_intl_context.useIntl()?.formatMessage ?? null;
|
|
14
14
|
return (0, react.useCallback)((params) => {
|
|
15
15
|
const { defaultMessage, description, id, values } = params;
|
|
16
|
-
if (formatMessage) return
|
|
16
|
+
if (formatMessage) return formatMessage({
|
|
17
17
|
id,
|
|
18
18
|
defaultMessage,
|
|
19
19
|
description
|
|
20
|
-
}, values)
|
|
20
|
+
}, values);
|
|
21
21
|
if (!values) return defaultMessage;
|
|
22
22
|
return defaultMessage.replace(/\{(\w+)\}/g, (match, key) => {
|
|
23
23
|
return key in values ? String(values[key]) : match;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-translation.cjs","names":["useIntl","useCallback"],"sources":["../../../../src/lib/i18n/use-translation.ts"],"sourcesContent":["\"use client\";\n\nimport { useCallback } from \"react\";\nimport { useIntl } from \"./intl-context.js\";\nimport type { MessageDescriptor } from \"./intl-context.js\";\n\ntype TranslationParams = MessageDescriptor & {\n values?: Record<string, string>;\n};\n\n/**\n * Translation hook that gracefully degrades when no I18nProvider is present.\n *\n * - With I18nProvider: Uses react-intl's formatMessage for full i18n support (react-intl will be bundled)\n * - Without I18nProvider: Returns the defaultMessage with simple string interpolation (no react-intl bundled)\n */\nexport function useTranslation() {\n const i18n = useIntl();\n const formatMessage = i18n?.formatMessage ?? null;\n\n return useCallback(\n (params: TranslationParams): string => {\n const { defaultMessage, description, id, values } = params;\n\n // If I18nProvider is present, use react-intl's formatMessage\n if (formatMessage) {\n
|
|
1
|
+
{"version":3,"file":"use-translation.cjs","names":["useIntl","useCallback"],"sources":["../../../../src/lib/i18n/use-translation.ts"],"sourcesContent":["\"use client\";\n\nimport { useCallback } from \"react\";\nimport { useIntl } from \"./intl-context.js\";\nimport type { MessageDescriptor } from \"./intl-context.js\";\n\ntype TranslationParams = MessageDescriptor & {\n values?: Record<string, string>;\n};\n\n/**\n * Translation hook that gracefully degrades when no I18nProvider is present.\n *\n * - With I18nProvider: Uses react-intl's formatMessage for full i18n support (react-intl will be bundled)\n * - Without I18nProvider: Returns the defaultMessage with simple string interpolation (no react-intl bundled)\n */\nexport function useTranslation() {\n const i18n = useIntl();\n const formatMessage = i18n?.formatMessage ?? null;\n\n return useCallback(\n (params: TranslationParams): string => {\n const { defaultMessage, description, id, values } = params;\n\n // If I18nProvider is present, use react-intl's formatMessage\n if (formatMessage) {\n return formatMessage({ id, defaultMessage, description }, values);\n }\n\n // If no I18nProvider is present, return defaultMessage with simple interpolation\n if (!values) {\n return defaultMessage;\n }\n\n // Simple string interpolation for values\n return defaultMessage.replace(/\\{(\\w+)\\}/g, (match, key) => {\n return key in values ? String(values[key]) : match;\n });\n },\n [formatMessage],\n );\n}\n"],"mappings":";;;;;;;;;;;AAgBA,SAAgB,iBAAiB;CAE/B,MAAM,gBADOA,8BAAAA,QACS,CAAA,EAAM,iBAAiB;CAE7C,QAAA,GAAOC,MAAAA,YAAAA,EACJ,WAAsC;EACrC,MAAM,EAAE,gBAAgB,aAAa,IAAI,WAAW;EAGpD,IAAI,eACF,OAAO,cAAc;GAAE;GAAI;GAAgB;EAAY,GAAG,MAAM;EAIlE,IAAI,CAAC,QACH,OAAO;EAIT,OAAO,eAAe,QAAQ,eAAe,OAAO,QAAQ;GAC1D,OAAO,OAAO,SAAS,OAAO,OAAO,IAAI,IAAI;EAC/C,CAAC;CACH,GACA,CAAC,aAAa,CAChB;AACF"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_runtime = require("../_virtual/_rolldown/runtime.cjs");
|
|
3
|
+
let react = require("react");
|
|
4
|
+
react = require_runtime.__toESM(react, 1);
|
|
5
|
+
//#region src/lib/use-composed-event-handlers.ts
|
|
6
|
+
function useComposedEventHandlers(originalEventHandler, ourEventHandler) {
|
|
7
|
+
return react.useCallback((event) => {
|
|
8
|
+
originalEventHandler?.(event);
|
|
9
|
+
if (!event?.defaultPrevented) ourEventHandler?.(event);
|
|
10
|
+
}, [originalEventHandler, ourEventHandler]);
|
|
11
|
+
}
|
|
12
|
+
//#endregion
|
|
13
|
+
exports.useComposedEventHandlers = useComposedEventHandlers;
|
|
14
|
+
|
|
15
|
+
//# sourceMappingURL=use-composed-event-handlers.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-composed-event-handlers.cjs","names":["React"],"sources":["../../../src/lib/use-composed-event-handlers.ts"],"sourcesContent":["import * as React from \"react\";\n\nexport function useComposedEventHandlers<\n E extends { defaultPrevented: boolean },\n>(\n originalEventHandler?: (event: E) => void,\n ourEventHandler?: (event: E) => void,\n): (event: E) => void;\n\nexport function useComposedEventHandlers<\n E extends { defaultPrevented: boolean },\n>(\n originalEventHandler?: (event: E) => void,\n ourEventHandler?: (event: E) => void,\n): (event: E) => void {\n return React.useCallback(\n (event: E) => {\n originalEventHandler?.(event);\n if (!event?.defaultPrevented) {\n ourEventHandler?.(event);\n }\n },\n [originalEventHandler, ourEventHandler],\n );\n}\n"],"mappings":";;;;;AASA,SAAgB,yBAGd,sBACA,iBACoB;CACpB,OAAOA,MAAM,aACV,UAAa;EACZ,uBAAuB,KAAK;EAC5B,IAAI,CAAC,OAAO,kBACV,kBAAkB,KAAK;CAE3B,GACA,CAAC,sBAAsB,eAAe,CACxC;AACF"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
//#region src/lib/use-composed-event-handlers.d.ts
|
|
2
|
+
export declare function useComposedEventHandlers<E extends {
|
|
3
|
+
defaultPrevented: boolean;
|
|
4
|
+
}>(originalEventHandler?: (event: E) => void, ourEventHandler?: (event: E) => void): (event: E) => void;
|
|
5
|
+
//#endregion
|
|
6
|
+
//# sourceMappingURL=use-composed-event-handlers.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-composed-event-handlers.d.cts","names":[],"sources":["../../../src/lib/use-composed-event-handlers.ts"],"mappings":";wBAEgB,yBACd;EAAY;GAEZ,wBAAwB,OAAO,YAC/B,mBAAmB,OAAO,cACxB,OAAO"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
const require_runtime = require("../_virtual/_rolldown/runtime.cjs");
|
|
3
|
+
const require_lib_use_layout_effect = require("./use-layout-effect.cjs");
|
|
3
4
|
const require_lib_utils = require("./utils.cjs");
|
|
4
5
|
let react = require("react");
|
|
5
6
|
react = require_runtime.__toESM(react, 1);
|
|
@@ -34,34 +35,25 @@ react = require_runtime.__toESM(react, 1);
|
|
|
34
35
|
* article](https://css-tricks.com/debouncing-throttling-explained-examples/)
|
|
35
36
|
* for details over the differences between `debounce` and `throttle`.
|
|
36
37
|
*
|
|
37
|
-
* @
|
|
38
|
-
* @param
|
|
39
|
-
* @
|
|
40
|
-
* `requestAnimationFrame` is used (if available, otherwise it will be
|
|
41
|
-
* setTimeout(...,0)).
|
|
42
|
-
* @param {Object} [options={}] The options object. Controls if `func` should be
|
|
43
|
-
* invoked on the leading edge of the timeout.
|
|
44
|
-
* @param {boolean} [options.leading=false] The maximum time `func` is allowed
|
|
45
|
-
* to be delayed before it's invoked.
|
|
46
|
-
* @param {number} [options.maxWait] Controls if `func` should be invoked the
|
|
47
|
-
* trailing edge of the timeout.
|
|
48
|
-
* @param {boolean} [options.trailing=true]
|
|
49
|
-
* @returns {Function} Returns the new debounced function.
|
|
38
|
+
* @param func The function to debounce
|
|
39
|
+
* @param options The options object
|
|
40
|
+
* @returns Returns the new debounced function.
|
|
50
41
|
* @example
|
|
51
42
|
* ```tsx
|
|
52
43
|
* // Avoid costly calculations while the window size is in flux.
|
|
53
|
-
* const resizeHandler = useDebouncedCallback(calculateLayout, 150);
|
|
44
|
+
* const resizeHandler = useDebouncedCallback(calculateLayout, { wait: 150 });
|
|
54
45
|
* window.addEventListener('resize', resizeHandler)
|
|
55
46
|
*
|
|
56
47
|
* // Invoke `sendMail` when clicked, debouncing subsequent calls.
|
|
57
|
-
* const clickHandler = useDebouncedCallback(sendMail,
|
|
48
|
+
* const clickHandler = useDebouncedCallback(sendMail, {
|
|
49
|
+
* wait: 300,
|
|
58
50
|
* leading: true,
|
|
59
51
|
* trailing: false,
|
|
60
52
|
* })
|
|
61
53
|
* <button onClick={clickHandler}>click me</button>
|
|
62
54
|
*
|
|
63
55
|
* // Ensure `batchLog` is invoked once after 1 second of debounced calls.
|
|
64
|
-
* const debounced = useDebouncedCallback(batchLog, 250,
|
|
56
|
+
* const debounced = useDebouncedCallback(batchLog, { wait: 250, maxWait: 1000 })
|
|
65
57
|
* const source = new EventSource('/stream')
|
|
66
58
|
* source.addEventListener('message', debounced)
|
|
67
59
|
*
|
|
@@ -72,125 +64,141 @@ react = require_runtime.__toESM(react, 1);
|
|
|
72
64
|
* const status = debounced.isPending() ? "Pending..." : "Ready"
|
|
73
65
|
* ```
|
|
74
66
|
*/
|
|
75
|
-
function useDebouncedCallback(func,
|
|
76
|
-
const
|
|
77
|
-
const
|
|
78
|
-
const timerId = react.useRef(null);
|
|
79
|
-
const lastArgs = react.useRef(null);
|
|
80
|
-
const lastThis = react.useRef(void 0);
|
|
81
|
-
const result = react.useRef(void 0);
|
|
82
|
-
const funcRef = react.useRef(func);
|
|
83
|
-
const mounted = react.useRef(true);
|
|
84
|
-
const visibilityListener = react.useRef(null);
|
|
85
|
-
const debouncedRef = react.useRef(void 0);
|
|
86
|
-
funcRef.current = func;
|
|
87
|
-
const useRAF = !wait && wait !== 0 && require_lib_utils.canUseDOM;
|
|
88
|
-
if (typeof func !== "function") throw new TypeError("Expected a function");
|
|
89
|
-
wait = +(wait || 0);
|
|
90
|
-
options = options || {};
|
|
91
|
-
const leading = !!options.leading;
|
|
92
|
-
const trailing = "trailing" in options ? !!options.trailing : true;
|
|
67
|
+
function useDebouncedCallback(func, options = {}) {
|
|
68
|
+
const { wait = 0, leading = false, trailing = true, maxWait: maxWaitOption, debounceOnServer = false } = options;
|
|
69
|
+
const useRAF = options.wait === void 0 && require_lib_utils.canUseDOM;
|
|
93
70
|
const flushOnExit = !!options.flushOnExit && trailing;
|
|
94
|
-
const
|
|
95
|
-
const
|
|
96
|
-
|
|
71
|
+
const maxWait = maxWaitOption === void 0 ? null : Math.max(maxWaitOption ?? 0, wait);
|
|
72
|
+
const stateRef = react.useRef({
|
|
73
|
+
func,
|
|
74
|
+
lastCallTime: null,
|
|
75
|
+
lastInvokeTime: 0,
|
|
76
|
+
timerId: null,
|
|
77
|
+
lastArgs: null,
|
|
78
|
+
lastThis: void 0,
|
|
79
|
+
result: void 0,
|
|
80
|
+
mounted: true,
|
|
81
|
+
visibilityListener: null,
|
|
82
|
+
debounced: void 0
|
|
83
|
+
});
|
|
97
84
|
const debounced = react.useMemo(() => {
|
|
98
|
-
const
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
85
|
+
const config = {
|
|
86
|
+
wait,
|
|
87
|
+
maxWait,
|
|
88
|
+
leading,
|
|
89
|
+
trailing,
|
|
90
|
+
flushOnExit,
|
|
91
|
+
useRAF,
|
|
92
|
+
debounceOnServer
|
|
104
93
|
};
|
|
105
|
-
const
|
|
106
|
-
|
|
107
|
-
timerId.current = useRAF ? requestAnimationFrame(pendingFunc) : setTimeout(pendingFunc, wait);
|
|
94
|
+
const debounced = function(...args) {
|
|
95
|
+
return debounce(stateRef.current, config, this, args);
|
|
108
96
|
};
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
return !lastCallTime.current || timeSinceLastCall >= wait || timeSinceLastCall < 0 || maxing && timeSinceLastInvoke >= (maxWait || 0);
|
|
114
|
-
};
|
|
115
|
-
const trailingEdge = (time) => {
|
|
116
|
-
timerId.current = null;
|
|
117
|
-
if (trailing && lastArgs.current) return invokeFunc(time);
|
|
118
|
-
lastArgs.current = lastThis.current = null;
|
|
119
|
-
return result.current;
|
|
120
|
-
};
|
|
121
|
-
const timerExpired = () => {
|
|
122
|
-
const time = Date.now();
|
|
123
|
-
if (shouldInvoke(time)) return trailingEdge(time);
|
|
124
|
-
if (!mounted.current) return;
|
|
125
|
-
const timeSinceLastCall = time - (lastCallTime.current || 0);
|
|
126
|
-
const timeSinceLastInvoke = time - lastInvokeTime.current;
|
|
127
|
-
const timeWaiting = wait - timeSinceLastCall;
|
|
128
|
-
const remainingWait = maxing ? Math.min(timeWaiting, (maxWait || 0) - timeSinceLastInvoke) : timeWaiting;
|
|
129
|
-
startTimer(timerExpired, remainingWait);
|
|
130
|
-
};
|
|
131
|
-
const func = (...args) => {
|
|
132
|
-
if (!require_lib_utils.canUseDOM && !debounceOnServer) return;
|
|
133
|
-
const time = Date.now();
|
|
134
|
-
const isInvoking = shouldInvoke(time);
|
|
135
|
-
lastArgs.current = args;
|
|
136
|
-
lastThis.current = this;
|
|
137
|
-
lastCallTime.current = time;
|
|
138
|
-
if (flushOnExit && !visibilityListener.current) {
|
|
139
|
-
visibilityListener.current = () => {
|
|
140
|
-
if (globalThis.document?.visibilityState === "hidden") debouncedRef.current?.flush();
|
|
141
|
-
};
|
|
142
|
-
globalThis.document?.addEventListener?.("visibilitychange", visibilityListener.current);
|
|
143
|
-
}
|
|
144
|
-
if (isInvoking) {
|
|
145
|
-
if (!timerId.current && mounted.current) {
|
|
146
|
-
lastInvokeTime.current = lastCallTime.current;
|
|
147
|
-
startTimer(timerExpired, wait);
|
|
148
|
-
return leading ? invokeFunc(lastCallTime.current) : result.current;
|
|
149
|
-
}
|
|
150
|
-
if (maxing) {
|
|
151
|
-
startTimer(timerExpired, wait);
|
|
152
|
-
return invokeFunc(lastCallTime.current);
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
if (!timerId.current) startTimer(timerExpired, wait);
|
|
156
|
-
return result.current;
|
|
157
|
-
};
|
|
158
|
-
func.cancel = () => {
|
|
159
|
-
if (timerId.current) useRAF ? cancelAnimationFrame(timerId.current) : clearTimeout(timerId.current);
|
|
160
|
-
lastInvokeTime.current = 0;
|
|
161
|
-
lastArgs.current = lastCallTime.current = lastThis.current = timerId.current = null;
|
|
162
|
-
};
|
|
163
|
-
func.isPending = () => {
|
|
164
|
-
return !!timerId.current;
|
|
165
|
-
};
|
|
166
|
-
func.flush = () => {
|
|
167
|
-
return !timerId.current ? result.current : trailingEdge(Date.now());
|
|
168
|
-
};
|
|
169
|
-
return func;
|
|
97
|
+
debounced.cancel = () => cancel(stateRef.current, config);
|
|
98
|
+
debounced.isPending = () => !!stateRef.current.timerId;
|
|
99
|
+
debounced.flush = () => flush(stateRef.current, config);
|
|
100
|
+
return debounced;
|
|
170
101
|
}, [
|
|
171
|
-
leading,
|
|
172
|
-
maxing,
|
|
173
102
|
wait,
|
|
174
103
|
maxWait,
|
|
104
|
+
leading,
|
|
175
105
|
trailing,
|
|
176
106
|
flushOnExit,
|
|
177
107
|
useRAF,
|
|
178
108
|
debounceOnServer
|
|
179
109
|
]);
|
|
180
|
-
|
|
110
|
+
require_lib_use_layout_effect.useLayoutEffect(() => {
|
|
111
|
+
stateRef.current.func = func;
|
|
112
|
+
stateRef.current.debounced = debounced;
|
|
113
|
+
});
|
|
181
114
|
react.useEffect(() => {
|
|
182
|
-
|
|
115
|
+
const state = stateRef.current;
|
|
116
|
+
state.mounted = true;
|
|
183
117
|
return () => {
|
|
184
|
-
if (flushOnExit)
|
|
185
|
-
if (visibilityListener
|
|
186
|
-
globalThis.document?.removeEventListener?.("visibilitychange", visibilityListener
|
|
187
|
-
visibilityListener
|
|
118
|
+
if (flushOnExit) state.debounced?.flush();
|
|
119
|
+
if (state.visibilityListener) {
|
|
120
|
+
globalThis.document?.removeEventListener?.("visibilitychange", state.visibilityListener);
|
|
121
|
+
state.visibilityListener = null;
|
|
188
122
|
}
|
|
189
|
-
mounted
|
|
123
|
+
state.mounted = false;
|
|
190
124
|
};
|
|
191
125
|
}, [flushOnExit]);
|
|
192
126
|
return debounced;
|
|
193
127
|
}
|
|
128
|
+
function invokeFunc(state, time) {
|
|
129
|
+
const args = state.lastArgs;
|
|
130
|
+
const thisArg = state.lastThis;
|
|
131
|
+
state.lastArgs = state.lastThis = null;
|
|
132
|
+
state.lastInvokeTime = time;
|
|
133
|
+
return state.result = state.func.apply(thisArg, args || []);
|
|
134
|
+
}
|
|
135
|
+
function startTimer(state, config, wait) {
|
|
136
|
+
const onTimer = () => timerExpired(state, config);
|
|
137
|
+
if (config.useRAF) cancelAnimationFrame(state.timerId);
|
|
138
|
+
state.timerId = config.useRAF ? requestAnimationFrame(onTimer) : setTimeout(onTimer, wait);
|
|
139
|
+
}
|
|
140
|
+
function shouldInvoke(state, { wait, maxWait }, time) {
|
|
141
|
+
if (!state.mounted) return false;
|
|
142
|
+
const timeSinceLastCall = time - (state.lastCallTime || 0);
|
|
143
|
+
const timeSinceLastInvoke = time - state.lastInvokeTime;
|
|
144
|
+
return !state.lastCallTime || timeSinceLastCall >= wait || timeSinceLastCall < 0 || maxWait !== null && timeSinceLastInvoke >= maxWait;
|
|
145
|
+
}
|
|
146
|
+
function trailingEdge(state, config, time) {
|
|
147
|
+
state.timerId = null;
|
|
148
|
+
if (config.trailing && state.lastArgs) return invokeFunc(state, time);
|
|
149
|
+
state.lastArgs = state.lastThis = null;
|
|
150
|
+
return state.result;
|
|
151
|
+
}
|
|
152
|
+
function timerExpired(state, config) {
|
|
153
|
+
const time = Date.now();
|
|
154
|
+
if (shouldInvoke(state, config, time)) {
|
|
155
|
+
trailingEdge(state, config, time);
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
if (!state.mounted) return;
|
|
159
|
+
const timeSinceLastCall = time - (state.lastCallTime || 0);
|
|
160
|
+
const timeSinceLastInvoke = time - state.lastInvokeTime;
|
|
161
|
+
const timeWaiting = config.wait - timeSinceLastCall;
|
|
162
|
+
startTimer(state, config, config.maxWait !== null ? Math.min(timeWaiting, config.maxWait - timeSinceLastInvoke) : timeWaiting);
|
|
163
|
+
}
|
|
164
|
+
function debounce(state, config, thisArg, args) {
|
|
165
|
+
if (!require_lib_utils.canUseDOM && !config.debounceOnServer) return;
|
|
166
|
+
const time = Date.now();
|
|
167
|
+
const isInvoking = shouldInvoke(state, config, time);
|
|
168
|
+
state.lastArgs = args;
|
|
169
|
+
state.lastThis = thisArg;
|
|
170
|
+
state.lastCallTime = time;
|
|
171
|
+
if (config.flushOnExit && !state.visibilityListener) {
|
|
172
|
+
state.visibilityListener = () => {
|
|
173
|
+
if (globalThis.document?.visibilityState === "hidden") state.debounced?.flush();
|
|
174
|
+
};
|
|
175
|
+
globalThis.document?.addEventListener?.("visibilitychange", state.visibilityListener);
|
|
176
|
+
}
|
|
177
|
+
if (isInvoking) {
|
|
178
|
+
if (!state.timerId && state.mounted) {
|
|
179
|
+
state.lastInvokeTime = time;
|
|
180
|
+
startTimer(state, config, config.wait);
|
|
181
|
+
return config.leading ? invokeFunc(state, time) : state.result;
|
|
182
|
+
}
|
|
183
|
+
if (config.maxWait !== null) {
|
|
184
|
+
startTimer(state, config, config.wait);
|
|
185
|
+
return invokeFunc(state, time);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
if (!state.timerId) startTimer(state, config, config.wait);
|
|
189
|
+
return state.result;
|
|
190
|
+
}
|
|
191
|
+
function cancel(state, config) {
|
|
192
|
+
if (state.timerId) {
|
|
193
|
+
if (config.useRAF) cancelAnimationFrame(state.timerId);
|
|
194
|
+
else clearTimeout(state.timerId);
|
|
195
|
+
}
|
|
196
|
+
state.lastInvokeTime = 0;
|
|
197
|
+
state.lastArgs = state.lastCallTime = state.lastThis = state.timerId = null;
|
|
198
|
+
}
|
|
199
|
+
function flush(state, config) {
|
|
200
|
+
return !state.timerId ? state.result : trailingEdge(state, config, Date.now());
|
|
201
|
+
}
|
|
194
202
|
//#endregion
|
|
195
203
|
exports.useDebouncedCallback = useDebouncedCallback;
|
|
196
204
|
|