@clerk/shared
Version:
Internal package utils used by the Clerk SDKs
705 lines (694 loc) • 22.9 kB
JavaScript
"use strict";
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/react/index.ts
var react_exports = {};
__export(react_exports, {
ClerkInstanceContext: () => ClerkInstanceContext,
ClientContext: () => ClientContext,
OrganizationContext: () => OrganizationContext,
OrganizationProvider: () => OrganizationProvider,
SessionContext: () => SessionContext,
UserContext: () => UserContext,
assertContextExists: () => assertContextExists,
createContextAndHook: () => createContextAndHook,
useClerkInstanceContext: () => useClerkInstanceContext,
useClientContext: () => useClientContext,
useOrganization: () => useOrganization,
useOrganizationContext: () => useOrganizationContext,
useOrganizationList: () => useOrganizationList,
useOrganizations: () => useOrganizations,
useSafeLayoutEffect: () => useSafeLayoutEffect,
useSessionContext: () => useSessionContext,
useUserContext: () => useUserContext
});
module.exports = __toCommonJS(react_exports);
// src/react/hooks/createContextAndHook.ts
var import_react = __toESM(require("react"));
function assertContextExists(contextVal, msgOrCtx) {
if (!contextVal) {
throw typeof msgOrCtx === "string" ? new Error(msgOrCtx) : new Error(`${msgOrCtx.displayName} not found`);
}
}
var createContextAndHook = (displayName, options) => {
const { assertCtxFn = assertContextExists } = options || {};
const Ctx = import_react.default.createContext(void 0);
Ctx.displayName = displayName;
const useCtx = () => {
const ctx = import_react.default.useContext(Ctx);
assertCtxFn(ctx, `${displayName} not found`);
return ctx.value;
};
const useCtxWithoutGuarantee = () => {
const ctx = import_react.default.useContext(Ctx);
return ctx ? ctx.value : {};
};
return [Ctx, useCtx, useCtxWithoutGuarantee];
};
// src/utils/runtimeEnvironment.ts
var isTestEnvironment = () => {
try {
return process.env.NODE_ENV === "test";
} catch (err) {
}
return false;
};
var isProductionEnvironment = () => {
try {
return process.env.NODE_ENV === "production";
} catch (err) {
}
return false;
};
// src/deprecated.ts
var displayedWarnings = /* @__PURE__ */ new Set();
var deprecated = (fnName, warning, key) => {
const hideWarning = isTestEnvironment() || isProductionEnvironment();
const messageId = key ?? fnName;
if (displayedWarnings.has(messageId) || hideWarning) {
return;
}
displayedWarnings.add(messageId);
console.warn(
`Clerk - DEPRECATION WARNING: "${fnName}" is deprecated and will be removed in the next major release.
${warning}`
);
};
var deprecatedObjectProperty = (obj, propName, warning, key) => {
let value = obj[propName];
Object.defineProperty(obj, propName, {
get() {
deprecated(propName, warning, key);
return value;
},
set(v) {
value = v;
}
});
};
// src/react/clerk-swr.ts
var clerk_swr_exports = {};
__export(clerk_swr_exports, {
SWRConfig: () => import_swr.SWRConfig,
useSWR: () => import_swr.default,
useSWRInfinite: () => import_infinite.default
});
__reExport(clerk_swr_exports, require("swr"));
var import_swr = __toESM(require("swr"));
var import_infinite = __toESM(require("swr/infinite"));
// src/react/contexts.tsx
var import_react2 = __toESM(require("react"));
var [ClerkInstanceContext, useClerkInstanceContext] = createContextAndHook("ClerkInstanceContext");
var [UserContext, useUserContext] = createContextAndHook("UserContext");
var [ClientContext, useClientContext] = createContextAndHook("ClientContext");
var [SessionContext, useSessionContext] = createContextAndHook(
"SessionContext"
);
var [OrganizationContextInternal, useOrganizationContext] = createContextAndHook("OrganizationContext");
var OrganizationProvider = ({
children,
organization,
lastOrganizationMember,
lastOrganizationInvitation,
swrConfig
}) => {
return /* @__PURE__ */ import_react2.default.createElement(import_swr.SWRConfig, { value: swrConfig }, /* @__PURE__ */ import_react2.default.createElement(
OrganizationContextInternal.Provider,
{
value: {
value: {
organization,
lastOrganizationMember,
lastOrganizationInvitation
}
}
},
children
));
};
var OrganizationContext = (...args) => {
deprecated("OrganizationContext", "Use `OrganizationProvider` instead");
return OrganizationProvider(...args);
};
// src/react/hooks/usePagesOrInfinite.ts
var import_react3 = require("react");
function getDifferentKeys(obj1, obj2) {
const keysSet = new Set(Object.keys(obj2));
const differentKeysObject = {};
for (const key1 of Object.keys(obj1)) {
if (!keysSet.has(key1)) {
differentKeysObject[key1] = obj1[key1];
}
}
return differentKeysObject;
}
var useWithSafeValues = (params, defaultValues) => {
const shouldUseDefaults = typeof params === "boolean" && params;
const initialPageRef = (0, import_react3.useRef)(
shouldUseDefaults ? defaultValues.initialPage : params?.initialPage ?? defaultValues.initialPage
);
const pageSizeRef = (0, import_react3.useRef)(shouldUseDefaults ? defaultValues.pageSize : params?.pageSize ?? defaultValues.pageSize);
const newObj = {};
for (const key of Object.keys(defaultValues)) {
newObj[key] = shouldUseDefaults ? defaultValues[key] : params?.[key] ?? defaultValues[key];
}
return {
...newObj,
initialPage: initialPageRef.current,
pageSize: pageSizeRef.current
};
};
var usePagesOrInfinite = (params, fetcher, options, cacheKeys) => {
const [paginatedPage, setPaginatedPage] = (0, import_react3.useState)(params.initialPage ?? 1);
const initialPageRef = (0, import_react3.useRef)(params.initialPage ?? 1);
const pageSizeRef = (0, import_react3.useRef)(params.pageSize ?? 10);
const enabled = options.enabled ?? true;
const triggerInfinite = options.infinite ?? false;
const keepPreviousData = options.keepPreviousData ?? false;
const pagesCacheKey = {
...cacheKeys,
...params,
initialPage: paginatedPage,
pageSize: pageSizeRef.current
};
const {
data: swrData,
isValidating: swrIsValidating,
isLoading: swrIsLoading,
error: swrError,
mutate: swrMutate
} = (0, import_swr.default)(
!triggerInfinite && !!fetcher && enabled ? pagesCacheKey : null,
(cacheKeyParams) => {
const requestParams = getDifferentKeys(cacheKeyParams, cacheKeys);
return fetcher?.(requestParams);
},
{ keepPreviousData }
);
const {
data: swrInfiniteData,
isLoading: swrInfiniteIsLoading,
isValidating: swrInfiniteIsValidating,
error: swrInfiniteError,
size,
setSize,
mutate: swrInfiniteMutate
} = (0, import_infinite.default)(
(pageIndex) => {
if (!triggerInfinite || !enabled) {
return null;
}
return {
...params,
...cacheKeys,
initialPage: initialPageRef.current + pageIndex,
pageSize: pageSizeRef.current
};
},
(cacheKeyParams) => {
const requestParams = getDifferentKeys(cacheKeyParams, cacheKeys);
return fetcher?.(requestParams);
}
);
const page = (0, import_react3.useMemo)(() => {
if (triggerInfinite) {
return size;
}
return paginatedPage;
}, [triggerInfinite, size, paginatedPage]);
const fetchPage = (0, import_react3.useCallback)(
(numberOrgFn) => {
if (triggerInfinite) {
void setSize(numberOrgFn);
return;
}
return setPaginatedPage(numberOrgFn);
},
[setSize]
);
const data = (0, import_react3.useMemo)(() => {
if (triggerInfinite) {
return swrInfiniteData?.map((a) => a?.data).flat() ?? [];
}
return swrData?.data ?? [];
}, [triggerInfinite, swrData, swrInfiniteData]);
const count = (0, import_react3.useMemo)(() => {
if (triggerInfinite) {
return swrInfiniteData?.[swrInfiniteData?.length - 1]?.total_count || 0;
}
return swrData?.total_count ?? 0;
}, [triggerInfinite, swrData, swrInfiniteData]);
const isLoading = triggerInfinite ? swrInfiniteIsLoading : swrIsLoading;
const isFetching = triggerInfinite ? swrInfiniteIsValidating : swrIsValidating;
const isError = !!(triggerInfinite ? swrInfiniteError : swrError);
const fetchNext = (0, import_react3.useCallback)(() => {
fetchPage((n) => Math.max(0, n + 1));
}, [fetchPage]);
const fetchPrevious = (0, import_react3.useCallback)(() => {
fetchPage((n) => Math.max(0, n - 1));
}, [fetchPage]);
const offsetCount = (initialPageRef.current - 1) * pageSizeRef.current;
const pageCount = Math.ceil((count - offsetCount) / pageSizeRef.current);
const hasNextPage = count - offsetCount * pageSizeRef.current > page * pageSizeRef.current;
const hasPreviousPage = (page - 1) * pageSizeRef.current > offsetCount * pageSizeRef.current;
const unstable__mutate = triggerInfinite ? swrInfiniteMutate : swrMutate;
return {
data,
count,
isLoading,
isFetching,
isError,
page,
pageCount,
fetchPage,
fetchNext,
fetchPrevious,
hasNextPage,
hasPreviousPage,
unstable__mutate
};
};
// src/react/hooks/useOrganization.tsx
var undefinedPaginatedResource = {
data: void 0,
count: void 0,
isLoading: false,
isFetching: false,
isError: false,
page: void 0,
pageCount: void 0,
fetchPage: void 0,
fetchNext: void 0,
fetchPrevious: void 0,
hasNextPage: false,
hasPreviousPage: false
};
var useOrganization = (params) => {
const {
invitationList: invitationListParams,
membershipList: membershipListParams,
domains: domainListParams,
membershipRequests: membershipRequestsListParams,
memberships: membersListParams,
invitations: invitationsListParams
} = params || {};
const { organization, lastOrganizationMember, lastOrganizationInvitation } = useOrganizationContext();
const session = useSessionContext();
const domainSafeValues = useWithSafeValues(domainListParams, {
initialPage: 1,
pageSize: 10,
keepPreviousData: false,
infinite: false,
enrollmentMode: void 0
});
const membershipRequestSafeValues = useWithSafeValues(membershipRequestsListParams, {
initialPage: 1,
pageSize: 10,
status: "pending",
keepPreviousData: false,
infinite: false
});
const membersSafeValues = useWithSafeValues(membersListParams, {
initialPage: 1,
pageSize: 10,
role: void 0,
keepPreviousData: false,
infinite: false
});
const invitationsSafeValues = useWithSafeValues(invitationsListParams, {
initialPage: 1,
pageSize: 10,
status: ["pending"],
keepPreviousData: false,
infinite: false
});
const clerk = useClerkInstanceContext();
const shouldFetch = !!(clerk.loaded && session && organization);
const domainParams = typeof domainListParams === "undefined" ? void 0 : {
initialPage: domainSafeValues.initialPage,
pageSize: domainSafeValues.pageSize,
enrollmentMode: domainSafeValues.enrollmentMode
};
const membershipRequestParams = typeof membershipRequestsListParams === "undefined" ? void 0 : {
initialPage: membershipRequestSafeValues.initialPage,
pageSize: membershipRequestSafeValues.pageSize,
status: membershipRequestSafeValues.status
};
const membersParams = typeof membersListParams === "undefined" ? void 0 : {
initialPage: membersSafeValues.initialPage,
pageSize: membersSafeValues.pageSize,
role: membersSafeValues.role
};
const invitationsParams = typeof invitationsListParams === "undefined" ? void 0 : {
initialPage: invitationsSafeValues.initialPage,
pageSize: invitationsSafeValues.pageSize,
status: invitationsSafeValues.status
};
const domains = usePagesOrInfinite(
{
...domainParams
},
organization?.getDomains,
{
keepPreviousData: domainSafeValues.keepPreviousData,
infinite: domainSafeValues.infinite,
enabled: !!domainParams
},
{
type: "domains",
organizationId: organization?.id
}
);
const membershipRequests = usePagesOrInfinite(
{
...membershipRequestParams
},
organization?.getMembershipRequests,
{
keepPreviousData: membershipRequestSafeValues.keepPreviousData,
infinite: membershipRequestSafeValues.infinite,
enabled: !!membershipRequestParams
},
{
type: "membershipRequests",
organizationId: organization?.id
}
);
const memberships = usePagesOrInfinite(
{
...membersParams,
paginated: true
},
organization?.getMemberships,
{
keepPreviousData: membersSafeValues.keepPreviousData,
infinite: membersSafeValues.infinite,
enabled: !!membersParams
},
{
type: "members",
organizationId: organization?.id
}
);
const invitations = usePagesOrInfinite(
{
...invitationsParams
},
organization?.getInvitations,
{
keepPreviousData: membersSafeValues.keepPreviousData,
infinite: membersSafeValues.infinite,
enabled: !!invitationsParams
},
{
type: "invitations",
organizationId: organization?.id
}
);
const pendingInvitations = !clerk.loaded ? () => [] : () => clerk.organization?.getPendingInvitations(invitationListParams);
const currentOrganizationMemberships = !clerk.loaded ? () => [] : () => clerk.organization?.getMemberships(membershipListParams);
if (invitationListParams) {
deprecated("invitationList in useOrganization", "Use the `invitations` property and return value instead.");
}
const {
data: invitationList,
isValidating: isInvitationsLoading,
mutate: mutateInvitationList
} = (0, import_swr.default)(
shouldFetch && invitationListParams ? cacheKey("invites", organization, lastOrganizationInvitation, invitationListParams) : null,
pendingInvitations
);
if (membershipListParams) {
deprecated("membershipList in useOrganization", "Use the `memberships` property and return value instead.");
}
const {
data: membershipList,
isValidating: isMembershipsLoading,
mutate: mutateMembershipList
} = (0, import_swr.default)(
shouldFetch && membershipListParams ? cacheKey("memberships", organization, lastOrganizationMember, membershipListParams) : null,
currentOrganizationMemberships
);
if (organization === void 0) {
return {
isLoaded: false,
organization: void 0,
invitationList: void 0,
membershipList: void 0,
membership: void 0,
domains: undefinedPaginatedResource,
membershipRequests: undefinedPaginatedResource,
memberships: undefinedPaginatedResource,
invitations: undefinedPaginatedResource
};
}
if (organization === null) {
return {
isLoaded: true,
organization: null,
invitationList: null,
membershipList: null,
membership: null,
domains: null,
membershipRequests: null,
memberships: null,
invitations: null
};
}
if (!clerk.loaded && organization) {
return {
isLoaded: true,
organization,
invitationList: void 0,
membershipList: void 0,
membership: void 0,
domains: undefinedPaginatedResource,
membershipRequests: undefinedPaginatedResource,
memberships: undefinedPaginatedResource,
invitations: undefinedPaginatedResource
};
}
return {
isLoaded: !isMembershipsLoading && !isInvitationsLoading,
organization,
membershipList,
membership: getCurrentOrganizationMembership(session.user.organizationMemberships, organization.id),
// your membership in the current org
invitationList,
unstable__mutate: () => {
void mutateMembershipList();
void mutateInvitationList();
},
domains,
membershipRequests,
memberships,
invitations
};
};
function getCurrentOrganizationMembership(organizationMemberships, activeOrganizationId) {
return organizationMemberships.find(
(organizationMembership) => organizationMembership.organization.id === activeOrganizationId
);
}
function cacheKey(type, organization, resource, pagination) {
return [type, organization.id, resource?.id, resource?.updatedAt, pagination.offset, pagination.limit].filter(Boolean).join("-");
}
// src/react/hooks/useOrganizationList.tsx
var undefinedPaginatedResource2 = {
data: void 0,
count: void 0,
isLoading: false,
isFetching: false,
isError: false,
page: void 0,
pageCount: void 0,
fetchPage: void 0,
fetchNext: void 0,
fetchPrevious: void 0,
hasNextPage: false,
hasPreviousPage: false,
unstable__mutate: void 0
};
var useOrganizationList = (params) => {
const { userMemberships, userInvitations, userSuggestions } = params || {};
const userMembershipsSafeValues = useWithSafeValues(userMemberships, {
initialPage: 1,
pageSize: 10,
keepPreviousData: false,
infinite: false
});
const userInvitationsSafeValues = useWithSafeValues(userInvitations, {
initialPage: 1,
pageSize: 10,
status: "pending",
keepPreviousData: false,
infinite: false
});
const userSuggestionsSafeValues = useWithSafeValues(userSuggestions, {
initialPage: 1,
pageSize: 10,
status: "pending",
keepPreviousData: false,
infinite: false
});
const clerk = useClerkInstanceContext();
const user = useUserContext();
const userMembershipsParams = typeof userMemberships === "undefined" ? void 0 : {
initialPage: userMembershipsSafeValues.initialPage,
pageSize: userMembershipsSafeValues.pageSize
};
const userInvitationsParams = typeof userInvitations === "undefined" ? void 0 : {
initialPage: userInvitationsSafeValues.initialPage,
pageSize: userInvitationsSafeValues.pageSize,
status: userInvitationsSafeValues.status
};
const userSuggestionsParams = typeof userSuggestions === "undefined" ? void 0 : {
initialPage: userSuggestionsSafeValues.initialPage,
pageSize: userSuggestionsSafeValues.pageSize,
status: userSuggestionsSafeValues.status
};
const isClerkLoaded = !!(clerk.loaded && user);
const memberships = usePagesOrInfinite(
{
...userMembershipsParams,
paginated: true
},
user?.getOrganizationMemberships,
{
keepPreviousData: userMembershipsSafeValues.keepPreviousData,
infinite: userMembershipsSafeValues.infinite,
enabled: !!userMembershipsParams
},
{
type: "userMemberships",
userId: user?.id
}
);
const invitations = usePagesOrInfinite(
{
...userInvitationsParams
},
user?.getOrganizationInvitations,
{
keepPreviousData: userInvitationsSafeValues.keepPreviousData,
infinite: userInvitationsSafeValues.infinite,
enabled: !!userInvitationsParams
},
{
type: "userInvitations",
userId: user?.id
}
);
const suggestions = usePagesOrInfinite(
{
...userSuggestionsParams
},
user?.getOrganizationSuggestions,
{
keepPreviousData: userSuggestionsSafeValues.keepPreviousData,
infinite: userSuggestionsSafeValues.infinite,
enabled: !!userSuggestionsParams
},
{
type: "userSuggestions",
userId: user?.id
}
);
if (!isClerkLoaded) {
return {
isLoaded: false,
organizationList: void 0,
createOrganization: void 0,
setActive: void 0,
userMemberships: undefinedPaginatedResource2,
userInvitations: undefinedPaginatedResource2,
userSuggestions: undefinedPaginatedResource2
};
}
const result = {
isLoaded: isClerkLoaded,
organizationList: createOrganizationList(user.organizationMemberships),
setActive: clerk.setActive,
createOrganization: clerk.createOrganization,
userMemberships: memberships,
userInvitations: invitations,
userSuggestions: suggestions
};
deprecatedObjectProperty(result, "organizationList", "Use `userMemberships` instead.");
return result;
};
function createOrganizationList(organizationMemberships) {
return organizationMemberships.map((organizationMembership) => ({
membership: organizationMembership,
organization: organizationMembership.organization
}));
}
// src/react/hooks/useOrganizations.tsx
var useOrganizations = () => {
deprecated("useOrganizations", "Use useOrganizationList, useOrganization, or useClerk instead.");
const clerk = useClerkInstanceContext();
if (!clerk.loaded) {
return {
isLoaded: false,
createOrganization: void 0,
getOrganizationMemberships: void 0,
getOrganization: void 0
};
}
return {
isLoaded: true,
createOrganization: clerk.createOrganization,
getOrganizationMemberships: clerk.getOrganizationMemberships,
getOrganization: clerk.getOrganization
};
};
// src/react/hooks/useSafeLayoutEffect.tsx
var import_react4 = __toESM(require("react"));
var useSafeLayoutEffect = typeof window !== "undefined" ? import_react4.default.useLayoutEffect : import_react4.default.useEffect;
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
ClerkInstanceContext,
ClientContext,
OrganizationContext,
OrganizationProvider,
SessionContext,
UserContext,
assertContextExists,
createContextAndHook,
useClerkInstanceContext,
useClientContext,
useOrganization,
useOrganizationContext,
useOrganizationList,
useOrganizations,
useSafeLayoutEffect,
useSessionContext,
useUserContext
});
//# sourceMappingURL=index.js.map