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