@dream-api/sdk 0.1.32 → 0.1.34

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/dist/index.d.mts CHANGED
@@ -325,6 +325,11 @@ declare class AuthHelpers {
325
325
  getCustomerPortalUrl(options?: {
326
326
  returnUrl?: string;
327
327
  }): string;
328
+ /**
329
+ * Convert a relative path to an absolute URL using current origin.
330
+ * Already-absolute URLs are returned unchanged.
331
+ */
332
+ private makeAbsoluteUrl;
328
333
  }
329
334
 
330
335
  /**
package/dist/index.d.ts CHANGED
@@ -325,6 +325,11 @@ declare class AuthHelpers {
325
325
  getCustomerPortalUrl(options?: {
326
326
  returnUrl?: string;
327
327
  }): string;
328
+ /**
329
+ * Convert a relative path to an absolute URL using current origin.
330
+ * Already-absolute URLs are returned unchanged.
331
+ */
332
+ private makeAbsoluteUrl;
328
333
  }
329
334
 
330
335
  /**
package/dist/index.js CHANGED
@@ -194,6 +194,7 @@ var JWT_TEMPLATE = "end-user-api";
194
194
  function getClerk() {
195
195
  return window.Clerk;
196
196
  }
197
+ var STORAGE_KEY = "dream_api_jwt";
197
198
  var ClerkManager = class {
198
199
  constructor(mode, onTokenChange) {
199
200
  this.loaded = false;
@@ -202,25 +203,57 @@ var ClerkManager = class {
202
203
  this.onTokenChange = onTokenChange;
203
204
  }
204
205
  /**
205
- * Load Clerk SDK (call once on page load)
206
+ * Load auth (call once on page load)
207
+ * Uses JWT from URL or localStorage - no Clerk needed on dev's domain
206
208
  */
