@scalemule/nextjs 0.0.1 → 0.0.2
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/client.d.mts +8 -8
- package/dist/client.d.ts +8 -8
- package/dist/client.js +65 -59
- package/dist/client.mjs +65 -59
- package/dist/{index-BkacIKdu.d.mts → index-9v0SaLgg.d.mts} +8 -1
- package/dist/{index-BkacIKdu.d.ts → index-9v0SaLgg.d.ts} +8 -1
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +455 -514
- package/dist/index.mjs +455 -515
- package/dist/server/auth.js +116 -78
- package/dist/server/auth.mjs +116 -78
- package/dist/server/index.d.mts +14 -11
- package/dist/server/index.d.ts +14 -11
- package/dist/server/index.js +209 -175
- package/dist/server/index.mjs +209 -175
- package/dist/server/webhook-handler.d.mts +2 -2
- package/dist/server/webhook-handler.d.ts +2 -2
- package/dist/testing.d.mts +10 -10
- package/dist/testing.d.ts +10 -10
- package/dist/testing.js +13 -7
- package/dist/testing.mjs +13 -7
- package/dist/{webhook-handler-BPNqhuwL.d.ts → webhook-handler-DCSwldKC.d.mts} +66 -66
- package/dist/{webhook-handler-C-5_Ey1T.d.mts → webhook-handler-Ymeice_x.d.ts} +66 -66
- package/package.json +1 -1
package/dist/server/index.mjs
CHANGED
|
@@ -2,6 +2,16 @@ import { cookies } from 'next/headers';
|
|
|
2
2
|
import { NextResponse } from 'next/server';
|
|
3
3
|
import { createHmac, timingSafeEqual } from 'crypto';
|
|
4
4
|
|
|
5
|
+
// src/types/index.ts
|
|
6
|
+
var ScaleMuleApiError = class extends Error {
|
|
7
|
+
constructor(error) {
|
|
8
|
+
super(error.message);
|
|
9
|
+
this.name = "ScaleMuleApiError";
|
|
10
|
+
this.code = error.code;
|
|
11
|
+
this.field = error.field;
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
|
|
5
15
|
// src/server/context.ts
|
|
6
16
|
function validateIP(ip) {
|
|
7
17
|
if (!ip) return void 0;
|
|
@@ -542,22 +552,23 @@ var ScaleMuleServer = class {
|
|
|
542
552
|
headers,
|
|
543
553
|
body: formData
|
|
544
554
|
});
|
|
545
|
-
const
|
|
555
|
+
const text = await response.text();
|
|
556
|
+
const responseData = text ? JSON.parse(text) : null;
|
|
546
557
|
if (!response.ok) {
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
};
|
|
558
|
+
throw new ScaleMuleApiError(
|
|
559
|
+
responseData?.error || { code: "UPLOAD_FAILED", message: "Upload failed" }
|
|
560
|
+
);
|
|
551
561
|
}
|
|
562
|
+
const data = responseData?.data !== void 0 ? responseData.data : responseData;
|
|
552
563
|
return data;
|
|
553
564
|
} catch (err) {
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
};
|
|
565
|
+
if (err instanceof ScaleMuleApiError) {
|
|
566
|
+
throw err;
|
|
567
|
+
}
|
|
568
|
+
throw new ScaleMuleApiError({
|
|
569
|
+
code: "UPLOAD_ERROR",
|
|
570
|
+
message: err instanceof Error ? err.message : "Upload failed"
|
|
571
|
+
});
|
|
561
572
|
}
|
|
562
573
|
}
|
|
563
574
|
};
|
|
@@ -580,7 +591,7 @@ var ScaleMuleServer = class {
|
|
|
580
591
|
* })
|
|
581
592
|
*
|
|
582
593
|
* // Store the secret for signature verification
|
|
583
|
-
* console.log('Webhook secret:', result.
|
|
594
|
+
* console.log('Webhook secret:', result.secret)
|
|
584
595
|
* ```
|
|
585
596
|
*/
|
|
586
597
|
create: async (data) => {
|
|
@@ -735,23 +746,25 @@ var ScaleMuleServer = class {
|
|
|
735
746
|
headers,
|
|
736
747
|
body: options.body ? JSON.stringify(options.body) : void 0
|
|
737
748
|
});
|
|
738
|
-
const
|
|
749
|
+
const text = await response.text();
|
|
750
|
+
const responseData = text ? JSON.parse(text) : null;
|
|
739
751
|
if (!response.ok) {
|
|
740
|
-
const error =
|
|
752
|
+
const error = responseData?.error || {
|
|
741
753
|
code: `HTTP_${response.status}`,
|
|
742
|
-
message:
|
|
754
|
+
message: responseData?.message || response.statusText
|
|
743
755
|
};
|
|
744
|
-
|
|
756
|
+
throw new ScaleMuleApiError(error);
|
|
745
757
|
}
|
|
758
|
+
const data = responseData?.data !== void 0 ? responseData.data : responseData;
|
|
746
759
|
return data;
|
|
747
760
|
} catch (err) {
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
};
|
|
761
|
+
if (err instanceof ScaleMuleApiError) {
|
|
762
|
+
throw err;
|
|
763
|
+
}
|
|
764
|
+
throw new ScaleMuleApiError({
|
|
765
|
+
code: "SERVER_ERROR",
|
|
766
|
+
message: err instanceof Error ? err.message : "Request failed"
|
|
767
|
+
});
|
|
755
768
|
}
|
|
756
769
|
}
|
|
757
770
|
};
|
|
@@ -1010,18 +1023,21 @@ function createAuthRoutes(config = {}) {
|
|
|
1010
1023
|
if (!email || !password) {
|
|
1011
1024
|
return errorResponse("VALIDATION_ERROR", "Email and password required", 400);
|
|
1012
1025
|
}
|
|
1013
|
-
|
|
1014
|
-
|
|
1026
|
+
let registeredUser;
|
|
1027
|
+
try {
|
|
1028
|
+
registeredUser = await sm.auth.register({ email, password, full_name, username, phone });
|
|
1029
|
+
} catch (err) {
|
|
1030
|
+
const apiErr = err instanceof ScaleMuleApiError ? err : null;
|
|
1015
1031
|
return errorResponse(
|
|
1016
|
-
|
|
1017
|
-
|
|
1032
|
+
apiErr?.code || "REGISTER_FAILED",
|
|
1033
|
+
apiErr?.message || "Registration failed",
|
|
1018
1034
|
400
|
|
1019
1035
|
);
|
|
1020
1036
|
}
|
|
1021
|
-
if (config.onRegister
|
|
1022
|
-
await config.onRegister({ id:
|
|
1037
|
+
if (config.onRegister) {
|
|
1038
|
+
await config.onRegister({ id: registeredUser.id, email: registeredUser.email });
|
|
1023
1039
|
}
|
|
1024
|
-
return successResponse({ user:
|
|
1040
|
+
return successResponse({ user: registeredUser, message: "Registration successful" }, 201);
|
|
1025
1041
|
}
|
|
1026
1042
|
// ==================== Login ====================
|
|
1027
1043
|
case "login": {
|
|
@@ -1029,9 +1045,12 @@ function createAuthRoutes(config = {}) {
|
|
|
1029
1045
|
if (!email || !password) {
|
|
1030
1046
|
return errorResponse("VALIDATION_ERROR", "Email and password required", 400);
|
|
1031
1047
|
}
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1048
|
+
let loginData;
|
|
1049
|
+
try {
|
|
1050
|
+
loginData = await sm.auth.login({ email, password, remember_me });
|
|
1051
|
+
} catch (err) {
|
|
1052
|
+
const apiErr = err instanceof ScaleMuleApiError ? err : null;
|
|
1053
|
+
const errorCode = apiErr?.code || "LOGIN_FAILED";
|
|
1035
1054
|
let status = 400;
|
|
1036
1055
|
if (errorCode === "INVALID_CREDENTIALS" || errorCode === "UNAUTHORIZED") status = 401;
|
|
1037
1056
|
if (["EMAIL_NOT_VERIFIED", "PHONE_NOT_VERIFIED", "ACCOUNT_LOCKED", "ACCOUNT_DISABLED", "MFA_REQUIRED"].includes(errorCode)) {
|
|
@@ -1039,17 +1058,17 @@ function createAuthRoutes(config = {}) {
|
|
|
1039
1058
|
}
|
|
1040
1059
|
return errorResponse(
|
|
1041
1060
|
errorCode,
|
|
1042
|
-
|
|
1061
|
+
apiErr?.message || "Login failed",
|
|
1043
1062
|
status
|
|
1044
1063
|
);
|
|
1045
1064
|
}
|
|
1046
1065
|
if (config.onLogin) {
|
|
1047
1066
|
await config.onLogin({
|
|
1048
|
-
id:
|
|
1049
|
-
email:
|
|
1067
|
+
id: loginData.user.id,
|
|
1068
|
+
email: loginData.user.email
|
|
1050
1069
|
});
|
|
1051
1070
|
}
|
|
1052
|
-
return withSession(
|
|
1071
|
+
return withSession(loginData, { user: loginData.user }, cookieOptions);
|
|
1053
1072
|
}
|
|
1054
1073
|
// ==================== Logout ====================
|
|
1055
1074
|
case "logout": {
|
|
@@ -1077,11 +1096,13 @@ function createAuthRoutes(config = {}) {
|
|
|
1077
1096
|
if (!token || !new_password) {
|
|
1078
1097
|
return errorResponse("VALIDATION_ERROR", "Token and new password required", 400);
|
|
1079
1098
|
}
|
|
1080
|
-
|
|
1081
|
-
|
|
1099
|
+
try {
|
|
1100
|
+
await sm.auth.resetPassword(token, new_password);
|
|
1101
|
+
} catch (err) {
|
|
1102
|
+
const apiErr = err instanceof ScaleMuleApiError ? err : null;
|
|
1082
1103
|
return errorResponse(
|
|
1083
|
-
|
|
1084
|
-
|
|
1104
|
+
apiErr?.code || "RESET_FAILED",
|
|
1105
|
+
apiErr?.message || "Password reset failed",
|
|
1085
1106
|
400
|
|
1086
1107
|
);
|
|
1087
1108
|
}
|
|
@@ -1093,11 +1114,13 @@ function createAuthRoutes(config = {}) {
|
|
|
1093
1114
|
if (!token) {
|
|
1094
1115
|
return errorResponse("VALIDATION_ERROR", "Token required", 400);
|
|
1095
1116
|
}
|
|
1096
|
-
|
|
1097
|
-
|
|
1117
|
+
try {
|
|
1118
|
+
await sm.auth.verifyEmail(token);
|
|
1119
|
+
} catch (err) {
|
|
1120
|
+
const apiErr = err instanceof ScaleMuleApiError ? err : null;
|
|
1098
1121
|
return errorResponse(
|
|
1099
|
-
|
|
1100
|
-
|
|
1122
|
+
apiErr?.code || "VERIFY_FAILED",
|
|
1123
|
+
apiErr?.message || "Email verification failed",
|
|
1101
1124
|
400
|
|
1102
1125
|
);
|
|
1103
1126
|
}
|
|
@@ -1109,12 +1132,14 @@ function createAuthRoutes(config = {}) {
|
|
|
1109
1132
|
const { email } = body;
|
|
1110
1133
|
const session = await getSession();
|
|
1111
1134
|
if (email) {
|
|
1112
|
-
|
|
1113
|
-
|
|
1135
|
+
try {
|
|
1136
|
+
await sm.auth.resendVerification(email);
|
|
1137
|
+
} catch (err) {
|
|
1138
|
+
const apiErr = err instanceof ScaleMuleApiError ? err : null;
|
|
1114
1139
|
return errorResponse(
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1140
|
+
apiErr?.code || "RESEND_FAILED",
|
|
1141
|
+
apiErr?.message || "Failed to resend verification",
|
|
1142
|
+
apiErr?.code === "RATE_LIMITED" ? 429 : 400
|
|
1118
1143
|
);
|
|
1119
1144
|
}
|
|
1120
1145
|
return successResponse({ message: "Verification email sent" });
|
|
@@ -1122,11 +1147,13 @@ function createAuthRoutes(config = {}) {
|
|
|
1122
1147
|
if (!session) {
|
|
1123
1148
|
return errorResponse("UNAUTHORIZED", "Email or session required", 401);
|
|
1124
1149
|
}
|
|
1125
|
-
|
|
1126
|
-
|
|
1150
|
+
try {
|
|
1151
|
+
await sm.auth.resendVerification(session.sessionToken);
|
|
1152
|
+
} catch (err) {
|
|
1153
|
+
const apiErr = err instanceof ScaleMuleApiError ? err : null;
|
|
1127
1154
|
return errorResponse(
|
|
1128
|
-
|
|
1129
|
-
|
|
1155
|
+
apiErr?.code || "RESEND_FAILED",
|
|
1156
|
+
apiErr?.message || "Failed to resend verification",
|
|
1130
1157
|
400
|
|
1131
1158
|
);
|
|
1132
1159
|
}
|
|
@@ -1138,15 +1165,17 @@ function createAuthRoutes(config = {}) {
|
|
|
1138
1165
|
if (!session) {
|
|
1139
1166
|
return errorResponse("UNAUTHORIZED", "Authentication required", 401);
|
|
1140
1167
|
}
|
|
1141
|
-
|
|
1142
|
-
|
|
1168
|
+
let refreshData;
|
|
1169
|
+
try {
|
|
1170
|
+
refreshData = await sm.auth.refresh(session.sessionToken);
|
|
1171
|
+
} catch {
|
|
1143
1172
|
return clearSession(
|
|
1144
1173
|
{ message: "Session expired" },
|
|
1145
1174
|
cookieOptions
|
|
1146
1175
|
);
|
|
1147
1176
|
}
|
|
1148
1177
|
return withRefreshedSession(
|
|
1149
|
-
|
|
1178
|
+
refreshData.session_token,
|
|
1150
1179
|
session.userId,
|
|
1151
1180
|
{ message: "Session refreshed" },
|
|
1152
1181
|
cookieOptions
|
|
@@ -1162,15 +1191,17 @@ function createAuthRoutes(config = {}) {
|
|
|
1162
1191
|
if (!current_password || !new_password) {
|
|
1163
1192
|
return errorResponse("VALIDATION_ERROR", "Current and new password required", 400);
|
|
1164
1193
|
}
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1194
|
+
try {
|
|
1195
|
+
await sm.user.changePassword(
|
|
1196
|
+
session.sessionToken,
|
|
1197
|
+
current_password,
|
|
1198
|
+
new_password
|
|
1199
|
+
);
|
|
1200
|
+
} catch (err) {
|
|
1201
|
+
const apiErr = err instanceof ScaleMuleApiError ? err : null;
|
|
1171
1202
|
return errorResponse(
|
|
1172
|
-
|
|
1173
|
-
|
|
1203
|
+
apiErr?.code || "CHANGE_FAILED",
|
|
1204
|
+
apiErr?.message || "Failed to change password",
|
|
1174
1205
|
400
|
|
1175
1206
|
);
|
|
1176
1207
|
}
|
|
@@ -1195,14 +1226,16 @@ function createAuthRoutes(config = {}) {
|
|
|
1195
1226
|
if (!session) {
|
|
1196
1227
|
return errorResponse("UNAUTHORIZED", "Authentication required", 401);
|
|
1197
1228
|
}
|
|
1198
|
-
|
|
1199
|
-
|
|
1229
|
+
let userData;
|
|
1230
|
+
try {
|
|
1231
|
+
userData = await sm.auth.me(session.sessionToken);
|
|
1232
|
+
} catch {
|
|
1200
1233
|
return clearSession(
|
|
1201
1234
|
{ error: { code: "SESSION_EXPIRED", message: "Session expired" } },
|
|
1202
1235
|
cookieOptions
|
|
1203
1236
|
);
|
|
1204
1237
|
}
|
|
1205
|
-
return successResponse({ user:
|
|
1238
|
+
return successResponse({ user: userData });
|
|
1206
1239
|
}
|
|
1207
1240
|
// ==================== Get Session Status ====================
|
|
1208
1241
|
case "session": {
|
|
@@ -1237,11 +1270,13 @@ function createAuthRoutes(config = {}) {
|
|
|
1237
1270
|
if (!password) {
|
|
1238
1271
|
return errorResponse("VALIDATION_ERROR", "Password required", 400);
|
|
1239
1272
|
}
|
|
1240
|
-
|
|
1241
|
-
|
|
1273
|
+
try {
|
|
1274
|
+
await sm.user.deleteAccount(session.sessionToken, password);
|
|
1275
|
+
} catch (err) {
|
|
1276
|
+
const apiErr = err instanceof ScaleMuleApiError ? err : null;
|
|
1242
1277
|
return errorResponse(
|
|
1243
|
-
|
|
1244
|
-
|
|
1278
|
+
apiErr?.code || "DELETE_FAILED",
|
|
1279
|
+
apiErr?.message || "Failed to delete account",
|
|
1245
1280
|
400
|
|
1246
1281
|
);
|
|
1247
1282
|
}
|
|
@@ -1269,15 +1304,18 @@ function createAuthRoutes(config = {}) {
|
|
|
1269
1304
|
}
|
|
1270
1305
|
const body = await request.json().catch(() => ({}));
|
|
1271
1306
|
const { full_name, avatar_url } = body;
|
|
1272
|
-
|
|
1273
|
-
|
|
1307
|
+
let updatedUser;
|
|
1308
|
+
try {
|
|
1309
|
+
updatedUser = await sm.user.update(session.sessionToken, { full_name, avatar_url });
|
|
1310
|
+
} catch (err) {
|
|
1311
|
+
const apiErr = err instanceof ScaleMuleApiError ? err : null;
|
|
1274
1312
|
return errorResponse(
|
|
1275
|
-
|
|
1276
|
-
|
|
1313
|
+
apiErr?.code || "UPDATE_FAILED",
|
|
1314
|
+
apiErr?.message || "Failed to update profile",
|
|
1277
1315
|
400
|
|
1278
1316
|
);
|
|
1279
1317
|
}
|
|
1280
|
-
return successResponse({ user:
|
|
1318
|
+
return successResponse({ user: updatedUser });
|
|
1281
1319
|
}
|
|
1282
1320
|
default:
|
|
1283
1321
|
return errorResponse("NOT_FOUND", `Unknown endpoint: ${path}`, 404);
|
|
@@ -1325,48 +1363,51 @@ function createAnalyticsRoutes(config = {}) {
|
|
|
1325
1363
|
if (!event_name) {
|
|
1326
1364
|
return errorResponse("VALIDATION_ERROR", "event_name is required", 400);
|
|
1327
1365
|
}
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1366
|
+
let trackResult;
|
|
1367
|
+
try {
|
|
1368
|
+
trackResult = await sm.analytics.trackEvent(
|
|
1369
|
+
{
|
|
1370
|
+
event_name,
|
|
1371
|
+
event_category,
|
|
1372
|
+
properties,
|
|
1373
|
+
user_id,
|
|
1374
|
+
session_id,
|
|
1375
|
+
anonymous_id,
|
|
1376
|
+
session_duration_seconds,
|
|
1377
|
+
page_url,
|
|
1378
|
+
page_title,
|
|
1379
|
+
referrer,
|
|
1380
|
+
landing_page,
|
|
1381
|
+
device_type,
|
|
1382
|
+
device_brand,
|
|
1383
|
+
device_model,
|
|
1384
|
+
browser,
|
|
1385
|
+
browser_version,
|
|
1386
|
+
os,
|
|
1387
|
+
os_version,
|
|
1388
|
+
screen_resolution,
|
|
1389
|
+
viewport_size,
|
|
1390
|
+
utm_source,
|
|
1391
|
+
utm_medium,
|
|
1392
|
+
utm_campaign,
|
|
1393
|
+
utm_term,
|
|
1394
|
+
utm_content,
|
|
1395
|
+
client_timestamp: client_timestamp || timestamp
|
|
1396
|
+
},
|
|
1397
|
+
{ clientContext }
|
|
1398
|
+
);
|
|
1399
|
+
} catch (err) {
|
|
1400
|
+
const apiErr = err instanceof ScaleMuleApiError ? err : null;
|
|
1360
1401
|
return errorResponse(
|
|
1361
|
-
|
|
1362
|
-
|
|
1402
|
+
apiErr?.code || "TRACK_FAILED",
|
|
1403
|
+
apiErr?.message || "Failed to track event",
|
|
1363
1404
|
400
|
|
1364
1405
|
);
|
|
1365
1406
|
}
|
|
1366
1407
|
if (config.onEvent) {
|
|
1367
|
-
await config.onEvent({ event_name, session_id:
|
|
1408
|
+
await config.onEvent({ event_name, session_id: trackResult?.session_id });
|
|
1368
1409
|
}
|
|
1369
|
-
return successResponse({ tracked:
|
|
1410
|
+
return successResponse({ tracked: trackResult?.tracked || 1, session_id: trackResult?.session_id });
|
|
1370
1411
|
};
|
|
1371
1412
|
const POST = async (request, context) => {
|
|
1372
1413
|
try {
|
|
@@ -1393,15 +1434,18 @@ function createAnalyticsRoutes(config = {}) {
|
|
|
1393
1434
|
if (events.length > 100) {
|
|
1394
1435
|
return errorResponse("VALIDATION_ERROR", "Maximum 100 events per batch", 400);
|
|
1395
1436
|
}
|
|
1396
|
-
|
|
1397
|
-
|
|
1437
|
+
let batchResult;
|
|
1438
|
+
try {
|
|
1439
|
+
batchResult = await sm.analytics.trackBatch(events, { clientContext });
|
|
1440
|
+
} catch (err) {
|
|
1441
|
+
const apiErr = err instanceof ScaleMuleApiError ? err : null;
|
|
1398
1442
|
return errorResponse(
|
|
1399
|
-
|
|
1400
|
-
|
|
1443
|
+
apiErr?.code || "BATCH_FAILED",
|
|
1444
|
+
apiErr?.message || "Failed to track events",
|
|
1401
1445
|
400
|
|
1402
1446
|
);
|
|
1403
1447
|
}
|
|
1404
|
-
return successResponse({ tracked:
|
|
1448
|
+
return successResponse({ tracked: batchResult?.tracked || events.length });
|
|
1405
1449
|
}
|
|
1406
1450
|
// ==================== Track Page View ====================
|
|
1407
1451
|
case "page-view":
|
|
@@ -1410,21 +1454,24 @@ function createAnalyticsRoutes(config = {}) {
|
|
|
1410
1454
|
if (!page_url) {
|
|
1411
1455
|
return errorResponse("VALIDATION_ERROR", "page_url is required", 400);
|
|
1412
1456
|
}
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1457
|
+
let pageViewResult;
|
|
1458
|
+
try {
|
|
1459
|
+
pageViewResult = await sm.analytics.trackPageView(
|
|
1460
|
+
{ page_url, page_title, referrer, session_id, user_id },
|
|
1461
|
+
{ clientContext }
|
|
1462
|
+
);
|
|
1463
|
+
} catch (err) {
|
|
1464
|
+
const apiErr = err instanceof ScaleMuleApiError ? err : null;
|
|
1418
1465
|
return errorResponse(
|
|
1419
|
-
|
|
1420
|
-
|
|
1466
|
+
apiErr?.code || "TRACK_FAILED",
|
|
1467
|
+
apiErr?.message || "Failed to track page view",
|
|
1421
1468
|
400
|
|
1422
1469
|
);
|
|
1423
1470
|
}
|
|
1424
1471
|
if (config.onEvent) {
|
|
1425
|
-
await config.onEvent({ event_name: "page_viewed", session_id:
|
|
1472
|
+
await config.onEvent({ event_name: "page_viewed", session_id: pageViewResult?.session_id });
|
|
1426
1473
|
}
|
|
1427
|
-
return successResponse({ tracked:
|
|
1474
|
+
return successResponse({ tracked: pageViewResult?.tracked || 1, session_id: pageViewResult?.session_id });
|
|
1428
1475
|
}
|
|
1429
1476
|
default:
|
|
1430
1477
|
return errorResponse("NOT_FOUND", `Unknown endpoint: ${path}`, 404);
|
|
@@ -1487,18 +1534,22 @@ function errorCodeToStatus(code) {
|
|
|
1487
1534
|
return CODE_TO_STATUS[code.toLowerCase()] || 400;
|
|
1488
1535
|
}
|
|
1489
1536
|
function unwrap(result) {
|
|
1490
|
-
if (result
|
|
1491
|
-
const
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
code
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1537
|
+
if (result !== null && result !== void 0 && typeof result === "object" && ("success" in result || "error" in result) && "data" in result) {
|
|
1538
|
+
const envelope = result;
|
|
1539
|
+
if (envelope.error || envelope.success === false) {
|
|
1540
|
+
const err = envelope.error;
|
|
1541
|
+
const code = err?.code || "UNKNOWN_ERROR";
|
|
1542
|
+
const status = err?.status || errorCodeToStatus(code);
|
|
1543
|
+
throw new ScaleMuleError(
|
|
1544
|
+
code,
|
|
1545
|
+
err?.message || "An error occurred",
|
|
1546
|
+
status,
|
|
1547
|
+
err?.details
|
|
1548
|
+
);
|
|
1549
|
+
}
|
|
1550
|
+
return envelope.data;
|
|
1500
1551
|
}
|
|
1501
|
-
return result
|
|
1552
|
+
return result;
|
|
1502
1553
|
}
|
|
1503
1554
|
|
|
1504
1555
|
// src/server/handler.ts
|
|
@@ -1576,12 +1627,9 @@ async function registerVideoWebhook(url, options) {
|
|
|
1576
1627
|
url,
|
|
1577
1628
|
events: options?.events || ["video.ready", "video.failed"]
|
|
1578
1629
|
});
|
|
1579
|
-
if (!result.success || !result.data) {
|
|
1580
|
-
throw new Error(result.error?.message || "Failed to register webhook");
|
|
1581
|
-
}
|
|
1582
1630
|
return {
|
|
1583
|
-
id: result.
|
|
1584
|
-
secret: result.
|
|
1631
|
+
id: result.id,
|
|
1632
|
+
secret: result.secret
|
|
1585
1633
|
};
|
|
1586
1634
|
}
|
|
1587
1635
|
function createWebhookRoutes(config = {}) {
|
|
@@ -1722,13 +1770,7 @@ function createAuthMiddleware(config = {}) {
|
|
|
1722
1770
|
if (!skipValidation) {
|
|
1723
1771
|
try {
|
|
1724
1772
|
const sm = createServerClient();
|
|
1725
|
-
|
|
1726
|
-
if (!result.success) {
|
|
1727
|
-
const response = NextResponse.redirect(new URL(redirectTo, request.url));
|
|
1728
|
-
response.cookies.delete(SESSION_COOKIE_NAME);
|
|
1729
|
-
response.cookies.delete(USER_ID_COOKIE_NAME);
|
|
1730
|
-
return response;
|
|
1731
|
-
}
|
|
1773
|
+
await sm.auth.me(session.sessionToken);
|
|
1732
1774
|
} catch (error) {
|
|
1733
1775
|
console.error("[ScaleMule Middleware] Session validation failed, blocking request:", error);
|
|
1734
1776
|
const response = NextResponse.redirect(new URL(redirectTo, request.url));
|
|
@@ -1819,22 +1861,18 @@ async function getAppSecret(key) {
|
|
|
1819
1861
|
try {
|
|
1820
1862
|
const client = createServerClient();
|
|
1821
1863
|
const result = await client.secrets.get(key);
|
|
1822
|
-
if (!result
|
|
1823
|
-
if (result.error?.code === "SECRET_NOT_FOUND") {
|
|
1824
|
-
return void 0;
|
|
1825
|
-
}
|
|
1826
|
-
console.error(`[ScaleMule Secrets] Failed to fetch ${key}:`, result.error);
|
|
1827
|
-
return void 0;
|
|
1828
|
-
}
|
|
1829
|
-
if (!noCache && result.data) {
|
|
1864
|
+
if (!noCache && result) {
|
|
1830
1865
|
secretsCache[key] = {
|
|
1831
|
-
value: result.
|
|
1832
|
-
version: result.
|
|
1866
|
+
value: result.value,
|
|
1867
|
+
version: result.version,
|
|
1833
1868
|
cachedAt: Date.now()
|
|
1834
1869
|
};
|
|
1835
1870
|
}
|
|
1836
|
-
return result
|
|
1871
|
+
return result?.value;
|
|
1837
1872
|
} catch (error) {
|
|
1873
|
+
if (error instanceof ScaleMuleApiError && error.code === "SECRET_NOT_FOUND") {
|
|
1874
|
+
return void 0;
|
|
1875
|
+
}
|
|
1838
1876
|
console.error(`[ScaleMule Secrets] Error fetching ${key}:`, error);
|
|
1839
1877
|
return void 0;
|
|
1840
1878
|
}
|
|
@@ -1882,24 +1920,20 @@ async function getBundle(key, resolve = true) {
|
|
|
1882
1920
|
try {
|
|
1883
1921
|
const client = createServerClient();
|
|
1884
1922
|
const result = await client.bundles.get(key, resolve);
|
|
1885
|
-
if (!result
|
|
1886
|
-
if (result.error?.code === "BUNDLE_NOT_FOUND") {
|
|
1887
|
-
return void 0;
|
|
1888
|
-
}
|
|
1889
|
-
console.error(`[ScaleMule Bundles] Failed to fetch ${key}:`, result.error);
|
|
1890
|
-
return void 0;
|
|
1891
|
-
}
|
|
1892
|
-
if (!noCache && result.data) {
|
|
1923
|
+
if (!noCache && result) {
|
|
1893
1924
|
bundlesCache[key] = {
|
|
1894
|
-
type: result.
|
|
1895
|
-
data: result.data
|
|
1896
|
-
version: result.
|
|
1897
|
-
inheritsFrom: result.
|
|
1925
|
+
type: result.type,
|
|
1926
|
+
data: result.data,
|
|
1927
|
+
version: result.version,
|
|
1928
|
+
inheritsFrom: result.inherits_from,
|
|
1898
1929
|
cachedAt: Date.now()
|
|
1899
1930
|
};
|
|
1900
1931
|
}
|
|
1901
|
-
return result
|
|
1932
|
+
return result?.data;
|
|
1902
1933
|
} catch (error) {
|
|
1934
|
+
if (error instanceof ScaleMuleApiError && error.code === "BUNDLE_NOT_FOUND") {
|
|
1935
|
+
return void 0;
|
|
1936
|
+
}
|
|
1903
1937
|
console.error(`[ScaleMule Bundles] Error fetching ${key}:`, error);
|
|
1904
1938
|
return void 0;
|
|
1905
1939
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { h as createWebhookHandler } from '../webhook-handler-
|
|
2
|
-
import '../index-
|
|
1
|
+
export { h as createWebhookHandler } from '../webhook-handler-DCSwldKC.mjs';
|
|
2
|
+
import '../index-9v0SaLgg.mjs';
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { h as createWebhookHandler } from '../webhook-handler-
|
|
2
|
-
import '../index-
|
|
1
|
+
export { h as createWebhookHandler } from '../webhook-handler-Ymeice_x.js';
|
|
2
|
+
import '../index-9v0SaLgg.js';
|
package/dist/testing.d.mts
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,
|
|
3
|
+
import { U as User, N as StorageFile, A as ApiError } from './index-9v0SaLgg.mjs';
|
|
4
4
|
|
|
5
5
|
interface MockUserOptions {
|
|
6
6
|
id?: string;
|
|
@@ -27,8 +27,8 @@ interface MockFileOptions {
|
|
|
27
27
|
}
|
|
28
28
|
declare function createMockFile(options?: MockFileOptions): StorageFile;
|
|
29
29
|
interface MockClientConfig {
|
|
30
|
-
/** Simulated responses for specific paths */
|
|
31
|
-
responses?: Record<string,
|
|
30
|
+
/** Simulated responses for specific paths (return value, not wrapped) */
|
|
31
|
+
responses?: Record<string, unknown>;
|
|
32
32
|
/** Default delay in ms (simulates network latency) */
|
|
33
33
|
delay?: number;
|
|
34
34
|
/** Whether to simulate errors */
|
|
@@ -46,13 +46,13 @@ declare class MockScaleMuleClient {
|
|
|
46
46
|
getSessionToken(): string | null;
|
|
47
47
|
getUserId(): string | null;
|
|
48
48
|
isAuthenticated(): boolean;
|
|
49
|
-
request<T>(path: string): Promise<
|
|
50
|
-
get<T>(path: string): Promise<
|
|
51
|
-
post<T>(path: string): Promise<
|
|
52
|
-
patch<T>(path: string): Promise<
|
|
53
|
-
put<T>(path: string): Promise<
|
|
54
|
-
delete<T>(path: string): Promise<
|
|
55
|
-
upload<T>(): Promise<
|
|
49
|
+
request<T>(path: string): Promise<T>;
|
|
50
|
+
get<T>(path: string): Promise<T>;
|
|
51
|
+
post<T>(path: string): Promise<T>;
|
|
52
|
+
patch<T>(path: string): Promise<T>;
|
|
53
|
+
put<T>(path: string): Promise<T>;
|
|
54
|
+
delete<T>(path: string): Promise<T>;
|
|
55
|
+
upload<T>(): Promise<T>;
|
|
56
56
|
}
|
|
57
57
|
interface MockScaleMuleContextValue {
|
|
58
58
|
client: MockScaleMuleClient;
|