@sylphx/sdk 0.10.0 → 0.10.1
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 +13 -12
- package/dist/index.d.ts +43 -23
- package/dist/index.mjs +81 -102
- package/dist/index.mjs.map +1 -1
- package/dist/nextjs/index.d.ts +19 -6
- package/dist/nextjs/index.mjs +127 -22
- package/dist/nextjs/index.mjs.map +1 -1
- package/dist/react/index.d.ts +20 -12
- package/dist/react/index.mjs +199 -153
- package/dist/react/index.mjs.map +1 -1
- package/dist/server/index.d.ts +41 -34
- package/dist/server/index.mjs +81 -66
- package/dist/server/index.mjs.map +1 -1
- package/dist/web-analytics.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -4783,7 +4783,7 @@ var init_webapi = __esm({
|
|
|
4783
4783
|
// src/connection-url.ts
|
|
4784
4784
|
var SYLPHX_PROTOCOL = "sylphx:";
|
|
4785
4785
|
var DEFAULT_VERSION = "v1";
|
|
4786
|
-
var CREDENTIAL_REGEX = /^(pk|sk)_(dev|stg|prod|prev)_[a-f0-9]{32,64}$/;
|
|
4786
|
+
var CREDENTIAL_REGEX = /^(pk|sk)_(dev|stg|prod|prev)(?:_[a-z0-9]{12})?_[a-f0-9]{32,64}$/;
|
|
4787
4787
|
var VERSION_REGEX = /^v[0-9]+$/;
|
|
4788
4788
|
var SLUG_REGEX = /^[a-z0-9]([a-z0-9-]*[a-z0-9])?$/;
|
|
4789
4789
|
var InvalidConnectionUrlError = class _InvalidConnectionUrlError extends Error {
|
|
@@ -4800,7 +4800,7 @@ function fail(reason) {
|
|
|
4800
4800
|
function parseCredential(raw) {
|
|
4801
4801
|
const match = CREDENTIAL_REGEX.exec(raw);
|
|
4802
4802
|
if (!match) {
|
|
4803
|
-
fail(`credential must match (pk|sk)_(dev|stg|prod|prev)_
|
|
4803
|
+
fail(`credential must match (pk|sk)_(dev|stg|prod|prev)(_{ref})?_{hex}, got "${raw}"`);
|
|
4804
4804
|
}
|
|
4805
4805
|
return {
|
|
4806
4806
|
credentialType: match[1],
|
|
@@ -4879,7 +4879,7 @@ init_constants();
|
|
|
4879
4879
|
init_errors();
|
|
4880
4880
|
var LEGACY_EMBEDDED_REF_PATTERN = /^(pk|sk)_(dev|stg|prod|prev)_[a-z0-9]{12}_[a-f0-9]+$/;
|
|
4881
4881
|
var LEGACY_APP_KEY_PATTERN = /^app_(dev|stg|prod|prev)_/;
|
|
4882
|
-
var MIGRATION_MESSAGE = "API key format has changed. Use a sylphx:// connection URL instead.\n\nNew format: sylphx://pk_prod_{hex}@your-slug.api.sylphx.com\n\nGenerate new credentials from the Sylphx Console \u2192 Your App \u2192 Environments.\nSee https://docs.sylphx.com/migration for details.";
|
|
4882
|
+
var MIGRATION_MESSAGE = "API key format has changed. Use a sylphx:// connection URL instead.\n\nNew format: sylphx://pk_prod_{ref?}_{hex}@your-slug.api.sylphx.com\n\nGenerate new credentials from the Sylphx Console \u2192 Your App \u2192 Environments.\nSee https://docs.sylphx.com/migration for details.";
|
|
4883
4883
|
function rejectLegacyKeyFormat(input) {
|
|
4884
4884
|
const trimmed = input.trim().toLowerCase();
|
|
4885
4885
|
if (LEGACY_APP_KEY_PATTERN.test(trimmed)) {
|
|
@@ -5012,7 +5012,7 @@ function createConfigFromComponents(input) {
|
|
|
5012
5012
|
});
|
|
5013
5013
|
}
|
|
5014
5014
|
throw new SylphxError(
|
|
5015
|
-
`[Sylphx] Invalid credential format. Expected (pk|sk)_(dev|stg|prod|prev)_
|
|
5015
|
+
`[Sylphx] Invalid credential format. Expected (pk|sk)_(dev|stg|prod|prev)(_{ref})?_{hex}. Got: "${trimmedCred.slice(0, 30)}..."`,
|
|
5016
5016
|
{ code: "BAD_REQUEST" }
|
|
5017
5017
|
);
|
|
5018
5018
|
}
|
|
@@ -5291,11 +5291,12 @@ init_constants();
|
|
|
5291
5291
|
init_errors();
|
|
5292
5292
|
|
|
5293
5293
|
// src/key-validation.ts
|
|
5294
|
-
var SECRET_KEY_PATTERN = /^sk_(dev|stg|prod)_[a-z0-9_-]+$/;
|
|
5294
|
+
var SECRET_KEY_PATTERN = /^sk_(dev|stg|prod|prev)_[a-z0-9_-]+$/;
|
|
5295
5295
|
var ENV_PREFIX_MAP = {
|
|
5296
5296
|
dev: "development",
|
|
5297
5297
|
stg: "staging",
|
|
5298
|
-
prod: "production"
|
|
5298
|
+
prod: "production",
|
|
5299
|
+
prev: "preview"
|
|
5299
5300
|
};
|
|
5300
5301
|
function detectKeyIssues(key) {
|
|
5301
5302
|
const issues = [];
|
|
@@ -5320,7 +5321,7 @@ The SDK will automatically sanitize the key, but fixing the source is recommende
|
|
|
5320
5321
|
}
|
|
5321
5322
|
function createInvalidKeyError(keyType, key, envVarName) {
|
|
5322
5323
|
const maskedKey = key.length > 20 ? `${key.slice(0, 20)}...` : key;
|
|
5323
|
-
const formatHint = keyType === "appId" ? "pk_(dev|stg|prod)_{ref}_{hex} or app_(dev|stg|prod)_[id]" : "sk_(dev|stg|prod)_{ref}_{hex}";
|
|
5324
|
+
const formatHint = keyType === "appId" ? "pk_(dev|stg|prod|prev)_{ref}_{hex} or app_(dev|stg|prod|prev)_[id]" : "sk_(dev|stg|prod|prev)_{ref}_{hex}";
|
|
5324
5325
|
const keyTypeName = keyType === "appId" ? "App ID" : "Secret Key";
|
|
5325
5326
|
return `[Sylphx] Invalid ${keyTypeName} format.
|
|
5326
5327
|
|
|
@@ -5333,7 +5334,7 @@ You can find your keys in the Sylphx Console \u2192 API Keys.
|
|
|
5333
5334
|
Common issues:
|
|
5334
5335
|
\u2022 Key has uppercase characters (must be lowercase)
|
|
5335
5336
|
\u2022 Key has wrong prefix (App ID: pk_ or app_, Secret Key: sk_)
|
|
5336
|
-
\u2022 Key has invalid environment (must be dev, stg, or
|
|
5337
|
+
\u2022 Key has invalid environment (must be dev, stg, prod, or prev)
|
|
5337
5338
|
\u2022 Key was copied with extra whitespace`;
|
|
5338
5339
|
}
|
|
5339
5340
|
function extractEnvironment(key) {
|
|
@@ -5380,7 +5381,7 @@ function validateKeyForType(key, keyType, pattern, envVarName) {
|
|
|
5380
5381
|
};
|
|
5381
5382
|
}
|
|
5382
5383
|
function validateSecretKey(key) {
|
|
5383
|
-
return validateKeyForType(key, "secret", SECRET_KEY_PATTERN, "
|
|
5384
|
+
return validateKeyForType(key, "secret", SECRET_KEY_PATTERN, "secret credential");
|
|
5384
5385
|
}
|
|
5385
5386
|
function validateAndSanitizeSecretKey(key) {
|
|
5386
5387
|
const result = validateSecretKey(key);
|
|
@@ -5402,7 +5403,14 @@ async function runPipeline(middlewares, initial) {
|
|
|
5402
5403
|
if (next) request = next;
|
|
5403
5404
|
}
|
|
5404
5405
|
}
|
|
5405
|
-
|
|
5406
|
+
const fetchWithMiddleware = middlewares.reduceRight(
|
|
5407
|
+
(next, mw) => mw.onFetch ? async (request2) => {
|
|
5408
|
+
const response2 = await mw.onFetch?.({ request: request2, next });
|
|
5409
|
+
return response2 ?? next(request2);
|
|
5410
|
+
} : next,
|
|
5411
|
+
(request2) => fetch(request2)
|
|
5412
|
+
);
|
|
5413
|
+
let response = await fetchWithMiddleware(request);
|
|
5406
5414
|
for (const mw of middlewares) {
|
|
5407
5415
|
if (mw.onResponse) {
|
|
5408
5416
|
const next = await mw.onResponse({ request, response });
|
|
@@ -5421,6 +5429,11 @@ function buildUrl(baseUrl, path, params) {
|
|
|
5421
5429
|
).toString();
|
|
5422
5430
|
return `${url}?${search2}`;
|
|
5423
5431
|
}
|
|
5432
|
+
function cloneRequestWithHeaders(request, updateHeaders) {
|
|
5433
|
+
const headers = new Headers(request.headers);
|
|
5434
|
+
updateHeaders(headers);
|
|
5435
|
+
return new Request(request, { headers });
|
|
5436
|
+
}
|
|
5424
5437
|
function interpolatePath(path, pathParams) {
|
|
5425
5438
|
if (!pathParams) return path;
|
|
5426
5439
|
return path.replace(/\{(\w+)\}/g, (_match, key) => {
|
|
@@ -5483,66 +5496,51 @@ function buildClient(baseUrl, baseHeaders) {
|
|
|
5483
5496
|
function createAuthMiddleware(config) {
|
|
5484
5497
|
return {
|
|
5485
5498
|
async onRequest({ request }) {
|
|
5486
|
-
request
|
|
5487
|
-
|
|
5488
|
-
|
|
5489
|
-
|
|
5490
|
-
|
|
5491
|
-
|
|
5492
|
-
|
|
5493
|
-
|
|
5494
|
-
|
|
5495
|
-
|
|
5499
|
+
return cloneRequestWithHeaders(request, (headers) => {
|
|
5500
|
+
headers.set("X-SDK-Version", SDK_VERSION);
|
|
5501
|
+
headers.set("X-SDK-Platform", SDK_PLATFORM);
|
|
5502
|
+
if (config.secretKey) {
|
|
5503
|
+
headers.set("x-app-secret", config.secretKey);
|
|
5504
|
+
}
|
|
5505
|
+
const token = config.getAccessToken?.();
|
|
5506
|
+
if (token) {
|
|
5507
|
+
headers.set("Authorization", `Bearer ${token}`);
|
|
5508
|
+
}
|
|
5509
|
+
});
|
|
5496
5510
|
}
|
|
5497
5511
|
};
|
|
5498
5512
|
}
|
|
5499
5513
|
function isRetryableStatus(status) {
|
|
5500
5514
|
return status >= 500 || status === 429;
|
|
5501
5515
|
}
|
|
5502
|
-
var inFlightRequests = /* @__PURE__ */ new Map();
|
|
5503
5516
|
async function getRequestKey(request) {
|
|
5504
5517
|
const body = request.body ? await request.clone().text() : "";
|
|
5505
5518
|
return `${request.method}:${request.url}:${body}`;
|
|
5506
5519
|
}
|
|
5507
5520
|
function createDeduplicationMiddleware(config = {}) {
|
|
5508
5521
|
const { enabled = true, methods = ["GET"] } = config;
|
|
5509
|
-
if (!enabled) {
|
|
5510
|
-
|
|
5511
|
-
async onRequest({ request }) {
|
|
5512
|
-
return request;
|
|
5513
|
-
}
|
|
5514
|
-
};
|
|
5515
|
-
}
|
|
5522
|
+
if (!enabled) return {};
|
|
5523
|
+
const inFlightRequests = /* @__PURE__ */ new Map();
|
|
5516
5524
|
return {
|
|
5517
|
-
async
|
|
5518
|
-
|
|
5519
|
-
|
|
5525
|
+
async onFetch({ request, next }) {
|
|
5526
|
+
const method = request.method.toUpperCase();
|
|
5527
|
+
if (!methods.includes(method)) {
|
|
5528
|
+
return next(request);
|
|
5520
5529
|
}
|
|
5521
5530
|
const key = await getRequestKey(request);
|
|
5522
5531
|
const existing = inFlightRequests.get(key);
|
|
5523
5532
|
if (existing) {
|
|
5524
|
-
const deduped = request.clone();
|
|
5525
|
-
deduped._dedupKey = key;
|
|
5526
|
-
return deduped;
|
|
5527
|
-
}
|
|
5528
|
-
;
|
|
5529
|
-
request._dedupKey = key;
|
|
5530
|
-
return request;
|
|
5531
|
-
},
|
|
5532
|
-
async onResponse({ request, response }) {
|
|
5533
|
-
const key = request._dedupKey;
|
|
5534
|
-
if (!key) return response;
|
|
5535
|
-
const existing = inFlightRequests.get(key);
|
|
5536
|
-
if (existing && inFlightRequests.get(key) !== void 0) {
|
|
5537
5533
|
const cachedResponse = await existing;
|
|
5538
5534
|
return cachedResponse.clone();
|
|
5539
5535
|
}
|
|
5540
|
-
const responsePromise =
|
|
5536
|
+
const responsePromise = next(request).then((response) => response.clone());
|
|
5541
5537
|
inFlightRequests.set(key, responsePromise);
|
|
5542
|
-
|
|
5543
|
-
|
|
5544
|
-
|
|
5545
|
-
|
|
5538
|
+
try {
|
|
5539
|
+
const response = await responsePromise;
|
|
5540
|
+
return response.clone();
|
|
5541
|
+
} finally {
|
|
5542
|
+
inFlightRequests.delete(key);
|
|
5543
|
+
}
|
|
5546
5544
|
}
|
|
5547
5545
|
};
|
|
5548
5546
|
}
|
|
@@ -5708,7 +5706,9 @@ function createETagMiddleware(config) {
|
|
|
5708
5706
|
if (Date.now() - cached.timestamp > ttlMs) {
|
|
5709
5707
|
etagCache.delete(cacheKey);
|
|
5710
5708
|
} else {
|
|
5711
|
-
request
|
|
5709
|
+
return cloneRequestWithHeaders(request, (headers) => {
|
|
5710
|
+
headers.set("If-None-Match", cached.etag);
|
|
5711
|
+
});
|
|
5712
5712
|
}
|
|
5713
5713
|
}
|
|
5714
5714
|
return request;
|
|
@@ -6000,11 +6000,28 @@ async function inviteUser(config, input) {
|
|
|
6000
6000
|
body: input
|
|
6001
6001
|
});
|
|
6002
6002
|
}
|
|
6003
|
-
|
|
6004
|
-
|
|
6003
|
+
function normalizeOrgScopedTokenResponse(data) {
|
|
6004
|
+
const accessToken = data.accessToken ?? data.access_token;
|
|
6005
|
+
if (!accessToken) {
|
|
6006
|
+
throw new Error("Invalid org-scoped token response: missing access token");
|
|
6007
|
+
}
|
|
6008
|
+
return {
|
|
6009
|
+
token: accessToken,
|
|
6010
|
+
accessToken,
|
|
6011
|
+
expiresIn: data.expiresIn ?? data.expires_in,
|
|
6012
|
+
tokenType: data.tokenType ?? data.token_type,
|
|
6013
|
+
user: data.user
|
|
6014
|
+
};
|
|
6015
|
+
}
|
|
6016
|
+
async function getOrgScopedToken(config, orgId) {
|
|
6017
|
+
const data = await callApi(config, "/auth/switch-org", {
|
|
6005
6018
|
method: "POST",
|
|
6006
6019
|
body: { orgId }
|
|
6007
6020
|
});
|
|
6021
|
+
return normalizeOrgScopedTokenResponse(data);
|
|
6022
|
+
}
|
|
6023
|
+
async function switchOrg(config, orgId) {
|
|
6024
|
+
return getOrgScopedToken(config, orgId);
|
|
6008
6025
|
}
|
|
6009
6026
|
var device = {
|
|
6010
6027
|
/**
|
|
@@ -8002,6 +8019,9 @@ async function getBillingUsage(config, options) {
|
|
|
8002
8019
|
});
|
|
8003
8020
|
}
|
|
8004
8021
|
|
|
8022
|
+
// src/storage.ts
|
|
8023
|
+
init_errors();
|
|
8024
|
+
|
|
8005
8025
|
// src/lib/retry.ts
|
|
8006
8026
|
init_constants();
|
|
8007
8027
|
var DEFAULT_RETRY_CONFIG = {
|
|
@@ -8124,7 +8144,6 @@ var PATHS = {
|
|
|
8124
8144
|
versions: (id) => `/storage/files/${encodeURIComponent(String(id))}/versions`,
|
|
8125
8145
|
versionRestore: (id, vid) => `/storage/files/${encodeURIComponent(String(id))}/versions/${encodeURIComponent(String(vid))}:restore`
|
|
8126
8146
|
};
|
|
8127
|
-
var isBrowser = () => typeof globalThis !== "undefined" && typeof globalThis.window !== "undefined";
|
|
8128
8147
|
var hasXhr = () => typeof globalThis.XMLHttpRequest !== "undefined";
|
|
8129
8148
|
var hasLocalStorage = () => {
|
|
8130
8149
|
try {
|
|
@@ -8136,16 +8155,14 @@ var hasLocalStorage = () => {
|
|
|
8136
8155
|
};
|
|
8137
8156
|
async function computeSha256Hex(blob) {
|
|
8138
8157
|
const subtle = globalThis.crypto?.subtle;
|
|
8139
|
-
if (subtle?.digest) {
|
|
8140
|
-
|
|
8141
|
-
|
|
8142
|
-
|
|
8158
|
+
if (!subtle?.digest) {
|
|
8159
|
+
throw new SylphxError("Web Crypto SHA-256 support is required for storage uploads", {
|
|
8160
|
+
code: "NOT_IMPLEMENTED"
|
|
8161
|
+
});
|
|
8143
8162
|
}
|
|
8144
|
-
const
|
|
8145
|
-
const
|
|
8146
|
-
|
|
8147
|
-
hash.update(buf);
|
|
8148
|
-
return hash.digest("hex");
|
|
8163
|
+
const buf = await blob.arrayBuffer();
|
|
8164
|
+
const digest2 = await subtle.digest("SHA-256", buf);
|
|
8165
|
+
return bytesToHex(new Uint8Array(digest2));
|
|
8149
8166
|
}
|
|
8150
8167
|
function bytesToHex(b) {
|
|
8151
8168
|
let s = "";
|
|
@@ -8162,10 +8179,6 @@ function persistResume(rec) {
|
|
|
8162
8179
|
localStorage.setItem(resumeKey(rec.uploadId), JSON.stringify(rec));
|
|
8163
8180
|
} catch {
|
|
8164
8181
|
}
|
|
8165
|
-
return;
|
|
8166
|
-
}
|
|
8167
|
-
if (!isBrowser()) {
|
|
8168
|
-
void persistResumeNode(rec);
|
|
8169
8182
|
}
|
|
8170
8183
|
}
|
|
8171
8184
|
function clearResume(uploadId) {
|
|
@@ -8174,41 +8187,6 @@ function clearResume(uploadId) {
|
|
|
8174
8187
|
localStorage.removeItem(resumeKey(uploadId));
|
|
8175
8188
|
} catch {
|
|
8176
8189
|
}
|
|
8177
|
-
return;
|
|
8178
|
-
}
|
|
8179
|
-
if (!isBrowser()) void clearResumeNode(uploadId);
|
|
8180
|
-
}
|
|
8181
|
-
async function persistResumeNode(rec) {
|
|
8182
|
-
try {
|
|
8183
|
-
const fs = await import("fs/promises");
|
|
8184
|
-
const path = await import("path");
|
|
8185
|
-
const os = await import("os");
|
|
8186
|
-
const dir = path.join(os.homedir(), ".sylphx");
|
|
8187
|
-
await fs.mkdir(dir, { recursive: true });
|
|
8188
|
-
const file = path.join(dir, "uploads.json");
|
|
8189
|
-
let store = {};
|
|
8190
|
-
try {
|
|
8191
|
-
const text = await fs.readFile(file, "utf8");
|
|
8192
|
-
store = JSON.parse(text);
|
|
8193
|
-
} catch {
|
|
8194
|
-
store = {};
|
|
8195
|
-
}
|
|
8196
|
-
store[rec.uploadId] = rec;
|
|
8197
|
-
await fs.writeFile(file, JSON.stringify(store), "utf8");
|
|
8198
|
-
} catch {
|
|
8199
|
-
}
|
|
8200
|
-
}
|
|
8201
|
-
async function clearResumeNode(uploadId) {
|
|
8202
|
-
try {
|
|
8203
|
-
const fs = await import("fs/promises");
|
|
8204
|
-
const path = await import("path");
|
|
8205
|
-
const os = await import("os");
|
|
8206
|
-
const file = path.join(os.homedir(), ".sylphx", "uploads.json");
|
|
8207
|
-
const text = await fs.readFile(file, "utf8");
|
|
8208
|
-
const store = JSON.parse(text);
|
|
8209
|
-
delete store[uploadId];
|
|
8210
|
-
await fs.writeFile(file, JSON.stringify(store), "utf8");
|
|
8211
|
-
} catch {
|
|
8212
8190
|
}
|
|
8213
8191
|
}
|
|
8214
8192
|
function putBlob(url, body, headers, signal, onProgress) {
|
|
@@ -8925,7 +8903,7 @@ function createTasksHandler(taskDefs, options = {}) {
|
|
|
8925
8903
|
{ status: 400 }
|
|
8926
8904
|
);
|
|
8927
8905
|
}
|
|
8928
|
-
const signingSecret = options.signingSecret ?? process.env.SYLPHX_SIGNING_SECRET ??
|
|
8906
|
+
const signingSecret = options.signingSecret ?? process.env.SYLPHX_SIGNING_SECRET ?? "";
|
|
8929
8907
|
if (signingSecret) {
|
|
8930
8908
|
const signature = req.headers.get("x-sylphx-signature") ?? "";
|
|
8931
8909
|
if (!signature) {
|
|
@@ -11032,6 +11010,7 @@ export {
|
|
|
11032
11010
|
getMemberPermissions,
|
|
11033
11011
|
getMyReferralCode,
|
|
11034
11012
|
getOidcDiscoveryDocument,
|
|
11013
|
+
getOrgScopedToken,
|
|
11035
11014
|
getOrganization,
|
|
11036
11015
|
getOrganizationInvitations,
|
|
11037
11016
|
getOrganizationMembers,
|