207
209
  async load() {
208
210
  if (this.loaded || typeof window === "undefined") return;
209
211
  const urlParams = new URLSearchParams(window.location.search);
210
212
  const jwt = urlParams.get("__clerk_jwt");
211
213
  if (jwt) {
212
- console.log("[DreamAPI] JWT received from sign-up worker");
213
- this.token = jwt;
214
- this.onTokenChange?.(jwt);
214
+ console.log("[DreamAPI] JWT received from auth worker");
215
+ this.setToken(jwt);
215
216
  urlParams.delete("__clerk_jwt");
216
217
  const newUrl = urlParams.toString() ? `${window.location.pathname}?${urlParams}` : window.location.pathname;
217
218
  window.history.replaceState({}, "", newUrl);
218
219
  this.loaded = true;
219
220
  return;
220
221
  }
222
+ const storedJwt = localStorage.getItem(STORAGE_KEY);
223
+ if (storedJwt) {
224
+ try {
225
+ const payload = JSON.parse(atob(storedJwt.split(".")[1].replace(/-/g, "+").replace(/_/g, "/")));
226
+ const now = Math.floor(Date.now() / 1e3);
227
+ if (payload.exp && payload.exp > now) {
228
+ console.log("[DreamAPI] Valid JWT from localStorage");
229
+ this.token = storedJwt;
230
+ this.onTokenChange?.(storedJwt);
231
+ this.loaded = true;
232
+ return;
233
+ } else {
234
+ console.log("[DreamAPI] Stored JWT expired, clearing");
235
+ localStorage.removeItem(STORAGE_KEY);
236
+ }
237
+ } catch (e) {
238
+ console.log("[DreamAPI] Invalid stored JWT, clearing");
239
+ localStorage.removeItem(STORAGE_KEY);
240
+ }
241
+ }
242
+ if (this.mode === "test") {
243
+ try {
244
+ await this.loadClerkSDK();
245
+ } catch (e) {
246
+ console.log("[DreamAPI] Clerk load failed (expected in some environments)");
247
+ }
248
+ }
249
+ this.loaded = true;
250
+ }
251
+ /**
252
+ * Load Clerk SDK (test mode only, for better DX on localhost)
253
+ */
254
+ async loadClerkSDK() {
221
255
  const existingClerk = getClerk();
222
256
  if (existingClerk) {
223
- this.loaded = true;
224
257
  await this.checkSession();
225
258
  return;
226
259
  }
@@ -242,55 +275,16 @@ var ClerkManager = class {
242
275
  }
243
276
  if (clerk) {
244
277
  await clerk.load();
245
- const urlParams2 = new URLSearchParams(window.location.search);
246
- const ticket = urlParams2.get("__clerk_ticket");
247
- console.log("[DreamAPI] URL:", window.location.href);
248
- console.log("[DreamAPI] Ticket present:", ticket ? "YES" : "NO");
249
- const sdkDebug = {
250
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
251
- url: window.location.href,
252
- hasTicket: !!ticket,
253
- ticketLength: ticket ? ticket.length : 0,
254
- signupDebug: localStorage.getItem("dream_signup_debug"),
255
- signupRedirect: localStorage.getItem("dream_signup_redirect")
256
- };
257
- localStorage.setItem("dream_sdk_debug", JSON.stringify(sdkDebug));
258
- if (ticket) {
259
- for (let i = 0; i < 50; i++) {
260
- const hasSignIn = clerk.signIn || clerk.client?.signIn;
261
- if (hasSignIn && clerk.setActive) break;
262
- await new Promise((r) => setTimeout(r, 100));
263
- }
264
- console.log("[DreamAPI] signIn available:", !!clerk.signIn, "client.signIn:", !!clerk.client?.signIn, "setActive:", !!clerk.setActive);
265
- }
266
- const signInObj = clerk.signIn || clerk.client?.signIn;
267
- if (ticket && signInObj && clerk.setActive) {
268
- console.log("[DreamAPI] Consuming ticket...");
269
- try {
270
- const result = await signInObj.create({ strategy: "ticket", ticket });
271
- console.log("[DreamAPI] Ticket result:", result.status, result.createdSessionId);
272
- if (result.status === "complete" && result.createdSessionId) {
273
- await clerk.setActive({ session: result.createdSessionId });
274
- console.log("[DreamAPI] Session activated!");
275
- for (let i = 0; i < 20; i++) {
276
- await new Promise((r) => setTimeout(r, 100));
277
- if (clerk.user && clerk.session) break;
278
- }
279
- console.log("[DreamAPI] User hydrated:", !!clerk.user);
280
- urlParams2.delete("__clerk_ticket");
281
- const newUrl = urlParams2.toString() ? `${window.location.pathname}?${urlParams2}` : window.location.pathname;
282
- window.history.replaceState({}, "", newUrl);
283
- }
284
- } catch (err) {
285
- console.error("[DreamAPI] Ticket error:", err?.message, err);
286
- }
287
- } else if (ticket) {
288
- console.error("[DreamAPI] FAILED to get signIn object! Ticket NOT consumed.");
289
- console.log("[DreamAPI] clerk keys:", Object.keys(clerk));
290
- }
278
+ await this.checkSession();
291
279
  }
292
- this.loaded = true;
293
- await this.checkSession();
280
+ }
281
+ /**
282
+ * Store JWT in memory and localStorage
283
+ */
284
+ setToken(jwt) {
285
+ this.token = jwt;
286
+ localStorage.setItem(STORAGE_KEY, jwt);
287
+ this.onTokenChange?.(jwt);
294
288
  }
295
289
  /**
296
290
  * Check if returning from auth and grab token
@@ -355,33 +349,40 @@ var ClerkManager = class {
355
349
  return this.token;
356
350
  }
357
351
  /**
358
- * Refresh token and user data from Clerk server
359
- * Call after plan changes (checkout success) to get updated metadata
352
+ * Refresh token and user data
353
+ * In test mode: refreshes from Clerk session
354
+ * In live mode: returns current token (re-auth needed for fresh data)
360
355
  */
