UNPKG

12.9 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3const utils_1 = require("./utils");
4const errors_1 = require("./errors");
5class IsomorphicClerk {
6 constructor(frontendApi, options = {}, Clerk = null) {
7 this.clerkjs = null;
8 this.preopenSignIn = null;
9 this.preopenSignUp = null;
10 this.premountSignInNodes = new Map();
11 this.premountSignUpNodes = new Map();
12 this.premountUserProfileNodes = new Map();
13 this.premountUserButtonNodes = new Map();
14 this.premountMethodCalls = new Map();
15 this._loaded = false;
16 this.ssrData = null;
17 this.hydrateClerkJS = async (clerkjs) => {
18 if (!clerkjs) {
19 throw new Error('Failed to hydrate latest Clerk JS');
20 }
21 this.clerkjs = clerkjs;
22 this.premountMethodCalls.forEach(cb => cb());
23 if (this.preopenSignIn !== null) {
24 clerkjs.openSignIn(this.preopenSignIn);
25 }
26 if (this.preopenSignUp !== null) {
27 clerkjs.openSignUp(this.preopenSignUp);
28 }
29 this.premountSignInNodes.forEach((props, node) => {
30 clerkjs.mountSignIn(node, props);
31 });
32 this.premountSignUpNodes.forEach((props, node) => {
33 clerkjs.mountSignUp(node, props);
34 });
35 this.premountUserProfileNodes.forEach((props, node) => {
36 clerkjs.mountUserProfile(node, props);
37 });
38 this.premountUserButtonNodes.forEach((props, node) => {
39 clerkjs.mountUserButton(node, props);
40 });
41 this._loaded = true;
42 return this.clerkjs;
43 };
44 this.setSession = (session, beforeEmit) => {
45 if (this.clerkjs) {
46 return this.clerkjs.setSession(session, beforeEmit);
47 }
48 else {
49 return Promise.reject();
50 }
51 };
52 this.openSignIn = (props) => {
53 if (this.clerkjs && this._loaded) {
54 this.clerkjs.openSignIn(props);
55 }
56 else {
57 this.preopenSignIn = props;
58 }
59 };
60 this.closeSignIn = () => {
61 if (this.clerkjs && this._loaded) {
62 this.clerkjs.closeSignIn();
63 }
64 else {
65 this.preopenSignIn = null;
66 }
67 };
68 this.openSignUp = (props) => {
69 if (this.clerkjs && this._loaded) {
70 this.clerkjs.openSignUp(props);
71 }
72 else {
73 this.preopenSignUp = props;
74 }
75 };
76 this.closeSignUp = () => {
77 if (this.clerkjs && this._loaded) {
78 this.clerkjs.closeSignUp();
79 }
80 else {
81 this.preopenSignUp = null;
82 }
83 };
84 this.mountSignIn = (node, props) => {
85 if (this.clerkjs && this._loaded) {
86 this.clerkjs.mountSignIn(node, props);
87 }
88 else {
89 this.premountSignInNodes.set(node, props);
90 }
91 };
92 this.unmountSignIn = (node) => {
93 if (this.clerkjs && this._loaded) {
94 this.clerkjs.unmountSignIn(node);
95 }
96 else {
97 this.premountSignInNodes.delete(node);
98 }
99 };
100 this.mountSignUp = (node, props) => {
101 if (this.clerkjs && this._loaded) {
102 this.clerkjs.mountSignUp(node, props);
103 }
104 else {
105 this.premountSignUpNodes.set(node, props);
106 }
107 };
108 this.unmountSignUp = (node) => {
109 if (this.clerkjs && this._loaded) {
110 this.clerkjs.unmountSignUp(node);
111 }
112 else {
113 this.premountSignUpNodes.delete(node);
114 }
115 };
116 this.mountUserProfile = (node, props) => {
117 if (this.clerkjs && this._loaded) {
118 this.clerkjs.mountUserProfile(node, props);
119 }
120 else {
121 this.premountUserProfileNodes.set(node, props);
122 }
123 };
124 this.unmountUserProfile = (node) => {
125 if (this.clerkjs && this._loaded) {
126 this.clerkjs.unmountUserProfile(node);
127 }
128 else {
129 this.premountUserProfileNodes.delete(node);
130 }
131 };
132 this.mountUserButton = (node, userButtonProps) => {
133 if (this.clerkjs && this._loaded) {
134 this.clerkjs.mountUserButton(node, userButtonProps);
135 }
136 else {
137 this.premountUserButtonNodes.set(node, userButtonProps);
138 }
139 };
140 this.unmountUserButton = (node) => {
141 if (this.clerkjs && this._loaded) {
142 this.clerkjs.unmountUserButton(node);
143 }
144 else {
145 this.premountUserButtonNodes.delete(node);
146 }
147 };
148 this.addListener = (listener) => {
149 const callback = () => { var _a; return (_a = this.clerkjs) === null || _a === void 0 ? void 0 : _a.addListener(listener); };
150 if (this.clerkjs) {
151 callback();
152 }
153 else {
154 this.premountMethodCalls.set('addListener', callback);
155 }
156 };
157 this.loadFromServer = (token) => {
158 if (this.mode === 'browser') {
159 void this.throwError('loadFromServer cannot be called in a browser context.');
160 }
161 this.ssrData = JSON.stringify({
162 client: this.client,
163 session: this.session,
164 token: token,
165 });
166 };
167 this.navigate = (to) => {
168 const callback = () => { var _a; return (_a = this.clerkjs) === null || _a === void 0 ? void 0 : _a.navigate(to); };
169 if (this.clerkjs && this._loaded) {
170 void callback();
171 }
172 else {
173 this.premountMethodCalls.set('navigate', callback);
174 }
175 };
176 // DX: deprecated <=2.4.2
177 // Deprecate the boolean type before removing returnBack
178 this.redirectToSignIn = (opts) => {
179 const callback = () => { var _a; return (_a = this.clerkjs) === null || _a === void 0 ? void 0 : _a.redirectToSignIn(opts); };
180 if (this.clerkjs && this._loaded) {
181 void callback();
182 }
183 else {
184 this.premountMethodCalls.set('redirectToSignIn', callback);
185 }
186 };
187 // DX: deprecated <=2.4.2
188 // Deprecate the boolean type before removing returnBack
189 this.redirectToSignUp = (opts) => {
190 const callback = () => { var _a; return (_a = this.clerkjs) === null || _a === void 0 ? void 0 : _a.redirectToSignUp(opts); };
191 if (this.clerkjs && this._loaded) {
192 void callback();
193 }
194 else {
195 this.premountMethodCalls.set('redirectToSignUp', callback);
196 }
197 };
198 this.redirectToUserProfile = () => {
199 const callback = () => { var _a; return (_a = this.clerkjs) === null || _a === void 0 ? void 0 : _a.redirectToUserProfile(); };
200 if (this.clerkjs && this._loaded) {
201 callback();
202 }
203 else {
204 this.premountMethodCalls.set('redirectToUserProfile', callback);
205 }
206 };
207 this.handleRedirectCallback = (params) => {
208 const callback = () => { var _a; return (_a = this.clerkjs) === null || _a === void 0 ? void 0 : _a.handleRedirectCallback(params); };
209 if (this.clerkjs && this._loaded) {
210 void callback();
211 }
212 else {
213 this.premountMethodCalls.set('handleRedirectCallback', callback);
214 }
215 };
216 this.handleMagicLinkVerification = async (params) => {
217 const callback = () => { var _a; return (_a = this.clerkjs) === null || _a === void 0 ? void 0 : _a.handleMagicLinkVerification(params); };
218 if (this.clerkjs && this._loaded) {
219 return callback();
220 }
221 else {
222 this.premountMethodCalls.set('handleMagicLinkVerification', callback);
223 }
224 };
225 this.signOut = async (signOutCallback) => {
226 const callback = () => { var _a; return (_a = this.clerkjs) === null || _a === void 0 ? void 0 : _a.signOut(signOutCallback); };
227 if (this.clerkjs && this._loaded) {
228 return callback();
229 }
230 else {
231 this.premountMethodCalls.set('signOut', callback);
232 }
233 };
234 this.signOutOne = async (signOutCallback) => {
235 const callback = () => { var _a; return (_a = this.clerkjs) === null || _a === void 0 ? void 0 : _a.signOutOne(signOutCallback); };
236 if (this.clerkjs && this._loaded) {
237 return callback();
238 }
239 else {
240 this.premountMethodCalls.set('signOutOne', callback);
241 }
242 };
243 this.frontendApi = frontendApi;
244 this.options = options;
245 this.Clerk = Clerk;
246 this.mode = (0, utils_1.inBrowser)() ? 'browser' : 'server';
247 // TODO: Support SRR for NextJS
248 // const ssrDataNode = document.querySelector(`script[data-clerk="SSR"]`);
249 // if (ssrDataNode) {
250 // this.ssrData = ssrDataNode.innerHTML;
251 // const parsedData = JSON.parse(this.ssrData);
252 // this.ssrClient = parsedData.client;
253 // this.ssrSession = parsedData.session;
254 // }
255 }
256 async loadClerkJS() {
257 if (!this.frontendApi) {
258 this.throwError(errors_1.noFrontendApiError);
259 }
260 try {
261 if (this.Clerk) {
262 // Set a fixed Clerk version
263 let c;
264 if ((0, utils_1.isConstructor)(this.Clerk)) {
265 // Construct a new Clerk object if a constructor is passed
266 c = new this.Clerk(this.frontendApi);
267 await c.load(this.options);
268 }
269 else {
270 // Otherwise use the instantiated Clerk object
271 c = this.Clerk;
272 if (!c.isReady()) {
273 await c.load(this.options);
274 }
275 }
276 global.Clerk = c;
277 }
278 else {
279 // Hot-load latest ClerkJS from Clerk CDN
280 await (0, utils_1.loadScript)(this.frontendApi, this.options.scriptUrl);
281 if (!global.Clerk) {
282 throw new Error('Failed to download latest ClerkJS. Contact support@clerk.dev.');
283 }
284 await global.Clerk.load(this.options);
285 }
286 return this.hydrateClerkJS(global.Clerk);
287 }
288 catch (err) {
289 let message;
290 if (err instanceof Error) {
291 message = err.message;
292 }
293 else {
294 message = String(err);
295 }
296 this.throwError(message);
297 return;
298 }
299 }
300 // Custom wrapper to throw an error, since we need to apply different handling between
301 // production and development builds. In Next.js we can throw a full screen error in
302 // development mode. However, in production throwing an error results in an infinite loop
303 // as shown at https://github.com/vercel/next.js/issues/6973
304 throwError(errorMsg) {
305 if (process.env.NODE_ENV === 'production') {
306 console.error(errorMsg);
307 }
308 throw new Error(errorMsg);
309 }
310 get version() {
311 var _a;
312 return (_a = this.clerkjs) === null || _a === void 0 ? void 0 : _a.version;
313 }
314 get client() {
315 if (this.clerkjs) {
316 return this.clerkjs.client;
317 // TODO: add ssr condition
318 }
319 else {
320 return undefined;
321 }
322 }
323 get session() {
324 if (this.clerkjs) {
325 return this.clerkjs.session;
326 // TODO: add ssr condition
327 }
328 else {
329 return undefined;
330 }
331 }
332 get user() {
333 if (this.clerkjs) {
334 return this.clerkjs.user;
335 // TODO: add ssr condition
336 }
337 else {
338 return undefined;
339 }
340 }
341 // TODO: Remove temp use of __unstable__environment
342 get __unstable__environment() {
343 if (this.clerkjs) {
344 return this.clerkjs.__unstable__environment;
345 // TODO: add ssr condition
346 }
347 else {
348 return undefined;
349 }
350 }
351}
352exports.default = IsomorphicClerk;
353//# sourceMappingURL=isomorphicClerk.js.map
\No newline at end of file