@sylphx/sdk 0.3.4 → 0.3.5
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/index.d.cts +71 -26
- package/dist/index.d.ts +71 -26
- package/dist/index.js +103 -13
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +102 -13
- package/dist/index.mjs.map +1 -1
- package/dist/nextjs/index.js +12 -7
- package/dist/nextjs/index.js.map +1 -1
- package/dist/nextjs/index.mjs +12 -7
- package/dist/nextjs/index.mjs.map +1 -1
- package/dist/react/index.d.cts +33 -35
- package/dist/react/index.d.ts +33 -35
- package/dist/react/index.js +109 -20
- package/dist/react/index.js.map +1 -1
- package/dist/react/index.mjs +109 -20
- package/dist/react/index.mjs.map +1 -1
- package/dist/server/index.d.cts +21 -14
- package/dist/server/index.d.ts +21 -14
- package/dist/server/index.js +17 -8
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +17 -8
- package/dist/server/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -330,6 +330,7 @@ function exponentialBackoff(attempt, baseDelay = BASE_RETRY_DELAY_MS, maxDelay =
|
|
|
330
330
|
}
|
|
331
331
|
|
|
332
332
|
// src/key-validation.ts
|
|
333
|
+
var PUBLIC_KEY_PATTERN = /^pk_(dev|stg|prod)_[a-z0-9]{12}_[a-f0-9]{32}$/;
|
|
333
334
|
var APP_ID_PATTERN = /^app_(dev|stg|prod)_[a-z0-9_-]+$/;
|
|
334
335
|
var SECRET_KEY_PATTERN = /^sk_(dev|stg|prod)_[a-z0-9_-]+$/;
|
|
335
336
|
var ENV_PREFIX_MAP = {
|
|
@@ -420,6 +421,9 @@ function validateKeyForType(key, keyType, pattern, envVarName) {
|
|
|
420
421
|
issues: [...issues, "invalid-format"]
|
|
421
422
|
};
|
|
422
423
|
}
|
|
424
|
+
function validatePublicKey(key) {
|
|
425
|
+
return validateKeyForType(key, "publicKey", PUBLIC_KEY_PATTERN, "NEXT_PUBLIC_SYLPHX_KEY");
|
|
426
|
+
}
|
|
423
427
|
function validateAppId(key) {
|
|
424
428
|
return validateKeyForType(key, "appId", APP_ID_PATTERN, "NEXT_PUBLIC_SYLPHX_APP_ID");
|
|
425
429
|
}
|
|
@@ -438,12 +442,16 @@ function validateAndSanitizeSecretKey(key) {
|
|
|
438
442
|
}
|
|
439
443
|
function detectKeyType(key) {
|
|
440
444
|
const sanitized = key.trim().toLowerCase();
|
|
445
|
+
if (sanitized.startsWith("pk_")) return "publicKey";
|
|
441
446
|
if (sanitized.startsWith("app_")) return "appId";
|
|
442
447
|
if (sanitized.startsWith("sk_")) return "secret";
|
|
443
448
|
return null;
|
|
444
449
|
}
|
|
445
450
|
function validateKey(key) {
|
|
446
451
|
const keyType = key ? detectKeyType(key) : null;
|
|
452
|
+
if (keyType === "publicKey") {
|
|
453
|
+
return validatePublicKey(key);
|
|
454
|
+
}
|
|
447
455
|
if (keyType === "appId") {
|
|
448
456
|
return validateAppId(key);
|
|
449
457
|
}
|
|
@@ -453,12 +461,63 @@ function validateKey(key) {
|
|
|
453
461
|
return {
|
|
454
462
|
valid: false,
|
|
455
463
|
sanitizedKey: "",
|
|
456
|
-
error: key ? `Invalid key format. Keys must start with 'app_' (
|
|
464
|
+
error: key ? `Invalid key format. Keys must start with 'pk_' (publishable), 'app_' (legacy), or 'sk_' (secret), followed by environment (dev/stg/prod). Got: ${key.slice(0, 20)}...` : "API key is required but was not provided.",
|
|
457
465
|
issues: key ? ["invalid_format"] : ["missing"]
|
|
458
466
|
};
|
|
459
467
|
}
|
|
460
468
|
|
|
461
469
|
// src/config.ts
|
|
470
|
+
function parseKey(key) {
|
|
471
|
+
const sanitized = key.trim().toLowerCase();
|
|
472
|
+
if (sanitized.startsWith("app_")) {
|
|
473
|
+
throw new SylphxError(
|
|
474
|
+
"[Sylphx] API key format has changed (ADR-021). Keys now embed the project ref.\n\nOld format: app_prod_xxx\nNew format: pk_prod_{ref}_xxx\n\nPlease regenerate your API keys from the Sylphx Console \u2192 Your App \u2192 Environments.\nOr contact support@sylphx.com for assistance.",
|
|
475
|
+
{ code: "BAD_REQUEST" }
|
|
476
|
+
);
|
|
477
|
+
}
|
|
478
|
+
const prefix = sanitized.startsWith("pk_") ? "pk" : sanitized.startsWith("sk_") ? "sk" : null;
|
|
479
|
+
if (!prefix) {
|
|
480
|
+
throw new SylphxError(
|
|
481
|
+
`[Sylphx] Invalid key format. Keys must start with 'pk_' (publishable) or 'sk_' (secret). Got: "${sanitized.slice(0, 15)}..."`,
|
|
482
|
+
{ code: "BAD_REQUEST" }
|
|
483
|
+
);
|
|
484
|
+
}
|
|
485
|
+
const parts = sanitized.split("_");
|
|
486
|
+
if (parts.length !== 4) {
|
|
487
|
+
throw new SylphxError(
|
|
488
|
+
`[Sylphx] Invalid key structure. Expected format: ${prefix}_{env}_{ref}_{token} (4 segments separated by '_'). Got ${parts.length} segment(s).`,
|
|
489
|
+
{ code: "BAD_REQUEST" }
|
|
490
|
+
);
|
|
491
|
+
}
|
|
492
|
+
const [, env, ref, token] = parts;
|
|
493
|
+
if (env !== "prod" && env !== "dev" && env !== "stg") {
|
|
494
|
+
throw new SylphxError(
|
|
495
|
+
`[Sylphx] Invalid key environment "${env}". Must be 'prod', 'dev', or 'stg'.`,
|
|
496
|
+
{ code: "BAD_REQUEST" }
|
|
497
|
+
);
|
|
498
|
+
}
|
|
499
|
+
if (!/^[a-z0-9]{12}$/.test(ref)) {
|
|
500
|
+
throw new SylphxError(
|
|
501
|
+
`[Sylphx] Invalid project ref in key: "${ref}". Must be a 12-character lowercase alphanumeric string.`,
|
|
502
|
+
{ code: "BAD_REQUEST" }
|
|
503
|
+
);
|
|
504
|
+
}
|
|
505
|
+
const expectedTokenLen = prefix === "pk" ? 32 : 64;
|
|
506
|
+
if (token.length !== expectedTokenLen || !/^[a-f0-9]+$/.test(token)) {
|
|
507
|
+
throw new SylphxError(
|
|
508
|
+
`[Sylphx] Invalid key token. ${prefix === "pk" ? "Publishable" : "Secret"} keys must have a ${expectedTokenLen}-char hex token.`,
|
|
509
|
+
{ code: "BAD_REQUEST" }
|
|
510
|
+
);
|
|
511
|
+
}
|
|
512
|
+
return {
|
|
513
|
+
type: prefix,
|
|
514
|
+
env,
|
|
515
|
+
ref,
|
|
516
|
+
token,
|
|
517
|
+
isPublic: prefix === "pk",
|
|
518
|
+
baseUrl: `https://${ref}.${DEFAULT_SDK_API_HOST}${SDK_API_PATH}`
|
|
519
|
+
};
|
|
520
|
+
}
|
|
462
521
|
function httpStatusToErrorCode(status) {
|
|
463
522
|
switch (status) {
|
|
464
523
|
case 400:
|
|
@@ -493,31 +552,58 @@ function httpStatusToErrorCode(status) {
|
|
|
493
552
|
}
|
|
494
553
|
var REF_PATTERN = /^[a-z0-9]{12}$/;
|
|
495
554
|
function createConfig(input) {
|
|
555
|
+
const keyForParsing = input.secretKey || input.publicKey;
|
|
556
|
+
if (!keyForParsing) {
|
|
557
|
+
if (input.ref) {
|
|
558
|
+
const trimmedRef = input.ref.trim();
|
|
559
|
+
if (!REF_PATTERN.test(trimmedRef)) {
|
|
560
|
+
throw new SylphxError(
|
|
561
|
+
`[Sylphx] Invalid project ref format: "${input.ref}". Expected a 12-character lowercase alphanumeric string (e.g. "abc123def456"). Get your ref from Platform Console \u2192 Projects \u2192 Your Project \u2192 Overview.`,
|
|
562
|
+
{ code: "BAD_REQUEST" }
|
|
563
|
+
);
|
|
564
|
+
}
|
|
565
|
+
const baseUrl2 = `https://${trimmedRef}.${DEFAULT_SDK_API_HOST}${SDK_API_PATH}`;
|
|
566
|
+
console.warn(
|
|
567
|
+
"[Sylphx] Providing only ref without a key is deprecated. Provide secretKey or publicKey \u2014 the ref is now embedded in keys (ADR-021)."
|
|
568
|
+
);
|
|
569
|
+
return Object.freeze({ ref: trimmedRef, baseUrl: baseUrl2, accessToken: input.accessToken });
|
|
570
|
+
}
|
|
571
|
+
throw new SylphxError(
|
|
572
|
+
"[Sylphx] Either publicKey or secretKey must be provided to createConfig().",
|
|
573
|
+
{ code: "BAD_REQUEST" }
|
|
574
|
+
);
|
|
575
|
+
}
|
|
576
|
+
const parsed = parseKey(keyForParsing);
|
|
577
|
+
const ref = parsed.ref;
|
|
578
|
+
const baseUrl = parsed.baseUrl;
|
|
496
579
|
let secretKey;
|
|
497
580
|
if (input.secretKey) {
|
|
498
581
|
const result = validateKey(input.secretKey);
|
|
499
582
|
if (!result.valid) {
|
|
500
|
-
throw new SylphxError(result.error || "Invalid
|
|
583
|
+
throw new SylphxError(result.error || "Invalid secret key", {
|
|
501
584
|
code: "BAD_REQUEST",
|
|
502
585
|
data: { issues: result.issues }
|
|
503
586
|
});
|
|
504
587
|
}
|
|
505
|
-
if (result.warning) {
|
|
506
|
-
console.warn(`[Sylphx] ${result.warning}`);
|
|
507
|
-
}
|
|
588
|
+
if (result.warning) console.warn(`[Sylphx] ${result.warning}`);
|
|
508
589
|
secretKey = result.sanitizedKey;
|
|
509
590
|
}
|
|
510
|
-
|
|
511
|
-
if (
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
591
|
+
let publicKey;
|
|
592
|
+
if (input.publicKey) {
|
|
593
|
+
const result = validateKey(input.publicKey);
|
|
594
|
+
if (!result.valid) {
|
|
595
|
+
throw new SylphxError(result.error || "Invalid public key", {
|
|
596
|
+
code: "BAD_REQUEST",
|
|
597
|
+
data: { issues: result.issues }
|
|
598
|
+
});
|
|
599
|
+
}
|
|
600
|
+
if (result.warning) console.warn(`[Sylphx] ${result.warning}`);
|
|
601
|
+
publicKey = result.sanitizedKey;
|
|
516
602
|
}
|
|
517
|
-
const baseUrl = `https://${trimmedRef}.${DEFAULT_SDK_API_HOST}${SDK_API_PATH}`;
|
|
518
603
|
return Object.freeze({
|
|
519
604
|
secretKey,
|
|
520
|
-
|
|
605
|
+
publicKey,
|
|
606
|
+
ref,
|
|
521
607
|
baseUrl,
|
|
522
608
|
accessToken: input.accessToken
|
|
523
609
|
});
|
|
@@ -535,6 +621,8 @@ function buildHeaders(config) {
|
|
|
535
621
|
};
|
|
536
622
|
if (config.secretKey) {
|
|
537
623
|
headers["x-app-secret"] = config.secretKey;
|
|
624
|
+
} else if (config.publicKey) {
|
|
625
|
+
headers["x-app-secret"] = config.publicKey;
|
|
538
626
|
}
|
|
539
627
|
if (config.accessToken) {
|
|
540
628
|
headers.Authorization = `Bearer ${config.accessToken}`;
|
|
@@ -3575,6 +3663,7 @@ export {
|
|
|
3575
3663
|
listTasks,
|
|
3576
3664
|
listUsers,
|
|
3577
3665
|
page,
|
|
3666
|
+
parseKey,
|
|
3578
3667
|
pauseCron,
|
|
3579
3668
|
realtimeEmit,
|
|
3580
3669
|
recordStreakActivity,
|