361
356
  async refreshToken() {
362
357
  const clerk = getClerk();
363
- if (!clerk?.session) return null;
364
- try {
365
- if (clerk.user?.reload) {
366
- await clerk.user.reload();
358
+ if (clerk?.session) {
359
+ try {
360
+ if (clerk.user?.reload) {
361
+ await clerk.user.reload();
362
+ }
363
+ this.token = await clerk.session.getToken({ template: JWT_TEMPLATE });
364
+ this.setToken(this.token);
365
+ return this.token;
366
+ } catch (err) {
367
+ console.error("Failed to refresh token from Clerk:", err);
367
368
  }
368
- this.token = await clerk.session.getToken({ template: JWT_TEMPLATE });
369
- this.onTokenChange?.(this.token);
370
- return this.token;
371
- } catch (err) {
372
- console.error("Failed to refresh token:", err);
373
- return null;
374
369
  }
370
+ return this.token;
375
371
  }
376
372
  /**
377
373
  * Sign out
378
374
  */
379
375
  async signOut() {
380
- const clerk = getClerk();
381
- if (!clerk) return;
382
- await clerk.signOut();
376
+ localStorage.removeItem(STORAGE_KEY);
383
377
  this.token = null;
384
378
  this.onTokenChange?.(null);
379
+ const clerk = getClerk();
380
+ if (clerk) {
381
+ try {
382
+ await clerk.signOut();
383
+ } catch (e) {
384
+ }
385
+ }
385
386
  }
386
387
  /**
387
388
  * Check if we're returning from auth (has clerk params/cookies)
@@ -477,9 +478,10 @@ var AuthHelpers = class {
477
478
  throw new Error("DreamAPI: publishableKey required for auth URLs");
478
479
  }
479
480
  const baseUrl = this.client.getSignupBaseUrl();
481
+ const redirectUrl = this.makeAbsoluteUrl(options.redirect);
480
482
  const params = new URLSearchParams({
481
483
  pk,
482
- redirect: options.redirect
484
+ redirect: redirectUrl
483
485
  });
484
486
  return `${baseUrl}/signup?${params.toString()}`;
485
487
  }
@@ -501,9 +503,10 @@ var AuthHelpers = class {
501
503
  throw new Error("DreamAPI: publishableKey required for auth URLs");
502
504
  }
503
505
  const baseUrl = this.client.getSignupBaseUrl();
506
+ const redirectUrl = this.makeAbsoluteUrl(options.redirect);
504
507
  const params = new URLSearchParams({
505
508
  pk,
506
- redirect: options.redirect
509
+ redirect: redirectUrl
507
510
  });
508
511
  return `${baseUrl}/signin?${params.toString()}`;
509
512
  }
@@ -529,12 +532,26 @@ var AuthHelpers = class {
529
532
  }
530
533
  const baseUrl = this.client.getSignupBaseUrl();
531
534
  const returnUrl = options?.returnUrl || (typeof window !== "undefined" ? window.location.href : "/");
535
+ const redirectUrl = this.makeAbsoluteUrl(returnUrl);
532
536
  const params = new URLSearchParams({
533
537
  pk,
534
- redirect: returnUrl
538
+ redirect: redirectUrl
535
539
  });
536
540
  return `${baseUrl}/account?${params.toString()}`;
537
541
  }
542
+ /**
543
+ * Convert a relative path to an absolute URL using current origin.
544
+ * Already-absolute URLs are returned unchanged.
545
+ */
546
+ makeAbsoluteUrl(path) {
547
+ if (path.startsWith("http://") || path.startsWith("https://")) {
548
+ return path;
549
+ }
550
+ if (typeof window !== "undefined") {
551
+ return new URL(path, window.location.origin).toString();
552
+ }
553
+ return path;
554
+ }
538
555
  };
539
556
 
540
557
  // src/index.ts
package/dist/index.mjs CHANGED
@@ -166,6 +166,7 @@ var JWT_TEMPLATE = "end-user-api";
166
166
  function getClerk() {
167
167
  return window.Clerk;
168
168
  }
169
+ var STORAGE_KEY = "dream_api_jwt";
169
170
  var ClerkManager = class {
170
171
  constructor(mode, onTokenChange) {
171
172
  this.loaded = false;
@@ -174,25 +175,57 @@ var ClerkManager = class {
174
175
  this.onTokenChange = onTokenChange;
175
176
  }
176
177
  /**
177
- * Load Clerk SDK (call once on page load)
178
+ * Load auth (call once on page load)
179
+ * Uses JWT from URL or localStorage - no Clerk needed on dev's domain
178
180
  */
179
181
  async load() {
180
182
  if (this.loaded || typeof window === "undefined") return;
181
183
  const urlParams = new URLSearchParams(window.location.search);
182
184
  const jwt = urlParams.get("__clerk_jwt");
183
185
  if (jwt) {
184
- console.log("[DreamAPI] JWT received from sign-up worker");
185
- this.token = jwt;
186
- this.onTokenChange?.(jwt);
186
+ console.log("[DreamAPI] JWT received from auth worker");
187
+ this.setToken(jwt);
187
188
  urlParams.delete("__clerk_jwt");
188
189
  const newUrl = urlParams.toString() ? `${window.location.pathname}?${urlParams}` : window.location.pathname;
189
190
  window.history.replaceState({}, "", newUrl);
190
191
  this.loaded = true;
191
192
  return;
192
193
  }
194
+ const storedJwt = localStorage.getItem(STORAGE_KEY);
195
+ if (storedJwt) {
196
+ try {
197
+ const payload = JSON.parse(atob(storedJwt.split(".")[1].replace(/-/g, "+").replace(/_/g, "/")));
198
+ const now = Math.floor(Date.now() / 1e3);
199
+ if (payload.exp && payload.exp > now) {
200
+ console.log("[DreamAPI] Valid JWT from localStorage");
201
+ this.token = storedJwt;
202
+ this.onTokenChange?.(storedJwt);
203
+ this.loaded = true;
204
+ return;
205
+ } else {
206
+ console.log("[DreamAPI] Stored JWT expired, clearing");
207
+ localStorage.removeItem(STORAGE_KEY);
208
+ }
209
+ } catch (e) {
210
+ console.log("[DreamAPI] Invalid stored JWT, clearing");
211
+ localStorage.removeItem(STORAGE_KEY);
212
+ }
213
+ }
214
+ if (this.mode === "test") {
215
+ try {
216
+ await this.loadClerkSDK();
217
+ } catch (e) {
218
+ console.log("[DreamAPI] Clerk load failed (expected in some environments)");
219
+ }
220
+ }
221
+ this.loaded = true;
222
+ }
223
+ /**
224
+ * Load Clerk SDK (test mode only, for better DX on localhost)
225
+ */
226
+ async loadClerkSDK() {
193
227
  const existingClerk = getClerk();
194
228
  if (existingClerk) {
195
- this.loaded = true;
196
229
  await this.checkSession();
197
230
  return;
198
231
  }
@@ -214,55 +247,16 @@ var ClerkManager = class {
214
247
  }
215
248
  if (clerk) {
216
249
  await clerk.load();
217
- const urlParams2 = new URLSearchParams(window.location.search);
218
- const ticket = urlParams2.get("__clerk_ticket");
219
- console.log("[DreamAPI] URL:", window.location.href);
220
- console.log("[DreamAPI] Ticket present:", ticket ? "YES" : "NO");
221
- const sdkDebug = {
222
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
223
- url: window.location.href,
224
- hasTicket: !!ticket,
225
- ticketLength: ticket ? ticket.length : 0,
226
- signupDebug: localStorage.getItem("dream_signup_debug"),
227
- signupRedirect: localStorage.getItem("dream_signup_redirect")
228
- };
229
- localStorage.setItem("dream_sdk_debug", JSON.stringify(sdkDebug));
230
- if (ticket) {
231
- for (let i = 0; i < 50; i++) {
232
- const hasSignIn = clerk.signIn || clerk.client?.signIn;
233
- if (hasSignIn && clerk.setActive) break;
234
- await new Promise((r) => setTimeout(r, 100));
235
- }
236
- console.log("[DreamAPI] signIn available:", !!clerk.signIn, "client.signIn:", !!clerk.client?.signIn, "setActive:", !!clerk.setActive);
237
- }
238
- const signInObj = clerk.signIn || clerk.client?.signIn;
239
- if (ticket && signInObj && clerk.setActive) {
240
- console.log("[DreamAPI] Consuming ticket...");
241
- try {
242
- const result = await signInObj.create({ strategy: "ticket", ticket });
243
- console.log("[DreamAPI] Ticket result:", result.status, result.createdSessionId);
244
- if (result.status === "complete" && result.createdSessionId) {
245
- await clerk.setActive({ session: result.createdSessionId });
246
- console.log("[DreamAPI] Session activated!");
247
- for (let i = 0; i < 20; i++) {
248
- await new Promise((r) => setTimeout(r, 100));
249
- if (clerk.user && clerk.session) break;
250
- }
251
- console.log("[DreamAPI] User hydrated:", !!clerk.user);
252
- urlParams2.delete("__clerk_ticket");
253
- const newUrl = urlParams2.toString() ? `${window.location.pathname}?${urlParams2}` : window.location.pathname;
254
- window.history.replaceState({}, "", newUrl);
255
- }
256
- } catch (err) {
257
- console.error("[DreamAPI] Ticket error:", err?.message, err);
258
- }
259
- } else if (ticket) {
260
- console.error("[DreamAPI] FAILED to get signIn object! Ticket NOT consumed.");
261
- console.log("[DreamAPI] clerk keys:", Object.keys(clerk));
262
- }
250
+ await this.checkSession();
263
251
  }
264
- this.loaded = true;
265
- await this.checkSession();
252
+ }
253
+ /**
254
+ * Store JWT in memory and localStorage
255
+ */
256
+ setToken(jwt) {
257
+ this.token = jwt;
258
+ localStorage.setItem(STORAGE_KEY, jwt);
259
+ this.onTokenChange?.(jwt);
266
260
  }
267
261
  /**
268
262
  * Check if returning from auth and grab token
@@ -327,33 +321,40 @@ var ClerkManager = class {
327
321
  return this.token;
328
322
  }
329
323
  /**
330
- * Refresh token and user data from Clerk server
331
- * Call after plan changes (checkout success) to get updated metadata
324
+ * Refresh token and user data
325
+ * In test mode: refreshes from Clerk session
326
+ * In live mode: returns current token (re-auth needed for fresh data)
332
327
  */
333
328
  async refreshToken() {
334
329
  const clerk = getClerk();
335
- if (!clerk?.session) return null;
336
- try {
337
- if (clerk.user?.reload) {
338
- await clerk.user.reload();
330
+ if (clerk?.session) {
331
+ try {
332
+ if (clerk.user?.reload) {
333
+ await clerk.user.reload();
334
+ }
335
+ this.token = await clerk.session.getToken({ template: JWT_TEMPLATE });
336
+ this.setToken(this.token);
337
+ return this.token;
338
+ } catch (err) {
339
+ console.error("Failed to refresh token from Clerk:", err);
339
340
  }
340
- this.token = await clerk.session.getToken({ template: JWT_TEMPLATE });
341
- this.onTokenChange?.(this.token);
342
- return this.token;
343
- } catch (err) {
344
- console.error("Failed to refresh token:", err);
345
- return null;
346
341
  }
342
+ return this.token;
347
343
  }
348
344
  /**
349
345
  * Sign out
350
346
  */
351
347
  async signOut() {
352
- const clerk = getClerk();
353
- if (!clerk) return;
354
- await clerk.signOut();
348
+ localStorage.removeItem(STORAGE_KEY);
355
349
  this.token = null;
356
350
  this.onTokenChange?.(null);
351
+ const clerk = getClerk();
352
+ if (clerk) {
353
+ try {
354
+ await clerk.signOut();
355
+ } catch (e) {
356
+ }
357
+ }
357
358
  }
358
359
  /**
359
360
  * Check if we're returning from auth (has clerk params/cookies)
@@ -449,9 +450,10 @@ var AuthHelpers = class {
449
450
  throw new Error("DreamAPI: publishableKey required for auth URLs");
450
451
  }
451
452
  const baseUrl = this.client.getSignupBaseUrl();
453
+ const redirectUrl = this.makeAbsoluteUrl(options.redirect);
452
454
  const params = new URLSearchParams({
453
455
  pk,
454
- redirect: options.redirect
456
+ redirect: redirectUrl
455
457
  });
456
458
  return `${baseUrl}/signup?${params.toString()}`;
457
459
  }
@@ -473,9 +475,10 @@ var AuthHelpers = class {
473
475
  throw new Error("DreamAPI: publishableKey required for auth URLs");
474
476
  }
475
477
  const baseUrl = this.client.getSignupBaseUrl();
478
+ const redirectUrl = this.makeAbsoluteUrl(options.redirect);
476
479
  const params = new URLSearchParams({
477
480
  pk,
478
- redirect: options.redirect
481
+ redirect: redirectUrl
479
482
  });
480
483
  return `${baseUrl}/signin?${params.toString()}`;
481
484
  }
@@ -501,12 +504,26 @@ var AuthHelpers = class {
501
504
  }
502
505
  const baseUrl = this.client.getSignupBaseUrl();
503
506
  const returnUrl = options?.returnUrl || (typeof window !== "undefined" ? window.location.href : "/");
507
+ const redirectUrl = this.makeAbsoluteUrl(returnUrl);
504
508
  const params = new URLSearchParams({
505
509
  pk,
506
- redirect: returnUrl
510
+ redirect: redirectUrl
507
511
  });
508
512
  return `${baseUrl}/account?${params.toString()}`;
509
513
  }
514
+ /**
515
+ * Convert a relative path to an absolute URL using current origin.
516
+ * Already-absolute URLs are returned unchanged.
517
+ */
518
+ makeAbsoluteUrl(path) {
519
+ if (path.startsWith("http://") || path.startsWith("https://")) {
520
+ return path;
521
+ }
522
+ if (typeof window !== "undefined") {
523
+ return new URL(path, window.location.origin).toString();
524
+ }
525
+ return path;
526
+ }
510
527
  };
511
528
 
512
529
  // src/index.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dream-api/sdk",
3
- "version": "0.1.32",
3
+ "version": "0.1.34",
4
4
  "description": "Official SDK for Dream API - Auth, billing, and usage tracking in one API",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",