@scalemule/nextjs 0.1.38 → 0.1.40

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.
@@ -15,6 +15,9 @@ var ScaleMuleApiError = class extends Error {
15
15
  this.code = error.code;
16
16
  this.field = error.field;
17
17
  this.status = status;
18
+ this.requestId = error.requestId;
19
+ this.traceId = error.traceId;
20
+ this.problem = error.problem;
18
21
  }
19
22
  };
20
23
 
@@ -32,40 +35,40 @@ function validateIP(ip) {
32
35
  return void 0;
33
36
  }
34
37
  function extractClientContext(request) {
35
- const headers2 = request.headers;
38
+ const headers3 = request.headers;
36
39
  let ip;
37
- const cfConnectingIp = headers2.get("cf-connecting-ip");
40
+ const cfConnectingIp = headers3.get("cf-connecting-ip");
38
41
  if (cfConnectingIp) {
39
42
  ip = validateIP(cfConnectingIp);
40
43
  }
41
44
  if (!ip) {
42
- const doConnectingIp = headers2.get("do-connecting-ip");
45
+ const doConnectingIp = headers3.get("do-connecting-ip");
43
46
  if (doConnectingIp) {
44
47
  ip = validateIP(doConnectingIp);
45
48
  }
46
49
  }
47
50
  if (!ip) {
48
- const realIp = headers2.get("x-real-ip");
51
+ const realIp = headers3.get("x-real-ip");
49
52
  if (realIp) {
50
53
  ip = validateIP(realIp);
51
54
  }
52
55
  }
53
56
  if (!ip) {
54
- const forwardedFor = headers2.get("x-forwarded-for");
57
+ const forwardedFor = headers3.get("x-forwarded-for");
55
58
  if (forwardedFor) {
56
59
  const firstIp = forwardedFor.split(",")[0]?.trim();
57
60
  ip = validateIP(firstIp);
58
61
  }
59
62
  }
60
63
  if (!ip) {
61
- const vercelForwarded = headers2.get("x-vercel-forwarded-for");
64
+ const vercelForwarded = headers3.get("x-vercel-forwarded-for");
62
65
  if (vercelForwarded) {
63
66
  const firstIp = vercelForwarded.split(",")[0]?.trim();
64
67
  ip = validateIP(firstIp);
65
68
  }
66
69
  }
67
70
  if (!ip) {
68
- const trueClientIp = headers2.get("true-client-ip");
71
+ const trueClientIp = headers3.get("true-client-ip");
69
72
  if (trueClientIp) {
70
73
  ip = validateIP(trueClientIp);
71
74
  }
@@ -73,10 +76,10 @@ function extractClientContext(request) {
73
76
  if (!ip && request.ip) {
74
77
  ip = validateIP(request.ip);
75
78
  }
76
- const userAgent = headers2.get("user-agent") || void 0;
77
- const deviceFingerprint = headers2.get("x-device-fingerprint") || void 0;
78
- const referrer = headers2.get("referer") || void 0;
79
- const anonymousId = headers2.get("x-anonymous-id") || void 0;
79
+ const userAgent = headers3.get("user-agent") || void 0;
80
+ const deviceFingerprint = headers3.get("x-device-fingerprint") || void 0;
81
+ const referrer = headers3.get("referer") || void 0;
82
+ const anonymousId = headers3.get("x-anonymous-id") || void 0;
80
83
  return {
81
84
  ip,
82
85
  userAgent,
@@ -86,9 +89,9 @@ function extractClientContext(request) {
86
89
  };
87
90
  }
88
91
  function extractClientContextFromReq(req) {
89
- const headers2 = req.headers;
92
+ const headers3 = req.headers;
90
93
  const getHeader = (name) => {
91
- const value = headers2[name.toLowerCase()];
94
+ const value = headers3[name.toLowerCase()];
92
95
  if (Array.isArray(value)) {
93
96
  return value[0];
94
97
  }
@@ -147,27 +150,27 @@ function extractClientContextFromReq(req) {
147
150
  };
148
151
  }
149
152
  function buildClientContextHeaders(context) {
150
- const headers2 = {};
153
+ const headers3 = {};
151
154
  if (!context) {
152
- return headers2;
155
+ return headers3;
153
156
  }
154
157
  if (context.ip) {
155
- headers2["x-sm-forwarded-client-ip"] = context.ip;
156
- headers2["X-Client-IP"] = context.ip;
158
+ headers3["x-sm-forwarded-client-ip"] = context.ip;
159
+ headers3["X-Client-IP"] = context.ip;
157
160
  }
158
161
  if (context.userAgent) {
159
- headers2["X-Client-User-Agent"] = context.userAgent;
162
+ headers3["X-Client-User-Agent"] = context.userAgent;
160
163
  }
161
164
  if (context.deviceFingerprint) {
162
- headers2["X-Client-Device-Fingerprint"] = context.deviceFingerprint;
165
+ headers3["X-Client-Device-Fingerprint"] = context.deviceFingerprint;
163
166
  }
164
167
  if (context.referrer) {
165
- headers2["X-Client-Referrer"] = context.referrer;
168
+ headers3["X-Client-Referrer"] = context.referrer;
166
169
  }
167
170
  if (context.anonymousId) {
168
- headers2["x-anonymous-id"] = context.anonymousId;
171
+ headers3["x-anonymous-id"] = context.anonymousId;
169
172
  }
170
- return headers2;
173
+ return headers3;
171
174
  }
172
175
  function buildFlagContext(clientContext, extraContext = {}) {
173
176
  const context = { ...extraContext };
@@ -177,6 +180,25 @@ function buildFlagContext(clientContext, extraContext = {}) {
177
180
  return context;
178
181
  }
179
182
 
183
+ // src/error-context.ts
184
+ function withErrorContext(error, responseData, headers3) {
185
+ const enriched = { ...error };
186
+ const meta = responseData?.meta;
187
+ const requestId = meta?.request_id ?? headers3?.get("x-request-id") ?? void 0;
188
+ if (requestId !== void 0 && enriched.requestId === void 0) {
189
+ enriched.requestId = requestId;
190
+ }
191
+ const traceId = meta?.trace_id;
192
+ if (traceId !== void 0 && enriched.traceId === void 0) {
193
+ enriched.traceId = traceId;
194
+ }
195
+ const rawError = responseData?.error;
196
+ if (rawError !== null && typeof rawError === "object" && enriched.problem === void 0) {
197
+ enriched.problem = rawError;
198
+ }
199
+ return enriched;
200
+ }
201
+
180
202
  // src/server/client.ts
181
203
  var GATEWAY_URLS = {
182
204
  dev: "https://api-dev.scalemule.com",
@@ -185,6 +207,7 @@ var GATEWAY_URLS = {
185
207
  function resolveGatewayUrl(config) {
186
208
  if (config.gatewayUrl) return config.gatewayUrl;
187
209
  if (process.env.SCALEMULE_API_URL) return process.env.SCALEMULE_API_URL;
210
+ if (process.env.SCALEMULE_GATEWAY_URL) return process.env.SCALEMULE_GATEWAY_URL;
188
211
  return GATEWAY_URLS[config.environment || "prod"];
189
212
  }
190
213
  var ScaleMuleServer = class {
@@ -573,7 +596,7 @@ var ScaleMuleServer = class {
573
596
  formData.append("file", blob, file.filename);
574
597
  formData.append("sm_user_id", userId);
575
598
  const url = `${this.gatewayUrl}/v1/storage/upload`;
576
- const headers2 = {
599
+ const headers3 = {
577
600
  "x-api-key": this.apiKey,
578
601
  "x-user-id": userId,
579
602
  ...buildClientContextHeaders(options?.clientContext)
@@ -584,7 +607,7 @@ var ScaleMuleServer = class {
584
607
  try {
585
608
  const response = await fetch(url, {
586
609
  method: "POST",
587
- headers: headers2,
610
+ headers: headers3,
588
611
  body: formData
589
612
  });
590
613
  const text = await response.text();
@@ -595,7 +618,11 @@ var ScaleMuleServer = class {
595
618
  }
596
619
  if (!response.ok) {
597
620
  throw new ScaleMuleApiError(
598
- responseData?.error || { code: "UPLOAD_FAILED", message: text || "Upload failed" }
621
+ withErrorContext(
622
+ responseData?.error || { code: "UPLOAD_FAILED", message: text || "Upload failed" },
623
+ responseData,
624
+ response.headers
625
+ )
599
626
  );
600
627
  }
601
628
  const data = responseData?.data !== void 0 ? responseData.data : responseData;
@@ -806,14 +833,14 @@ var ScaleMuleServer = class {
806
833
  */
807
834
  async request(method, path, options = {}) {
808
835
  const url = `${this.gatewayUrl}${path}`;
809
- const headers2 = {
836
+ const headers3 = {
810
837
  "x-api-key": this.apiKey,
811
838
  "Content-Type": "application/json",
812
839
  // Forward client context headers if provided
813
840
  ...buildClientContextHeaders(options.clientContext)
814
841
  };
815
842
  if (options.sessionToken) {
816
- headers2["Authorization"] = `Bearer ${options.sessionToken}`;
843
+ headers3["Authorization"] = `Bearer ${options.sessionToken}`;
817
844
  }
818
845
  if (this.debug) {
819
846
  console.log(`[ScaleMule Server] ${method} ${path}`);
@@ -824,7 +851,7 @@ var ScaleMuleServer = class {
824
851
  try {
825
852
  const response = await fetch(url, {
826
853
  method,
827
- headers: headers2,
854
+ headers: headers3,
828
855
  body: options.body ? JSON.stringify(options.body) : void 0
829
856
  });
830
857
  const rotated = response.headers.get("x-rotated-session-token");
@@ -838,10 +865,11 @@ var ScaleMuleServer = class {
838
865
  } catch {
839
866
  }
840
867
  if (!response.ok) {
841
- const error = responseData?.error || {
868
+ const baseError = responseData?.error || {
842
869
  code: `HTTP_${response.status}`,
843
870
  message: responseData?.message || text || response.statusText
844
871
  };
872
+ const error = withErrorContext(baseError, responseData, response.headers);
845
873
  if (response.status === 401 && options.sessionToken && !options.isAutoRefresh) {
846
874
  if (this.debug) console.log("[ScaleMule Server] 401 received, attempting auto-refresh...");
847
875
  try {
@@ -920,87 +948,111 @@ function createCookieHeader(name, value, options = {}) {
920
948
  }
921
949
  function createClearCookieHeader(name, options = {}) {
922
950
  const path = options.path ?? "/";
923
- let cookie = `${name}=; Path=${path}; Max-Age=0; HttpOnly`;
951
+ const secure = options.secure ?? process.env.NODE_ENV === "production";
952
+ const sameSite = options.sameSite ?? "lax";
953
+ let cookie = `${name}=; Path=${path}; Max-Age=0; HttpOnly; SameSite=${sameSite}`;
954
+ if (secure) {
955
+ cookie += "; Secure";
956
+ }
924
957
  if (options.domain) {
925
958
  cookie += `; Domain=${options.domain}`;
926
959
  }
927
960
  return cookie;
928
961
  }
929
962
  function withSession(loginResponse, responseBody, options = {}) {
930
- const headers2 = new Headers();
931
- headers2.set("Content-Type", "application/json");
932
- headers2.append(
963
+ const headers3 = new Headers();
964
+ headers3.set("Content-Type", "application/json");
965
+ headers3.append(
933
966
  "Set-Cookie",
934
967
  createCookieHeader(SESSION_COOKIE_NAME, loginResponse.session_token, options)
935
968
  );
936
- headers2.append(
969
+ headers3.append(
937
970
  "Set-Cookie",
938
971
  createCookieHeader(USER_ID_COOKIE_NAME, loginResponse.user.id, options)
939
972
  );
940
973
  return new Response(JSON.stringify({ success: true, data: responseBody }), {
941
974
  status: 200,
942
- headers: headers2
975
+ headers: headers3
943
976
  });
944
977
  }
945
978
  function withRefreshedSession(sessionToken, userId, responseBody, options = {}) {
946
- const headers2 = new Headers();
947
- headers2.set("Content-Type", "application/json");
948
- headers2.append(
979
+ const headers3 = new Headers();
980
+ headers3.set("Content-Type", "application/json");
981
+ headers3.append(
949
982
  "Set-Cookie",
950
983
  createCookieHeader(SESSION_COOKIE_NAME, sessionToken, options)
951
984
  );
952
- headers2.append(
985
+ headers3.append(
953
986
  "Set-Cookie",
954
987
  createCookieHeader(USER_ID_COOKIE_NAME, userId, options)
955
988
  );
956
989
  return new Response(JSON.stringify({ success: true, data: responseBody }), {
957
990
  status: 200,
958
- headers: headers2
991
+ headers: headers3
959
992
  });
960
993
  }
961
994
  function clearSession(responseBody, options = {}, status = 200) {
962
- const headers2 = new Headers();
963
- headers2.set("Content-Type", "application/json");
964
- headers2.append("Set-Cookie", createClearCookieHeader(SESSION_COOKIE_NAME, options));
965
- headers2.append("Set-Cookie", createClearCookieHeader(USER_ID_COOKIE_NAME, options));
995
+ const headers3 = new Headers();
996
+ headers3.set("Content-Type", "application/json");
997
+ headers3.append("Set-Cookie", createClearCookieHeader(SESSION_COOKIE_NAME, options));
998
+ headers3.append("Set-Cookie", createClearCookieHeader(USER_ID_COOKIE_NAME, options));
966
999
  return new Response(JSON.stringify({ success: status < 300, data: responseBody }), {
967
1000
  status,
968
- headers: headers2
1001
+ headers: headers3
969
1002
  });
970
1003
  }
971
1004
  async function getSession() {
972
1005
  const cookieStore = await cookies();
973
1006
  const sessionCookie = cookieStore.get(SESSION_COOKIE_NAME);
974
1007
  const userIdCookie = cookieStore.get(USER_ID_COOKIE_NAME);
975
- if (!sessionCookie?.value || !userIdCookie?.value) {
976
- return null;
1008
+ if (sessionCookie?.value && userIdCookie?.value) {
1009
+ return {
1010
+ sessionToken: sessionCookie.value,
1011
+ userId: userIdCookie.value,
1012
+ expiresAt: /* @__PURE__ */ new Date()
1013
+ // Note: actual expiry is managed by ScaleMule backend
1014
+ };
977
1015
  }
1016
+ const headerStore = await headers();
1017
+ return sessionFromAuthHeaders(
1018
+ headerStore.get("authorization"),
1019
+ headerStore.get("x-sm-user-id")
1020
+ );
1021
+ }
1022
+ function sessionFromAuthHeaders(authorization, userId) {
1023
+ if (!authorization || !userId) return null;
1024
+ const match = /^Bearer\s+(.+)$/i.exec(authorization.trim());
1025
+ const token = match?.[1]?.trim();
1026
+ if (!token) return null;
978
1027
  return {
979
- sessionToken: sessionCookie.value,
980
- userId: userIdCookie.value,
1028
+ sessionToken: token,
1029
+ userId,
981
1030
  expiresAt: /* @__PURE__ */ new Date()
982
- // Note: actual expiry is managed by ScaleMule backend
983
1031
  };
984
1032
  }
985
1033
  function getSessionFromRequest(request) {
986
1034
  const cookieHeader = request.headers.get("cookie");
987
- if (!cookieHeader) return null;
988
- const cookies4 = Object.fromEntries(
989
- cookieHeader.split(";").map((c) => {
990
- const [key, ...rest] = c.trim().split("=");
991
- return [key, decodeURIComponent(rest.join("="))];
992
- })
993
- );
994
- const sessionToken = cookies4[SESSION_COOKIE_NAME];
995
- const userId = cookies4[USER_ID_COOKIE_NAME];
996
- if (!sessionToken || !userId) {
997
- return null;
1035
+ if (cookieHeader) {
1036
+ const cookies4 = Object.fromEntries(
1037
+ cookieHeader.split(";").map((c) => {
1038
+ const [key, ...rest] = c.trim().split("=");
1039
+ return [key, decodeURIComponent(rest.join("="))];
1040
+ })
1041
+ );
1042
+ const sessionToken = cookies4[SESSION_COOKIE_NAME];
1043
+ const userId = cookies4[USER_ID_COOKIE_NAME];
1044
+ if (sessionToken && userId) {
1045
+ return {
1046
+ sessionToken,
1047
+ userId,
1048
+ expiresAt: /* @__PURE__ */ new Date()
1049
+ };
1050
+ }
998
1051
  }
999
- return {
1000
- sessionToken,
1001
- userId,
1002
- expiresAt: /* @__PURE__ */ new Date()
1003
- };
1052
+ return sessionFromAuthHeaders(
1053
+ request.headers.get("authorization"),
1054
+ request.headers.get("x-sm-user-id")
1055
+ );
1004
1056
  }
1005
1057
  var MAX_KNOWN_ACCOUNTS = 10;
1006
1058
  function maskEmail(email) {
@@ -1041,7 +1093,7 @@ function applyPrivacyToEntry(entry, privacy) {
1041
1093
  };
1042
1094
  }
1043
1095
  }
1044
- function appendKnownAccountCookie(headers2, account, existingCookie, options = {}, privacy) {
1096
+ function appendKnownAccountCookie(headers3, account, existingCookie, options = {}, privacy) {
1045
1097
  let accounts = {};
1046
1098
  if (existingCookie) {
1047
1099
  try {
@@ -1070,9 +1122,9 @@ function appendKnownAccountCookie(headers2, account, existingCookie, options = {
1070
1122
  if (options.domain) {
1071
1123
  cookie += `; Domain=${options.domain}`;
1072
1124
  }
1073
- headers2.append("Set-Cookie", cookie);
1125
+ headers3.append("Set-Cookie", cookie);
1074
1126
  }
1075
- function removeKnownAccountFromCookie(headers2, userId, existingCookie, options = {}) {
1127
+ function removeKnownAccountFromCookie(headers3, userId, existingCookie, options = {}) {
1076
1128
  let accounts = {};
1077
1129
  if (existingCookie) {
1078
1130
  try {
@@ -1092,15 +1144,15 @@ function removeKnownAccountFromCookie(headers2, userId, existingCookie, options
1092
1144
  if (options.domain) {
1093
1145
  cookie += `; Domain=${options.domain}`;
1094
1146
  }
1095
- headers2.append("Set-Cookie", cookie);
1147
+ headers3.append("Set-Cookie", cookie);
1096
1148
  }
1097
- function clearKnownAccountsCookie(headers2, options = {}) {
1149
+ function clearKnownAccountsCookie(headers3, options = {}) {
1098
1150
  const path = options.path ?? "/";
1099
1151
  let cookie = `${KNOWN_ACCOUNTS_COOKIE_NAME}=; Path=${path}; Max-Age=0`;
1100
1152
  if (options.domain) {
1101
1153
  cookie += `; Domain=${options.domain}`;
1102
1154
  }
1103
- headers2.append("Set-Cookie", cookie);
1155
+ headers3.append("Set-Cookie", cookie);
1104
1156
  }
1105
1157
  function getKnownAccountsFromRequest(request) {
1106
1158
  const cookieHeader = request.headers.get("cookie");
@@ -1598,13 +1650,13 @@ function createAuthRoutes(config = {}) {
1598
1650
  if (!user_id) {
1599
1651
  return errorResponse("VALIDATION_ERROR", "user_id required", 400);
1600
1652
  }
1601
- const headers2 = new Headers();
1602
- headers2.set("Content-Type", "application/json");
1653
+ const headers3 = new Headers();
1654
+ headers3.set("Content-Type", "application/json");
1603
1655
  const existingKnown = getKnownAccountsCookieRaw(request);
1604
- removeKnownAccountFromCookie(headers2, user_id, existingKnown, cookieOptions);
1656
+ removeKnownAccountFromCookie(headers3, user_id, existingKnown, cookieOptions);
1605
1657
  return new Response(
1606
1658
  JSON.stringify({ success: true, data: { message: "Account forgotten" } }),
1607
- { status: 200, headers: headers2 }
1659
+ { status: 200, headers: headers3 }
1608
1660
  );
1609
1661
  }
1610
1662
  // ==================== Forget All Accounts ====================
@@ -1612,12 +1664,12 @@ function createAuthRoutes(config = {}) {
1612
1664
  if (!config.enableAccountSwitcher) {
1613
1665
  return errorResponse("NOT_FOUND", "Account switcher not enabled", 404);
1614
1666
  }
1615
- const headers2 = new Headers();
1616
- headers2.set("Content-Type", "application/json");
1617
- clearKnownAccountsCookie(headers2, cookieOptions);
1667
+ const headers3 = new Headers();
1668
+ headers3.set("Content-Type", "application/json");
1669
+ clearKnownAccountsCookie(headers3, cookieOptions);
1618
1670
  return new Response(
1619
1671
  JSON.stringify({ success: true, data: { message: "All accounts forgotten" } }),
1620
- { status: 200, headers: headers2 }
1672
+ { status: 200, headers: headers3 }
1621
1673
  );
1622
1674
  }
1623
1675
  default:
@@ -2327,31 +2379,31 @@ function createPushRoutes(config) {
2327
2379
  const { apiKey, gatewayUrl, csrf = true } = config;
2328
2380
  async function proxyToGateway(request, method, subPath) {
2329
2381
  const targetUrl = `${gatewayUrl}/v1/communication/push/${subPath}`;
2330
- const headers2 = {
2382
+ const headers3 = {
2331
2383
  "x-api-key": apiKey
2332
2384
  };
2333
2385
  const session = getSessionFromRequest(request);
2334
2386
  if (session?.sessionToken) {
2335
- headers2["Authorization"] = `Bearer ${session.sessionToken}`;
2387
+ headers3["Authorization"] = `Bearer ${session.sessionToken}`;
2336
2388
  }
2337
2389
  const clientContext = extractClientContext(
2338
2390
  request
2339
2391
  );
2340
2392
  const contextHeaders = buildClientContextHeaders(clientContext);
2341
- Object.assign(headers2, contextHeaders);
2393
+ Object.assign(headers3, contextHeaders);
2342
2394
  const workspaceId = request.headers.get("x-sm-workspace-id");
2343
2395
  if (workspaceId) {
2344
- headers2["x-sm-workspace-id"] = workspaceId;
2396
+ headers3["x-sm-workspace-id"] = workspaceId;
2345
2397
  }
2346
2398
  const fetchOptions = {
2347
2399
  method,
2348
- headers: headers2
2400
+ headers: headers3
2349
2401
  };
2350
2402
  if (method !== "GET" && method !== "DELETE") {
2351
2403
  try {
2352
2404
  const body = await request.text();
2353
2405
  if (body) {
2354
- headers2["Content-Type"] = "application/json";
2406
+ headers3["Content-Type"] = "application/json";
2355
2407
  fetchOptions.body = body;
2356
2408
  }
2357
2409
  } catch {
@@ -2446,26 +2498,26 @@ function createNotificationRoutes(config) {
2446
2498
  const { apiKey, gatewayUrl } = config;
2447
2499
  async function proxyToGateway(request, method, subPath) {
2448
2500
  const targetUrl = `${gatewayUrl}/v1/notifications/${subPath}`;
2449
- const headers2 = {
2501
+ const headers3 = {
2450
2502
  "x-api-key": apiKey,
2451
2503
  "Content-Type": "application/json"
2452
2504
  };
2453
2505
  const session = getSessionFromRequest(request);
2454
2506
  if (session?.sessionToken) {
2455
- headers2["Authorization"] = `Bearer ${session.sessionToken}`;
2507
+ headers3["Authorization"] = `Bearer ${session.sessionToken}`;
2456
2508
  }
2457
2509
  const clientContext = extractClientContext(
2458
2510
  request
2459
2511
  );
2460
2512
  const contextHeaders = buildClientContextHeaders(clientContext);
2461
- Object.assign(headers2, contextHeaders);
2513
+ Object.assign(headers3, contextHeaders);
2462
2514
  const workspaceId = request.headers.get("x-sm-workspace-id");
2463
2515
  if (workspaceId) {
2464
- headers2["x-sm-workspace-id"] = workspaceId;
2516
+ headers3["x-sm-workspace-id"] = workspaceId;
2465
2517
  }
2466
2518
  const fetchOptions = {
2467
2519
  method,
2468
- headers: headers2
2520
+ headers: headers3
2469
2521
  };
2470
2522
  if (method === "PATCH") {
2471
2523
  try {
@@ -2510,11 +2562,12 @@ function createNotificationRoutes(config) {
2510
2562
 
2511
2563
  // src/server/errors.ts
2512
2564
  var ScaleMuleError = class extends Error {
2513
- constructor(code, message, status = 400, details) {
2565
+ constructor(code, message, status = 400, details, requestId) {
2514
2566
  super(message);
2515
2567
  this.code = code;
2516
2568
  this.status = status;
2517
2569
  this.details = details;
2570
+ this.requestId = requestId;
2518
2571
  this.name = "ScaleMuleError";
2519
2572
  }
2520
2573
  };
@@ -2568,7 +2621,8 @@ function unwrap(result) {
2568
2621
  code,
2569
2622
  err?.message || "An error occurred",
2570
2623
  status,
2571
- err?.details
2624
+ err?.details,
2625
+ err?.requestId ?? envelope.meta?.request_id
2572
2626
  );
2573
2627
  }
2574
2628
  return envelope.data;
@@ -2617,7 +2671,11 @@ function apiHandler(handler, options) {
2617
2671
  console.error("Internal API error:", error.message);
2618
2672
  }
2619
2673
  return Response.json(
2620
- { success: false, error: { code: error.code, message: safeMessage } },
2674
+ {
2675
+ success: false,
2676
+ error: { code: error.code, message: safeMessage },
2677
+ ...error.requestId ? { meta: { request_id: error.requestId } } : {}
2678
+ },
2621
2679
  { status: error.status }
2622
2680
  );
2623
2681
  }
@@ -3139,47 +3197,47 @@ function formatPermissionsDirective(feature, value) {
3139
3197
  return `${feature}=(${parts.join(" ")})`;
3140
3198
  }
3141
3199
  function buildSecurityHeaders(opts = {}) {
3142
- const headers2 = [];
3200
+ const headers3 = [];
3143
3201
  const includeHsts = opts.includeHsts ?? true;
3144
3202
  const hstsMaxAge = opts.hstsMaxAgeSeconds ?? 31536e3;
3145
3203
  if (includeHsts && hstsMaxAge > 0) {
3146
3204
  const parts = [`max-age=${hstsMaxAge}`];
3147
3205
  if (opts.hstsIncludeSubDomains ?? true) parts.push("includeSubDomains");
3148
3206
  if (opts.hstsPreload ?? false) parts.push("preload");
3149
- headers2.push({
3207
+ headers3.push({
3150
3208
  key: "Strict-Transport-Security",
3151
3209
  value: parts.join("; ")
3152
3210
  });
3153
3211
  }
3154
3212
  const frameOptions = opts.frameOptions === void 0 ? "DENY" : opts.frameOptions;
3155
3213
  if (frameOptions !== null) {
3156
- headers2.push({ key: "X-Frame-Options", value: frameOptions });
3214
+ headers3.push({ key: "X-Frame-Options", value: frameOptions });
3157
3215
  }
3158
3216
  const contentTypeOptions = opts.contentTypeOptions === void 0 ? "nosniff" : opts.contentTypeOptions;
3159
3217
  if (contentTypeOptions !== null) {
3160
- headers2.push({ key: "X-Content-Type-Options", value: contentTypeOptions });
3218
+ headers3.push({ key: "X-Content-Type-Options", value: contentTypeOptions });
3161
3219
  }
3162
- headers2.push({
3220
+ headers3.push({
3163
3221
  key: "Referrer-Policy",
3164
3222
  value: opts.referrerPolicy ?? "strict-origin-when-cross-origin"
3165
3223
  });
3166
3224
  const xss = opts.xssProtection === void 0 ? "0" : opts.xssProtection;
3167
3225
  if (xss !== null) {
3168
- headers2.push({ key: "X-XSS-Protection", value: xss });
3226
+ headers3.push({ key: "X-XSS-Protection", value: xss });
3169
3227
  }
3170
3228
  const permissions = opts.permissionsPolicy === void 0 ? DEFAULT_PERMISSIONS_POLICY : opts.permissionsPolicy;
3171
3229
  if (permissions !== null) {
3172
3230
  const directives = Object.entries(permissions).map(([feature, value]) => formatPermissionsDirective(feature, value)).join(", ");
3173
- headers2.push({ key: "Permissions-Policy", value: directives });
3231
+ headers3.push({ key: "Permissions-Policy", value: directives });
3174
3232
  }
3175
3233
  if (opts.extraHeaders?.length) {
3176
- const byKey = new Map(headers2.map((h) => [h.key.toLowerCase(), h]));
3234
+ const byKey = new Map(headers3.map((h) => [h.key.toLowerCase(), h]));
3177
3235
  for (const extra of opts.extraHeaders) {
3178
3236
  byKey.set(extra.key.toLowerCase(), extra);
3179
3237
  }
3180
3238
  return Array.from(byKey.values());
3181
3239
  }
3182
- return headers2;
3240
+ return headers3;
3183
3241
  }
3184
3242
 
3185
3243
  export { CSRF_COOKIE_NAME, CSRF_HEADER_NAME, DEFAULT_PERMISSIONS_POLICY, KNOWN_ACCOUNTS_COOKIE_NAME, OAUTH_STATE_COOKIE_NAME, SESSION_COOKIE_NAME, SM_LEDVERY_ACCESS_TOKEN_COOKIE, SM_LEDVERY_ID_TOKEN_COOKIE, SM_LEDVERY_NONCE_COOKIE, SM_LEDVERY_PKCE_VERIFIER_COOKIE, SM_LEDVERY_STATE_COOKIE, ScaleMuleError, ScaleMuleServer, USER_ID_COOKIE_NAME, apiHandler, appendKnownAccountCookie, buildClientContextHeaders, buildFlagContext, buildSecurityHeaders, clearKnownAccountsCookie, clearOAuthState, clearSession, configureBundles, configureSecrets, createAnalyticsRoutes, createAuthMiddleware, createAuthRoutes, createLedveryRoutes, createNotificationRoutes, createPushRoutes, createServerClient, createWebhookHandler, createWebhookRoutes, errorCodeToStatus, extractClientContext, extractClientContextFromReq, generateCSRFToken, getAppSecret, getAppSecretOrDefault, getBootstrapFlags, getBundle, getCSRFToken, getKnownAccountsCookieRaw, getKnownAccountsFromRequest, getLedverySession, getMySqlBundle, getOAuthBundle, getPostgresBundle, getRedisBundle, getS3Bundle, getSession, getSessionFromRequest, getSmtpBundle, invalidateBundleCache, invalidateSecretCache, isSafeRedirect, normalizeKnownAccountsCookie, parseWebhookEvent, prefetchBundles, prefetchSecrets, registerVideoWebhook, removeKnownAccountFromCookie, requireAppSecret, requireBundle, requireSession, resolveGatewayUrl, setOAuthState, unwrap, validateCSRFToken, validateCSRFTokenAsync, validateOAuthState, validateOAuthStateAsync, validateSafeRedirect, verifyWebhookSignature, withAuth, withCSRFProtection, withCSRFToken, withSession };
@@ -1,3 +1,3 @@
1
- export { g as createWebhookHandler } from '../webhook-handler-DN4WBjbm.mjs';
1
+ export { g as createWebhookHandler } from '../webhook-handler-CVmBvPFN.mjs';
2
2
  import '@scalemule/money';
3
- import '../index-Tq5WdDfS.mjs';
3
+ import '../index-Bv1m_qQ8.mjs';
@@ -1,3 +1,3 @@
1
- export { g as createWebhookHandler } from '../webhook-handler-Cfa7-yKN.js';
1
+ export { g as createWebhookHandler } from '../webhook-handler-5ymVecTD.js';
2
2
  import '@scalemule/money';
3
- import '../index-Tq5WdDfS.js';
3
+ import '../index-Bv1m_qQ8.js';
@@ -1,6 +1,6 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { ReactNode } from 'react';
3
- import { U as User, A as ApiError, a9 as StorageFile } from './index-Tq5WdDfS.mjs';
3
+ import { U as User, A as ApiError, a9 as StorageFile } from './index-Bv1m_qQ8.mjs';
4
4
 
5
5
  interface MockUserOptions {
6
6
  id?: string;
package/dist/testing.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { ReactNode } from 'react';
3
- import { U as User, A as ApiError, a9 as StorageFile } from './index-Tq5WdDfS.js';
3
+ import { U as User, A as ApiError, a9 as StorageFile } from './index-Bv1m_qQ8.js';
4
4
 
5
5
  interface MockUserOptions {
6
6
  id?: string;
package/dist/testing.js CHANGED
@@ -11,6 +11,9 @@ var ScaleMuleApiError = class extends Error {
11
11
  this.code = error.code;
12
12
  this.field = error.field;
13
13
  this.status = status;
14
+ this.requestId = error.requestId;
15
+ this.traceId = error.traceId;
16
+ this.problem = error.problem;
14
17
  }
15
18
  };
16
19
  function createMockUser(options = {}) {
package/dist/testing.mjs CHANGED
@@ -9,6 +9,9 @@ var ScaleMuleApiError = class extends Error {
9
9
  this.code = error.code;
10
10
  this.field = error.field;
11
11
  this.status = status;
12
+ this.requestId = error.requestId;
13
+ this.traceId = error.traceId;
14
+ this.problem = error.problem;
12
15
  }
13
16
  };
14
17
  function createMockUser(options = {}) {
@@ -1,5 +1,5 @@
1
1
  import { MoneyClient } from '@scalemule/money';
2
- import { A as ApiError, $ as RegisterRequest, p as ClientContext, U as User, v as LoginRequest, L as LoginResponse, c as ListFilesParams, t as ListFilesResponse, a9 as StorageFile, af as UploadResponse } from './index-Tq5WdDfS.js';
2
+ import { A as ApiError, $ as RegisterRequest, p as ClientContext, U as User, v as LoginRequest, L as LoginResponse, c as ListFilesParams, t as ListFilesResponse, a9 as StorageFile, af as UploadResponse } from './index-Bv1m_qQ8.js';
3
3
 
4
4
  /**
5
5
  * Server-Side ScaleMule Client