@sylphx/sdk 0.0.1 → 0.2.0
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/README.md +247 -260
- package/dist/index.js +61 -65
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +61 -65
- package/dist/index.mjs.map +1 -1
- package/dist/nextjs/index.js.map +1 -1
- package/dist/nextjs/index.mjs.map +1 -1
- package/dist/react/index.js +3668 -12695
- package/dist/react/index.js.map +1 -1
- package/dist/react/index.mjs +3671 -12698
- package/dist/react/index.mjs.map +1 -1
- package/dist/server/index.js +40 -39
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +39 -39
- package/dist/server/index.mjs.map +1 -1
- package/dist/web-analytics.js +1 -1
- package/dist/web-analytics.js.map +1 -1
- package/dist/web-analytics.mjs +1 -1
- package/dist/web-analytics.mjs.map +1 -1
- package/package.json +5 -6
- package/dist/index.d.cts +0 -13938
- package/dist/index.d.ts +0 -13938
- package/dist/nextjs/index.d.cts +0 -2089
- package/dist/nextjs/index.d.ts +0 -2089
- package/dist/react/index.d.cts +0 -14894
- package/dist/react/index.d.ts +0 -14894
- package/dist/server/index.d.cts +0 -9908
- package/dist/server/index.d.ts +0 -9908
- package/dist/web-analytics.d.cts +0 -90
- package/dist/web-analytics.d.ts +0 -90
package/dist/index.js
CHANGED
|
@@ -232,7 +232,7 @@ module.exports = __toCommonJS(index_exports);
|
|
|
232
232
|
|
|
233
233
|
// src/constants.ts
|
|
234
234
|
var DEFAULT_PLATFORM_URL = "https://sylphx.com";
|
|
235
|
-
var SDK_API_PATH = `/api/
|
|
235
|
+
var SDK_API_PATH = `/api/v1`;
|
|
236
236
|
var SDK_API_PATH_NEW = `/v1`;
|
|
237
237
|
var DEFAULT_SDK_API_HOST = "api.sylphx.com";
|
|
238
238
|
var SDK_VERSION = "0.1.0";
|
|
@@ -683,6 +683,7 @@ function httpStatusToErrorCode(status) {
|
|
|
683
683
|
return status >= 500 ? "INTERNAL_SERVER_ERROR" : "BAD_REQUEST";
|
|
684
684
|
}
|
|
685
685
|
}
|
|
686
|
+
var REF_PATTERN = /^[a-z0-9]{16}$/;
|
|
686
687
|
function createConfig(input) {
|
|
687
688
|
let secretKey;
|
|
688
689
|
if (input.secretKey) {
|
|
@@ -698,13 +699,22 @@ function createConfig(input) {
|
|
|
698
699
|
}
|
|
699
700
|
secretKey = result.sanitizedKey;
|
|
700
701
|
}
|
|
702
|
+
if (input.ref !== void 0) {
|
|
703
|
+
const trimmedRef = input.ref.trim();
|
|
704
|
+
if (!REF_PATTERN.test(trimmedRef)) {
|
|
705
|
+
throw new SylphxError(
|
|
706
|
+
`[Sylphx] Invalid project ref format: "${input.ref}". Expected a 16-character lowercase alphanumeric string (e.g. "abc123def456ghij"). Get your ref from Platform Console \u2192 Projects \u2192 Your Project \u2192 Overview.`,
|
|
707
|
+
{ code: "BAD_REQUEST" }
|
|
708
|
+
);
|
|
709
|
+
}
|
|
710
|
+
}
|
|
701
711
|
let platformUrl;
|
|
702
712
|
let apiBasePath;
|
|
703
713
|
if (input.platformUrl) {
|
|
704
714
|
platformUrl = input.platformUrl.trim();
|
|
705
715
|
apiBasePath = SDK_API_PATH;
|
|
706
716
|
} else if (input.ref) {
|
|
707
|
-
platformUrl = `https://${input.ref}.${DEFAULT_SDK_API_HOST}`;
|
|
717
|
+
platformUrl = `https://${input.ref.trim()}.${DEFAULT_SDK_API_HOST}`;
|
|
708
718
|
apiBasePath = SDK_API_PATH_NEW;
|
|
709
719
|
} else {
|
|
710
720
|
platformUrl = DEFAULT_PLATFORM_URL;
|
|
@@ -1008,6 +1018,7 @@ function createDeduplicationMiddleware(config = {}) {
|
|
|
1008
1018
|
deduped._dedupKey = key;
|
|
1009
1019
|
return deduped;
|
|
1010
1020
|
}
|
|
1021
|
+
;
|
|
1011
1022
|
request._dedupKey = key;
|
|
1012
1023
|
return request;
|
|
1013
1024
|
},
|
|
@@ -1031,30 +1042,24 @@ function createDeduplicationMiddleware(config = {}) {
|
|
|
1031
1042
|
var CircuitBreakerOpenError = class extends Error {
|
|
1032
1043
|
remainingMs;
|
|
1033
1044
|
constructor(remainingMs) {
|
|
1034
|
-
super(
|
|
1035
|
-
`Circuit breaker is open. Retry after ${Math.ceil(remainingMs / 1e3)}s`
|
|
1036
|
-
);
|
|
1045
|
+
super(`Circuit breaker is open. Retry after ${Math.ceil(remainingMs / 1e3)}s`);
|
|
1037
1046
|
this.name = "CircuitBreakerOpenError";
|
|
1038
1047
|
this.remainingMs = remainingMs;
|
|
1039
1048
|
}
|
|
1040
1049
|
};
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
}
|
|
1055
|
-
};
|
|
1056
|
-
}
|
|
1057
|
-
return circuitBreaker;
|
|
1050
|
+
function createCircuitBreakerInstance(config = {}) {
|
|
1051
|
+
return {
|
|
1052
|
+
state: "CLOSED",
|
|
1053
|
+
failures: [],
|
|
1054
|
+
openedAt: null,
|
|
1055
|
+
config: {
|
|
1056
|
+
enabled: config.enabled ?? true,
|
|
1057
|
+
failureThreshold: config.failureThreshold ?? CIRCUIT_BREAKER_FAILURE_THRESHOLD,
|
|
1058
|
+
windowMs: config.windowMs ?? CIRCUIT_BREAKER_WINDOW_MS,
|
|
1059
|
+
openDurationMs: config.openDurationMs ?? CIRCUIT_BREAKER_OPEN_DURATION_MS,
|
|
1060
|
+
isFailure: config.isFailure ?? ((status) => status >= 500 || status === 429)
|
|
1061
|
+
}
|
|
1062
|
+
};
|
|
1058
1063
|
}
|
|
1059
1064
|
function recordFailure(cb) {
|
|
1060
1065
|
const now = Date.now();
|
|
@@ -1102,7 +1107,8 @@ function createCircuitBreakerMiddleware(config) {
|
|
|
1102
1107
|
}
|
|
1103
1108
|
};
|
|
1104
1109
|
}
|
|
1105
|
-
const cb =
|
|
1110
|
+
const cb = createCircuitBreakerInstance(config ?? {});
|
|
1111
|
+
_lastCircuitBreaker = cb;
|
|
1106
1112
|
return {
|
|
1107
1113
|
async onRequest({ request }) {
|
|
1108
1114
|
if (!cb.config.enabled) {
|
|
@@ -1127,15 +1133,21 @@ function createCircuitBreakerMiddleware(config) {
|
|
|
1127
1133
|
}
|
|
1128
1134
|
};
|
|
1129
1135
|
}
|
|
1136
|
+
var _lastCircuitBreaker = null;
|
|
1130
1137
|
function resetCircuitBreaker() {
|
|
1131
|
-
|
|
1138
|
+
if (_lastCircuitBreaker) {
|
|
1139
|
+
_lastCircuitBreaker.state = "CLOSED";
|
|
1140
|
+
_lastCircuitBreaker.failures = [];
|
|
1141
|
+
_lastCircuitBreaker.openedAt = null;
|
|
1142
|
+
}
|
|
1143
|
+
_lastCircuitBreaker = null;
|
|
1132
1144
|
}
|
|
1133
1145
|
function getCircuitBreakerState() {
|
|
1134
|
-
if (!
|
|
1146
|
+
if (!_lastCircuitBreaker) return null;
|
|
1135
1147
|
return {
|
|
1136
|
-
state:
|
|
1137
|
-
failures:
|
|
1138
|
-
openedAt:
|
|
1148
|
+
state: _lastCircuitBreaker.state,
|
|
1149
|
+
failures: _lastCircuitBreaker.failures.length,
|
|
1150
|
+
openedAt: _lastCircuitBreaker.openedAt
|
|
1139
1151
|
};
|
|
1140
1152
|
}
|
|
1141
1153
|
var etagCache = /* @__PURE__ */ new Map();
|
|
@@ -1227,6 +1239,7 @@ function createETagMiddleware(config) {
|
|
|
1227
1239
|
}
|
|
1228
1240
|
};
|
|
1229
1241
|
}
|
|
1242
|
+
var retryBodyMap = /* @__PURE__ */ new WeakMap();
|
|
1230
1243
|
function createRetryMiddleware(retryConfig) {
|
|
1231
1244
|
if (retryConfig === false) {
|
|
1232
1245
|
return {
|
|
@@ -1242,27 +1255,22 @@ function createRetryMiddleware(retryConfig) {
|
|
|
1242
1255
|
shouldRetry = isRetryableStatus,
|
|
1243
1256
|
timeout = DEFAULT_TIMEOUT_MS
|
|
1244
1257
|
} = retryConfig ?? {};
|
|
1245
|
-
let originalBody = null;
|
|
1246
1258
|
return {
|
|
1247
1259
|
async onRequest({ request }) {
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
body: originalBody,
|
|
1260
|
-
signal: controller.signal
|
|
1261
|
-
});
|
|
1262
|
-
}
|
|
1263
|
-
return request;
|
|
1260
|
+
const body = request.body ? await request.clone().text() : null;
|
|
1261
|
+
const controller = new AbortController();
|
|
1262
|
+
setTimeout(() => controller.abort(), timeout);
|
|
1263
|
+
const newRequest = new Request(request.url, {
|
|
1264
|
+
method: request.method,
|
|
1265
|
+
headers: request.headers,
|
|
1266
|
+
body,
|
|
1267
|
+
signal: controller.signal
|
|
1268
|
+
});
|
|
1269
|
+
retryBodyMap.set(newRequest, body);
|
|
1270
|
+
return newRequest;
|
|
1264
1271
|
},
|
|
1265
1272
|
async onResponse({ response, request }) {
|
|
1273
|
+
const originalBody = retryBodyMap.get(request) ?? null;
|
|
1266
1274
|
let attempt = 0;
|
|
1267
1275
|
let currentResponse = response;
|
|
1268
1276
|
while (attempt < maxRetries && shouldRetry(currentResponse.status, attempt)) {
|
|
@@ -1282,16 +1290,19 @@ function createRetryMiddleware(retryConfig) {
|
|
|
1282
1290
|
const newResponse = await fetch(retryRequest);
|
|
1283
1291
|
clearTimeout(timeoutId);
|
|
1284
1292
|
if (newResponse.ok || !shouldRetry(newResponse.status, attempt)) {
|
|
1293
|
+
retryBodyMap.delete(request);
|
|
1285
1294
|
return newResponse;
|
|
1286
1295
|
}
|
|
1287
1296
|
currentResponse = newResponse;
|
|
1288
1297
|
} catch (error) {
|
|
1289
1298
|
clearTimeout(timeoutId);
|
|
1290
1299
|
if (attempt >= maxRetries) {
|
|
1300
|
+
retryBodyMap.delete(request);
|
|
1291
1301
|
throw error;
|
|
1292
1302
|
}
|
|
1293
1303
|
}
|
|
1294
1304
|
}
|
|
1305
|
+
retryBodyMap.delete(request);
|
|
1295
1306
|
return currentResponse;
|
|
1296
1307
|
}
|
|
1297
1308
|
};
|
|
@@ -1380,35 +1391,20 @@ async function signOut(config) {
|
|
|
1380
1391
|
await callApi(config, "/auth/logout", { method: "POST" });
|
|
1381
1392
|
}
|
|
1382
1393
|
async function refreshToken(config, token) {
|
|
1383
|
-
|
|
1394
|
+
return callApi(config, "/auth/token", {
|
|
1384
1395
|
method: "POST",
|
|
1385
|
-
|
|
1386
|
-
body: JSON.stringify({
|
|
1396
|
+
body: {
|
|
1387
1397
|
grant_type: "refresh_token",
|
|
1388
1398
|
refresh_token: token,
|
|
1389
1399
|
client_secret: config.secretKey
|
|
1390
|
-
}
|
|
1400
|
+
}
|
|
1391
1401
|
});
|
|
1392
|
-
if (!response.ok) {
|
|
1393
|
-
const error = await response.json().catch(() => ({ message: "Token refresh failed" }));
|
|
1394
|
-
throw new SylphxError(error.message ?? "Token refresh failed", {
|
|
1395
|
-
code: "UNAUTHORIZED"
|
|
1396
|
-
});
|
|
1397
|
-
}
|
|
1398
|
-
return response.json();
|
|
1399
1402
|
}
|
|
1400
1403
|
async function verifyEmail(config, token) {
|
|
1401
|
-
|
|
1404
|
+
await callApi(config, "/auth/verify-email", {
|
|
1402
1405
|
method: "POST",
|
|
1403
|
-
|
|
1404
|
-
body: JSON.stringify({ token })
|
|
1406
|
+
body: { token }
|
|
1405
1407
|
});
|
|
1406
|
-
if (!response.ok) {
|
|
1407
|
-
const error = await response.json().catch(() => ({ message: "Email verification failed" }));
|
|
1408
|
-
throw new SylphxError(error.message ?? "Email verification failed", {
|
|
1409
|
-
code: "BAD_REQUEST"
|
|
1410
|
-
});
|
|
1411
|
-
}
|
|
1412
1408
|
}
|
|
1413
1409
|
async function forgotPassword(config, email) {
|
|
1414
1410
|
await callApi(config, "/auth/forgot-password", {
|